src/Model/UserModel.php line 4935

Open in your IDE?
  1. <?php
  2. namespace App\Model;
  3. use Pimcore\Db;
  4. use Carbon\Carbon;
  5. use App\Lib\Utility;
  6. use App\Lib\ExcelGenerator;
  7. use App\Service\EmailService;
  8. use Pimcore\Model\DataObject;
  9. use App\Service\UserPermission;
  10. use Pimcore\Model\DataObject\Customer;
  11. use Pimcore\Model\DataObject\Location;
  12. use Pimcore\Model\DataObject\Tags;
  13. use Pimcore\Model\DataObject\UserGroup;
  14. use Pimcore\Model\DataObject\UserSMSGroup;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use App\C2IntegrationBundle\Service\C2Service;
  17. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  18. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  19. use DateTime;
  20. use Pimcore\Model\Asset\MetaData\ClassDefinition\Data\DataObject as DataDataObject;
  21. use Pimcore\Model\DataObject\Subscription;
  22. use Pimcore\Model\DataObject\UserTag;
  23. use App\Model\ReportingPortalModel;
  24. use App\Model\EwsPortalModel;
  25. use Pimcore\Model\DataObject\PermissionGroup;
  26. use Symfony\Component\Templating\EngineInterface;
  27. class UserModel
  28. {
  29.     public $emailService;
  30.     public $userPermission;
  31.     private $locationModel;
  32.     private $c2Service;
  33.     private $reportingPortalModel;
  34.     private $ewsPortalModel;
  35.     function __construct()
  36.     {
  37.         $this->emailService  = new EmailService();
  38.         $this->userPermission  = new UserPermission();
  39.         $this->locationModel = new LocationModel();
  40.         $this->c2Service = new C2Service();
  41.         $this->reportingPortalModel = new ReportingPortalModel();
  42.         $this->ewsPortalModel = new EwsPortalModel();
  43.     }
  44.     public function register($request$params$translator): array
  45.     {
  46.         $result = [];
  47.         try {
  48.             Utility::validateEmail($params['email']);
  49.             Utility::validateName($params['name']);
  50.             if (!$params['organization'] instanceof \Pimcore\Model\DataObject\Organization) {
  51.                 return ["success" => false"message" => $translator->trans("invalid_organization_passed")];
  52.             }
  53.             if (!$params['role'] instanceof \Pimcore\Model\DataObject\UserRole) {
  54.                 return ["success" => false"message" => $translator->trans("invalid_user_role")];
  55.             }
  56.             $user DataObject\Customer::getByEmail($params['email'], true);
  57.             if ($user instanceof \Pimcore\Model\DataObject\Customer) {
  58.                 return ["success" => false"message" => $translator->trans("user_already_exists")];
  59.             }
  60.             $userGroup DataObject\UserGroup::getById($params['groupId'], true);
  61.             $registerUser = new DataObject\Customer();
  62.             $registerUser->setParent(DataObject\Service::createFolderByPath('/UserManagement/Users'));
  63.             $registerUser->setKey(trim(strip_tags($params['email'])));
  64.             $registerUser->setName(strip_tags($params['name']));
  65.             $registerUser->setEmail(trim(strip_tags($params['email'])));
  66.             if ((isset($params['published'])) && ($params['published'] == false)) {
  67.                 # code...
  68.                 $registerUser->setToken((isset($params['token'])) ? $params['token'] : '');
  69.             }
  70.             $registerUser->setRole($params['role']);
  71.             if ($userGroup instanceof \Pimcore\Model\DataObject\UserGroup) {
  72.                 $registerUser->setUserGroup($userGroup);
  73.             }
  74.             // assign user permissions to user
  75.             if (isset($params['permissionUserGroupIds']) && !empty($params['permissionUserGroupIds']) && is_array($params['permissionUserGroupIds'])) {
  76.                 $permissionGroups = [];
  77.                 foreach ($params['permissionUserGroupIds'] as $groupId) {
  78.                     $permissionGroup PermissionGroup::getById($groupId);
  79.                     if ($permissionGroup) {
  80.                         $permissionGroups[] = $permissionGroup;
  81.                     }
  82.                 }
  83.                 $registerUser->setPermissionGroups($permissionGroups);
  84.             }
  85.             $registerUser->setOrganization($params['organization']);
  86.             $registerUser->setPassword($params['password']);
  87.             $registerUser->setTitle((isset($params['title'])) ? $params['title'] : '');
  88.             $registerUser->setDepartment((isset($params['department'])) ? $params['department'] : '');
  89.             $registerUser->setCreatedBy($params['createdBy']);
  90.             // Set created-by snapshot fields for future reference even if relation is removed
  91.             if (isset($params['createdBy']) && $params['createdBy'] instanceof DataObject\Customer) {
  92.                 $creator $params['createdBy'];
  93.                 $registerUser->setCreatedByUserName($creator->getName());
  94.                 $registerUser->setCreatedByUserEmail($creator->getEmail());
  95.                 $registerUser->setCreatedByUserStatus($creator->getIsDeleted() ? 'deleted' 'active');
  96.             } else {
  97.                 $registerUser->setCreatedByUserStatus('deleted');
  98.             }
  99.             $registerUser->setPublished((isset($params['published'])) ? $params['published'] : true);
  100.             $registerUser->setIsActive(true);
  101.             $registerUser->setphoneNo(isset($params['phone']) ? $params['phone'] : '');
  102.             if ($params['role']->getName() == USER_ROLES['CLIENT_ADMIN'] || $params['role']->getName() == USER_ROLES['CLIENT_USER']) {
  103.                 $registerUser->setTwoFactorAuth(true);
  104.             }
  105.             $registerUser->save();
  106.             // assign default subscription based on role
  107.             if ($params['role']->getName() !== USER_ROLES['NCM_IT'] && $params['role']->getName() !== USER_ROLES['NCM_OPERATOR']) {
  108.                 # code...
  109.                 $this->createSubscription($translator$registerUser$params['role'], isset($params['isNoExpiry']) ? $params['isNoExpiry'] : false);
  110.             }
  111.             return ["success" => true"message" => $translator->trans("user_registered_success"), 'data' => $registerUser];
  112.         } catch (\Exception $ex) {
  113.             throw new \Exception($ex->getMessage());
  114.         }
  115.         return $result;
  116.     }
  117.     /**
  118.      * Create Subscritpion 
  119.      */
  120.     public function createSubscription($translator$user$role$isNoExpiry false): array
  121.     {
  122.         $result = [];
  123.         try {
  124.             $subscriptionsArray = [];
  125.             if ($role instanceof DataObject\UserRole) {
  126.                 $packages $role->getDefaultPackages();
  127.                 if ($packages) {
  128.                     foreach ($packages as $key => $package) {
  129.                         if ($package instanceof DataObject\Package) {
  130.                             if ($user instanceof DataObject\Customer) {
  131.                                 $subscription $this->setSubscription($package$usernull"default"true);
  132.                                 if ($subscription instanceof DataObject\Subscription) {
  133.                                     $subscriptionsArray[] = [
  134.                                         "id" => $subscription->getId(),
  135.                                         "key" => $subscription->getKey(),
  136.                                     ];
  137.                                 }
  138.                             }
  139.                         }
  140.                     }
  141.                     return ["success" => true"data" => $subscriptionsArray];
  142.                 }
  143.             }
  144.         } catch (\Exception $ex) {
  145.             throw new \Exception($ex->getMessage());
  146.         }
  147.         return $result;
  148.     }
  149.     public function editUser($params$translator): array
  150.     {
  151.         $updateUser DataObject\Customer::getById($params['id'], true);
  152.         if ($updateUser instanceof DataObject\Customer && !$updateUser->getIsDeleted()) {
  153.             $loggedInUserRole $params['loggedInUser']->getRole() ? $params['loggedInUser']->getRole()->getName() : null;
  154.             $updateOrganization $updateUser->getOrganization();
  155.             // Update client type for NCM_IT role
  156.             if (!empty($params['client_type'])) {
  157.                 if ($loggedInUserRole == USER_ROLES['NCM_IT']  || $loggedInUserRole == USER_ROLES['NCM_OPERATOR'] && $updateOrganization) {
  158.                     $updateOrganization->setCilent_type($params['client_type']);
  159.                     $updateOrganization->setClientType($params['client_type']);
  160.                     $updateOrganization->save();
  161.                 } else {
  162.                     return [
  163.                         "success" => false,
  164.                         "message" => $translator->trans("access_denied_to_update_organization_client_type")
  165.                     ];
  166.                 }
  167.             }
  168.             // Update entity status with validation
  169.             if (!empty($params['entity_status'])) {
  170.                 $allowedStatuses = ['paid''trial''expired'];
  171.                 if (in_array($params['entity_status'], $allowedStatuses)) {
  172.                     if (in_array($loggedInUserRole, [USER_ROLES['NCM_IT'], USER_ROLES['NCM_OPERATOR']]) && $updateOrganization) {
  173.                         if ($params['client_type'] == "government") {
  174.                             $updateOrganization->setStatus("paid");
  175.                         } else {
  176.                             $updateOrganization->setStatus($params['entity_status']);
  177.                         }
  178.                         if ($params['entity_status'] == "trial") {
  179.                             if (empty($params['trialLimit'])) {
  180.                                 return [
  181.                                     "success" => false,
  182.                                     "message" => $translator->trans("trial_limit_is_required")
  183.                                 ];
  184.                             }
  185.                             if ($updateOrganization->getStatus() == "expired") {
  186.                                 $updateOrganization->setPackageActivationDate(Carbon::now());
  187.                             }
  188.                             $updateOrganization->setTrialLimit($params['trialLimit']);
  189.                         }
  190.                         $updateOrganization->save();
  191.                     }
  192.                 }
  193.             }
  194.             // Update company name in English
  195.             if (!empty($params['company_name_en'])) {
  196.                 if ($loggedInUserRole == USER_ROLES['NCM_IT'] || $loggedInUserRole == USER_ROLES['NCM_OPERATOR'] && $updateOrganization) {
  197.                     // Check if the name already exists for another organization
  198.                     $existingOrganization DataObject\Organization::getByName($params['company_name_en'], 'en', ['limit' => 1'unpublished' => true]);
  199.                     if ($existingOrganization && $existingOrganization->getId() !== $updateOrganization->getId()) {
  200.                         return [
  201.                             "success" => false,
  202.                             "message" => $translator->trans("organization_already_exists") . " : " $params['company_name_en']
  203.                         ];
  204.                     }
  205.                     $updateOrganization->setName($params['company_name_en'], 'en');
  206.                     $updateOrganization->setKey(trim(strip_tags($params['company_name_en']))); // Update key to match new name
  207.                     $updateOrganization->save();
  208.                 } else {
  209.                     return [
  210.                         "success" => false,
  211.                         "message" => $translator->trans("access_denied_to_update_organization_company_name_en")
  212.                     ];
  213.                 }
  214.             }
  215.             // Update company name in Arabic
  216.             if (!empty($params['company_name_ar'])) {
  217.                 if ($loggedInUserRole == USER_ROLES['NCM_IT'] || $loggedInUserRole == USER_ROLES['NCM_OPERATOR'] && $updateOrganization) {
  218.                     $updateOrganization->setName($params['company_name_ar'], 'ar');
  219.                     $updateOrganization->save();
  220.                 } else {
  221.                     return [
  222.                         "success" => false,
  223.                         "message" => $translator->trans("access_denied_to_update_organization_company_name_ar")
  224.                     ];
  225.                 }
  226.             }
  227.             // Update user details (name, password, phone, etc.)
  228.             if (!empty($params['name'])) {
  229.                 $updateUser->setName(strip_tags($params['name']));
  230.             }
  231.             if (!empty($params['password'])) {
  232.                 $updateUser->setPassword(strip_tags($params['password']));
  233.             }
  234.             // update phone number
  235.             if (!empty($params['phone'])) {
  236.                 $phone trim($params['phone']);
  237.                 if (strlen($phone) !== 9) {
  238.                     return ["success" => false"message" => $translator->trans("phone_no_must_be_9_digits")];
  239.                 } elseif (!ctype_digit($phone)) {
  240.                     return ["success" => false"message" => $translator->trans("phone_no_must_be_numeric")];
  241.                 } else {
  242.                     $updateUser->setPhoneNo($phone);
  243.                 }
  244.             } else if (empty($params['phone']) && isset($params['phone'])) {
  245.                 $updateUser->setPhoneNo("");
  246.             }
  247.             // Set user role if provided
  248.             if (!empty($params['role'])) {
  249.                 $userRole DataObject\UserRole::getByName(USER_ROLES[$params['role']], true);
  250.                 if ($userRole instanceof DataObject\UserRole) {
  251.                     // Prevent role update if it would leave no admin in the organization
  252.                     if ($params['role'] == USER_ROLES['CLIENT_USER'] && $updateUser->getRole()->getName() == USER_ROLES['CLIENT_ADMIN']) {
  253.                         $adminRole DataObject\UserRole::getByName(USER_ROLES['CLIENT_ADMIN'], true);
  254.                         $adminCount = new DataObject\Customer\Listing();
  255.                         $adminCount->filterByOrganization($updateUser->getOrganization());
  256.                         $adminCount->filterByRole($adminRole);
  257.                         $adminCount->filterByIsActive(true);
  258.                         if ($adminCount->getCount() <= 1) {
  259.                             return [
  260.                                 "success" => false,
  261.                                 "message" => $translator->trans('atleast_one_admin_required')
  262.                             ];
  263.                         }
  264.                     }
  265.                     $updateUser->setRole($userRole);
  266.                     // Update default Package according to role
  267.                     $rolePackage $userRole->getDefaultPackages();
  268.                     if ($rolePackage) {
  269.                         foreach ($rolePackage as $package) {
  270.                             if ($package instanceof DataObject\Package) {
  271.                                 $this->updateSubscription($package$updateUsernull"default");
  272.                             }
  273.                         }
  274.                     }
  275.                 }
  276.             }
  277.             // Set department and title if provided
  278.             if (!empty($params['department'])) {
  279.                 $updateUser->setDepartment(strip_tags($params['department']));
  280.             }
  281.             if (!empty($params['title'])) {
  282.                 $updateUser->setTitle(strip_tags($params['title']));
  283.             }
  284.             // Assign location by location tag id to user
  285.             if (!empty($params['location_tag_ids'])) {
  286.                 $this->assignLocationToUser($params['loggedInUser'], null$params['location_tag_ids'], [$updateUser->getId()], nullfalsefalse$translator);
  287.             }
  288.             $updateUser->save();
  289.             // Add updated user to updated permissions
  290.             $params['user'] = $updateUser;
  291.             // Package subscription update
  292.             if (!empty($params['package_id'])) {
  293.                 $package DataObject\Package::getById($params['package_id'], true);
  294.                 if ($package instanceof DataObject\Package) {
  295.                     $this->updateSubscription($package$params['user'], null"custom");
  296.                 }
  297.             }
  298.             if (isset($params['disallowedApiGroups'])) {
  299.                 $this->disallowApiGroups($params['user'], $params['disallowedApiGroups'], "custom");
  300.             }
  301.             // Handle location assignment for CLIENT_ADMIN or CLIENT_USER roles
  302.             if (in_array($params['role'], [USER_ROLES['CLIENT_ADMIN'], USER_ROLES['CLIENT_USER']])) {
  303.                 if (isset($params['location'])) {
  304.                     foreach ($params['location'] as $value) {
  305.                         $location DataObject\Location::getById($valuetrue);
  306.                         if ($location) {
  307.                             $this->locationModel->locationMetaData($location$updateUser);
  308.                         }
  309.                     }
  310.                 }
  311.             }
  312.             return [
  313.                 "success" => true,
  314.                 "message" => $translator->trans("user_updated_successfully")
  315.             ];
  316.         }
  317.         return [
  318.             "success" => false,
  319.             "message" => $translator->trans("user_does_not_exist")
  320.         ];
  321.     }
  322.     public function editNCMUser($params$translator): array
  323.     {
  324.         $result = [];
  325.         // try {
  326.         $updateUser DataObject\Customer::getById($params['id'], true);
  327.         if ($updateUser instanceof DataObject\Customer && $updateUser->getIsDeleted() != true) {
  328.             $loggedInUserRole $params['loggedInUser']->getRole() ? $params['loggedInUser']->getRole()->getName() : null;
  329.             if (isset($params['name']) && !empty($params['name'])) {
  330.                 $updateUser->setName(strip_tags($params['name']));
  331.             }
  332.             // Set Role if $UserRole is provided
  333.             if (isset($params['role']) && !empty($params['role'])) {
  334.                 $UserRole DataObject\UserRole::getByName(USER_ROLES[$params['role']], true);
  335.                 if ($UserRole instanceof DataObject\UserRole) {
  336.                     $updateUser->setRole($UserRole);
  337.                     // Update default Package according to role
  338.                     $rolePackage $UserRole->getDefaultPackages();
  339.                     if ($rolePackage) {
  340.                         foreach ($rolePackage as $key => $package) {
  341.                             if ($package instanceof DataObject\Package) {
  342.                                 $this->updateSubscription($package$updateUsernull"default");
  343.                             }
  344.                         }
  345.                     }
  346.                 }
  347.             }
  348.             // update password
  349.             if (isset($params['password']) && !empty($params['password'])) {
  350.                 $updateUser->setPassword(strip_tags($params['password']));
  351.             }
  352.             // updated permissions 
  353.             if (isset($params['allowedApiGrpups']) && !empty($params['allowedApiGrpups'])) {
  354.                 $this->updateNCMUserSubscription($updateUser$params['allowedApiGrpups']);
  355.             }
  356.             // update permission user groups
  357.             if (isset($params['permissionUserGroupIds']) && !empty($params['permissionUserGroupIds'])) {
  358.                 // Validate and prepare permission groups
  359.                 $permissionGroups = [];
  360.                 foreach ($params['permissionUserGroupIds'] as $groupId) {
  361.                     $permissionGroup PermissionGroup::getById($groupId);
  362.                     if ($permissionGroup) {
  363.                         $permissionGroups[] = $permissionGroup;
  364.                     }
  365.                 }
  366.                 $updateUser->setPermissionGroups($permissionGroups);
  367.             }
  368.             // assign user tag to user
  369.             if (isset($params['tagId']) && !empty($params['tagId'])) {
  370.                 $tage  UserTag::getById($params['tagId']);
  371.                 if ($tage instanceof UserTag) {
  372.                     $updateUser->setTag($tage);
  373.                 }
  374.             }
  375.             if (isset($params['phone']) && !empty($params['phone'])) {
  376.                 $updateUser->setPhoneNo(strip_tags($params['phone']));
  377.             }
  378.             $updateUser->save();
  379.             // unset($params["Authorization"]);
  380.             // $params["loggedInUserEmail"] = $loggedInUserRole = $params['loggedInUser']->getEmail();
  381.             // $ncmReportingUser = $this->reportingPortalModel->updateNcmUser($params);
  382.             // $ewsPortalUser = $this->ewsPortalModel->updateNcmUser($params);
  383.             return ["success" => true"message" => $translator->trans("user_updated_successifully")];
  384.         }
  385.         return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  386.         // } catch (\Exception $ex) {
  387.         //     throw new \Exception($ex->getMessage());
  388.         // }
  389.         return $result;
  390.     }
  391.     public function disallowApiGroups($user$disallowedApiGroups$type)
  392.     {
  393.         $result = [];
  394.         if (!$user instanceof DataObject\Customer) {
  395.             return ["success" => false"message" => "User is not available"];
  396.         }
  397.         $customSubscriptions = new DataObject\Subscription\Listing();
  398.         $customSubscriptions->filterBySubscribedUser($user);
  399.         $customSubscriptions->filterBySubscriptionType("custom");
  400.         $customSubscriptions->filterByIsActive(true);
  401.         $updateSubscription $customSubscriptions->current();
  402.         if ($updateSubscription instanceof  DataObject\Subscription) {
  403.             //Set Disallowed ApiGroups
  404.             if ($disallowedApiGroups != null) {
  405.                 $disallowedApiGroupsArr = [];
  406.                 foreach ($disallowedApiGroups as $disallowedApiGroupsId) {
  407.                     $apiGroup =  DataObject\APIGroup::getById($disallowedApiGroupsIdtrue);
  408.                     $disallowedApiGroupsArr[] = $apiGroup;
  409.                 }
  410.                 $updateSubscription->setDisallowedApiGroups($disallowedApiGroupsArr);
  411.             } else {
  412.                 $updateSubscription->setDisallowedApiGroups(null);
  413.             }
  414.             $updateSubscription->save();
  415.         }
  416.         return  $updateSubscription;
  417.     }
  418.     public function updateUserGroupData(
  419.         $loggedInUser,
  420.         $locations,
  421.         $locationTagIds,
  422.         $userGroupId,
  423.         $userIds,
  424.         $request,
  425.         $lang,
  426.         $translator
  427.     ): array {
  428.         $result = [];
  429.         try {
  430.             $userGroup DataObject\UserGroup::getById($userGroupIdtrue);
  431.             if (!$userGroup instanceof DataObject\UserGroup) {
  432.                 return ["success" => false"message" => $translator->trans("user_group_is_not_available")];
  433.             }
  434.             if (count($userIds) > 0) {
  435.                 foreach ($userIds as $key => $userId) {
  436.                     $user DataObject\Customer::getById($userIdtrue);
  437.                     $userGroupArr[] =  $userGroup;
  438.                     foreach ($user->getUserGroup() as $group) {
  439.                         $userGroupArr[] = $group;
  440.                     }
  441.                     $userGroupArr array_unique($userGroupArr);
  442.                     if ($user instanceof DataObject\Customer) {
  443.                         $user->setUserGroup($userGroupArr);
  444.                         $user->save();
  445.                     }
  446.                 }
  447.                 // Assign location by location tag id to user
  448.                 if (isset($locationTagIds) && !empty($locationTagIds)) {
  449.                     $assignLocationByLocationTagId $this->assignLocationToUser($loggedInUser$locations$locationTagIds$userIdsnullfalsefalse$translator);
  450.                     if (isset($assignLocationByLocationTagId['success']) && $assignLocationByLocationTagId['success'] == false) {
  451.                         return $assignLocationByLocationTagId;
  452.                     }
  453.                 }
  454.                 return ["success" => true"message" => $translator->trans("user_group_are_updated_successfully ")];
  455.             }
  456.             return ["success" => false"message" => $translator->trans("user_group_not_available")];
  457.         } catch (\Exception $ex) {
  458.             throw new \Exception($ex->getMessage());
  459.         }
  460.         return $result;
  461.     }
  462.     public function createUserGroupData($user$groupNameEn$groupNameAr$detailEn$detailAr$groupId$request$lang$translator): array
  463.     {
  464.         $result = [];
  465.         try {
  466.             $organization $user->getOrganization();
  467.             if (!$organization instanceof DataObject\Organization) {
  468.                 return ["success" => false"message" => $translator->trans("user_does_not_belongs_to_organization ")];
  469.             }
  470.             $userGroup = new DataObject\UserGroup\Listing();
  471.             $userGroup->setLocale($lang);
  472.             $userGroup->setCondition("groupName = ? ", [$groupNameEn]);
  473.             $userGroup->filterByOrganization($organization);
  474.             $userGroup $userGroup->current();
  475.             if ($userGroup instanceof DataObject\UserGroup) {
  476.                 return ["success" => false"message" => $translator->trans("user_group_name_already_available")];
  477.             }
  478.             if (!empty($groupId)) {
  479.                 $userGroup DataObject\UserGroup::getById($groupIdtrue);
  480.                 if (!$userGroup instanceof DataObject\UserGroup) {
  481.                     return ["success" => false"message" => $translator->trans("user_group_is_not_available")];
  482.                 }
  483.                 $userGroup->setKey(trim(strip_tags($groupNameEn)));
  484.                 $userGroup->setGroupName($groupNameEn'en');
  485.                 $userGroup->setGroupName($groupNameAr'ar');
  486.                 $userGroup->setDetail($detailEn'en');
  487.                 $userGroup->setDetail($detailAr'ar');
  488.                 $userGroup->save();
  489.                 if ($userGroup) {
  490.                     return ["success" => true"message" => $translator->trans("user_group_updated_successfully")];
  491.                 }
  492.             }
  493.             $userGroup = new DataObject\UserGroup();
  494.             $userGroup->setParent(DataObject\Service::createFolderByPath('/UserManagement/UserGroups/' $organization->getName()));
  495.             $userGroup->setKey(trim(strip_tags($groupNameEn)));
  496.             $userGroup->setGroupName($groupNameEn'en');
  497.             $userGroup->setGroupName($groupNameAr'ar');
  498.             $userGroup->setDetail($detailEn'en');
  499.             $userGroup->setDetail($detailAr'ar');
  500.             $userGroup->setOrganization($organization);
  501.             $userGroup->setPublished(true);
  502.             $userGroup->save();
  503.             if ($userGroup) {
  504.                 return ["success" => true"message" => $translator->trans("user_group_created_successfully"), "user_group_id" => $userGroup->getId()];
  505.             }
  506.         } catch (\Exception $ex) {
  507.             throw new \Exception($ex->getMessage());
  508.         }
  509.         return $result;
  510.     }
  511.     public function editUserGroupData($id$groupNameEn$groupNameAr$detailEn$detailAr$request$lang$translator): array
  512.     {
  513.         $result = [];
  514.         try {
  515.             $userGroup DataObject\UserGroup::getById($idtrue);
  516.             if (!$userGroup instanceof DataObject\UserGroup) {
  517.                 return ["success" => false"message" => $translator->trans("user_group_is_not_available")];
  518.             }
  519.             if (isset($groupNameEn) && !empty($groupNameEn)) {
  520.                 $userGroup->setGroupName($groupNameEn'en');
  521.             }
  522.             if (isset($groupNameAr) && !empty($groupNameAr)) {
  523.                 $userGroup->setGroupName($groupNameAr'ar');
  524.             }
  525.             if (isset($detailEn) && !empty($detailEn)) {
  526.                 $userGroup->setDetail($detailEn'en');
  527.             }
  528.             if (isset($detailAr) && !empty($detailAr)) {
  529.                 $userGroup->setDetail($detailAr'ar');
  530.             }
  531.             $userGroup->save();
  532.             if ($userGroup) {
  533.                 return ["success" => true"message" => $translator->trans("user_group_updated_successfully")];
  534.             }
  535.         } catch (\Exception $ex) {
  536.             throw new \Exception($ex->getMessage());
  537.         }
  538.         return $result;
  539.     }
  540.     public function deleteUserGroup($user$id$request$translator): array
  541.     {
  542.         $result = [];
  543.         try {
  544.             $userGroup DataObject\UserGroup::getById($idtrue);
  545.             if (!$userGroup instanceof DataObject\UserGroup) {
  546.                 return ["success" => false"message" => $translator->trans("user_group_is_not_available")];
  547.             }
  548.             if (!$userGroup->getOrganization()) {
  549.                 return ["success" => false"message" => $translator->trans("no_organization_is_assigned_to_this_user_group")];
  550.             }
  551.             $loggedInUserOrganizationName $user->getOrganization() ? $user->getOrganization()->getName() : '';
  552.             if ($userGroup->getOrganization()->getName("en") != $loggedInUserOrganizationName) {
  553.                 return ["success" => false"message" => $translator->trans("user_group_is_not_assigned_to_your_organization")];
  554.             }
  555.             $userGroup->delete();
  556.             return ["success" => true"message" => $translator->trans("user_group_deleted_successifully")];
  557.         } catch (\Exception $ex) {
  558.             throw new \Exception($ex->getMessage());
  559.         }
  560.         return $result;
  561.     }
  562.     public function userGroupListing($user$translator$paginator$params): array
  563.     {
  564.         $result = [];
  565.         try {
  566.             $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  567.             $page = isset($params['page']) ? $params['page'] : 1;
  568.             $lang = isset($params['lang']) ? $params['lang'] : 'en';
  569.             $organization $user->getOrganization();
  570.             if (!$organization instanceof DataObject\Organization) {
  571.                 return ["success" => false"message" => $translator->trans("user_does_not_belongs_to_organization ")];
  572.             }
  573.             // Load LocationGroup listing
  574.             $userGroupList = new DataObject\UserGroup\Listing();
  575.             $userGroupList->filterByOrganization($organization);
  576.             $userGroupList->setLocale($lang);
  577.             if (isset($params['search']) && !empty($params['search'])) {
  578.                 $userGroupList->addConditionParam('(groupName LIKE ? OR detail LIKE ?)', ['%' $params['search'] . '%''%' $params['search'] . '%']);
  579.             }
  580.             $userGroupList->setOrderKey("oo_id");
  581.             $userGroupList->setOrder("desc");
  582.             $paginator $paginator->paginate(
  583.                 $userGroupList,
  584.                 $page,
  585.                 $pageSize
  586.             );
  587.             if ($paginator->getTotalItemCount() > 0) {
  588.                 $userGroupListData = [];
  589.                 foreach ($paginator as $key => $userGroup) {
  590.                     $userListData = [];
  591.                     $usersList = new DataObject\Customer\Listing();
  592.                     $usersList->filterByUserGroup($userGroup);
  593.                     $usersList->setOrderKey("oo_id");
  594.                     $usersList->setOrder("desc");
  595.                     if ($usersList) {
  596.                         foreach ($usersList as $user) {
  597.                             $userListData[] = [
  598.                                 'id' => $user->getId(),
  599.                                 'name' => $user->getName(),
  600.                                 'email' => $user->getEmail(),
  601.                                 'role' => $user->getRole() ? $user->getRole()->getName() : '',
  602.                                 'organization' => $user->getOrganization() ?  $user->getOrganization()->getName() : '',
  603.                             ];
  604.                         }
  605.                     }
  606.                     $userGroupListData[] = [
  607.                         'id' => $userGroup->getId(),
  608.                         'groupName_en' => $userGroup->getGroupName("en"),
  609.                         'detail_en' => $userGroup->getDetail("en"),
  610.                         'groupName_ar' => $userGroup->getGroupName("ar"),
  611.                         'detail_ar' => $userGroup->getDetail("ar"),
  612.                         'usersData' => $userListData
  613.                     ];
  614.                 }
  615.                 if (!empty($userGroupListData) && count($userGroupListData) > 0) {
  616.                     return ["success" => true"data" => $userGroupListData"paginationVariables" => $paginator->getPaginationData()];
  617.                 }
  618.             }
  619.             return ["success" => false"message" => $translator->trans("user_groups_are_not_available")];
  620.         } catch (\Exception $ex) {
  621.             throw new \Exception($ex->getMessage());
  622.         }
  623.         return $result;
  624.     }
  625.     public function userGroupDetail($user$userGroupId$translator): array
  626.     {
  627.         $result = [];
  628.         try {
  629.             $organization $user->getOrganization();
  630.             if (!$organization instanceof DataObject\Organization) {
  631.                 return ["success" => false"message" => $translator->trans("user_does_not_belongs_to_organization")];
  632.             }
  633.             $userGroupData = [];
  634.             $userListData = [];
  635.             $data = [];
  636.             $totalUsers  0;
  637.             //load user group
  638.             $userGroup = new DataObject\UserGroup\Listing();
  639.             $userGroup->setCondition("oo_id = ? ", [$userGroupId]);
  640.             $userGroup->filterByOrganization($organization);
  641.             $userGroup $userGroup->current();
  642.             if ($userGroup instanceof DataObject\UserGroup) {
  643.                 //get user group data   
  644.                 $userGroupData[] = [
  645.                     'id' => $userGroup->getId(),
  646.                     'groupName_en' => $userGroup->getGroupName("en"),
  647.                     'detail_en' => $userGroup->getDetail("en"),
  648.                     'groupName_ar' => $userGroup->getGroupName("ar"),
  649.                     'detail_ar' => $userGroup->getDetail("ar"),
  650.                 ];
  651.                 //get all users available in above user group
  652.                 $customers = new DataObject\Customer\Listing();
  653.                 $customers->filterByOrganization($organization);
  654.                 $customers->filterByUserGroup($userGroup);
  655.                 $customers->filterByIsActive(true);
  656.                 if ($customers->getCount() > 0) {
  657.                     $totalUsers $customers->getCount();
  658.                     foreach ($customers as $key => $customer) {
  659.                         if ($customer instanceof DataObject\Customer) {
  660.                             //get user  data   
  661.                             $userListData[] = [
  662.                                 'id' => $customer->getId(),
  663.                                 'name' => $customer->getName(),
  664.                                 'email' => $customer->getEmail(),
  665.                                 'role' => $customer->getRole() ? $customer->getRole()->getName() : null,
  666.                                 'department' => $customer->getDepartment(),
  667.                                 'titile' => $customer->getTitle()
  668.                             ];
  669.                         }
  670.                     }
  671.                     // store all data in data array
  672.                     $data[] = [
  673.                         "userGroupData" => $userGroupData,
  674.                         "totalUsers" => $totalUsers,
  675.                         "users" => $userListData
  676.                     ];
  677.                     if (!empty($data) && count($data) > 0) {
  678.                         return ["success" => true"data" => $data];
  679.                     }
  680.                 }
  681.             }
  682.             return ["success" => false"message" => $translator->trans("user_group_is_not_available")];
  683.         } catch (\Exception $ex) {
  684.             throw new \Exception($ex->getMessage());
  685.         }
  686.         return $result;
  687.     }
  688.     public function updateProfile($params$translator): array
  689.     {
  690.         $result = [];
  691.         try {
  692.             $updateUser DataObject\Customer::getById($params['id'], true);
  693.             if ($updateUser) {
  694.                 try {
  695.                     $updateUser->setName(strip_tags($params['name']));
  696.                     $updateUser->setDepartment(strip_tags($params['department']));
  697.                     $updateUser->setTitle(strip_tags($params['title']));
  698.                     if (isset($params['isTwoFactorAuth'])) {
  699.                         if ($params['isTwoFactorAuth'] == true) {
  700.                             $updateUser->setTwoFactorAuth(true);
  701.                         } else {
  702.                             $updateUser->setTwoFactorAuth(false);
  703.                         }
  704.                     }
  705.                     if (isset($params['iqamaId']) && !empty($params['iqamaId'])) {
  706.                         if (\App\Lib\Utility::validateIqamaId($params['iqamaId'])) {
  707.                             $updateUser->setIqamaId($params['iqamaId']);
  708.                         } else {
  709.                             return ["success" => false"message" => $translator->trans("iqama_id_is_invalid")];
  710.                         }
  711.                     }
  712.                     if (!empty($params['phoneno'])) {
  713.                         $phoneNo trim($params['phoneno']);
  714.                         if (strlen($phoneNo) !== 9) {
  715.                             return ["success" => false"message" => $translator->trans("phone_no_must_be_9_digits")];
  716.                         } elseif (!ctype_digit($phoneNo)) {
  717.                             return ["success" => false"message" => $translator->trans("phone_no_must_be_numeric")];
  718.                         } else {
  719.                             $updateUser->setPhoneNo($phoneNo);
  720.                         }
  721.                     }
  722.                     $updateUser->save();
  723.                     if (!isset($params['from_ews']) && !isset($params['from_reporting'])) {
  724.                         unset($params["Authorization"]);
  725.                         $params["userEmail"] = $updateUser->getEmail();
  726.                         $params["from_portal"] = true;
  727.                         // Inform other systems
  728.                         // $this->ewsPortalModel->updateProfile($params);
  729.                         // $this->reportingPortalModel->updateProfile($params);
  730.                     }
  731.                     return ["success" => true"message" => $translator->trans("user_updated_successfully")];
  732.                 } catch (\Exception $ex) {
  733.                     return ["success" => false"message" => $translator->trans("user_not_updated_successfully")];
  734.                 }
  735.             }
  736.             return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  737.         } catch (\Exception $ex) {
  738.             throw new \Exception($ex->getMessage());
  739.         }
  740.         return $result;
  741.     }
  742.     /**
  743.      * forget user password
  744.      */
  745.     public function forgotPassword($request$email$httpOrigin$translator$templating)
  746.     {
  747.         $result = [];
  748.         try {
  749.             $lang $translator->getLocale();
  750.             $user DataObject\Customer::getByEmail($emailtrue);
  751.             if ($user instanceof \Pimcore\Model\DataObject\Customer) {
  752.                 //generate token
  753.                 $token md5($user->getId() . time() . uniqid());
  754.                 $user->setResetPasswordToken($token);
  755.                 //$user->setPasswordRecoveryTokenDate(Carbon::now());
  756.                 $user->save();
  757.                 $role = ($user->getRole()) ? $user->getRole()->getName() : null;
  758.                 $hostName $httpOrigin "/auth/reset-password?token=";
  759.                 if ($role == 'CLIENT_ADMIN' || $role == 'CLIENT_USER') {
  760.                     $subject $translator->trans("Reset Password to Join NCM Business Portal");
  761.                     $title $translator->trans("Meteo KSA");
  762.                 } else {
  763.                     $subject $translator->trans("Reset Password to Join NCM Admin Portal");
  764.                     $title $translator->trans("Meteo KSA Admin");
  765.                 }
  766.                 $param = [
  767.                     'userName' => $user->getName(),
  768.                     'tokenLink' => $hostName $token,
  769.                     'title' => $title,
  770.                 ];
  771.                 $html $templating->render('web2print/generic_mail.html.twig'$param);
  772.                 $templateId $_ENV['RESET_PASSWORD_TEMPLATE'];
  773.                 $purpose RESET_PASSWORD_MESSAGE;
  774.                 $result $this->c2Service->sendNotificationEmail($templateId$user->getId(), $user->getId(), $html$subject$purpose);
  775.                 //$result = $this->emailService->sendMail($param, $user->getEmail(), PASSWORD_RECOVERY_EMAIL_DOCUMENT_PATH, $subject);
  776.                 $translator->setLocale($lang);
  777.                 if ($result) {
  778.                     return ["success" => true"message" => $translator->trans("account_reset_mail_sent_when_possible")];
  779.                 }
  780.                 return ["success" => false"message" => $translator->trans("an_error_occured_while_sending_mail")];
  781.             } else {
  782.                 return ["success" => false"message" => $translator->trans("user_not_found")];
  783.             }
  784.         } catch (\Exception $ex) {
  785.             throw new \Exception($ex->getMessage());
  786.         }
  787.         return $result;
  788.     }
  789.     /**
  790.      * Reset user password
  791.      */
  792.     public function resetPassword($request$token$newPassword$conformNewPassword$translator): array
  793.     {
  794.         $result = [];
  795.         try {
  796.             //check if the token is valid
  797.             $user DataObject\Customer::getByResetPasswordToken($tokentrue);
  798.             if ($user instanceof \Pimcore\Model\DataObject\Customer) {
  799.                 if ($newPassword != $conformNewPassword) {
  800.                     return ["success" => false"message" => $translator->trans("new_password_and_conformNewPassword_not_matching")];
  801.                 }
  802.                 $user->setPassword($newPassword);
  803.                 $user->setResetPasswordToken(null);
  804.                 $user->save();
  805.                 if ($user) {
  806.                     return ["success" => true"message" => $translator->trans("password_updated_successifully")];
  807.                 }
  808.             } else {
  809.                 return ["success" => false"message" => $translator->trans("user_not_found_token_is_not_valid")];
  810.             }
  811.         } catch (\Exception $ex) {
  812.             throw new \Exception($ex->getMessage());
  813.         }
  814.         return $result;
  815.     }
  816.     /**
  817.      * Reset user password
  818.      */
  819.     public function changePassword($user$params$translator): array
  820.     {
  821.         $result = [];
  822.         try {
  823.             if ($params['newPassword'] != $params['confirmNewPassword']) {
  824.                 return ["success" => false"message" => $translator->trans("new_password_and_conformNewPassword_not_matching")];
  825.             }
  826.             if ($user) {
  827.                 if (password_verify(trim($params['oldPassword']), $user->getPassword())) {
  828.                     $user->setPassword($params['newPassword']);
  829.                     $user->save();
  830.                     if (!isset($params['from_ews']) && !isset($params['from_reporting'])) {
  831.                         unset($params["Authorization"]);
  832.                         $params["userEmail"] = $user->getEmail();
  833.                         $params["from_portal"] = true;
  834.                         // Inform other systems
  835.                         // $this->ewsPortalModel->changePassword($params);
  836.                         // $this->reportingPortalModel->changePassword($params);
  837.                     }
  838.                     return ["success" => true"message" => $translator->trans("password_updated_successifully")];
  839.                 } else {
  840.                     return ["success" => false"message" => $translator->trans("old_password_is_not_correct")];
  841.                 }
  842.             }
  843.             return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  844.         } catch (\Exception $ex) {
  845.             throw new \Exception($ex->getMessage());
  846.         }
  847.         return $result;
  848.     }
  849.     /**
  850.      * Get Public User Premissions
  851.      */
  852.     public function publicUserPermissions($translator): array
  853.     {
  854.         $result = [];
  855.         try {
  856.             $db Db::get();
  857.             $permissions $db->fetchAll("SELECT * FROM `policy`");
  858.             return ["success" => true"data" => $permissions];
  859.         } catch (\Exception $ex) {
  860.             throw new \Exception($ex->getMessage());
  861.         }
  862.         return $result;
  863.     }
  864.     /**
  865.      * Create Public User
  866.      */
  867.     public function addPublicUser($request$params$translator): array
  868.     {
  869.         $result = [];
  870.         try {
  871.             $user DataObject\PublicUser::getByName($params['name'], true);
  872.             if ($user instanceof DataObject\PublicUser) {
  873.                 return ["success" => false"message" => $translator->trans("This public user already exists.")];
  874.             }
  875.             $addPublicUser = new DataObject\PublicUser();
  876.             $addPublicUser->setParent(DataObject\Service::createFolderByPath('/UserManagement/PublicUsers/'));
  877.             $addPublicUser->setKey($params['name']);
  878.             $addPublicUser->setName($params['name']);
  879.             $addPublicUser->setStartDate(Carbon::parse($params['startDate']));
  880.             $addPublicUser->setEndDate(Carbon::parse($params['endDate']));
  881.             $addPublicUser->setPublished(true);
  882.             $addPublicUser->save();
  883.             if (!$addPublicUser->getId()) {
  884.                 throw new \Exception("Failed to create public user.");
  885.             }
  886.             $db Db::get();
  887.             foreach ($params['permissions'] as $parameter) {
  888.                 $permission $db->fetchOne("SELECT id FROM policy WHERE parameter = ?"$parameter);
  889.                 if ($permission) {
  890.                     $data = array(
  891.                         'user_id' => $addPublicUser->getId(),
  892.                         'policy_id' => $permission,
  893.                         'is_allowed' => 1
  894.                     );
  895.                     $insertResult $db->insert("user_policy"$data);
  896.                     if (!$insertResult) {
  897.                         throw new \Exception($translator->trans("Failed to associate permissions with the public user."));
  898.                     }
  899.                 } else {
  900.                     throw new \Exception($translator->trans("Permission not found for parameter: " $parameter));
  901.                 }
  902.             }
  903.             return ["success" => true"message" => $translator->trans("Public user created successfully.")];
  904.         } catch (\Exception $ex) {
  905.             return ["success" => false"message" => $ex->getMessage()];
  906.         }
  907.         return $result;
  908.     }
  909.     // public function deleteUser($request, $params, $translator): array
  910.     // {
  911.     //     $result = [];
  912.     //     // try {
  913.     //     $user = DataObject\Customer::getById($params['id'], true);
  914.     //     if ($user) {
  915.     //         // Deleting user location              
  916.     //         $locations = $this->locationModel->getLocationsByUserId($user->getId());
  917.     //         if ($locations) {
  918.     //             foreach ($locations as $location) {
  919.     //                 if ($location instanceof \Pimcore\Model\DataObject\Location) {
  920.     //                     $this->locationModel->deAssociateUserLocation($location, $user, $translator);
  921.     //                 }
  922.     //             }
  923.     //         }
  924.     //         // Deleting user custom notification
  925.     //         $customNotification = new \Pimcore\Model\DataObject\CustomNotification\Listing();
  926.     //         $customNotification->filterByUser($user);
  927.     //         foreach ($customNotification as $notification) {
  928.     //             $notification->delete();
  929.     //         }
  930.     //         $user->delete();
  931.     //         return ["success" => true, "message" => $translator->trans("user_deleted_successifully")];
  932.     //     }
  933.     //     return ["success" => false, "message" => $translator->trans("user_does_not_exists")];
  934.     //     // } catch (\Exception $ex) {
  935.     //     //     throw new \Exception($ex->getMessage());
  936.     //     // }
  937.     //     return $result;
  938.     // }
  939.     public function deleteUser($request$params$loggedInUser$translator$templating=null): array
  940.     {
  941.         $result = [];
  942.         // Check if the user is already deleted
  943.         $deletedUsers = new DataObject\DeletedUsersData\Listing();
  944.         $deletedUsers->filterByPimId($params['id']);
  945.         $deletedUsers->filterByIsDeleted(true);
  946.         $check $deletedUsers->current();
  947.         if ($check instanceof DataObject\DeletedUsersData) {
  948.             return ["success" => false"message" => $translator->trans("user_already_deleted")];
  949.         }
  950.         // Fetch the user by ID
  951.         $user DataObject\Customer::getById($params['id'], true);
  952.         
  953.         if (!$user) {
  954.             return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  955.         }
  956.         // Check if user is already deleted (in archive)
  957.         if ($user->getIsArchive()) {
  958.             return ["success" => false"message" => $translator->trans("user_already_archived")];
  959.         }
  960.         
  961.         // Check if the delete request comes from a super admin
  962.         $isSuperAdmin $loggedInUser->getIsSuperAdmin();
  963.         
  964.         if ($isSuperAdmin) {
  965.             // If super admin, directly archive the user
  966.             $user->setIsArchive(true);
  967.             $user->setIsDeleted(false);
  968.             $user->save();
  969.             
  970.             // Update created-by references: mark status as deleted and clear relation
  971.             $createdUsers = new DataObject\Customer\Listing();
  972.             $createdUsers->filterByCreatedBy($user);
  973.             foreach ($createdUsers as $createdUser) {
  974.                 if ($createdUser instanceof DataObject\Customer) {
  975.                     $createdUser->setCreatedBy(null);
  976.                     $createdUser->setCreatedByUserStatus('deleted');
  977.                     $createdUser->save();
  978.                 }
  979.             }
  980.             
  981.             // Create a deleted user record with reason "deleted by super admin"
  982.             $deleteUserRecord = new DataObject\DeletedUsersData();
  983.             $deleteUserRecord->setParent(DataObject\Service::createFolderByPath('/UserManagement/DeletedUsers/'));
  984.             $deleteUserRecord->setKey($user->getName() . strtotime("now") . rand(0100));
  985.             $deleteUserRecord->setName($user->getName());
  986.             $deleteUserRecord->setEmail($user->getEmail());
  987.             $deleteUserRecord->setPimId($user->getId());
  988.             $deleteUserRecord->setOrganizationName($user->getOrganization() ? $user->getOrganization()->getName() : '');
  989.             $deleteUserRecord->setRole($user->getRole() ? $user->getRole()->getName() : '');
  990.             $deleteUserRecord->setIsDeleted(true); // true = deleted by super admin
  991.             $deleteUserRecord->setDeletedBy($loggedInUser->getEmail());
  992.             $deleteUserRecord->setReason('deleted by super admin');
  993.             $deleteUserRecord->setPublished(true);
  994.             $deleteUserRecord->save();
  995.             
  996.             return ["success" => true"message" => $translator->trans("user_deleted_by_super_admin")];
  997.         }
  998.         
  999.         // Mark user for deletion (soft delete - request for approval)
  1000.         $user->setIsDeleted(true);
  1001.         $user->save();
  1002.         // Update created-by references: mark status as deleted and clear relation
  1003.         $createdUsers = new DataObject\Customer\Listing();
  1004.         $createdUsers->filterByCreatedBy($user);
  1005.         foreach ($createdUsers as $createdUser) {
  1006.             if ($createdUser instanceof DataObject\Customer) {
  1007.                 $createdUser->setCreatedBy(null);
  1008.                 $createdUser->setCreatedByUserStatus('deleted');
  1009.                 $createdUser->save();
  1010.             }
  1011.         }
  1012.         // Create a deleted user record
  1013.         $deleteUserRecord = new DataObject\DeletedUsersData();
  1014.         $deleteUserRecord->setParent(DataObject\Service::createFolderByPath('/UserManagement/DeletedUsers/'));
  1015.         $deleteUserRecord->setKey($user->getName() . strtotime("now") . rand(0100));
  1016.         $deleteUserRecord->setName($user->getName());
  1017.         $deleteUserRecord->setEmail($user->getEmail());
  1018.         $deleteUserRecord->setPimId($user->getId());
  1019.         $deleteUserRecord->setOrganizationName($user->getOrganization() ? $user->getOrganization()->getName() : '');
  1020.         $deleteUserRecord->setRole($user->getRole() ? $user->getRole()->getName() : '');
  1021.         $deleteUserRecord->setIsDeleted(false); // false = pending approval
  1022.         $deleteUserRecord->setDeletedBy($loggedInUser->getEmail());
  1023.         $deleteUserRecord->setReason(isset($params['reason']) ? trim($params['reason']) : '');
  1024.         $deleteUserRecord->setPublished(true);
  1025.         $deleteUserRecord->save();
  1026.         if($templating != null){
  1027.             
  1028.             // Send email notification to super admin users
  1029.             $this->notifySuperAdminsForDeletion($user$loggedInUser$params['reason'],$translator,  $templating);
  1030.         }
  1031.         
  1032.         return ["success" => true"message" => $translator->trans("user_deletion_request_sent_for_approval")];
  1033.     }
  1034.     public function deleteNcmUser($request$params$loggedInUser$translator$templating null): array
  1035.     {
  1036.         $result = [];
  1037.         try {
  1038.             $deletedUsers = new DataObject\DeletedUsersData\Listing();
  1039.             $deletedUsers->filterByPimId($params['id']);
  1040.             $deletedUsers->filterByIsDeleted(false);
  1041.             $check $deletedUsers->current();
  1042.             if ($check instanceof DataObject\DeletedUsersData) {
  1043.                 return ["success" => false"message" => $translator->trans("user_already_deleted")];
  1044.             }
  1045.             // Fetch the user by ID
  1046.             $user DataObject\Customer::getById($params['id'], true);
  1047.             if (!$user) {
  1048.                 return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  1049.             }
  1050.             $user->setToken(null);
  1051.             $user->setIsDeleted(true);
  1052.             $user->setPublished(false);
  1053.             $user->save();
  1054.             $createdUsers = new DataObject\Customer\Listing();
  1055.             $createdUsers->filterByCreatedBy($user);
  1056.             foreach ($createdUsers as $createdUser) {
  1057.                 if ($createdUser instanceof DataObject\Customer) {
  1058.                     $createdUser->setCreatedBy(null);
  1059.                     $createdUser->setCreatedByUserStatus('deleted');
  1060.                     $createdUser->save();
  1061.                 }
  1062.             }
  1063.             $deleteUserRecord = new DataObject\DeletedUsersData();
  1064.             $deleteUserRecord->setParent(DataObject\Service::createFolderByPath('/UserManagement/DeletedUsers/'));
  1065.             $deleteUserRecord->setKey($user->getName() . strtotime("now") . rand(0100));
  1066.             $deleteUserRecord->setName($user->getName());
  1067.             $deleteUserRecord->setEmail($user->getEmail());
  1068.             $deleteUserRecord->setPimId($user->getId());
  1069.             $deleteUserRecord->setOrganizationName($user->getOrganization() ? $user->getOrganization()->getName() : '');
  1070.             $deleteUserRecord->setRole($user->getRole() ? $user->getRole()->getName() : '');
  1071.             $deleteUserRecord->setIsDeleted(false);
  1072.             $deleteUserRecord->setDeletedBy($loggedInUser->getEmail());
  1073.             $deleteUserRecord->setPublished(true);
  1074.             $deleteUserRecord->save();
  1075.             $locations $this->locationModel->getLocationsByUserId($user->getId());
  1076.             if ($locations) {
  1077.                 foreach ($locations as $location) {
  1078.                     if ($location instanceof \Pimcore\Model\DataObject\Location) {
  1079.                         $this->locationModel->deAssociateUserLocation($location$user$translator);
  1080.                     }
  1081.                 }
  1082.             }
  1083.             // Delete user custom notifications
  1084.             $customNotification = new \Pimcore\Model\DataObject\CustomNotification\Listing();
  1085.             $customNotification->filterByUser($user);
  1086.             foreach ($customNotification as $notification) {
  1087.                 $notification->delete();
  1088.             }
  1089.             $dashboard = new DataObject\Dashboard\Listing();
  1090.             $dashboard->setCondition('user__id = ?', [$user->getId()]);
  1091.             if ($dashboard->current() instanceof DataObject\Dashboard) {
  1092.                 $dashboard->current()->delete();
  1093.             }
  1094.             $subscriptions = new DataObject\Subscription\Listing();
  1095.             $subscriptions->setCondition('subscribedUser__id = ?', [$user->getId()]);
  1096.             foreach ($subscriptions as $subscription) {
  1097.                 if ($subscription instanceof DataObject\Subscription) {
  1098.                     $subscription->delete();
  1099.                 }
  1100.             }
  1101.             $user->delete();
  1102.             $deleteUserRecord->setIsDeleted(true);
  1103.             $deleteUserRecord->save();
  1104.             return ["success" => true"message" => $translator->trans("user_deleted_successfully")];
  1105.         }
  1106.         catch (\Exception $ex) {
  1107.             throw new \Exception($ex->getMessage());
  1108.         }
  1109.         return $result;
  1110.     }
  1111.     /**
  1112.      * Un-archive user
  1113.      */
  1114.     public function unArchiveUser($request$userId$loggedInUser$translator$templating null): array
  1115.     {
  1116.         $result = [];
  1117.         
  1118.         // Fetch the user by ID
  1119.         $user DataObject\Customer::getById($userIdtrue);  
  1120.         if (!$user) {
  1121.             return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  1122.         }
  1123.         
  1124.         // Check if user is already un-archived
  1125.         if (!$user->getIsArchive()) {
  1126.             return ["success" => false"message" => $translator->trans("user_already_un_archived")];
  1127.         }
  1128.         $deletedUsers = new DataObject\DeletedUsersData\Listing();
  1129.         $deletedUsers->filterByPimId($userId);
  1130.         $deletedUsers->filterByIsDeleted(true);
  1131.         $deleteUserRecord $deletedUsers->current();
  1132.         if (!$deleteUserRecord instanceof DataObject\DeletedUsersData) {
  1133.             return ["success" => false"message" => $translator->trans("no_pending_deletion_request")];
  1134.         }
  1135.         
  1136.         // set archive to false (move to active)
  1137.         $user->setIsArchive(false);
  1138.         $user->setIsDeleted(false);
  1139.         $user->save();
  1140.         $deleteUserRecord = new DataObject\DeletedUsersData();
  1141.         $deleteUserRecord->setParent(DataObject\Service::createFolderByPath('/UserManagement/DeletedUsers/'));
  1142.         $deleteUserRecord->setKey($user->getName() . strtotime("now") . rand(0100));
  1143.         $deleteUserRecord->setName($user->getName());
  1144.         $deleteUserRecord->setEmail($user->getEmail());
  1145.         $deleteUserRecord->setPimId($user->getId());
  1146.         $deleteUserRecord->setOrganizationName($user->getOrganization() ? $user->getOrganization()->getName() : '');
  1147.         $deleteUserRecord->setRole($user->getRole() ? $user->getRole()->getName() : '');
  1148.         $deleteUserRecord->setIsDeleted(false); // false = un-deleted
  1149.         $deleteUserRecord->setDeletedBy($loggedInUser->getEmail());
  1150.         $deleteUserRecord->setPublished(true);
  1151.         $deleteUserRecord->setReason('un-archive by super admin');
  1152.         $deleteUserRecord->save();
  1153.         
  1154.         // Delete all existing DeletedUsersData records for this un-archived user (excluding the newly created un-archive record)
  1155.         $existingDeletedUsers = new DataObject\DeletedUsersData\Listing();
  1156.         $existingDeletedUsers->filterByPimId($user->getId());
  1157.         foreach ($existingDeletedUsers as $existingRecord) {
  1158.             if ($existingRecord instanceof DataObject\DeletedUsersData && $existingRecord->getId() !== $deleteUserRecord->getId()) {
  1159.                 $existingRecord->delete();
  1160.             }
  1161.         }
  1162.         
  1163.         // Send email notification to the user
  1164.         if ($templating != null) {
  1165.             $this->notifyUserForUnArchive($user$loggedInUser$translator$templating);
  1166.         }
  1167.         
  1168.         return ["success" => true"message" => $translator->trans("user_un_archive_successfully")];
  1169.     }
  1170.     /**
  1171.      * Approve user deletion - finalize the deletion process
  1172.      */
  1173.     public function approveUserDeletion($request$params$loggedInUser$translator$templating null): array
  1174.     {
  1175.         $result = [];
  1176.         // Normalize ID - handle if it comes as an array
  1177.         $userId is_array($params['id']) ? (isset($params['id'][0]) ? $params['id'][0] : null) : $params['id'];
  1178.         
  1179.         if (empty($userId)) {
  1180.             return ["success" => false"message" => $translator->trans("missing_required_parameter_user_id")];
  1181.         }
  1182.         // Check if there's a pending deletion request
  1183.         $deletedUsers = new DataObject\DeletedUsersData\Listing();
  1184.         $deletedUsers->filterByPimId($userId);
  1185.         $deletedUsers->filterByIsDeleted(false);
  1186.         $deleteUserRecord $deletedUsers->current();
  1187.         if (!$deleteUserRecord instanceof DataObject\DeletedUsersData) {
  1188.             return ["success" => false"message" => $translator->trans("no_pending_deletion_request")];
  1189.         }
  1190.         // Fetch the user by ID
  1191.         $user DataObject\Customer::getById($userIdtrue);
  1192.         if (!$user) {
  1193.             return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  1194.         }
  1195.         // set archive to true (move to archive)
  1196.        
  1197.         $user->setIsArchive(true);
  1198.         $user->save();
  1199.         $deleteUserRecord = new DataObject\DeletedUsersData();
  1200.         $deleteUserRecord->setParent(DataObject\Service::createFolderByPath('/UserManagement/DeletedUsers/'));
  1201.         $deleteUserRecord->setKey($user->getName() . strtotime("now") . rand(0100));
  1202.         $deleteUserRecord->setName($user->getName());
  1203.         $deleteUserRecord->setEmail($user->getEmail());
  1204.         $deleteUserRecord->setPimId($user->getId());
  1205.         $deleteUserRecord->setOrganizationName($user->getOrganization() ? $user->getOrganization()->getName() : '');
  1206.         $deleteUserRecord->setRole($user->getRole() ? $user->getRole()->getName() : '');
  1207.         $deleteUserRecord->setIsDeleted(true); // true = deleted approved by super admin
  1208.         $deleteUserRecord->setDeletedBy($loggedInUser->getEmail());
  1209.         $deleteUserRecord->setReason(isset($params['reason']) ? trim($params['reason']) : '');
  1210.         $deleteUserRecord->setPublished(true);
  1211.         $deleteUserRecord->save();
  1212.         
  1213.         // Send email notification to the user
  1214.         if ($templating != null) {
  1215.             $this->notifyUserForArchive($user$loggedInUser$translator$templating);
  1216.         }
  1217.         
  1218.         return ["success" => true"message" => $translator->trans("user_deletion_approved_and_moved_to_archive")];
  1219.     }
  1220.     /**
  1221.      * Reject user deletion - undo the deletion request
  1222.      */
  1223.     public function rejectUserDeletion($request$params$loggedInUser$translator): array
  1224.     {
  1225.         $result = [];
  1226.         // Normalize ID - handle if it comes as an array
  1227.         $userId is_array($params['id']) ? (isset($params['id'][0]) ? $params['id'][0] : null) : $params['id'];
  1228.         
  1229.         if (empty($userId)) {
  1230.             return ["success" => false"message" => $translator->trans("missing_required_parameter_user_id")];
  1231.         }
  1232.         // Check if there's a pending deletion request
  1233.         $deletedUsers = new DataObject\DeletedUsersData\Listing();
  1234.         $deletedUsers->filterByPimId($userId);
  1235.         $deletedUsers->filterByIsDeleted(false);
  1236.         $deleteUserRecord $deletedUsers->current();
  1237.         if (!$deleteUserRecord instanceof DataObject\DeletedUsersData) {
  1238.             return ["success" => false"message" => $translator->trans("no_pending_deletion_request")];
  1239.         }
  1240.         // Fetch the user by ID
  1241.         $user DataObject\Customer::getById($userIdtrue);
  1242.         if (!$user) {
  1243.             return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  1244.         }
  1245.         // Reject deletion: set isDeleted to false to undo the deletion request
  1246.         $user->setIsDeleted(false);
  1247.         $user->save();
  1248.         // Delete the pending deletion request record
  1249.         $deleteUserRecord->delete();
  1250.         return ["success" => true"message" => $translator->trans("user_deletion_rejected")];
  1251.     }
  1252.     
  1253.     
  1254.    
  1255.     /**
  1256.      * Get all super admin users (NCM_IT role and users with IsSuperAdmin checkbox)
  1257.      */
  1258.     private function getSuperAdminUsers(): array
  1259.     {
  1260.         $superAdmins = [];
  1261.         
  1262.         // Get users with IsSuperAdmin checkbox checked
  1263.         $isSuperAdminUsers = new DataObject\Customer\Listing();
  1264.         $isSuperAdminUsers->filterByIsSuperAdmin(1);
  1265.         $isSuperAdminUsers->setUnpublished(true);
  1266.         foreach ($isSuperAdminUsers as $admin) {
  1267.             if ($admin instanceof DataObject\Customer && !$admin->getIsDeleted()) {
  1268.                 $superAdmins[] = [
  1269.                     'email' => $admin->getEmail(),
  1270.                     'name' => $admin->getName()
  1271.                 ];
  1272.             }
  1273.         }
  1274.         // Remove duplicates based on email
  1275.         $uniqueAdmins = [];
  1276.         $emails = [];
  1277.         foreach ($superAdmins as $admin) {
  1278.             if (!in_array($admin['email'], $emails)) {
  1279.                 $emails[] = $admin['email'];
  1280.                 $uniqueAdmins[] = $admin;
  1281.             }
  1282.         }
  1283.         return $uniqueAdmins;
  1284.     }
  1285.     /**
  1286.      * Send email notification to super admin users about user deletion request
  1287.      */
  1288.     private function notifySuperAdminsForDeletion($user$loggedInUser$reason$translator$templating): void
  1289.     {
  1290.        
  1291.         try {
  1292.             $superAdmins $this->getSuperAdminUsers();
  1293.             if (empty($superAdmins)) {
  1294.                 return; // No super admins to notify
  1295.             }
  1296.             // Prepare email parameters
  1297.             $emailParams = [
  1298.                 'adminName' => $loggedInUser->getName(),
  1299.                 'userName' => $user->getName(),
  1300.                 'userEmail' => $user->getEmail(),
  1301.                 'userRole' => $user->getRole() ? $user->getRole()->getName() : '',
  1302.                 'organizationName' => $user->getOrganization() ? $user->getOrganization()->getName() : '',
  1303.                 'deletedBy' => $loggedInUser->getName() . ' (' $loggedInUser->getEmail() . ')',
  1304.                 'userId' => $user->getId(),
  1305.                 'reason'=>$reason,
  1306.                 'host'=>API_BASE_URL,
  1307.             ];
  1308.             $subject $translator->trans("user_deletion_request_notification_subject", [], null$translator->getLocale());
  1309.             if (empty($subject) || $subject === "user_deletion_request_notification_subject") {
  1310.                 $subject "طلب حذف مستخدم - User Deletion Request";
  1311.             }
  1312.             // Send email to each super admin
  1313.             foreach ($superAdmins as $admin) {
  1314.                 error_log("Sending deletion notification email to " $admin['email']);
  1315.                 try {
  1316.                     
  1317.                     // Generate HTML content from email parameters
  1318.                     $html $templating->render('email/user_deletion_request_template.html.twig'$emailParams);
  1319.                     $templateId 32;
  1320.                     $objectId $user->getId();
  1321.                     $purpose "user deletion request notification";
  1322.                     $this->c2Service->sendDefaultEmail($templateId$objectId$admin['email'], $html$subject$purpose);
  1323.                 } catch (\Exception $ex) {
  1324.                     // Log error but continue with other admins
  1325.                     error_log("Failed to send deletion notification email to " $admin['email'] . ": " $ex->getMessage());
  1326.                 }
  1327.             }
  1328.         } catch (\Exception $ex) {
  1329.             // Log error but don't fail the deletion request
  1330.             error_log("Error in notifySuperAdminsForDeletion: " $ex->getMessage());
  1331.         }
  1332.     }
  1333.     /**
  1334.      * Send email notification to user about un-archive
  1335.      */
  1336.     private function notifyUserForUnArchive($user$loggedInUser$translator$templating): void
  1337.     {
  1338.         try {
  1339.             // Check if user has email
  1340.             if (empty($user->getEmail())) {
  1341.                 error_log("User " $user->getId() . " does not have an email address");
  1342.                 return;
  1343.             }
  1344.             // Prepare email parameters
  1345.             $emailParams = [
  1346.                 'adminName' => $loggedInUser->getName(),
  1347.                 'userName' => $user->getName(),
  1348.                 'userEmail' => $user->getEmail(),
  1349.                 'userRole' => $translator->trans$user->getRole() ? $user->getRole()->getName() : ''),
  1350.                 'organizationName' => $user->getOrganization() ? $user->getOrganization()->getName() : '',
  1351.                 'unArchivedBy' => $loggedInUser->getName() . ' (' $loggedInUser->getEmail() . ')',
  1352.                 'userId' => $user->getId(),
  1353.                 'host' => API_BASE_URL,
  1354.             ];
  1355.             $subject $translator->trans("user_un_archive_notification_subject", [], null$translator->getLocale());
  1356.             if (empty($subject) || $subject === "user_un_archive_notification_subject") {
  1357.                 $subject "إعادة تفعيل المستخدم - User Un-Archive Notification";
  1358.             }
  1359.             error_log("Sending un-archive notification email to " $user->getEmail());
  1360.             try {
  1361.                 // Generate HTML content from email parameters
  1362.                 $html $templating->render('email/user_un_archive_template.html.twig'$emailParams);
  1363.                 $templateId 32;
  1364.                 $objectId $user->getId();
  1365.                 $purpose "user un-archive notification";
  1366.                 $this->c2Service->sendDefaultEmail($templateId$objectId$user->getEmail(), $html$subject$purpose);
  1367.             } catch (\Exception $ex) {
  1368.                 // Log error but don't fail the un-archive process
  1369.                 error_log("Failed to send un-archive notification email to " $user->getEmail() . ": " $ex->getMessage());
  1370.             }
  1371.         } catch (\Exception $ex) {
  1372.             // Log error but don't fail the un-archive process
  1373.             error_log("Error in notifyUserForUnArchive: " $ex->getMessage());
  1374.         }
  1375.     }
  1376.     /**
  1377.      * Send email notification to user about archive
  1378.      */
  1379.     private function notifyUserForArchive($user$loggedInUser$translator$templating): void
  1380.     {
  1381.         try {
  1382.             // Check if user has email
  1383.             if (empty($user->getEmail())) {
  1384.                 error_log("User " $user->getId() . " does not have an email address");
  1385.                 return;
  1386.             }
  1387.             // Prepare email parameters
  1388.             $emailParams = [
  1389.                 'adminName' => $loggedInUser->getName(),
  1390.                 'userName' => $user->getName(),
  1391.                 'userEmail' => $user->getEmail(),
  1392.                 'userRole' => $translator->trans$user->getRole() ? $user->getRole()->getName() : ''),
  1393.                 'organizationName' => $user->getOrganization() ? $user->getOrganization()->getName() : '',
  1394.                 'archivedBy' => $loggedInUser->getName() . ' (' $loggedInUser->getEmail() . ')',
  1395.                 'userId' => $user->getId(),
  1396.                 'host' => API_BASE_URL,
  1397.             ];
  1398.             $subject $translator->trans("user_archive_notification_subject", [], null$translator->getLocale());
  1399.             if (empty($subject) || $subject === "user_archive_notification_subject") {
  1400.                 $subject "أرشفة المستخدم - User Archive Notification";
  1401.             }
  1402.             error_log("Sending archive notification email to " $user->getEmail());
  1403.             try {
  1404.                 // Generate HTML content from email parameters
  1405.                 $html $templating->render('email/user_archive_template.html.twig'$emailParams);
  1406.                 $templateId 32;
  1407.                 $objectId $user->getId();
  1408.                 $purpose "user archive notification";
  1409.                 $this->c2Service->sendDefaultEmail($templateId$objectId$user->getEmail(), $html$subject$purpose);
  1410.             } catch (\Exception $ex) {
  1411.                 // Log error but don't fail the archive process
  1412.                 error_log("Failed to send archive notification email to " $user->getEmail() . ": " $ex->getMessage());
  1413.             }
  1414.         } catch (\Exception $ex) {
  1415.             // Log error but don't fail the archive process
  1416.             error_log("Error in notifyUserForArchive: " $ex->getMessage());
  1417.         }
  1418.     }
  1419.     /**
  1420.      * Get Client User Organization List
  1421.      */
  1422.     public function getClientUsers($request$user$params$paginator$translator)
  1423.     {
  1424.         $result = [];
  1425.         $userData = [];
  1426.         // try {
  1427.         // Get All the Classes
  1428.         $class = new \Pimcore\Model\DataObject\ClassDefinition();
  1429.         $customer $class->getDao()->getIdByName('Customer');
  1430.         $subscription $class->getDao()->getIdByName('Subscription');
  1431.         $userRole $class->getDao()->getIdByName('UserRole');
  1432.         $organization $class->getDao()->getIdByName('Organization');
  1433.         $package $class->getDao()->getIdByName('Package');
  1434.         $db Db::get();
  1435.         $select $db->createQueryBuilder();
  1436.         $select->select('customer.oo_id');
  1437.         $select->from('object_' $customer'customer');
  1438.         // $select->andWhere("customer.isArchive = 0");
  1439.         // Use LEFT JOIN for subscriptions to handle suspended users (users without subscriptions)
  1440.         $select->leftJoin('customer''object_' $subscription'subscription''customer.oo_id = subscription.subscribedUser__id');
  1441.         $select->leftJoin('subscription''object_' $package'package''package.oo_id = subscription.subscribedPackage__id');
  1442.         $select->innerJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  1443.         $select->innerJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  1444.         // Use placeholders to prevent SQL injection
  1445.         if (isset($params['clientType']) && !empty($params['clientType'])) {
  1446.             $select->Where("organization.clientType = " $db->quote($params['clientType']));
  1447.         }
  1448.         if (isset($params['organization_id']) && !empty($params['organization_id'])) {
  1449.             $select->andWhere("organization.oo_id = " $db->quote($params['organization_id']));
  1450.         }
  1451.         if (isset($params['package_id']) && !empty($params['package_id'])) {
  1452.             $select->andWhere("package.oo_id = " $db->quote($params['package_id']));
  1453.         }
  1454.         if (isset($params['search']) && !empty($params['search'])) {
  1455.             $select->andWhere("customer.name LIKE " $db->quote("%" $params['search'] . "%") . " OR customer.email LIKE " $db->quote("%" $params['search'] . "%"));
  1456.         }
  1457.         // Filter for archived users: archive =  , isDeleted and all
  1458.         if (isset($params['type']) ) {
  1459.             switch ($params['type']) {
  1460.                 case 'archive':
  1461.                     $select->andWhere("customer.isArchive = 1");
  1462.                     break;
  1463.                 case 'delete_pending':
  1464.                     $select->andWhere("(customer.isDeleted = 1 AND (customer.isArchive = 0 OR customer.isArchive IS NULL))");
  1465.                     break;
  1466.                 case 'all':
  1467.                     $select->andWhere("customer.isArchive = 0 OR customer.isArchive is NULL" );
  1468.                     break;
  1469.             }
  1470.         }
  1471.         if (isset($params['userStatus']) && !empty($params['userStatus'])) {
  1472.             $filterStatus strtolower(trim($params['userStatus']));
  1473.             // Validate that the filter status is one of the allowed values
  1474.             $allowedStatuses = ['pending''active''suspended''activepending'];
  1475.             if (in_array($filterStatus$allowedStatuses)) {
  1476.                 switch ($filterStatus) {
  1477.                     case 'pending':
  1478.                         // Pending: user is unpublished, no custom subscription, has default subscription
  1479.                         $select->andWhere("customer.o_published = 0");
  1480.                         $select->andWhere("subscription.subscriptionType != 'custom'");
  1481.                         $select->andWhere("subscription.subscribedUser__id IS NOT NULL");
  1482.                         $select->andWhere("subscription.isWso IS NULL OR subscription.isWso = 0");
  1483.                         $select->andWhere("userRole.name IN ('CLIENT_USER', 'CLIENT_ADMIN')");
  1484.                         break;
  1485.                     case 'active':
  1486.                         // Active: user is published, has custom subscription, isActive = true
  1487.                         $select->andWhere("customer.o_published = 1");
  1488.                         $select->andWhere("subscription.subscriptionType = 'custom'");
  1489.                         $select->andWhere("subscription.subscribedUser__id IS NOT NULL");
  1490.                         $select->andWhere("subscription.isActive = 1");
  1491.                         $select->andWhere("subscription.isWso IS NULL OR subscription.isWso = 0");
  1492.                         $select->andWhere("userRole.name IN ('CLIENT_USER', 'CLIENT_ADMIN')");
  1493.                         break;
  1494.                     case 'suspended':
  1495.                         // Suspended: user is published, has custom subscription, isActive = false
  1496.                         $select->andWhere("customer.o_published = 1");
  1497.                         $select->andWhere("subscription.subscriptionType = 'custom'");
  1498.                         $select->andWhere("subscription.subscribedUser__id IS NOT NULL");
  1499.                         $select->andWhere("subscription.isActive = 0");
  1500.                         break;
  1501.                     
  1502.                     case 'activepending':
  1503.                         // Active OR Pending
  1504.                         $select->andWhere("((customer.o_published = 0 AND subscription.subscriptionType != 'custom' AND subscription.subscribedUser__id IS NOT NULL) OR (customer.o_published = 1 AND subscription.subscriptionType = 'custom' AND subscription.subscribedUser__id IS NOT NULL AND subscription.isActive = 1))");
  1505.                         $select->andWhere("subscription.isWso IS NULL OR subscription.isWso = 0");
  1506.                         $select->andWhere("userRole.name IN ('CLIENT_USER', 'CLIENT_ADMIN')");
  1507.                         break;
  1508.                 }
  1509.             }
  1510.         }
  1511.         $select->andWhere("userRole.name = " $db->quote(USER_ROLES['CLIENT_ADMIN']) . " OR userRole.name = " $db->quote(USER_ROLES['CLIENT_USER']));
  1512.         $select->andWhere("customer.oo_id != " $db->quote($user->getId()));
  1513.         // $select->andWhere("customer.isDeleted != 1 OR customer.isDeleted IS NULL");
  1514.         $select->andWhere("customer.organization__id IS NOT NULL");
  1515.         $groupByFields = ['customer.oo_id'];
  1516.         $hasSorting false;
  1517.         // Dynamic sorting logic with orderKey and order
  1518.         $orderKey $params['orderKey'] ?? null;
  1519.         $order $params['order'] ?? 'asc';
  1520.         // Validate order parameter
  1521.         if (!in_array(strtolower($order), ['asc''desc'])) {
  1522.             $order 'asc';
  1523.         }
  1524.         // Map orderKey to database fields
  1525.         $sortingMap = [
  1526.             'created' => 'customer.o_creationDate',
  1527.             'username' => 'customer.name',
  1528.             'email' => 'customer.email',
  1529.             'role' => 'userRole.name',
  1530.             'entityType' => 'organization.clientType',
  1531.             'packageExpiry' => 'subscription.endDate',
  1532.             'packageName' => 'localized_package.packageName',
  1533.             'entityName' => 'localized_organization.name'
  1534.         ];
  1535.         if ($orderKey && isset($sortingMap[$orderKey])) {
  1536.             $field $sortingMap[$orderKey];
  1537.             // Handle special cases that require joins
  1538.             if ($orderKey === 'packageName') {
  1539.                 $localizedPackageTable 'object_localized_packages_' . ($params['lang'] ?? 'en');
  1540.                 $select->leftJoin('package'$localizedPackageTable'localized_package''localized_package.ooo_id = package.oo_id');
  1541.                 $groupByFields[] = 'localized_package.packageName';
  1542.             } elseif ($orderKey === 'entityName') {
  1543.                 $localizedOrgTable 'object_localized_organization_' . ($params['lang'] ?? 'en');
  1544.                 $select->leftJoin('organization'$localizedOrgTable'localized_organization''localized_organization.ooo_id = organization.oo_id');
  1545.                 $groupByFields[] = 'localized_organization.name';
  1546.             } else {
  1547.                 $groupByFields[] = $field;
  1548.             }
  1549.             $select->orderBy($fieldstrtoupper($order));
  1550.             $hasSorting true;
  1551.         }
  1552.         // If no sort param given, apply default sort and group
  1553.         if (!$hasSorting) {
  1554.             $select->orderBy('customer.oo_id''DESC');
  1555.             $groupByFields = ['customer.oo_id'];
  1556.         }
  1557.         // Final groupBy
  1558.         $select->groupBy(array_unique($groupByFields));
  1559.         // dd( $select->getSQL());
  1560.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  1561.         $page = isset($params['page']) ? $params['page'] : 1;
  1562.         $paginator $paginator->paginate(
  1563.             $select,
  1564.             $page,
  1565.             $pageSize
  1566.         );
  1567.         foreach ($paginator as $usersId) {
  1568.             $usersData DataObject\Customer::getById($usersId['oo_id'], true);
  1569.             if ($usersData instanceof \Pimcore\Model\DataObject\Customer) {
  1570.                 // Get Custom Subscription of the organization and package
  1571.                 $customSubscriptions = new DataObject\Subscription\Listing();
  1572.                 $customSubscriptions->filterBySubscribedUser($usersData);
  1573.                 $customSubscriptions->filterByIsActive(true);
  1574.                 $status "Pending";
  1575.                 if ($usersData->getToken() == "" && $usersData->isPublished() == true) {
  1576.                     if ($customSubscriptions->count() > 0) {
  1577.                         $status "Active";
  1578.                     } else {
  1579.                         $status "Suspended";
  1580.                     }
  1581.                 } elseif ($usersData->getToken() != "" && $usersData->isPublished() == false) {
  1582.                     if ($customSubscriptions->count() > 0) {
  1583.                         $status "Pending";
  1584.                     } else {
  1585.                         $status "Suspended";
  1586.                     }
  1587.                 }
  1588.                 $customSubscriptions->filterBySubscriptionType("custom");
  1589.                 $customSubscriptions->setOrderKey("o_modificationDate");
  1590.                 $customSubscriptions->setOrder("desc");
  1591.                 $packageData = [];
  1592.                 $userPackage null;
  1593.                 if ($customSubscriptions->count() > 0) {
  1594.                     foreach ($customSubscriptions as $key => $customSubscription) {
  1595.                         if ($customSubscription instanceof \Pimcore\Model\DataObject\Subscription) {
  1596.                             $package $customSubscription->getSubscribedPackage();
  1597.                             $userPackage $package;
  1598.                             if ($package) {
  1599.                                 $packageData[] = [
  1600.                                     "id" => $package->getId(),
  1601.                                     "name" => $package->getPackageName('en'),
  1602.                                     "name_ar" => $package->getPackageName('ar'),
  1603.                                     "package_expiry" => $customSubscription->getEndDate(date("M d, Y"))
  1604.                                 ];
  1605.                             }
  1606.                         }
  1607.                     }
  1608.                 }
  1609.                 $permissionObj $this->getUserPermissionInfo($usersData$translator);
  1610.                 $userPermissions $permissionObj['success'] ? $permissionObj['grants'] : null;
  1611.                 $organization $usersData->getOrganization();
  1612.                 $clientType $organization $organization->getClientType() : '';
  1613.                 $clientTypeArray = [
  1614.                     "key" => $clientType,
  1615.                     'name_en' => $clientType === 'organization' 'Entity' : ($clientType $translator->trans($clientType, [], null'en') : ''),
  1616.                     'name_ar' => $clientType === 'organization' 'الجهة' : ($clientType $translator->trans($clientType, [], null'ar') : ''),
  1617.                 ];
  1618.                 $roleArray = [
  1619.                     "key" => ($usersData->getRole()) ? $usersData->getRole()->getName() : null,
  1620.                     'name_en' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'en') : null,
  1621.                     'name_ar' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'ar') : null,
  1622.                 ];
  1623.                 // If user is pending, get invitation duration from MannedAlertLog
  1624.                 if ($status === "Pending") {
  1625.                     $invitationDuration $this->getInvitationDate($usersData);
  1626.                     $statusArray = [
  1627.                         "key" => $status,
  1628.                         'name_en' => $translator->trans($status, [], null'en'),
  1629.                         'name_ar' => $translator->trans($status, [], null'ar'),
  1630.                         'pendingDuration' => $invitationDuration // Add this field
  1631.                     ];
  1632.                 } else {
  1633.                     $statusArray = [
  1634.                         "key" => $status,
  1635.                         'name_en' => $translator->trans($status, [], null'en'),
  1636.                         'name_ar' => $translator->trans($status, [], null'ar'),
  1637.                     ];
  1638.                 }
  1639.                 // $statusArray = [
  1640.                 //     "key" => $status,
  1641.                 //     'name_en' => $translator->trans($status, [], null, 'en'),
  1642.                 //     'name_ar' => $translator->trans($status, [], null, 'ar'),
  1643.                 // ];
  1644.                 // Get delete reason from DeletedUsersData if type is delete_pending
  1645.                 $deleteReason null;
  1646.                 if (isset($params['type']) && $params['type'] == 'delete_pending') {
  1647.                     $deletedUsers = new DataObject\DeletedUsersData\Listing();
  1648.                     $deletedUsers->filterByPimId($usersData->getId());
  1649.                     $deletedUsers->setOrderKey('o_creationDate');
  1650.                     $deletedUsers->setOrder('desc');
  1651.                     $deletedUsers->setLimit(1);
  1652.                     $deleteUserRecord $deletedUsers->current();
  1653.                     if ($deleteUserRecord instanceof DataObject\DeletedUsersData) {
  1654.                         $deleteReason $deleteUserRecord->getReason();
  1655.                     }
  1656.                 }
  1657.                 $userData[] = [
  1658.                     'id' => $usersData->getId(),
  1659.                     'name' => $usersData->getName(),
  1660.                     'title' => $usersData->getTitle(),
  1661.                     'email' => $usersData->getEmail(),
  1662.                     'phone' => $usersData->getPhoneNo(),
  1663.                     'department' => $usersData->getDepartment(),
  1664.                     'reason' => $deleteReason,
  1665.                     'isDeleted' => $usersData->getIsDeleted() ? true false,
  1666.                     'role' => $roleArray,
  1667.                     'company_name_en' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName("en") : null,
  1668.                     'company_name_ar' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName("ar") : null,
  1669.                     'packageData' => $packageData,
  1670.                     'organizationId' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getId() : null,
  1671.                     'location' => $this->getLocationList($usersData),
  1672.                     'allowCustomNotification' => ($permissionObj['success'] && isset($userPermissions['get_custom_notification'])) ? $userPermissions['get_custom_notification'] : false,
  1673.                     'allowAddLocation' => ($permissionObj['success'] && isset($userPermissions['create_location'])) ? $userPermissions['create_location'] : false,
  1674.                     'allowForecast' => ($permissionObj['success'] && isset($userPermissions['get_weather'])) ? $userPermissions['get_weather'] : false,
  1675.                     'allowAlertHistoryForCustomAlerts' => ($permissionObj['success'] && isset($userPermissions['alert_history'])) ? $userPermissions['alert_history'] : false,
  1676.                     'automotive' => ($permissionObj['success'] && isset($userPermissions['automotive'])) ? $userPermissions['automotive'] : false,
  1677.                     'aviation' => ($permissionObj['success'] && isset($userPermissions['aviation'])) ? $userPermissions['aviation'] : false,
  1678.                     'shippingAndOffshore' => ($permissionObj['success'] && isset($userPermissions['shipping_and_offshore'])) ? $userPermissions['shipping_and_offshore'] : false,
  1679.                     'insurance' => ($permissionObj['success'] && isset($userPermissions['insurance'])) ? $userPermissions['insurance'] : false,
  1680.                     'energy' => ($permissionObj['success'] && isset($userPermissions['energy'])) ? $userPermissions['energy'] : false,
  1681.                     'client_type' => $clientTypeArray,
  1682.                     'status' => $statusArray,
  1683.                     'createdBy' => $usersData->getCreatedBy() ? $usersData->getCreatedBy()->getName() : null,
  1684.                     'createdAt' => date('Y-m-d H:i:s'$usersData->getCreationDate()),
  1685.                     'iqamaId' => $usersData->getIqamaId() ? (string) $usersData->getIqamaId() : null,
  1686.                     //'token' => $status == "Pending" ? $usersData->getToken() : '',
  1687.                     'entity_status' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getStatus() : null,
  1688.                     'entity_status_en' => ($usersData->getOrganization() && $usersData->getOrganization()->getStatus()) ? $translator->trans($usersData->getOrganization()->getStatus(), [], null'en') : null,
  1689.                     'entity_status_ar' => ($usersData->getOrganization() && $usersData->getOrganization()->getStatus()) ? $translator->trans($usersData->getOrganization()->getStatus(), [], null'ar') : null,
  1690.                     'trialLeftDays' => $usersData->getOrganization() ? 
  1691.                         \App\Lib\Utility::getTrialLeftDays(
  1692.                             $usersData->getOrganization()->getPackageActivationDate(),
  1693.                             $usersData->getOrganization()->getTrialLimit()
  1694.                         ) : null,
  1695.                     'isSMSEnabled' => $organization $organization->getIsSMSEnabled() : false,
  1696.                     'SMSLimit' => $userPackage?->getSMSLimit(),
  1697.                     'SMSConsumption' => $organization $organization->getSmsConsumption() : 0,
  1698.                 ];
  1699.                 if (isset($params['sortByStatus']) && !empty($params['sortByStatus'])) {
  1700.                     $statusFilter strtoupper($params['sortByStatus']);
  1701.                     usort($userData, function ($a$b) use ($statusFilter) {
  1702.                         $statusKeyA $a['status']['key'];
  1703.                         $statusKeyB $b['status']['key'];
  1704.                         if ($statusFilter === 'ASC') {
  1705.                             if ($statusKeyA === 'Active' && $statusKeyB !== 'Active') {
  1706.                                 return -1;
  1707.                             }
  1708.                             if ($statusKeyA !== 'Active' && $statusKeyB === 'Active') {
  1709.                                 return 1;
  1710.                             }
  1711.                         } else if ($statusFilter === 'DESC') {
  1712.                             if ($statusKeyA === 'Pending' && $statusKeyB !== 'Pending') {
  1713.                                 return -1;
  1714.                             }
  1715.                             if ($statusKeyA !== 'Pending' && $statusKeyB === 'Pending') {
  1716.                                 return 1;
  1717.                             }
  1718.                         }
  1719.                         return 0// They are equal in terms of status priority
  1720.                     });
  1721.                 }
  1722.             }
  1723.         }
  1724.         if (!$paginator->count()) {
  1725.             return ["success" => false"message" => $translator->trans("no_user_available_to_this_organization")];
  1726.         }
  1727.         return ["success" => TRUE"data" => $userData"paginationVariables" => $paginator->getPaginationData()];
  1728.         // } catch (\Exception $ex) {
  1729.         //     throw new \Exception($ex->getMessage());
  1730.         // }
  1731.         return $result;
  1732.     }
  1733.     /**
  1734.      * Get NCM User List
  1735.      */
  1736.     public function getNCMUsers($request$user$params$paginator$translator)
  1737.     {
  1738.         $result = [];
  1739.         try {
  1740.             $userData = [];
  1741.             // if ($user->getOrganization() === null) {
  1742.             //     return ["success" => false, "message" => $translator->trans("organization_does_not_exists")];
  1743.             //  }
  1744.             //  $organizationId = $user->getOrganization()->getId();
  1745.             // Get All the Classes
  1746.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  1747.             $customer $class->getDao()->getIdByName('Customer');
  1748.             $subscription $class->getDao()->getIdByName('Subscription');
  1749.             $userRole $class->getDao()->getIdByName('UserRole');
  1750.             $userTag $class->getDao()->getIdByName('UserTag');
  1751.             $organization $class->getDao()->getIdByName('Organization');
  1752.             $package $class->getDao()->getIdByName('Package');
  1753.             $db Db::get();
  1754.             $select $db->createQueryBuilder();
  1755.             $select->select('customer.oo_id');
  1756.             $select->from('object_' $customer'customer');
  1757.             $select->leftJoin('customer''object_' $subscription'subscription''customer.oo_id = subscription.subscribedUser__id');
  1758.             $select->leftJoin('subscription''object_' $package'package''package.oo_id = subscription.subscribedPackage__id');
  1759.             $select->leftJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  1760.             $select->leftJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  1761.             $select->leftJoin('customer''object_' $userTag'userTage''userTage.oo_id = customer.tag__id');
  1762.             if (isset($params['search']) && !empty($params['search'])) {
  1763.                 $select->andWhere("customer.name LIKE " $db->quote("%" $params['search'] . "%") . " OR customer.email LIKE " $db->quote("%" $params['search'] . "%"));
  1764.             }
  1765.             if (isset($params['searchByTag']) && !empty($params['searchByTag'])) {
  1766.                 $select->andWhere("customer.tag__id = " $db->quote($params['searchByTag']));
  1767.             }
  1768.             // Filter by dual mode
  1769.             if (isset($params['is_dual_mode']) && ($params['is_dual_mode'] == true )) {
  1770.                 $select->andWhere("customer.dualMode = 1");
  1771.             }
  1772.             $select->andWhere("userRole.name = " $db->quote(USER_ROLES['NCM_IT']) . " OR userRole.name = " $db->quote(USER_ROLES['NCM_OPERATOR']));
  1773.             $select->andWhere("customer.oo_id != " $db->quote($user->getId()));
  1774.             $select->andWhere("customer.isDeleted != 1 or customer.isDeleted IS NULL");
  1775.             //$select->andWhere("organization.oo_id = ".$db->quote($organizationId));
  1776.             // if (isset($params['status']) && !empty($params['status'])) {
  1777.             //     $statusFilter = ucfirst($params['status']);
  1778.             //     if ($statusFilter == 'Active') {
  1779.             //         $select->andWhere("customer.token IS NULL AND customer.o_published = 1 AND subscription.subscribedUser__id IS NOT NULL");
  1780.             //     } elseif ($statusFilter == 'Suspended') {
  1781.             //         $select->andWhere("customer.token IS NULL AND customer.o_published = 1 AND subscription.subscribedUser__id IS NULL");
  1782.             //     } elseif ($statusFilter == 'Pending') {
  1783.             //         $select->andWhere("customer.token != '' AND customer.o_published = 0");
  1784.             //     }
  1785.             // }
  1786.             // Dynamic sorting logic
  1787.             $orderKey = isset($params['orderKey']) ? $params['orderKey'] : null;
  1788.             $order = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
  1789.             // Validate order parameter
  1790.             if (!in_array(strtoupper($order), ['ASC''DESC'])) {
  1791.                 $order 'ASC';
  1792.             }
  1793.             // Map orderKey to database fields
  1794.             $fieldMapping = [
  1795.                 'username' => 'customer.name',
  1796.                 'email' => 'customer.email',
  1797.                 'userTag' => 'userTage.name',
  1798.                 'createdBy' => 'createdBy.name',
  1799.                 'role' => 'userRole.name',
  1800.                 'status' => 'status'// This will be handled separately as it's computed
  1801.                 'createdOn' => 'customer.o_creationDate'
  1802.             ];
  1803.             if ($orderKey && isset($fieldMapping[$orderKey])) {
  1804.                 $field $fieldMapping[$orderKey];
  1805.                 if ($orderKey === 'createdBy') {
  1806.                     $select->leftJoin('customer''object_' $customer'createdBy''createdBy.oo_id = customer.createdBy__id');
  1807.                 }
  1808.                 if ($orderKey === 'status') {
  1809.                     $needStatusSort true;
  1810.                 } else {
  1811.                     $select->orderBy($field$order);
  1812.                 }
  1813.             } else {
  1814.                 // Default sorting
  1815.                 $select->orderBy('customer.o_creationDate''DESC');
  1816.             }
  1817.             $select->groupBy(array('oo_id'));
  1818.             $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  1819.             $page = isset($params['page']) ? $params['page'] : 1;
  1820.             $paginator $paginator->paginate(
  1821.                 $select,
  1822.                 $page,
  1823.                 $pageSize
  1824.             );
  1825.             foreach ($paginator as $usersId) {
  1826.                 $usersData DataObject\Customer::getById($usersId['oo_id'], true);
  1827.                 if ($usersData instanceof \Pimcore\Model\DataObject\Customer) {
  1828.                     // Get Custom Subscription of the organization and package
  1829.                     $customSubscriptions = new DataObject\Subscription\Listing();
  1830.                     $customSubscriptions->filterBySubscribedUser($usersData);
  1831.                     $customSubscriptions->filterByIsActive(true);
  1832.                     $status "Pending";
  1833.                     if ($usersData->getToken() == "" && $usersData->isPublished() == true) {
  1834.                         if ($usersData->getPermissionGroups() && count($usersData->getPermissionGroups()) > 0) {
  1835.                             $status "Active";
  1836.                         } else {
  1837.                             $status "Suspended";
  1838.                         }
  1839.                     } elseif ($usersData->getToken() != "" && $usersData->isPublished() == false) {
  1840.                         $status "Pending";
  1841.                     }
  1842.                     $permissionObj $this->getUserPermissionInfo($usersData$translator);
  1843.                     $userPermissions $permissionObj['success'] ? $permissionObj['grants'] : null;
  1844.                     //$customSubscriptions->filterBySubscriptionType("custom");
  1845.                     $customSubscriptions->setOrderKey("o_modificationDate");
  1846.                     $customSubscriptions->setOrder("desc");
  1847.                     $apiGroupData = [];
  1848.                     $packageData = [];
  1849.                     $assignedApiGroupIds = [];
  1850.                     if ($customSubscriptions->count() > 0) {
  1851.                         foreach ($customSubscriptions as $key => $customSubscription) {
  1852.                             if ($customSubscription instanceof \Pimcore\Model\DataObject\Subscription) {
  1853.                                 $package $customSubscription->getSubscribedPackage();
  1854.                                 $disallowedApiGroups $customSubscription->getDisallowedApiGroups();
  1855.                                 // get all allowed API Group IDs for the user
  1856.                                 $allowedApiGroups $customSubscription->getAllowedApiGroups();
  1857.                                 if (count($allowedApiGroups) > 0) {
  1858.                                     foreach ($allowedApiGroups as $allowedApiGroup) {
  1859.                                         if ($allowedApiGroup instanceof \Pimcore\Model\DataObject\ApiGroup) {
  1860.                                             # code...
  1861.                                             $assignedApiGroupIds[] = [
  1862.                                                 "id" => $allowedApiGroup->getId(),
  1863.                                                 "name" => $allowedApiGroup->getGroupName(),
  1864.                                             ];
  1865.                                         }
  1866.                                     }
  1867.                                 }
  1868.                                 if ($package) {
  1869.                                     $packageData[] = [
  1870.                                         "id" => $package->getId(),
  1871.                                         "name" => $package->getName(),
  1872.                                         "package_expiry" => $customSubscription->getEndDate(date("M d, Y")),
  1873.                                         "is_no_expiry" => $customSubscription->getIsNoExpiry() == null false $customSubscription->getIsNoExpiry()
  1874.                                     ];
  1875.                                     $apiGroups $package->getApiGroups();
  1876.                                     if ($apiGroups) {
  1877.                                         foreach ($apiGroups as  $apiGroup) {
  1878.                                             $apiGroupId $apiGroup->getId();
  1879.                                             $apiGroupNameEn $apiGroup->getApiGroupName('en');
  1880.                                             $apiGroupNameAr $apiGroup->getApiGroupName('ar');
  1881.                                             $isDisallowed false;
  1882.                                             // Check if the current API group is disallowed
  1883.                                             foreach ($disallowedApiGroups as $disallowedApiGroup) {
  1884.                                                 if ($apiGroupId == $disallowedApiGroup->getId()) {
  1885.                                                     $isDisallowed true;
  1886.                                                     break;
  1887.                                                 }
  1888.                                             }
  1889.                                             // Only add the API group if it's not disallowed
  1890.                                             if (!$isDisallowed) {
  1891.                                                 $apiGroupData[] = [
  1892.                                                     "id" => $apiGroupId,
  1893.                                                     "name" => $apiGroupNameEn,
  1894.                                                     "name_ar" => $apiGroupNameAr
  1895.                                                 ];
  1896.                                             }
  1897.                                         }
  1898.                                     }
  1899.                                 }
  1900.                             }
  1901.                         }
  1902.                     }
  1903.                     $typeArray = [
  1904.                         "key" => 'user',
  1905.                         'name_en' => $translator->trans('user', [], null'en'),
  1906.                         'name_ar' => $translator->trans('user', [], null'ar'),
  1907.                     ];
  1908.                     $roleArray = [
  1909.                         "key" => ($usersData->getRole()) ? $usersData->getRole()->getName() : null,
  1910.                         'name_en' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'en') : null,
  1911.                         'name_ar' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'ar') : null,
  1912.                     ];
  1913.                     $statusArray = [
  1914.                         "key" => $status,
  1915.                         'name_en' => $translator->trans($status, [], null'en'),
  1916.                         'name_ar' => $translator->trans($status, [], null'ar'),
  1917.                     ];
  1918.                     // Fetch Permission Groups Data
  1919.                     $permissionGroups $usersData->getPermissionGroups();
  1920.                    
  1921.                     $permissionGroupsData = [];
  1922.                     $permissionGroupDualModeData = [];
  1923.                     if ($permissionGroups) {
  1924.                         foreach ($permissionGroups as $permissionGroup) {
  1925.                             if ($permissionGroup instanceof \Pimcore\Model\DataObject\PermissionGroup) {
  1926.                                 if($permissionGroup->getIsDualMode() == true){
  1927.                                     $permissionGroupDualModeData[] = [
  1928.                                         'id' => $permissionGroup->getId(),
  1929.                                         'nameEn' => $permissionGroup->getName('en'),
  1930.                                         'nameAr' => $permissionGroup->getName('ar'),
  1931.                                         'descriptionEn' => $permissionGroup->getDescription('en'),
  1932.                                         'descriptionAr' => $permissionGroup->getDescription('ar'),
  1933.                                         'apiGroups' => array_map(function ($group) {
  1934.                                             return ['id' => $group->getId(), 'nameEn' => $group->getApiGroupName('en'), 'nameAr' => $group->getApiGroupName('ar')];
  1935.                                         }, $permissionGroup->getApiGroups() ?? []),
  1936.                                     ];
  1937.                                 }
  1938.                                 else{
  1939.                                 $permissionGroupsData[] = [
  1940.                                     'id' => $permissionGroup->getId(),
  1941.                                     'nameEn' => $permissionGroup->getName('en'),
  1942.                                     'nameAr' => $permissionGroup->getName('ar'),
  1943.                                     'descriptionEn' => $permissionGroup->getDescription('en'),
  1944.                                     'descriptionAr' => $permissionGroup->getDescription('ar'),
  1945.                                     'apiGroups' => array_map(function ($group) {
  1946.                                         return ['id' => $group->getId(), 'nameEn' => $group->getApiGroupName('en'), 'nameAr' => $group->getApiGroupName('ar')];
  1947.                                     }, $permissionGroup->getApiGroups() ?? []),
  1948.                                     ];
  1949.                                 }
  1950.                             }
  1951.                         }
  1952.                     }
  1953.                     $userData[] = [
  1954.                         'id' => $usersData->getId(),
  1955.                         'name' => $usersData->getName(),
  1956.                         'title' => $usersData->getTitle(),
  1957.                         'email' => $usersData->getEmail(),
  1958.                         'department' => $usersData->getDepartment(),
  1959.                         'role' => $roleArray,
  1960.                         'organization' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName() : null,
  1961.                         'organizationId' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getId() : null,
  1962.                         'location' => $this->getLocationList($usersData),
  1963.                         'invite_user' => ($permissionObj['success'] && isset($userPermissions['invite_user'])) ? $userPermissions['invite_user'] : false,
  1964.                         'edit_user' => ($permissionObj['success'] && isset($userPermissions['edit_user'])) ? $userPermissions['edit_user'] : false,
  1965.                         'delete_user' => ($permissionObj['success'] && isset($userPermissions['delete_user'])) ? $userPermissions['delete_user'] : false,
  1966.                         'invite_ncm_user' => ($permissionObj['success'] && isset($userPermissions['invite_ncm_user'])) ? $userPermissions['invite_ncm_user'] : false,
  1967.                         'edit_ncm_user' => ($permissionObj['success'] && isset($userPermissions['edit_ncm_user'])) ? $userPermissions['edit_ncm_user'] : false,
  1968.                         'delete_ncm_user' => ($permissionObj['success'] && isset($userPermissions['delete_ncm_user'])) ? $userPermissions['delete_ncm_user'] : false,
  1969.                         'type' => $typeArray,
  1970.                         'status' => $statusArray,
  1971.                         'apiGroups' => $apiGroupData,
  1972.                         'assignedApiGroupIds' => $assignedApiGroupIds,
  1973.                         'packageData' => $packageData,
  1974.                         'createdBy' => $usersData->getCreatedBy() ? $usersData->getCreatedBy()->getName() : null,
  1975.                         'creationDate' => $usersData->getCreationDate() ? date('Y-m-d'$usersData->getCreationDate()) : null,
  1976.                         'iqamaId' => $usersData->getIqamaId() ? (string) $usersData->getIqamaId() : null,
  1977.                         'tag' => $usersData->getTag() ? ['id' => $usersData->getTag()->getId(), 'name' => $usersData->getTag()->getName()] : null,
  1978.                         'permissionGroupsData' => $permissionGroupsData,
  1979.                         'permissionGroupDualMode' => $permissionGroupDualModeData,
  1980.                         'dualMode' => $usersData->getDualMode() ? true false,
  1981.                         //'token' => $usersData->getToken(),
  1982.                     ];
  1983.                 }
  1984.             }
  1985.             if (!$userData) {
  1986.                 return ["success" => false"message" => $translator->trans("no_user_available_in_NCM")];
  1987.             }
  1988.             // Handle status sorting if needed
  1989.             if (isset($needStatusSort) && $needStatusSort && $orderKey === 'status') {
  1990.                 usort($userData, function ($a$b) use ($order) {
  1991.                     $statusA $a['status']['key'];
  1992.                     $statusB $b['status']['key'];
  1993.                     if ($order === 'ASC') {
  1994.                         return strcmp($statusA$statusB);
  1995.                     } else {
  1996.                         return strcmp($statusB$statusA);
  1997.                     }
  1998.                 });
  1999.             }
  2000.             return ["success" => TRUE"data" => $userData"paginationVariables" => $paginator->getPaginationData()];
  2001.         } catch (\Exception $ex) {
  2002.             throw new \Exception($ex->getMessage());
  2003.         }
  2004.         return $result;
  2005.     }
  2006.     public function getDualModeUsers($request$user$params$paginator$translator)
  2007.     {
  2008.        $result = [];
  2009.         try {
  2010.             $userData = [];
  2011.             // if ($user->getOrganization() === null) {
  2012.             //     return ["success" => false, "message" => $translator->trans("organization_does_not_exists")];
  2013.             //  }
  2014.             //  $organizationId = $user->getOrganization()->getId();
  2015.             // Get All the Classes
  2016.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  2017.             $customer $class->getDao()->getIdByName('Customer');
  2018.             $subscription $class->getDao()->getIdByName('Subscription');
  2019.             $userRole $class->getDao()->getIdByName('UserRole');
  2020.             $userTag $class->getDao()->getIdByName('UserTag');
  2021.             $organization $class->getDao()->getIdByName('Organization');
  2022.             $package $class->getDao()->getIdByName('Package');
  2023.             $db Db::get();
  2024.             $select $db->createQueryBuilder();
  2025.             $select->select('customer.oo_id');
  2026.             $select->from('object_' $customer'customer');
  2027.             $select->leftJoin('customer''object_' $subscription'subscription''customer.oo_id = subscription.subscribedUser__id');
  2028.             $select->leftJoin('subscription''object_' $package'package''package.oo_id = subscription.subscribedPackage__id');
  2029.             $select->leftJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  2030.             $select->leftJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  2031.             $select->leftJoin('customer''object_' $userTag'userTage''userTage.oo_id = customer.tag__id');
  2032.             if (isset($params['search']) && !empty($params['search'])) {
  2033.                 $select->andWhere("customer.name LIKE " $db->quote("%" $params['search'] . "%") . " OR customer.email LIKE " $db->quote("%" $params['search'] . "%"));
  2034.             }
  2035.             if (isset($params['searchByTag']) && !empty($params['searchByTag'])) {
  2036.                 $select->andWhere("customer.tag__id = " $db->quote($params['searchByTag']));
  2037.             }
  2038.             
  2039.             $select->andWhere("customer.dualMode = 1");
  2040.            
  2041.             $select->andWhere("userRole.name = " $db->quote(USER_ROLES['NCM_IT']) . " OR userRole.name = " $db->quote(USER_ROLES['NCM_OPERATOR']));
  2042.             $select->andWhere("customer.oo_id != " $db->quote($user->getId()));
  2043.             $select->andWhere("customer.isDeleted != 1 or customer.isDeleted IS NULL");
  2044.             //$select->andWhere("organization.oo_id = ".$db->quote($organizationId));
  2045.             // if (isset($params['status']) && !empty($params['status'])) {
  2046.             //     $statusFilter = ucfirst($params['status']);
  2047.             //     if ($statusFilter == 'Active') {
  2048.             //         $select->andWhere("customer.token IS NULL AND customer.o_published = 1 AND subscription.subscribedUser__id IS NOT NULL");
  2049.             //     } elseif ($statusFilter == 'Suspended') {
  2050.             //         $select->andWhere("customer.token IS NULL AND customer.o_published = 1 AND subscription.subscribedUser__id IS NULL");
  2051.             //     } elseif ($statusFilter == 'Pending') {
  2052.             //         $select->andWhere("customer.token != '' AND customer.o_published = 0");
  2053.             //     }
  2054.             // }
  2055.             // Dynamic sorting logic
  2056.             $orderKey = isset($params['orderKey']) ? $params['orderKey'] : null;
  2057.             $order = isset($params['order']) ? strtoupper($params['order']) : 'ASC';
  2058.             // Validate order parameter
  2059.             if (!in_array(strtoupper($order), ['ASC''DESC'])) {
  2060.                 $order 'ASC';
  2061.             }
  2062.             // Map orderKey to database fields
  2063.             $fieldMapping = [
  2064.                 'username' => 'customer.name',
  2065.                 'email' => 'customer.email',
  2066.                 'userTag' => 'userTage.name',
  2067.                 'createdBy' => 'createdBy.name',
  2068.                 'role' => 'userRole.name',
  2069.                 'status' => 'status'// This will be handled separately as it's computed
  2070.                 'createdOn' => 'customer.o_creationDate'
  2071.             ];
  2072.             if ($orderKey && isset($fieldMapping[$orderKey])) {
  2073.                 $field $fieldMapping[$orderKey];
  2074.                 if ($orderKey === 'createdBy') {
  2075.                     $select->leftJoin('customer''object_' $customer'createdBy''createdBy.oo_id = customer.createdBy__id');
  2076.                 }
  2077.                 if ($orderKey === 'status') {
  2078.                     $needStatusSort true;
  2079.                 } else {
  2080.                     $select->orderBy($field$order);
  2081.                 }
  2082.             } else {
  2083.                 // Default sorting
  2084.                 $select->orderBy('customer.o_creationDate''DESC');
  2085.             }
  2086.             $select->groupBy(array('oo_id'));
  2087.             $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  2088.             $page = isset($params['page']) ? $params['page'] : 1;
  2089.             $paginator $paginator->paginate(
  2090.                 $select,
  2091.                 $page,
  2092.                 $pageSize
  2093.             );
  2094.             foreach ($paginator as $usersId) {
  2095.                 $usersData DataObject\Customer::getById($usersId['oo_id'], true);
  2096.                 if ($usersData instanceof \Pimcore\Model\DataObject\Customer) {
  2097.                     // Get Custom Subscription of the organization and package
  2098.                     $customSubscriptions = new DataObject\Subscription\Listing();
  2099.                     $customSubscriptions->filterBySubscribedUser($usersData);
  2100.                     $customSubscriptions->filterByIsActive(true);
  2101.                     $status "Pending";
  2102.                     if ($usersData->getToken() == "" && $usersData->isPublished() == true) {
  2103.                         if ($usersData->getPermissionGroups() && count($usersData->getPermissionGroups()) > 0) {
  2104.                             $status "Active";
  2105.                         } else {
  2106.                             $status "Suspended";
  2107.                         }
  2108.                     } elseif ($usersData->getToken() != "" && $usersData->isPublished() == false) {
  2109.                         $status "Pending";
  2110.                     }
  2111.                     $permissionObj $this->getUserPermissionInfo($usersData$translator);
  2112.                     $userPermissions $permissionObj['success'] ? $permissionObj['grants'] : null;
  2113.                     //$customSubscriptions->filterBySubscriptionType("custom");
  2114.                     $customSubscriptions->setOrderKey("o_modificationDate");
  2115.                     $customSubscriptions->setOrder("desc");
  2116.                     $apiGroupData = [];
  2117.                     $packageData = [];
  2118.                     $assignedApiGroupIds = [];
  2119.                     if ($customSubscriptions->count() > 0) {
  2120.                         foreach ($customSubscriptions as $key => $customSubscription) {
  2121.                             if ($customSubscription instanceof \Pimcore\Model\DataObject\Subscription) {
  2122.                                 $package $customSubscription->getSubscribedPackage();
  2123.                                 $disallowedApiGroups $customSubscription->getDisallowedApiGroups();
  2124.                                 // get all allowed API Group IDs for the user
  2125.                                 $allowedApiGroups $customSubscription->getAllowedApiGroups();
  2126.                                 if (count($allowedApiGroups) > 0) {
  2127.                                     foreach ($allowedApiGroups as $allowedApiGroup) {
  2128.                                         if ($allowedApiGroup instanceof \Pimcore\Model\DataObject\ApiGroup) {
  2129.                                             # code...
  2130.                                             $assignedApiGroupIds[] = [
  2131.                                                 "id" => $allowedApiGroup->getId(),
  2132.                                                 "name" => $allowedApiGroup->getGroupName(),
  2133.                                             ];
  2134.                                         }
  2135.                                     }
  2136.                                 }
  2137.                                 if ($package) {
  2138.                                     $packageData[] = [
  2139.                                         "id" => $package->getId(),
  2140.                                         "name" => $package->getName(),
  2141.                                         "package_expiry" => $customSubscription->getEndDate(date("M d, Y")),
  2142.                                         "is_no_expiry" => $customSubscription->getIsNoExpiry() == null false $customSubscription->getIsNoExpiry()
  2143.                                     ];
  2144.                                     $apiGroups $package->getApiGroups();
  2145.                                     if ($apiGroups) {
  2146.                                         foreach ($apiGroups as  $apiGroup) {
  2147.                                             $apiGroupId $apiGroup->getId();
  2148.                                             $apiGroupNameEn $apiGroup->getApiGroupName('en');
  2149.                                             $apiGroupNameAr $apiGroup->getApiGroupName('ar');
  2150.                                             $isDisallowed false;
  2151.                                             // Check if the current API group is disallowed
  2152.                                             foreach ($disallowedApiGroups as $disallowedApiGroup) {
  2153.                                                 if ($apiGroupId == $disallowedApiGroup->getId()) {
  2154.                                                     $isDisallowed true;
  2155.                                                     break;
  2156.                                                 }
  2157.                                             }
  2158.                                             // Only add the API group if it's not disallowed
  2159.                                             if (!$isDisallowed) {
  2160.                                                 $apiGroupData[] = [
  2161.                                                     "id" => $apiGroupId,
  2162.                                                     "name" => $apiGroupNameEn,
  2163.                                                     "name_ar" => $apiGroupNameAr
  2164.                                                 ];
  2165.                                             }
  2166.                                         }
  2167.                                     }
  2168.                                 }
  2169.                             }
  2170.                         }
  2171.                     }
  2172.                     $typeArray = [
  2173.                         "key" => 'user',
  2174.                         'name_en' => $translator->trans('user', [], null'en'),
  2175.                         'name_ar' => $translator->trans('user', [], null'ar'),
  2176.                     ];
  2177.                     $roleArray = [
  2178.                         "key" => ($usersData->getRole()) ? $usersData->getRole()->getName() : null,
  2179.                         'name_en' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'en') : null,
  2180.                         'name_ar' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'ar') : null,
  2181.                     ];
  2182.                     $statusArray = [
  2183.                         "key" => $status,
  2184.                         'name_en' => $translator->trans($status, [], null'en'),
  2185.                         'name_ar' => $translator->trans($status, [], null'ar'),
  2186.                     ];
  2187.                     // Fetch Permission Groups Data
  2188.                     $permissionGroups $usersData->getPermissionGroups();
  2189.                    
  2190.                     $permissionGroupsData = [];
  2191.                     $permissionGroupDualModeData = [];
  2192.                     if ($permissionGroups) {
  2193.                         foreach ($permissionGroups as $permissionGroup) {
  2194.                             if ($permissionGroup instanceof \Pimcore\Model\DataObject\PermissionGroup) {
  2195.                                 if($permissionGroup->getIsDualMode() == true){
  2196.                                     $permissionGroupDualModeData[] = [
  2197.                                         'id' => $permissionGroup->getId(),
  2198.                                         'nameEn' => $permissionGroup->getName('en'),
  2199.                                         'nameAr' => $permissionGroup->getName('ar'),
  2200.                                         'descriptionEn' => $permissionGroup->getDescription('en'),
  2201.                                         'descriptionAr' => $permissionGroup->getDescription('ar'),
  2202.                                         'apiGroups' => array_map(function ($group) {
  2203.                                             return ['id' => $group->getId(), 'nameEn' => $group->getApiGroupName('en'), 'nameAr' => $group->getApiGroupName('ar')];
  2204.                                         }, $permissionGroup->getApiGroups() ?? []),
  2205.                                     ];
  2206.                                 }
  2207.                                 else{
  2208.                                 $permissionGroupsData[] = [
  2209.                                     'id' => $permissionGroup->getId(),
  2210.                                     'nameEn' => $permissionGroup->getName('en'),
  2211.                                     'nameAr' => $permissionGroup->getName('ar'),
  2212.                                     'descriptionEn' => $permissionGroup->getDescription('en'),
  2213.                                     'descriptionAr' => $permissionGroup->getDescription('ar'),
  2214.                                     'apiGroups' => array_map(function ($group) {
  2215.                                         return ['id' => $group->getId(), 'nameEn' => $group->getApiGroupName('en'), 'nameAr' => $group->getApiGroupName('ar')];
  2216.                                     }, $permissionGroup->getApiGroups() ?? []),
  2217.                                     ];
  2218.                                 }
  2219.                             }
  2220.                         }
  2221.                     }
  2222.                     $userData[] = [
  2223.                         'id' => $usersData->getId(),
  2224.                         'name' => $usersData->getName(),
  2225.                         'title' => $usersData->getTitle(),
  2226.                         'email' => $usersData->getEmail(),
  2227.                         'department' => $usersData->getDepartment(),
  2228.                         'role' => $roleArray,
  2229.                         'organization' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName() : null,
  2230.                         'organizationId' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getId() : null,
  2231.                         'location' => $this->getLocationList($usersData),
  2232.                         'invite_user' => ($permissionObj['success'] && isset($userPermissions['invite_user'])) ? $userPermissions['invite_user'] : false,
  2233.                         'edit_user' => ($permissionObj['success'] && isset($userPermissions['edit_user'])) ? $userPermissions['edit_user'] : false,
  2234.                         'delete_user' => ($permissionObj['success'] && isset($userPermissions['delete_user'])) ? $userPermissions['delete_user'] : false,
  2235.                         'invite_ncm_user' => ($permissionObj['success'] && isset($userPermissions['invite_ncm_user'])) ? $userPermissions['invite_ncm_user'] : false,
  2236.                         'edit_ncm_user' => ($permissionObj['success'] && isset($userPermissions['edit_ncm_user'])) ? $userPermissions['edit_ncm_user'] : false,
  2237.                         'delete_ncm_user' => ($permissionObj['success'] && isset($userPermissions['delete_ncm_user'])) ? $userPermissions['delete_ncm_user'] : false,
  2238.                         'type' => $typeArray,
  2239.                         'status' => $statusArray,
  2240.                         'apiGroups' => $apiGroupData,
  2241.                         'assignedApiGroupIds' => $assignedApiGroupIds,
  2242.                         'packageData' => $packageData,
  2243.                         'createdBy' => $usersData->getCreatedBy() ? $usersData->getCreatedBy()->getName() : null,
  2244.                         'creationDate' => $usersData->getCreationDate() ? date('Y-m-d'$usersData->getCreationDate()) : null,
  2245.                         'iqamaId' => $usersData->getIqamaId() ? (string) $usersData->getIqamaId() : null,
  2246.                         'tag' => $usersData->getTag() ? ['id' => $usersData->getTag()->getId(), 'name' => $usersData->getTag()->getName()] : null,
  2247.                         'permissionGroupsData' => $permissionGroupsData,
  2248.                         'permissionGroupDualMode' => $permissionGroupDualModeData,
  2249.                         'dualMode' => $usersData->getDualMode() ? true false,
  2250.                         //'token' => $usersData->getToken(),
  2251.                     ];
  2252.                 }
  2253.             }
  2254.             $permissionGroups = new DataObject\PermissionGroup\Listing();
  2255.             $permissionGroups->setCondition("isDualMode = 1");
  2256.             // Total active users: same logic as per-user status (token empty, published, at least one permission group)
  2257.             $totalActiveUsers 0;
  2258.             $activeListing = new DataObject\Customer\Listing();
  2259.             $activeListing->addConditionParam('dualMode = ?'1);
  2260.             $activeListing->addConditionParam('(token IS NULL OR token = "")');
  2261.             $activeListing->addConditionParam('o_published = ?'1);
  2262.             $activeListing->addConditionParam('(isDeleted != 1 OR isDeleted IS NULL)');
  2263.             $activeListing->addConditionParam('oo_id != ?'$user->getId());
  2264.             $ncmRoleRows $db->executeQuery("SELECT oo_id FROM object_" $userRole " WHERE name IN (?, ?)", [
  2265.                 USER_ROLES['NCM_IT'],
  2266.                 USER_ROLES['NCM_OPERATOR']
  2267.             ])->fetchAll(\PDO::FETCH_ASSOC);
  2268.             $ncmRoleIds $ncmRoleRows array_column($ncmRoleRows'oo_id') : [];
  2269.             if (!empty($ncmRoleIds)) {
  2270.                 $activeListing->addConditionParam('role__id IN (' implode(','array_map('intval'$ncmRoleIds)) . ')');
  2271.             }
  2272.             // if (isset($params['search']) && !empty($params['search'])) {
  2273.             //     $activeListing->addConditionParam('(name LIKE ? OR email LIKE ?)', ['%' . $params['search'] . '%', '%' . $params['search'] . '%']);
  2274.             // }
  2275.             // if (isset($params['searchByTag']) && !empty($params['searchByTag'])) {
  2276.             //     $activeListing->addConditionParam('tag__id = ?', $params['searchByTag']);
  2277.             // }
  2278.             foreach ($activeListing as $customerObj) {
  2279.                 if ($customerObj instanceof \Pimcore\Model\DataObject\Customer) {
  2280.                     $groups $customerObj->getPermissionGroups();
  2281.                     if ($groups && count($groups) > 0) {
  2282.                         $totalActiveUsers++;
  2283.                     }
  2284.                 }
  2285.             }
  2286.             // Total users count: all dual-mode NCM users (no search/tag filter)
  2287.             $countSelect $db->createQueryBuilder();
  2288.             $countSelect->select('COUNT(DISTINCT customer.oo_id) as total');
  2289.             $countSelect->from('object_' $customer'customer');
  2290.             $countSelect->leftJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  2291.             $countSelect->andWhere("customer.dualMode = 1");
  2292.             $countSelect->andWhere("(userRole.name = " $db->quote(USER_ROLES['NCM_IT']) . " OR userRole.name = " $db->quote(USER_ROLES['NCM_OPERATOR']) . ")");
  2293.             $countSelect->andWhere("customer.oo_id != " $db->quote($user->getId()));
  2294.             $countSelect->andWhere("(customer.isDeleted != 1 OR customer.isDeleted IS NULL)");
  2295.             $totalUsersCount = (int) $countSelect->execute()->fetchOne();
  2296.             $summary = [
  2297.                 "total_groups" => $permissionGroups->count(),
  2298.                 "total_users" => $totalUsersCount,
  2299.                 "total_active_users" => $totalActiveUsers,
  2300.             ];
  2301.        
  2302.           
  2303.             if (!$userData) {
  2304.                 return ["success" => false"message" => $translator->trans("no_user_available_in_NCM")];
  2305.             }
  2306.             // Handle status sorting if needed
  2307.             if (isset($needStatusSort) && $needStatusSort && $orderKey === 'status') {
  2308.                 usort($userData, function ($a$b) use ($order) {
  2309.                     $statusA $a['status']['key'];
  2310.                     $statusB $b['status']['key'];
  2311.                     if ($order === 'ASC') {
  2312.                         return strcmp($statusA$statusB);
  2313.                     } else {
  2314.                         return strcmp($statusB$statusA);
  2315.                     }
  2316.                 });
  2317.             }
  2318.             return [
  2319.                 "success" => true,
  2320.                 "data" => $userData,
  2321.                 "summary_counts" => $summary,
  2322.                 "paginationVariables" => $paginator->getPaginationData()
  2323.             ];
  2324.         } catch (\Exception $ex) {
  2325.             throw new \Exception($ex->getMessage());
  2326.         }
  2327.         return $result;
  2328.     }
  2329.     /**
  2330.      * Summary of assignPermissionUserGroupToDualModeUser
  2331.      * assign permission group to dual mode user
  2332.      */
  2333.     public function assignPermissionUserGroupToDualModeUser($request$user$params$translator)
  2334.     {
  2335.         try {
  2336.             $user DataObject\Customer::getById($params['userid'], true);
  2337.             if (!$user) {
  2338.                 return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  2339.             }
  2340.             $permissionGroups = [];
  2341.             foreach ($params['permissions_id'] as $groupId) {
  2342.                 $permissionGroup PermissionGroup::getById($groupId);
  2343.                 if ($permissionGroup) {
  2344.                     $permissionGroups[] = $permissionGroup;
  2345.                 } else {
  2346.                     return ["success" => false"message" => $translator->trans("permission_group_does_not_exists")];
  2347.                 }
  2348.             }
  2349.             $user->setPermissionGroups($permissionGroups);
  2350.             $user->save();
  2351.             return ["success" => true"message" => $translator->trans("user_assigned_to_dual_mode_successfully")];
  2352.             
  2353.         } catch (\Exception $ex) {
  2354.             return ["success" => false"message" => $ex->getMessage()];
  2355.         }
  2356.     }
  2357.     /**
  2358.      * Summary of assignBulkUserPermissionGroup
  2359.      * assign permission groups to multiple users in bulk
  2360.      */
  2361.     public function assignBulkUserPermissionGroup($user$params$translator)
  2362.     {
  2363.         try {
  2364.             // Validate and prepare users
  2365.             $userData = [];
  2366.             foreach ($params["userIds"] as $userId) {
  2367.                 $userToUpdate DataObject\Customer::getById($userId);
  2368.                 if (!$userToUpdate) {
  2369.                     return ["success" => false"message" => $translator->trans("User_not_found") . ": " $userId];
  2370.                 }
  2371.                 $userData[] = $userToUpdate;
  2372.             }
  2373.             // Validate and prepare permission groups
  2374.             $permissionGroups = [];
  2375.             foreach ($params["permissionIds"] as $groupId) {
  2376.                 $permissionGroup PermissionGroup::getById($groupId);
  2377.                 if (!$permissionGroup) {
  2378.                     return ["success" => false"message" => $translator->trans("Invalid_GroupId") . ": " $groupId];
  2379.                 }
  2380.                 $permissionGroups[] = $permissionGroup;
  2381.             }
  2382.             // Assign permission groups to all users
  2383.             foreach ($userData as $userToUpdate) {
  2384.                 $userToUpdate->setPermissionGroups($permissionGroups);
  2385.                 $userToUpdate->save();
  2386.             }
  2387.             return ["success" => true"message" => $translator->trans("Permission_groups_assigned")];
  2388.         } catch (\Exception $ex) {
  2389.             return ["success" => false"message" => $ex->getMessage()];
  2390.         }
  2391.     }
  2392.     /**
  2393.      * Get User List
  2394.      */
  2395.     public function getUsers($request$user$translator$params$paginator)
  2396.     {
  2397.         $result = [];
  2398.         $userData = [];
  2399.         try {
  2400.             if ($user->getOrganization() === null) {
  2401.                 return ["success" => false"message" => $translator->trans("organization_does_not_exists")];
  2402.             }
  2403.             $organizationId $user->getOrganization()->getId();
  2404.             
  2405.             // Get All the Classes
  2406.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  2407.             $customer $class->getDao()->getIdByName('Customer');
  2408.             $subscription $class->getDao()->getIdByName('Subscription');
  2409.             $userRole $class->getDao()->getIdByName('UserRole');
  2410.             $organization $class->getDao()->getIdByName('Organization');
  2411.             $package $class->getDao()->getIdByName('Package');
  2412.             $db Db::get();
  2413.             $select $db->createQueryBuilder();
  2414.             $select->select('customer.oo_id');
  2415.             $select->from('object_' $customer'customer');
  2416.             $select->innerJoin('customer''object_' $subscription'subscription''customer.oo_id = subscription.subscribedUser__id');
  2417.             $select->innerJoin('subscription''object_' $package'package''package.oo_id = subscription.subscribedPackage__id');
  2418.             $select->innerJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  2419.             $select->innerJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  2420.             if (isset($params['search']) && !empty($params['search'])) {
  2421.                 $select->andWhere("customer.name LIKE " $db->quote("%" $params['search'] . "%") . " OR customer.email LIKE " $db->quote("%" $params['search'] . "%"));
  2422.             }
  2423.             $select->andWhere("userRole.name = " $db->quote(USER_ROLES['CLIENT_ADMIN']) . " OR userRole.name = " $db->quote(USER_ROLES['CLIENT_USER']));
  2424.             $select->andWhere("customer.oo_id != " $db->quote($user->getId()));
  2425.             $select->andWhere("organization.oo_id = " $db->quote($organizationId));
  2426.             $select->andWhere("customer.isArchive != 1 or customer.isArchive IS NULL");
  2427.             if (isset($params['status']) && $params['status'] == true) {
  2428.                 $select->andWhere("customer.o_published = 1");
  2429.             }
  2430.             $select->orderBy('oo_id''DESC');
  2431.             $select->groupBy(array('oo_id'));
  2432.             $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  2433.             $page = isset($params['page']) ? $params['page'] : 1;
  2434.             $paginator $paginator->paginate(
  2435.                 $select,
  2436.                 $page,
  2437.                 $pageSize
  2438.             );
  2439.             foreach ($paginator as $usersId) {
  2440.                 $usersData DataObject\Customer::getById($usersId['oo_id'], true);
  2441.                 if ($usersData instanceof \Pimcore\Model\DataObject\Customer) {
  2442.                     // Get Custom Subscription of the organization and package
  2443.                     $customSubscriptions = new DataObject\Subscription\Listing();
  2444.                     $customSubscriptions->filterBySubscribedUser($usersData);
  2445.                     $customSubscriptions->filterByIsActive(true);
  2446.                     $status "Pending";
  2447.                     if ($usersData->getToken() == "" && $usersData->isPublished() == true) {
  2448.                         if ($customSubscriptions->count() > 0) {
  2449.                             $status "Active";
  2450.                         } else {
  2451.                             $status "Suspended";
  2452.                         }
  2453.                     } elseif ($usersData->getToken() != "" && $usersData->isPublished() == false) {
  2454.                         $status "Pending";
  2455.                     }
  2456.                     $permissionObj $this->getUserPermissionInfo($usersData$translator);
  2457.                     $userPermissions $permissionObj['success'] ? $permissionObj['grants'] : null;
  2458.                     $customSubscriptions->filterBySubscriptionType("custom");
  2459.                     $customSubscriptions->setOrderKey("o_modificationDate");
  2460.                     $customSubscriptions->setOrder("desc");
  2461.                     $apiGroupData = [];
  2462.                     $packageData = [];
  2463.                     $dissAllowedApiGroupID = [];
  2464.                     if ($customSubscriptions->count() > 0) {
  2465.                         foreach ($customSubscriptions as $key => $customSubscription) {
  2466.                             if ($customSubscription instanceof \Pimcore\Model\DataObject\Subscription) {
  2467.                                 $package $customSubscription->getSubscribedPackage();
  2468.                                 if ($package) {
  2469.                                     $packageData[] = [
  2470.                                         "id" => $package->getId(),
  2471.                                         "name" => $package->getName(),
  2472.                                         "package_expiry" => $customSubscription->getEndDate(date("M d, Y"))
  2473.                                     ];
  2474.                                 }
  2475.                                 $disallowedApiGroups $customSubscription->getDisallowedApiGroups();
  2476.                                 if (count($disallowedApiGroups) > 0) {
  2477.                                     foreach ($disallowedApiGroups as $value) {
  2478.                                         $dissAllowedApiGroupID[] = $value->getId();
  2479.                                     }
  2480.                                 }
  2481.                                 if ($package) {
  2482.                                     $apiGroups $package->getApiGroups();
  2483.                                     if ($apiGroups) {
  2484.                                         foreach ($apiGroups as  $apiGroup) {
  2485.                                             if (!in_array($apiGroup->getId(), $dissAllowedApiGroupID)) {
  2486.                                                 $apiGroupData[] = [
  2487.                                                     "id" => $apiGroup->getId(),
  2488.                                                     "name" => $apiGroup->getApiGroupName('en'),
  2489.                                                     "name_ar" => $apiGroup->getApiGroupName('ar')
  2490.                                                 ];
  2491.                                             }
  2492.                                         }
  2493.                                     }
  2494.                                 }
  2495.                             }
  2496.                         }
  2497.                     }
  2498.                     $typeArray = [
  2499.                         "key" => 'user',
  2500.                         'name_en' => $translator->trans('user', [], null'en'),
  2501.                         'name_ar' => $translator->trans('user', [], null'ar'),
  2502.                     ];
  2503.                     $roleArray = [
  2504.                         "key" => ($usersData->getRole()) ? $usersData->getRole()->getName() : null,
  2505.                         'name_en' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'en') : null,
  2506.                         'name_ar' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'ar') : null,
  2507.                     ];
  2508.                     $statusArray = [
  2509.                         "key" => $status,
  2510.                         'name_en' => $translator->trans($status, [], null'en'),
  2511.                         'name_ar' => $translator->trans($status, [], null'ar'),
  2512.                     ];
  2513.                     $userData[] = [
  2514.                         'id' => $usersData->getId(),
  2515.                         'name' => $usersData->getName(),
  2516.                         'title' => $usersData->getTitle(),
  2517.                         'email' => $usersData->getEmail(),
  2518.                         'phone' => $usersData->getPhoneNo(),
  2519.                         'department' => $usersData->getDepartment(),
  2520.                         'role' => $roleArray,
  2521.                         'organization' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName() : null,
  2522.                         'organizationId' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getId() : null,
  2523.                         'location' => $this->getLocationList($usersData),
  2524.                         'allowCustomNotification' => ($permissionObj['success']) ? $userPermissions['get_custom_notification'] : false,
  2525.                         'allowAddLocation' => ($permissionObj['success']) ? $userPermissions['create_location'] : false,
  2526.                         'allowForecast' => ($permissionObj['success']) ? $userPermissions['get_weather'] : false,
  2527.                         'allowAlertHistoryForCustomAlerts' => ($permissionObj['success']) ? $userPermissions['alert_history'] : false,
  2528.                         'automotive' => ($permissionObj['success']) ? $userPermissions['automotive'] : false,
  2529.                         'aviation' => ($permissionObj['success']) ? $userPermissions['aviation'] : false,
  2530.                         'shippingAndOffshore' => ($permissionObj['success']) ? $userPermissions['shipping_and_offshore'] : false,
  2531.                         'insurance' => ($permissionObj['success']) ? $userPermissions['insurance'] : false,
  2532.                         'energy' => ($permissionObj['success']) ? $userPermissions['energy'] : false,
  2533.                         'type' => $typeArray,
  2534.                         'status' => $statusArray,
  2535.                         'packageData' => $packageData,
  2536.                         'apiGroups' => $apiGroupData,
  2537.                         'createdBy' => $usersData->getCreatedBy() ? $usersData->getCreatedBy()->getName() : null,
  2538.                         'iqamaId' => $usersData->getIqamaId() ? (string) $usersData->getIqamaId() : null,
  2539.                         //'token' => $status == "Pending" ? $usersData->getToken() : '',
  2540.                     ];
  2541.                 }
  2542.             }
  2543.             if (!$paginator->count()) {
  2544.                 return ["success" => false"message" => $translator->trans("no_user_available_to_this_organization.")];
  2545.             }
  2546.             return ["success" => TRUE"data" => $userData'paginationVariables' => $paginator->getPaginationData()];
  2547.         } catch (\Exception $ex) {
  2548.             throw new \Exception($ex->getMessage());
  2549.         }
  2550.         return $result;
  2551.     }
  2552.     // /**
  2553.     //  * set package subscription
  2554.     //  */
  2555.     // public function setPcakageSubscription($params)
  2556.     // {
  2557.     //     $result = [];
  2558.     //     try {
  2559.     //         $apiGroup = $this->createApiGrpup($params);
  2560.     //         $package = new DataObject\Package();
  2561.     //         $package->setParent(DataObject\Service::createFolderByPath('/UserManagement/Packages/CustomPackages/'));
  2562.     //         $package->setKey(\Pimcore\Model\Element\Service::getValidKey($apiGroup->getId() . time(), 'object'));
  2563.     //         $package->setApiGroups([$apiGroup]);
  2564.     //         $package->setTenure(1);
  2565.     //         $package->setMaxLocation(100);
  2566.     //         $package->setMaxUsers(100);
  2567.     //         $package->setIsActive(true);
  2568.     //         $package->setPublished(true);
  2569.     //         $package->save();
  2570.     //         $subscription = $this->setSubscription($package, $params['user']);
  2571.     //         if ($subscription instanceof DataObject\Subscription) {
  2572.     //             return ["success" => true, "message" => "set_subscription."];
  2573.     //         }
  2574.     //         //return $subscription;
  2575.     //     } catch (\Exception $ex) {
  2576.     //         throw new \Exception($ex->getMessage());
  2577.     //     }
  2578.     //     return $result;
  2579.     // }
  2580.     /**
  2581.      * set create subscription
  2582.      */
  2583.     public function setSubscription($package$user$disallowedApiGroupsArray$subscriptionType$isNoExpiry false)
  2584.     {
  2585.         $result = [];
  2586.         try {
  2587.             if (!$package instanceof DataObject\Package) {
  2588.                 return ["success" => false"message" => "Package is not available"];
  2589.             }
  2590.             if (!$user instanceof DataObject\Customer) {
  2591.                 return ["success" => false"message" => "User is not available"];
  2592.             }
  2593.             $organization $user->getOrganization();
  2594.             if (!$organization instanceof DataObject\Organization) {
  2595.                 return ["success" => false"message" => "Organization is not available"];
  2596.             }
  2597.             $packageActivationDate $organization->getPackageActivationDate();
  2598.             if (!$packageActivationDate || strtotime($packageActivationDate) === false) {
  2599.                 $packageActivationDate date('Y-m-d');
  2600.             } else {
  2601.                 $packageActivationDate date('Y-m-d'strtotime($packageActivationDate));
  2602.             }
  2603.             // Set Subscription Expiry
  2604.             $subscriptionExpiry date('Y-m-d'strtotime('+' $organization->getTrialLimit() . ' days'strtotime($packageActivationDate)));
  2605.             $subscription = new DataObject\Subscription();
  2606.             $subscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/' $user->getEmail()));
  2607.             $subscription->setKey(\Pimcore\Model\Element\Service::getValidKey($package->getId() . time() . rand(100010000), 'object'));
  2608.             $subscription->setSubscribedPackage($package);
  2609.             $subscription->setSubscribedUser($user);
  2610.             //Set Disallowed ApiGroups
  2611.             if ($disallowedApiGroupsArray != null) {
  2612.                 $disallowedApiGroups = [];
  2613.                 foreach ($disallowedApiGroupsArray as $disallowedApiGroupsId) {
  2614.                     $apiGroup =  DataObject\APIGroup::getById($disallowedApiGroupsIdtrue);
  2615.                     $disallowedApiGroups[] = $apiGroup;
  2616.                 }
  2617.                 $subscription->setDisallowedApiGroups($disallowedApiGroups);
  2618.             }
  2619.             //$subscription->setDisallowedApis($disAllowPermissions);
  2620.             $subscription->setSubscriptionType($subscriptionType);
  2621.             $subscription->setStartDate(Carbon::parse(new \Datetime(date('Y-m-d'))));
  2622.             $subscription->setEndDate(Carbon::parse(new \Datetime($subscriptionExpiry)));
  2623.             $subscription->setIsNoExpiry($isNoExpiry);
  2624.             $subscription->setIsActive(true);
  2625.             $subscription->setPublished(true);
  2626.             $subscription->save();
  2627.             return  $subscription;
  2628.         } catch (\Exception $ex) {
  2629.             throw new \Exception($ex->getMessage());
  2630.         }
  2631.         return $result;
  2632.     }
  2633.     /**
  2634.      * set NCM User subscription
  2635.      */
  2636.     public function setNcmUserSubscription($role$user$allowedApiGrpups$isNoExpiry false)
  2637.     {
  2638.         $result = [];
  2639.         try {
  2640.             if ($role instanceof DataObject\UserRole) {
  2641.                 $packages $role->getDefaultPackages();
  2642.                 if ($packages) {
  2643.                     $defaultPackage $packages[0];
  2644.                     if ($defaultPackage instanceof DataObject\Package) {
  2645.                         $subscription = new DataObject\Subscription();
  2646.                         $subscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/NCM Users/' $user->getEmail()));
  2647.                         $subscription->setKey(\Pimcore\Model\Element\Service::getValidKey($defaultPackage->getId() . time() . uniqid(), 'object'));
  2648.                         $subscription->setSubscribedPackage($defaultPackage);
  2649.                         $subscription->setSubscribedUser($user);
  2650.                         //Set allowed ApiGroups
  2651.                         if ($allowedApiGrpups != null) {
  2652.                             $allowedApiGrpupsArray = [];
  2653.                             foreach ($allowedApiGrpups as $allowedApiGrpupId) {
  2654.                                 $apiGroup =  DataObject\APIGroup::getById($allowedApiGrpupIdtrue);
  2655.                                 if ($apiGroup) {
  2656.                                     $allowedApiGrpupsArray[] = $apiGroup;
  2657.                                 }
  2658.                             }
  2659.                             $subscription->setAllowedApiGroups($allowedApiGrpupsArray);
  2660.                         }
  2661.                         $subscriptionExpiry date('Y-m-d'strtotime('+' $defaultPackage->getTenure() . ' days'));
  2662.                         $subscription->setSubscriptionType("default");
  2663.                         $subscription->setStartDate(Carbon::parse(new \Datetime(date('Y-m-d'))));
  2664.                         $subscription->setEndDate(Carbon::parse(new \Datetime($subscriptionExpiry)));
  2665.                         $subscription->setIsNoExpiry($isNoExpiry);
  2666.                         $subscription->setIsActive(true);
  2667.                         $subscription->setPublished(true);
  2668.                         $subscription->save();
  2669.                         return $subscription;
  2670.                     }
  2671.                 }
  2672.             }
  2673.         } catch (\Exception $ex) {
  2674.             throw new \Exception($ex->getMessage());
  2675.         }
  2676.         return $result;
  2677.     }
  2678.     /**
  2679.      * set create subscription
  2680.      */
  2681.     public function updateSubscription($package$user$disAllowPermissions$subscriptionType "custom")
  2682.     {
  2683.         $result = [];
  2684.         try {
  2685.             if (!$package instanceof DataObject\Package) {
  2686.                 return ["success" => false"message" => "Package is not available"];
  2687.             }
  2688.             if (!$user instanceof DataObject\Customer) {
  2689.                 return ["success" => false"message" => "User is not available"];
  2690.             }
  2691.             $subscriptionExpiry date('Y-m-d'strtotime('+' $package->getTenure() . ' days'));
  2692.             $customSubscriptions = new DataObject\Subscription\Listing();
  2693.             $customSubscriptions->filterBySubscribedUser($user);
  2694.             $customSubscriptions->filterBySubscriptionType($subscriptionType);
  2695.             //$customSubscriptions->filterByIsActive(true);
  2696.             $updateSubscription $customSubscriptions->current();
  2697.             if (!$updateSubscription instanceof  DataObject\Subscription) {
  2698.                 $updateSubscription = new DataObject\Subscription();
  2699.                 $updateSubscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/' $user->getEmail()));
  2700.                 $updateSubscription->setKey(\Pimcore\Model\Element\Service::getValidKey($package->getId() . time() . rand(100010000), 'object'));
  2701.                 $updateSubscription->setStartDate(Carbon::parse(new \Datetime(date('Y-m-d'))));
  2702.                 $updateSubscription->setEndDate(Carbon::parse(new \Datetime($subscriptionExpiry)));
  2703.                 $updateSubscription->setIsActive(true);
  2704.                 $updateSubscription->setSubscriptionType($subscriptionType);
  2705.                 $updateSubscription->setPublished(true);
  2706.                 $updateSubscription->setSubscribedUser($user);
  2707.             }
  2708.             $updateSubscription->setSubscribedPackage($package);
  2709.             if ($subscriptionType == 'default') {
  2710.                 $updateSubscription->setIsNoExpiry(true);
  2711.             }
  2712.             $updateSubscription->save();
  2713.             return  $updateSubscription;
  2714.         } catch (\Exception $ex) {
  2715.             throw new \Exception($ex->getMessage());
  2716.         }
  2717.         return $result;
  2718.     }
  2719.     /**
  2720.      * Update NCM User Subscription
  2721.      */
  2722.     public function updateNCMUserSubscription($user$allowedApiGroups)
  2723.     {
  2724.         $result = [];
  2725.         try {
  2726.             if (!$user instanceof DataObject\Customer) {
  2727.                 return ["success" => false"message" => "User is not available"];
  2728.             }
  2729.             $subscriptionListing = new DataObject\Subscription\Listing();
  2730.             $subscriptionListing->filterBySubscribedUser($user);
  2731.             $subscriptionListing->filterByIsActive(true);
  2732.             // Fetch all active subscriptions
  2733.             $activeSubscriptions iterator_to_array($subscriptionListing);
  2734.             if (count($activeSubscriptions) === 0) {
  2735.                 $defaultPackage $user->getRole()?->getDefaultPackages()[0] ?? null;
  2736.                 if ($defaultPackage instanceof DataObject\Package) {
  2737.                     $subscription = new DataObject\Subscription();
  2738.                     $subscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/NCM Users/' $user->getEmail()));
  2739.                     $subscription->setKey(\Pimcore\Model\Element\Service::getValidKey($defaultPackage->getId() . time() . uniqid(), 'object'));
  2740.                     $subscription->setSubscribedPackage($defaultPackage);
  2741.                     $subscription->setSubscribedUser($user);
  2742.                     $subscription->setStartDate(Carbon::parse(new \DateTime(date('Y-m-d'))));
  2743.                     // Set end date to one month from today
  2744.                     $subscription->setEndDate(Carbon::now()->addMonth());
  2745.                     $subscription->setIsNoExpiry(true);
  2746.                     $subscription->setIsActive(true);
  2747.                     $subscription->setPublished(false);
  2748.                     $subscription->save();
  2749.                     $activeSubscriptions = [$subscription];
  2750.                 }
  2751.             }
  2752.             // Unpublish all active subscriptions except the first one
  2753.             foreach ($activeSubscriptions as $index => $subscription) {
  2754.                 if ($index 0) {
  2755.                     $subscription->setPublished(false);
  2756.                     $subscription->save();
  2757.                 }
  2758.             }
  2759.             // Update the first subscription if it exists
  2760.             $updateSubscription $activeSubscriptions[0] ?? null;
  2761.             if ($updateSubscription instanceof DataObject\Subscription) {
  2762.                 // Set allowed ApiGroups
  2763.                 if (!empty($allowedApiGroups)) {
  2764.                     $allowedApiGroupsArray = [];
  2765.                     foreach ($allowedApiGroups as $allowedApiGroupId) {
  2766.                         $apiGroup DataObject\APIGroup::getById($allowedApiGroupIdtrue);
  2767.                         if ($apiGroup) {
  2768.                             $allowedApiGroupsArray[] = $apiGroup;
  2769.                         }
  2770.                     }
  2771.                     $updateSubscription->setAllowedApiGroups($allowedApiGroupsArray);
  2772.                 }
  2773.                 $updateSubscription->setSubscriptionType("default");
  2774.                 $updateSubscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/NCM Users/' $user->getEmail()));
  2775.                 $updateSubscription->save();
  2776.                 return $updateSubscription;
  2777.             }
  2778.         } catch (\Exception $ex) {
  2779.             throw new \Exception($ex->getMessage());
  2780.         }
  2781.         return $result;
  2782.     }
  2783.     /**
  2784.      * set package subscription
  2785.      */
  2786.     public function createApiGrpup($params)
  2787.     {
  2788.         $result = [];
  2789.         try {
  2790.             $mergedArray = [];
  2791.             if (isset($params['allowAddLocation']) && $params['allowAddLocation'] === true) {
  2792.                 foreach (USER_PERMISSIONS['is_allow_location'] as $value) {
  2793.                     $mergedArray[] = $value;
  2794.                 }
  2795.             }
  2796.             if (isset($params['is_allow_user']) && $params['is_allow_user']   === true) {
  2797.                 foreach (USER_PERMISSIONS['is_allow_user'] as $value) {
  2798.                     $mergedArray[] = $value;
  2799.                 }
  2800.             }
  2801.             if (isset($params['is_allow_ncm_user']) && $params['is_allow_ncm_user']  === true) {
  2802.                 foreach (USER_PERMISSIONS['is_allow_ncm_user'] as $value) {
  2803.                     $mergedArray[] = $value;
  2804.                 }
  2805.             }
  2806.             if (isset($params['is_allow_organization']) && $params['is_allow_organization']  === true) {
  2807.                 foreach (USER_PERMISSIONS['is_allow_organization'] as $value) {
  2808.                     $mergedArray[] = $value;
  2809.                 }
  2810.             }
  2811.             if (isset($params['is_allow_ncm_organization']) && $params['is_allow_ncm_organization']  === true) {
  2812.                 foreach (USER_PERMISSIONS['is_allow_ncm_organization'] as $value) {
  2813.                     $mergedArray[] = $value;
  2814.                 }
  2815.             }
  2816.             if (isset($params['is_allow_custom_notification']) && $params['is_allow_custom_notification']  === true) {
  2817.                 foreach (USER_PERMISSIONS['is_allow_custom_notification'] as $value) {
  2818.                     $mergedArray[] = $value;
  2819.                 }
  2820.             }
  2821.             if (isset($params['is_allow_weather_forecast']) && $params['is_allow_weather_forecast']  === true) {
  2822.                 foreach (USER_PERMISSIONS['is_allow_weather_forecast'] as $key => $value) {
  2823.                     $mergedArray[] = $value;
  2824.                 }
  2825.             }
  2826.             if (isset($params['is_allow_alert']) && $params['is_allow_alert']  === true) {
  2827.                 foreach (USER_PERMISSIONS['is_allow_alert'] as $value) {
  2828.                     $mergedArray[] = $value;
  2829.                 }
  2830.             }
  2831.             if (isset($params['is_allow_report']) && $params['is_allow_report']  === true) {
  2832.                 foreach (USER_PERMISSIONS['is_allow_report'] as $value) {
  2833.                     $mergedArray[] = $value;
  2834.                 }
  2835.             }
  2836.             if (isset($params['is_allow_weather_warnings']) && $params['is_allow_weather_warnings']  === true) {
  2837.                 foreach (USER_PERMISSIONS['is_allow_weather_warnings'] as $value) {
  2838.                     $mergedArray[] = $value;
  2839.                 }
  2840.             }
  2841.             if (isset($params['is_energy']) && $params['is_energy']  === true) {
  2842.                 foreach (USER_PERMISSIONS['is_energy'] as $value) {
  2843.                     $mergedArray[] = $value;
  2844.                 }
  2845.             }
  2846.             if (isset($params['is_insurance']) && $params['is_insurance']  === true) {
  2847.                 foreach (USER_PERMISSIONS['is_insurance'] as $value) {
  2848.                     $mergedArray[] = $value;
  2849.                 }
  2850.             }
  2851.             if (isset($params['is_shippingAndOffshore']) && $params['is_shippingAndOffshore']  === true) {
  2852.                 foreach (USER_PERMISSIONS['is_shippingAndOffshore'] as $value) {
  2853.                     $mergedArray[] = $value;
  2854.                 }
  2855.             }
  2856.             if (isset($params['is_automotive']) && $params['is_automotive']  === true) {
  2857.                 foreach (USER_PERMISSIONS['is_automotive'] as $value) {
  2858.                     $mergedArray[] = $value;
  2859.                 }
  2860.             }
  2861.             if (isset($params['is_aviation']) && $params['is_aviation']  === true) {
  2862.                 foreach (USER_PERMISSIONS['is_aviation'] as $value) {
  2863.                     $mergedArray[] = $value;
  2864.                 }
  2865.             }
  2866.             if (isset($params['is_agriculture']) && $params['is_agriculture']  === true) {
  2867.                 foreach (USER_PERMISSIONS['is_agriculture'] as $value) {
  2868.                     $mergedArray[] = $value;
  2869.                 }
  2870.             }
  2871.             if (isset($params['invitingClients']) && $params['invitingClients']  === true) {
  2872.                 foreach (USER_PERMISSIONS['invitingClients'] as $value) {
  2873.                     $mergedArray[] = $value;
  2874.                 }
  2875.             }
  2876.             if (isset($params['managingClients']) && $params['managingClients']  === true) {
  2877.                 foreach (USER_PERMISSIONS['managingClients'] as $value) {
  2878.                     $mergedArray[] = $value;
  2879.                 }
  2880.             }
  2881.             if (isset($params['deletingClients']) && $params['deletingClients']  === true) {
  2882.                 foreach (USER_PERMISSIONS['deletingClients'] as $value) {
  2883.                     $mergedArray[] = $value;
  2884.                 }
  2885.             }
  2886.             if (isset($params['invitingNCMAdmin']) && $params['invitingNCMAdmin']  === true) {
  2887.                 foreach (USER_PERMISSIONS['invitingNCMAdmin'] as $value) {
  2888.                     $mergedArray[] = $value;
  2889.                 }
  2890.             }
  2891.             if (isset($params['managingNCMAdmin']) && $params['managingNCMAdmin']  === true) {
  2892.                 foreach (USER_PERMISSIONS['managingNCMAdmin'] as $value) {
  2893.                     $mergedArray[] = $value;
  2894.                 }
  2895.             }
  2896.             if (isset($params['deletingNCMAdmin']) && $params['deletingNCMAdmin']  === true) {
  2897.                 foreach (USER_PERMISSIONS['deletingNCMAdmin'] as $value) {
  2898.                     $mergedArray[] = $value;
  2899.                 }
  2900.             }
  2901.             // Get unique values using array_unique()
  2902.             $uniqueValues array_unique(array_values($mergedArray));
  2903.             $userPermission  array_values($uniqueValues);
  2904.             $apiGroup = new DataObject\APIGroup();
  2905.             $apiGroup->setParent(DataObject\Service::createFolderByPath('/UserManagement/APIGroups/CustomAPIGroups/'));
  2906.             $apiGroup->setKey(\Pimcore\Model\Element\Service::getValidKey($userPermission[0] . time(), 'object'));
  2907.             $apiGroup->setIsActive(true);
  2908.             $apiGroup->setAllowedApis($userPermission);
  2909.             $apiGroup->setPublished(true);
  2910.             $apiGroup->save();
  2911.             return $apiGroup;
  2912.         } catch (\Exception $ex) {
  2913.             throw new \Exception($ex->getMessage());
  2914.         }
  2915.         return $result;
  2916.     }
  2917.     /**
  2918.      * set User Permissions
  2919.      */
  2920.     public function setUserPermissions($params)
  2921.     {
  2922.         $result = [];
  2923.         try {
  2924.             // check if all permissions are given than now need to create seperate role 
  2925.             $loggedInUserRole = ($params['loggedInUser']->getRole() ? $params['loggedInUser']->getRole()->getName() : null);
  2926.             $invitedUserRoleName = ($params['user']->getRole() ? $params['user']->getRole()->getName() : null);
  2927.             if ($loggedInUserRole == USER_ROLES['NCM_OPERATOR'] || $loggedInUserRole == USER_ROLES['NCM_IT']) {
  2928.                 if ($params['allowCustomNotification'] == true && $params['allowAddLocation'] == true && $params['allowAlertHistoryForCustomAlerts'] == true && $params['allowForecast'] == true && $params['allowOrganizationAdminToInviteUsers'] == true) {
  2929.                     // delete specific role if all permission are given
  2930.                     $permission DataObject\Permission::getByAllowedUserRole($params['user'], true);
  2931.                     if ($permission instanceof \Pimcore\Model\DataObject\Permission) {
  2932.                         $permission->delete();
  2933.                     }
  2934.                     return ["success" => true"message" => "Set Permission."];
  2935.                 }
  2936.             } else {
  2937.                 if (
  2938.                     $params['allowCustomNotification'] == true &&
  2939.                     $params['allowAddLocation'] == true &&
  2940.                     $params['allowAlertHistoryForCustomAlerts'] == true &&
  2941.                     $params['allowForecast'] == true  &&
  2942.                     $params['automotive'] == true &&
  2943.                     $params['aviation'] == true &&
  2944.                     $params['insurance'] == true &&
  2945.                     $params['energy'] == true
  2946.                 ) {
  2947.                     // delete specific role if all permission are given
  2948.                     $permission DataObject\Permission::getByAllowedUserRole($params['user'], true);
  2949.                     if ($permission instanceof \Pimcore\Model\DataObject\Permission) {
  2950.                         $permission->delete();
  2951.                     }
  2952.                     return ["success" => true"message" => "set_permission"];
  2953.                 }
  2954.             }
  2955.             $permission DataObject\Permission::getByAllowedUserRole($params['user'], true);
  2956.             if ($permission) {
  2957.                 // $permission->setDepartment($allowAlertHistoryForCustomAlerts);
  2958.                 $permission->setAlert_history($params['allowAlertHistoryForCustomAlerts']);
  2959.                 $permission->setGet_custom_notification($params['allowCustomNotification']);
  2960.                 $permission->setCreate_location($params['allowAddLocation']);
  2961.                 $permission->setGet_weather($params['allowForecast']);
  2962.                 // set Industry permissions
  2963.                 $permission->setAutomotive($params['automotive'] == false false true);
  2964.                 $permission->setAviation($params['aviation'] == false false true);
  2965.                 $permission->setShipping_and_offshore($params['shippingAndOffshore'] == false false true);
  2966.                 $permission->setInsurance($params['insurance'] == false false true);
  2967.                 $permission->setEnergy($params['energy'] == false false true);
  2968.                 // default permission on the basis of add location
  2969.                 if (false == $params['allowAddLocation']) {
  2970.                     $permission->setEdit_location(false);
  2971.                     $permission->setDelete_location(false);
  2972.                     $permission->setSearch_location(false);
  2973.                     $permission->setCompare_location(false);
  2974.                 } else {
  2975.                     $permission->setEdit_location(true);
  2976.                     $permission->setDelete_location(true);
  2977.                     $permission->setSearch_location(true);
  2978.                     $permission->setCompare_location(true);
  2979.                 }
  2980.                 // default permission on the basis of add invite user
  2981.                 if ($params['allowOrganizationAdminToInviteUsers'] == true || $invitedUserRoleName == USER_ROLES['CLIENT_ADMIN']) {
  2982.                     $permission->setEdit_user(true);
  2983.                     $permission->setDelete_user(true);
  2984.                     $permission->setList_user(true);
  2985.                     $permission->setSuspend_user(true);
  2986.                     $permission->setInvite_user(true);
  2987.                     $permission->setResend_invite(true);
  2988.                     $permission->setCreate_user(true);
  2989.                 } else {
  2990.                     $permission->setEdit_user(false);
  2991.                     $permission->setDelete_user(false);
  2992.                     $permission->setList_user(false);
  2993.                     $permission->setSuspend_user(false);
  2994.                     $permission->setInvite_user(false);
  2995.                     $permission->setResend_invite(false);
  2996.                     $permission->setCreate_user(false);
  2997.                 }
  2998.                 // default permission to any user
  2999.                 $permission->setGet_profile(true);
  3000.                 $permission->setUpdate_profile(true);
  3001.                 $permission->setChange_password(true);
  3002.                 $permission->setView_user(true);
  3003.                 $permission->setList_location(true);
  3004.                 $permission->setView_location(true);
  3005.                 $permission->setAllowedUserRole($params['user']);
  3006.                 $permission->save();
  3007.             } else {
  3008.                 $permissions = new DataObject\Permission();
  3009.                 $permissions->setParent(DataObject\Service::createFolderByPath('/UserManagement/Permission/User'));
  3010.                 $permissions->setKey($params['user']->getEmail());
  3011.                 // $permissions->setDepartment($allowAlertHistoryForCustomAlerts);
  3012.                 $permissions->setAlert_history($params['allowAlertHistoryForCustomAlerts']);
  3013.                 $permissions->setGet_custom_notification($params['allowCustomNotification']);
  3014.                 $permissions->setInvite_user($params['allowOrganizationAdminToInviteUsers']);
  3015.                 $permissions->setCreate_location($params['allowAddLocation']);
  3016.                 $permissions->setGet_weather($params['allowForecast']);
  3017.                 // set Industry permissions
  3018.                 $permissions->setAutomotive($params['automotive'] == false false true);
  3019.                 $permissions->setAviation($params['aviation'] == false false true);
  3020.                 $permissions->setShipping_and_offshore($params['shippingAndOffshore'] == false false true);
  3021.                 $permissions->setInsurance($params['insurance'] == false false true);
  3022.                 $permissions->setEnergy($params['energy'] == false false true);
  3023.                 // default permission on the basis of add location
  3024.                 if ($params['allowAddLocation'] == true) {
  3025.                     $permissions->setEdit_location(true);
  3026.                     $permissions->setDelete_location(true);
  3027.                     $permissions->setSearch_location(true);
  3028.                     $permissions->setCompare_location(true);
  3029.                 } else {
  3030.                     $permissions->setEdit_location(false);
  3031.                     $permissions->setDelete_location(false);
  3032.                     $permissions->setSearch_location(false);
  3033.                     $permissions->setCompare_location(false);
  3034.                 }
  3035.                 // default permission on the basis of add invite user
  3036.                 if ($params['allowOrganizationAdminToInviteUsers'] == true || $invitedUserRoleName == USER_ROLES['CLIENT_ADMIN']) {
  3037.                     $permissions->setEdit_user(true);
  3038.                     $permissions->setDelete_user(true);
  3039.                     $permissions->setList_user(true);
  3040.                     $permissions->setSuspend_user(true);
  3041.                     $permissions->setInvite_user(true);
  3042.                     $permissions->setResend_invite(true);
  3043.                     $permissions->setCreate_user(true);
  3044.                 } else {
  3045.                     $permissions->setEdit_user(false);
  3046.                     $permissions->setDelete_user(false);
  3047.                     $permissions->setList_user(false);
  3048.                     $permissions->setSuspend_user(false);
  3049.                     $permissions->setInvite_user(false);
  3050.                     $permissions->setResend_invite(false);
  3051.                     $permissions->setCreate_user(false);
  3052.                 }
  3053.                 // default permission to any user
  3054.                 $permissions->setGet_profile(true);
  3055.                 $permissions->setUpdate_profile(true);
  3056.                 $permissions->setChange_password(true);
  3057.                 $permissions->setView_user(true);
  3058.                 $permissions->setList_location(true);
  3059.                 $permissions->setView_location(true);
  3060.                 $permissions->setAllowedUserRole($params['user']);
  3061.                 $permissions->setPublished(true);
  3062.                 $permissions->save();
  3063.             }
  3064.             return ["success" => true"message" => "set_permission."];
  3065.         } catch (\Exception $ex) {
  3066.             throw new \Exception($ex->getMessage());
  3067.         }
  3068.         return $result;
  3069.     }
  3070.     /**
  3071.      * set NCM Admin User Permissions
  3072.      */
  3073.     public function setNCMAdminUserPermissions($params)
  3074.     {
  3075.         $result = [];
  3076.         try {
  3077.             if ($params['invitingClients'] == false || $params['managingClients'] == false || $params['deletingClients'] == false || $params['invitingNCMAdmin'] == false || $params['managingNCMAdmin'] == false || $params['deletingNCMAdmin'] == false) {
  3078.                 $permission DataObject\Permission::getByAllowedUserRole($params['user'], true);
  3079.                 if ($permission) {
  3080.                     // default permission to any user
  3081.                     $permission->setGet_profile(true);
  3082.                     $permission->setUpdate_profile(true);
  3083.                     $permission->setChange_password(true);
  3084.                     $permission->setView_user(true);
  3085.                     $permission->setList_location(true);
  3086.                     $permission->setView_location(true);
  3087.                     $permission->setEdit_location(true);
  3088.                     $permission->setDelete_location(true);
  3089.                     $permission->setSearch_location(true);
  3090.                     $permission->setCompare_location(true);
  3091.                     $permission->setList_ncm_user(true);
  3092.                     $permission->setList_user(true);
  3093.                     // set Industry permissions
  3094.                     $permission->setAutomotive(true);
  3095.                     $permission->setAviation(true);
  3096.                     $permission->setShipping_and_offshore(true);
  3097.                     $permission->setInsurance(true);
  3098.                     $permission->setEnergy(true);
  3099.                     // set invitingClients permissions
  3100.                     $permission->setInvite_user($params['invitingClients'] == false false true);
  3101.                     $permission->setInvite_organization($params['invitingClients'] == false false true);
  3102.                     $permission->setResend_invite($params['invitingClients'] == false false true);
  3103.                     // set managingClients permissions
  3104.                     $permission->setEdit_user($params['managingClients'] == false false true);
  3105.                     // set deletingClients permissions
  3106.                     $permission->setDelete_user($params['deletingClients'] == false false true);
  3107.                     // set invitingNCMAdmin permissions
  3108.                     $permission->setInvite_ncm_user($params['invitingNCMAdmin'] == false false true);
  3109.                     // set managingNCMAdmin permissions
  3110.                     $permission->setEdit_ncm_user($params['managingNCMAdmin'] == false false true);
  3111.                     // set deletingNCMAdmin permissions
  3112.                     $permission->setDelete_ncm_user($params['deletingNCMAdmin'] == false false true);
  3113.                     $permission->setAllowedUserRole($params['user']);
  3114.                     $permission->save();
  3115.                 } else {
  3116.                     $permissions = new DataObject\Permission();
  3117.                     $permissions->setParent(DataObject\Service::createFolderByPath('/UserManagement/Permission/User'));
  3118.                     $permissions->setKey($params['user']->getEmail());
  3119.                     // $permissions->setDepartment($allowAlertHistoryForCustomAlerts);
  3120.                     // default permission to any user
  3121.                     $permissions->setGet_profile(true);
  3122.                     $permissions->setUpdate_profile(true);
  3123.                     $permissions->setChange_password(true);
  3124.                     $permissions->setView_user(true);
  3125.                     $permissions->setList_location(true);
  3126.                     $permissions->setView_location(true);
  3127.                     $permissions->setList_ncm_user(true);
  3128.                     $permissions->setList_user(true);
  3129.                     // set Industry permissions
  3130.                     $permissions->setAutomotive(true);
  3131.                     $permissions->setAviation(true);
  3132.                     $permissions->setShipping_and_offshore(true);
  3133.                     $permissions->setInsurance(true);
  3134.                     $permissions->setEnergy(true);
  3135.                     // set invitingClients permissions
  3136.                     $permissions->setInvite_user($params['invitingClients'] == false false true);
  3137.                     $permissions->setInvite_organization($params['invitingClients'] == false false true);
  3138.                     $permissions->setResend_invite($params['invitingClients'] == false false true);
  3139.                     // set managingClients permissions
  3140.                     $permissions->setEdit_user($params['managingClients'] == false false true);
  3141.                     // set deletingClients permissions
  3142.                     $permissions->setDelete_user($params['deletingClients'] == false false true);
  3143.                     // set invitingNCMAdmin permissions
  3144.                     $permissions->setInvite_ncm_user($params['invitingNCMAdmin'] == false false true);
  3145.                     // set managingNCMAdmin permissions
  3146.                     $permissions->setEdit_ncm_user($params['managingNCMAdmin'] == false false true);
  3147.                     // set deletingNCMAdmin permissions
  3148.                     $permissions->setDelete_ncm_user($params['deletingNCMAdmin'] == false false true);
  3149.                     $permissions->setAllowedUserRole($params['user']);
  3150.                     $permissions->setPublished(true);
  3151.                     $permissions->save();
  3152.                 }
  3153.                 return ["success" => true"message" => "set_permission"];
  3154.             } else {
  3155.                 // delete specific role if all permission are given
  3156.                 $permission DataObject\Permission::getByAllowedUserRole($params['user'], true);
  3157.                 if ($permission instanceof \Pimcore\Model\DataObject\Permission) {
  3158.                     $permission->delete();
  3159.                 }
  3160.                 return ["success" => true"message" => "set_permission"];
  3161.             }
  3162.         } catch (\Exception $ex) {
  3163.             throw new \Exception($ex->getMessage());
  3164.         }
  3165.         return $result;
  3166.     }
  3167.     public function getUserPermissionInfo($user$translator)
  3168.     {
  3169.         $userEmail = [];
  3170.         $userEmail['username'] = $user->getEmail();
  3171.         // return $permission = DataObject\Permission::getByAllowedUserRole($user, true);
  3172.         return $permission $this->userPermission->getUserPermissions($userEmail$translator);
  3173.     }
  3174.     public function getLocationList($user)
  3175.     {
  3176.         try {
  3177.             $entries = new DataObject\Location\Listing();
  3178.             $entries->setCondition("user LIKE " $entries->quote("%," $user->getId() . ",%"));
  3179.             $entries->load();
  3180.             $tempArr = [];
  3181.             if (!empty($entries)) {
  3182.                 foreach ($entries as $object) {
  3183.                     array_push($tempArr$object->getId());
  3184.                 }
  3185.             }
  3186.             return $tempArr;
  3187.         } catch (\Exception $ex) {
  3188.             throw new \Exception($ex->getMessage());
  3189.         }
  3190.     }
  3191.     public function assignLocationToUser($loggedInUser$locationIds$locationTagIds$targetUsers$targetUserGroups$weatherSevereAlert$customNotificationAlert$translator)
  3192.     {
  3193.         $assignedLocationArr = [];
  3194.         // Validate all users and user groups upfront
  3195.         $validatedUsers = [];
  3196.         if ($targetUsers) {
  3197.             foreach ($targetUsers as $userId) {
  3198.                 $user \Pimcore\Model\DataObject::getById($userId);
  3199.                 if (!$user instanceof Customer) {
  3200.                     return ["success" => false"message" => $translator->trans("Invalid User ID"), "userId" => $userId];
  3201.                 }
  3202.                 $organizationMatch \App\Lib\Utility::matchOrganization($user$loggedInUser);
  3203.                 if (!$organizationMatch["success"]) {
  3204.                     return ["success" => false"message" => $translator->trans("User ID does not belong to your organization."), "userId" => $userId];
  3205.                 }
  3206.                 $validatedUsers[] = $user;
  3207.             }
  3208.         }
  3209.         $validatedUserGroups = [];
  3210.         if ($targetUserGroups) {
  3211.             foreach ($targetUserGroups as $userGroupId) {
  3212.                 $userGroup \Pimcore\Model\DataObject::getById($userGroupId);
  3213.                 if (!$userGroup instanceof UserGroup) {
  3214.                     return ["success" => false"message" => $translator->trans("Invalid User Group ID"), "userGroupId" => $userGroupId];
  3215.                 }
  3216.                 $targetUsersInGroup = new DataObject\Customer\Listing();
  3217.                 $targetUsersInGroup->filterByUserGroup($userGroup);
  3218.                 foreach ($targetUsersInGroup as $user) {
  3219.                     $organizationMatch \App\Lib\Utility::matchOrganization($user$loggedInUser);
  3220.                     if (!$organizationMatch["success"]) {
  3221.                         return ["success" => false"message" => $translator->trans("A user in group ID does not belong to your organization."), "userGroupId" => $userGroupId];
  3222.                     }
  3223.                 }
  3224.                 $validatedUserGroups[] = $userGroup;
  3225.             }
  3226.         }
  3227.         // Process Locations by Location IDs
  3228.         if ($locationIds) {
  3229.             foreach ($locationIds as $locationID) {
  3230.                 $location \Pimcore\Model\DataObject::getById($locationID);
  3231.                 if ($location instanceof Location) {
  3232.                     // Assign to validated users
  3233.                     foreach ($validatedUsers as $user) {
  3234.                         $this->locationModel->locationMetaData($location$user$weatherSevereAlert$customNotificationAlert);
  3235.                         $assignedLocationArr[] = $location->getId();
  3236.                     }
  3237.                     // Assign to validated user groups
  3238.                     foreach ($validatedUserGroups as $userGroup) {
  3239.                         $targetUsersInGroup = new DataObject\Customer\Listing();
  3240.                         $targetUsersInGroup->filterByUserGroup($userGroup);
  3241.                         foreach ($targetUsersInGroup as $user) {
  3242.                             $this->locationModel->locationMetaData($location$user$weatherSevereAlert$customNotificationAlert);
  3243.                             $assignedLocationArr[] = $location->getId();
  3244.                         }
  3245.                     }
  3246.                 } else {
  3247.                     return ["success" => false"message" => $translator->trans("Invalid Location ID"), "locationId" => $locationID];
  3248.                 }
  3249.             }
  3250.         }
  3251.         // Process Locations by Location Tag IDs
  3252.         if ($locationTagIds) {
  3253.             foreach ($locationTagIds as $locationTagId) {
  3254.                 $locationTag \Pimcore\Model\DataObject::getById($locationTagId);
  3255.                 if ($locationTag instanceof Tags) {
  3256.                     $locations = new DataObject\Location\Listing();
  3257.                     $locations->setCondition("Tag LIKE " $locations->quote("%," $locationTag->getId() . ",%"));
  3258.                     $locations->load();
  3259.                     foreach ($locations as $location) {
  3260.                         if ($location instanceof Location) {
  3261.                             // Assign to validated users
  3262.                             foreach ($validatedUsers as $user) {
  3263.                                 $this->locationModel->locationMetaData($location$user$weatherSevereAlert$customNotificationAlert);
  3264.                                 $assignedLocationArr[] = $location->getId();
  3265.                             }
  3266.                             // Assign to validated user groups
  3267.                             foreach ($validatedUserGroups as $userGroup) {
  3268.                                 $targetUsersInGroup = new DataObject\Customer\Listing();
  3269.                                 $targetUsersInGroup->filterByUserGroup($userGroup);
  3270.                                 foreach ($targetUsersInGroup as $user) {
  3271.                                     $this->locationModel->locationMetaData($location$user$weatherSevereAlert$customNotificationAlert);
  3272.                                     $assignedLocationArr[] = $location->getId();
  3273.                                 }
  3274.                             }
  3275.                         }
  3276.                     }
  3277.                 } else {
  3278.                     return ["success" => false"message" => $translator->trans("Invalid Location Tag ID"), 'locationId' => $locationTagId];
  3279.                 }
  3280.             }
  3281.         }
  3282.         return array_values(array_unique($assignedLocationArr));
  3283.     }
  3284.     public function getUserLocations($user)
  3285.     {
  3286.         try {
  3287.             $locationData = [];
  3288.             $locations $this->getLocationList($user);
  3289.             if ($locations) {
  3290.                 foreach ($locations as $locationId) {
  3291.                     $location \Pimcore\Model\DataObject::getById($locationId);
  3292.                     if ($location instanceof Location) {
  3293.                         $alertConfig $this->locationModel->getUserSevereAlertAndCustomNotification($location$user);
  3294.                         $locationData[] = [
  3295.                             'id' => $location->getId(),
  3296.                             'name' => $location->getName(),
  3297.                             'title' => $location->getTitle(),
  3298.                             'coordinates' => $location->getCoordinates(),
  3299.                             'severeWeatherAlert' => isset($alertConfig['get_severe_alert']) && ($alertConfig['get_severe_alert'] == true) ?? false,
  3300.                             'customNotificationAlert' => isset($alertConfig['get_custom_notification']) && ($alertConfig['get_custom_notification'] == true) ?? false,
  3301.                         ];
  3302.                     }
  3303.                 }
  3304.             }
  3305.             return $locationData;
  3306.         } catch (\Exception $ex) {
  3307.             throw new \Exception($ex->getMessage());
  3308.         }
  3309.     }
  3310.     public function getUsersLocationByOrganizationId($organizationId)
  3311.     {
  3312.         // try {
  3313.         $organization \Pimcore\Model\DataObject::getById($organizationId);
  3314.         if (!$organization instanceof \Pimcore\Model\DataObject\Organization) {
  3315.             throw new \Exception("Organization not found");
  3316.         }
  3317.         $customers = new \Pimcore\Model\DataObject\Customer\Listing();
  3318.         $customers->filterByOrganization($organization);
  3319.         if ($customers->getCount() == 0) {
  3320.             throw new \Exception("Customers does not exists in this organization");
  3321.         }
  3322.         $locationData = [];
  3323.         foreach ($customers as $customer) {
  3324.             $locations $this->getLocationList($customer);
  3325.             if ($locations) {
  3326.                 foreach ($locations as $locationId) {
  3327.                     $location \Pimcore\Model\DataObject::getById($locationId);
  3328.                     if ($location instanceof Location) {
  3329.                         $alertConfig $this->locationModel->getUserSevereAlertAndCustomNotification($location$customer);
  3330.                         $locationData[] = [
  3331.                             'id' => $location->getId(),
  3332.                             'name' => $location->getName(),
  3333.                             'title' => $location->getTitle(),
  3334.                             'coordinates' => $location->getCoordinates(),
  3335.                             'severeWeatherAlert' => isset($alertConfig['get_severe_alert']) && ($alertConfig['get_severe_alert'] == true) ?? false,
  3336.                             'customNotificationAlert' => isset($alertConfig['get_custom_notification']) && ($alertConfig['get_custom_notification'] == true) ?? false,
  3337.                             "customerId" => $customer->getId(),
  3338.                             "customerName" => $customer->getName(),
  3339.                             "customerEmail" => $customer->getEmail()
  3340.                         ];
  3341.                     }
  3342.                 }
  3343.             }
  3344.         }
  3345.         return $locationData;
  3346.         // } catch (\Exception $ex) {
  3347.         //     throw new \Exception($ex->getMessage());
  3348.         // }
  3349.     }
  3350.     /**
  3351.      * Get User Assigned API Groups
  3352.      *
  3353.      */
  3354.     public function getUserApiGroups($user)
  3355.     {
  3356.         $apiGroups = [];
  3357.         $subscriptions = new DataObject\Subscription\Listing();
  3358.         $subscriptions->filterBySubscribedUser($user);
  3359.         $currentDate date('Y-m-d'); // Assuming the date and time format is 'YYYY-MM-DD'
  3360.         $subscriptions->filterByEndDate(strtotime($currentDate), ">=");
  3361.         $subscriptions->filterBySubscriptionType("custom");
  3362.         $subscriptions->filterByIsActive(true);
  3363.         $subscriptions->load();
  3364.         foreach ($subscriptions as $subscription) {
  3365.             $package $subscription->getSubscribedPackage();
  3366.             if ($package instanceof DataObject\Package) {
  3367.                 if ($package->getApiGroups()) {
  3368.                     foreach ($package->getApiGroups() as $key => $ApiGroup) {
  3369.                         $apiGroups[] = [
  3370.                             "apiGroupId" => $ApiGroup->getId(),
  3371.                             "type" => $ApiGroup->getApiGroupType(),
  3372.                             "name" => $ApiGroup->getApiGroupName('en'),
  3373.                             "name_ar" => $ApiGroup->getApiGroupName('ar'),
  3374.                         ];
  3375.                     }
  3376.                 }
  3377.             }
  3378.         }
  3379.         return $apiGroups;
  3380.     }
  3381.     /**
  3382.      * generate unsubscribe token user
  3383.      */
  3384.     public function unSubscribeGenerateToken($email)
  3385.     {
  3386.         $token '';
  3387.         try {
  3388.             //generate token
  3389.             $user DataObject\Customer::getByEmail($emailtrue);
  3390.             // $token = md5($user->getEmail() . time() . uniqid());
  3391.             $token base64_encode($user->getEmail() . time() . uniqid());
  3392.             $user->setunSubscribeToken($token);
  3393.             $user->save();
  3394.             return $token;
  3395.         } catch (\Exception $ex) {
  3396.             throw new \Exception($ex->getMessage());
  3397.         }
  3398.         return $token;
  3399.     }
  3400.     /**
  3401.      * generate unsubscribe ews notification token user
  3402.      */
  3403.     public function unSubscribeEwsGenerateToken($email)
  3404.     {
  3405.         $token '';
  3406.         try {
  3407.             //generate token
  3408.             $user DataObject\Customer::getByEmail($emailtrue);
  3409.             // $token = md5($user->getEmail() . time() . uniqid());
  3410.             $token base64_encode($user->getEmail() . time() . uniqid());
  3411.             $user->setEwsNotificationToken($token);
  3412.             $user->save();
  3413.             return $token;
  3414.         } catch (\Exception $ex) {
  3415.             throw new \Exception($ex->getMessage());
  3416.         }
  3417.         return $token;
  3418.     }
  3419.     /**
  3420.      * Get NCM User List
  3421.      */
  3422.     public function getAllActiveUsersInExcelData($params$user$translator)
  3423.     {
  3424.         $result = [];
  3425.         try {
  3426.             $userDataEn = [];
  3427.             // Get All the Classes
  3428.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  3429.             $customer $class->getDao()->getIdByName('Customer');
  3430.             $subscription $class->getDao()->getIdByName('Subscription');
  3431.             $userRole $class->getDao()->getIdByName('UserRole');
  3432.             $organization $class->getDao()->getIdByName('Organization');
  3433.             $package $class->getDao()->getIdByName('Package');
  3434.             $db Db::get();
  3435.             $select $db->createQueryBuilder();
  3436.             $select->select('customer.oo_id');
  3437.             $select->from('object_' $customer'customer');
  3438.             $select->innerJoin('customer''object_' $subscription'subscription''customer.oo_id = subscription.subscribedUser__id');
  3439.             $select->innerJoin('subscription''object_' $package'package''package.oo_id = subscription.subscribedPackage__id');
  3440.             $select->innerJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  3441.             $select->innerJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  3442.             // if (isset($params['search']) && !empty($params['search'])) {
  3443.             //     $select->andWhere("customer.name LIKE " . $db->quote("%" . $params['search'] . "%") . " OR customer.email LIKE " . $db->quote("%" . $params['search'] . "%"));
  3444.             // }
  3445.             if (isset($params['type']) && !empty($params['type'])) {
  3446.                 if ($params['type'] == 'client') {
  3447.                     $select->andWhere("userRole.name = " $db->quote(USER_ROLES['CLIENT_ADMIN']) . " OR userRole.name = " $db->quote(USER_ROLES['CLIENT_USER']));
  3448.                 } elseif ($params['type'] == 'ncm') {
  3449.                     $select->andWhere("userRole.name = " $db->quote(USER_ROLES['NCM_IT']) . " OR userRole.name = " $db->quote(USER_ROLES['NCM_OPERATOR']));
  3450.                 }
  3451.             }
  3452.             $select->andWhere("customer.oo_id != " $db->quote($user->getId()));
  3453.             $select->andWhere("customer.isDeleted != 1 or customer.isDeleted IS NULL");
  3454.             if (!empty($params["entityId"])) {
  3455.                 $select->andWhere("organization.oo_id = " $db->quote($params["entityId"]));
  3456.             }
  3457.             $select->orderBy('oo_id''DESC');
  3458.             $select->groupBy(array('oo_id'));
  3459.             $select $select->execute();
  3460.             $usersIds $select->fetchAllAssociative();
  3461.             if (count($usersIds) == 0) {
  3462.                 return ["success" => false"message" => $translator->trans("no_user_available_in_NCM")];
  3463.             }
  3464.             $userDataEn[] = [
  3465.                 'S. No' => 'S. No',
  3466.                 'Username' => 'Username',
  3467.                 'Entity' => 'Entity',
  3468.                 'Entity AR' => 'Entity AR',
  3469.                 'Email Address' => 'Email Address',
  3470.                 'Type' => 'Type',
  3471.                 'Role' => 'Role',
  3472.                 'Created By' => 'Created By',
  3473.                 'Created On' => 'Created On',
  3474.                 'Package' => 'Package',
  3475.                 'Package Expiry' => 'Package Expiry',
  3476.                 'Status' => 'Status',
  3477.             ];
  3478.             foreach ($usersIds as $userKey => $usersId) {
  3479.                 $usersData DataObject\Customer::getById($usersId['oo_id'], true);
  3480.                 if ($usersData instanceof \Pimcore\Model\DataObject\Customer) {
  3481.                     // Get Custom Subscription of the organization and package
  3482.                     $customSubscriptions = new DataObject\Subscription\Listing();
  3483.                     $customSubscriptions->filterBySubscribedUser($usersData);
  3484.                     $customSubscriptions->filterByIsActive(true);
  3485.                     $status "";
  3486.                     if ($usersData->getToken() == "" && $usersData->isPublished() == true) {
  3487.                         if ($customSubscriptions->count() > 0) {
  3488.                             $status "Active";
  3489.                         } else {
  3490.                             $status "Suspended";
  3491.                         }
  3492.                     } elseif ($usersData->getToken() != "" && $usersData->isPublished() == false) {
  3493.                         $status "Pending";
  3494.                     }
  3495.                     $permissionObj $this->getUserPermissionInfo($usersData$translator);
  3496.                     $userPermissions $permissionObj['success'] ? $permissionObj['grants'] : null;
  3497.                     $customSubscriptions->filterBySubscriptionType("custom");
  3498.                     $customSubscriptions->setOrderKey("o_modificationDate");
  3499.                     $customSubscriptions->setOrder("desc");
  3500.                     $apiGroupData = [];
  3501.                     $packageData = [];
  3502.                     if ($customSubscriptions->count() > 0) {
  3503.                         foreach ($customSubscriptions as $key => $customSubscription) {
  3504.                             if ($customSubscription instanceof \Pimcore\Model\DataObject\Subscription) {
  3505.                                 $package $customSubscription->getSubscribedPackage();
  3506.                                 $disallowedApiGroups $customSubscription->getDisallowedApiGroups();
  3507.                                 if ($package) {
  3508.                                     $packageData[] = [
  3509.                                         "id" => $package->getId(),
  3510.                                         "name" => $package->getPackageName("en"),
  3511.                                         "package_expiry" => $customSubscription->getEndDate(date("M d, Y"))
  3512.                                     ];
  3513.                                     $apiGroups $package->getApiGroups();
  3514.                                     if ($apiGroups) {
  3515.                                         foreach ($apiGroups as  $apiGroup) {
  3516.                                             $apiGroupId $apiGroup->getId();
  3517.                                             $apiGroupNameEn $apiGroup->getApiGroupName('en');
  3518.                                             $apiGroupNameAr $apiGroup->getApiGroupName('ar');
  3519.                                             $isDisallowed false;
  3520.                                             // Check if the current API group is disallowed
  3521.                                             foreach ($disallowedApiGroups as $disallowedApiGroup) {
  3522.                                                 if ($apiGroupId == $disallowedApiGroup->getId()) {
  3523.                                                     $isDisallowed true;
  3524.                                                     break;
  3525.                                                 }
  3526.                                             }
  3527.                                             // Only add the API group if it's not disallowed
  3528.                                             if (!$isDisallowed) {
  3529.                                                 $apiGroupData[] = [
  3530.                                                     "id" => $apiGroupId,
  3531.                                                     "name" => $apiGroupNameEn,
  3532.                                                     "name_ar" => $apiGroupNameAr
  3533.                                                 ];
  3534.                                             }
  3535.                                         }
  3536.                                     }
  3537.                                 }
  3538.                             }
  3539.                         }
  3540.                     }
  3541.                     $userDataEn[] = [
  3542.                         'S. No' => $userKey 1,
  3543.                         'Username' => $usersData->getName(),
  3544.                         'Entity' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName() : null,
  3545.                         'Entity AR' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName('ar') : null,
  3546.                         'Email Address' => $usersData->getEmail(),
  3547.                         'Type' => $translator->trans('user', [], null'en'),
  3548.                         'Role' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'en') : null,
  3549.                         'Created By' => $usersData->getCreatedBy() ? $usersData->getCreatedBy()->getName() : null,
  3550.                         'Created On' => $usersData->getCreationDate() ? date('Y-m-d'$usersData->getCreationDate()) : null,
  3551.                         'Package' => isset($packageData[0]['name']) ? $packageData[0]['name'] : null,
  3552.                         'Package Expiry' => isset($packageData[0]['package_expiry']) ? date("M d, Y"strtotime($packageData[0]['package_expiry'])) : null,
  3553.                         'Status' => $translator->trans($status, [], null'en'),
  3554.                     ];
  3555.                 }
  3556.             }
  3557.             $excelData ExcelGenerator::createAndSaveXlsx($userDataEn$params['type'] . "_users_data"true'/users/excel/');
  3558.             return ["success" => true"message" => $translator->trans("excel_generated"), "data" =>  $excelData];
  3559.         } catch (\Exception $ex) {
  3560.             throw new \Exception($ex->getMessage());
  3561.         }
  3562.     }
  3563.     public function getDualModeUsersInExcelData($params$user$translator)
  3564.     {
  3565.         $result = [];
  3566.         try {
  3567.             $userDataEn = [];
  3568.             // Get All the Classes
  3569.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  3570.             $customer $class->getDao()->getIdByName('Customer');
  3571.             $subscription $class->getDao()->getIdByName('Subscription');
  3572.             $userRole $class->getDao()->getIdByName('UserRole');
  3573.             $organization $class->getDao()->getIdByName('Organization');
  3574.             $package $class->getDao()->getIdByName('Package');
  3575.             $db Db::get();
  3576.             $select $db->createQueryBuilder();
  3577.             $select->select('customer.oo_id');
  3578.             $select->from('object_' $customer'customer');
  3579.             $select->innerJoin('customer''object_' $subscription'subscription''customer.oo_id = subscription.subscribedUser__id');
  3580.             $select->innerJoin('subscription''object_' $package'package''package.oo_id = subscription.subscribedPackage__id');
  3581.             $select->innerJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  3582.             $select->innerJoin('customer''object_' $userRole'userRole''userRole.oo_id = customer.role__id');
  3583.             // Filter for dual mode users
  3584.             $select->andWhere("customer.dualMode = 1");
  3585.             // if (isset($params['type']) && !empty($params['type'])) {
  3586.             //     if ($params['type'] == 'client') {
  3587.             //         $select->andWhere("userRole.name = " . $db->quote(USER_ROLES['CLIENT_ADMIN']) . " OR userRole.name = " . $db->quote(USER_ROLES['CLIENT_USER']));
  3588.             //     } elseif ($params['type'] == 'ncm') {
  3589.             //         $select->andWhere("userRole.name = " . $db->quote(USER_ROLES['NCM_IT']) . " OR userRole.name = " . $db->quote(USER_ROLES['NCM_OPERATOR']));
  3590.             //     }
  3591.             // }
  3592.             $select->andWhere("customer.oo_id != " $db->quote($user->getId()));
  3593.             $select->andWhere("customer.isDeleted != 1 or customer.isDeleted IS NULL");
  3594.             if (!empty($params["entityId"])) {
  3595.                 $select->andWhere("organization.oo_id = ".$db->quote($params["entityId"]));
  3596.             }
  3597.             $select->orderBy('oo_id''DESC');
  3598.             $select->groupBy(array('oo_id'));
  3599.             $select $select->execute();
  3600.             $usersIds $select->fetchAllAssociative();
  3601.             if (count($usersIds) == 0) {
  3602.                 return ["success" => false"message" => $translator->trans("no_dual_mode_user_available")];
  3603.             }
  3604.             $userDataEn[] = [
  3605.                 'S. No' => 'S. No',
  3606.                 'Username' => 'Username',
  3607.                 'Entity' => 'Entity',
  3608.                 'Entity AR' => 'Entity AR',
  3609.                 'Email Address' => 'Email Address',
  3610.                 'Type' => 'Type',
  3611.                 'Role' => 'Role',
  3612.                 'Created By' => 'Created By',
  3613.                 'Created On' => 'Created On',
  3614.                 'Package' => 'Package',
  3615.                 'Package Expiry' => 'Package Expiry',
  3616.                 'Status' => 'Status',
  3617.             ];
  3618.             foreach ($usersIds as $userKey => $usersId) {
  3619.                 $usersData DataObject\Customer::getById($usersId['oo_id'], true);
  3620.                 if ($usersData instanceof \Pimcore\Model\DataObject\Customer) {
  3621.                     // Get Custom Subscription of the organization and package
  3622.                     $customSubscriptions = new DataObject\Subscription\Listing();
  3623.                     $customSubscriptions->filterBySubscribedUser($usersData);
  3624.                     $customSubscriptions->filterByIsActive(true);
  3625.                     $status "";
  3626.                     if ($usersData->getToken() == "" && $usersData->isPublished() == true) {
  3627.                         if ($customSubscriptions->count() > 0) {
  3628.                             $status "Active";
  3629.                         } else {
  3630.                             $status "Suspended";
  3631.                         }
  3632.                     } elseif ($usersData->getToken() != "" && $usersData->isPublished() == false) {
  3633.                         $status "Pending";
  3634.                     }
  3635.                     $permissionObj $this->getUserPermissionInfo($usersData$translator);
  3636.                     $userPermissions $permissionObj['success'] ? $permissionObj['grants'] : null;
  3637.                     $customSubscriptions->filterBySubscriptionType("custom");
  3638.                     $customSubscriptions->setOrderKey("o_modificationDate");
  3639.                     $customSubscriptions->setOrder("desc");
  3640.                     $apiGroupData = [];
  3641.                     $packageData = [];
  3642.                     if ($customSubscriptions->count() > 0) {
  3643.                         foreach ($customSubscriptions as $key => $customSubscription) {
  3644.                             if ($customSubscription instanceof \Pimcore\Model\DataObject\Subscription) {
  3645.                                 $package $customSubscription->getSubscribedPackage();
  3646.                                 $disallowedApiGroups $customSubscription->getDisallowedApiGroups();
  3647.                                 if ($package) {
  3648.                                     $packageData[] = [
  3649.                                         "id" => $package->getId(),
  3650.                                         "name" => $package->getPackageName("en"),
  3651.                                         "package_expiry" => $customSubscription->getEndDate(date("M d, Y"))
  3652.                                     ];
  3653.                                     $apiGroups $package->getApiGroups();
  3654.                                     if ($apiGroups) {
  3655.                                         foreach ($apiGroups as  $apiGroup) {
  3656.                                             $apiGroupId $apiGroup->getId();
  3657.                                             $apiGroupNameEn $apiGroup->getApiGroupName('en');
  3658.                                             $apiGroupNameAr $apiGroup->getApiGroupName('ar');
  3659.                                             $isDisallowed false;
  3660.                                             // Check if the current API group is disallowed
  3661.                                             foreach ($disallowedApiGroups as $disallowedApiGroup) {
  3662.                                                 if ($apiGroupId == $disallowedApiGroup->getId()) {
  3663.                                                     $isDisallowed true;
  3664.                                                     break;
  3665.                                                 }
  3666.                                             }
  3667.                                             // Only add the API group if it's not disallowed
  3668.                                             if (!$isDisallowed) {
  3669.                                                 $apiGroupData[] = [
  3670.                                                     "id" => $apiGroupId,
  3671.                                                     "name" => $apiGroupNameEn,
  3672.                                                     "name_ar" => $apiGroupNameAr
  3673.                                                 ];
  3674.                                             }
  3675.                                         }
  3676.                                     }
  3677.                                 }
  3678.                             }
  3679.                         }
  3680.                     }
  3681.                     $userDataEn[] = [
  3682.                         'S. No' => $userKey 1,
  3683.                         'Username' => $usersData->getName(),
  3684.                         'Entity' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName() : null,
  3685.                         'Entity AR' => ($usersData->getOrganization()) ? $usersData->getOrganization()->getName('ar') : null,
  3686.                         'Email Address' => $usersData->getEmail(),
  3687.                         'Type' => $translator->trans('user', [], null'en'),
  3688.                         'Role' => $usersData->getRole() ? $translator->trans($usersData->getRole()->getName(), [], null'en') : null,
  3689.                         'Created By' => $usersData->getCreatedBy() ? $usersData->getCreatedBy()->getName() : null,
  3690.                         'Created On' => $usersData->getCreationDate() ? date('Y-m-d'$usersData->getCreationDate()) : null,
  3691.                         'Package' => isset($packageData[0]['name']) ? $packageData[0]['name'] : null,
  3692.                         'Package Expiry' => isset($packageData[0]['package_expiry']) ? date("M d, Y"strtotime($packageData[0]['package_expiry'])) : null,
  3693.                         'Status' => $translator->trans($status, [], null'en'),
  3694.                     ];
  3695.                 }
  3696.             }
  3697.             $excelData ExcelGenerator::createAndSaveXlsx($userDataEn$params['type'] . "_dual_mode_users_data"true'/users/excel/');
  3698.             return ["success" => true"message" => $translator->trans("excel_generated"), "data" =>  $excelData];
  3699.         } catch (\Exception $ex) {
  3700.             throw new \Exception($ex->getMessage());
  3701.         }
  3702.     }
  3703.     public function createWsoUser($name$email$translator): array
  3704.     {
  3705.         try {
  3706.             Utility::validateEmail($email);
  3707.             Utility::validateName($name);
  3708.             $user DataObject\Customer::getByEmail($emailtrue);
  3709.             if ($user instanceof \Pimcore\Model\DataObject\Customer) {
  3710.                 return ["success" => false"message" => $translator->trans("user_already_exists")];
  3711.             }
  3712.             $registerUser = new DataObject\Customer();
  3713.             $registerUser->setParent(DataObject\Service::createFolderByPath('/UserManagement/WsoUsers'));
  3714.             $registerUser->setKey(trim(strip_tags($email)));
  3715.             $registerUser->setUserType('public');
  3716.             $registerUser->setName(strip_tags($name));
  3717.             $registerUser->setEmail(trim(strip_tags($email)));
  3718.             $registerUser->setPublished(true);
  3719.             $registerUser->setIsActive(true);
  3720.             $registerUser->setSendEwsEmail(false);
  3721.             $registerUser->setOmitMandatoryCheck(true);
  3722.             $registerUser->save();
  3723.             return ["success" => true"message" => $translator->trans("user_registered_success"), 'data' => $registerUser->getId()];
  3724.         } catch (\Exception $ex) {
  3725.             throw new \Exception($ex->getMessage());
  3726.         }
  3727.         return [];
  3728.     }
  3729.     /**
  3730.      * Create User Tag
  3731.      */
  3732.     public function createUserTag($user$name$request$lang$translator$organization false)
  3733.     {
  3734.         $result = [];
  3735.         try {
  3736.             $userTag = new DataObject\UserTag();
  3737.             if ($organization) {
  3738.                 $userTag->setParent(DataObject\Service::createFolderByPath('/Organization/tags/'));
  3739.             } else {
  3740.                 $userTag->setParent(DataObject\Service::createFolderByPath('/UserManagement/user tags/'));
  3741.             }
  3742.             $userTag->setKey(\Pimcore\Model\Element\Service::getValidKey($name '_' uniqid(), 'object'));
  3743.             $userTag->setName(strip_tags($name));
  3744.             $userTag->setOrganization($organization);
  3745.             $userTag->setPublished(true);
  3746.             $userTag->save();
  3747.             if ($userTag) {
  3748.                 return ["success" => true"message" => $translator->trans("user_tag_created_successfully"), "user_tag_id" => $userTag->getId()];
  3749.             }
  3750.         } catch (\Exception $ex) {
  3751.             throw new \Exception($ex->getMessage());
  3752.         }
  3753.         return $result;
  3754.     }
  3755.     public function assignBulkUserTag($user$params$translator)
  3756.     {
  3757.         try {
  3758.             // Validate tag first
  3759.             $tag DataObject\UserTag::getById($params['tagId'], true);
  3760.             if (!$tag) {
  3761.                 return ["success" => false"message" => $translator->trans("tag_does_not_exists")];
  3762.             }
  3763.             // Validate and process all users
  3764.             $userIds $params['userIds'];
  3765.             $processedUsers = [];
  3766.             $failedUsers = [];
  3767.             foreach ($userIds as $userId) {
  3768.                 $userToUpdate DataObject\Customer::getById($userIdtrue);
  3769.                 if (!$userToUpdate) {
  3770.                     $failedUsers[] = $userId;
  3771.                     continue;
  3772.                 }
  3773.                 $userToUpdate->setTag($tag);
  3774.                 $userToUpdate->save();
  3775.                 $processedUsers[] = $userId;
  3776.             }
  3777.             if (!empty($failedUsers)) {
  3778.                 return [
  3779.                     "success" => false,
  3780.                     "message" => $translator->trans("Some_users_not_found"),
  3781.                     "failed_user_ids" => $failedUsers,
  3782.                     "processed_user_ids" => $processedUsers
  3783.                 ];
  3784.             }
  3785.             return [
  3786.                 "success" => true,
  3787.                 "message" => $translator->trans("user_tag_assigned_successfully"),
  3788.                 "processed_user_ids" => $processedUsers
  3789.             ];
  3790.         } catch (\Exception $ex) {
  3791.             return ["success" => false"message" => $ex->getMessage()];
  3792.         }
  3793.     }
  3794.     /**
  3795.      * User Tag Listing
  3796.      */
  3797.     public function userTagListing($user$translator$paginator$params)
  3798.     {
  3799.         $result = [];
  3800.         try {
  3801.             $tagData = [];
  3802.             $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  3803.             $page = isset($params['page']) ? $params['page'] : 1;
  3804.             $tagList = new DataObject\UserTag\Listing();
  3805.             // Check if organization parameter is set and not empty
  3806.             if (isset($params['organization']) && !empty($params['organization'])) {
  3807.                 $organization $params['organization'];
  3808.                 $tagList->setCondition("organization = true");
  3809.             } else {
  3810.                 $tagList->setCondition("(organization = false OR organization is null)");
  3811.             }
  3812.             if (isset($params['search']) && !empty($params['search'])) {
  3813.                 $tagList->setCondition("name LIKE " $tagList->quote("%" $params['search'] . "%"));
  3814.             }
  3815.             $allowed = [
  3816.                 'name'
  3817.             ];
  3818.             if ($params['sortBy'] && in_array($params['sortBy'], $allowedtrue)) {
  3819.                 $tagList->setOrderKey($params['sortBy']);
  3820.                 $tagList->setOrder($params['sortDir'] === 'DESC' 'DESC' 'ASC');
  3821.             }
  3822.             $paginator $paginator->paginate(
  3823.                 $tagList,
  3824.                 $page,
  3825.                 $pageSize
  3826.             );
  3827.             if ($paginator->getTotalItemCount() > 0) {
  3828.                 foreach ($paginator as $key => $tag) {
  3829.                     $tagData[] = [
  3830.                         'id' => $tag->getId(),
  3831.                         'name' => $tag->getName()
  3832.                     ];
  3833.                 }
  3834.                 if (!empty($tagData) && count($tagData) > 0) {
  3835.                     return ["success" => true"data" => $tagData"paginationVariables" => $paginator->getPaginationData()];
  3836.                 }
  3837.             }
  3838.             return ["success" => false"message" => $translator->trans("user_groups_are_not_available")];
  3839.         } catch (\Exception $ex) {
  3840.             throw new \Exception($ex->getMessage());
  3841.         }
  3842.         return $result;
  3843.     }
  3844.     /**
  3845.      * Validate the unsubscribe token
  3846.      *
  3847.      * @param string $token
  3848.      * @param Translator $translator
  3849.      * @return array
  3850.      */
  3851.     public function unsubscribeTokenValidate($token$translator)
  3852.     {
  3853.         // Fetch user by unsubscribe token
  3854.         $user Customer::getByUnSubToken($tokentrue);
  3855.         if (!$user) {
  3856.             return [
  3857.                 "success" => false,
  3858.                 "message" => $translator->trans("invalid_token")
  3859.             ];
  3860.         }
  3861.         // Prepare the data
  3862.         $data = [
  3863.             "success" => true,
  3864.             "id" => $user->getId(),
  3865.             "email" => $user->getEmail(),
  3866.             "customNotification" => $user->getCustomNotification(),
  3867.             "earlyWarningNotification" => $user->getEarlyWarningNotification(),
  3868.             "advanceCustomNotification" => $user->getAdvanceCustomNotification(),
  3869.             "severeWeatherAlert" => $user->getSevereWeatherAlert()
  3870.         ];
  3871.         return $data;
  3872.     }
  3873.     /**
  3874.      * update user Subscription
  3875.      *
  3876.      * @param string $params
  3877.      * @param Translator $translator
  3878.      * @return array
  3879.      */
  3880.     public function updateUserSubscription($params$translator)
  3881.     {
  3882.         // Fetch user by unsubscribe token
  3883.         $user Customer::getById($params['id'], true);
  3884.         if (!$user) {
  3885.             return [
  3886.                 "success" => false,
  3887.                 "message" => $translator->trans("invalid_user_id")
  3888.             ];
  3889.         }
  3890.         if (isset($params['customNotification'])) {
  3891.             $user->setCustomNotification($params['customNotification']);
  3892.         }
  3893.         if (isset($params['earlyWarningNotification'])) {
  3894.             $user->setEarlyWarningNotification($params['earlyWarningNotification']);
  3895.         }
  3896.         if (isset($params['advanceCustomNotification'])) {
  3897.             $user->setAdvanceCustomNotification($params['advanceCustomNotification']);
  3898.         }
  3899.         if (isset($params['severeWeatherAlert'])) {
  3900.             $user->setSevereWeatherAlert($params['severeWeatherAlert']);
  3901.         }
  3902.         $user->save();
  3903.         // Prepare the data
  3904.         $data = [
  3905.             "success" => true,
  3906.             "message" => $translator->trans("subscription_updated")
  3907.         ];
  3908.         return $data;
  3909.     }
  3910.     public function saveBulkUserInviteLog($user$data$organizationId)
  3911.     {
  3912.         $bulkUserInviteLog = new DataObject\BulkInviteUserReport();
  3913.         $bulkUserInviteLog->setParent(DataObject\Service::createFolderByPath('/UserManagement/BulkUserInviteLog'));
  3914.         $bulkUserInviteLog->setKey(\Pimcore\Model\Element\Service::getValidKey(uniqid(), 'object'));
  3915.         $bulkUserInviteLog->setPublished(true);
  3916.         $bulkUserInviteLog->setJsonData(json_encode($data));
  3917.         $organization DataObject\Organization::getById($organizationId);
  3918.         if ($organization) {
  3919.             $bulkUserInviteLog->setOrganization($organization);
  3920.         }
  3921.         $bulkUserInviteLog->setCreatedBy($user);
  3922.         $bulkUserInviteLog->save();
  3923.         return $bulkUserInviteLog;
  3924.     }
  3925.     public function getEntitySubscription($user)
  3926.     {
  3927.         $package null;
  3928.         $subscriptions = new Subscription\Listing();
  3929.         $subscriptions->filterBySubscribedUser($user);
  3930.         $subscriptions->filterBySubscriptionType("custom");
  3931.         $subscription $subscriptions->current();
  3932.         return $subscription;
  3933.     }
  3934.     public function getEntityPackage($user)
  3935.     {
  3936.         $package null;
  3937.         $subscriptions = new Subscription\Listing();
  3938.         $subscriptions->filterBySubscribedUser($user);
  3939.         $subscriptions->filterBySubscriptionType("custom");
  3940.         $subscription $subscriptions->current();
  3941.         if ($subscription) {
  3942.             $package $subscription->getSubscribedPackage();
  3943.         }
  3944.         return $package;
  3945.     }
  3946.     private function getInvitationDate($user): string
  3947.     {
  3948.         try {
  3949.             $token $user->getToken();
  3950.             if (empty($token)) {
  3951.                 $creationDate $user->getCreationDate();
  3952.                 if ($creationDate) {
  3953.                     return date('Y-m-d H:i:s'$creationDate);
  3954.                 }
  3955.                 return "Unknown";
  3956.             }
  3957.             $tokenParts explode('.'$token);
  3958.             if (count($tokenParts) !== 3) {
  3959.                 $creationDate $user->getCreationDate();
  3960.                 if ($creationDate) {
  3961.                     return date('Y-m-d H:i:s'$creationDate);
  3962.                 }
  3963.                 return "Invalid token";
  3964.             }
  3965.             $payload json_decode(base64_decode(str_replace(['-''_'], ['+''/'], $tokenParts[1])), true);
  3966.             if (!$payload || !isset($payload['time'])) {
  3967.                 $creationDate $user->getCreationDate();
  3968.                 if ($creationDate) {
  3969.                     return date('Y-m-d H:i:s'$creationDate);
  3970.                 }
  3971.                 return "No invitation time found";
  3972.             }
  3973.             $invitationTime $payload['time'];
  3974.             return date('Y-m-d H:i:s'$invitationTime);
  3975.         } catch (\Exception $e) {
  3976.             $creationDate $user->getCreationDate();
  3977.             if ($creationDate) {
  3978.                 return date('Y-m-d H:i:s'$creationDate);
  3979.             }
  3980.             return "Error getting date";
  3981.         }
  3982.     }
  3983.     public function listC2Users($params$translator)
  3984.     {
  3985.         try {
  3986.             $userData = [];
  3987.             // Get class IDs for table names
  3988.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  3989.             $customerClassId $class->getDao()->getIdByName('Customer');
  3990.             $subscriptionClassId $class->getDao()->getIdByName('Subscription');
  3991.             $packageClassId $class->getDao()->getIdByName('Package');
  3992.             $db Db::get();
  3993.             $select $db->createQueryBuilder();
  3994.             // Select customer data and subscription/package info
  3995.             $select->select([
  3996.                 'customer.oo_id AS customer_id',
  3997.                 'customer.name AS customer_name',
  3998.                 'customer.email AS customer_email',
  3999.                 'customer.phoneNo AS customer_phone',
  4000.                 'subscription.oo_id AS subscription_id',
  4001.                 'subscription.isActive AS subscription_is_active',
  4002.                 'subscription.endDate AS subscription_end_date',
  4003.                 'subscription.subscriptionType AS subscription_type'
  4004.             ]);
  4005.             $select->from('object_' $customerClassId'customer');
  4006.             // INNER JOIN with Subscription to get only customers with subscriptions
  4007.             // Then filter by active subscriptions
  4008.             $select->innerJoin(
  4009.                 'customer',
  4010.                 'object_' $subscriptionClassId,
  4011.                 'subscription',
  4012.                 'customer.oo_id = subscription.subscribedUser__id'
  4013.             );
  4014.             // Apply filters
  4015.             // Phone number must exist and be exactly 9 digits
  4016.             $select->where("customer.phoneNo IS NOT NULL AND customer.phoneNo != '' AND CHAR_LENGTH(customer.phoneNo) = 9");
  4017.             
  4018.             // Customer must be published
  4019.             $select->andWhere("customer.o_published = 1");
  4020.             
  4021.             // Only active subscriptions
  4022.             $select->andWhere("subscription.isActive = 1");
  4023.             
  4024.             // Only 'custom' subscription type (matching the commented code pattern)
  4025.             $select->andWhere("subscription.subscriptionType = " $db->quote('custom'));
  4026.             
  4027.             // Only subscriptions with end date in future (or no expiry)
  4028.             // Pimcore stores dates as Unix timestamps, so compare with current timestamp
  4029.             $currentTimestamp time();
  4030.             $select->andWhere("(subscription.endDate IS NULL OR subscription.endDate >= " $currentTimestamp ")");
  4031.             // Execute query
  4032.             $results $select->execute()->fetchAllAssociative();
  4033.             // Process results
  4034.             foreach ($results as $row) {
  4035.                 // Parse endDate - Pimcore stores dates as Unix timestamps
  4036.                 $packageExpiry null;
  4037.                 if (!empty($row['subscription_end_date'])) {
  4038.                     try {
  4039.                         // Check if it's a Unix timestamp (numeric) or date string
  4040.                         if (is_numeric($row['subscription_end_date'])) {
  4041.                             // Unix timestamp - use @ prefix to parse
  4042.                             $date = new \DateTime('@' $row['subscription_end_date']);
  4043.                             $date->setTimezone(new \DateTimeZone('Asia/Riyadh'));
  4044.                             $packageExpiry $date->format('M d, Y');
  4045.                         } else {
  4046.                             // Date string - parse directly
  4047.                             $date = new \DateTime($row['subscription_end_date']);
  4048.                             $packageExpiry $date->format('M d, Y');
  4049.                         }
  4050.                     } catch (\Exception $e) {
  4051.                         // If parsing fails, log and continue
  4052.                         error_log('Error parsing subscription end date: ' $e->getMessage() . ' - Value: ' $row['subscription_end_date']);
  4053.                         $packageExpiry null;
  4054.                     }
  4055.                 }
  4056.                 
  4057.                 $userData[] = [
  4058.                     'id' => (int) $row['customer_id'],
  4059.                     'name' => $row['customer_name'] ?? '',
  4060.                     'email' => $row['customer_email'] ?? '',
  4061.                     'phoneNumber' => '+966' $row['customer_phone'],
  4062.                     'package_expiry' => $packageExpiry,
  4063.                     'status' => $row['subscription_is_active'] ? 'Active' 'Suspended',
  4064.                 ];
  4065.             }
  4066.             return ["success" => true"data" => $userData];
  4067.         } catch (\Exception $e) {
  4068.             error_log('Error in listC2Users: ' $e->getMessage());
  4069.             return ["success" => false"error" => $e->getMessage(), "data" => []];
  4070.         }
  4071.     }
  4072.     /**
  4073.      * List user groups with simplified response (groupid, name, user_ids)
  4074.      * Only includes users with mobile numbers (like listC2Users logic)
  4075.      */
  4076.     public function listUserGroupsSimple($user$translator): array
  4077.     {
  4078.         try {
  4079.             $organization $user->getOrganization();
  4080.             if (!$organization instanceof DataObject\Organization) {
  4081.                 return ["success" => false"message" => $translator->trans("user_does_not_belongs_to_organization")];
  4082.             }
  4083.             // Get class IDs for table names
  4084.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  4085.             $customerClassId $class->getDao()->getIdByName('Customer');
  4086.             $subscriptionClassId $class->getDao()->getIdByName('Subscription');
  4087.             $db Db::get();
  4088.             // Load UserGroup listing
  4089.             $userGroupList = new DataObject\UserGroup\Listing();
  4090.             $userGroupList->filterByOrganization($organization);
  4091.             $userGroupList->setOrderKey("oo_id");
  4092.             $userGroupList->setOrder("desc");
  4093.             $userGroupListData = [];
  4094.             foreach ($userGroupList as $userGroup) {
  4095.                 $groupId $userGroup->getId();
  4096.                 
  4097.                 // Use direct SQL to find users in this group
  4098.                 // Pimcore stores userGroup as comma-separated string: ",398039,398040,"
  4099.                 $select $db->createQueryBuilder();
  4100.                 $select->select(['customer.oo_id AS customer_id''customer.phoneNo AS phone_no']);
  4101.                 $select->from('object_' $customerClassId'customer');
  4102.                 
  4103.                 // Filter by user group - format is ",groupId," to match exact group ID
  4104.                 $select->where("customer.userGroup LIKE :groupIdPattern");
  4105.                 $select->setParameter('groupIdPattern''%,' $groupId ',%');
  4106.                 
  4107.                 // Join with subscription to filter active subscriptions
  4108.                 $select->innerJoin(
  4109.                     'customer',
  4110.                     'object_' $subscriptionClassId,
  4111.                     'subscription',
  4112.                     'customer.oo_id = subscription.subscribedUser__id'
  4113.                 );
  4114.                 // Apply mobile number filter (same as listC2Users)
  4115.                 $select->andWhere("customer.phoneNo IS NOT NULL AND customer.phoneNo != '' AND CHAR_LENGTH(customer.phoneNo) = 9");
  4116.                 
  4117.                 // Customer must be published
  4118.                 $select->andWhere("customer.o_published = 1");
  4119.                 
  4120.                 // Only active subscriptions
  4121.                 $select->andWhere("subscription.isActive = 1");
  4122.                 
  4123.                 // Only 'custom' subscription type
  4124.                 $select->andWhere("subscription.subscriptionType = " $db->quote('custom'));
  4125.                 
  4126.                 // Only subscriptions with end date in future (or no expiry)
  4127.                 $currentTimestamp time();
  4128.                 $select->andWhere("(subscription.endDate IS NULL OR subscription.endDate >= " $currentTimestamp ")");
  4129.                 $results $select->execute()->fetchAllAssociative();
  4130.                 
  4131.                 // Convert user_ids to phone numbers
  4132.                 $userPhones = [];
  4133.                 foreach ($results as $row) {
  4134.                     $phoneNo $row['phone_no'];
  4135.                     if (!empty($phoneNo) && strlen($phoneNo) === 9) {
  4136.                         $userPhones[] = '+966' $phoneNo;
  4137.                     }
  4138.                 }
  4139.                 $userGroupListData[] = [
  4140.                     'groupid' => $userGroup->getId(),
  4141.                     'name' => $userGroup->getGroupName("en") ?: $userGroup->getGroupName("ar") ?: '',
  4142.                     'user_phones' => $userPhones
  4143.                 ];
  4144.             }
  4145.             
  4146.             // Also fetch UserSMSGroup objects
  4147.             $userSMSGroupList = new DataObject\UserSMSGroup\Listing();
  4148.             $userSMSGroupList->setOrderKey("oo_id");
  4149.             $userSMSGroupList->setOrder("desc");
  4150.             
  4151.             foreach ($userSMSGroupList as $userSMSGroup) {
  4152.                 // Extract phone numbers from groupData JSON
  4153.                 $groupData $userSMSGroup->getGroupData();
  4154.                 $userPhones = [];
  4155.                 
  4156.                 if (!empty($groupData)) {
  4157.                     try {
  4158.                         $userInfoArray json_decode($groupDatatrue);
  4159.                         if (is_array($userInfoArray)) {
  4160.                             foreach ($userInfoArray as $userInfo) {
  4161.                                 if (isset($userInfo['phoneNumber']) && !empty($userInfo['phoneNumber'])) {
  4162.                                     $phoneNumber $userInfo['phoneNumber'];
  4163.                                     // Ensure phone number is in +966XXXXXXXXX format
  4164.                                     if (!preg_match('/^\+966/'$phoneNumber)) {
  4165.                                         // Remove +966 or 966 prefix to get 9 digits
  4166.                                         $phoneDigits preg_replace('/^\+966/'''$phoneNumber);
  4167.                                         $phoneDigits preg_replace('/^966/'''$phoneDigits);
  4168.                                         $phoneDigits preg_replace('/[^0-9]/'''$phoneDigits);
  4169.                                         if (strlen($phoneDigits) === 9) {
  4170.                                             $phoneNumber '+966' $phoneDigits;
  4171.                                         }
  4172.                                     }
  4173.                                     $userPhones[] = $phoneNumber;
  4174.                                 }
  4175.                             }
  4176.                         }
  4177.                     } catch (\Exception $ex) {
  4178.                         // Skip invalid JSON
  4179.                         continue;
  4180.                     }
  4181.                 }
  4182.                 
  4183.                 // Merge with existing UserGroup if same name, otherwise add as new entry
  4184.                 $groupName $userSMSGroup->getGroupName("en") ?: $userSMSGroup->getGroupName("ar") ?: '';
  4185.                 $merged false;
  4186.                 
  4187.                 foreach ($userGroupListData as &$existingGroup) {
  4188.                     if ($existingGroup['name'] === $groupName) {
  4189.                         // Merge phone numbers (remove duplicates)
  4190.                         $existingGroup['user_phones'] = array_values(array_unique(array_merge($existingGroup['user_phones'], $userPhones)));
  4191.                         $merged true;
  4192.                         break;
  4193.                     }
  4194.                 }
  4195.                 
  4196.                 if (!$merged && !empty($userPhones)) {
  4197.                     // Add as new entry if not merged
  4198.                     $userGroupListData[] = [
  4199.                         'groupid' => $userSMSGroup->getId(),
  4200.                         'name' => $groupName,
  4201.                         'user_phones' => $userPhones
  4202.                     ];
  4203.                 }
  4204.             }
  4205.             if (!empty($userGroupListData)) {
  4206.                 return ["success" => true"data" => $userGroupListData];
  4207.             }
  4208.             return ["success" => false"message" => $translator->trans("user_groups_are_not_available")];
  4209.         } catch (\Exception $ex) {
  4210.             throw new \Exception($ex->getMessage());
  4211.         }
  4212.     }
  4213.     /**
  4214.      * Create or update user group with simplified parameters
  4215.      * Only assigns users that have mobile numbers (like listC2Users logic)
  4216.      */
  4217.     public function createUpdateUserGroupSimple($user$groupName$userIds$groupId null$translator): array
  4218.     {
  4219.         try {
  4220.             $organization $user->getOrganization();
  4221.             if (!$organization instanceof DataObject\Organization) {
  4222.                 return ["success" => false"message" => $translator->trans("user_does_not_belongs_to_organization")];
  4223.             }
  4224.             // Get class IDs for table names
  4225.             $class = new \Pimcore\Model\DataObject\ClassDefinition();
  4226.             $customerClassId $class->getDao()->getIdByName('Customer');
  4227.             $subscriptionClassId $class->getDao()->getIdByName('Subscription');
  4228.             $db Db::get();
  4229.             // Validate and filter user_ids - only include users with mobile numbers
  4230.             $validUserIds = [];
  4231.             if (!empty($userIds)) {
  4232.                 $select $db->createQueryBuilder();
  4233.                 $select->select(['customer.oo_id AS customer_id']);
  4234.                 $select->from('object_' $customerClassId'customer');
  4235.                 
  4236.                 // Join with subscription to filter active subscriptions
  4237.                 $select->innerJoin(
  4238.                     'customer',
  4239.                     'object_' $subscriptionClassId,
  4240.                     'subscription',
  4241.                     'customer.oo_id = subscription.subscribedUser__id'
  4242.                 );
  4243.                 // Filter by provided user IDs
  4244.                 $select->where("customer.oo_id IN (:userIds)");
  4245.                 $select->setParameter('userIds'$userIds\Doctrine\DBAL\Connection::PARAM_INT_ARRAY);
  4246.                 // Apply mobile number filter (same as listC2Users)
  4247.                 $select->andWhere("customer.phoneNo IS NOT NULL AND customer.phoneNo != '' AND CHAR_LENGTH(customer.phoneNo) = 9");
  4248.                 
  4249.                 // Customer must be published
  4250.                 $select->andWhere("customer.o_published = 1");
  4251.                 
  4252.                 // Only active subscriptions
  4253.                 $select->andWhere("subscription.isActive = 1");
  4254.                 
  4255.                 // Only 'custom' subscription type
  4256.                 $select->andWhere("subscription.subscriptionType = " $db->quote('custom'));
  4257.                 
  4258.                 // Only subscriptions with end date in future (or no expiry)
  4259.                 $currentTimestamp time();
  4260.                 $select->andWhere("(subscription.endDate IS NULL OR subscription.endDate >= " $currentTimestamp ")");
  4261.                 $results $select->execute()->fetchAllAssociative();
  4262.                 
  4263.                 foreach ($results as $row) {
  4264.                     $validUserIds[] = (int) $row['customer_id'];
  4265.                 }
  4266.             }
  4267.             if (empty($validUserIds)) {
  4268.                 return ["success" => false"message" => $translator->trans("no_valid_users_with_mobile_numbers_found")];
  4269.             }
  4270.             // Validate group name uniqueness when creating new group
  4271.             if (!$groupId) {
  4272.                 // Check if group name already exists in the same organization
  4273.                 $existingGroupList = new DataObject\UserGroup\Listing();
  4274.                 $existingGroupList->filterByOrganization($organization);
  4275.                 $existingGroupList->setLocale('en');
  4276.                 
  4277.                 foreach ($existingGroupList as $existingGroup) {
  4278.                     if ($existingGroup instanceof DataObject\UserGroup) {
  4279.                         $existingGroupNameEn $existingGroup->getGroupName('en');
  4280.                         $existingGroupNameAr $existingGroup->getGroupName('ar');
  4281.                         
  4282.                         // Check if group name matches (case-insensitive)
  4283.                         if (strcasecmp(trim($existingGroupNameEn), trim($groupName)) === || 
  4284.                             strcasecmp(trim($existingGroupNameAr), trim($groupName)) === 0) {
  4285.                             return ["success" => false"message" => $translator->trans("group_name_already_exists")];
  4286.                         }
  4287.                     }
  4288.                 }
  4289.             }
  4290.             // Create or update user group
  4291.             if ($groupId) {
  4292.                 // Update existing group
  4293.                 $userGroup DataObject\UserGroup::getById($groupIdtrue);
  4294.                 
  4295.                 
  4296.                 if (!$userGroup instanceof DataObject\UserGroup) {
  4297.                     return ["success" => false"message" => $translator->trans("user_group_is_not_available")];
  4298.                 }
  4299.                 // Verify organization
  4300.                 if (!$userGroup->getOrganization() || $userGroup->getOrganization()->getId() != $organization->getId()) {
  4301.                     return ["success" => false"message" => $translator->trans("user_group_is_not_assigned_to_your_organization")];
  4302.                 }
  4303.                 // Update group name
  4304.                 $userGroup->setGroupName($groupName"en");
  4305.                 $userGroup->setGroupName($groupName"ar");
  4306.             } else {
  4307.                 // Create new group
  4308.                 $userGroup = new DataObject\UserGroup();
  4309.                 $userGroup->setParent(DataObject\Service::createFolderByPath('/UserManagement/UserGroups/' $organization->getName()));
  4310.             $userGroup->setKey(trim(strip_tags($groupName.'-'.uniqid())));
  4311.             $userGroup->setGroupName($groupName'en');
  4312.             $userGroup->setGroupName($groupName'ar');
  4313.             $userGroup->setDetail($groupName'en');
  4314.             $userGroup->setDetail($groupName'ar');
  4315.             $userGroup->setOrganization($organization);
  4316.             $userGroup->setPublished(true);
  4317.                 // dump($userGroup);
  4318.                 // die;
  4319.                 // $userGroup->setGroupName($groupName, "en");
  4320.                 // $userGroup->setGroupName($groupName, "ar");
  4321.                 // $userGroup->setOrganization($organization);
  4322.                 $userGroup->setIsActive(true);
  4323.             }
  4324.             $userGroup->save();
  4325.             
  4326.             // Reload the group to ensure it has all necessary data
  4327.             $userGroup DataObject\UserGroup::getById($userGroup->getId(), true);
  4328.             // Assign users to group
  4329.             foreach ($validUserIds as $userId) {
  4330.                 $customer DataObject\Customer::getById($userIdtrue);
  4331.                 
  4332.                 if ($customer instanceof DataObject\Customer) {
  4333.                     // Get existing user groups for this customer
  4334.                     $existingGroups = [];
  4335.                     
  4336.                     // Collect existing groups and their IDs
  4337.                     $currentGroups $customer->getUserGroup();
  4338.                     if ($currentGroups) {
  4339.                         foreach ($currentGroups as $group) {
  4340.                             if ($group instanceof DataObject\UserGroup) {
  4341.                                 $groupId $group->getId();
  4342.                                 // Skip if this is the same group we're adding
  4343.                                 if ($groupId != $userGroup->getId()) {
  4344.                                     $existingGroups[] = $group;
  4345.                                 }
  4346.                             }
  4347.                         }
  4348.                     }
  4349.                     
  4350.                     // Add the new/updated group
  4351.                     $existingGroups[] = $userGroup;
  4352.                     
  4353.                     // Update customer's user groups
  4354.                     $customer->setUserGroup($existingGroups);
  4355.                     $customer->save();
  4356.                 }
  4357.             }
  4358.             // Remove users from group if they're not in the valid list
  4359.             // Get all users currently in this group
  4360.             $allUsersInGroup = new DataObject\Customer\Listing();
  4361.             $allUsersInGroup->filterByUserGroup($userGroup);
  4362.             
  4363.             foreach ($allUsersInGroup as $customer) {
  4364.                 if (!in_array($customer->getId(), $validUserIds)) {
  4365.                     // Get existing groups and remove this one
  4366.                     $existingGroups = [];
  4367.                     $currentGroups $customer->getUserGroup();
  4368.                     
  4369.                     if ($currentGroups) {
  4370.                         foreach ($currentGroups as $group) {
  4371.                             if ($group instanceof DataObject\UserGroup) {
  4372.                                 // Only keep groups that are NOT the one we're removing
  4373.                                 if ($group->getId() != $userGroup->getId()) {
  4374.                                     $existingGroups[] = $group;
  4375.                                 }
  4376.                             }
  4377.                         }
  4378.                     }
  4379.                     
  4380.                     $customer->setUserGroup($existingGroups);
  4381.                     $customer->save();
  4382.                 }
  4383.             }
  4384.             $action $groupId "updated" "created";
  4385.             return [
  4386.                 "success" => true
  4387.                 "message" => $translator->trans("user_group_{$action}_successfully"),
  4388.                 "data" => [
  4389.                     "groupid" => $userGroup->getId(),
  4390.                     "name" => $groupName,
  4391.                     "user_ids" => $validUserIds
  4392.                 ]
  4393.             ];
  4394.         } catch (\Exception $ex) {
  4395.             throw new \Exception($ex->getMessage());
  4396.         }
  4397.     }
  4398.     /**
  4399.      * Internal user dual mode
  4400.      * @param array $params
  4401.      * @param Translator $translator
  4402.      * @return array
  4403.      */
  4404.     public function internalUserDualMode($params$translator): array
  4405.     {
  4406.         try {
  4407.             $user DataObject\Customer::getById($params['id'], true);
  4408.             // check if user is internal user
  4409.             if (!$user) {
  4410.                 return ["success" => false"message" => $translator->trans("user_does_not_exists")];
  4411.             }
  4412.             // get internal organization
  4413.             $organization = new DataObject\Organization\Listing();
  4414.             $organization->filterByIsInternal(true);
  4415.             $entity $organization->current();
  4416.             if(!$entity) {
  4417.                 return ["success" => false"message" => $translator->trans("internal_organization_does_not_exists")];
  4418.             }
  4419.             $package $entity->getPackage();
  4420.             if (!$package) {
  4421.                 return ["success" => false"message" => $translator->trans("package_does_not_exists")];
  4422.             }
  4423.             if ($params['mode'] == true) {
  4424.                 $user->setDualMode(true);
  4425.                 $user->save();
  4426.                
  4427.                 // get existing subscription
  4428.                 $subscriptions = new DataObject\Subscription\Listing();
  4429.                 $subscriptions->filterBySubscribedUser($user);
  4430.                 $subscriptions->filterBySubscriptionType('custom');
  4431.                 $subscriptions->filterBySubscribedPackage($package);
  4432.                 $subscription $subscriptions->current();
  4433.                 if ($subscription) {
  4434.                     $subscription->setIsNoExpiry(true);
  4435.                     $subscription->setIsActive(true);
  4436.                     $subscription->setSubscriptionType('custom');
  4437.                     $subscription->setPublished(true);
  4438.                     $subscription->setSubscribedPackage($package);
  4439.                     $subscription->setSubscribedUser($user);
  4440.                     $subscription->save();
  4441.                 } else {
  4442.                     // create new subscription
  4443.                     $subscription = new DataObject\Subscription();
  4444.                     $subscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/' $user->getEmail()));
  4445.                     $subscription->setKey(\Pimcore\Model\Element\Service::getValidKey($package->getId() . time() . rand(100010000), 'object'));
  4446.                     $subscription->setSubscribedPackage($package);
  4447.                     $subscription->setSubscribedUser($user);
  4448.                     $subscription->setSubscriptionType('custom');
  4449.                     $subscription->setIsNoExpiry(true);
  4450.                     $subscription->setIsActive(true);
  4451.                     $subscription->setPublished(true);
  4452.                     $subscription->save();
  4453.                 }
  4454.               
  4455.             } else {
  4456.                 // disable dual mode
  4457.                 $user->setDualMode(false);
  4458.                 $user->save();
  4459.                 // get existing subscription
  4460.                 $subscriptions = new DataObject\Subscription\Listing();
  4461.                 $subscriptions->filterBySubscribedUser($user);
  4462.                 $subscriptions->filterBySubscribedPackage($package);
  4463.                 $subscriptions->filterBySubscriptionType('custom');
  4464.                 $subscription $subscriptions->current();
  4465.                 // delete subscription
  4466.                 if ($subscription) {
  4467.                     $subscription->delete();
  4468.                 }
  4469.             }
  4470.             return ["success" => true"message" => $translator->trans("internal_user_dual_mode_updated_successfully")];
  4471.         } catch (\Exception $ex) {
  4472.             throw new \Exception($ex->getMessage());
  4473.         }
  4474.     }
  4475. }