<commit_before><?php
/**
 * User: <NAME> <<EMAIL>>
 */

namespace Praxigento\BonusHybrid\Web\Dcp\Report;

use Praxigento\BonusBase\Repo\Query\Period\Calcs\GetLast\ByCalcTypeCode\Builder as QBLastCalc;
use Praxigento\BonusHybrid\Config as Cfg;
use Praxigento\BonusHybrid\Repo\Query\Dcp\Report\Downline\Builder as QBDownline;

class Downline
    extends \Praxigento\Core\App\Api\Web\Processor\WithQuery
    implements \Praxigento\BonusHybrid\Api\Web\Dcp\Report\DownlineInterface
{
    /**
     * Types of the requested report.
     */
    const REPORT_TYPE_COMPLETE = 'complete';
    const REPORT_TYPE_COMPRESSED = 'compressed';

    /**
     * Name of the local context variables.
     */
    const VAR_CALC_ID = 'calcId';
    const VAR_CUST_ID = 'custId';
    const VAR_CUST_PATH = 'path';

    /** @var \Praxigento\Core\App\Api\Web\IAuthenticator */
    private $authenticator;
    /** @var \Praxigento\Core\Tool\IPeriod */
    private $hlpPeriod;
    /** @var \Praxigento\BonusHybrid\Repo\Query\Dcp\Report\Downline\Builder */
    private $qbDownline;
    /** @var \Praxigento\BonusBase\Repo\Query\Period\Calcs\GetLast\ByCalcTypeCode\Builder */
    private $qbLastCalc;
    /** @var \Praxigento\Downline\Repo\Entity\Snap */
    private $repoSnap;

    public function __construct(
        \Magento\Framework\ObjectManagerInterface $manObj,
        \Praxigento\Core\App\Api\Web\IAuthenticator $authenticator,
        \Praxigento\Core\Helper\Config $hlpCfg,
        \Praxigento\Core\Tool\IPeriod $hlpPeriod,
        \Praxigento\Downline\Repo\Entity\Snap $repoSnap,
        \Praxigento\BonusBase\Repo\Query\Period\Calcs\GetLast\ByCalcTypeCode\Builder $qbLastCalc,
        \Praxigento\BonusHybrid\Repo\Query\Dcp\Report\Downline\Builder $qbDownline
    )
    {
        /* don't pass query builder to the parent - we have 4 builders in the operation, not one */
        parent::__construct($manObj, null, $hlpCfg);
        $this->authenticator = $authenticator;
        $this->hlpPeriod = $hlpPeriod;
        $this->repoSnap = $repoSnap;
        $this->qbDownline = $qbDownline;
        $this->qbLastCalc = $qbLastCalc;
    }

    protected function authorize(\Praxigento\Core\Data $ctx)
    {
        /* do nothing - in Production Mode current customer's ID is used as root customer ID */
    }

    protected function createQuerySelect(\Praxigento\Core\Data $ctx)
    {
        $query = $this->qbDownline->build();
        $ctx->set(self::CTX_QUERY, $query);
    }

    public function exec(\Praxigento\BonusHybrid\Api\Web\Dcp\Report\Downline\Request $request)
    {
        $result = parent::process($request);
        return $result;
    }

    /**
     * Get complete calculation ID for given date by calculation type code.
     *
     * @param $calcTypeCode
     * @param $dateEnd
     * @return mixed
     */
    private function getCalcId($calcTypeCode, $dateEnd)
    {
        $query = $this->qbLastCalc->build();
        $bind = [
            QBLastCalc::BND_CODE => $calcTypeCode,
            QBLastCalc::BND_DATE => $dateEnd,
            QBLastCalc::BND_STATE => Cfg::CALC_STATE_COMPLETE
        ];

        /* fetch & parse data */
        $conn = $query->getConnection();
        $rs = $conn->fetchRow($query, $bind);
        $result = $rs[QBLastCalc::A_CALC_ID];
        return $result;
    }

    protected function populateQuery(\Praxigento\Core\Data $ctx)
    {
        /* get working vars from context */
        /** @var \Praxigento\Core\Data $bind */
        $bind = $ctx->get(self::CTX_BIND);
        /** @var \Praxigento\Core\Data $vars */
        $vars = $ctx->get(self::CTX_VARS);

        /* get working vars */
        $rootCustId = $vars->get(self::VAR_CUST_ID);
        $rootPath = $vars->get(self::VAR_CUST_PATH);
        $calcRef = $vars->get(self::VAR_CALC_ID);
        $path = $rootPath . $rootCustId . Cfg::DTPS . '%';

        /* bind values for query parameters */
        $bind->set(QBDownline::BND_CALC_ID, $calcRef);
        $bind->set(QBDownline::BND_PATH, $path);
        $bind->set(QBDownline::BND_CUST_ID, $rootCustId);
    }


    protected function prepareQueryParameters(\Praxigento\Core\Data $ctx)
    {
        /* get working vars from context */
        /** @var \Praxigento\Core\Data $vars */
        $vars = $ctx->get(self::CTX_VARS);
        /** @var \Praxigento\BonusHybrid\Api\Web\Dcp\Report\Downline\Request $req */
        $req = $ctx->get(self::CTX_REQ);

        /* extract HTTP request parameters */
        $period = $req->getPeriod();
        $rootCustId = $req->getRootCustId();
        $reqType = $req->getType();

        /**
         * Define period.
         */
        if (!$period) {
            /* CAUTION: this code will be failed after 2999 year. Please, call to the author in this case. */
            $period = '2999';
        }
        $period = $this->hlpPeriod->getPeriodLastDate($period);

        /**
         * Define root customer & path to the root customer on the date.
         */
        $isLiveMode = !$this->hlpCfg->getApiAuthenticationEnabledDevMode();
        if (is_null($rootCustId) || $isLiveMode) {
            $rootCustId = $this->authenticator->getCurrentCustomerId();
        }
        $customerRoot = $this->repoSnap->getByCustomerIdOnDate($rootCustId, $period);
        $path = $customerRoot->getPath();

        /**<commit_msg>MOBI-1033 Fix path & root's parent in downline web-service<commit_after><?php
/**
 * User: <NAME> <<EMAIL>>
 */

namespace Praxigento\BonusHybrid\Web\Dcp\Report;

use Praxigento\BonusBase\Repo\Query\Period\Calcs\GetLast\ByCalcTypeCode\Builder as QBLastCalc;
use Praxigento\BonusHybrid\Config as Cfg;
use Praxigento\BonusHybrid\Repo\Query\Dcp\Report\Downline\Builder as QBDownline;

class Downline
    extends \Praxigento\Core\App\Api\Web\Processor\WithQuery
    implements \Praxigento\BonusHybrid\Api\Web\Dcp\Report\DownlineInterface
{
    /**
     * Types of the requested report.
     */
    const REPORT_TYPE_COMPLETE = 'complete';
    const REPORT_TYPE_COMPRESSED = 'compressed';

    /**
     * Name of the local context variables.
     */
    const VAR_CALC_ID = 'calcId';
    const VAR_CUST_ID = 'custId';
    const VAR_CUST_PATH = 'path';

    /** @var \Praxigento\Core\App\Api\Web\IAuthenticator */
    private $authenticator;
    /** @var \Praxigento\Core\Tool\IPeriod */
    private $hlpPeriod;
    /** @var \Praxigento\BonusHybrid\Repo\Query\Dcp\Report\Downline\Builder */
    private $qbDownline;
    /** @var \Praxigento\BonusBase\Repo\Query\Period\Calcs\GetLast\ByCalcTypeCode\Builder */
    private $qbLastCalc;
    /** @var \Praxigento\Downline\Repo\Entity\Snap */
    private $repoSnap;

    public function __construct(
        \Magento\Framework\ObjectManagerInterface $manObj,
        \Praxigento\Core\App\Api\Web\IAuthenticator $authenticator,
        \Praxigento\Core\Helper\Config $hlpCfg,
        \Praxigento\Core\Tool\IPeriod $hlpPeriod,
        \Praxigento\Downline\Repo\Entity\Snap $repoSnap,
        \Praxigento\BonusBase\Repo\Query\Period\Calcs\GetLast\ByCalcTypeCode\Builder $qbLastCalc,
        \Praxigento\BonusHybrid\Repo\Query\Dcp\Report\Downline\Builder $qbDownline
    ) {
        /* don't pass query builder to the parent - we have 4 builders in the operation, not one */
        parent::__construct($manObj, null, $hlpCfg);
        $this->authenticator = $authenticator;
        $this->hlpPeriod = $hlpPeriod;
        $this->repoSnap = $repoSnap;
        $this->qbDownline = $qbDownline;
        $this->qbLastCalc = $qbLastCalc;
    }

    protected function authorize(\Praxigento\Core\Data $ctx) {
        /* do nothing - in Production Mode current customer's ID is used as root customer ID */
    }

    protected function createQuerySelect(\Praxigento\Core\Data $ctx) {
        $query = $this->qbDownline->build();
        $ctx->set(self::CTX_QUERY, $query);
    }

    public function exec(\Praxigento\BonusHybrid\Api\Web\Dcp\Report\Downline\Request $request) {
        $result = parent::process($request);
        return $result;
    }

    /**
     * Get complete calculation ID for given date by calculation type code.
     *
     * @param $calcTypeCode
     * @param $dateEnd
     * @return mixed
     */
    private function getCalcId($calcTypeCode, $dateEnd) {
        $query = $this->qbLastCalc->build();
        $bind = [
            QBLastCalc::BND_CODE => $calcTypeCode,
            QBLastCalc::BND_DATE => $dateEnd,
            QBLastCalc::BND_STATE => Cfg::CALC_STATE_COMPLETE
        ];

        /* fetch & parse data */
        $conn = $query->getConnection();
        $rs = $conn->fetchRow($query, $bind);
        $result = $rs[QBLastCalc::A_CALC_ID];
        return $result;
    }

    protected function performQuery(\Praxigento\Core\Data $ctx) {
        parent::performQuery($ctx);
        /* MOBI-1033 */
        $vars = $ctx->get(self::CTX_VARS);
        $raw = $ctx->get(self::CTX_RESULT);
        $rootId = $vars->get(self::VAR_CUST_ID);
        $rootPath = $vars->get(self::VAR_CUST_PATH);
        $result = [];
        foreach ($raw as $item) {
            $custId = $item[QBDownline::A_CUSTOMER_REF];
            $path = $item[QBDownline::A_PATH];
            if ($custId == $rootId) {
                /* set parent ID for the root */
                $item[QBDownline::A_PARENT_REF] = $custId;
            }
            /* shrink path */
            $shrinked = str_replace($rootPath, '', $path);
            $item[QBDownline::A_PATH] = $shrinked;
            $result[] = $item;
        }
        $ctx->set(self::CTX_RESULT, $result);
    }

    protected function populateQuery(\Praxigento\Core\Data $ctx) {
        /* get working vars from context */
        /** @var \Praxigento\Core\Data $bind */
        $bind = $ctx->get(self::CTX_BIND);
        /** @var \Praxigento\Core\Data $vars */
        $vars = $ctx->get(self::CTX_VARS);

        /* get working vars */
        $rootCustId = $vars->get(self::VAR_CUST_ID);
        $rootPath = $vars->get(self::VAR_CUST_PATH);
        $calcRef = $vars->get(self::VAR_CALC_ID);
        $path = $rootPath . $rootCustId . Cfg::DTPS . '%';

        /* bind values for query parameters */
        $bind->set(QBDownline::BND_CALC_ID, $calcRef);
        $bind->set(QBDownline::BND_PATH, $path);
        $bind->set(QBDownline::BND_CUST_ID, $rootCustId);
    }

    protected function prepareQueryParameters(\Praxigento\Core\Data $ctx) {
        /* get working vars from context */
        /** @var \Praxigento\Core\Data $vars */
        $vars = $ctx->get(self::CTX_VARS);
        /** @var \Praxigento\BonusHybrid\Api\Web\Dcp\Report\Downline\Request $req */
        $req = $ctx->get(self::CTX_REQ);
        /** @var \Praxigento\BonusHybrid\Api\Web\Dcp\Report\Downline\Request\Data $req */
        $reqData = $req->getData();
        /** @var \Praxigento\Core\App\Api\Web\Request\Dev $reqDev */
        $reqDev = $req->getDev();
        /* extract HTTP request parameters */
        $period = $reqData->getPeriod();
        $reqType = $reqData->getType();
        $rootCustId = $reqDev->getCustId();

        /**
         * Define period.
         */
        if (!$period) {
            /* CAUTION: this code will be failed after 2999 year. Please, call to the author in this case. */
            $period = '2999';
        }
        $period = $this->hlpPeriod->getPeriodLastDate($period);

        /**
         * Define root customer & path to the root customer on the date.
         */
        $isLiveMode = !$this->hlpCfg->getApiAuthenticationEnabledDevMode();
        if (is_null($rootCustId) || $isLiveMode) {
            $rootCustId = $this->authenticator->getCurrentCustomerId();
        }
        $customerRoot = $this->repoSnap->getByCustomerIdOnDate($rootCustId, $period);
        $path = $customerRoot->getPath();

        /**
{'fraction_non_alphanumeric': 0.1420918367346939, 'fraction_numerical': 0.002210884353741497, 'mean_word_length': 2.491983372921615, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 90, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2340093', 'n_tokens_mistral': 4032, 'n_tokens_neox': 3939, 'n_words': 686}