vendor/lm/engine-sokujitsu-hassou/src/SokujitsuHassou.php line 207

Open in your IDE?
  1. <?php
  2. namespace Lm\Engine\SokujitsuHassou;
  3. use Lm\Engine\SokujitsuHassou\Config\Constant;
  4. use Lm\Engine\Zaiko\Entity\SkuExtended;
  5. use Lm\Entity\Sku;
  6. use Lm\Service\Cache\LmCacheTrait;
  7. use Lm\Service\Cache\CacheService;
  8. use Lm\Service\Db\SqlService;
  9. use Lm\Entity\OrderHeader;
  10. use Lm\Entity\OrderList;
  11. use Lm\Entity\OrderGoodsList;
  12. class SokujitsuHassou
  13. {
  14.     use LmCacheTrait {
  15.         LmCacheTrait::__construct as __traitConstruct;
  16.     }
  17.     const FLG_NONE 0;                            // 即日発送不可
  18.     const FLG_CHOKUSOU 1;                        // 即日発送可(メーカー直送)
  19.     const FLG_BICHIKU 2;                        // 即日発送可(備蓄)
  20.     const FLG_NG_ORDER_CANCELLED = -1;            // 即日発送不可(受注取消済みのため)
  21.     const FLG_NG_SHIIRESAKI_MIXED = -2;            // 即日発送不可(仕入先混在のため)
  22.     const FLG_NG_SOUKO_MIXED = -3;                // 即日発送不可(倉庫(メーカー直送、備蓄在庫)混在のため)
  23.     const FLG_NG_ORDER_TYPE = -4;                // 即日発送不可(受注タイプ未対応のため)
  24.     const FLG_NG_PAYMENT_TYPE = -5;                // 即日発送不可(支払い方法未対応のため)
  25.     const FLG_NG_ORDER_SHUBETSU = -6;            // 即日発送不可(受注種別未対応のため)
  26.     const FLG_NG_YOYAKU = -7;                    // 即日発送不可(予約注文のため)
  27.     const FLG_NG_ORGANIZATION = -8;                // 即日発送不可(顧客種別(個人/組織)未対応のため)
  28.     const FLG_NG_DEADLINE_HAS_PASSED = -9;
  29.     const FLG_NG_NUMBER_ORDER_EXCEEDS_SHIPPING_IN_DAY = -10;
  30.     const TIME_LIMIT_BICHIKU '16:00';    // 締切時刻(備蓄)
  31.     const MIGRATION_DATE_FOR_SOKUJITSU_HASSOU_FLG '2022-07-08 00:00:00';
  32.     /**
  33.      * 受注時の仕入先別の即日発送条件
  34.      */
  35.     const ORDER_SHIIRESAKI_LIST = [
  36.         'default' => [
  37.             'available_order_type_list' => [
  38.                 OrderHeader::TYPE_PURCHASE,
  39.                 OrderHeader::TYPE_SAMPLE,
  40.             ],
  41.             'available_order_shubetsu_list' => [
  42.                 OrderHeader::SHUBETSU_MUJI,
  43.                 OrderHeader::SHUBETSU_SAMPLE,
  44.                 OrderHeader::SHUBETSU_CATALOG,
  45.             ],
  46.             'available_payment_type_list' => [
  47.                 OrderHeader::PAYMENT_TYPE_CREDIT_CARD,
  48.             ],
  49.             'organization_only' => false,
  50.         ], // デフォルト
  51.         'bichiku' => [
  52.             'available_order_type_list' => [
  53.                 OrderHeader::TYPE_PURCHASE,
  54.                 OrderHeader::TYPE_SAMPLE,
  55.             ],
  56.             'available_order_shubetsu_list' => [
  57.                 OrderHeader::SHUBETSU_MUJI,
  58.                 OrderHeader::SHUBETSU_SAMPLE,
  59.                 OrderHeader::SHUBETSU_CATALOG,
  60.             ],
  61.             'available_payment_type_list' => [
  62.                 OrderHeader::PAYMENT_TYPE_CREDIT_CARD,
  63.                 OrderHeader::PAYMENT_TYPE_DAIKIN_HIKIKAE,
  64.                 OrderHeader::PAYMENT_TYPE_ATOBARAI,
  65.                 OrderHeader::PAYMENT_TYPE_ATOBARAI_MONTHLY,
  66.                 OrderHeader::PAYMENT_TYPE_AMAZON_PAY,
  67.                 Constant::AMAZON_PAY
  68.             ],
  69.             'organization_only' => false,
  70.         ], // 備蓄
  71.         '84' => [
  72.             'available_payment_type_list' => [
  73.                 OrderHeader::PAYMENT_TYPE_CREDIT_CARD,
  74.                 OrderHeader::PAYMENT_TYPE_DAIKIN_HIKIKAE,
  75.             ],
  76.             'organization_only' => false,
  77.         ], // 84: チトセ
  78.         '56' => [
  79.             'available_payment_type_list' => [
  80.                 OrderHeader::PAYMENT_TYPE_CREDIT_CARD,
  81.             ],
  82.             'organization_only' => true,
  83.         ], // 56: 自重堂
  84.     ];
  85.     /**
  86.      * @var SqlService
  87.      */
  88.     protected $db;
  89.     public function __construct()
  90.     {
  91.         //
  92.         $this->db = new SqlService();
  93.         //
  94.         $cacheService = new CacheService();
  95.         //
  96.         $this->__traitConstruct($cacheService);
  97.     }
  98.     /**
  99.      * 商品単位での即日発送可否判定を行う
  100.      *
  101.      * TODO: 異なるメーカーを含むセット品番の対応
  102.      * TODO: 欠品の対応
  103.      *
  104.      * @param int $goodsId
  105.      * @param bool|null $isMatrix
  106.      * @param int|null $janId
  107.      * @param int|null $gclId
  108.      * @param int|null $gpId
  109.      * @param string|null $datetime
  110.      * @param int|null $amount
  111.      * @param array $listJanId
  112.      * @return array|int
  113.      * @throws \Exception
  114.      */
  115.     public function check($goodsId$isMatrix false$janId null$gclId null$gpId null$datetime null$amount null$isGetFullStatusDelivery false)
  116.     {
  117.         //
  118.         if (empty($datetime)) {
  119.             // 日時の指定が省略された場合、当日の00:00:00が指定されたものとする
  120.             $datetime date("Y-m-d 00:00:00");
  121.         }
  122.         //
  123.         if (empty($amount)) {
  124.             // 数量の指定が省略された場合、ゼロ「0」が指定されたものとする
  125.             $amount 0;
  126.         }
  127.         //
  128.         if (empty($gclId) && empty($gpId)) {
  129.             //
  130.             if (empty($janId)) {
  131.                 //
  132.                 if (!empty($goodsId)) {
  133.                     //
  134.                     if (!empty($amount)) {
  135.                         //
  136.                         throw new \Exception('引数$amountはnullもしくは0である必要があります($goods_idのみの指定の場合、数量の指定は出来ません)');
  137.                     }
  138.                 }
  139.             }
  140.         }
  141.         try {
  142.             //
  143.             if (!($skuList SkuExtended::getInstanceList($goodsId$janId$gclId$gpId$datetime))) {
  144.                 //
  145.                 throw new \Exception("指定された商品の在庫情報が取得できませんでした");
  146.             }
  147.             if ($isGetFullStatusDelivery) {
  148.                 return $this->getFullStatusDelivery($skuList$isMatrix$datetime$amount);
  149.             }
  150.             return $this->_check($skuList$isMatrix$datetime$amount);
  151.         } catch (\Exception $e) {
  152.             // error_log($e->getMessage());
  153.             // error_log($e->getTraceAsString());
  154.             return self::FLG_NONE;
  155.         }
  156.     }
  157.     /**
  158.      * @param Sku[] $skuList
  159.      * @param bool $isMatrix
  160.      * @param string $datetime
  161.      * @param int $amount
  162.      * @return array|int
  163.      */
  164.     protected function _check($skuList$isMatrix$datetime$amount)
  165.     {
  166.         //
  167.         $result = [];
  168.         $flgMax self::FLG_NONE;    // 【マトリクス対応】同一の品番において、1つでも即日可のSKUが存在する場合、最も良い条件を採用
  169.         $flgBuf = [];                // 【セット品番対応】複数品番を含む場合、それら全ての品番における最低の条件を採用
  170.         //
  171.         foreach ($skuList as $index => $sku) {
  172.             //
  173.             $goodsId $sku->getGoodsId();
  174.             $gclId $sku->getGclId();
  175.             $gpId $sku->getGpId();
  176.             //
  177.             $lmHinban $sku->getLmHinban();
  178.             $makerHinban $sku->getMakerHinban();
  179.             $makerTimeLimit $sku->getTimeLimit();
  180.             //
  181.             $stockChokusou = (int)$sku->getStockChokusou();
  182.             $stockBichiku = (int)$sku->getStockBichiku();
  183.             //
  184.             $bichikuNyukaDate $sku->getBichikuNyukaDate();
  185.             //
  186.             $flg self::FLG_NONE;
  187.             if (!isset($flgBuf[$goodsId])) {
  188.                 $flgBuf[$goodsId] = self::FLG_NONE;
  189.             }
  190.             //
  191.             if (!empty($bichikuNyukaDate)) {
  192.                 //
  193.                 $flg self::FLG_NG_YOYAKU;
  194.             } else if ($sku->getIsDirectDeliveryConfigExists() == 1) {
  195.                 // 直送設定あり
  196.                 $makerHinbanCharcters preg_replace('/[^a-zA-Z]/'''$makerHinban);
  197.                 $shiiresakiSoukoCharactersList $sku->getShiiresakiSoukoHanteiAsArray();
  198.                 $chokusouIncludeHinbanList $sku->getChokusouIncludeHinbanListAsArray();
  199.                 $chokusouExcludeHinbanList $sku->getChokusouExcludeHinbanListAsArray();
  200.                 $bichikuIncludeHinbanList $sku->getBichikuIncludeHinbanListAsArray();
  201.                 //
  202.                 if ($this->isBichikuAvailable($stockBichiku$datetime$amount)) {
  203.                     //
  204.                     $flg self::FLG_BICHIKU;
  205.                 } else if (in_array($lmHinban$bichikuIncludeHinbanList)) {
  206.                     // LM備蓄在庫(アシスト物流で在庫している)している品番
  207.                     // // 数量にゼロ「0」の指定がある場合に限り、在庫数に関わらず 即日発送可(備蓄)とする
  208.                     // if ($this->isBichikuAvailable($amount === 0 ? 999 : $amount, $datetime, $amount)) {
  209.                     //     $flg = self::FLG_BICHIKU;
  210.                     // }
  211.                     // マトリクス式でなく且つ、数量の指定が無い場合に限り、在庫数に関わらず 即日発送可(備蓄)とする
  212.                     if ($this->isBichikuAvailable((!$isMatrix && !$amount) ? 999 $stockBichiku$datetime$amount)) {
  213.                         $flg self::FLG_BICHIKU;
  214.                     }
  215.                 } else if (in_array($lmHinban$chokusouExcludeHinbanList)) {
  216.                     // 除外品番
  217.                     // 無条件で 即日発送不可 とする
  218.                     $flg self::FLG_NONE;
  219.                 } else if (empty($chokusouIncludeHinbanList) || in_array($lmHinban$chokusouIncludeHinbanList)) {
  220.                     // メーカー直送品番(対象商品をLM品番で入力)
  221.                     if ($this->isSokujitsuAvailable($makerTimeLimit$stockChokusou$datetime$amount)) {
  222.                         $flg self::FLG_CHOKUSOU;
  223.                     }
  224.                 } else if (empty($shiiresakiSoukoCharactersList) || in_array($makerHinbanCharcters$shiiresakiSoukoCharactersList)) {
  225.                     // メーカー直送品番(該当アルファベット)
  226.                     if ($this->isSokujitsuAvailable($makerTimeLimit$stockChokusou$datetime$amount)) {
  227.                         $flg self::FLG_CHOKUSOU;
  228.                     }
  229.                 } else {
  230.                     // いずれにも該当しない場合
  231.                     // ※各種直送の設定漏れ時の救済(但しこの場合、備蓄のチェックのみとなる)
  232.                     error_log('[engine-sokujitsu-hassou] check it out(001).');
  233.                 }
  234.             } else {
  235.                 // 直送設定なし
  236.                 if ($this->isBichikuAvailable($stockBichiku$datetime$amount)) {
  237.                     //
  238.                     $flg self::FLG_BICHIKU;
  239.                 }
  240.             }
  241.             //
  242.             if (!isset($result[$gclId])) {
  243.                 $result[$gclId] = [];
  244.             }
  245.             //
  246.             $result[$gclId][$gpId] = $flg;
  247.             //
  248.             if ($flgBuf[$goodsId] < $flg) {
  249.                 $flgBuf[$goodsId] = $flg;
  250.             }
  251.             //
  252.             $flgMax min($flgBuf);
  253.         }
  254.         //
  255.         if ($isMatrix) {
  256.             //
  257.             return $result;
  258.         } else {
  259.             //
  260.             return $flgMax;
  261.         }
  262.     }
  263.     /***
  264.      * Get Full status of List sku
  265.      *
  266.      * @param $skuList
  267.      * @param $isMatrix
  268.      * @param $datetime
  269.      * @param $amount
  270.      * @return array|int|mixed
  271.      */
  272.     protected function getFullStatusDelivery($skuList$isMatrix$datetime$amount)
  273.     {
  274.         $result = [];
  275.         $flgMax self::FLG_NONE;    // 【マトリクス対応】同一の品番において、1つでも即日可のSKUが存在する場合、最も良い条件を採用
  276.         $flgBuf = [];                // 【セット品番対応】複数品番を含む場合、それら全ての品番における最低の条件を採用
  277.         $timeLimit self::TIME_LIMIT_BICHIKU;
  278.         foreach ($skuList as $index => $sku) {
  279.             $goodsId $sku->getGoodsId();
  280.             $gclId $sku->getGclId();
  281.             $gpId $sku->getGpId();
  282.             if (!isset($flgBuf[$goodsId])) {
  283.                 $flgBuf[$goodsId] = self::FLG_NONE;
  284.             }
  285.             $flg self::getFlagDelivery($sku$datetime$amount$isMatrix$timeLimit);
  286.             if (!isset($result[$gclId])) {
  287.                 $result[$gclId] = [];
  288.             }
  289.             $result[$gclId][$gpId] = $flg;
  290.             $flgBuf[$goodsId] = $flg;
  291.             $flgMax min($flgBuf);
  292.         }
  293.         return $isMatrix $result $flgMax;
  294.     }
  295.     /**
  296.      * 受注単位での即日発送可否判定を行う
  297.      *
  298.      * TODO: 受注単位の合計数量で計算するように(現在は受注明細(SKU毎)単位)
  299.      *
  300.      * @param int|array|OrderHeader $orderHeader 受注IDもしくは受注データ(配列 or OrderHeaderエンティティ)を渡す
  301.      * @param string|null $datetime
  302.      * @return array|int
  303.      * @throws \Exception
  304.      */
  305.     public function checkOrder($orderHeader$datetime null)
  306.     {
  307.         // 受注IDが渡された場合、受注情報を検索する
  308.         if (is_numeric($orderHeader) || is_array($orderHeader)) {
  309.             //
  310.             $orderHeader = new OrderHeader($orderHeader);
  311.         }
  312.         //
  313.         if (empty($datetime)) {
  314.             // 日時の指定が省略された場合
  315.             if ($ohDate $orderHeader->getOhDate()) {
  316.                 // 当該受注の受注日時があれば採用
  317.                 $datetime date("Y-m-d H:i:s"strtotime($ohDate));
  318.             } else {
  319.                 // 無ければ現在
  320.                 $datetime date("Y-m-d H:i:s");
  321.             }
  322.         }
  323.         // 即日発送フラグによる判定
  324.         if (date('H:i:s'strtotime($datetime)) === '00:00:00') {
  325.             // TODO: 倉庫判定エンジンとして機能する
  326.         } else if ($orderHeader->getOhSokujitsuHassouFlg() === self::FLG_CHOKUSOU) {
  327.             // 即日発送可(メーカー直送)
  328.             return self::FLG_CHOKUSOU;
  329.         } else if ($orderHeader->getOhSokujitsuHassouFlg() === self::FLG_BICHIKU) {
  330.             // 即日発送可(備蓄)
  331.             return self::FLG_BICHIKU;
  332.         } else if ($orderHeader->getOhId() && (strtotime($orderHeader->getOhDate()) > strtotime(self::MIGRATION_DATE_FOR_SOKUJITSU_HASSOU_FLG))) {
  333.             // TODO: 即日発送エンジン切り替え前後の判定。もっとスマートな方法?
  334.             return (int)$orderHeader->getOhSokujitsuHassouFlg();
  335.         }
  336.         //
  337.         return $this->_checkOrder($orderHeader$datetime);
  338.     }
  339.     /**
  340.      * @param OrderHeader $orderHeader
  341.      * @param string $datetime
  342.      * @return array|int
  343.      * @throws \Exception
  344.      */
  345.     protected function _checkOrder(OrderHeader $orderHeader$datetime)
  346.     {
  347.         //
  348.         $shiiresakiIdBuf = [];        // 【受注明細別対応】メーカーが混在の場合、NGとする
  349.         $flgBuf = [];                // 【受注明細別対応】複数明細を含む場合、それら全ての明細における最低の条件を採用
  350.         // 受注タイプによる判定
  351.         if ($orderHeader->getOhType() === OrderHeader::TYPE_CANCEL) {
  352.             // 取消済みは除外
  353.             return self::FLG_NG_ORDER_CANCELLED;
  354.         } else if (in_array($orderHeader->getOhType(), [
  355.             OrderHeader::TYPE_CATALOG// 5: カタログ請求
  356.         ])) {
  357.             // 受注タイプ非対応
  358.             return self::FLG_NG_ORDER_TYPE;
  359.         }
  360.         // 予約か否か
  361.         if ($orderHeader->getOhYoyaku() == OrderHeader::YOYAKU_YES) {
  362.             // 予約の場合は無条件で即日発送の対象外とする
  363.             return self::FLG_NG_YOYAKU;
  364.         }
  365.         //
  366.         foreach ($orderHeader->getOrderListList() as $orderList) {
  367.             //
  368.             $goods $orderList->getGoods();
  369.             $shiiresakiId $goods->getGoodsShiiresaki();
  370.             $shiiresakiIdBuf[] = $shiiresakiId;
  371.             //
  372.             $flgBuf[] = $this->checkOrderList($orderHeader$orderList$datetime);
  373.         }
  374.         //
  375.         if (count(array_unique($shiiresakiIdBuf)) > 1) {
  376.             // 仕入先混在
  377.             return self::FLG_NG_SHIIRESAKI_MIXED;
  378.         } else if (count(array_unique($flgBuf)) > 1) {
  379.             // 倉庫混在(備蓄・直送・それ以外)
  380.             return self::FLG_NG_SOUKO_MIXED;
  381.         }
  382.         //
  383.         $flg min($flgBuf);
  384.         //
  385.         return $flg;
  386.     }
  387.     protected function checkOrderList(OrderHeader $orderHeaderOrderList $orderList$datetime)
  388.     {
  389.         //
  390.         $flg $this->_checkOrderList($orderList$datetime);
  391.         //
  392.         $shiiresakiId $orderList->getGoods()->getGoodsShiiresaki();
  393.         $orderShiiresakiConfig self::ORDER_SHIIRESAKI_LIST['default'];
  394.         // 仕入先毎の設定があればそちらで上書き
  395.         if ($flg === self::FLG_BICHIKU) {
  396.             // LM備蓄
  397.             $orderShiiresakiConfig array_replace($orderShiiresakiConfigself::ORDER_SHIIRESAKI_LIST['bichiku']);
  398.         } else if ($flg === self::FLG_CHOKUSOU) {
  399.             // メーカー直送
  400.             if (array_key_exists($shiiresakiIdself::ORDER_SHIIRESAKI_LIST)) {
  401.                 // 仕入先毎の設定あり
  402.                 $orderShiiresakiConfig array_replace($orderShiiresakiConfigself::ORDER_SHIIRESAKI_LIST[$shiiresakiId]);
  403.             }
  404.         } else {
  405.             // この時点で即日不可の場合は「即日不可」
  406.             return $flg;
  407.         }
  408.         //
  409.         if (!in_array($orderHeader->getOhType(), $orderShiiresakiConfig['available_order_type_list'])) {
  410.             //
  411.             return self::FLG_NG_ORDER_TYPE;
  412.         }
  413.         //
  414.         if (($orderHeader->getOhType() === OrderHeader::TYPE_SAMPLE) && ($orderHeader->getOhPayment() !== OrderHeader::PAYMENT_TYPE_SAMPLE)) {
  415.             //
  416.             return self::FLG_NG_ORDER_TYPE;
  417.         } else if (($orderHeader->getOhType() === OrderHeader::TYPE_CATALOG) && ($orderHeader->getOhPayment() !== OrderHeader::PAYMENT_TYPE_CATALOG)) {
  418.             //
  419.             return self::FLG_NG_ORDER_TYPE;
  420.         } else if (!in_array($orderHeader->getOhShubetsu(), $orderShiiresakiConfig['available_order_shubetsu_list'])) {
  421.             //
  422.             return self::FLG_NG_ORDER_SHUBETSU;
  423.         }
  424.         //
  425.         if (!in_array($orderHeader->getOhPayment(), $orderShiiresakiConfig['available_payment_type_list'])) {
  426.             //
  427.             return self::FLG_NG_PAYMENT_TYPE;
  428.         }
  429.         //
  430.         if ($orderShiiresakiConfig['organization_only'] && (empty($orderHeader->getOhSendCompany()) && empty($orderHeader->getCustomer()->getCustomerCompany()))) {
  431.             //
  432.             return self::FLG_NG_ORGANIZATION;
  433.         }
  434.         //
  435.         return $flg;
  436.     }
  437.     protected function _checkOrderList(OrderList $orderList$datetime)
  438.     {
  439.         $flgBuf = [];                // 【受注明細(SKU毎)別対応】複数明細を含む場合、それら全ての明細における最低の条件を採用
  440.         //
  441.         foreach ($orderList->getOrderGoodsListList() as $orderGoodsList) {
  442.             //
  443.             $flgBuf[] = $this->checkOrderGoodsList($orderGoodsList$datetime);
  444.         }
  445.         //
  446.         if (empty($flgBuf)) {
  447.             // 受注明細(SKU毎)が存在しないため、判定不可。
  448.             return self::FLG_NONE;
  449.         }
  450.         //
  451.         if (count(array_unique($flgBuf)) > 1) {
  452.             // 倉庫混在(備蓄・直送・それ以外)
  453.             return self::FLG_NG_SOUKO_MIXED;
  454.         }
  455.         //
  456.         $flg min($flgBuf);
  457.         //
  458.         return $flg;
  459.     }
  460.     /**
  461.      * @param OrderGoodsList $orderGoodsList
  462.      * @param string $datetime
  463.      * @return array|int
  464.      * @throws \Exception
  465.      */
  466.     protected function checkOrderGoodsList(OrderGoodsList $orderGoodsList$datetime)
  467.     {
  468.         //
  469.         $orderHeader $orderGoodsList->getOrderList()->getOrderHeader();
  470.         //
  471.         $gclId $orderGoodsList->getOglGcl();
  472.         $gpId $orderGoodsList->getOglGp();
  473.         $amount $orderGoodsList->getOglAmount();
  474.         $oglStockConsume $orderGoodsList->getStockConsume();
  475.         //
  476.         if ($oglStockConsume !== null) {
  477.             // 倉庫混在の判定(=但し、一部、条件によっては混在可)
  478.             if (($oglStockConsume->getJanStock3() && ($amount !== $oglStockConsume->getJanStock3()))
  479.             ||    ($oglStockConsume->getJanStock4() && ($amount !== ($oglStockConsume->getJanStock() + $oglStockConsume->getJanStock4())))
  480.             ||    ($oglStockConsume->getJanStock5() && ($amount !== ($oglStockConsume->getJanStock() + $oglStockConsume->getJanStock5())))
  481.             ) {
  482.                 //
  483.                 return self::FLG_NG_SOUKO_MIXED;
  484.             } else if (
  485.                 ($oglStockConsume->getJanStock9() && ($amount === ($oglStockConsume->getJanStock() + $oglStockConsume->getJanStock9())))
  486.             ) {
  487.                 // チトセ外部在庫
  488.                 // TODO: 倉庫判定エンジン
  489.                 if (date('H:i:s'strtotime($datetime)) === '00:00:00') {
  490.                     // no operation.
  491.                 } else {
  492.                     return self::FLG_NG_SOUKO_MIXED;
  493.                 }
  494.             }
  495.         }
  496.         //
  497.         return $this->check(nullfalsenull$gclId$gpId$datetime$amount);
  498.     }
  499.     /**
  500.      * @param int $stockBichiku
  501.      * @param string $datetime
  502.      * @param int $amount
  503.      * @return bool
  504.      */
  505.     protected function isBichikuAvailable($stockBichiku$datetime$amount)
  506.     {
  507.         //
  508.         $timeLimit self::TIME_LIMIT_BICHIKU;
  509.         $stock $stockBichiku;
  510.         //
  511.         return $this->isSokujitsuAvailable($timeLimit$stock$datetime$amount);
  512.     }
  513.     /**
  514.      * @param string $timeLimit
  515.      * @param int $stock
  516.      * @param string $datetime
  517.      * @param int $amount
  518.      * @return bool
  519.      */
  520.     protected function isSokujitsuAvailable($timeLimit$stock$datetime$amount)
  521.     {
  522.         //
  523.         $time date('H:i'strtotime($datetime));
  524.         //
  525.         return ($time $timeLimit) && ($stock && $amount <= $stock);
  526.     }
  527.     /***
  528.      * Check Time delivery is available
  529.      *
  530.      * @param string $timeLimit
  531.      * @param $datetime
  532.      * @return bool
  533.      */
  534.     protected function isTimeAvailable(string $timeLimit,$datetime)
  535.     {
  536.         $time date('H:i'strtotime($datetime));
  537.         return ($time $timeLimit);
  538.     }
  539.     /***
  540.      * Check amount product Order is available
  541.      *
  542.      * @param int $stock
  543.      * @param int $amount
  544.      * @return bool
  545.      */
  546.     protected function isAmountOrderAvailable(int $stockint $amount)
  547.     {
  548.         return $stock && $amount <= $stock;
  549.     }
  550.     /***
  551.      * Get status delivery
  552.      * 
  553.      * @param int $stock
  554.      * @param int $amount
  555.      * @param $timeLimit
  556.      * @param $datetime
  557.      * @param int $flg
  558.      * @return int
  559.      */
  560.     private function getStatusByStockAndTimeLimit($stock=0$amount=0$timeLimit$datetime$flg)
  561.     {
  562.         if (!self::isTimeAvailable($timeLimit$datetime)) {
  563.             $flg self::FLG_NG_DEADLINE_HAS_PASSED;
  564.         }
  565.         if (!self::isAmountOrderAvailable($stock$amount)) {
  566.             $flg self::FLG_NG_NUMBER_ORDER_EXCEEDS_SHIPPING_IN_DAY;
  567.         }
  568.         return $flg;
  569.     }
  570.     /***
  571.      * Get status delivery
  572.      *
  573.      * @param $sku
  574.      * @param $datetime
  575.      * @param $amount
  576.      * @param $isMatrix
  577.      * @param $timeLimit
  578.      * @return int
  579.      */
  580.     private function getFlagDelivery($sku$datetime$amount$isMatrix$timeLimit)
  581.     {
  582.         $flg self::FLG_NONE;
  583.         $lmHinban $sku->getLmHinban();
  584.         $makerHinban $sku->getMakerHinban();
  585.         $makerTimeLimit $sku->getTimeLimit();
  586.         $stockChokusou = (int)$sku->getStockChokusou();
  587.         $stockBichiku = (int)$sku->getStockBichiku();
  588.         $bichikuNyukaDate $sku->getBichikuNyukaDate();
  589.         if (!empty($bichikuNyukaDate)) {
  590.             $flg self::FLG_NG_YOYAKU;
  591.         } else if ($sku->getIsDirectDeliveryConfigExists() == 1) {
  592.             $makerHinbanCharcters preg_replace('/[^a-zA-Z]/'''$makerHinban);
  593.             $shiiresakiSoukoCharactersList $sku->getShiiresakiSoukoHanteiAsArray();
  594.             $chokusouIncludeHinbanList $sku->getChokusouIncludeHinbanListAsArray();
  595.             $chokusouExcludeHinbanList $sku->getChokusouExcludeHinbanListAsArray();
  596.             $bichikuIncludeHinbanList $sku->getBichikuIncludeHinbanListAsArray();
  597.             if ($this->isBichikuAvailable($stockBichiku$datetime$amount)) {
  598.                 $flg self::FLG_BICHIKU;
  599.             } else if (in_array($lmHinban$bichikuIncludeHinbanList)) {
  600.                 if ($this->isBichikuAvailable((!$isMatrix && !$amount) ? 999 $stockBichiku$datetime$amount)) {
  601.                     $flg self::FLG_BICHIKU;
  602.                 }
  603.             } else if (in_array($lmHinban$chokusouExcludeHinbanList)) {
  604.                 // 除外品番
  605.                 // 無条件で 即日発送不可 とする
  606.                 $flg self::FLG_NONE;
  607.             } else if (empty($chokusouIncludeHinbanList) || in_array($lmHinban$chokusouIncludeHinbanList)) {
  608.                 // メーカー直送品番(対象商品をLM品番で入力)
  609.                 if ($this->isSokujitsuAvailable($makerTimeLimit$stockChokusou$datetime$amount)) {
  610.                     $flg self::FLG_CHOKUSOU;
  611.                 }
  612.             } else if (empty($shiiresakiSoukoCharactersList) || in_array($makerHinbanCharcters$shiiresakiSoukoCharactersList)) {
  613.                 if ($this->isSokujitsuAvailable($makerTimeLimit$stockChokusou$datetime$amount)) {
  614.                     $flg self::FLG_CHOKUSOU;
  615.                 }
  616.             } else {
  617.                 // いずれにも該当しない場合
  618.                 // ※各種直送の設定漏れ時の救済(但しこの場合、備蓄のチェックのみとなる)
  619.                 error_log('[engine-sokujitsu-hassou] check it out(001).');
  620.             }
  621.             // add more condition to check quantity order, and deadline
  622.             if ($stockBichiku 0) {
  623.                 $flg self::getStatusByStockAndTimeLimit($stockBichiku$amount$timeLimit$datetime$flg);
  624.             } else if ($stockChokusou 0) {
  625.                 $flg self::getStatusByStockAndTimeLimit($stockChokusou$amount$makerTimeLimit$datetime$flg);
  626.             }
  627.         } else {
  628.             // 直送設定なし
  629.             if ($this->isBichikuAvailable($stockBichiku$datetime$amount)) {
  630.                 $flg self::FLG_BICHIKU;
  631.             }
  632.             if ($stockBichiku 0) {
  633.                 $flg self::getStatusByStockAndTimeLimit($stockBichiku$amount$timeLimit$datetime$flg);
  634.             } else if ($stockChokusou 0) {
  635.                 $flg self::getStatusByStockAndTimeLimit($stockChokusou$amount$makerTimeLimit$datetime$flg);
  636.             }
  637.         }
  638.         return $flg;
  639.     }
  640. }