vendor/lm/engine-zaiko/src/Entity/SkuExtended.php line 19

Open in your IDE?
  1. <?php
  2. namespace Lm\Engine\Zaiko\Entity;
  3. use Lm\Engine\Zaiko\Yoyaku;
  4. use Lm\Engine\Zaiko\Zaiko;
  5. use Lm\Entity\Sku;
  6. use Lm\Service\Cache\CacheService;
  7. use Lm\Service\Db\SqlService;
  8. use Lm\Util\Date;
  9. use Lm\Util\Str;
  10. class SkuExtended extends Sku
  11. {
  12.     /**
  13.      * @return false|string[]
  14.      */
  15.     public function getShiiresakiSoukoHanteiAsArray()
  16.     {
  17.         return Str::csvToArray($this->getShiiresakiSoukoHantei());
  18.     }
  19.     /**
  20.      * @return false|string[]
  21.      */
  22.     public function getChokusouIncludeHinbanListAsArray()
  23.     {
  24.         return Str::csvToArray($this->getChokusouIncludeHinbanList());
  25.     }
  26.     /**
  27.      * @return false|string[]
  28.      */
  29.     public function getChokusouExcludeHinbanListAsArray()
  30.     {
  31.         return Str::csvToArray($this->getChokusouExcludeHinbanList());
  32.     }
  33.     /**
  34.      * @return false|string[]
  35.      */
  36.     public function getBichikuIncludeHinbanListAsArray()
  37.     {
  38.         return Str::csvToArray($this->getBichikuIncludeHinbanList());
  39.     }
  40.     /**
  41.      * @return int
  42.      */
  43.     public function getStockAvailability()
  44.     {
  45.         return self::compute($this->stockAvailability, function () {
  46.             //
  47.             if ($this->getStockTotal() === null) {
  48.                 //
  49.                 return Sku::STOCK_AVL_UNKNOWN;
  50.             } else if ($this->getStockTotal() === 0) {
  51.                 //
  52.                 return Sku::STOCK_AVL_OUT_OF_STOCK;
  53.             } else if ($this->getStockTotal() <= Zaiko::LOW_STOCK_LESS_THAN) {
  54.                 //
  55.                 return Sku::STOCK_AVL_LOW_STOCK;
  56.             } else {
  57.                 //
  58.                 return Sku::STOCK_AVL_IN_STOCK;
  59.             }
  60.         });
  61.     }
  62.     /**
  63.      * @return int
  64.      * @throws \Exception
  65.      */
  66.     public function getBackOrder()
  67.     {
  68.         return self::compute($this->backOrder, function () {
  69.             //
  70.             if ($nyukaDate $this->getBichikuNyukaDate() ?: $this->getNyukaDate()) {
  71.                 //
  72.                 if (Yoyaku::calculateIsYoyakuAvailable($nyukaDate)) {
  73.                     //
  74.                     return Sku::BACK_ORDER_RESERVATION;
  75.                 } else {
  76.                     //
  77.                     return Sku::BACK_ORDER_WAITING;
  78.                 }
  79.             } else {
  80.                 //
  81.                 return Sku::BACK_ORDER_UNAVAILABLE;
  82.             }
  83.         });
  84.     }
  85.     /**
  86.      * @return bool
  87.      */
  88.     public function isChokusouAvailable()
  89.     {
  90.         //
  91.         $result false;
  92.         //
  93.         if ($this->getIsDirectDeliveryConfigExists() == 1) {
  94.             // 直送設定あり
  95.             $makerHinban $this->getMakerHinban();
  96.             $lmHinban $this->getLmHinban();
  97.             $makerHinbanCharcters preg_replace('/[^a-zA-Z]/'''$makerHinban);
  98.             $shiiresakiSoukoCharactersList $this->getShiiresakiSoukoHanteiAsArray();
  99.             $chokusouIncludeHinbanList $this->getChokusouIncludeHinbanListAsArray();
  100.             $chokusouExcludeHinbanList $this->getChokusouExcludeHinbanListAsArray();
  101.             //
  102.             if (in_array($lmHinban$chokusouExcludeHinbanList)) {
  103.                 // 除外品番
  104.                 // 無条件で 直送不可 とする
  105.                 $result false;
  106.             } else if (empty($chokusouIncludeHinbanList) || in_array($lmHinban$chokusouIncludeHinbanList)) {
  107.                 // メーカー直送品番(対象商品をLM品番で入力)
  108.                 $result true;
  109.             } else if (empty($shiiresakiSoukoCharactersList) || in_array($makerHinbanCharcters$shiiresakiSoukoCharactersList)) {
  110.                 // メーカー直送品番(該当アルファベット)
  111.                 $result true;
  112.             }
  113.         }
  114.         //
  115.         return $result;
  116.     }
  117.     /**
  118.      * @return bool
  119.      */
  120.     public function isNoDisplay()
  121.     {
  122.         return $this->getNoDisp() === 1;
  123.     }
  124.     public static function getInstanceList($goodsId$janId null$gclId null$gpId null$datetime null)
  125.     {
  126.         //
  127.         return CacheService::getCached(function () use ($goodsId$janId$gclId$gpId$datetime) {
  128.             //
  129.             if (empty($datetime)) {
  130.                 // 日時の指定が省略された場合、当日の00:00:00が指定されたものとする
  131.                 $datetime date(self::DATE_FORMAT_DEFAULT." 00:00:00");
  132.             } else {
  133.                 //
  134.                 $datetime Date::getAsDateTime($datetime)->format(self::DATE_TIME_FORMAT_DEFAULT);
  135.             }
  136.             // セット品番の対応
  137.             // TODO: 異なるメーカーを含むセット品番の対応
  138.             $goodsSetPurchaseFlg false;
  139.             $childGoodsList = [];
  140.             if (!empty($goodsId)) {
  141.                 //
  142.                 if ($goods self::getGoodsInfoByGoodsId($goodsId)) {
  143.                     // セット品番か否か
  144.                     // // goodsSetPurchaseFlg = ($goods['goods_set_purchase_flg'] == 1);
  145.                     // // childGoodsList = array_values(array_filter(explode(',', $goods['child_goods_list']), function ($item) {
  146.                     // //     return trim($item) !== '';
  147.                     // // ));
  148.                 } else {
  149.                     //
  150.                     throw new \Exception("指定された商品が見つかりません");
  151.                 }
  152.             }
  153.             //
  154.             if (!empty($childGoodsList)) {
  155.                 //
  156.                 $_skuList self::getGoodsStockInfoByGoodsIdList($childGoodsList$datetime);
  157.             } elseif (!empty($gclId) && !empty($gpId)) {
  158.                 //
  159.                 $_skuList self::getGoodsStockInfoBySkuIdentity($gclId$gpId$datetime);
  160.             } elseif (!empty($janId)) {
  161.                 //
  162.                 $_skuList self::getGoodsStockInfoByJanId($janId$datetime);
  163.             } elseif (!empty($goodsId)) {
  164.                 //
  165.                 $_skuList self::getGoodsStockInfoByGoodsId($goodsId$datetime);
  166.             } else {
  167.                 //
  168.                 throw new \Exception('$goods_id, $jan_id, $gp_id & $gcl_id のいずれかを指定する必要があります');
  169.             }
  170.             //
  171.             $skuList array_map(function ($_sku) {
  172.                 //
  173.                 return new SkuExtended($_sku);
  174.             }, $_skuList);
  175.             //
  176.             return $skuList;
  177.         });
  178.     }
  179.     /**
  180.      * @param $goodsId
  181.      * @param $janId
  182.      * @param $gclId
  183.      * @param $gpId
  184.      * @param $datetime
  185.      * @return mixed
  186.      * @throws \Exception
  187.      */
  188.     public static function getInstance($goodsId$janId null$gclId null$gpId null$datetime null)
  189.     {
  190.         return CacheService::getCached(function () use ($goodsId$janId$gclId$gpId$datetime) {
  191.             //
  192.             $skuList = static::getInstanceList($goodsId$janId$gclId$gpId$datetime);
  193.             //
  194.             if (($skuList array_filter($skuList, function ($sku) use ($janId$gclId$gpId) {
  195.                 /**
  196.                  * @var SkuExtended $sku
  197.                  */
  198.                 if (!empty($janId)) {
  199.                     //
  200.                     return $sku->getJanId() === $janId;
  201.                 } else if (!empty($gclId) && !empty($gpId)) {
  202.                     //
  203.                     return ($sku->getGclId() === (int)$gclId) && ($sku->getGpId() === (int)$gpId);
  204.                 }
  205.             })) && !empty($skuList[0])) {
  206.                 //
  207.                 return $skuList[0];
  208.             } else {
  209.                 //
  210.                 throw new \Exception('SKU情報が見つかりませんでした('.json_encode(compact('goodsId''janId''gclId''gpId''datetime')).')');
  211.             }
  212.         });
  213.     }
  214.     /**
  215.      * @param string $datetime
  216.      * @param array $bind
  217.      * @param string|null $criteria
  218.      * @return array|null
  219.      */
  220.     protected static function getGoodsStockInfo($datetime, array $bind = [], $criteria '')
  221.     {
  222.         //
  223.         $bind += [
  224.             'datetime' => $datetime,
  225.             'yoyaku_available_since_days_ago' => Yoyaku::YOYAKU_AVAILABLE_SINCE_DAYS_AGO,
  226.         ];
  227.         //
  228.         $sql "SELECT
  229.                     goods_id
  230.                 ,    shiiresaki_id
  231.                 ,    jan_id
  232.                 ,    gcl_id
  233.                 ,    gcl_display
  234.                 ,    gcl_display_status
  235.                 ,    gp_id
  236.                 ,    gp_display
  237.                 ,    gp_kataban AS `lmHinban`
  238.                 ,    jan_shiire_no AS `makerHinban`
  239.                 ,    jan_nodisplay AS `noDisp`
  240.                 ,    jan_shiire_color
  241.                 ,    color_id
  242.                 ,    color_name
  243.                 ,    size_id
  244.                 ,    size_name
  245.                 ,    shiiresaki_souko_hantei
  246.                 ,    DATE_FORMAT(shiiresaki_shimekiri_time, '%H:%i') AS `timeLimit`
  247.                 ,    goods_set_purchase_flg
  248.                 ,    (dd_id IS NOT NULL) AS `isDirectDeliveryConfigExists`
  249.                 ,    dd_hinban_chokusou AS `chokusouIncludeHinbanList`
  250.                 ,    dd_hinban_exclude AS `chokusouExcludeHinbanList`
  251.                 ,    dd_hinban_bichiku AS `bichikuIncludeHinbanList`
  252.                 ,    `nyuka_date`
  253.                 ,    IfNull(`nyuka_date`, '9999-99-99 23:59:59') BETWEEN :datetime AND :datetime + INTERVAL :yoyaku_available_since_days_ago DAY AS `is_yoyaku_available`
  254.                 ,    CASE WHEN stock_total > 0 THEN DATE_FORMAT(`bichiku_nyuka_date`, '%Y-%m-%d') ELSE NULL END AS `bichiku_nyuka_date`
  255.                 ,    `is_bichiku_ready`
  256.                 ,    `is_bichiku_yoyaku_available`
  257.                 ,    CASE 
  258.                         WHEN `shiiresaki_id` = 84 THEN
  259.                             COALESCE(
  260.                                 NullIf(IfNull(`jan_stock3`, 0), 0),
  261.                                 NullIf(IfNull(`jan_stock`, 0), 0),
  262.                                 NullIf(IfNull(`jan_stock9`, 0), 0),
  263.                                 `stock_total`,
  264.                                 '*'
  265.                             )
  266.                         WHEN `shiiresaki_id` = 56 THEN
  267.                             COALESCE(
  268.                                 NullIf(IfNull(`jan_stock3`, 0), 0),
  269.                                 NullIf(IfNull(`jan_stock`, 0), 0),
  270.                                 `stock_total`,
  271.                                 '*'
  272.                             )
  273.                         ELSE
  274.                             COALESCE(`stock_total`, '*')
  275.                     END AS `stock_total`
  276.                 ,    `stock_other`
  277.                 ,    CASE 
  278.                         WHEN `shiiresaki_id` = 84 THEN
  279.                             COALESCE(
  280.                                 NullIf(IfNull(`jan_stock3`, 0), 0),
  281.                                 NullIf(IfNull(`jan_stock`, 0), 0),
  282.                                 NullIf(IfNull(`jan_stock9`, 0), 0),
  283.                                 NullIf(`stock_bichiku` * `is_bichiku_ready`, 0),
  284.                                 NullIf(`stock_chokusou`, 0),
  285.                                 0
  286.                             )
  287.                         WHEN `shiiresaki_id` = 56 THEN
  288.                             COALESCE(
  289.                                 NullIf(IfNull(`jan_stock3`, 0), 0),
  290.                                 NullIf(IfNull(`jan_stock`, 0), 0),
  291.                                 NullIf(`stock_bichiku` * `is_bichiku_ready`, 0),
  292.                                 NullIf(`stock_chokusou`, 0),
  293.                                 0
  294.                             )
  295.                         ELSE
  296.                             COALESCE(NullIf(`stock_bichiku` * `is_bichiku_ready`, 0), NullIf(`stock_chokusou`, 0), 0)
  297.                     END AS `stock_sokujitsu`
  298.                 ,    `stock_chokusou`
  299.                 ,    `stock_bichiku`
  300.                 ,    ki_comment AS `nyuka_date_comment`
  301.                 ,    cp_price AS `cp_price_in_tax`
  302.                 ,    gp_price2 AS `gp_price_ex_tax`
  303.                 ,    gp_teika AS `gp_teika_in_tax`
  304.                 FROM (
  305.                     SELECT
  306.                         *
  307.                     ,    CASE
  308.                             WHEN
  309.                                 `stock_total_sub` > 0
  310.                             THEN
  311.                                 null
  312.                             ELSE
  313.                                 STR_TO_DATE(`_nyuka_date`, '%Y-%m-%d')
  314.                         END AS `nyuka_date`
  315.                     FROM (
  316.                         SELECT
  317.                             *
  318.                         ,    NullIf(LEAST(IfNull(ki_date, '9999-99-99 23:59:59'), IfNull(zero_period, '9999-99-99 23:59:59')), '9999-99-99 23:59:59') AS `_nyuka_date`
  319.                         FROM
  320.                             goods_table AS `goods`
  321.                         INNER JOIN
  322.                             shiiresaki_table AS `shiiresaki`
  323.                         ON
  324.                             shiiresaki_id = goods_shiiresaki
  325.                         LEFT JOIN
  326.                             direct_delivery_table AS `direct_delivery`
  327.                         ON
  328.                             shiiresaki_id = dd_shiiresaki
  329.                         INNER JOIN
  330.                             goods_color_table AS `gcl`
  331.                         ON
  332.                             goods_id = gcl_goods
  333.                         INNER JOIN
  334.                             color_table AS `color`
  335.                         ON
  336.                             color_id = gcl_color_id
  337.                         INNER JOIN
  338.                             goods_price_table AS `gp`
  339.                         ON
  340.                             goods_id = gp_goods
  341.                         INNER JOIN
  342.                             size_table AS `size`
  343.                         ON
  344.                             size_id = gp_size_id
  345.                         INNER JOIN (
  346.                             SELECT
  347.                                 `jan`.*
  348.                             ,    (
  349.                                     jan_stock
  350.                                 +    IfNull(jan_stock2, 0)
  351.                                 +    IfNull(`stock_bichiku`, 0)
  352.                                 +    IfNull(jan_stock4, 0)
  353.                                 +    IfNull(jan_stock5, 0)
  354.                                 +    IfNull(jan_stock6, 0)
  355.                                 +    IfNull(jan_stock7, 0)
  356.                                 +    IfNull(jan_stock8, 0)
  357.                                 +    IfNull(jan_stock9, 0)
  358.                                 ) AS `stock_total`
  359.                             ,    (
  360.                                     IfNull(jan_stock4, 0)
  361.                                 +    IfNull(jan_stock5, 0)
  362.                                 +    IfNull(jan_stock6, 0)
  363.                                 +    IfNull(jan_stock7, 0)
  364.                                 +    IfNull(jan_stock8, 0)
  365.                                 +    IfNull(`stock_bichiku`, 0)
  366.                                 ) AS `stock_other`
  367.                             ,    (
  368.                                     IfNull(`stock_bichiku`, 0)
  369.                                 +    IfNull(jan_stock5, 0)
  370.                                 +    IfNull(jan_stock6, 0)
  371.                                 +    IfNull(jan_stock7, 0)
  372.                                 +    IfNull(jan_stock8, 0)
  373.                                 +    IfNull(jan_stock9, 0)
  374.                                 ) AS `stock_total_sub`
  375.                             ,    (`stock_bichiku` * `is_bichiku_ready`) AS `stock_bichiku_available`
  376.                             ,    (`stock_bichiku` * `is_bichiku_yoyaku_available`) AS `stock_bichiku_yoyaku_available`
  377.                             FROM (
  378.                                 SELECT
  379.                                     `jan`.*
  380.                                 ,    NullIf(IfNull(jan_stock3, 0) * `is_jan_stock3_nyuka_date_not_out_date` * (`is_bichiku_ready` || `is_bichiku_yoyaku_available`), 0) AS `stock_bichiku`
  381.                                 FROM (
  382.                                     SELECT
  383.                                         `jan`.*
  384.                                     ,    CASE WHEN jan_stock != 0 THEN (IfNull(`bichiku_nyuka_date`, '9999-99-99 23:59:59') BETWEEN :datetime AND :datetime + INTERVAL :yoyaku_available_since_days_ago DAY) ELSE bichiku_nyuka_date IS NOT NULL END AS `is_bichiku_yoyaku_available`
  385.                                     FROM (
  386.                                         SELECT
  387.                                             `jan`.*
  388.                                         ,    goods.goods_shiiresaki AS `jan_goods_shiiresaki`
  389.                                         ,    (IfNull(jan_stock, 0) + IfNull(jan_stock5, 0) + IfNull(jan_stock7, 0)) AS `stock_chokusou`
  390.                                         ,    DATE_FORMAT(jan_stock3_nyuka_date + INTERVAL 1 DAY,'%Y-%m-%d %h:%i:%s') AS `bichiku_nyuka_date`
  391.                                         ,    IfNull(jan_stock, 0) = 0 OR (jan_stock3_nyuka_date IS  NULL OR (IfNull(DATE_FORMAT(jan_stock3_nyuka_date + INTERVAL 1 DAY, '%Y-%m-%d'), '0000-00-00') >= DATE_FORMAT(:datetime, '%Y-%m-%d'))) AS `is_jan_stock3_nyuka_date_not_out_date`
  392.                                         ,    (jan_stock3 IS NOT NULL AND (IfNull(DATE_FORMAT(jan_stock3_nyuka_date, '%Y-%m-%d'), '0000-00-00 00:00:00') < DATE_FORMAT(:datetime, '%Y-%m-%d'))) AS `is_bichiku_ready`
  393.                                         FROM
  394.                                             goods_table AS `goods`
  395.                                         INNER JOIN
  396.                                             goods_color_table AS `gcl`
  397.                                         ON
  398.                                             goods_id = gcl_goods
  399.                                         INNER JOIN
  400.                                             color_table AS `color`
  401.                                         ON
  402.                                             color_id = gcl_color_id
  403.                                         INNER JOIN
  404.                                             goods_price_table AS `gp`
  405.                                         ON
  406.                                             goods_id = gp_goods
  407.                                         INNER JOIN
  408.                                             size_table AS `size`
  409.                                         ON
  410.                                             size_id = gp_size_id
  411.                                         INNER JOIN
  412.                                             jancode_table AS `jan`
  413.                                         ON
  414.                                             goods_id = jan_goods
  415.                                         AND
  416.                                             gcl_id = jan_color
  417.                                         AND
  418.                                             gp_id = jan_price
  419.                                         WHERE
  420.                                             1 = 1
  421.                                         {$criteria}
  422.                                     ) AS `jan`
  423.                                 ) AS `jan`
  424.                             ) AS `jan`
  425.                         ) AS `jan`
  426.                         ON
  427.                             goods_id = jan_goods
  428.                         AND
  429.                             gcl_id = jan_color
  430.                         AND
  431.                             gp_id = jan_price
  432.                         LEFT JOIN
  433.                             keppin_item_table AS `ki`
  434.                         ON
  435.                             goods_id = ki_goods
  436.                         AND
  437.                             gcl_id = ki_gcl
  438.                         AND
  439.                             gp_id = ki_gp
  440.                         AND
  441.                             ki_date > :datetime
  442.                         LEFT JOIN
  443.                             zero_stock_table AS `zero`
  444.                         ON
  445.                             goods_id = zero_goods
  446.                         AND
  447.                             gcl_id = zero_gcl
  448.                         AND
  449.                             gp_id = zero_gp
  450.                         AND
  451.                             zero_period > :datetime
  452.                         WHERE
  453.                             1 = 1
  454.                         {$criteria}
  455.                     ) AS `stock`
  456.                 ) AS `stock`
  457.             LEFT JOIN
  458.                 campaign_price_table
  459.             ON
  460.                 gp_id = cp_gp
  461.             AND
  462.                 cp_start_datetime <= :datetime
  463.             AND
  464.                 cp_end_datetime >= :datetime
  465.             AND
  466.                 cp_del_flg = 0
  467.             ORDER BY
  468.                 goods_id
  469.             ,    gcl_display
  470.             ,    color_display
  471.             ,    gcl_id
  472.             ,    gp_display
  473.             ,    size_display
  474.             ,    gp_id";
  475.         //
  476.         $result = (new SqlService())
  477.             ->Sql($sql)
  478.             ->Params($bind)
  479.             ->FetchAll() ?: []
  480.         ;
  481.         //
  482.         return $result;
  483.     }
  484.     /**
  485.      * @param int $goodsId
  486.      * @param string $datetime
  487.      * @return array|false
  488.      */
  489.     protected static function getGoodsStockInfoByGoodsId($goodsId$datetime)
  490.     {
  491.         return CacheService::getCached(function () use ($goodsId$datetime) {
  492.             //
  493.             $bind = [
  494.                 'goods_id' => $goodsId,
  495.             ];
  496.             //
  497.             $criteria "AND
  498.                         goods_id = :goods_id";
  499.             //
  500.             $result self::getGoodsStockInfo($datetime$bind$criteria);
  501.             //
  502.             return $result;
  503.         });
  504.     }
  505.     /**
  506.      * @param array $goodsIdList
  507.      * @param string $datetime
  508.      * @return array|false
  509.      */
  510.     protected static function getGoodsStockInfoByGoodsIdList(array $goodsIdList$datetime)
  511.     {
  512.         return CacheService::getCached(function () use ($goodsIdList$datetime) {
  513.             //
  514.             $bind = [];
  515.             foreach ($goodsIdList as $i => $goodsId) {
  516.                 $bind["goodsId{$i}"] = $goodsId;
  517.             }
  518.             $placeHolderGoodsIdIn implode(','array_map(function ($item) {
  519.                 return ":{$item}";
  520.             }, array_keys($bind)));
  521.             //
  522.             $criteria "AND
  523.                         goods_id IN ({$placeHolderGoodsIdIn})";
  524.             //
  525.             $result self::getGoodsStockInfo($datetime$bind$criteria);
  526.             //
  527.             return $result;
  528.         });
  529.     }
  530.     /**
  531.      * @param int $janId
  532.      * @param string $datetime
  533.      * @return array|false
  534.      */
  535.     protected static function getGoodsStockInfoByJanId($janId$datetime)
  536.     {
  537.         return CacheService::getCached(function () use ($janId$datetime) {
  538.             //
  539.             $placeholders array_map(function ($key) {
  540.                 //
  541.                 return "jan_id_{$key}";
  542.             }, array_keys((array)$janId));
  543.             //
  544.             $bind array_combine($placeholders, (array)$janId);
  545.             $placeholdersIn implode(','array_map(function ($placeholder) {
  546.                 //
  547.                 return ":{$placeholder}";
  548.             }, $placeholders));
  549.             //
  550.             $criteria "AND
  551.                             jan_id IN ({$placeholdersIn})";
  552.             //
  553.             $result self::getGoodsStockInfo($datetime$bind$criteria);
  554.             //
  555.             return $result;
  556.         });
  557.     }
  558.     /**
  559.      * @param int $gclId
  560.      * @param int $gpId
  561.      * @param string $datetime
  562.      * @return array|false
  563.      */
  564.     protected static function getGoodsStockInfoBySkuIdentity($gclId$gpId$datetime)
  565.     {
  566.         return CacheService::getCached(function () use ($gclId$gpId$datetime) {
  567.             //
  568.             $bind = [
  569.                 'gcl_id' => $gclId,
  570.                 'gp_id' => $gpId,
  571.             ];
  572.             //
  573.             $criteria "AND
  574.                             gcl_id = :gcl_id
  575.                         AND
  576.                             gp_id = :gp_id";
  577.             //
  578.             $result self::getGoodsStockInfo($datetime$bind$criteria);
  579.             //
  580.             return $result;
  581.         });
  582.     }
  583.     /**
  584.      * @param int $goodsId
  585.      * @return mixed
  586.      */
  587.     protected static function getGoodsInfoByGoodsId($goodsId)
  588.     {
  589.         return CacheService::getCached(function () use ($goodsId) {
  590.             //
  591.             $sql "SELECT
  592.                     `parent`.goods_id
  593.                 ,    `parent`.goods_set_purchase_flg
  594.                 ,    GROUP_CONCAT(DISTINCT `child`.goods_id ORDER BY gsp_type SEPARATOR ',') AS `child_goods_list`
  595.                 FROM
  596.                     goods_table AS `parent`
  597.                 LEFT JOIN
  598.                     goods_set_purchase_table
  599.                 ON
  600.                     `parent`.goods_id = gsp_goods_parent
  601.                 LEFT JOIN
  602.                     goods_table AS `child`
  603.                 ON
  604.                     `child`.goods_id = gsp_goods_child
  605.                 WHERE
  606.                     `parent`.goods_id = :goods_id
  607.                 GROUP BY
  608.                     `parent`.goods_id";
  609.             //
  610.             $bind = [
  611.                 'goods_id' => $goodsId,
  612.             ];
  613.             //
  614.             $result = (new SqlService())
  615.                 ->Sql($sql)
  616.                 ->Params($bind)
  617.                 ->fetch()
  618.             ;
  619.             //
  620.             return $result;
  621.         });
  622.     }
  623. }