private function _expandTree($data)
 {
     $req = new DownlineSnapExtendMinimalRequest();
     $req->setKeyCustomerId(Compress::ATTR_CUSTOMER_ID);
     $req->setKeyParentId(Compress::ATTR_PARENT_ID);
     $req->setTree($data);
     $resp = $this->_callDownlineSnap->expandMinimal($req);
     return $resp->getSnapData();
 }
 private function _mapCustomersMlmId()
 {
     $result = [];
     /* create minimal tree based on MLM IDs */
     $treeOnMlmIds = [];
     foreach ($this->_mapCsvDownline as $one) {
         $mlmId = $one[self::A_CUST_ID];
         $parentMlmId = $one[self::A_PARENT_ID];
         $treeOnMlmIds[$mlmId] = $parentMlmId;
     }
     /* expand minimal tree: populate tree with depth & path */
     $reqExpand = new SnapExtendMinimalRequest();
     $reqExpand->setTree($treeOnMlmIds);
     $respExpand = $this->_callDownlineSnap->expandMinimal($reqExpand);
     $mapTree = $respExpand->getSnapData();
     /* create tree map sorted by level from top to bottom */
     $mapByDepthAsc = $this->_mapTreeByDepth($mapTree, Snap::ATTR_CUSTOMER_ID, Snap::ATTR_DEPTH);
     /* map MLM IDs and indexes */
     $ndx = 1;
     foreach ($mapByDepthAsc as $level => $ids) {
         foreach ($ids as $mlmId) {
             $this->_mapCustomerIndexByMlmId[$mlmId] = $ndx;
             $this->_mapCustomerMlmIdByIndex[$ndx] = $mlmId;
             $ndx++;
         }
     }
     /* create tree based on Mage IDs using original MLM IDs data and indexes */
     foreach ($this->_mapCsvDownline as $one) {
         $mlmId = $one[self::A_CUST_ID];
         $parentMlmId = $one[self::A_PARENT_ID];
         $custNdx = $this->_mapCustomerIndexByMlmId[$mlmId];
         $parentNdx = isset($this->_mapCustomerIndexByMlmId[$parentMlmId]) ? $this->_mapCustomerIndexByMlmId[$parentMlmId] : null;
         if (is_null($parentNdx)) {
             /* this is orphan */
             $parentNdx = $custNdx;
         }
         $custId = $this->_mapCustomerMageIdByIndex[$custNdx];
         $parentId = $this->_mapCustomerMageIdByIndex[$parentNdx];
         $result[$custId] = $parentId;
     }
     return $result;
 }
 private function _setCompressedPtc()
 {
     $data = [[PtcCompression::ATTR_CUSTOMER_ID => 1, PtcCompression::ATTR_PARENT_ID => 1, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 2, PtcCompression::ATTR_PARENT_ID => 1, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 4550], [PtcCompression::ATTR_CUSTOMER_ID => 3, PtcCompression::ATTR_PARENT_ID => 1, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 3755], [PtcCompression::ATTR_CUSTOMER_ID => 4, PtcCompression::ATTR_PARENT_ID => 1, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 2255], [PtcCompression::ATTR_CUSTOMER_ID => 5, PtcCompression::ATTR_PARENT_ID => 3, PtcCompression::ATTR_PV => 40, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 6, PtcCompression::ATTR_PARENT_ID => 3, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 7, PtcCompression::ATTR_PARENT_ID => 3, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 8, PtcCompression::ATTR_PARENT_ID => 5, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 9, PtcCompression::ATTR_PARENT_ID => 6, PtcCompression::ATTR_PV => 40, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 10, PtcCompression::ATTR_PARENT_ID => 9, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 11, PtcCompression::ATTR_PARENT_ID => 10, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 12, PtcCompression::ATTR_PARENT_ID => 10, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 13, PtcCompression::ATTR_PARENT_ID => 10, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 14, PtcCompression::ATTR_PARENT_ID => 11, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 15, PtcCompression::ATTR_PARENT_ID => 11, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 16, PtcCompression::ATTR_PARENT_ID => 12, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 17, PtcCompression::ATTR_PARENT_ID => 12, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 18, PtcCompression::ATTR_PARENT_ID => 13, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 19, PtcCompression::ATTR_PARENT_ID => 13, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 800, PtcCompression::ATTR_OV => 800], [PtcCompression::ATTR_CUSTOMER_ID => 20, PtcCompression::ATTR_PARENT_ID => 13, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 900, PtcCompression::ATTR_OV => 900], [PtcCompression::ATTR_CUSTOMER_ID => 21, PtcCompression::ATTR_PARENT_ID => 14, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 22, PtcCompression::ATTR_PARENT_ID => 15, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 23, PtcCompression::ATTR_PARENT_ID => 16, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 24, PtcCompression::ATTR_PARENT_ID => 17, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750], [PtcCompression::ATTR_CUSTOMER_ID => 25, PtcCompression::ATTR_PARENT_ID => 18, PtcCompression::ATTR_PV => 100, PtcCompression::ATTR_TV => 750, PtcCompression::ATTR_OV => 750]];
     /* replace customer indexes by Magento IDs */
     $tree = [];
     // tree data as [$custId => $parentId, ...]
     foreach ($data as $key => $one) {
         $custNdx = $one[PtcCompression::ATTR_CUSTOMER_ID];
         $parentNdx = $one[PtcCompression::ATTR_PARENT_ID];
         $custId = $this->_mapCustomerMageIdByIndex[$custNdx];
         $parentId = $this->_mapCustomerMageIdByIndex[$parentNdx];
         $data[$key][PtcCompression::ATTR_CUSTOMER_ID] = $custId;
         $data[$key][PtcCompression::ATTR_PARENT_ID] = $parentId;
         $tree[$custId] = $parentId;
     }
     /* populate tree with depth & path */
     $reqExtend = new SnapExtendMinimalRequest();
     $reqExtend->setTree($tree);
     $respExtend = $this->_callDownlineSnap->expandMinimal($reqExtend);
     $snap = $respExtend->getSnapData();
     // [$custId=>[...], ...]
     /* populate initial data with depth & path */
     foreach ($data as $key => $one) {
         $custId = $one[PtcCompression::ATTR_CUSTOMER_ID];
         $snapEntry = $snap[$custId];
         $data[$key][PtcCompression::ATTR_DEPTH] = $snapEntry[Snap::ATTR_DEPTH];
         $data[$key][PtcCompression::ATTR_PATH] = $snapEntry[Snap::ATTR_PATH];
     }
     /* save data into DB */
     foreach ($data as $one) {
         $one[PtcCompression::ATTR_CALC_ID] = $this->_testCalcIdPtc;
         $this->_repoBasic->addEntity(PtcCompression::ENTITY_NAME, $one);
     }
     $this->_logger->debug("PTC compression data is set.");
 }
 /**
  * Populate data with depth & path values.
  *
  * @param $data array of customer data with customer ID & parent ID
  * @param $labelCustomerId string label for customerId
  * @param $labelParentId string label for parentId
  *
  * @return array Downline Snap: [ $custId => [customer_id, depth, parent_id, path], ...]
  */
 private function _getExpandedTreeSnap($data, $labelCustomerId, $labelParentId)
 {
     /* populate compressed data with depth & path values */
     $tree = [];
     foreach ($data as $one) {
         $custId = $one[$labelCustomerId];
         $parentId = $one[$labelParentId];
         $tree[$custId] = $parentId;
     }
     $reqExt = new DownlineSnapExtendMinimalRequest();
     $reqExt->setTree($tree);
     $respExt = $this->_callDownlineSnap->expandMinimal($reqExt);
     $result = $respExt->getSnapData();
     return $result;
 }