src/Model/PackageModel.php line 40

Open in your IDE?
  1. <?php
  2. namespace App\Model;
  3. use Symfony\Component\HttpFoundation\Request;
  4. use Pimcore\Model\DataObject;
  5. use App\Service\EmailService;
  6. use Pimcore\Bundle\AdminBundle\GDPR\DataProvider\SentMail;
  7. use App\Lib\Utility;
  8. use Pimcore\Db;
  9. use Pimcore\Model\DataObject\Package;
  10. use Pimcore\Model\DataObject\WeatherStations;
  11. use Pimcore\Model\DataObject\ThrottlingPolicy;
  12. use Pimcore\Model\DataObject\Subscription;
  13. use Carbon\Carbon;
  14. use App\C2IntegrationBundle\Service\C2Service;
  15. use Symfony\Component\Templating\EngineInterface;
  16. use Pimcore\Model\DataObject\Customer;
  17. use Pimcore\Model\DataObject\Organization;
  18. use Pimcore\Model\Asset;
  19. use Pimcore\Model\WebsiteSetting;
  20. class PackageModel
  21. {
  22.     private $templating;
  23.     private $c2Service;
  24.     private $db;
  25.     function __construct(EngineInterface $templating)
  26.     {
  27.         $this->c2Service = new C2Service();
  28.         $this->templating $templating;
  29.         $this->db \Pimcore\Db::get();
  30.     }
  31.     /**
  32.      * Create Package  function
  33.      */
  34.     public function createPackage($packageNameEn$packageNameAr$apiGroups$price$maxLocations$maxUsers$translator$packageType "public"$isAvailableOnWebsite true$isSMSEnabled$isSMSEnableForCustomNotification$isSMSEnableForMannedAlert$isSMSEnableForOTP$smsLimit$weatherStationIds)
  35.     {
  36.         $apiGroupsArray = [];
  37.         // Utility::isValidTenure($tenure);
  38.         foreach ($apiGroups as $key => $apiGroupId) {
  39.             $apiGroup DataObject\APIGroup::getById($apiGroupIdtrue);
  40.             if ($apiGroup instanceof DataObject\APIGroup) {
  41.                 $apiGroupsArray[] = $apiGroup;
  42.             }
  43.         }
  44.         if (count($apiGroupsArray) == 0) {
  45.             return ["success" => false"message" => $translator->trans("no_api_group_available")];
  46.         }
  47.         $package = new DataObject\Package();
  48.         if ($packageType == "private") {
  49.             $package->setParent(DataObject\Service::createFolderByPath('/UserManagement/Packages/NCM Users/CustomPackages'));
  50.             $package->setPackagetype('private');
  51.         } else {
  52.             $package->setParent(DataObject\Service::createFolderByPath('/UserManagement/Packages/CustomPackages'));
  53.             $package->setPackagetype('public');
  54.         }
  55.         $weatherStations = [];
  56.         if (!empty($weatherStationIds)) {
  57.             foreach ($weatherStationIds as $stationId) {
  58.                 $weatherStation DataObject\WeatherStations::getById($stationIdtrue);
  59.                 if ($weatherStation instanceof \Pimcore\Model\DataObject\WeatherStations) {
  60.                     $weatherStations[] = $weatherStation;
  61.                 }
  62.             }
  63.         }
  64.         $package->setWeatherStations($weatherStations);
  65.         $package->setKey(rand(11000) . '-' time());
  66.         $package->setPackageName(strip_tags($packageNameEn), 'en');
  67.         $package->setPackageName(strip_tags($packageNameAr), 'ar');
  68.         $quantityValue = new DataObject\Data\QuantityValue($price'SAR');
  69.         $package->setPrice($quantityValue);
  70.         $package->setApiGroups($apiGroupsArray);
  71.         // $package->setTenure(strip_tags($tenure));
  72.         $package->setMaxLocation(strip_tags($maxLocations));
  73.         $package->setMaxUsers(strip_tags($maxUsers));
  74.         $package->setIsActive(true);
  75.         $package->setIsApi(false);
  76.         $package->setIsAvailableOnWebsite($isAvailableOnWebsite ?? true);
  77.         $package->setIsSMSEnabled($isSMSEnabled);
  78.         $package->setIsSMSEnableForCustomNotification($isSMSEnableForCustomNotification);
  79.         $package->setIsSMSEnableForMannedAlert($isSMSEnableForMannedAlert);
  80.         $package->setIsSMSEnableForOTP($isSMSEnableForOTP);
  81.         $package->setSMSLimit($smsLimit);
  82.         $package->setPublished(true);
  83.         $package->Save();
  84.         if ($package) {
  85.             return ["success" => true"data" => $package->getId(), "message" => $translator->trans("package_created")];
  86.         }
  87.     }
  88.     /**
  89.      * Update Package  function
  90.      */
  91.     public function updatePackage($params$translator)
  92.     {
  93.         $updatePackage DataObject\Package::getById($params["id"], true);
  94.         if (!$updatePackage instanceof DataObject\Package) {
  95.             return ["success" => false"message" => $translator->trans("package_is_not_available")];
  96.         }
  97.         if (isset($params["api_groups"]) && !empty($params["api_groups"])) {
  98.             $apiGroupsArray = [];
  99.             foreach ($params["api_groups"] as $key => $apiGroupId) {
  100.                 $apiGroup DataObject\APIGroup::getById($apiGroupIdtrue);
  101.                 if ($apiGroup instanceof DataObject\APIGroup) {
  102.                     $apiGroupsArray[] = $apiGroup;
  103.                 }
  104.             }
  105.             if (count($apiGroupsArray) > 0) {
  106.                 $updatePackage->setApiGroups($apiGroupsArray);
  107.             }
  108.         }
  109.         if (isset($params["name"]) && !empty($params["name"])) {
  110.             $updatePackage->setPackageName(strip_tags($params["name"]), 'en');
  111.         }
  112.         if (isset($params["name_ar"]) && !empty($params["name_ar"])) {
  113.             $updatePackage->setPackageName(strip_tags($params["name_ar"]), 'ar');
  114.         }
  115.         if (isset($params["price"]) && !empty($params["price"])) {
  116.             $quantityValue = new DataObject\Data\QuantityValue($params["price"], 'SAR');
  117.             $updatePackage->setPrice($quantityValue);
  118.         }
  119.         if (isset($params["tenure"]) && !empty($params["tenure"])) {
  120.             Utility::isValidTenure($params['tenure']);
  121.             $updatePackage->setTenure(strip_tags($params["tenure"]));
  122.         }
  123.         if (isset($params["max_locations"]) && !empty($params["max_locations"])) {
  124.             $updatePackage->setMaxLocation(strip_tags($params["max_locations"]));
  125.         }
  126.         if (isset($params["max_users"]) && !empty($params["max_users"])) {
  127.             $updatePackage->setMaxUsers(strip_tags($params["max_users"]));
  128.         }
  129.         if (isset($params['isSMSEnabled'])) {
  130.             $updatePackage->setIsSMSEnabled($params["isSMSEnabled"]);
  131.         }
  132.         if (isset($params['isSMSEnableForCustomNotification'])) {
  133.             $updatePackage->setIsSMSEnableForCustomNotification($params["isSMSEnableForCustomNotification"]);
  134.         }
  135.         if (isset($params['isSMSEnableForMannedAlert'])) {
  136.             $updatePackage->setIsSMSEnableForMannedAlert($params["isSMSEnableForMannedAlert"]);
  137.         }
  138.         if (isset($params['isSMSEnableForOTP'])) {
  139.             $updatePackage->setIsSMSEnableForOTP($params["isSMSEnableForOTP"]);
  140.         }
  141.         if (!empty($params['SMSLimit'])) {
  142.             $updatePackage->setSMSLimit($params["SMSLimit"]);
  143.         }
  144.         if (!empty($params['weatherStationIds']) && is_array($params['weatherStationIds'])) {
  145.             $weatherStations = [];
  146.             foreach ($params['weatherStationIds'] as $stationId) {
  147.                 $weatherStation \Pimcore\Model\DataObject\WeatherStations::getById((int)$stationId);
  148.                 if ($weatherStation instanceof \Pimcore\Model\DataObject\WeatherStations) {
  149.                     $weatherStations[] = $weatherStation;
  150.                 }
  151.             }
  152.             $updatePackage->setWeatherStations($weatherStations);
  153.         }
  154.         $updatePackage->setIsApi(false);
  155.         $updatePackage->Save();
  156.         if ($updatePackage) {
  157.             return ["success" => true"data" => $updatePackage->getId(), "message" => $translator->trans("package_updated")];
  158.         }
  159.     }
  160.     /**
  161.      * Delete Package function
  162.      */
  163.     public function deletePackage($Id$loggedinUser$translator)
  164.     {
  165.         // Get package by ID
  166.         $package DataObject\Package::getById($Idtrue);
  167.         if (!$package instanceof DataObject\Package) {
  168.             return ["success" => false"message" => $translator->trans("package_is_not_available")];
  169.         }
  170.         // Check for active subscriptions
  171.         $subscriptions = new DataObject\Subscription\Listing();
  172.         $subscriptions->filterBySubscribedPackage($package);
  173.         $subscriptions->addConditionParam("subscribedUser__id IS NOT NULL");
  174.         $subscriptionsCount $subscriptions->count();
  175.         // Check for organizations assigned to the package
  176.         $organizations = new DataObject\Organization\Listing();
  177.         $organizations->addConditionParam("package__id = ?", [$package->getId()]);
  178.         $organizationsCount $organizations->count();
  179.         // Handle the different scenarios based on counts
  180.         if ($subscriptionsCount == && $organizationsCount == 0) {
  181.             $package->delete();
  182.             return ["success" => true"message" => $translator->trans("package_is_deleted")];
  183.         }
  184.         if ($subscriptionsCount && $organizationsCount == 0) {
  185.             return ["success" => false"message" => $translator->trans("package_is_subscribed_by_customer")];
  186.         }
  187.         if ($organizationsCount && $subscriptionsCount == 0) {
  188.             return ["success" => false"message" => $translator->trans("package_is_assigned_to_organization")];
  189.         }
  190.         return ["success" => false"message" => $translator->trans("package_is_subscribed_by_user_and_assigned_to_organization")];
  191.     }
  192.     /**
  193.      * List Package  function
  194.      */
  195.     public function listPackage($params$paginator$translator)
  196.     {
  197.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  198.         $page = isset($params['page']) ? $params['page'] : 1;
  199.         $lang = isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE;
  200.         // Get class IDs
  201.         $class = new \Pimcore\Model\DataObject\ClassDefinition();
  202.         $customerClassId $class->getDao()->getIdByName('Customer');
  203.         $subscriptionClassId $class->getDao()->getIdByName('Subscription');
  204.         $packageClassId $class->getDao()->getIdByName('Package');
  205.         $db Db::get();
  206.         // Create QueryBuilder for the main query
  207.         $qb $db->createQueryBuilder();
  208.         $qb->select([
  209.             'p.oo_id as id',
  210.             'p.packagetype as type',
  211.             'p.price__value as price',
  212.             'p.tenure',
  213.             'p.maxLocation as max_locations',
  214.             'p.maxUsers as max_users',
  215.             'p.isSMSEnabled',
  216.             'p.isSMSEnableForCustomNotification',
  217.             'p.isSMSEnableForMannedAlert',
  218.             'p.isSMSEnableForOTP',
  219.             'p.SMSLimit',
  220.             'p.isActive',
  221.             'p.o_published',
  222.             'p.isApi',
  223.             'p.isAvailableOnWebsite'
  224.         ])
  225.             ->from('object_' $packageClassId'p')
  226.             ->where('p.packagetype = :packagetype')
  227.             ->andWhere('p.isAvailableOnWebsite = :isAvailableOnWebsite')
  228.             ->andWhere('p.isActive = :isActive')
  229.             ->andWhere('(p.isApi = 0 OR p.isApi IS NULL)')
  230.             ->setParameter('packagetype''public')
  231.             ->setParameter('isAvailableOnWebsite'1)
  232.             ->setParameter('isActive'1);
  233.         // Join localized tables for packageName
  234.         $qb->leftJoin('p''object_localized_query_packages_en''p_en''p_en.ooo_id = p.oo_id')
  235.             ->leftJoin('p''object_localized_query_packages_ar''p_ar''p_ar.ooo_id = p.oo_id')
  236.             ->addSelect([
  237.                 'p_en.packageName as name',
  238.                 'p_ar.packageName as name_ar'
  239.             ]);
  240.         // Add assign_users calculation as a subquery
  241.         $assignUsersSubquery "(
  242.             SELECT COUNT(DISTINCT customer.oo_id) 
  243.             FROM object_{$customerClassId} customer
  244.             INNER JOIN object_{$subscriptionClassId} subscription ON customer.oo_id = subscription.subscribedUser__id
  245.             WHERE subscription.subscribedPackage__id = p.oo_id 
  246.             AND subscription.isActive = 1 
  247.             AND subscription.o_published = 1
  248.         )";
  249.         $qb->addSelect($assignUsersSubquery ' as assign_users');
  250.         // Handle single ID filter
  251.         if (isset($params['id']) && !empty($params['id'])) {
  252.             $qb->andWhere('p.oo_id = :id')
  253.                 ->setParameter('id'$params['id']);
  254.         }
  255.         // Handle search filter
  256.         if (isset($params['search']) && !empty($params['search'])) {
  257.             $qb->andWhere('(p_en.packageName LIKE :search OR p_ar.packageName LIKE :search)')
  258.                 ->setParameter('search''%' $params['search'] . '%');
  259.         }
  260.         // Handle API group filter
  261.         if (isset($params['api_group']) && !empty($params['api_group'])) {
  262.             $qb->andWhere('p.ApiGroups LIKE :api_group')
  263.                 ->setParameter('api_group''%,' $params['api_group'] . ',%');
  264.         }
  265.         // Handle sorting
  266.         $allowedOrderKeys = ['name''tenure''price''maxLocation''maxUser''smsLimit''assign_users'];
  267.         $allowedOrderDirections = ['asc''desc'];
  268.         if (
  269.             isset($params['orderKey']) && in_array($params['orderKey'], $allowedOrderKeys) &&
  270.             isset($params['order']) && in_array(strtolower($params['order']), $allowedOrderDirections)
  271.         ) {
  272.             $orderKey $params['orderKey'];
  273.             $orderDirection strtolower($params['order']);
  274.             // Map the orderKey to the actual database field names
  275.             $fieldMapping = [
  276.                 'name' => $lang === 'ar' 'p_ar.packageName' 'p_en.packageName',
  277.                 'tenure' => 'p.tenure',
  278.                 'price' => 'p.price__value',
  279.                 'maxLocation' => 'p.maxLocation',
  280.                 'maxUser' => 'p.maxUsers',
  281.                 'smsLimit' => 'p.SMSLimit',
  282.                 'assign_users' => 'assign_users'
  283.             ];
  284.             if (isset($fieldMapping[$orderKey])) {
  285.                 $dbField $fieldMapping[$orderKey];
  286.                 $qb->orderBy($dbFieldstrtoupper($orderDirection));
  287.             }
  288.         } else {
  289.             // Default sorting
  290.             $qb->orderBy('p.oo_id''DESC');
  291.         }
  292.         // Use the paginator
  293.         $paginatorResult $paginator->paginate(
  294.             $qb,
  295.             $page,
  296.             $pageSize
  297.         );
  298.         $totalPackages $paginatorResult->count();
  299.         if ($totalPackages 0) {
  300.             $packageDataArray = [];
  301.             foreach ($paginatorResult as $package) {
  302.                 // Get API Groups for this package
  303.                 $apiGroupDataArray = [];
  304.                 $packageObj DataObject\Package::getById($package['id']);
  305.                 if ($packageObj) {
  306.                     $apiGroups $packageObj->getApiGroups();
  307.                     if ($apiGroups) {
  308.                         foreach ($apiGroups as $apiGroup) {
  309.                             if ($apiGroup instanceof DataObject\APIGroup) {
  310.                                 $apiGroupDataArray[] = [
  311.                                     "id" => $apiGroup->getId(),
  312.                                     "type" => $apiGroup->getApiGroupType(),
  313.                                     "name" => $apiGroup->getApiGroupName('en'),
  314.                                     "name_ar" => $apiGroup->getApiGroupName('ar')
  315.                                 ];
  316.                             }
  317.                         }
  318.                     }
  319.                     // Get Weather Stations for this package
  320.                     $weatherStationArray = [];
  321.                     $weatherStations $packageObj->getWeatherStations();
  322.                     if ($weatherStations) {
  323.                         foreach ($weatherStations as $weatherStation) {
  324.                             $weatherStationArray[] = [
  325.                                 "id" => $weatherStation->getId(),
  326.                                 "name" => $weatherStation->getName("en"),
  327.                                 "name_ar" => $weatherStation->getName("ar"),
  328.                             ];
  329.                         }
  330.                     }
  331.                 }
  332.                 // Build package data array
  333.                 $packageDataArray[] = [
  334.                     "id" => $package['id'],
  335.                     "assign_users" => (int)$package['assign_users'],
  336.                     "type" => $package['type'],
  337.                     "name" => $package['name'],
  338.                     "name_ar" => $package['name_ar'],
  339.                     "price" => $package['price'],
  340.                     "tenure" => $package['tenure'],
  341.                     "max_locations" => $package['max_locations'],
  342.                     "max_users" => $package['max_users'],
  343.                     "api_groups" => $apiGroupDataArray,
  344.                     "isSMSEnabled" => (bool)$package['isSMSEnabled'],
  345.                     "isSMSEnableForCustomNotification" => (bool)$package['isSMSEnableForCustomNotification'],
  346.                     "isSMSEnableForMannedAlert" => (bool)$package['isSMSEnableForMannedAlert'],
  347.                     "isSMSEnableForOTP" => (bool)$package['isSMSEnableForOTP'],
  348.                     "SMSLimit" => $package['SMSLimit'],
  349.                     "weatherStations" => $weatherStationArray,
  350.                 ];
  351.             }
  352.             return ["success" => true"data" => $packageDataArray"paginationVariables" => $paginatorResult->getPaginationData()];
  353.         }
  354.         return ["success" => false"message" => $translator->trans("packages_are_not_available")];
  355.     }
  356.     /**
  357.      * List Package  function
  358.      */
  359.     public function listPackagesWithFilters($params$paginator$translator)
  360.     {
  361.         $class = new \Pimcore\Model\DataObject\ClassDefinition();
  362.         $customer $class->getDao()->getIdByName('Customer');
  363.         $subscription $class->getDao()->getIdByName('Subscription');
  364.         $organization $class->getDao()->getIdByName('Organization');
  365.         $package $class->getDao()->getIdByName('Package');
  366.         $db Db::get();
  367.         $select $db->createQueryBuilder();
  368.         $select->select('package.oo_id');
  369.         $select->from('object_' $package'package');
  370.         $select->leftJoin('package''object_' $subscription'subscription''package.oo_id = subscription.subscribedPackage__id');
  371.         $select->leftJoin('subscription''object_' $customer'customer''customer.oo_id = subscription.subscribedUser__id');
  372.         $select->leftJoin('customer''object_' $organization'organization''organization.oo_id = customer.organization__id');
  373.         $select->where("package.packagetype = " $db->quote("public"));
  374.         if (isset($params['clientType']) && !empty($params['clientType'])) {
  375.             $select->andWhere("organization.cilent_type = " $db->quote($params['clientType']));
  376.         }
  377.         if (isset($params['organization_id']) && !empty($params['organization_id'])) {
  378.             $select->andWhere("organization.oo_id = " $db->quote($params['organization_id']));
  379.         }
  380.         if (isset($params['search']) && !empty($params['search'])) {
  381.             // Join the localized fields table for the language
  382.             $select->leftJoin('package''object_localized_query_' $package '_' $params['lang'], 'localized''localized.ooo_id = package.oo_id');
  383.             $select->andWhere("localized.packageName LIKE " $db->quote("%" $params['search'] . "%"));
  384.         }
  385.         $select->andWhere("package.isAvailableOnWebsite = 1");
  386.         $select->andWhere("package.isActive = 1");
  387.         $select->andWhere("package.isApi = 0 OR package.isApi IS NULL");
  388.         $select->andWhere("package.o_published = 1");
  389.         $allowed = [
  390.             'name',
  391.             'name_ar'
  392.         ];
  393.         if (isset($params['sortBy']) && in_array($params['sortBy'], $allowedtrue)) {
  394.             // decide language based on requested field
  395.             $sortAlias 'localized_sort';
  396.             // ensure localized table is joined for sorting (avoids missing column error)
  397.             $select->leftJoin('package''object_localized_query_' $package '_' $params['lang'], $sortAlias$sortAlias '.ooo_id = package.oo_id');
  398.             $direction = (isset($params['sortDir']) && strtoupper($params['sortDir']) === 'DESC') ? 'DESC' 'ASC';
  399.             $select->orderBy($sortAlias '.packageName'$direction);
  400.         } else {
  401.             $select->orderBy('package.oo_id''DESC');
  402.         }
  403.         // always group by package id to avoid duplicates from joins
  404.         $select->groupBy(['package.oo_id']);
  405.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  406.         $page = isset($params['page']) ? $params['page'] : 1;
  407.         $paginator $paginator->paginate(
  408.             $select,
  409.             $page,
  410.             $pageSize
  411.         );
  412.         $totalPackages $paginator->count();
  413.         if ($totalPackages 0) {
  414.             foreach ($paginator as $key => $packageId) {
  415.                 $package Package::getById($packageId['oo_id'], true);
  416.                 if ($package) {
  417.                     $apiGroupDataArray = [];
  418.                     // load all assigned APIGroups Data
  419.                     $apiGroups $package->getApiGroups();
  420.                     if ($apiGroups) {
  421.                         foreach ($apiGroups as $key => $apiGroup) {
  422.                             if ($apiGroup instanceof DataObject\APIGroup) {
  423.                                 $apiGroupDataArray[] = [
  424.                                     "id" => $apiGroup->getId(),
  425.                                     "type" => $apiGroup->getApiGroupType(),
  426.                                     "name" => $apiGroup->getApiGroupName('en'),
  427.                                     "name_ar" => $apiGroup->getApiGroupName('ar')
  428.                                 ];
  429.                             }
  430.                         }
  431.                     }
  432.                     // Now, to get the price if it's set:
  433.                     $price null;
  434.                     if ($package->getPrice()) {
  435.                         $price .= $package->getPrice()->getValue(); // Accessing the value of the QuantityValue object
  436.                     }
  437.                     // Get All Packes data
  438.                     $packageDataArray[] = [
  439.                         "id" => $package->getId(),
  440.                         "type" => $package->getPackagetype(),
  441.                         "name" => $package->getPackageName('en'),
  442.                         "name_ar" => $package->getPackageName('ar'),
  443.                         "price" => $price,
  444.                         "tenure" => $package->getTenure(),
  445.                         "max_locations" => $package->getMaxLocation(),
  446.                         "max_users" => $package->getMaxUsers(),
  447.                         "api_groups" => $apiGroupDataArray
  448.                     ];
  449.                     $apiGroupDataArray = [];
  450.                 }
  451.             }
  452.             return ["success" => true"data" => $packageDataArray"paginationVariables" => $paginator->getPaginationData()];
  453.         }
  454.         return ["success" => false"message" => $translator->trans("packages_are_not_available")];
  455.     }
  456.     /**
  457.      * List APIGroup function
  458.      */
  459.     public function listApiGroup($params$translator)
  460.     {
  461.         $apiGroupDataArray = [];
  462.         $apiGroups = new DataObject\APIGroup\Listing();
  463.         $apiGroups->filterByApiGroupType("public");
  464.         $apiGroups->filterByIsActive(true);
  465.         $apiGroups->setLocale($translator->getLocale());
  466.         if (isset($params['search']) && !empty(trim($params['search']))) {
  467.             $apiGroups->addConditionParam("apiGroupName LIKE " $apiGroups->quote("%" trim($params['search']) . "%"));
  468.         }
  469.         $allowed = [
  470.             'name',
  471.             'name_ar'
  472.         ];
  473.         if ($params['sortBy'] && in_array($params['sortBy'], $allowedtrue)) {
  474.             $apiGroups->setOrderKey("apiGroupName"$params['sortBy'] == "name_ar" 'ar' 'en');
  475.             $apiGroups->setOrder($params['sortDir'] === 'DESC' 'DESC' 'ASC');
  476.         }
  477.         $totalApiGroups $apiGroups->count();
  478.         if ($totalApiGroups 0) {
  479.             $apiGroupDataArray[] = [
  480.                 "totalApiGroups" => $totalApiGroups
  481.             ];
  482.             foreach ($apiGroups as $key => $apiGroup) {
  483.                 // load all assigned APIGroups Data
  484.                 if ($apiGroup instanceof DataObject\APIGroup) {
  485.                     $apiGroupDataArray[] = [
  486.                         "id" => $apiGroup->getId(),
  487.                         "type" => $apiGroup->getApiGroupType(),
  488.                         "name" => $apiGroup->getApiGroupName('en'),
  489.                         "name_ar" => $apiGroup->getApiGroupName('ar')
  490.                     ];
  491.                 }
  492.             }
  493.             return ["success" => true"data" => $apiGroupDataArray];
  494.         }
  495.         return ["success" => false"message" => $translator->trans("api_groups_are_not_available")];
  496.     }
  497.     /**
  498.      * List Private APIGroup function
  499.      */
  500.     public function listPrivateApiGroup($params$user$translator)
  501.     {
  502.         $apiGroupDataArray = [];
  503.         $apiGroups = new DataObject\APIGroup\Listing();
  504.         $apiGroups->filterByApiGroupType("private");
  505.         $apiGroups->filterByIsActive(true);
  506.         $apiGroups->setOrderKey("order");
  507.         $apiGroups->setOrder('ASC');
  508.         $apiGroups->setLocale($translator->getLocale());
  509.         if ($apiGroups) {
  510.             foreach ($apiGroups as $apiGroup) {
  511.                 if ($apiGroup instanceof DataObject\APIGroup) {
  512.                     $apiGroupDataArray[] = [
  513.                         "id" => $apiGroup->getId(),
  514.                         "type" => $apiGroup->getApiGroupType(),
  515.                         "group_name" => $apiGroup->getGroupName(),
  516.                         "name" => $apiGroup->getApiGroupName('en'),
  517.                         "name_ar" => $apiGroup->getApiGroupName('ar')
  518.                     ];
  519.                 }
  520.             }
  521.         }
  522.         return ["success" => true"data" => $apiGroupDataArray];
  523.     }
  524.     /**
  525.      * View APIGroup function
  526.      */
  527.     public function viewApiGroup($Id$loggedinUser$translator)
  528.     {
  529.         $apiGroupDataArray = [];
  530.         $apiGroups = new DataObject\APIGroup\Listing();
  531.         $apiGroups->filterById($Id);
  532.         $apiGroups->filterByApiGroupType("public");
  533.         $apiGroups->filterByIsActive(true);
  534.         $apiGroup =  $apiGroups->current();
  535.         // load all assigned APIGroups Data
  536.         if ($apiGroup instanceof DataObject\APIGroup) {
  537.             $apiGroupDataArray[] = [
  538.                 "id" => $apiGroup->getId(),
  539.                 "type" => $apiGroup->getApiGroupType(),
  540.                 "name" => $apiGroup->getApiGroupName('en'),
  541.                 "name_ar" => $apiGroup->getApiGroupName('ar'),
  542.                 "permission" => $apiGroup->getAllowedApis()
  543.             ];
  544.             return ["success" => true"data" => $apiGroupDataArray];
  545.         }
  546.         return ["success" => false"message" => $translator->trans("api_group_is_not_available")];
  547.     }
  548.     /**
  549.      * Suspend Package function
  550.      */
  551.     public function suspendPackage($userIdOrIds$loggedinUser$translator)
  552.     {
  553.         $ids is_array($userIdOrIds) ? $userIdOrIds : [$userIdOrIds];
  554.         $results = [];
  555.         foreach ($ids as $userId) {
  556.             $customer DataObject\Customer::getById($userIdtrue);
  557.             if (!$customer) {
  558.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("user_is_not_available")];
  559.                 continue;
  560.             }
  561.             //validate Role first
  562.             $loggedInUserRole $loggedinUser->getRole() ? $loggedinUser->getRole()->getName() : USER_ROLES['CLIENT_USER'];
  563.             $customerRole =  $customer->getRole() ? $customer->getRole()->getName() : USER_ROLES['CLIENT_USER'];
  564.             if ($loggedInUserRole == USER_ROLES['CLIENT_USER'] && ($customerRole == USER_ROLES['NCM_OPERATOR'] || $customerRole == USER_ROLES['NCM_IT'] || $customerRole == USER_ROLES['CLIENT_ADMIN'])) {
  565.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  566.                 continue;
  567.             } elseif ($loggedInUserRole == USER_ROLES['CLIENT_ADMIN'] && ($customerRole == USER_ROLES['NCM_IT'] || $customerRole == USER_ROLES['NCM_OPERATOR'])) {
  568.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  569.                 continue;
  570.             } elseif ($loggedInUserRole == USER_ROLES['NCM_OPERATOR'] && ($customerRole == USER_ROLES['NCM_IT'])) {
  571.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  572.                 continue;
  573.             }
  574.             $subscriptions = new DataObject\Subscription\Listing();
  575.             $subscriptions->filterBySubscribedUser($customer);
  576.             $subscriptions->filterByIsActive(true);
  577.             if ($subscriptions->count() > 0) {
  578.                 foreach ($subscriptions as $subscription) {
  579.                     if ($subscription) {
  580.                         $subscription->setIsActive(false);
  581.                         $subscription->save();
  582.                     }
  583.                 }
  584.                 $results[] = ["id" => $userId"success" => true"message" => $translator->trans("package_suspended_successfully")];
  585.             } else {
  586.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("active_subscription_is_not_available")];
  587.             }
  588.         }
  589.         // Preserve backward compatibility: if input was scalar, return single-object style
  590.         if (!is_array($userIdOrIds)) {
  591.             $single $results[0] ?? ["success" => false"message" => $translator->trans("unknown_error")];
  592.             return ["success" => $single["success"], "message" => $single["message"]];
  593.         }
  594.         $successCount 0;
  595.         foreach ($results as $r) {
  596.             if (!empty($r['success'])) {
  597.                 $successCount++;
  598.             }
  599.         }
  600.         return ["success" => true"message" => sprintf("%s: %d"$translator->trans("package_suspended_successfully"), $successCount)];
  601.     }
  602.     /**
  603.      * Resume Package function
  604.      */
  605.     public function resumePackage($userIdOrIds$loggedinUser$translator)
  606.     {
  607.         $ids is_array($userIdOrIds) ? $userIdOrIds : [$userIdOrIds];
  608.         $results = [];
  609.         foreach ($ids as $userId) {
  610.             $customer DataObject\Customer::getById($userIdtrue);
  611.             if (!$customer) {
  612.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("user_is_not_available")];
  613.                 continue;
  614.             }
  615.             //validate Role first
  616.             $loggedInUserRole $loggedinUser->getRole() ? $loggedinUser->getRole()->getName() : USER_ROLES['CLIENT_USER'];
  617.             $customerRole =  $customer->getRole() ? $customer->getRole()->getName() : USER_ROLES['CLIENT_USER'];
  618.             if ($loggedInUserRole == USER_ROLES['CLIENT_USER'] && ($customerRole == USER_ROLES['NCM_OPERATOR'] || $customerRole == USER_ROLES['NCM_IT'] || $customerRole == USER_ROLES['CLIENT_ADMIN'])) {
  619.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  620.                 continue;
  621.             } elseif ($loggedInUserRole == USER_ROLES['CLIENT_ADMIN'] && ($customerRole == USER_ROLES['NCM_IT'] || $customerRole == USER_ROLES['NCM_OPERATOR'])) {
  622.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  623.                 continue;
  624.             } elseif ($loggedInUserRole == USER_ROLES['NCM_OPERATOR'] && ($customerRole == USER_ROLES['NCM_IT'])) {
  625.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  626.                 continue;
  627.             }
  628.             $subscriptions = new DataObject\Subscription\Listing();
  629.             $subscriptions->filterBySubscribedUser($customer);
  630.             $subscriptions->filterByIsActive(false);
  631.             if ($subscriptions->count() > 0) {
  632.                 foreach ($subscriptions as $subscription) {
  633.                     if ($subscription) {
  634.                         $subscription->setIsActive(true);
  635.                         $subscription->save();
  636.                     }
  637.                 }
  638.                 $results[] = ["id" => $userId"success" => true"message" => $translator->trans("package_resumed_successfully")];
  639.             } else {
  640.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("suspended_subscription_is_not_available")];
  641.             }
  642.         }
  643.         if (!is_array($userIdOrIds)) {
  644.             $single $results[0] ?? ["success" => false"message" => $translator->trans("unknown_error")];
  645.             return ["success" => $single["success"], "message" => $single["message"]];
  646.         }
  647.         $successCount 0;
  648.         foreach ($results as $r) {
  649.             if (!empty($r['success'])) {
  650.                 $successCount++;
  651.             }
  652.         }
  653.         return ["success" => true"message" => sprintf("%s: %d"$translator->trans("package_resumed_successfully"), $successCount)];
  654.     }
  655.     /**
  656.      * Renew Package function for all users in organization
  657.      * $organization : organization object
  658.      */
  659.     public function renewPackage($organization$days$loggedinUser$translator)
  660.     {
  661.         $successCount 0;
  662.         $failCount 0;
  663.         $results = [];
  664.         $customers = new DataObject\Customer\Listing();
  665.         $customers->filterByOrganization($organization);
  666.         foreach ($customers as $customer) {
  667.             $userId $customer->getId();
  668.             //validate Role first
  669.             $loggedInUserRole $loggedinUser->getRole() ? $loggedinUser->getRole()->getName() : USER_ROLES['CLIENT_USER'];
  670.             $customerRole =  $customer->getRole() ? $customer->getRole()->getName() : USER_ROLES['CLIENT_USER'];
  671.             if ($loggedInUserRole == USER_ROLES['CLIENT_USER'] && ($customerRole == USER_ROLES['NCM_OPERATOR'] || $customerRole == USER_ROLES['NCM_IT'] || $customerRole == USER_ROLES['CLIENT_ADMIN'])) {
  672.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  673.                 continue;
  674.             } elseif ($loggedInUserRole == USER_ROLES['CLIENT_ADMIN'] && ($customerRole == USER_ROLES['NCM_IT'] || $customerRole == USER_ROLES['NCM_OPERATOR'])) {
  675.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  676.                 continue;
  677.             } elseif ($loggedInUserRole == USER_ROLES['NCM_OPERATOR'] && ($customerRole == USER_ROLES['NCM_IT'])) {
  678.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("permission_denied_to_role")];
  679.                 continue;
  680.             }
  681.             $subscriptions = new DataObject\Subscription\Listing();
  682.             $subscriptions->filterBySubscribedUser($customer);
  683.             // $subscriptions->filterByIsActive(true);
  684.             if ($subscriptions->count() > 0) {
  685.                 $subscriptionExpiry date('Y-m-d'strtotime('+' $days ' days'));
  686.                 foreach ($subscriptions as $subscription) {
  687.                     $subscription->setEndDate(\Carbon\Carbon::parse(new \Datetime($subscriptionExpiry)));
  688.                     $subscription->save();
  689.                 }
  690.                 $results[] = ["id" => $userId"success" => true"message" => $translator->trans("package_renewed_successfully")];
  691.                 $successCount++;
  692.             } else {
  693.                 $results[] = ["id" => $userId"success" => false"message" => $translator->trans("subscription_is_not_available")];
  694.                 $failCount++;
  695.             }
  696.         }
  697.         $organization->setPackageActivationDate(\Carbon\Carbon::parse(new \Datetime(date('Y-m-d'))));
  698.         $organization->setTrialLimit($days);
  699.         $organization->save();
  700.         return ["success" => true"message" => sprintf("%s: %d"$translator->trans("package_renewed_successfully"), $successCount)];
  701.     }
  702.     /**
  703.      * Create Wso Package function
  704.      */
  705.     public function createWsoPackage($packageNameEn$price$tenure$throttling$packageType "public"$translator)
  706.     {
  707.         $package DataObject\Package::getByName($packageNameEn'en');
  708.         if ($package->getCount() > 0) {
  709.             return ["success" => false"message" => $translator->trans("package_with_this_name_exists")];
  710.         }
  711.         Utility::isValidTenure($tenure);
  712.         $throttling DataObject\WSO2Policies::getById($throttlingtrue);
  713.         if (!$throttling) {
  714.             return ["success" => false"message" => $translator->trans("throttling_is_not_available")];
  715.         }
  716.         $package = new DataObject\Package();
  717.         $package->setParent(DataObject\Service::createFolderByPath('/UserManagement/Packages/WSOPackages'));
  718.         $package->setPackagetype($packageType);
  719.         $package->setKey(rand(11000) . '-' time());
  720.         $package->setPackageCode(uniqid());
  721.         $package->setName(strip_tags($packageNameEn), 'en');
  722.         $package->setPackageName(strip_tags($packageNameEn), 'en');
  723.         // $package->setPackageName(strip_tags($packageNameAr), 'ar');
  724.         $quantityValue = new DataObject\Data\QuantityValue($price'SAR');
  725.         $package->setPrice($quantityValue);
  726.         $package->setTenure(strip_tags($tenure));
  727.         $package->setThrottlingPolicy($throttling->getId());
  728.         $package->setMaxLocation(0);
  729.         $package->setMaxUsers(0);
  730.         $package->setIsActive(true);
  731.         $package->setIsApi(true);
  732.         $package->setIsAvailableOnWebsite($isAvailableOnWebsite ?? false);
  733.         $package->setPublished(true);
  734.         $package->Save();
  735.         if ($package) {
  736.             return ["success" => true"data" => $package->getId(), "message" => $translator->trans("package_created")];
  737.         }
  738.     }
  739.     /**
  740.      * Update Wso Package function
  741.      */
  742.     public function updateWsoPackage($params$translator)
  743.     {
  744.         $updatePackage DataObject\Package::getById($params["id"], true);
  745.         if (!$updatePackage instanceof DataObject\Package) {
  746.             return ["success" => false"message" => $translator->trans("package_is_not_available")];
  747.         }
  748.         $updatePackage->setIsApi(true);
  749.         if (isset($params["name"]) && !empty($params["name"])) {
  750.             $updatePackage->setName(strip_tags($params["name"]), 'en');
  751.         }
  752.         if (isset($params["name"]) && !empty($params["name"])) {
  753.             $updatePackage->setPackageName(strip_tags($params["name"]), 'en');
  754.         }
  755.         if (isset($params["name_ar"]) && !empty($params["name_ar"])) {
  756.             $updatePackage->setPackageName(strip_tags($params["name_ar"]), 'ar');
  757.         }
  758.         if (isset($params["price"]) && ($params["price"] != null || $params["price"] != '')) {
  759.             $quantityValue = new DataObject\Data\QuantityValue($params["price"], 'SAR');
  760.             $updatePackage->setPrice($quantityValue);
  761.         }
  762.         if (isset($params["tenure"]) && !empty($params["tenure"])) {
  763.             Utility::isValidTenure($params['tenure']);
  764.             $updatePackage->setTenure(strip_tags($params["tenure"]));
  765.         }
  766.         if (isset($params["throttling"]) && !empty($params["throttling"])) {
  767.             $updatePackage->setThrottlingPolicy($params["throttling"]);
  768.         }
  769.         $updatePackage->Save();
  770.         if ($updatePackage) {
  771.             return ["success" => true"data" => $updatePackage->getId(), "message" => $translator->trans("package_updated")];
  772.         }
  773.     }
  774.     /**
  775.      * Inactive Wso Package function
  776.      */
  777.     public function inactiveWsoPackage($Id$status$translator)
  778.     {
  779.         $package DataObject\Package::getById($Idtrue);
  780.         if (!$package instanceof DataObject\Package) {
  781.             return ["success" => false"message" => $translator->trans("package_is_not_available")];
  782.         }
  783.         $package->setIsActive($status);
  784.         $package->save();
  785.         return ["success" => true"message" => $translator->trans("package_status_updated")];
  786.     }
  787.     /**
  788.      * Delete Wso Package function
  789.      */
  790.     public function deleteWsoPackage($Id$translator)
  791.     {
  792.         $package DataObject\Package::getById($Idtrue);
  793.         if (!$package instanceof DataObject\Package) {
  794.             return ["success" => false"message" => $translator->trans("package_is_not_available")];
  795.         }
  796.         $subscriptions = new DataObject\Subscription\Listing();
  797.         $subscriptions->addConditionParam('subscribedUser__id IS NOT NULL');
  798.         $subscriptions->filterBySubscribedPackage($package);
  799.         $subscriptions->filterByIsActive(true);
  800.         if ($subscriptions->count() == 0) {
  801.             $package->delete();
  802.             return ["success" => true"message" => $translator->trans("package_is_deleted")];
  803.         } else {
  804.             return ["success" => false"message" => $translator->trans("package_is_subscribed_by_customer")];
  805.         }
  806.     }
  807.     /**
  808.      * List  Wso Package function
  809.      */
  810.     public function listWsoPackage($params$paginator$translator)
  811.     {
  812.         $throttlingArr = [];
  813.         $policies = new DataObject\WSO2Policies\Listing();
  814.         foreach ($policies as $policie) {
  815.             $throttlingArr[$policie->getId()] = $policie->getPolicyName();
  816.         }
  817.         $packageDataArray = [];
  818.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  819.         $page = isset($params['page']) ? $params['page'] : 1;
  820.         $lang = isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE;
  821.         $packages = new DataObject\Package\Listing();
  822.         $packages->filterByIsApi(true);
  823.         if (isset($params['search']) && !empty($params['search'])) {
  824.             $packages->addConditionParam("packageName LIKE " $packages->quote("%" $params['search'] . "%"));
  825.         }
  826.         $packages->filterByPackagetype("public");
  827.         $packages->addConditionParam("ThrottlingPolicy IS Not NULL");
  828.         // Dynamic sorting with orderKey and order
  829.         $orderKey $params['orderKey'] ?? null;
  830.         $order $params['order'] ?? 'desc';
  831.         // Validate order parameter
  832.         if (!in_array(strtolower($order), ['asc''desc'])) {
  833.             $order 'desc';
  834.         }
  835.         // Map orderKey to database fields
  836.         $sortingMap = [
  837.             'name' => 'packageName',
  838.             'price' => 'price__value',
  839.             'tenure' => 'tenure',
  840.             'throttling' => 'ThrottlingPolicy',
  841.             'status' => 'isActive'
  842.         ];
  843.         if ($orderKey && isset($sortingMap[$orderKey])) {
  844.             $field $sortingMap[$orderKey];
  845.             $packages->setOrderKey($field);
  846.             $packages->setOrder(strtoupper($order));
  847.         } else {
  848.             // Default sorting
  849.             $packages->setOrderKey("oo_id");
  850.             $packages->setOrder('desc');
  851.         }
  852.         $paginator $paginator->paginate(
  853.             $packages,
  854.             $page,
  855.             $pageSize
  856.         );
  857.         $totalPackages $paginator->count();
  858.         foreach ($paginator as $key => $package) {
  859.             $price null;
  860.             if ($package->getPrice()) {
  861.                 $price .= $package->getPrice()->getValue(); // Accessing the value of the QuantityValue object
  862.             }
  863.             $throttlingPolicy intval($package->getThrottlingPolicy());
  864.             // Get All Packes data
  865.             $packageDataArray[] = [
  866.                 "id" => $package->getId(),
  867.                 "type" => $package->getPackagetype(),
  868.                 "name" => $package->getPackageName('en'),
  869.                 "name_ar" => $package->getPackageName('ar'),
  870.                 "price" => $price,
  871.                 "tenure" => $package->getTenure(),
  872.                 "throttling" => $throttling =  $translator->trans($throttlingArr[$throttlingPolicy], [], null"en"),
  873.                 "throttling_ar" => $throttling $translator->trans($throttlingArr[$throttlingPolicy], [], null"ar")
  874.             ];
  875.         }
  876.         if ($totalPackages 0) {
  877.             return ["success" => true"data" => $packageDataArray"paginationVariables" => $paginator->getPaginationData()];
  878.         }
  879.         return ["success" => false"message" => $translator->trans("packages_are_not_available")];
  880.     }
  881.     /**
  882.      * List Throttling  function
  883.      */
  884.     public function listThrottlingPolicies($params$paginator$translator)
  885.     {
  886.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  887.         $page = isset($params['page']) ? $params['page'] : 1;
  888.         $lang = isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE;
  889.         $policesDataArray = [];
  890.         // $apiGroupDataArray = [];
  891.         $policies = new DataObject\WSO2Policies\Listing();
  892.         $policies->setOrderKey('policyName');
  893.         $policies->setOrder('asc');
  894.         $paginator $paginator->paginate(
  895.             $policies,
  896.             $page,
  897.             $pageSize
  898.         );
  899.         if ($paginator->count() > 0) {
  900.             $policesDataArray = [];
  901.             foreach ($paginator as $policie) {
  902.                 $policesDataArray[] = [
  903.                     "id" => $policie->getId(),
  904.                     "police_name" => $policie->getPolicyName(),
  905.                     "police_display_name" => $translator->trans($policie->getDisplayName(), [], null"en"),
  906.                     "police_display_name_ar" => $translator->trans($policie->getDisplayName(), [], null"ar"),
  907.                     "description" => $policie->getDescription()
  908.                 ];
  909.             }
  910.             if (!empty($policesDataArray)) {
  911.                 return ["success" => true"data" => $policesDataArray'paginationVariables' => $paginator->getPaginationData()];
  912.             }
  913.         }
  914.         return ["success" => false"message" => $translator->trans("throttling_policies_are_not_available")];
  915.     }
  916.     public function createWsoSubscription($params$loggedInUser$translator)
  917.     {
  918.         $result = [];
  919.         $subscriptionType "default";
  920.         $disallowedApiGroupsArray null;
  921.         $package DataObject\Package::getById($params['package_id']);
  922.         if (!$package instanceof DataObject\Package) {
  923.             return ["success" => false"message" => "Package is not available"];
  924.         }
  925.         $user Customer::getByEmail($params['email'], true);
  926.         if (!$user) {
  927.             // register wso user 
  928.             Utility::validateEmail($params['email']);
  929.             Utility::validateName($params['name']);
  930.             $user = new DataObject\Customer();
  931.             $user->setParent(DataObject\Service::createFolderByPath('/UserManagement/WsoUsers'));
  932.             $user->setKey(trim(strip_tags($params['email'])));
  933.             $user->setUserType('public');
  934.             $user->setName(strip_tags($params['name']));
  935.             $user->setEmail(trim(strip_tags($params['email'])));
  936.             $user->setIsActive(true);
  937.             $user->setSendEwsEmail(false);
  938.             $user->setPublished(true);
  939.             $user->setCreatedBy($loggedInUser);
  940.             $user->setOmitMandatoryCheck(true);
  941.             $user->save();
  942.             $user->save();
  943.         } else {
  944.             $user->setName(strip_tags($params['name']));
  945.             $user->setCreatedBy($loggedInUser);
  946.             $user->setOmitMandatoryCheck(true);
  947.             $user->save();
  948.             $user->save();
  949.         }
  950.         $returnMessage '';
  951.         if (isset($params['subscription_id'])) {
  952.             $subscription DataObject\Subscription::getById($params['subscription_id']);
  953.             if (!$subscription instanceof DataObject\Subscription) {
  954.                 return ["success" => false"message" => $translator->trans("invalid_subscription_id")];
  955.             }
  956.             $returnMessage $translator->trans("wso_subscription_updated");
  957.         } else {
  958.             $subscription = new DataObject\Subscription();
  959.             $subscription->setParent(DataObject\Service::createFolderByPath('/WSO2/Subscription/' $user->getEmail()));
  960.             $subscription->setKey(\Pimcore\Model\Element\Service::getValidKey($package->getId() . time() . rand(100010000), 'object'));
  961.             $subscription->setPublished(true);
  962.             $returnMessage $translator->trans("wso_subscription_created");
  963.         }
  964.         $subscriptionExpiry date('Y-m-d'strtotime('+' $package->getTenure() . ' days'));
  965.         $subscription->setSubscribedPackage($package);
  966.         $subscription->setSubscribedUser($user);
  967.         $subscription->setIsWso(true);
  968.         //Set Disallowed ApiGroups
  969.         if ($disallowedApiGroupsArray != null) {
  970.             $disallowedApiGroups = [];
  971.             foreach ($disallowedApiGroupsArray as $disallowedApiGroupsId) {
  972.                 $apiGroup =  DataObject\APIGroup::getById($disallowedApiGroupsIdtrue);
  973.                 $disallowedApiGroups[] = $apiGroup;
  974.             }
  975.             $subscription->setDisallowedApiGroups($disallowedApiGroups);
  976.         }
  977.         //$subscription->setDisallowedApis($disAllowPermissions);
  978.         $subscription->setSubscriptionType($subscriptionType);
  979.         $subscription->setStartDate(Carbon::parse(new \Datetime(date('Y-m-d'))));
  980.         $subscription->setEndDate(Carbon::parse(new \Datetime($subscriptionExpiry)));
  981.         $subscription->setIsActive(true);
  982.         $subscription->save();
  983.         $subscription->save();
  984.         // do not send email if subscription id is set
  985.         if (!isset($params['subscription_id'])) {
  986.             // send an email to the subscriber with the ClientID and Secret Key via C2.
  987.             $user->save();
  988.             $this->sendEmailSubscriber($subscription$params['email']);
  989.         }
  990.         if ($subscription) {
  991.             return ["success" => true"data" => $subscription->getId(), "message" => $returnMessage];
  992.         }
  993.     }
  994.     public function reinviteWsoSubscription($params$translator)
  995.     {
  996.         $result = [];
  997.         $customer Customer::getById($params['user_id']);
  998.         if (!$customer) {
  999.             return ["success" => false"message" => $translator->trans("invalid_user_id")];
  1000.         }
  1001.         $subscriptions = new DataObject\Subscription\Listing();
  1002.         $subscriptions->filterBySubscribedUser($customer);
  1003.         $subscriptions->filterByIsActive(true);
  1004.         $subscription $subscriptions->current();
  1005.         $subscription->save();
  1006.         if ($subscription instanceof DataObject\Subscription) {
  1007.             $result $this->sendEmailSubscriber($subscription$customer->getEmail());
  1008.             if ($result) {
  1009.                 return ["success" => true"message" => $translator->trans("reinvite_email_sent")];
  1010.             }
  1011.         } else {
  1012.             return ["success" => false"message" => $translator->trans('subscription_is_not_available')];
  1013.         }
  1014.     }
  1015.     public function sendEmailSubscriber($subscription$email)
  1016.     {
  1017.         // dd($subscription->getConsumerKey(),$subscription->getId());
  1018.         $purpose WSO_SUBSCRIPTION_MESSAGE;
  1019.         $templateId $_ENV['WSO_SUBSCRIPTION_TEMPLATE'];
  1020.         $subject 'Wso Subscription Email';
  1021.         $param = [
  1022.             'name' => $subscription->getSubscribedUser()?->getName(),
  1023.             'consumerKey' => $subscription->getConsumerKey(),
  1024.             'consumerSecret' => $subscription->getConsumerSecret(),
  1025.             'apiEndpointUrl' => $_ENV['WSO_API_ENDPOINT'],
  1026.             'postmanCollectionUrl' => $_ENV['WSO_POSTMAN_COLLECTION'],
  1027.             'apiToken' => base64_encode($subscription->getSubscribedUser()?->getUserId() . ':' $subscription->getSubscribedUser()?->getSecretKey()),
  1028.             'tenure' => $subscription->getSubscribedPackage()?->getTenure(),
  1029.             'packageName' => $subscription->getSubscribedPackage()?->getPackageName('en'),
  1030.             'subscriptionStartDate' => $subscription->getStartDate(),
  1031.             'subscriptionEndDate' => $subscription->getEndDate(),
  1032.         ];
  1033.         // Retrieve the PDF asset from website settings
  1034.         $pdfAssetId WebsiteSetting::getByName('wso_pdf_document')->getData();
  1035.         $pdfAsset Asset::getById($pdfAssetId->getId());
  1036.         // Check if the asset exists and is a PDF
  1037.         if ($pdfAsset && $pdfAsset instanceof Asset\Document) {
  1038.             $pdfFile $pdfAsset;
  1039.         } else {
  1040.             // Handle the case where the asset is not found or not a PDF
  1041.             $pdfFile null;
  1042.         }
  1043.         $html $this->templating->render('web2print/wso_subscription_email.html.twig'$param);
  1044.         $this->c2Service->sendCustomReportEmail($templateId$subscription->getId(), $email$html$subject, [$pdfFile], $purpose);
  1045.         return true;
  1046.     }
  1047.     public function listWsoSubscription($params$paginator$translator)
  1048.     {
  1049.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  1050.         $page = isset($params['page']) ? $params['page'] : 1;
  1051.         $lang = isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE;
  1052.         $subscriptionDataArray = [];
  1053.         // Use raw SQL query with JOINs
  1054.         $qb $this->db->createQueryBuilder();
  1055.         $qb->select([
  1056.             's.oo_id as id',
  1057.             's.subscribedUser__id as user_id',
  1058.             'u.name as user_name',
  1059.             'u.email as user_email',
  1060.             's.subscribedPackage__id as package_id',
  1061.             'p.packageName as package_name',
  1062.             'p_ar.packageName as package_name_ar',
  1063.             'creator.name as createdBy',
  1064.             'u.o_creationDate as createdOn',
  1065.             's.startDate as subscription_start_date',
  1066.             's.endDate as subscription_end_date',
  1067.             's.isActive as subscription_status',
  1068.             's.subscriptionType as subscription_type'
  1069.         ])
  1070.             ->from('object_subscription''s')
  1071.             ->leftJoin('s''object_customer''u''s.subscribedUser__id = u.oo_id')
  1072.             ->leftJoin('u''object_customer''creator''u.createdBy__id = creator.oo_id')
  1073.             ->leftJoin('s''object_localized_query_packages_en''p''s.subscribedPackage__id = p.ooo_id')
  1074.             ->leftJoin('s''object_localized_query_packages_ar''p_ar''s.subscribedPackage__id = p_ar.ooo_id')
  1075.             ->where('s.subscribedPackage__id IS NOT NULL AND s.subscribedUser__id IS NOT NULL')
  1076.             ->andWhere('s.isWso = 1');
  1077.         // Add package filter
  1078.         if (isset($params['package_id']) && !empty($params['package_id'])) {
  1079.             $package DataObject\Package::getById($params['package_id']);
  1080.             if ($package) {
  1081.                 $qb->andWhere('s.subscribedPackage__id = :package_id')
  1082.                     ->setParameter('package_id'$package->getId());
  1083.             }
  1084.         }
  1085.         // Add search filter
  1086.         if (isset($params['search']) && !empty($params['search'])) {
  1087.             $searchTerm "%" $params['search'] . "%";
  1088.             $qb->andWhere('u.name LIKE :search OR u.email LIKE :search')
  1089.                 ->setParameter('search'$searchTerm);
  1090.         }
  1091.         // Apply sorting
  1092.         $orderKey $params['orderKey'] ?? null;
  1093.         $order $params['order'] ?? 'desc';
  1094.         // Validate order parameter
  1095.         if (!in_array(strtolower($order), ['asc''desc'])) {
  1096.             $order 'desc';
  1097.         }
  1098.         // Map orderKey to database fields
  1099.         $sortingMap = [
  1100.             'username' => 'u.name',
  1101.             'email' => 'u.email',
  1102.             'createdBy' => 'creator.name',
  1103.             'createdOn' => 'u.o_creationDate',
  1104.             'packageName' => 'p.packageName',
  1105.             'status' => 's.isActive',
  1106.             'startDate' => 's.startDate',
  1107.             'endDate' => 's.endDate'
  1108.         ];
  1109.         if ($orderKey && isset($sortingMap[$orderKey])) {
  1110.             $qb->orderBy($sortingMap[$orderKey], strtoupper($order));
  1111.         } else {
  1112.             // Default sorting
  1113.             $qb->orderBy('s.o_creationDate''DESC');
  1114.         }
  1115.         // Legacy sorting support (for backward compatibility)
  1116.         if (isset($params['start_date']) && in_array($params['start_date'], ['asc''desc'])) {
  1117.             $qb->orderBy('s.startDate'strtoupper($params['start_date']));
  1118.         }
  1119.         if (isset($params['end_date']) && in_array($params['end_date'], ['asc''desc'])) {
  1120.             $qb->orderBy('s.endDate'strtoupper($params['end_date']));
  1121.         }
  1122.         // Execute query and paginate
  1123.         $paginator $paginator->paginate($qb$page$pageSize);
  1124.         if ($paginator->count() > 0) {
  1125.             foreach ($paginator as $row) {
  1126.                 $subscriptionDataArray[] = [
  1127.                     "id" => $row['id'],
  1128.                     'user_id' => $row['user_id'],
  1129.                     'user_name' => $row['user_name'],
  1130.                     'user_email' => $row['user_email'],
  1131.                     "package_id" => $row['package_id'],
  1132.                     "package_name" => $row['package_name'],
  1133.                     "package_name_ar" => $row['package_name_ar'] ?: (function () use ($row) {
  1134.                         // Fallback: get Arabic name using Pimcore ORM
  1135.                         if ($row['package_id']) {
  1136.                             $package DataObject\Package::getById($row['package_id']);
  1137.                             return $package $package->getPackageName('ar') : null;
  1138.                         }
  1139.                         return null;
  1140.                     })(),
  1141.                     'createdBy' => $row['createdBy'],
  1142.                     'createdOn' => $row['createdOn'] ? date('Y-m-d h:i:s'$row['createdOn']) : null,
  1143.                     "subscription_start_date" => $row['subscription_start_date'] ? (new \DateTime('@' $row['subscription_start_date']))->setTimezone(new \DateTimeZone('Asia/Riyadh')) : null,
  1144.                     "subscription_end_date" => $row['subscription_end_date'] ? (new \DateTime('@' $row['subscription_end_date']))->setTimezone(new \DateTimeZone('Asia/Riyadh')) : null,
  1145.                     "subscription_status" => (bool)$row['subscription_status'],
  1146.                     "subscription_type" => $row['subscription_type'],
  1147.                     "status" => [
  1148.                         "key" => !$row['subscription_status'] ? $translator->trans("suspended") : (($row['subscription_end_date'] && time() <= $row['subscription_end_date']) ? $translator->trans("active") : $translator->trans("expired")),
  1149.                         "name_en" => !$row['subscription_status'] ? $translator->trans("suspended") : (($row['subscription_end_date'] && time() <= $row['subscription_end_date']) ? $translator->trans("active") : $translator->trans("expired")),
  1150.                         "name_ar" => !$row['subscription_status'] ? $translator->trans("suspended") : (($row['subscription_end_date'] && time() <= $row['subscription_end_date']) ? $translator->trans("active") : $translator->trans("expired"))
  1151.                     ]
  1152.                 ];
  1153.             }
  1154.             if (!empty($subscriptionDataArray)) {
  1155.                 return ["success" => true"data" => $subscriptionDataArray'paginationVariables' => $paginator->getPaginationData()];
  1156.             }
  1157.         }
  1158.         return ["success" => true"data" => [], 'paginationVariables' => $paginator->getPaginationData()];
  1159.     }
  1160.     /**
  1161.      * Delete Wso Subscription function
  1162.      */
  1163.     public function deleteWsoSubscription($params$user$translator)
  1164.     {
  1165.         $successDeletes = [];
  1166.         $failedDeletes = [];
  1167.         // Loop through each user ID to process deletion
  1168.         foreach ($params['user_id'] as $userId) {
  1169.             $customer DataObject\Customer::getById($userIdtrue);
  1170.             if ($customer instanceof DataObject\Customer) {
  1171.                 // Handle subscriptions
  1172.                 $subscriptions = new DataObject\Subscription\Listing();
  1173.                 $subscriptions->filterBySubscribedUser($customer);
  1174.                 $subscriptions->filterByIsWso(true);
  1175.                 foreach ($subscriptions as $subscription) {
  1176.                     $subscription->delete();
  1177.                     \App\Lib\Utility::storeActivityLog($subscription$user'temp user subscription delete'$translator);
  1178.                 }
  1179.                 // Handle customer deletion if they don't have a role or organization
  1180.                 if ($customer->getRole() === null && $customer->getOrganization() === null) {
  1181.                     $customer->delete();
  1182.                     \App\Lib\Utility::storeActivityLog($customer$user'temp user delete'$translator);
  1183.                 }
  1184.                 $successDeletes[] = $userId;  // Add user ID to success array
  1185.             } else {
  1186.                 $failedDeletes[] = $userId;  // Add user ID to failed array if customer not found
  1187.             }
  1188.         }
  1189.         // Return the result
  1190.         if (!empty($failedDeletes)) {
  1191.             return [
  1192.                 "success" => false,
  1193.                 "message" => $translator->trans('some_users_failed_to_delete'),
  1194.                 'failed_users' => $failedDeletes,
  1195.                 'successful_deletions' => $successDeletes
  1196.             ];
  1197.         }
  1198.         // Success message if all deletions were successful
  1199.         return [
  1200.             "success" => true,
  1201.             "message" => $translator->trans('subscriptions_and_temp_users_deleted_successfully'),
  1202.             'deleted_users' => $successDeletes
  1203.         ];
  1204.     }
  1205.     public function updateEntityPackage($package$organizations$translator)
  1206.     {
  1207.         $totalUpdatedSubscriptions 0;
  1208.         $organizationsResult = [];
  1209.         foreach ($organizations as $organization) {
  1210.             if (!$organization instanceof DataObject\Organization) {
  1211.                 continue;
  1212.             }
  1213.             $activationDate $organization->getPackageActivationDate() ?: Carbon::now();
  1214.             $trialLimit = (int)$organization->getTrialLimit();
  1215.             if ($trialLimit <= 0) {
  1216.                 // fallback to package tenure (days) if trial limit not set
  1217.                 $trialLimit = (int)$package->getTenure();
  1218.             }
  1219.             $orgUpdated 0;
  1220.             $customers = new DataObject\Customer\Listing();
  1221.             $customers->setUnpublished(true);
  1222.             $customers->filterByOrganization($organization);
  1223.             foreach ($customers as $customer) {
  1224.                 $roleName $customer->getRole()?->getName();
  1225.                 if (!in_array($roleName, [USER_ROLES['CLIENT_ADMIN'], USER_ROLES['CLIENT_USER']], true)) {
  1226.                     continue;
  1227.                 }
  1228.                 $subscriptions = new DataObject\Subscription\Listing();
  1229.                 $subscriptions->filterBySubscribedUser($customer);
  1230.                 $subscriptions->filterBySubscriptionType("custom");
  1231.                 $subscriptionExpiry Carbon::parse($activationDate)->copy()->addDays($trialLimit)->format('Y-m-d');
  1232.                 if ($subscriptions->count() > 0) {
  1233.                     foreach ($subscriptions as $subscription) {
  1234.                         $subscription->setEndDate(Carbon::parse(new \DateTime($subscriptionExpiry)));
  1235.                         $subscription->setSubscribedPackage($package);
  1236.                         $subscription->setDisallowedApiGroups(null);
  1237.                         $subscription->save();
  1238.                         $orgUpdated++;
  1239.                         $totalUpdatedSubscriptions++;
  1240.                     }
  1241.                 } else {
  1242.                     $subscription = new DataObject\Subscription();
  1243.                     $subscription->setParent(DataObject\Service::createFolderByPath('/UserManagement/Subscriptions/' $customer->getEmail()));
  1244.                     $subscription->setKey(\Pimcore\Model\Element\Service::getValidKey($package->getId() . time() . rand(100010000), 'object'));
  1245.                     $subscription->setSubscribedPackage($package);
  1246.                     $subscription->setSubscribedUser($customer);
  1247.                     $subscription->setSubscriptionType("custom");
  1248.                     $subscription->setStartDate(Carbon::parse($activationDate));
  1249.                     $subscription->setEndDate(Carbon::parse(new \DateTime($subscriptionExpiry)));
  1250.                     $subscription->setIsActive(true);
  1251.                     $subscription->setPublished(true);
  1252.                     $subscription->setDisallowedApiGroups(null);
  1253.                     $subscription->save();
  1254.                     $orgUpdated++;
  1255.                     $totalUpdatedSubscriptions++;
  1256.                 }
  1257.             }
  1258.             // Sync organization with package
  1259.             $organization->setIsSMSEnabled((bool)$package->getIsSMSEnabled());
  1260.             $organization->setPackage($package);
  1261.             $organization->setIsActive(true);
  1262.             $organization->save();
  1263.             $organizationsResult[] = [
  1264.                 'organization_id' => $organization->getId(),
  1265.                 'updated_subscriptions' => $orgUpdated
  1266.             ];
  1267.         }
  1268.         return [
  1269.             "success" => true,
  1270.             "message" => $translator->trans("total_customer_subscription_updated") . ": " $totalUpdatedSubscriptions,
  1271.             "organizations" => $organizationsResult
  1272.         ];
  1273.     }
  1274.     /**
  1275.      * List SMS  function
  1276.      */
  1277.     public function listSmsCofiguration($params$paginator$translator)
  1278.     {
  1279.         $pageSize = isset($params['page_size']) ? $params['page_size'] : LIMIT_PER_PAGE;
  1280.         $page = isset($params['page']) ? $params['page'] : 1;
  1281.         $lang = isset($params["lang"]) ? $params["lang"] : DEFAULT_LOCALE;
  1282.         $smsConfigArray = [];
  1283.         $smsConfig = new DataObject\SmsConfiguration\Listing();
  1284.         $smsConfig->setOrderKey('order');
  1285.         $smsConfig->setOrder('asc');
  1286.         $paginator $paginator->paginate(
  1287.             $smsConfig,
  1288.             $page,
  1289.             $pageSize
  1290.         );
  1291.         if ($paginator->count() > 0) {
  1292.             $smsConfigArray = [];
  1293.             foreach ($paginator as $limit) {
  1294.                 $smsConfigArray[] = [
  1295.                     "id" => $limit->getId(),
  1296.                     "limit" => $limit->getLimit(),
  1297.                 ];
  1298.             }
  1299.             if (!empty($smsConfigArray)) {
  1300.                 return ["success" => true"data" => $smsConfigArray'paginationVariables' => $paginator->getPaginationData()];
  1301.             }
  1302.         }
  1303.         return ["success" => false"message" => $translator->trans("throttling_policies_are_not_available")];
  1304.     }
  1305. }