bundles/PfcGenerateSkuBundle/EventListener/WorkflowListener.php line 45

Open in your IDE?
  1. <?php
  2. namespace PfcGenerateSkuBundle\EventListener;
  3. use Carbon\Carbon;
  4. use Cocur\Slugify\Slugify;
  5. use mysql_xdevapi\Exception;
  6. use Pimcore\Event\Model\DataObjectEvent;
  7. use Pimcore\Event\Model\ElementEventInterface;
  8. use Pimcore\Model\DataObject;
  9. use Pimcore\Model\DataObject\Folder;
  10. use Pimcore\Model\Element\ValidationException;
  11. use Pimcore\Model\Notification\Service\UserService;
  12. use Pimcore\Tool\Admin;
  13. use Symfony\Component\Workflow\Event\GuardEvent;
  14. use Symfony\Component\Workflow\Registry;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\Workflow\Event\Event;
  17. use Pimcore\Model\Notification\Service\NotificationService;
  18. use Pimcore\Model\User;
  19. use Symfony\Component\EventDispatcher\GenericEvent;
  20. use Pimcore\Model\DataObject\ClassDefinition\CustomLayout;
  21. use Pimcore\Model\DataObject\Service;
  22. use function Sabre\Event\Loop\instance;
  23. class WorkflowListener implements EventSubscriberInterface
  24. {
  25.     const OPTIONCOLORS = [919293949596979899100];
  26.     const FOLDER_NAME "Attributes";
  27.     const FOLDER_INSIDE_FOLDER self::FOLDER_NAME '/AttributeName';
  28.     const FOLDER_INSIDE_ATTRIBUTEVALUE self::FOLDER_NAME '/AttributeValue';
  29.     const FOLDER_NAME_PFATTRIBUTE "Attribute name";
  30.     const FOLDER_NAME_ATTRIBUTEVALUE "AttributeValue";
  31.     private $workflowRegistry;
  32.     protected $slugify;
  33.     /** By : Khagendra Wagle
  34.      * Unfurtunately Pimcore allows to update the unique code field and there is no field leave security to decide
  35.      * on the fly if a field is editable or not. checkPermission function will have some custom logic
  36.      *  manipulate object layout data before it is opened for users.
  37.      * Note: Not sure if this is is the right approach but there is noway we could acheive this in the current PIMCORE
  38.      * version 6.4. May be in the future, PIMCORE will come up with the solution for field level security
  39.      **/
  40.     public function checkPermissions(GenericEvent $event): void
  41.     {
  42.         $object $event->getArgument("object");
  43.         //data element that is send to Pimcore backend UI
  44.         $data $event->getArgument("data");
  45.         if ($object instanceof DataObject\Product) {
  46.             
  47.             $data['hasPreview'] = false;
  48.             $currentLayout explode(",""-1,1,2");
  49.             if(!in_array($data['currentLayoutId'], $currentLayout)){
  50.                 // Set Model Layout when product is a Model and Sku Layout when it is variant (sku)
  51.                 $data $this->f_setLayout($object$data);
  52.                 $data $this->f_setMandatoryAttributes($object$data);
  53.                 $data $this->f_setAuthentication($object$data);
  54.                 $data $this->f_setProductSpecificAttributes($object$data);
  55.                 $event->setArgument("data"$data);
  56.             }
  57.             //modelCode must be locked once product created and locked for further enhancement
  58.             if ($data['currentLayoutId'] == "1") {
  59.                 $data $this->f_lockModelCode($object$data);
  60.                 $event->setArgument("data"$data);
  61.             }
  62.             if ($data['currentLayoutId'] == "2") {
  63.                 $data $this->f_SetSkuGenerateLayout($object$data);
  64.                 $event->setArgument("data"$data);
  65.             }
  66.             //Hide Size grid and size list in SKU genereate Layout when model code is of 6 length
  67.             if ($data['currentLayoutId'] != "-1" && (($object instanceof DataObject\Brand && $object->getBrandID() != null)
  68.             || ($object instanceof DataObject\MenuCategory && $object->getUniqueCode() != null)
  69.             || ($object instanceof DataObject\Color1 && $object->getColor1Code() != null)
  70.             || ($object instanceof DataObject\MainColor && $object->getMainColor() != null)
  71.             || ($object instanceof DataObject\SimpleColor && $object->getSimpleColorCode() != null)
  72.             || ($object instanceof DataObject\SizeGroup && $object->getCode() != null)
  73.             || ($object instanceof DataObject\Size && $object->getUniqueCode() != null)
  74.             || ($object instanceof DataObject\Tier1 && $object->getTier1Code() != null)
  75.             || ($object instanceof DataObject\Tier2 && $object->getTier2Code() != null)
  76.             || ($object instanceof DataObject\Tier3 && $object->getTier3Code() != null)
  77.             || ($object instanceof DataObject\Theme && $object->getUniqueCode() != null)
  78.                 )) {
  79.                 $data $this->f_makeUniqueFieldReadOnly($object$data);
  80.                 $event->setArgument("data"$data);
  81.             }
  82.         }
  83.     }
  84.     public function f_setMandatoryAttributes($object$data): array
  85.     {
  86.         if ('variant' != $object->gettype()) {
  87.             $settingObject DataObject\SettingAttributes::getBySettingCode('manadatoryModel'1);
  88.             if ($settingObject) {
  89.                 $mandatoryAttributes explode(","trim($settingObject->getAttributes()));
  90.             }
  91.         } else {
  92.             $settingObject DataObject\SettingAttributes::getBySettingCode('mandatorySku'1);
  93.             if ($settingObject) {
  94.                 $mandatoryAttributes explode(","trim($settingObject->getAttributes()));
  95.             }
  96.         }
  97.         $layout \GuzzleHttp\json_encode($data["layout"]);
  98.         if (is_array($mandatoryAttributes)) {
  99.             $from_man_property 'mandatory":false';
  100.             $to_man_property 'mandatory":true';
  101.             foreach ($mandatoryAttributes as $mandatoryAttribute) {
  102.                 $key '"name":"' $mandatoryAttribute '"';
  103.                 $poss $this->strpos_all($layout$key);
  104.                 foreach ($poss as $pos) {
  105.                     $layout_str1 substr($layout0$pos);
  106.                     $layout_str2 substr($layout$pos);
  107.                     $layout_str2 preg_replace('/' $from_man_property '/'$to_man_property$layout_str21);
  108.                     $layout $layout_str1 $layout_str2;
  109.                 }
  110.             }
  111.         }
  112.         $layout_data \GuzzleHttp\json_decode($layout);
  113.         $data['layout'] = $layout_data;
  114.         return $data;
  115.     }
  116.     public function f_setProductSpecificAttributes($object$data): array
  117.     {
  118.         //Product Specific Attribute
  119.         if ($object->getTier3() && (($object->getTier3()->getProductSpecificAttributes() != null && !empty($object->getTier3()->getProductSpecificAttributes()))
  120.                 || ($object->getTier3()->getMandatoryAttributes() != null && !empty($object->getTier3()->getMandatoryAttributes())))) {
  121.             $tier1Object $object->getTier3();
  122.         } else {
  123.             $tier1Object $object->getTier1();
  124.         }
  125.         if ($tier1Object) {
  126.             $optionalAttributes explode(","trim($tier1Object->getProductSpecificAttributes()));
  127.             $mandatory explode(","trim($tier1Object->getMandatoryAttributes()));
  128.             $attributes array_merge($mandatory$optionalAttributes);
  129.             $attributes array_unique($attributes);
  130.             if (is_array($attributes)) {
  131.                 $layout \GuzzleHttp\json_encode($data["layout"]);
  132.                 $layout_new $this->makeAttributeVisible(true$layout$attributes$mandatory);
  133.                 /** Not required anymore so commented for now...
  134.                  * Fabric description is localized and when it must be invisible for any Tier, the language flags are still shown
  135.                  * To hide those flags we user the trick and hide it. For this purpose localized title is set as Fabric description:
  136.                  * */
  137. //                if (!in_array("fabricDescription", $attributes)) { //means localized flags should be hidden
  138. //                    $key = '"title":"Fabric description:"';
  139. //                    $poss = $this->strpos_all($layout_new, $key);
  140. //                    foreach ($poss as $pos) {
  141. //                        $layout_str1 = substr($layout_new, 0, $pos);
  142. //                        $layout_str2 = substr($layout_new, $pos);
  143. //                        $from_property = 'width":""';
  144. //                        $to_property = 'width":1';
  145. //                        $layout_str2 = preg_replace('/' . $from_property . '/', $to_property, $layout_str2, 1);
  146. //                        $from_property = 'height":""';
  147. //                        $to_property = 'height":1';
  148. //                        $layout_str2 = preg_replace('/' . $from_property . '/', $to_property, $layout_str2, 1);
  149. //                        $from_property = 'border":true';
  150. //                        $to_property = 'border":false';
  151. //                        $layout_str2 = preg_replace('/' . $from_property . '/', $to_property, $layout_str2, 1);
  152. //
  153. //                        $layout_new = $layout_str1 . $layout_str2;
  154. //
  155. //                    }
  156. //                }
  157.                 $layout_data \GuzzleHttp\json_decode($layout_new);
  158.                 $data['layout'] = $layout_data;
  159.             }
  160.         }
  161.         return $data;
  162.     }
  163.     /**
  164.      * @param $object
  165.      * @param $data
  166.      */
  167.     public function f_setAuthentication($object$data): array
  168.     {
  169.         // Translation update should be blocked once it is sent for Review or translation done. Only Translation manager or Admin with Master (Admin mode) layout can update it.
  170.         if (!$this->isUserAllowed('editTranslations') && ($object->getTranslationStatus() == "done" || $object->getTranslationStatus() == "send")) {
  171.             $settingObject DataObject\SettingAttributes::getBySettingCode('editTranslations'1);
  172.             if ($settingObject) {
  173.                 $attributes explode(","$settingObject->getAttributes());
  174.                 if (is_array($attributes)) {
  175.                     $layout \GuzzleHttp\json_encode($data["layout"]);
  176.                     $layout_new $this->makeAttributeReadOnly(true$layout$attributes);
  177.                     $layout_data \GuzzleHttp\json_decode($layout_new);
  178.                     $data['layout'] = $layout_data;
  179.                 }
  180.             }
  181.         }
  182.         // Allow Onboarding status and pfstore status editable for roles setup in the setting
  183.         $user \Pimcore\Tool\Admin::getCurrentUser()->getName();
  184.         if ($user == "admin" || $this->isUserAllowed('editStatus')) {
  185.             $settingObject DataObject\SettingAttributes::getBySettingCode('editStatus'1);
  186.             if ($settingObject) {
  187.                 $attributes explode(","$settingObject->getAttributes());
  188.                 if (is_array($attributes)) {
  189.                     $layout \GuzzleHttp\json_encode($data["layout"]);
  190.                     $layout_new $this->makeAttributeReadOnly(false$layout$attributes);
  191.                     $layout_data \GuzzleHttp\json_decode($layout_new);
  192.                     $data['layout'] = $layout_data;
  193.                 }
  194.             }
  195.         }
  196.         $users \Pimcore\Tool\Admin::getCurrentUser();
  197.         if ($object->getInitialIntroDate() != null || $object->getInitialIntroDate() != "") {
  198.             foreach ($users->getRoles() as $user) {
  199. //                $userOrRoleToCheck = User\Role::getById($user);
  200. //                    if (($user == 26 || $userOrRoleToCheck == "Launch_manager") || $this->isUserAllowed('editStatus')) {
  201.                 if ($object->getInitialIntroDate() != null || $object->getInitialIntroDate != "") {
  202.                     $settingObject DataObject\SettingAttributes::getBySettingCode('editStatus'1);
  203.                     $attributes explode(","$settingObject->getAttributes());
  204.                     array_push($attributes"initialIntroDate");
  205.                     $layout \GuzzleHttp\json_encode($data["layout"]);
  206.                     $layout_new $this->makeAttributeReadOnly(true$layout$attributes);
  207.                     $layout_data \GuzzleHttp\json_decode($layout_new);
  208.                     $data['layout'] = $layout_data;
  209.                 }
  210.             }
  211.         } else {
  212.             if (!empty($users->getRoles()) || $users->getRoles() != null || $users->getRoles() != "") {
  213.                 foreach ($users->getRoles() as $user) {
  214.                     $userOrRoleToCheck User\Role::getById($user);
  215.                     if (($user == 26 || $userOrRoleToCheck == "Launch_manager") || $this->isUserAllowed('editStatus')) {
  216.                         $settingObject DataObject\SettingAttributes::getBySettingCode('editStatus'1);
  217.                         $attributes explode(","$settingObject->getAttributes());
  218.                         array_push($attributes"initialIntroDate");
  219.                         $layout \GuzzleHttp\json_encode($data["layout"]);
  220.                         $layout_new $this->makeAttributeReadOnly(false$layout$attributes);
  221.                         $layout_data \GuzzleHttp\json_decode($layout_new);
  222.                         $data['layout'] = $layout_data;
  223.                     }
  224.                 }
  225.             }
  226.         }
  227.         return $data;
  228.     }
  229.     public function f_SetSkuGenerateLayout($object$data): array
  230.     {
  231.         DataObject\Product::setGetInheritedValues(true);
  232.         $attributes = [];
  233.         $layout \GuzzleHttp\json_encode($data["layout"]);
  234.         if (strlen($object->getModelCode()) > 5) {
  235.             $attributes explode(",""sizeGroup,sizeList");
  236.             $layout $this->makeAttributeVisible(false$layout$attributes);
  237.         } //if model code is 5 and sizegrid was already saved with sku generation, do not allow to switch sizeGrid
  238.         else if ($object->getSizeGrid()) {
  239.             $attributes explode(",""sizeGroup");
  240.             $layout $this->makeAttributeReadOnly(true$layout$attributes);
  241.         }
  242.         $layout_data \GuzzleHttp\json_decode($layout);
  243.         $data['layout'] = $layout_data;
  244.         return $data;
  245.     }
  246.     /**
  247.      * @param $object
  248.      * @param $data
  249.      * @return mixed
  250.      */
  251.     public function f_setLayout($object$data): array
  252.     {
  253.         DataObject\Product::setGetInheritedValues(true);
  254.         if ('variant' == $object->gettype()) {
  255.             $customLayoutToSelect 4;
  256.         } else {
  257.             $customLayoutToSelect 3;
  258.         }
  259.         if ($customLayoutToSelect != null) {
  260.             //set current layout to subcategory layout
  261.             $data['currentLayoutId'] = $customLayoutToSelect;
  262.             $customLayout CustomLayout::getById($customLayoutToSelect);
  263.             $data['layout'] = $customLayout->getLayoutDefinitions();
  264.             Service::enrichLayoutDefinition($data["layout"], $object);
  265.         }
  266.         if (!empty($layoutsToRemove)) {
  267.             //remove master layout from valid layouts
  268.             $validLayouts $data["validLayouts"];
  269.             foreach ($validLayouts as $key => $validLayout) {
  270.                 if (in_array($validLayout['id'], $layoutsToRemove)) {
  271.                     unset($validLayouts[$key]);
  272.                 }
  273.             }
  274.             $data["validLayouts"] = array_values($validLayouts);
  275.         }
  276.         return $data;
  277.     }
  278.     /**
  279.      * @param $object
  280.      * @param $data
  281.      * Lock modelcode field after Model code is locked in layout 1.
  282.      */
  283.     public function f_lockModelCode($object$data): array
  284.     {
  285.         if ($this->getWorkflowStatus($object) != "mode_create") {
  286.             $attributes explode(",""modelCode");
  287.             $layout \GuzzleHttp\json_encode($data["layout"]);
  288.             $layout_new $this->makeAttributeReadOnly(true$layout$attributes);
  289.             $layout_data \GuzzleHttp\json_decode($layout_new);
  290.             $data['layout'] = $layout_data;
  291.         }
  292.         return $data;
  293.     }
  294.     /**
  295.      * @param $data
  296.      * @param $object
  297.      *  make attribute read-only when there Unique (code) defined in the Master Data class.
  298.      * Admin can alwayas do using Master(admin mode) layout
  299.      */
  300.     public function f_makeUniqueFieldReadOnly($object$data): array
  301.     {
  302.         $layout \GuzzleHttp\json_encode($data["layout"]);
  303.         $layout_new $this->makeUniqueFieldReadOnly($layout'"unique":true');
  304.         $layout_data \GuzzleHttp\json_decode($layout_new);
  305.         $data['layout'] = $layout_data;
  306.         return $data;
  307.     }
  308.     public function isUserAllowed($settingCode): bool
  309.     {
  310.         $userAllowed false;
  311.         $settingObject DataObject\SettingAttributes::getBySettingCode($settingCode1);
  312.         if ($settingObject) {
  313.             $roles_setting $settingObject->getRoles();
  314.             if ($roles_setting != null && $roles_setting != "") {
  315.                 $allowedRoles explode(","$roles_setting); //We can move this to setting in the future
  316.                 $roles $this->rolesName(); // All the roles current user has got
  317.                 foreach ($roles as $role) {
  318.                     if (in_array($role$allowedRoles)) {
  319.                         $userAllowed true;
  320.                         break;
  321.                     }
  322.                 }
  323.             }
  324.         }
  325.         return $userAllowed;
  326.     }
  327.     public function rolesName(): array
  328.     {
  329.         // get available roles
  330.         $roles = [];
  331.         $currentRoles \Pimcore\Tool\Admin::getCurrentUser()->getRoles();
  332.         $list = new User\Role\Listing();
  333.         $list->setCondition('`type` = ?', ['role']);
  334.         $list->load();
  335.         foreach ($currentRoles as $currentRole) {
  336.             if (is_array($list->getItems())) {
  337.                 foreach ($list->getItems() as $role) {
  338.                     if ($role->getId() == $currentRole) {
  339.                         $roles $role->getName();
  340.                     }
  341.                 }
  342.             }
  343.         }
  344.         return [$roles];
  345.     }
  346.     public function makeAttributeReadOnly($flag_readonly$layout$attributes): string
  347.     {
  348.         if ($flag_readonly) {
  349.             $from_property 'noteditable":false';
  350.             $to_property 'noteditable":true';
  351.         } else {
  352.             $from_property 'noteditable":true';
  353.             $to_property 'noteditable":false';
  354.         }
  355.         foreach ($attributes as $attribute) {
  356.             $key '"name":"' $attribute '"';
  357.             $poss $this->strpos_all($layout$key);
  358.             foreach ($poss as $pos) {
  359.                 $layout_str1 substr($layout0$pos);
  360.                 $layout_str2 substr($layout$pos);
  361.                 $layout_str2 preg_replace('/' $from_property '/'$to_property$layout_str21);
  362.                 //mark as mandatory if it is in mandatory attribute list under Tier1. used only for product specific attributes.
  363.                 $layout $layout_str1 $layout_str2;
  364.             }
  365.         }
  366.         return $layout;
  367.     }
  368.     public function makeAttributeVisible($flag_visible$layout$attributes$mandatory null): string
  369.     {
  370.         if ($flag_visible) {
  371.             $from_property 'invisible":true';
  372.             $to_property 'invisible":false';
  373.         } else {
  374.             $from_property 'invisible":false';
  375.             $to_property 'invisible":true';
  376.         }
  377.         foreach ($attributes as $attribute) {
  378.             $key '"name":"' $attribute '"';
  379.             $poss $this->strpos_all($layout$key);
  380.             foreach ($poss as $pos) {
  381.                 $layout_str1 substr($layout0$pos);
  382.                 $layout_str2 substr($layout$pos);
  383.                 $layout_str2 preg_replace('/' $from_property '/'$to_property$layout_str21);
  384.                 if (is_array($mandatory) && in_array($attribute$mandatory)) {
  385.                     $from_man_property 'mandatory":false';
  386.                     $to_man_property 'mandatory":true';
  387.                     $layout_str2 preg_replace('/' $from_man_property '/'$to_man_property$layout_str21);
  388.                 }
  389.                 $layout $layout_str1 $layout_str2;
  390.             }
  391.         }
  392.         return $layout;
  393.     }
  394.     public function makeUniqueFieldReadOnly($layout$key): string
  395.     {
  396.         $poss $this->strpos_all($layout$key);
  397.         foreach ($poss as $pos) {
  398.             $layout_str1 substr($layout0$pos);
  399.             $layout_str2 substr($layout$pos);
  400.             $layout_str2 preg_replace('/' 'noteditable":false' '/''noteditable":true'$layout_str21);
  401.             $layout $layout_str1 $layout_str2;
  402.         }
  403.         return $layout;
  404.     }
  405.     public function strpos_all($layout$key): array
  406.     {
  407.         $offset 0;
  408.         $allpos = array();
  409.         while (($pos strpos($layout$key$offset)) !== FALSE) {
  410.             $offset $pos 1;
  411.             $allpos[] = $pos;
  412.         }
  413.         return $allpos;
  414.     }
  415.     public function __construct(Registry $workflowRegistry)
  416.     {
  417.         $this->workflowRegistry $workflowRegistry;
  418.     }
  419.     /** By Khagendra
  420.      * The onleave event will catch the workflow transition and setLastWorkflowAction
  421.      * which will later be used to skip validation while creating model for the first time
  422.      * This is also the place when you want to hook any validation for any workflow transition
  423.      */
  424.     public function onLeave(Event $event): void
  425.     {
  426.         $errors = [];
  427.         $object $event->getSubject();
  428.         $eventTransition $event->getTransition();
  429.         $transitionName $eventTransition->getName();
  430.         $this->workflowActionValidation($object$transitionName);
  431.         $object->setSkipValidation(true);
  432.         $user \Pimcore\Tool\Admin::getCurrentUser();
  433.         if ($user) {
  434.             $username $user->getName();
  435.         }
  436.         if ($transitionName == 'create_done') {
  437.             $user \Pimcore\Tool\Admin::getCurrentUser();
  438.             $object->setProductCreator($username);
  439.             $object->setProductType("Model");
  440.             $this->setProductOwner($object$username);
  441.             $object->setProductCreateDate(Carbon::now());
  442.             if (strlen($object->getModelCode()) == 6) {
  443.                 $gridObject DataObject\SizeGroup::getByCode('NA'1);
  444.                 if ($gridObject) {
  445.                     $object->setSizeGrid($gridObject);
  446.                 }
  447.             }
  448.         } else if ($transitionName == 'create_sku') {
  449.             if (strlen($object->getModelCode()) == 6) {
  450.                 $this->CreateSkuWithColorVariants($object);
  451.             } elseif (strlen($object->getModelCode()) == 5) {
  452.                 $this->CreateSkuWithColorSizeVariants($object);
  453.             } else {
  454.                 $message 'Model code length must  be either 5 or 6 for Sku generation.';
  455.                 array_push($errors$message);
  456.                 $this->ValidationExceptionWorkflow($errors);
  457.             }
  458.         } else if ($transitionName == 'ready_for_review') {
  459.             $object->setTranslationStatus('send');
  460.             $object->setTranslationSentBy($username);
  461.         } else if ($transitionName == 'translation_done') {
  462.             $object->setTranslationStatus('done');
  463.         } else if ($transitionName == 'reopen_product_enrich') {
  464.             $object->setTranslationStatus('reopen');
  465.         } else if ($transitionName == 'ready_for_translation' || $transitionName == 'ready_for_translation2') {
  466.             $object->setTranslationStatus('translating');
  467.         } else if ($transitionName == 'reject_review') {
  468.             $object->setTranslationStatus('rejected');
  469.             $user_receipient $object->getTranslationSentBY();
  470.             if ($user_receipient != null) {
  471.                 $title 'Request for translation is rejected for product ' $object->getModelCode();
  472.                 $message $title '<br>' 'Please open the product and check details under "Notes & Events"';
  473.                 $this->createUserNotification($object$user_receipient$title$message);
  474.             }
  475.         }
  476.         
  477.     }
  478.     public function setProductOwner($object$userid): void
  479.     {
  480.         $uname '';
  481.         $userObject User::getByName($userid);
  482.         if ($userObject) {
  483.             $uname $userObject->getFirstname() . " " $userObject->getLastname();
  484.         }
  485.         if ($uname == '' || $uname == null || $userid == 'admin') {
  486.             $uname $userid;
  487.         }
  488.         $object->setProductOwner($uname);
  489.     }
  490.     /** By Khagendra
  491.      * The Guard event is use to block Workflow transition without minimum required feilds are available
  492.      */
  493.     public function guardPublish(GuardEvent $event): void
  494.     {
  495.         $objects $event->getSubject();
  496.         if ('variant' == $objects->gettype()) {  // Workflow action is blocked on variant level
  497.             $event->setBlocked(true);
  498.         }
  499.         if ($objects->getModelCode() == null || $objects->getTier3() == null) {
  500.             $event->setBlocked(true);
  501.         }
  502.     }
  503.     public static function getSubscribedEvents(): array
  504.     {
  505.         return [
  506.             'workflow.Product_Workflow.guard' => ['guardPublish'],
  507.             'workflow.Product_Workflow.leave' => ['onLeave'],
  508.         ];
  509.     }
  510.     public function workflowActionValidation($object$transitionName): void
  511.     {
  512.         if ($transitionName == "ready_for_translation") {
  513.             $errors = [];
  514.             if ($object->getProductTitle('en') == null) {
  515.                 $message 'Product title is empty.';
  516.                 array_push($errors$message);
  517.             }
  518.             if ($object->getProductDescription('en') == null) {
  519.                 $message 'Product description is empty.';
  520.                 array_push($errors$message);
  521.             }
  522.             $this->ValidationExceptionWorkflow($errors);
  523.         }
  524.     }
  525.     public function createUserNotification($object$user_receiver$title$message): void
  526.     {
  527.         try {
  528.             $element DataObject::getById($object->getId());
  529.             $userService = new UserService();
  530.             $notificationService = new NotificationService($userService);
  531.             $recipient User::getByName($user_receiver)->getId();
  532.             $notificationService->sendToUser(
  533.                 $recipient// User recipient
  534.                 0// User sender 0 - system
  535.                 $title,
  536.                 $message '<br>' $element,
  537.                 $element
  538.             );
  539.         } catch (\Exception $e) {
  540.         }
  541.     }
  542.     public function ValidationExceptionWorkflow($errors): void
  543.     {
  544.         // throw ExceptionMessage of validation
  545.         if (!empty($errors)) {
  546.             $result null;
  547.             foreach ($errors as $error) {
  548.                 $result .= $error '<br>';
  549.             }
  550.             throw new \UnexpectedValueException($result);
  551.         }
  552.     }
  553.     public function getWorkflowStatus($object): string
  554.     {
  555.         $workflow $this->workflowRegistry->get($object'Product_Workflow');
  556.         return implode(', 'array_keys($workflow->getMarking($object)->getPlaces()));
  557.     }
  558.     /**
  559.      * @param $object
  560.      */
  561.     public function CreateSkuWithColorVariants($object): void
  562.     {
  563.         $skuList = [];
  564.         $colorList = [];
  565.         $colorCodeList = [];
  566.         $skuMessages = [];
  567.         if (($object->getSelectColors()) == null) {
  568.             $message "Color1 is required. Select Color1 and save first.";
  569.             array_push($skuMessages$message);
  570.             $this->ValidationExceptionWorkflow($skuMessages);
  571.         }
  572.         if ($object->getSelectColors()) {
  573.             foreach ($object->getSelectColors() as $SelectColor) {
  574.                 $SelectColorObject DataObject\Color1::getById($SelectColor->getElementId());
  575.                 $listing = new DataObject\Product\Listing();
  576.                 $listing->setCondition('ModelCode = ?'$object->getModelCode());
  577.                 $listing->setObjectTypes([DataObject\AbstractObject::OBJECT_TYPE_VARIANT]);
  578.                 if ($object->getselectedColors()) {
  579.                     if (in_array(trim($SelectColorObject->getColor1Code()), explode(','$object->getselectedColors()))) {
  580.                         continue;
  581.                     }
  582.                 }
  583.                 $skus $listing->getObjects();
  584.                 foreach ($skus as $sku) {
  585.                     array_push($skuList$sku->getSku());
  586.                     if (!in_array($sku->getColor1Code(), $colorList)) {
  587.                         array_push($colorList$sku->getColor1Code());
  588.                     }
  589.                     //Check if there is sku already generated with selected color now
  590. //                    if ($object->getColors()->getColor1Code() == $sku->getColor1Code()) {
  591. //                        $message = "Sku " . $sku->getSku() . " already exists with Color " . $object->getColors()->getColor1Code();
  592. //                        array_push($skuMessages, $message);
  593. //                        $this->ValidationExceptionWorkflow($skuMessages);
  594. //                    }
  595.                     array_push($colorCodeListsubstr($sku->getSku(), 62));
  596.                 }
  597.                 /** Now generate sku with selected color
  598.                  *1. First calculate what is the sku code for selected color */
  599.                 $skuNumber $object->getModelCode() . $SelectColorObject->getParent()->getSkuColorCode();
  600.                 /** 2 . First check if this skuNumber already exits */
  601.                 if (!in_array($skuNumber$skuList)) {
  602.                     /** 2.1 Does not exists so create it with $skuNumber */
  603.                     $this->CreateSku($object$sizeObjects null$skuNumber$SelectColorObject->getColor1Code(), $SelectColorObject->getHexColor1());
  604.                 } else {
  605.                     /** 2.2 exists so deviate to sku code miscellaneous range */
  606.                     $deviationCode 91;
  607.                     do {
  608.                         if (in_array($deviationCode$colorCodeList)) {
  609.                             $deviationCode $deviationCode 1;
  610.                         } else {
  611.                             break;
  612.                         }
  613.                     } while ($deviationCode 100);
  614.                     if ($deviationCode 99) {
  615.                         $message "Miscellaneous sku color code range 91-99 exceeds.";
  616.                         array_push($skuMessages$message);
  617.                         $this->ValidationExceptionWorkflow($skuMessages);
  618.                     }
  619.                     $skuNumber $object->getModelCode() . $deviationCode;
  620.                     $this->CreateSku($object$sizeObjects null$skuNumber$SelectColorObject->getColor1Code(), $SelectColorObject->getHexColor1());
  621.                 }
  622.                 // set list of colors created on model level
  623.                 $modelSelectedColor implode(","$colorList) . "," $SelectColorObject->getColor1Code();
  624.                 $object->setselectedColors(trim($modelSelectedColor","));
  625.                 // $object->save();
  626.                 //   \Pimcore\Cache::clearAll();
  627.                 //throw new ValidationException("Created sku is ".$skuNumber, 409);
  628.             }
  629.         }
  630.         $object->setSelectColors(null); // reset select color  1 after sku is generated
  631.         $object->setColors2(null); // reset select color 2 after sku is generated
  632.         $object->setColors3(null); // reset select color 3 after sku is generated
  633.         $object->setOmitMandatoryCheck(true);
  634.         $object->setSkipValidation(true);
  635.         $object->setPublished(true);
  636.     }
  637.     /**
  638.      * @param $object
  639.      */
  640.     public function CreateSkuWithColorSizeVariants($object): void
  641.     {
  642.         $skuList = [];
  643.         $colorList = [];
  644.         $colorCodeList = [];
  645.         $skuMessages = [];
  646.         $skuNumbers = [];
  647.         $sizeList = [];
  648.         $skuColorCode 0;
  649.         if (($object->getSelectColors()) == null) {
  650.             $message "Color1 is required.";
  651.             array_push($skuMessages$message);
  652.             //$this->ValidationExceptionWorkflow($skuMessages);
  653.         }
  654.         if ($object->getSizeGroup() == null) {
  655.             $message "Size group is required.";
  656.             array_push($skuMessages$message);
  657.         }
  658.         if (empty($object->getSizeList())) {
  659.             $message "Select size and save.";
  660.             array_push($skuMessages$message);
  661.         }
  662.         $this->ValidationExceptionWorkflow($skuMessages);
  663.         foreach ($object->getSelectColors() as $SelectColor) {
  664.             $SelectColorObject DataObject\Color1::getById($SelectColor->getElementId());
  665.             $listing = new DataObject\Product\Listing();
  666.             $listing->setCondition('ModelCode = ?'$object->getModelCode());
  667.             $listing->setObjectTypes([DataObject\AbstractObject::OBJECT_TYPE_VARIANT]);
  668.             $skus $listing->getObjects();
  669.             foreach ($skus as $sku) {
  670.                 array_push($skuList$sku->getSku());
  671.                 if (!in_array($sku->getColor1Code(), $colorList)) {
  672.                     array_push($colorList$sku->getColor1Code());
  673.                 }
  674.                 /**  Build Size string to calucate later SizeRange and SizeRangeDetails */
  675.                 $sizeCodeObject DataObject\Size::getByCode($sku->getSizeCode(), 1);
  676.                 if ($sizeCodeObject) {
  677.                     if (strlen($sizeCodeObject->getSizeSequence()) == 1) {
  678.                         $sizeString "0" $sizeCodeObject->getSizeSequence() . "-" $sku->getSizeCode();
  679.                     } else {
  680.                         $sizeString $sizeCodeObject->getSizeSequence() . "-" $sku->getSizeCode();
  681.                     }
  682.                 } else {
  683.                     $sizeString "01-" $sku->getSizeCode();
  684.                 }
  685.                 if (!in_array($sizeString$sizeList)) {
  686.                     array_push($sizeList$sizeString);
  687.                 }
  688.                 array_push($colorCodeListsubstr($sku->getSku(), 52));
  689.                 if ($skuColorCode == && $SelectColorObject->getColor1Code() == $sku->getColor1Code()) {
  690.                     $skuColorCode substr($sku->getSku(), 52);
  691.                 }
  692.             }
  693.             /** Now generate sku with selected color
  694.              * 1. First check if deviation is needed or not
  695.              * Deviation rule is simple here.
  696.              * When selected color does not exist in already created SKU List and SKU color code is already used by
  697.              * another color from simple color of an item, then deviation is needed.
  698.              */
  699.             if ($skuColorCode == 0) {
  700.                 $skuColorCode $SelectColorObject->getParent()->getSkuColorCode(); // SKu Code of simple color
  701.             }
  702.             $deviationCode 0;
  703.             if (!in_array($SelectColorObject->getColor1Code(), $colorList)
  704.                 && in_array($SelectColorObject->getParent()->getSkuColorCode(), $colorCodeList)) {
  705.                 $deviationCode 91;
  706.                 do {
  707.                     if (in_array($deviationCode$colorCodeList)) {
  708.                         $deviationCode $deviationCode 1;
  709.                     } else {
  710.                         break;
  711.                     }
  712.                 } while ($deviationCode 100);
  713.                 if ($deviationCode 99) {
  714.                     $message "Miscellaneous sku color code range 91-99 exceeds.";
  715.                     array_push($skuMessages$message);
  716.                     $this->ValidationExceptionWorkflow($skuMessages);
  717.                 }
  718.             } else {
  719.                 $skuColorCode $SelectColorObject->getParent()->getSkuColorCode();
  720.             }
  721.             /**2. We know now if deviation is needed and what would be sku color code. Let's define all the sku numbers
  722.              * to be created per size
  723.              */
  724.             foreach ($object->getSizeList() as $key => $sizeObject) {
  725.                 $sizeCodeObject DataObject\Size::getById($sizeObject);
  726.                 $sizeSkuCode $sizeCodeObject->getSkuCode();
  727.                 if ($deviationCode 0) {
  728.                     $skuKey $object->getModelCode() . $deviationCode $sizeSkuCode;
  729.                 } else {
  730.                     $skuKey $object->getModelCode() . $skuColorCode $sizeSkuCode;
  731.                 }
  732.                 // needed for SizeRange and SizeDetail
  733.                 if (strlen($sizeCodeObject->getSizeSequence()) == 1) {
  734.                     $sizeString "0" $sizeCodeObject->getSizeSequence() . "-" $sizeCodeObject->getCode();
  735.                 } else {
  736.                     $sizeString $sizeCodeObject->getSizeSequence() . "-" $sizeCodeObject->getCode();
  737.                 }
  738.                 if (!in_array($sizeString$sizeList)) {
  739.                     array_push($sizeList$sizeString);
  740.                 }
  741.                 /** 2.1 First check if this skuNumber already exits with the size in $skuList(already created list)*/
  742.                 if (in_array($skuKey$skuList)) {
  743.                     /** exists so block to proceed further */
  744. //                    $message = "Sku creation not possible with Size code " . $sizeCodeObject->getCode() . "<br>" . $skuKey . " already exists.";
  745. //                    array_push($skuMessages, $message);
  746. //                    $this->ValidationExceptionWorkflow($skuMessages);
  747.                     continue;
  748.                 }
  749.                 $skuString $skuKey $sizeCodeObject;
  750.                 array_push($skuNumbers$skuString);
  751.             }
  752.             /** All the validation passed now, so we can start creating SKUs based on the list built in step 2.1 */
  753.             foreach ($skuNumbers as $skuNumber) {
  754.                 $sku substr($skuNumber08);
  755.                 $sizePath substr($skuNumber8);
  756.                 $listing = new DataObject\Product\Listing();
  757.                 $listing->setCondition('Sku = ?'$sku);
  758.                 $listing->setObjectTypes([DataObject\AbstractObject::OBJECT_TYPE_VARIANT]);
  759.                 if ($listing->getObjects() != null && $listing->getObjects()[0]->getSku() == $sku) {
  760.                     continue;
  761.                 }
  762.                 $this->CreateSku($object$sizePath$sku$SelectColorObject->getColor1Code(), $SelectColorObject->getHexColor1());
  763.             }
  764.             // set list of colors created on model level
  765.             if (!in_array($SelectColorObject->getColor1Code(), $colorList)) {
  766.                 $modelSelectedColor implode(","$colorList) . "," $SelectColorObject->getColor1Code();
  767.             } else {
  768.                 $modelSelectedColor implode(","$colorList);
  769.             }
  770.             $object->setselectedColors(trim($modelSelectedColor","));
  771.             if ($object->getSizeGrid() == null) {
  772.                 $object->setSizeGrid($object->getSizeGroup());
  773.             }
  774.             //Set size range and size details
  775.             asort($sizeList);
  776.             // file_put_contents("D:\Projects\objectdata2.json", json_encode($sizeList,JSON_PRETTY_PRINT));
  777.             $minSize "";
  778.             $sizeDetails "";
  779.             foreach ($sizeList as $size) {
  780.                 $sizestr explode("-"$size);
  781.                 if ($sizeDetails == "") {
  782.                     $minSize $sizestr[1];
  783.                 }
  784.                 $maxSize $sizestr[1];
  785.                 $sizeDetails $sizeDetails "," $sizestr[1];;
  786.             }
  787.             $object->setsizeRange($minSize "-" $maxSize);
  788.             $object->setSizeRangeDetail(trim($sizeDetails","));
  789.             // $object->save();
  790.             //  Pimcore\Cache::clearAll();
  791.         }
  792.         $object->setSelectColors(null); // reset select color  1 after sku is generated
  793.         $object->setColors2(null); // reset select color 2 after sku is generated
  794.         $object->setColors3(null); // reset select color 3 after sku is generated
  795.         $object->setOmitMandatoryCheck(true);
  796.         $object->setSkipValidation(true);
  797.         $object->setPublished(true);
  798.     }
  799.     /**
  800.      * @param $objects
  801.      * @throws \Exception
  802.      */
  803.     public function CreateSku($modelObject$sizePath$skuNumber$color1Code$color1HexColor1): void
  804.     {
  805.         if (strlen($skuNumber) != 8) {
  806.             return;
  807.         }
  808.         $skuObject = new DataObject\Product();
  809.         $skuObject->setType(DataObject\Product::OBJECT_TYPE_VARIANT);
  810.         $skuObject->setKey($skuNumber);
  811.         $skuObject->setParentId($modelObject->getId());
  812.         $skuObject->setSku($skuNumber);
  813.         $skuObject->setProductType('Sku');
  814.         $skuObject->setProductIdentifier($skuNumber);
  815.         $skuObject->setColor1Code($color1Code);
  816.         $skuObject->setHexColor1($color1HexColor1);
  817. //        $skuObject->setColor1Code($modelObject->getColors()->getColor1Code());
  818. //        $skuObject->setHexColor1($modelObject->getColors()->getHexColor1());
  819.         if ($modelObject->getColors2()) {
  820.             $skuObject->setColor2Code($modelObject->getColors2());
  821.             $skuObject->setHexColor2($modelObject->getColors2()->getHexColor1());
  822.         }
  823.         if ($modelObject->getColors3()) {
  824.             $skuObject->setColor3Code($modelObject->getColors3());
  825.             $skuObject->setHexColor3($modelObject->getColors3()->getHexColor1());
  826.         }
  827.         $skuObject->setOnboardingStatus('pafPhase');
  828.         $skuObject->setpfstoreStatus('new');
  829.         $skuObject->setErpStatus('new');
  830.         $user \Pimcore\Tool\Admin::getCurrentUser();
  831.         if ($user) {
  832.             $username $user->getName();
  833.         }
  834.         $skuObject->setSkuCreator($username);
  835.         $skuObject->setSkuCreateDate(Carbon::now());
  836.         if ($sizePath != null) {
  837.             $sizeCodeObject DataObject\Size::getByPath($sizePath);
  838.             $skuObject->setSizeCode($sizeCodeObject->getCode());
  839.         } else {
  840.             $skuObject->setSizeCode("NA");
  841.         }
  842.         $skuObject->setOmitMandatoryCheck(true);
  843.         $skuObject->setPublished(true);
  844.         $skuObject->save();
  845.     }
  846.     /**
  847.      * @param ElementEventInterface $event
  848.      *
  849.      * @throws \Pimcore\Model\Element\ValidationException
  850.      */
  851.     public function onPreUpdate(ElementEventInterface $event): void
  852.     {
  853.         if ($event instanceof DataObjectEvent) {
  854.             $objects $event->getObject();
  855.             $this->checkValidation($objects);
  856.         }
  857.     }
  858.     /**
  859.      * @param ElementEventInterface $event
  860.      * Set inital workflow state to sku_created to avoid further workflow on variant
  861.      */
  862.     public
  863.     function postAdd(ElementEventInterface $event): void
  864.     {
  865.         if ($event instanceof DataObjectEvent) {
  866.             $object $event->getObject();
  867.             if ($object instanceof DataObject\Product) {
  868.                 if ('variant' == $object->gettype()) { // default workflow is added for variant
  869.                     $this->setSkuWorkFlowState($object);
  870.                 }
  871.             }
  872.         }
  873.     }
  874.     /**
  875.      * @param $object
  876.      * Set inital workflow state to sku_created to avoid further workflow on variant
  877.      */
  878.     public
  879.     function setSkuWorkFlowState($object): void
  880.     {
  881.         $skuObjectId $object->getId();
  882.         $db \Pimcore\Db::get();
  883.         $db->query("INSERT element_workflow_state(cid, ctype, place, workflow) VALUES($skuObjectId, 'object', 'sku_created', 'Product_Workflow') ");
  884.     }
  885.     /**
  886.      * @param $message
  887.      * @throws ValidationException
  888.      */
  889.     public function getExceptionMessage($skuMessages$object): void
  890.     {
  891.         if (!empty($skuMessages)) {
  892.             $result null;
  893. //            if($this->getWorkflowStatus($object) != "mode_create") {
  894. //                $message = "<h4><u>Use temporary save to save work in progress</u></h4>";
  895. //            }
  896. //            $result .= $message;
  897.             foreach ($skuMessages as $skuMessage) {
  898.                 $result .= $skuMessage "<span style='color: red;'>*</span>" '<br>';
  899.             }
  900.             throw new ValidationException($result403);
  901.         }
  902.     }
  903.     /**
  904.      * @param $objects
  905.      * @throws \Exception
  906.      */
  907.     public
  908.     function getProductTierTree($objects): void
  909.     {
  910.         $this->slugify = new Slugify();
  911.         if (null != $objects->getProductName()) {
  912.             $productName $objects->getProductName() . '_' $objects->getProductTitle('en');
  913.         } else {
  914.             $productName $objects->getProductTitle('en');
  915.         }
  916.         $keyValue $objects->getModelCode() . '_' $this->slugify->slugify($productName);
  917.         if ($keyValue != $objects->getKey()) {
  918.             $objects->setKey($keyValue);
  919.         }
  920.         $tier_3 $objects->getTier3();
  921.         $tier_2 $tier_3->getParent();
  922.         $tier_1 $tier_2->getParent();
  923.         $objects->setTier2($tier_2);
  924.         $objects->setTier1($tier_1);
  925.         $tier1Key $objects->getTier1()->getKey();
  926.         $tier2Key $objects->getTier2()->getKey();
  927.         $tier3Key $objects->getTier3()->getKey();
  928.         $objectPath explode('/'$objects->getFullPath());
  929.         $productFolder $objectPath[1];
  930.         /* Check if Tier3 sub-folder was already created*/
  931.         if (== substr_count($objects->getFullPath(), "/" $tier3Key)) {
  932.             $tierFoldersPath $productFolder '/' $tier1Key '/' $tier2Key '/' $tier3Key;
  933.             $tierPathExist DataObject\Service::pathExists('/' $tierFoldersPath);
  934.             if (!$tierPathExist) {
  935.                 DataObject\Service::createFolderByPath($tierFoldersPath);
  936.             }
  937.             $Tier3Object DataObject::getByPath('/' $tierFoldersPath);
  938.             $objectPath '/' $tierFoldersPath '/';
  939.             $objects->setParentId($Tier3Object->getID());
  940.             $objects->setPath($objectPath);
  941.         }
  942.     }
  943.     /**
  944.      * @param $folderName
  945.      * @param int $parentId
  946.      * @return bool|int
  947.      * @throws \Exception
  948.      */
  949.     protected
  950.     function createFolder($folderName$parentId 1): bool|int
  951.     {
  952.         // check if folder exists
  953.         if ($folderId $this->isFolderExists($folderName$parentId)) {
  954. //            var_dump($folderId);die;
  955.             return $folderId;
  956.         } else {
  957.             // create folder
  958.             $folder Folder::create(['o_key' => $folderName'o_parentId' => $parentId]);
  959.             $folder->save();
  960. //            var_dump($folderId);
  961. //            var_dump('folder');die;
  962.             return $folder->getId();
  963.         }
  964.     }
  965.     protected function isFolderExists($folderName$parentId 1): bool|int
  966.     {
  967.         // search if folder exists
  968.         if (== $parentId) {
  969.             $folder Folder::getByPath("/$folderName");
  970.         } else {
  971.             $path Folder::getById($parentId)->getRealFullPath();
  972.             $folder Folder::getByPath("$path/$folderName");
  973.         }
  974.         if ($folder) {
  975.             return $folder->getId();
  976.         }
  977.         return false;
  978.     }
  979.     /**
  980.      * @param $objects
  981.      * @throws ValidationException
  982.      */
  983.     public function checkValidation($objects): void
  984.     {
  985.         $baseMaterial1percentage 0;
  986.         $baseMaterial2percentage 0;
  987.         $baseMaterial3percentage 0;
  988.         $errors = [];
  989.         $hastDate date("Y-m-d h:i:s A");
  990.         $onboaringDate date("Y-m-d");
  991.         if ($objects instanceof DataObject\Product) {
  992.             if ($objects instanceof DataObject\Product and 'variant' != $objects->gettype()) {
  993.                 $skipValidation $objects->getSkipValidation();
  994.                 /** TODO: Refactor this chain of validations
  995.                  *  Instead of a massive chain of ifs with mostly repeated code, we should add these checks in an array
  996.                  *  Then associate the corresponding error messages
  997.                  *  And finally call these checks inside a foreach loop
  998.                  *  This way it is easier to read and understand the code as well as locate specific checks and change them
  999.                  *  Ex:
  1000.                  *  $checks = [
  1001.                  *     [$objects->getTier3(), 'Tier3 is required.'],
  1002.                  *     [$objects->getMarkSegment(), 'Market segment is required.'],
  1003.                  *     [$objects->getModelCode(), 'Model code is required.'],
  1004.                  *     …
  1005.                  *     …
  1006.                  *  ];
  1007.                  * 
  1008.                  *  foreach ($checks as $check) {
  1009.                  *    if ($check[0] === null || $check[0] === false) {
  1010.                  *       array_push($errors, $check[1]);
  1011.                  *    }
  1012.                  *  }
  1013.                  * 
  1014.                  */
  1015.                 // This validation is must to save Product data
  1016.                 if (null == $objects->getTier3()) {
  1017.                     $message 'Tier3 is required.';
  1018.                     array_push($errors$message);
  1019.                 }
  1020.                 if (null == $objects->getMarkSegment()) {
  1021.                     $message 'Market segment is required.';
  1022.                     array_push($errors$message);
  1023.                 }
  1024.                 if (null == $objects->getModelCode()) {
  1025.                     $message 'Model code is required.';
  1026.                     array_push($errors$message);
  1027.                 }
  1028.                 if ($objects->getConfiguratorType() == 'base_component') {
  1029.                     if (substr($objects->getModelCode(), 02) != 'CB') {
  1030.                         $message "Model code should start with CB ";
  1031.                         array_push($errors$message);
  1032.                     }
  1033.                 }
  1034.                 if ('yes' == $objects->getIsConfigurable() && ($objects->getConfiguratorType() == "" || $objects->getConfiguratorType() == null)) {
  1035.                     $message 'Configurator type is required.';
  1036.                     array_push($errors$message);
  1037.                 }
  1038.                 if ($this->getWorkflowStatus($objects) == "mode_create" && preg_match('/[^A-Z0-9]/', ($objects->getModelCode()))) {
  1039.                     $message 'Model code cannot be special character and lower case !';
  1040.                     array_push($errors$message);
  1041.                 }
  1042.                 $productModelObject DataObject\Product::getByModelCode($objects->getModelCode(), ['limit' => 1'unpublished' => false]);
  1043.                 if (null != $productModelObject && $productModelObject->getId() !== $objects->getId()) {
  1044.                     $message 'Model number already taken. Please enter new model code';
  1045.                     array_push($errors$message);
  1046.                 }
  1047.                 if ($this->getWorkflowStatus($objects) == "mode_create" && null != $objects->getModelCode() && strlen($objects->getModelCode()) <= 4) {
  1048.                     $message 'Model code length should be either 5 or 6.';
  1049.                     array_push($errors$message);
  1050.                 }
  1051.                 if ($this->getWorkflowStatus($objects) == "mode_create" && null != $objects->getModelCode() && strlen($objects->getModelCode()) >= 7) {
  1052.                     $message 'Model code length can not exceed 6';
  1053.                     array_push($errors$message);
  1054.                 }
  1055.                 if (null == $objects->getProductTitle('en')) {
  1056.                     $message 'Product title is required.';
  1057.                     array_push($errors$message);
  1058.                 }
  1059.                 /** Block adding sku description, color data to Model, those attributes must be under sku */
  1060.                 if (null != $objects->getSkuDescription()) {
  1061.                     $message 'Sku description is of sku, not Model.';
  1062.                     array_push($errors$message);
  1063.                 }
  1064.                 if (null != $objects->getColor1Code()) {
  1065.                     $message 'Color1 is of sku, not Model.';
  1066.                     array_push($errors$message);
  1067.                 }
  1068.                 if (null != $objects->getColor2Code()) {
  1069.                     $message 'Color2 is of sku, not Model.';
  1070.                     array_push($errors$message);
  1071.                 }
  1072.                 if (null != $objects->getColor3Code()) {
  1073.                     $message 'Color3 is of sku, not Model.';
  1074.                     array_push($errors$message);
  1075.                 }
  1076.                 if (null != $objects->getHexColor1()) {
  1077.                     $message 'Hex color1 is of sku, not Model.';
  1078.                     array_push($errors$message);
  1079.                 }
  1080.                 if (null != $objects->getHexColor2()) {
  1081.                     $message 'Hex color2 is of sku, not Model.';
  1082.                     array_push($errors$message);
  1083.                 }
  1084.                 if (null != $objects->getHexColor3()) {
  1085.                     $message 'Hex color3 is of sku, not Model.';
  1086.                     array_push($errors$message);
  1087.                 }
  1088.                 if (null != $objects->getColor1PmsReference()) {
  1089.                     $message 'Color1 PMS is of sku, not Model.';
  1090.                     array_push($errors$message);
  1091.                 }
  1092.                 if (null != $objects->getColor1PmsReference()) {
  1093.                     $message 'Color2 PMS is of sku, not Model.';
  1094.                     array_push($errors$message);
  1095.                 }
  1096.                 if (null != $objects->getColor1PmsReference()) {
  1097.                     $message 'Color3 PMS is of sku, not Model.';
  1098.                     array_push($errors$message);
  1099.                 }
  1100.                 if (null != $objects->getTcxColor1()) {
  1101.                     $message 'TCX color1 is of sku, not Model.';
  1102.                     array_push($errors$message);
  1103.                 }
  1104.                 if (null != $objects->getTcxColor2()) {
  1105.                     $message 'TCX color2 is of sku, not Model.';
  1106.                     array_push($errors$message);
  1107.                 }
  1108.                 if (null != $objects->getTcxColor3()) {
  1109.                     $message 'TCX color3 is of sku, not Model.';
  1110.                     array_push($errors$message);
  1111.                 }
  1112.                 //!Commented on 2023-09-21
  1113.                 //!NOTES: SkipValidation is only being set in a later stage
  1114.                 /*
  1115.                 * When creating a product, it will always throw this error
  1116.                 * because at this stage you cannot add yet a Link Component to the model
  1117.                 */
  1118.                 /*if ($objects->getSkipValidation() == false) {
  1119.                     if ($objects->getConfiguratorType() == 'base_component') {
  1120.                         if (null == $objects->getLinkComponent()) {
  1121.                             $message = 'Link Component is required.';
  1122.                             array_push($errors, $message);
  1123.                         }
  1124.                     }
  1125.                 }*/
  1126.             }
  1127.             if ($objects instanceof DataObject\Product and 'variant' != $objects->gettype()) {
  1128.                 // Fill in unique Product Identifier as ModelCode
  1129.                 if (null != $objects->getModelCode() && $objects->getModelCode() != $objects->getProductIdentifier()) {
  1130.                     $objects->setProductIdentifier($objects->getModelCode());
  1131.                 }
  1132.                 //Model with tier hiearchy
  1133.                 if (null != $objects->getTier3()) {
  1134.                     $this->getProductTierTree($objects);
  1135.                 }
  1136.                 $this->getSustainability($objects);
  1137.             }
  1138.             /**
  1139.              * Further validation is skipped while creating model or item. Otherwise full
  1140.              * validaiton is done based on the attribute matrix provide by PD.
  1141.              * End user wil have force save toggle on the screen to validation and save
  1142.              */
  1143.             if ($objects->getSkipValidation() || $this->getWorkflowStatus($objects) == "mode_create") {
  1144.                 $objects->setSkipValidation(false);
  1145.                 $objects->setOmitMandatoryCheck(true);
  1146.             } else {
  1147.                 /** Based on mandatory setting for model or sku, validation is applied */
  1148.                 if ($objects instanceof DataObject\Product) {
  1149.                     $manAttributes = [];
  1150.                     if ('variant' != $objects->gettype()) {
  1151.                         $settingObject DataObject\SettingAttributes::getBySettingCode('manadatoryModel'1);
  1152.                         if ($settingObject) {
  1153.                             $manAttributes explode(","trim($settingObject->getAttributes()));
  1154.                         }
  1155.                         /** Get the mandatory attributes setup on Tier3 or Tier1 level
  1156.                          */
  1157.                         if ($objects->getTier3()->getMandatoryAttributes()) {
  1158.                             $manProdSpecific explode(","trim($objects->getTier3()->getMandatoryAttributes()));
  1159.                         } else {
  1160.                             $manProdSpecific explode(","trim($objects->getTier1()->getMandatoryAttributes()));
  1161.                         }
  1162.                         $manAttributes array_merge($manAttributes$manProdSpecific);
  1163.                     } else {
  1164.                         $settingObject DataObject\SettingAttributes::getBySettingCode('mandatorySku'1);
  1165.                         if ($settingObject) {
  1166.                             $manAttributes explode(","trim($settingObject->getAttributes()));
  1167.                         }
  1168.                     }
  1169.                     if (is_array($manAttributes)) {
  1170.                         foreach ($manAttributes as $manAttribute) {
  1171.                             if (strlen($manAttribute) > 1) {
  1172.                                 $getattribute 'get' $manAttribute;
  1173.                                 if (null == $objects->$getattribute()) {
  1174.                                     $message $this->getPimMessage($manAttribute);
  1175.                                     if ($message != "") {
  1176.                                         array_push($errors$this->getPimMessage($manAttribute));
  1177.                                     } else {
  1178.                                         array_push($errors$manAttribute " is required.");
  1179.                                     }
  1180.                                 }
  1181.                             }
  1182.                         }
  1183.                     }
  1184.                     if ($objects instanceof DataObject\Product and 'variant' == $objects->gettype()) {
  1185.                         /** Hex Color1 validation */
  1186.                         if ($objects->getHexColor1()) {
  1187.                             if (strlen($objects->getHexColor1()) != 6) {
  1188.                                 $message 'Length of Color1 hex code must be 6.';
  1189.                                 array_push($errors$message);
  1190.                             }
  1191.                         }
  1192.                         /** Hex Color2 validation */
  1193.                         if ($objects->getHexColor2()) {
  1194.                             if (strlen($objects->getHexColor2()) != 6) {
  1195.                                 $message 'Length of Color2 hex code must be 6.';
  1196.                                 array_push($errors$message);
  1197.                             }
  1198.                         }
  1199.                         /** Hex Color3 validation */
  1200.                         if ($objects->getHexColor3()) {
  1201.                             if (strlen($objects->getHexColor3()) != 6) {
  1202.                                 $message 'Length of Color3 hex code must be 6.';
  1203.                                 array_push($errors$message);
  1204.                             }
  1205.                         }
  1206.                         /** update hexColorcode when it is still empty and color2 or color3 is added or updated */
  1207.                         if ($objects->getColor2Code() && $objects->getHexColor2() == null) {
  1208.                             $objects->setHexColor2($objects->getColor2Code()->getHexColor1());
  1209.                         }
  1210.                         /** update hexColorcode when it is still empty and color2 or color3 is added or updated */
  1211.                         if ($objects->getColor3Code() && $objects->getHexColor3() == null) {
  1212.                             $objects->setHexColor3($objects->getColor3Code()->getHexColor1());
  1213.                         }
  1214.                     }
  1215.                 }
  1216.                 /** Base Material 1 exceed 100 */
  1217.                 if ($objects->getBaseMaterial1()) {
  1218.                     foreach ($objects->getBaseMaterial1() as $baseMaterial1) {
  1219.                         $baseMaterial1Object DataObject\MaterialDetail::getById($baseMaterial1->getElementId());
  1220.                         if ($baseMaterial1->getCompositionofmaterial1() != null) {
  1221.                             $baseMaterial1percentage $baseMaterial1percentage $baseMaterial1->getCompositionofmaterial1();
  1222.                         } else {
  1223.                             $message "Base  material 1 [" $baseMaterial1Object->getMaterialDetail() . "] cannot be empty";
  1224.                             array_push($errors$message);
  1225.                         }
  1226.                     }
  1227.                     if ($baseMaterial1percentage != 100) {
  1228.                         $message 'Base  material 1 composition must be 100 %';
  1229.                         array_push($errors$message);
  1230.                     }
  1231.                 }
  1232.                 /** Base Material 2 exceed 100 */
  1233.                 if ($objects->getBaseMaterial2()) {
  1234.                     foreach ($objects->getBaseMaterial2() as $baseMaterial2) {
  1235.                         $baseMaterial2Object DataObject\MaterialDetail::getById($baseMaterial2->getElementId());
  1236.                         if ($baseMaterial2->getCompositionofmaterial2() != null) {
  1237.                             $baseMaterial2percentage $baseMaterial2percentage $baseMaterial2->getCompositionofmaterial2();
  1238.                         } else {
  1239.                             $message "Base  material 2 [" $baseMaterial2Object->getMaterialDetail() . "] cannot be empty";
  1240.                             array_push($errors$message);
  1241.                         }
  1242.                     }
  1243.                     if ($baseMaterial2percentage != 100) {
  1244.                         $message 'Base  material 2 composition must be 100 %';
  1245.                         array_push($errors$message);
  1246.                     }
  1247.                 }
  1248.                 /** Base Material 3 exceed 100 */
  1249.                 if ($objects->getBaseMaterial3()) {
  1250.                     foreach ($objects->getBaseMaterial3() as $baseMaterial3) {
  1251.                         $baseMaterial3Object DataObject\MaterialDetail::getById($baseMaterial3->getElementId());
  1252.                         if ($baseMaterial3->getCompositionofmaterial3() != null) {
  1253.                             $baseMaterial3percentage $baseMaterial3percentage $baseMaterial3->getCompositionofmaterial3();
  1254.                         } else {
  1255.                             $message "Base  material 3 [" $baseMaterial3Object->getMaterialDetail() . "] cannot be empty";
  1256.                             array_push($errors$message);
  1257.                         }
  1258.                     }
  1259.                     if ($baseMaterial3percentage != 100) {
  1260.                         $message 'Base  material 3 composition must be 100 %';
  1261.                         array_push($errors$message);
  1262.                     }
  1263.                 }
  1264.                 if ($objects->getSkipValidation() == false) {
  1265.                     if ($objects->getConfiguratorType() == 'base_component') {
  1266.                         if (null == $objects->getLinkComponent()) {
  1267.                             $message 'Link Component is required.';
  1268.                             array_push($errors$message);
  1269.                         }
  1270.                     }
  1271.                 }
  1272.                 if ('variant' != $objects->gettype()) {
  1273.                     if ($objects->getSkipValidation() == false) {
  1274.                         if ($objects->getConfiguratorType() == 'component') {
  1275.                             if ($objects->getStoreVisibility() != "1" || $objects->getStoreVisibility() != 1) {
  1276.                                 $message 'For the configurator components only “Not display individually” is allowed. Please adjust the Store visibility setting to this required value';
  1277.                                 array_push($errors$message);
  1278.                             }
  1279.                         }
  1280.                     }
  1281.                 }
  1282.             }
  1283.             // throw ExceptionMessage of validation
  1284.             $this->getExceptionMessage($errors$objects);
  1285.             if ($objects instanceof DataObject\Product and 'variant' == $objects->gettype()) {
  1286.                 $errors = [];
  1287.                 // Fill in unique Product Identifier as skuCode
  1288.                 if (null != $objects->getSku() && $objects->getSku() != $objects->getProductIdentifier()) {
  1289.                     $objects->setProductIdentifier($objects->getSku());
  1290.                 }
  1291.                 if ($objects->getOnboardingStatus() == "pafPhase") {
  1292.                     $objects->setDatePafPhase(Carbon::parse($onboaringDate));
  1293.                 } elseif ($objects->getOnboardingStatus() == "preProductionPhase") {
  1294.                     $objects->setDatePreproductionPhase(Carbon::parse($onboaringDate));
  1295.                 } elseif ($objects->getOnboardingStatus() == "productionPhase") {
  1296.                     $objects->setDateProductionPhase(Carbon::parse($onboaringDate));
  1297.                 } elseif ($objects->getOnboardingStatus() == "shippingPhase") {
  1298.                     $objects->setDateShippingPhase(Carbon::parse($onboaringDate));
  1299.                 } elseif ($objects->getOnboardingStatus() == "readyForSale") {
  1300.                     $objects->setDateReadyForSale(Carbon::parse($onboaringDate));
  1301.                 } elseif ($objects->getOnboardingStatus() == "launched") {
  1302.                     $objects->setDateLaunched(Carbon::parse($onboaringDate));
  1303.                 }
  1304.                 // When pfstore status is move to Active, set onboarding status to Launched
  1305. //                if($objects->getPfstoreStatus() == "active" && $objects->getOnboardingStatus() != 'launched' ) {
  1306. //                    $objects->setOnboardingStatus('launched');
  1307. //                }
  1308.             }
  1309.             $this->checkForSubMenuCategory($objects);
  1310.             $this->correctFabricWeight($objects);
  1311.             $this->updateSkuParentModificationDate($objects);
  1312.             if ($user Admin::getCurrentUser()) {
  1313.                 if ($objects->gettype() == 'object') {
  1314.                     $productVaiants $objects->getChildren([\Pimcore\Model\DataObject\AbstractObject::OBJECT_TYPE_VARIANT], true);
  1315.                     foreach ($productVaiants as $productVaiant) {
  1316.                         $productObject DataObject\Product::getById($productVaiant->getId(), ['force'=> true]);
  1317.                         if ($productObject) {
  1318. //                            if ($skipValidation == false || $skipValidation != true) {
  1319.                             $productObject->setSkipValidation(true);
  1320.                             $productObject->setOmitMandatoryCheck(true);
  1321.                             $productObject->setHashDate(strtotime($hastDate));
  1322.                             $productObject->setPublished(true);
  1323.                             $productObject->save();
  1324. //                            }
  1325.                         }
  1326.                     }
  1327. //                    if ($objects->getSkipValidation() == false) {
  1328.                     $objects->setHashDate(strtotime($hastDate));
  1329. //                    }
  1330.                 } else {
  1331. //                    if ($objects->getSkipValidation() == false) {
  1332.                     $objects->setHashDate(strtotime($hastDate));
  1333. //                    }
  1334.                 }
  1335.             }
  1336.         }
  1337.     }
  1338.     public function getPimMessage($messageCode)
  1339.     {
  1340.         $pimMessageObject DataObject\PimMessages::getByMessageCode($messageCode1);
  1341.         if ($pimMessageObject) {
  1342.             return $pimMessageObject->getMessage();
  1343.         } else {
  1344.             return "";
  1345.         }
  1346.     }
  1347.     /**
  1348.      * @param $object
  1349.      * @throws \Exception
  1350.      *
  1351.      * Check for Variant and Update Parent Modification Date only.
  1352.      * Update only when pfstore_status is active and no change today
  1353.      */
  1354.     protected function updateSkuParentModificationDate($object)
  1355.     {
  1356.         if ($object instanceof DataObject\Product && $object->getType() == 'variant') {
  1357.             $parent $object->getParent();
  1358.             if (date("Ymd") != date("Ymd"$parent->getModificationDate()) && $object->getPfstoreStatus() == "active") {
  1359.                 $parent->setModificationDate(Carbon::now()->timestamp);
  1360.                 $parent->setSkipValidation(true);
  1361.                 $parent->save();
  1362.             };
  1363.         }
  1364.     }
  1365.     /**
  1366.      * When product weight is not entered and unit is selected, reset unit to empty to avoid inhertiance issue
  1367.      */
  1368.     protected function correctFabricWeight($object)
  1369.     {
  1370.         if ($object instanceof DataObject\Product) {
  1371.             if (in_array(trim($object->getFabricWeight(), " "), array("g/m2""gauge""gram"))) {
  1372.                 $object->setFabricWeight(null);
  1373.             }
  1374.             if (in_array(trim($object->getFabricWeight2(), " "), array("g/m2""gauge""gram"))) {
  1375.                 $object->setFabricWeight2(null);
  1376.             }
  1377.             if (in_array(trim($object->getFabricWeight3(), " "), array("g/m2""gauge""gram"))) {
  1378.                 $object->setFabricWeight3(null);
  1379.             }
  1380.         }
  1381.     }
  1382.     /**
  1383.      * @param $objects
  1384.      * @throws ValidationException
  1385.      */
  1386.     private function checkForSubMenuCategory($objects)
  1387.     {
  1388.         $menuSub = new DataObject\MenuCategory\Listing();
  1389.         $menuChild $menuSub->getObjects();
  1390.         if ($objects->getDefaultSubCategory()) {
  1391.             foreach ($menuChild as $child) {
  1392.                 if ($objects->getDefaultSubCategory()->getChildren() == true) {
  1393.                     $message[] = "You have selected a menu category. Please select a sub-menucategory";
  1394.                     $this->getExceptionMessage($message$child);
  1395.                 }
  1396.             }
  1397.         }
  1398.     }
  1399.     public function getSustainability($objects)
  1400.     {
  1401.         $sustainabilityTotalScore 0;
  1402.         if (!empty($objects->getSustainablity()->getSustainabilityRanking()) || ($objects->getSustainablity()->getSustainabilityRanking() != null || $objects->getSustainablity()->getSustainabilityRanking() != "")) {
  1403.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getMaterials50pctinformation()) || $objects->getSustainablity()->getSustainabilityRanking()->getMaterials50pctinformation() == null || $objects->getSustainablity()->getSustainabilityRanking()->getMaterials50pctinformation() == "") {
  1404.                 $materialsScoreTotal "No score set!";
  1405.             } else {
  1406.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('materials50pct''1');
  1407.                 $materialsScoreTotal $objects->getSustainablity()->getSustainabilityRanking()->getMaterials50pctinformation()->getSustainableMaterialInformationScore() * $sustainabilitySettings->getWeight();
  1408.                 $sustainabilityTotalScore $materialsScoreTotal;
  1409.             }
  1410.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getEndoflifeInformation())  || $objects->getSustainablity()->getSustainabilityRanking()->getEndoflifeInformation() == null || $objects->getSustainablity()->getSustainabilityRanking()->getEndoflifeInformation() == "") {
  1411.                 $endOfLifeProductLevelScoreTotal "No score set!";
  1412.             } else {
  1413.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('endOfLifeProductLevel''1');
  1414.                 $endOfLifeProductLevelScoreTotal $objects->getSustainablity()->getSustainabilityRanking()->getEndoflifeInformation()->getEndOfLifeInformationScore() * $sustainabilitySettings->getWeight();
  1415.                 $sustainabilityTotalScore $sustainabilityTotalScore $endOfLifeProductLevelScoreTotal;
  1416.             }
  1417.             if ($objects->getCountryOfOrigin() == null || empty($objects->getCountryOfOrigin()) || $objects->getCountryOfOrigin()->getEpiScore() == null || $objects->getCountryOfOrigin()->getEpiScore() == "") {
  1418.                 $productionEpiScoreTotal "No score set!";
  1419.             } else {
  1420.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('productionEpi''1');
  1421.                 $productionEpiScoreTotal $objects->getCountryOfOrigin()->getEpiScore() * $sustainabilitySettings->getWeight();
  1422.                 $sustainabilityTotalScore $sustainabilityTotalScore $productionEpiScoreTotal;
  1423.             }
  1424.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getCertificationsEnvironmental()) || $objects->getSustainablity()->getSustainabilityRanking()->getCertificationsEnvironmental() == null || $objects->getSustainablity()->getSustainabilityRanking()->getCertificationsEnvironmental() == "") {
  1425.                 $certificationEnvironmentScoreTotal "No score set!";
  1426.             } else {
  1427.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('certificationEnvironment''1');
  1428.                 $certificationMaxScore $this->getCertificationData($objects'certificationsEnvironmental''certificationEnvironmentalScore');
  1429.                 $certificationEnvironmentScoreTotal $certificationMaxScore $sustainabilitySettings->getWeight();
  1430.                 $sustainabilityTotalScore $sustainabilityTotalScore $certificationEnvironmentScoreTotal;
  1431.             }
  1432.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getCertificationsSocial()) || $objects->getSustainablity()->getSustainabilityRanking()->getCertificationsSocial() == null || $objects->getSustainablity()->getSustainabilityRanking()->getCertificationsSocial() == "") {
  1433.                 $certificationSocialScoreTotal "No score set!";
  1434.             } else {
  1435.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('certificationSocial''1');
  1436.                 $certificationSocialMaxScore $this->getCertificationData($objects'certificationsSocial''certificationSocialScore');
  1437.                 $certificationSocialScoreTotal $certificationSocialMaxScore $sustainabilitySettings->getWeight();
  1438.                 $sustainabilityTotalScore $sustainabilityTotalScore $certificationSocialScoreTotal;
  1439.             }
  1440.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getSustainableBranding()) || $objects->getSustainablity()->getSustainabilityRanking()->getSustainableBranding() == null || $objects->getSustainablity()->getSustainabilityRanking()->getSustainableBranding() == "") {
  1441.                 $sustainabilityBrandingScoreTotal "No score set!";
  1442.             } else {
  1443.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('sustainabilityBranding''1');
  1444.                 $sustainabilityMaxScore $this->getCertificationData($objects'sustainableBranding''sustainableBrandingScore');
  1445.                 $sustainabilityBrandingScoreTotal $sustainabilityMaxScore $sustainabilitySettings->getWeight();
  1446.                 $sustainabilityTotalScore $sustainabilityTotalScore $sustainabilityBrandingScoreTotal;
  1447.             }
  1448.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getPackaging50pctinformation()) || $objects->getSustainablity()->getSustainabilityRanking()->getPackaging50pctinformation() == null || $objects->getSustainablity()->getSustainabilityRanking()->getPackaging50pctinformation() == "") {
  1449.                 $packagingScoreTotal "No score set!";
  1450.             } else {
  1451.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('packaging50pct''1');
  1452.                 $packagingScoreTotal $objects->getSustainablity()->getSustainabilityRanking()->getPackaging50pctinformation()->getSustainablePackagingInformationScore() * $sustainabilitySettings->getWeight();
  1453.                 $sustainabilityTotalScore $sustainabilityTotalScore $packagingScoreTotal;
  1454.             }
  1455.             if (empty($objects->getSustainablity()->getSustainabilityRanking()->getTraceableSupplyChainInformation())  || $objects->getSustainablity()->getSustainabilityRanking()->getTraceableSupplyChainInformation() == null || $objects->getSustainablity()->getSustainabilityRanking()->getTraceableSupplyChainInformation() == "") {
  1456.                 $traceableSupplyChainScoreTotal "No score set!";
  1457.             } else {
  1458.                 $sustainabilitySettings DataObject\SustainabilitySettings::getByCode('traceableSupplyChain''1');
  1459.                 $traceableSupplyChainScoreTotal $objects->getSustainablity()->getSustainabilityRanking()->getTraceableSupplyChainInformation()->getTraceableSupplyChainInformationScore() * $sustainabilitySettings->getWeight();
  1460.                 $sustainabilityTotalScore $sustainabilityTotalScore $traceableSupplyChainScoreTotal;
  1461.             }
  1462.             if ($sustainabilityTotalScore 25) {
  1463.                 $rankingLabel "0 to 24";
  1464.                 $collectionLabel null;
  1465.             } elseif ($sustainabilityTotalScore >= 25 && $sustainabilityTotalScore <= 49) {
  1466.                 $rankingLabel "25 to 49";
  1467.                 $collectionLabel 'greenConcept';
  1468.             } elseif ($sustainabilityTotalScore >= 50 && $sustainabilityTotalScore <= 74) {
  1469.                 $rankingLabel "50 to 74";
  1470.                 $collectionLabel 'greenConcept';
  1471.             } elseif ($sustainabilityTotalScore >= 75) {
  1472.                 $rankingLabel "75 to 100";
  1473.                 $collectionLabel 'greenConcept';
  1474.             } else {
  1475.                 $rankingLabel "0 to 24";
  1476.                 $collectionLabel '';
  1477.             }
  1478.             if (empty($objects->getCollectionLabel()) || $objects->getCollectionLabel() == "" || $objects->getCollectionLabel() == null) {
  1479.                 $collectionLabelValue array_filter(array_unique(array_merge([$objects->getCollectionLabel()], [$collectionLabel])));
  1480.             } else {
  1481.                 $collectionLabelValue array_filter(array_unique(array_merge($objects->getCollectionLabel(), [$collectionLabel])));
  1482.             }
  1483.             if($objects->getCountryOfOrigin() != null || $objects->getCountryOfOrigin() != "" || !empty($objects->getCountryOfOrigin())) {
  1484.                 if ($objects->getCountryOfOrigin()->getCountryName() == 'PRC') {
  1485.                     $objects->getSustainablity()->getSustainabilityRanking()->setCountryOfOriginInformation('China');
  1486.                 } else {
  1487.                     $lowerCase strtolower($objects->getCountryOfOrigin()->getCountryName());
  1488.                     $objects->getSustainablity()->getSustainabilityRanking()->setCountryOfOriginInformation(ucfirst($lowerCase));
  1489.                 }
  1490.             }
  1491.             $objects->getSustainablity()->getSustainabilityRanking()->setMaterialsScoreTotal($materialsScoreTotal);
  1492.             $objects->getSustainablity()->getSustainabilityRanking()->setEndOfLifeProductLevelScoreTotal($endOfLifeProductLevelScoreTotal);
  1493.             $objects->getSustainablity()->getSustainabilityRanking()->setProductionEpiScoreTotal($productionEpiScoreTotal);
  1494.             $objects->getSustainablity()->getSustainabilityRanking()->setCertificationEnvironmentScoreTotal($certificationEnvironmentScoreTotal);
  1495.             $objects->getSustainablity()->getSustainabilityRanking()->setCertificationSocialScoreTotal($certificationSocialScoreTotal);
  1496.             $objects->getSustainablity()->getSustainabilityRanking()->setSustainabilityBrandingScoreTotal($sustainabilityBrandingScoreTotal);
  1497.             $objects->getSustainablity()->getSustainabilityRanking()->setPackagingScoreTotal($packagingScoreTotal);
  1498.             $objects->getSustainablity()->getSustainabilityRanking()->setTraceableSupplyChainScoreTotal($traceableSupplyChainScoreTotal);
  1499.             $objects->getSustainablity()->getSustainabilityRanking()->setSustainabilityTotalScore($sustainabilityTotalScore);
  1500.             $objects->getSustainablity()->getSustainabilityRanking()->setRankingLabel($rankingLabel);
  1501.             $objects->getSustainablity()->getSustainabilityRanking()->setCollectionLabel($collectionLabel);
  1502.             $objects->setCollectionLabel($collectionLabelValue);
  1503.         }
  1504.     }
  1505.     private function getCertificationData($object$relationName$score)
  1506.     {
  1507.         $relationName 'get' ucfirst($relationName);
  1508.         $score 'get' ucfirst($score);
  1509.         $allScore = [];
  1510.         if($object->getSustainablity()->getSustainabilityRanking()->$relationName() != null || !empty($object->getSustainablity()->getSustainabilityRanking()->$relationName())) {
  1511.             $scoreData $object->getSustainablity()->getSustainabilityRanking()->$relationName();
  1512.             foreach ($scoreData as $scores) {
  1513.                 array_push($allScore$scores->$score());
  1514.             }
  1515.             $maxValue max($allScore);
  1516.             return $maxValue;
  1517.         }
  1518.         return 0;
  1519.     }
  1520.     /**
  1521.      * @param GenericEvent $objectBrickDefinitionGenericEvent
  1522.      * @throws \Exception
  1523.      */
  1524.     public function generatePfAttributeDefinition(GenericEvent $objectBrickDefinitionGenericEvent)
  1525.     {
  1526.         $folderId $this->createFolder(self::FOLDER_NAME);
  1527.         $objects $objectBrickDefinitionGenericEvent->getArguments();
  1528.         foreach ($objects as $object) {
  1529.             foreach (($object) as $brick) {
  1530.                 $objectBrickObjects json_decode(json_encode($object), true);
  1531.                 if ($objectBrickObjects['key'] != null || $objectBrickObjects['key'] != "") {
  1532.                     if ($objectBrickObjects['layoutDefinitions'] != null || $objectBrickObjects['layoutDefinitions'] != "") {
  1533.                         if (($objectBrickObjects['layoutDefinitions']['children'])) {
  1534.                             foreach ($objectBrickObjects['layoutDefinitions']['children'] as $layoutDefinition) {
  1535.                                 if ($layoutDefinition['children']) {
  1536.                                     $optionName null;
  1537.                                     //attribute child to import in Pf Attribute classes
  1538.                                     foreach ($layoutDefinition['children'] as $valueClass) {
  1539.                                         $optionValue = [];
  1540.                                         $attributeChildValuesObject = [];
  1541.                                         $optionName $valueClass['name'];
  1542.                                         if ($valueClass['fieldtype'] == "select" || $valueClass['fieldtype'] == "multiselect") {
  1543.                                             if ($valueClass['options']) {
  1544.                                                 foreach ($valueClass['options'] as $options) {
  1545.                                                     $optionValue[] = $options['value'];
  1546.                                                 }
  1547.                                             }
  1548.                                             $attributeChildValuesObject $this->associateAttributeValue($optionValue$folderId$objectBrickObjects['key']);
  1549.                                             $this->associatePfAttribute($valueClass['name'], $attributeChildValuesObject$objectBrickObjects['key'],$valueClass['fieldtype']);
  1550.                                         } else {
  1551.                                             $attributeChildValuesObject $this->associateAttributeValue(array($valueClass['name']), $folderId$objectBrickObjects['key']);
  1552.                                             $this->associatePfAttribute($valueClass['name'], $attributeChildValuesObject$objectBrickObjects['key'],$valueClass['fieldtype']);
  1553.                                         }
  1554.                                     }
  1555.                                 }
  1556.                             }
  1557.                         }
  1558.                     }
  1559.                 }
  1560.             }
  1561.         }
  1562.     }
  1563.     /**
  1564.      * @param $attributeValues
  1565.      * @return array
  1566.      * @throws \Exception
  1567.      */
  1568.     public function associateAttributeValue($attributeValues$folderId$dynamicFolderName)
  1569.     {
  1570.         $attributeObjectValues = [];
  1571.         $dynamicFolderId $this->createFolder($dynamicFolderName$folderId);
  1572.         $valueFolderId=$this->createFolderself::FOLDER_NAME_ATTRIBUTEVALUE$dynamicFolderId);
  1573. //        $folderId = $this->createFolder(self::FOLDER_INSIDE_ATTRIBUTEVALUE, $this->createFolder(self::FOLDER_INSIDE_FOLDER));
  1574.         foreach ($attributeValues as $attributeValue) {
  1575.             $attributeValueObject DataObject\AttributeValue::getByCode($attributeValue1);
  1576.             $key strtolower($attributeValue);
  1577.             if (!$attributeValueObject) {
  1578.                 $attributeValueObject = new DataObject\AttributeValue();
  1579.                 $attributeValueObject->setCode($attributeValue);
  1580.                 $attributeValueObject->setKey($key);
  1581.                 $attributeValueObject->setParentId($valueFolderId);
  1582.             }
  1583. //            $attributeValueObject->setName($attributeValue);
  1584.             $attributeValueObject->setPublished(true);
  1585.             $attributeValueObject->save();
  1586.             $attributeObjectValues[$attributeValue] = $attributeValueObject;
  1587.         }
  1588.         return $attributeObjectValues;
  1589.     }
  1590.     /**
  1591.      * @param $attributes
  1592.      * @param $attributeValueObject
  1593.      * @throws \Exception
  1594.      */
  1595.     public function associatePfAttribute($attributes$attributeValueObject$dynamicFolderId$fieldtype)
  1596.     {
  1597.         $createDynamicFolderId $this->createFolder($dynamicFolderId$this->createFolder(self::FOLDER_NAME));
  1598.         $folderId $this->createFolder(self::FOLDER_NAME_PFATTRIBUTE$createDynamicFolderId);
  1599.         foreach (array($attributes) as $attribute) {
  1600.             $attributeObject DataObject\AttributeName::getByCode($attribute1);
  1601.             $key strtolower($attribute);
  1602.             if (!$attributeObject) {
  1603.                 $attributeObject = new DataObject\AttributeName();
  1604.                 $attributeObject->setCode($attribute);
  1605.                 $attributeObject->setKey($key);
  1606.                 $attributeObject->setParentId($folderId);
  1607.             }
  1608.                $attributeObject->setFieldType($fieldtype);
  1609.             $attributeObject->setLinkedAttributeValue($attributeValueObject);
  1610.             $attributeObject->setPublished(true);
  1611.             $attributeObject->save();
  1612.         }
  1613.     }
  1614. }