app/Customize/Twig/Extension/ServiceExtension.php line 1161

Open in your IDE?
  1. <?php
  2. /**
  3.  * @version EC=CUBE4
  4.  * @copyright 株式会社 翔 kakeru.co.jp
  5.  * @author
  6.  * 2021年11月29日作成
  7.  *
  8.  * app\Customize\Twig\Extension\ServiceExtension.php
  9.  *
  10.  * TWIGからサービスの呼び出し
  11.  *
  12.  *
  13.  *
  14.  *                             C= C= C= ┌(;・_・)┘トコトコ
  15.  ******************************************************/
  16. namespace Customize\Twig\Extension;
  17. use Customize\Entity\CacheTrait;
  18. use Customize\Service\FavoriteService;
  19. use Customize\Service\ShoppingConfirmSendScheduleHelper;
  20. use Customize\Service\GoodsPriceService;
  21. use Customize\Service\Google\ReCaptchaService;
  22. use Customize\Service\InventoryMatrixService;
  23. use Customize\Service\OrderService;
  24. use Customize\Service\Payment\PaymentService;
  25. use Customize\Service\SampleService;
  26. use DOMNamedNodeMap;
  27. use DOMNode;
  28. use Eccube\Entity\CartItem;
  29. use Eccube\Entity\OrderItem;
  30. use Eccube\Repository\ClassCategoryRepository;
  31. use Eccube\Repository\ProductRepository;
  32. use Lm\Engine\EC\Entity\GoodsWithRelated;
  33. use Lm\Engine\EC\Entity\Item\Item;
  34. use Lm\Engine\EC\Entity\OrderHeaderExtended;
  35. use Lm\Engine\InventoryMatrix\InventoryMatrix;
  36. use Lm\Engine\Zaiko\Yoyaku;
  37. use Lm\Entity\Goods;
  38. use Lm\Entity\OrderHeader;
  39. use Lm\Service\Cache\CacheService;
  40. use Lm\Util\Date;
  41. use Detection\MobileDetect as MobileDetector;
  42. use Symfony\Component\DependencyInjection\ContainerInterface;
  43. use Symfony\Component\DomCrawler\Crawler;
  44. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  45. use Symfony\Component\HttpFoundation\RequestStack;
  46. use Twig\Extension\AbstractExtension;
  47. use Twig\TwigFunction;
  48. use Twig\TwigFilter;
  49. use Twig\Environment as Twig;
  50. use Customize\Service\LmHelper;
  51. use Customize\Service\CustomerService;
  52. use Customize\Service\CommonService;
  53. use Eccube\Repository\ProductClassRepository;
  54. use Eccube\Repository\OrderRepository;
  55. use Eccube\Repository\Master\PrefRepository;
  56. use Eccube\Repository\Master\JobRepository;
  57. use Lm\Service\Db\SqlService;
  58. use Lm\Engine\NoukiKeisan\NoukiKeisan as NoukiEngine;
  59. use Customize\Service\CatalogService;
  60. use Customize\Service\CartService;
  61. use Customize\Service\GoodsService;
  62. use Customize\Service\MetaTagService;
  63. use Customize\Service\EstimateCharacterizer;
  64. use Eccube\Repository\Master\OrderItemTypeRepository;
  65. use Customize\Converter\OrderConverter;
  66. use Customize\Service\OrderHelper;
  67. use Customize\Service\AutoLoadService;
  68. use Customize\Service\MobileDetector as LmMobileDetector;
  69. use Lm\Engine\SokujitsuHassou\SokujitsuHassou;
  70. use Twig\TwigTest;
  71. use Customize\Converter\ProductConverter;
  72. class ServiceExtension extends AbstractExtension
  73. {
  74.     use CacheTrait;
  75.     const Cache1 'EstimateProductClassIds';
  76.     const MetatagTwig 'Common/MetaTags.twig';
  77.     const BreadCrumTwig 'Common/BreadCrumb.twig';
  78.     const EstimateTwig 'Common/Estimate.twig';
  79.     const ExclusionTwig 'Cart/Parts/Exclusion.twig';
  80.     const CartAddLineTwig 'Cart/Parts/Responsive/AddLine.twig';
  81.     const ShoppingEstimate 'Shopping/Parts/Estimate.twig';
  82.     const MobileShoppingEstimate 'Common/MobileEstimate.twig';
  83.     const MailEstimate 'Mail/Parts/Estimate.twig';
  84.     const JWeek = ['日''月''火''水''木''金''土'];
  85.     /**
  86.      * @var Container
  87.      */
  88.     protected $Container;
  89.     protected $Session;
  90.     protected $RequestStack;
  91.     protected $LmHelper;
  92.     protected $CustomerService;
  93.     protected $CommonService;
  94.     protected $PrefRepository;
  95.     protected $JobRepository;
  96.     protected $Router;
  97.     protected $Request;
  98.     protected $CatalogService;
  99.     protected $CartService;
  100.     protected $CatalogValue;
  101.     protected $GoodsService;
  102.     protected $Twig;
  103.     /**
  104.      * @var ProductRepository
  105.      */
  106.     private $ProductRepository;
  107.     protected $ProductClassRepository;
  108.     protected $Bank;
  109.     protected $CacheService;
  110.     protected $MetaTagService;
  111.     protected $EstimateCharacterizer;
  112.     protected $OrderItemTypeRepository;
  113.     protected $PaymentDetails = [];
  114.     protected $EstimateOptions = [];
  115.     protected $OrderConverter;
  116.     protected $OrderRepository;
  117.     protected $EstimateType;
  118.     protected $AutoLoadService;
  119.     protected $CartSortFlg;
  120.     
  121.     /**
  122.      * @var array
  123.      */
  124.     protected $EstimateOptionsByEstimateId = [];
  125.     
  126.     /**
  127.      * @var array
  128.      */
  129.     protected $ItemIdToEstimateId = [];
  130.     
  131.     /**
  132.      * @var array
  133.      */
  134.     protected $AllOrderItems = [];
  135.     /**
  136.      * @var MobileDetector
  137.      */
  138.     private $mobileDetector;
  139.     /**
  140.      * @var LmMobileDetector
  141.      */
  142.     private $LmMobileDetector;
  143.     /**
  144.      * @var FavoriteService
  145.      */
  146.     private $FavoriteService;
  147.     /**
  148.      * @var SampleService
  149.      */
  150.     private $SampleService;
  151.     /**
  152.      * @var OrderService
  153.      */
  154.     private $OrderService;
  155.     private $paymentService;
  156.     private $reCaptchaService;
  157.     private $productConverter;
  158.     public function __construct(ContainerInterface      $Container,
  159.                                 SessionInterface        $Session,
  160.                                 RequestStack            $RequestStack,
  161.                                 LmHelper                $LmHelper,
  162.                                 CustomerService         $CustomerService,
  163.                                 CommonService           $CommonService,
  164.                                 PrefRepository          $PrefRepository,
  165.                                 JobRepository           $JobRepository,
  166.                                 CatalogService          $CatalogService,
  167.                                 CartService             $CartService,
  168.                                 GoodsService            $GoodsService,
  169.                                 Twig                    $Twig,
  170.                                 ProductRepository       $productRepository,
  171.                                 ProductClassRepository  $ProductClassRepository,
  172.                                 ClassCategoryRepository $ClassCategoryRepository,
  173.                                 CacheService            $CacheService,
  174.                                 MetaTagService          $MetaTagService,
  175.                                 EstimateCharacterizer   $EstimateCharacterizer,
  176.                                 OrderItemTypeRepository $OrderItemTypeRepository,
  177.                                 OrderService            $orderService,
  178.                                 OrderConverter          $OrderConverter,
  179.                                 OrderRepository         $OrderRepository,
  180.                                 GoodsPriceService       $GoodsPriceService,
  181.                                 AutoLoadService         $AutoLoadService,
  182.                                 MobileDetector          $mobileDetector,
  183.                                 LmMobileDetector        $LmMobileDetector,
  184.                                 FavoriteService         $FavoriteService,
  185.                                 SampleService           $SampleService,
  186.                                 PaymentService          $paymentService,
  187.                                 InventoryMatrixService  $inventoryMatrixService,
  188.                                 ReCaptchaService        $reCaptchaService,
  189.                                 ProductConverter        $productConverter
  190.     )
  191.     {
  192.         $this->Container $Container;
  193.         $this->Session $Session;
  194.         $this->RequestStack $RequestStack;
  195.         $this->LmHelper $LmHelper;
  196.         $this->CustomerService $CustomerService;
  197.         $this->CommonService $CommonService;
  198.         $this->PrefRepository $PrefRepository;
  199.         $this->JobRepository $JobRepository;
  200.         $this->Router $Container->get('router');
  201.         $this->Request $RequestStack->getCurrentRequest();
  202.         $this->CatalogService $CatalogService;
  203.         $this->CartService $CartService;
  204.         $this->GoodsService $GoodsService;
  205.         $this->Twig $Twig;
  206.         $this->ProductRepository $productRepository;
  207.         $this->ProductClassRepository $ProductClassRepository;
  208.         $this->ClassCategoryRepository $ClassCategoryRepository;
  209.         $this->CacheService $CacheService;
  210.         $this->MetaTagService $MetaTagService;
  211.         $this->EstimateCharacterizer $EstimateCharacterizer;
  212.         $this->OrderItemTypeRepository $OrderItemTypeRepository;
  213.         $this->OrderService $orderService;
  214.         $this->OrderConverter $OrderConverter;
  215.         $this->OrderRepository $OrderRepository;
  216.         $this->GoodsPriceService $GoodsPriceService;
  217.         $this->AutoLoadService $AutoLoadService;
  218.         $this->mobileDetector $mobileDetector;
  219.         $this->LmMobileDetector $LmMobileDetector;
  220.         $this->FavoriteService $FavoriteService;
  221.         $this->SampleService $SampleService;
  222.         $this->paymentService $paymentService;
  223.         $this->inventoryMatrixService $inventoryMatrixService;
  224.         $this->reCaptchaService $reCaptchaService;
  225.         $this->productConverter $productConverter;
  226.     }
  227.     public function getFunctions()
  228.     {
  229.         return [
  230.             new TwigFunction('Service', function ($Service) {
  231.                 return new $Service($this->Container$this->RequestStack);
  232.             }, ['pre_escape' => 'html''is_safe' => ['html']]),
  233.             new TwigFunction('LmCssList', [$this'GetLmCssList']),
  234.             new TwigFunction('LmCartType', [$this'GetLmCartType']),
  235.             new TwigFunction('FristLogin', [$this'GetFirstLogin']),
  236.             new TwigFunction('AmazonLogin', [$this'GetAmazonLogin']),
  237.             new TwigFunction('GetPrefs', [$this'GetPrefs']),
  238.             new TwigFunction('GetLmCuatomer', [$this'GetLmCuatomer']),
  239.             new TwigFunction('GetJob', [$this'GetJob']),
  240.             new TwigFunction('GetPrivacy3', [$this'GetPrivacy3']),
  241.             new TwigFunction('OlToken', [$this'GetOlToken']),
  242.             new TwigFunction('RequestLmOrderOption', [$this->CommonService'RequestLmOrderOption']),
  243.             new TwigFunction('Survey', [$this->CommonService'SetSurvey']),
  244.             new TwigFunction('SurveyData', [$this->CommonService'SetSurveyData']),
  245.             new TwigFunction('RequestUri', [$this'GetRequestUri']),
  246.             new TwigFunction('CouponData', [$this'GetCouponData']),
  247.             new TwigFunction('InitiarizeLmOrederOption', [$this'SetInitiarizeLmOrederOption']),
  248.             new TwigFunction('DiscountName', [$this'SetDiscountName']),
  249.             new TwigFunction('SetReceipt', [$this'SetReceipt']),
  250.             new TwigFunction('Receipt', [$this'GetReceipt']),
  251.             new TwigFunction('LmOptionName', [$this'GetLmOptionName']),
  252.             new TwigFunction('CatalogLimit', [$this->CatalogService'GetLimit']),
  253.             new TwigFunction('CatalogLimitMessage', [$this'CatalogLimitMessage']),
  254.             new TwigFunction('CatalogValidation', [$this->CatalogService'CatalogValidation']),
  255.             new TwigFunction('CatalogChecked', [$this'GetCatalogChecked']),
  256.             new TwigFunction('ShoppingTitle', [$this'SetShoppingTitle']),
  257.             new TwigFunction('ShoppingConfirmBtn', [$this'ShoppingConfirmBtn']),
  258.             new TwigFunction('GetCatalogViews', [$this'GetCatalogViews']),
  259.             new TwigFunction('GetSampleCatalogs', [$this->CatalogService'GetSampleCatalogs']),
  260.             new TwigFunction('CartSumImage', [$this'GetCartSumImage']),
  261.             new TwigFunction('GoodsMainImage', [$this'GetGoodsMainImage']),
  262.             new TwigFunction('CartItemPullDown', [$this'GetCartItemPullDown']),
  263.             new TwigFunction('LoadStockLabel', [$this'getStockLabel']),
  264.             new TwigFunction('CartItemSizePullDown', [$this'GetCartItemSizePullDown']),
  265.             new TwigFunction('CartItemColorPullDown', [$this'GetCartItemColorPullDown']),
  266.             new TwigFunction('lm_tax', [$this'GetLmTax']),
  267.             new TwigFunction('Caet_item_stock', [$this'GetCartItmeStock']),
  268.             new TwigFunction('CartItemSameDayShippingFlg', [$this'GetCartItemSameDayShippingFlg']),
  269.             new TwigFunction('CartItemStockNumber', [$this'GetCartItemStockNumber']),
  270.             new TwigFunction('GetConfig', [$this'GetConfig']),
  271.             new TwigFunction('GetCartNextBtnText', [$this'GetCartNextBtnText']),
  272.             new TwigFunction('GetCartBackBtnText', [$this'GetCartBackBtnText']),
  273.             new TwigFunction('GetShoppingNextBtnText', [$this'GetShoppingNextBtnText']),
  274.             new TwigFunction('GetShoppingBackBtnText', [$this'GetShoppingBackBtnText']),
  275.             new TwigFunction('GetLmOrderOption', [$this'GetLmOrderOption']),
  276.             new TwigFunction('Bank', [$this'GetBank']),
  277.             new TwigFunction('JunctionMode', [$this->CommonService'GetJunctionMode']),
  278.             new TwigFunction('CartHybridBtn', [$this'SetCartHybridBtn']),
  279.             new TwigFunction('CartHybridBtnByCartItem', [$this'ShowCartHybridBtnByCartItem']),
  280.             new TwigFunction('ShowOrderItem', [$this'SetShowOrderItem']),
  281.             new TwigFunction('ExclusionControl', [$this'SetExclusionControl']),
  282.             new TwigFunction('SetMetaTags', [$this'SetMetaTags']),
  283.             new TwigFunction('HeaderH1', [$this'SetHeaderH1']),
  284.             new TwigFunction('SetBreadCrumb', [$this'SetBreadCrumb']),
  285.             new TwigFunction('EstimateCharaCart', [$this'SetEstimateCharaCart']),
  286.             new TwigFunction('ItemType', [$this'GetItemType']),
  287.             new TwigFunction('isSliderEnabled', [$this'isSliderEnabled']),
  288.             new TwigFunction('PaymentDetails', [$this'GetPaymentDetails']),
  289.             new TwigFunction('SetEstimateOptions', [$this'SetEstimateOptions']),
  290.             new TwigFunction('SetEstimateOptionsForGroup', [$this'SetEstimateOptionsForGroup']),
  291.             new TwigFunction('ResetEstimateOptions', [$this'ResetEstimateOptions']),
  292.             new TwigFunction('GetEstimateOption', [$this'GetEstimateOption']),
  293.             new TwigFunction('ShowEstimateOptions', [$this'ShowEstimateOptions']),
  294.             new TwigFunction('ShowEstimateMobileOptions', [$this'ShowEstimateMobileOptions']),
  295.             new TwigFunction('ShowEstimateOptionsMail', [$this'ShowEstimateOptionsMail']),
  296.             new TwigFunction('ZeusCardDatas', [$this'GetZeusCardDatas']),
  297.             new TwigFunction('ZeusCardError', [$this'GetZeusCardError']),
  298.             new TwigFunction('EstimateType', [$this'GetEstimateType']),
  299.             new TwigFunction('GetCustomerBangou', [$this'GetCustomerBangou']),
  300.             new TwigFunction('NariKawariSession', [$this->AutoLoadService'GetNariKawariSession']),
  301.             new TwigFunction('NariKawariFormData', [$this->AutoLoadService'GetNariKawariFormData']),
  302.             new TwigFunction('GetCatalogNoukiSchedule', [$this'getCatalogNoukiSchedule']),
  303.             new TwigFunction('CartSortFlg', [$this'GetCartSortFlg']),
  304.             new TwigFunction('CartAddLine', [$this'GetCartAddLine']),
  305.             new TwigFunction('PageType', [$this'getPageType']),
  306.             new TwigFunction('isMobile', [$this'isMobile']),
  307.             new TwigFunction('wannaSeePc', [$this'wannaSeePc']),
  308.             new TwigFunction('CartBackBtn', [$this'GetCartBackBtn']),
  309.             new TwigFunction('WithGetParams', [$this'WithGetParams']),
  310.             new TwigFunction('PageWithGetParams', [$this'PageWithGetParams']),
  311.             new TwigFunction('ShowSendScheduleDate', [$this'showSendScheduleDate']),
  312.             new TwigFunction('ShowSendScheduleMessage', [$this'showSendScheduleMessage']),
  313.             new TwigFunction('ShowSendScheduleDateTo', [ShoppingConfirmSendScheduleHelper::class, 'getSendScheduleToLabel']),
  314.             new TwigFunction('GetCategoryImageUrlById', [$this'getCategoryImageUrlById']),
  315.             new TwigFunction('EigyoubiCalendar', [$this->CommonService'EigyoubiCalendar']),
  316.             new TwigFunction('GetOrderPaymentId', [$this'getOrderPaymentId']),
  317.             new TwigFunction('GetShippingAddr03', [$this->CustomerService'getShippingAddr03']),
  318.             new TwigFunction('GetLandMarkCustomerInfo', [$this->CustomerService'GetLandMarkCustomerId']),
  319.             new TwigFunction('CalculateTotalQuantityForOrder', [$this->CommonService'calculateTotalQuantityForOrder']),
  320.             new TwigFunction('getMessageForPayment', [$this->paymentService'getMessage']),
  321.             new TwigFunction('GetFavoriteFlashMessage', [$this->FavoriteService'getFavoriteFlashMessage']),
  322.             new TwigFunction('GetFavoriteFlashGoods', [$this->FavoriteService'getFavoriteFlashGoods']),
  323.             new TwigFunction('FileUploadNotice', [$this'showFileSizeUpload']),
  324.             new TwigFunction('GetSampleLimitError', [$this->SampleService'getSampleLimitError']),
  325.             new TwigFunction('formatDataToJson', [$this'formatDataToJson']),
  326.             new TwigFunction('getCurrentBreadcrumb', [$this'getCurrentBreadcrumb']),
  327.             new TwigFunction('getCartSessionName', [$this'getCartSessionName']),
  328.             new TwigFunction('groupItemsHasSameProductId', [$this'groupItemsHasSameProductId']),
  329.             new TwigFunction('getColorRGBCode', [$this'getColorRGBCode']),
  330.             new TwigFunction('formatDate', [$this'formatDate']),
  331.             new TwigFunction('formatSendScheduleArrivalPeriod', [$this'formatSendScheduleArrivalPeriod']),
  332.             new TwigFunction('formatMonthAndDay', [$this'formatMonthAndDay']),
  333.             new TwigFunction('formatStockArrivalDate', [$this'formatStockArrivalDate']),
  334.             new TwigFunction('getToTraceParent', function () {
  335.                 return $this->RequestStack->getCurrentRequest()->attributes->get('toTraceParent');
  336.             }),
  337.             new TwigFunction('getTrackId', function () {
  338.                 return $this->RequestStack->getCurrentRequest()->attributes->get('toTrackId');
  339.             }),
  340.             new TwigFunction('getInventoryMatrix', [$this'getInventoryMatrixData']),
  341.             new TwigFunction('shouldProcessReCaptcha', [$this->reCaptchaService'shouldProcessReCaptcha']),
  342.             new TwigFunction('showYoyakuFlag', [$this'showYoyakuFlag']),
  343.             new TwigFunction('showSokujitsuHassouBannerIfSo', [$this'showSokujitsuHassouBannerIfSo']),
  344.         ];
  345.     }
  346.     /**
  347.      * Get inventory matrix via cache
  348.      *
  349.      * @param GoodsWithRelated $goods
  350.      * @param $color
  351.      * @param $size
  352.      * @return mixed|null
  353.      * @throws \Psr\Cache\InvalidArgumentException
  354.      */
  355.     public function getInventoryMatrixData(GoodsWithRelated $goods, &$color null, &$size null)
  356.     {
  357.         $cacheKey $this->LmHelper->getCacheKey("getInventoryMatrixData", [$goods$color$size]);
  358.         $id $goods->getGoodsId();
  359.         $stock $this->GoodsService->getGoodsStock($id1); // value of stock is not should cache
  360.         return $this->getCacheByKey($cacheKey, function () use ($goods$color$size$stock$id) {
  361.             // JAN情報(=product_class id)
  362.             list($jan$janColor) = $this->productConverter->getGoodsJanById($id);
  363.             // 色情報
  364.             $color $this->GoodsService->getGoodsColorSelectSql($id);
  365.             // サイズ情報
  366.             $size $this->GoodsService->getGoodsSizeListById($id);
  367.             // 商品即日情報
  368.             $sokujitsu $this->GoodsService->getGoodsSameDayShipping($id1);
  369.             // 商品在庫情報
  370.             // 商品予約情報
  371.             $yoyaku $this->GoodsService->getGoodsReservation($id1);
  372.             // 商品入荷予定日情報
  373.             $yoteibi $this->GoodsService->getGoodsStockDate($id1);
  374.             // カートマトリックス用のデータ生成
  375.             $matrixData = [];
  376.             $matrixData_cnt = [];
  377.             $line 0;
  378.             $sizeMax = ($this->LmMobileDetector->isMobile() ? 999 8);
  379.             $max 0;
  380.             foreach ($color as $v1) {
  381.                 $line++;
  382.                 $line2 0;
  383.                 $no 1;
  384.                 foreach ($size as $v2) {
  385.                     if ($line2 % ($sizeMax) === 0) {
  386.                         $no++;
  387.                     } else {
  388.                         $max $line2 % ($sizeMax);
  389.                     }
  390.                     $tmpYoteibi NULL;
  391.                     if (!empty($yoteibi[$v1["gcl_id"]][$v2["gp_id"]]) and $sokujitsu[$v1["gcl_id"]][$v2["gp_id"]] <= SokujitsuHassou::FLG_NONE) {
  392.                         $tmpYoteibi date("n月j日"strtotime($yoteibi[$v1["gcl_id"]][$v2["gp_id"]]));
  393.                     }
  394.                     $matrixData_cnt[$no] = $max;
  395.                     $matrixData[$no][$line][$line2] = [
  396.                         'line' => $line,
  397.                         'product_id' => $jan[$v1["gcl_id"]][$v2["gp_id"]],
  398.                         'shiire_color' => $janColor[$v1["gcl_id"]][$v2["gp_id"]],
  399.                         'color' => $v1,
  400.                         'size' => $v2,
  401.                         'stock' => $stock[$v1["gcl_id"]][$v2["gp_id"]],
  402.                         'yoyaku' => $yoyaku[$v1["gcl_id"]][$v2["gp_id"]],
  403.                         'yoteibi' => $tmpYoteibi,
  404.                         'sokujitsu' => $sokujitsu[$v1["gcl_id"]][$v2["gp_id"]],
  405.                     ];
  406.                     $line2++;
  407.                 }
  408.             }
  409.             return $matrixData;
  410.         });
  411.     }
  412.     public function getFilters()
  413.     {
  414.         return [
  415.             new TwigFilter('Base', [$this'BaseInfo']),
  416.             new TwigFilter('LmPrice', [$this'GetLmPrice']),
  417.             new TwigFilter('FormatPrice', [$this'FormatPrice']),
  418.             new TwigFilter('phone', [$this'SetPhone']),
  419.             new TwigFilter('post', [$this'SetPost']),
  420.             new TwigFilter('jweek', [$this'SetJWeek']),
  421.             new TwigFilter('AjaxPrice', [$this->GoodsPriceService'embedGoodsPrice']),
  422.             new TwigFilter('OrderId', [$this->LmHelper'convertOrderToOrderId']),
  423.             new TwigFilter('InventoryMatrix', [$this'showInventoryMatrix']),
  424.             new TwigFilter('LmWebTeika', [$this'filterLmWebTeika']),
  425.             new TwigFilter('LmWebPrice', [$this'filterLmWebPrice']),
  426.         ];
  427.     }
  428.     public function getTests()
  429.     {
  430.         return [
  431.             new TwigTest('numeric''is_numeric'),
  432.         ];
  433.     }
  434.     /**
  435.      * Master Job をゲットする
  436.      *
  437.      * @return obj Job
  438.      */
  439.     public function GetPrefs()
  440.     {
  441.         return $this->PrefRepository->finsBy([], ['sort_no' => 'asc']);
  442.     }
  443.     public function GetJob()
  444.     {
  445.         return $this->JobRepository->findBy([], ['sort_no' => 'asc']);
  446.     }
  447.     /**
  448.      * TWIG に LMカートタイプを返す
  449.      *   cart_type:
  450.      * 1 -- 購入(加工なし)
  451.      * 2 -- 購入(加工あり(加工なしとの混在含む))
  452.      * 3 -- 貸出サンプル
  453.      * 4 -- カタログ請求
  454.      */
  455.     public function GetLmCartType()
  456.     {
  457.         return $this->LmHelper->getCartType();
  458.     }
  459.     /**
  460.      * 初回ログイン
  461.      *
  462.      */
  463.     public function GetFirstLogin()
  464.     {
  465.         $Flg $this->CustomerService->GetFirstLoginFlg();
  466.         $this->CustomerService->SetFirstLoginFlg(null);
  467.         return $Flg;
  468.     }
  469.     public function GetLmCuatomer($Eail)
  470.     {
  471.         if (!$Lmcustomer $this->CustomerService->GetLandMarkCustomerEmail($Eail)) {
  472.             $Columns $this->CommonService->GetYaml('LmCustomer.yaml');
  473.             foreach ($Columns as $Column) {
  474.                 switch ($Column) {
  475.                     case 'address03':
  476.                         $Lmcustomer['customer_address3'] = '';
  477.                         break;
  478.                     case 'fax_number':
  479.                         $Lmcustomer['customer_fax'] = '';
  480.                         break;
  481.                     default:
  482.                         $Lmcustomer[$Column] = '';
  483.                         break;
  484.                 }
  485.             }
  486.         };
  487.         return $Lmcustomer;
  488.     }
  489.     /**
  490.      * アマゾンログイン
  491.      *
  492.      */
  493.     public function GetAmazonLogin()
  494.     {
  495.         return $this->CustomerService->GetAmazonLoginFlg();
  496.     }
  497.     /**
  498.      *  LMプライバシーポリシーの取得
  499.      *
  500.      * @return string admin_privacy3
  501.      */
  502.     public function GetPrivacy3()
  503.     {
  504.         $Sql = new SqlService;
  505.         $Data $Sql->Table('admin_table')
  506.             ->Find();
  507.         return $Data['admin_privacy3'] ?? '';
  508.     }
  509.     /**
  510.      * オリジナルトークンを返す
  511.      * @param string $Cd
  512.      * @param string $name 'token'
  513.      *
  514.      * @return string $Token
  515.      */
  516.     public function GetOlToken($Cd$Name 'token')
  517.     {
  518.         return $this->CommonService->ResetToken($Cd$Name);
  519.     }
  520.     /**
  521.      * クーポンの値引き時 リダイレクト先URIを返す
  522.      *
  523.      */
  524.     public function GetRequestUri()
  525.     {
  526.         return $this->Request->server->get('REQUEST_URI');
  527.     }
  528.     /**
  529.      * クーポンのData
  530.      *
  531.      */
  532.     public function GetCouponData()
  533.     {
  534.         return $this->CommonService->GetLmOrderOption(CommonService::Lm_Option_Coupon);
  535.     }
  536.     /**
  537.      * 領収書
  538.      *
  539.      */
  540.     public function SetReceipt($CompanyName$Name$Write)
  541.     {
  542.         $Receipt $this->CommonService->GetLmOrderOption(CommonService::Lm_Option_Receipt);
  543.         $Re $Receipt;
  544.         $Re['flg'] = [''''];
  545.         if (!$Receipt) {
  546.             $Re['name'] = $CompanyName $CompanyName $Name;
  547.             $Re['flg'][0] = 'checked="checked"';
  548.             $Re['write'] = $Write;
  549.             $Re['comment'] = '';
  550.         } else {
  551.             $Re['flg'][$Receipt['flg']] = 'checked="checked"';
  552.         }
  553.         return $Re;
  554.     }
  555.     public function GetReceipt()
  556.     {
  557.         if (!$Receipt $this->CommonService->GetLmOrderOption(CommonService::Lm_Option_Receipt)) {
  558.             return false;
  559.         }
  560.         return $Receipt['flg'] == false $Receipt;
  561.     }
  562.     public function GetLmOptionName($Name null)
  563.     {
  564.         switch ($Name) {
  565.             case 'catalog':
  566.                 $Re CommonService::Lm_Option_Catalog;
  567.                 break;
  568.             case 'receipt';
  569.             default:
  570.                 $Re CommonService::Lm_Option_Receipt;
  571.                 break;
  572.         }
  573.         return $Re;
  574.     }
  575.     /**
  576.      * LMOrderPption 初期化
  577.      *
  578.      */
  579.     public function SetInitiarizeLmOrederOption($OrderId)
  580.     {
  581.         $this->CommonService->SetInitiarizeLmOrederOption($OrderId);
  582.     }
  583.     public function SetShoppingTitle($Message$Num)
  584.     {
  585.         $Message trans($Message);
  586.         if (is_null($Num)) {
  587.             return $Message;
  588.         }
  589.         return $this->LmHelper->getCartType() <= CartService::CartTypeEstimate $Num '.' $Message $Message;
  590.     }
  591.     /**
  592.      * 確認気年のボタン
  593.      *
  594.      * @return string
  595.      */
  596.     public function ShoppingConfirmBtn()
  597.     {
  598.         $Message 'front.shopping.checkout';
  599.         switch ($this->LmHelper->getCartType()) {
  600.             case CartService::CartTypeCatalog:
  601.                 $Message 'front.Shopping_Button04';
  602.                 break;
  603.             case CartService::CartTypeNormal:
  604.             default:
  605.                 break;
  606.         }
  607.         return $Message;
  608.     }
  609.     public function GetCatalogChecked($Id$Name null)
  610.     {
  611.         $Checked = ['''checked="checked"'];
  612.         if ('Open' == $Name) {
  613.             $OpenCtalog $this->CommonService->GetLmOrderOption('OpenCatalog');
  614.             if (is_null($OpenCtalog) && $Id == 0) {
  615.                 return $Checked[1];
  616.             }
  617.             return $Id == $OpenCtalog $Checked[1] : $Checked[0];
  618.         }
  619.         if (!$this->CatalogValue) {
  620.             if ($Value $this->CommonService->GetLmOrderOption(CommonService::Lm_Option_Catalog)) {
  621.                 $this->CatalogValue array_flip($Value);
  622.             }
  623.         }
  624.         if (isset($this->CatalogValue[$Id])) {
  625.             return $Checked[1];
  626.         }
  627.         return $Checked[0];
  628.     }
  629.     public function GetLmOrderOption($name)
  630.     {
  631.         return $this->CommonService->GetLmOrderOption($name);
  632.     }
  633.     /**
  634.      * LMOrderPption クーポン
  635.      * ショッピング 表示
  636.      *
  637.      * @return string $name
  638.      */
  639.     public function SetDiscountName()
  640.     {
  641.         return $this->CommonService->GetLmOrderOption(CommonService::Lm_Option_Coupon) ? 'クーポン' trans('common.discount');
  642.     }
  643.     /**
  644.      * カタログの札数メッセージ
  645.      *
  646.      * @param int num
  647.      *
  648.      * @return string メッセージ
  649.      */
  650.     public function CatalogLimitMessage($Num)
  651.     {
  652.         return str_replace('@@'$Numtrans('front.cart_catalog.message09'));
  653.     }
  654.     public function CatalogValidation()
  655.     {
  656.         if (CartService::CartTypeCatalog != $this->CartService->getCartType()) {
  657.             return false;
  658.         }
  659.         return $this->CatalogService->CatalogValidation();
  660.     }
  661.     public function GetCatalogViews()
  662.     {
  663.         return $this->CatalogService->GetView();
  664.     }
  665.     /**
  666.      * カートにて サムネイルのURLを生成する
  667.      *
  668.      */
  669.     public function GetCartSumImage($ProductId)
  670.     {
  671.         $Dir substr($ProductId, -1);
  672.         return "/goods.img/{$Dir}/{$ProductId}/main_sum.jpg";
  673.     }
  674.     /**
  675.      * カートにて サムネイルのURLを生成する
  676.      *
  677.      */
  678.     public function GetGoodsMainImage($ProductId)
  679.     {
  680.         $Dir substr($ProductId, -1);
  681.         return "/goods.img/{$Dir}/{$ProductId}/main.jpg";
  682.     }
  683.     /**
  684.      * LMの価格に対して 税込価格を返す
  685.      *
  686.      */
  687.     public function GetLmTax($ProductClassId)
  688.     {
  689.         $ProductClass $this->ProductClassRepository->find($ProductClassId);
  690.         return $ProductClass->getPrice02IncTax();
  691.     }
  692.     /**
  693.      * LM在庫数を返す
  694.      *
  695.      * 0 ・・・ 在庫なし
  696.      * 1以上 ・・・ 在庫あり
  697.      * # null ・・・ 99(入荷予定)
  698.      * #  *   ・・・ 999
  699.      *`@param int ClassId
  700.      *
  701.      * @return string 在庫数
  702.      */
  703.     public function GetCartItmeStock($ProductClass)
  704.     {
  705.         $ClassId $ProductClass->getId();
  706.         $Stock $this->GoodsService->getValidationStock($ClassId);
  707.         $Re '';
  708.         switch (true) {
  709.             case is_null($Stock):
  710.                 $Re trans('front.cart_item.title10');
  711.                 break;
  712.             case $Stock == 0:
  713.                 $Re trans('front.cart_item.title11');;
  714.                 break;
  715.             default:
  716.                 $Text $this->CommonService->GetConfig('ESTIMATE_TEXT');
  717.                 $Re $Text['Text23'] . number_format($Stock) . $Text['Text04'];
  718.                 break;
  719.         }
  720.         return $Re;
  721.     }
  722.     public function GetCartItemSameDayShippingFlg($ProductClass$quantity null)
  723.     {
  724.         if ($ProductClass) {
  725.             $result $this->GoodsService->getGoodsSameDayShipping($ProductClass->getProduct()->getId(), 0$ProductClass->getId(), nullnull$quantity);
  726.             return $result;
  727.         }
  728.         return false;
  729.     }
  730.     public function GetCartItemStockNumber($productClass$sameShippingFlg)
  731.     {
  732.         $stock $this->GoodsService->getGoodsStock(nullfalse$productClass->getId());
  733.         if ($sameShippingFlg SokujitsuHassou::FLG_NONE) {
  734.             return $stock['stock_sokujitsu'];
  735.         } else {
  736.             return $stock['stock_total'];
  737.         }
  738.     }
  739.     public function GetCartNextBtnText()
  740.     {
  741.         switch ($this->GetLmCartType()) {
  742.             case CartService::CartTypeSample:
  743.                 return 'サンプル申込の手続きへ';
  744.             case CartService::CartTypeNormal:
  745.             case CartService::CartTypeEstimate:
  746.             default:
  747.                 return '次へ(レジへ進む)';
  748.         }
  749.     }
  750.     public function GetCartBackBtnText()
  751.     {
  752.         switch ($this->GetLmCartType()) {
  753.             case CartService::CartTypeSample:
  754.                 return '他にもサンプル申込商品を選ぶ';
  755.             case CartService::CartTypeNormal:
  756.             case CartService::CartTypeEstimate:
  757.             default:
  758.                 return '買い物を続ける';
  759.         }
  760.     }
  761.     public function GetShoppingNextBtnText()
  762.     {
  763.         switch ($this->GetLmCartType()) {
  764.             case CartService::CartTypeSample:
  765.                 return '同意して次へ';
  766.             case CartService::CartTypeCatalog:
  767.                 return '送信する';
  768.             case CartService::CartTypeNormal:
  769.             case CartService::CartTypeEstimate:
  770.             default:
  771.                 return '確認画面に進む';
  772.         }
  773.     }
  774.     public function GetShoppingBackBtnText()
  775.     {
  776.         switch ($this->GetLmCartType()) {
  777.             case CartService::CartTypeCatalog:
  778.                 return '入力画面に戻る';
  779.             case CartService::CartTypeNormal:
  780.             case CartService::CartTypeEstimate:
  781.             case CartService::CartTypeSample:
  782.             default:
  783.                 return 'カートに戻る';
  784.         }
  785.     }
  786.     public function GetConfig($key)
  787.     {
  788.         return $this->LmHelper->getConfig($key);
  789.     }
  790.     public function getColorRGBCode($productId)
  791.     {
  792.         $colors = [];
  793.         $goodColors $this->GoodsService->getGoodsColorSelectSql($productId);
  794.         if (is_array($goodColors) && count($goodColors) > 0) {
  795.             foreach ($goodColors as $goodColor) {
  796.                 if (!$goodColor['color_name']) {
  797.                     continue;
  798.                 }
  799.                 $id $this->LmHelper->convGclIdToClassCategory1Id($goodColor['gcl_id']);
  800.                 $colors[$id] = $goodColor['color_rgb'];
  801.             }
  802.         }
  803.         return $colors;
  804.     }
  805.     public function GetCartItemColorPullDown($ItemId$ProductId$classCategory1Id$EstimateId$EmptyOptionAsFirst false$isAjaxCart false$classCategory2Id null)
  806.     {
  807.         //
  808.         $Type 'color';
  809.         //
  810.         $Data = [];
  811.         $Value null;
  812.         $Id 0;
  813.         //
  814.         $kbn 1;
  815.         if ($classCategory1Id) {
  816.             $ClassCategory1 $this->ClassCategoryRepository->find($classCategory1Id);
  817.             $Value $ClassCategory1->getId();
  818.             $ClassName $ClassCategory1->getClassName();
  819.             $kbn $ClassName->getId();
  820.         }
  821.         foreach ($this->GoodsService->getGoodsColorSelectSql($ProductId) as $Val) {
  822.             if (!$Val['color_name']) {
  823.                 continue;
  824.             }
  825.             $Id $this->LmHelper->convGclIdToClassCategory1Id($Val['gcl_id']);
  826.             $Selected = !$EmptyOptionAsFirst && $Value == $Id 'selected="selected"' '';
  827.             $Rgb 'data-rgb=#' $Val['color_rgb'];
  828.             $disabled '';
  829.             if($isAjaxCart && $classCategory2Id){
  830.                 $estId =  $classCategory2Id;
  831.                 $estId $this->LmHelper->convClassCategory2IdToGpIdRe($estId);
  832.                 try {
  833.                     $result = (new SqlService())
  834.                         ->Select('*')
  835.                         ->Table('jancode_table')
  836.                         ->Set('jan_color'$Val['gcl_id'])
  837.                         ->Set('jan_price'$estId)
  838.                         ->Find();
  839.                     if($result){
  840.                         if((is_null($result['jan_stock']) || $result['jan_stock'] > )){
  841.                             $disabled '';
  842.                         }else if((isset($result['jan_stock3']) && $result['jan_stock3'] > )){
  843.                             $disabled '';
  844.                         }else if((isset($result['jan_stock4']) && $result['jan_stock4'] > )){
  845.                             $disabled '';
  846.                         }else{
  847.                             $disabled 'disabled';
  848.                         }
  849.                     }else {
  850.                         $disabled '';
  851.                     }
  852.                 } catch (\Throwable $th) {
  853.                     $disabled '';
  854.                 }
  855.             }
  856.             $name = ($disabled == 'disabled') ? $Val['color_name'] . ' - 在庫切れ' $Val['color_name'];
  857.             $Data[$Id] = [
  858.                 'name' => $name,
  859.                 'Selected' => $Selected,
  860.                 'disabled' => $disabled,
  861.                 'Data' => $Rgb
  862.             ];
  863.         };
  864.         //
  865.         return $this->GetCartItemPullDown($ItemId$ProductId$Type$Data$Value$EstimateId$EmptyOptionAsFirst);
  866.     }
  867.     public function GetCartItemSizePullDown($ItemId$ProductId$classCategory2Id$classCategory1Id$EstimateId$EmptyOptionAsFirst false)
  868.     {
  869.         //
  870.         $Type 'size';
  871.         //
  872.         $Data = [];
  873.         $Value null;
  874.         $Id 0;
  875.         //
  876.         $kbn 2;
  877.         if ($classCategory2Id) {
  878.             $ClassCategory2 $this->ClassCategoryRepository->find($classCategory2Id);
  879.             $Value $ClassCategory2->getId();
  880.             $ClassName $ClassCategory2->getClassName();
  881.             $kbn $ClassName->getId();
  882.         }
  883.         if ($classCategory1Id) {
  884.             //
  885.             $ClassCategory1 $this->ClassCategoryRepository->find($classCategory1Id);
  886.             $sizeList $this->GoodsService->getGoodsSizeListWithStockInfoByClassCategory1($ClassCategory1);
  887.         } else {
  888.             $sizeList $this->GoodsService->getGoodsSizeListById($ProductId);
  889.         }
  890.         foreach ($sizeList as $Val) {
  891.             if (!$Val['size_name']) {
  892.                 continue;
  893.             }
  894.             $Id $this->LmHelper->convGpIdToClassCategory2Id($Val['gp_id']);
  895.             $Selected = !$EmptyOptionAsFirst && $Value == $Id 'selected="selected"' '';
  896.             $disabled = (isset($Val['disabled']) && $Val['disabled'] === 1) ? 'disabled' '';
  897.             $Data[$Id] = [
  898.                 'name' => $Val['size_name'],
  899.                 'Selected' => $Selected,
  900.                 'disabled' => $disabled,
  901.                 'Data' => ''
  902.             ];
  903.         };
  904.         //
  905.         return $this->GetCartItemPullDown($ItemId$ProductId$Type$Data$Value$EstimateId$EmptyOptionAsFirst);
  906.     }
  907.     public function GetCartItemPullDown($ItemId$ProductId$Type$ItemDatas$Value$EstimateId$EmptyOptionAsFirst false)
  908.     {
  909.         //
  910.         $Re = [
  911.             'ItemId' => $ItemId,
  912.             'ProductId' => $ProductId,
  913.             'Type' => $Type,
  914.             'ItemDatas' => $ItemDatas,
  915.             'Value' => $Value,
  916.             'EstimateId' => $EstimateId,
  917.             'EmptyOptionAsFirst' => $EmptyOptionAsFirst
  918.         ];
  919.         //
  920.         return $this->Twig->render('Cart/Parts/PullDown.twig'$Re);
  921.     }
  922.     public function getStockLabel($ProductId$ClassCategory1Id$ClassCategory2Id)
  923.     {
  924.         //
  925.         $context = [
  926.             'ProductClass' => $this->ProductClassRepository->findOneBy([
  927.                 'Product' => $ProductId,
  928.                 'ClassCategory1' => $ClassCategory1Id,
  929.                 'ClassCategory2' => $ClassCategory2Id,
  930.             ]),
  931.         ];
  932.         //
  933.         return $this->Twig->render('Cart/Parts/StockLabel.twig'$context);
  934.     }
  935.     public function GetBank($Name$Bancode '')
  936.     {
  937.         if (!$this->Bank) {
  938.             $Banks $this->CommonService->GetYaml('Bank.yaml');
  939.             if ($Bancode) {
  940.                 $this->Bank $Banks[1];
  941.                 $this->Bank['account'] = $Bancode;
  942.             } else {
  943.                 $this->Bank $Banks[0];
  944.             }
  945.         }
  946.         return $this->Bank[$Name];
  947.     }
  948.     /**
  949.      * ハイブリッドボタンの設置
  950.      * 1 サンプルは出力しない
  951.      * 2 加工できない商品は出力しない
  952.      * 3 分割対応  2022/10/20
  953.      */
  954.     public function SetCartHybridBtn($ProductId$EstimateId$ItemId$btnName null)
  955.     {
  956.         #1
  957.         if ($this->CartService->getCartType() >= CartService::CartTypeSample) {
  958.             return;
  959.         }
  960.         #2
  961.         if (!$Type GoodsService::getEnableEstimateTypeById($ProductId)) {
  962.             return;
  963.         }
  964.         #3
  965.         if (CartService::CartTypeEstimate == $this->CartService->GetCartType() &&
  966.             $this->CommonService->GetConfig('BunkaruFlg') == false) {
  967.             $this->EstimateType $this->EstimateType ?? $this->CartService->GetEstimateType();
  968.         }
  969.         if (is_numeric($ItemId)) {
  970.             $Itemids $ItemId;
  971.         } else {
  972.             $Ids = [];
  973.             foreach ($ItemId as $Item) {
  974.                 if ($Item->getEstimateId() != $EstimateId) {
  975.                     continue;
  976.                 }
  977.                 $productItemId $Item->getProductClass()->getProduct()->getId();
  978.                 if (!GoodsService::getEnableEstimateTypeById($productItemId)) {
  979.                     continue;
  980.                 }
  981.                 $Ids[] = $Item->getId();
  982.             }
  983.             $Itemids implode(','$Ids);
  984.         }
  985.         $Re = [
  986.             'ItemIds' => $Itemids,
  987.             'Name' => $btnName ?? trans('front.cart_item_button04_' $Type),
  988.             'EstimateId' => $EstimateId,
  989.             'Type' => $ProductId,
  990.         ];
  991.         return $this->Twig->render('Cart/Parts/CartHybridBtn.twig'$Re);
  992.     }
  993.     /**
  994.      * @param CartItem $CartItem
  995.      * @return string
  996.      */
  997.     public function ShowCartHybridBtnByCartItem(CartItem $CartItem)
  998.     {
  999.         //
  1000.         $ProductId $CartItem->getProductClass()->getProduct()->getId();
  1001.         $EstimateId $CartItem->getEstimateId();
  1002.         // TODO: 旧・セット品番への対応
  1003.         // // $ItemId = array_filter(is_array($CartItems = $CartItem->getCart()->getCartItems()) ? $CartItems : $CartItems->toArray(), function ($CartItem) {
  1004.         // //     /**
  1005.         // //      * @var CartItem $CartItem
  1006.         // //      */
  1007.         // //     return !$this->CartService->isProductNoOptions($CartItem->getProductClass()->getProduct()->getId());
  1008.         // // });
  1009.         $ItemId $CartItem->getCart()->getCartItems();
  1010.         $btnName $CartItem->isSusoage() ? '裾上げ内容の変更' '加工内容の変更';
  1011.         //
  1012.         return $this->SetCartHybridBtn($ProductId$EstimateId$ItemId$btnName);
  1013.     }
  1014.     public function SetShowOrderItem($Order$Type)
  1015.     {
  1016.         $Item null;
  1017.         foreach ($Order->getOrderItems() as $OrderItem) {
  1018.             $OrderItemType $OrderItem->getOrderItemType();
  1019.             if ($Type == $OrderItemType->getId()) {
  1020.                 $Item $OrderItem;
  1021.             }
  1022.         };
  1023.         if (!$Item) {
  1024.             return '';
  1025.         }
  1026.         $Re = [
  1027.             'Item' => $Item,
  1028.             'Type' => $Item->getOrderItemType(),
  1029.         ];
  1030.         return $this->Twig->render('Shopping/Parts/OrderItem.twig'$Re);
  1031.     }
  1032.     /**
  1033.      * カート排他制御
  1034.      *
  1035.      */
  1036.     public function SetExclusionControl()
  1037.     {
  1038.         $Type '';
  1039.         if (!$Type $this->Session->get(CartService::Session_ExclusionControlFlg)) {
  1040.             return;
  1041.         };
  1042.         #2022/10/22 リピート注文特殊処理 Cartエラーで返せない
  1043.         switch ($Type) {
  1044.             case CartService::RepeatError01:
  1045.                 $Messages[] = trans('front.Cart.Repeat_message01');
  1046.                 break;
  1047.             case CartService::RepeatError02:
  1048.                 $Messages[] = trans('front.ExclusionControl.message04');
  1049.                 break;
  1050.             case CartService::RepeatError03:
  1051.                 $Messages[] = trans('front.ExclusionControl.message05');
  1052.                 break;
  1053.             default:
  1054.                 for ($i 1$i <= 2$i++) {
  1055.                     $Messages[] = $this->CommonService->SetExclusionControl($Type$i);
  1056.                 }
  1057.                 break;
  1058.         }
  1059.         $this->Session->set(CartService::Session_ExclusionControlFlgnull);
  1060.         return $this->Twig->render(self::ExclusionTwig,
  1061.             [
  1062.                 'Messages' => $Messages,
  1063.             ]);
  1064.     }
  1065.     public function SetMetaTags($Datas)
  1066.     {
  1067.         $Key array_key_first($Datas);
  1068.         $Data $Datas[$Key] ?? null;
  1069.         switch (true) {
  1070.             case $Key === 'item':
  1071.                 $this->MetaTagService->SetItem($Datas[$Key]);
  1072.                 $Image $this->LmHelper->getGoodsImageUrl($Data['goods_id'], 'main.jpg');
  1073.                 $this->MetaTagService->SetOpgs(4$Image);
  1074.                 break;
  1075.             case $Key === 'SubCategory':
  1076.             case $Key === 'Category':
  1077.                 $this->MetaTagService->SetCategory($Datas[$Key]);
  1078.                 $this->MetaTagService->SetOpgs();
  1079.                 break;
  1080.             case $Key === 'message':
  1081.                 $this->MetaTagService->SetMessage($Datas[$Key]);
  1082.                 $this->MetaTagService->SetOpgs();
  1083.                 break;
  1084.             case $Key === 'review':
  1085.                 $this->MetaTagService->SetReview($Datas[$Key]);
  1086.                 $this->MetaTagService->SetOpgs(4);
  1087.                 break;
  1088.             case $Key === 0:
  1089.                 $this->MetaTagService->SetMetaTags($Data); //
  1090.                 break;
  1091.             default:
  1092.                 $this->MetaTagService->SetMetaPages(); //
  1093.                 break;
  1094.         }
  1095.         return $this->Twig->render(self::MetatagTwig, [
  1096.             'Title' => $this->MetaTagService->GetTitle(),
  1097.             'MetaTags' => $this->MetaTagService->GetMetaTags(),
  1098.             'Opgs' => $this->MetaTagService->GetOpgs(),
  1099.             'UrlName' => $this->Request->get('_route'),
  1100.         ]);
  1101.     }
  1102.     public function SetHeaderH1()
  1103.     {
  1104.         return $this->MetaTagService->GetHeaderH1();
  1105.     }
  1106.     /**
  1107.      * パンクズを一括管理する
  1108.      * @param $BreadCrumbs  string | array none 非表示
  1109.      * 1 第一因子を TOPページとする 固定
  1110.      * 2 BreadCrumbsのKEYを1にすると 最後に ページ名を追加します
  1111.      * 3 配列の内容は、KEYが href' 'label' になります
  1112.      */
  1113.     public function SetBreadCrumb($BreadCrumbs)
  1114.     {
  1115.         $Type $BreadCrumbs[0] ?? null;
  1116.         if (!is_array($Type) && $Type == 'none') {
  1117.             return;
  1118.         }
  1119.         $this->getBreadCrumb('homepage');
  1120.         $Re[] = $this->getBreadCrumb('homepage');
  1121.         #第一因子 (0)
  1122.         $UrlName $this->Request->get('_route');
  1123.         if (count($BreadCrumbs) > 0) {
  1124.             foreach ($BreadCrumbs as $Key => $BreadCrumb) {
  1125.                 $BC['label'] = $BreadCrumb['label'] ?? '';
  1126.                 $BC['href'] = $BreadCrumb['href'] ?? '';
  1127.                 switch (array_key_first($BreadCrumbs)) {
  1128.                     case 1:
  1129.                         $Re[] = $BC;
  1130.                         $Re[] = $this->getBreadCrumb($UrlName);
  1131.                         break;
  1132.                     default:
  1133.                         $Re[] = $BC;
  1134.                 }
  1135.             }
  1136.         } else {
  1137.             $Re[] = $this->getBreadCrumb($UrlName);
  1138.         }
  1139.         return $this->Twig->render(self::BreadCrumTwig, [
  1140.             'BreadCrumbs' => $Re,
  1141.         ]);
  1142.     }
  1143.     protected function getBreadCrumb($UrlName)
  1144.     {
  1145.         $Name $this->CommonService->GetPagename($UrlName);
  1146.         switch ($UrlName) {
  1147.             case 'cart':
  1148.                 if ($this->LmHelper->getCartType() == 4) {
  1149.                     $MetaTags $this->CommonService->GetYaml(CommonService::MetaTagData);
  1150.                     $Name $MetaTags['catalog']['PageName'];
  1151.                 }
  1152.                 break;
  1153.             case 'shopping_login':
  1154.                 $Name "ログイン";
  1155.                 break;
  1156.             default:
  1157.                 break;
  1158.         }
  1159.         try {
  1160.             return [
  1161.                 'href' => $this->Router->generate($UrlName) ?? '',
  1162.                 'label' => $this->LmHelper->display_text($Name)
  1163.             ];
  1164.         } catch (\Throwable $e) {
  1165.             return $this->getBreadCrumb('homepage');
  1166.         } catch (\Exception $e) {
  1167.             return $this->getBreadCrumb('homepage');
  1168.         }
  1169.     }
  1170.     public function getCurrentBreadcrumb()
  1171.     {
  1172.         $Re[] = $this->getBreadCrumb('homepage');
  1173.         $UrlName $this->Request->get('_route');
  1174.         $Re[] = $this->getBreadCrumb($UrlName);
  1175.         return $Re;
  1176.     }
  1177.     /**
  1178.      * 見積もりシミュレーション文字化
  1179.      *
  1180.      */
  1181.     public function SetEstimateCharaCart($CartKey$EstimateId$Options$isDisplayOnSp false)
  1182.     {
  1183.         if (!$Option $Options[$CartKey][$EstimateId] ?? null) {
  1184.             return;
  1185.         }
  1186.         if ($isDisplayOnSp) {
  1187.             return $this->Twig->render('Common/EstimateMobile.twig', [
  1188.                 'Prints' => $Option['print'] ?? [],
  1189.                 'Susoage' => $Option['susoage'] ?? '',
  1190.                 'Lot' => $Option['lot'] ?? null,
  1191.             ]);
  1192.         }
  1193.         return $this->Twig->render(self::EstimateTwig, [
  1194.             'Prints' => $Option['print'] ?? [],
  1195.             'Susoage' => $Option['susoage'] ?? '',
  1196.             'Lot' => $Option['lot'] ?? null,
  1197.         ]);
  1198.     }
  1199.     public function GetItemType($Id$Flg null)
  1200.     {
  1201.         $ItemType $this->OrderItemTypeRepository->find($Id);
  1202.         return $ItemType->getName();
  1203.     }
  1204.     public function GetPaymentDetails($Param$Items)
  1205.     {
  1206.         foreach ($Items as $Item) {
  1207.             $Type $Item->getOrderItemTypeId();
  1208.             if ($Type == $Param) {
  1209.                 return $Item->getPrice();
  1210.             }
  1211.         }
  1212.         return null;
  1213.     }
  1214.     /**
  1215.      * Reset AllOrderItems for proper setLots calculation
  1216.      * @return void
  1217.      */
  1218.     public function ResetEstimateOptions()
  1219.     {
  1220.         $this->AllOrderItems = [];
  1221.         $this->EstimateOptionsByEstimateId = [];
  1222.     }
  1223.     /**
  1224.      * @param OrderItem[] $Items
  1225.      * @return void
  1226.      */
  1227.     public function SetEstimateOptions($Items)
  1228.     {
  1229.         foreach ($Items as $Item) {
  1230.             $this->AllOrderItems[] = $Item;
  1231.         }
  1232.         
  1233.         $this->EstimateOptions = [];
  1234.         $this->ItemIdToEstimateId = [];
  1235.         $EstimetIds = [];
  1236.         $Options = [];
  1237.         $I null;
  1238.         $Num 1;
  1239.         $ItemCount 0;
  1240.         foreach ($Items as $Item) {
  1241.             $ProductClass $Item->getProductClass();
  1242.             $Product $ProductClass->getProduct();
  1243.             $EstimetIds[$Product->getId()][$Item->getEstimateId()] = $Item->getId();
  1244.             $Options[$Item->getId()] = $Item->getOptions();
  1245.             $this->ItemIdToEstimateId[$Item->getId()] = is_object($Item->getEstimateId()) ? (int) (string) $Item->getEstimateId() : (int) $Item->getEstimateId();
  1246.             $L $Product->getId() . '-' $Item->getEstimateId();
  1247.             if ($I != $L) {
  1248.                 $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['h'] = $Item->getId();
  1249.                 $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['n'] = $Num;
  1250.                 $Num++;
  1251.                 $ItemCount 0;
  1252.             }
  1253.             $I $L;
  1254.             $ItemCount++;
  1255.             $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['f'] = $Item->getId();
  1256.             $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['ItemCount'] = $ItemCount;
  1257.         }
  1258.         foreach ($EstimetIds as $ProductId) {
  1259.             foreach ($ProductId as $Id) {
  1260.                 $this->EstimateOptions[$Id] = $Options[$Id];
  1261.             }
  1262.         }
  1263.         // Always recalculate EstimateOptionsByEstimateId to ensure proper setLots calculation
  1264.         // This ensures all items are considered together for lot calculation
  1265.         list($total$optionsByEstimateId) = $this->EstimateCharacterizer->SetEstimateOption($this->AllOrderItems, [], 'shopping');
  1266.         $this->EstimateOptionsByEstimateId $optionsByEstimateId;
  1267.     }
  1268.     /**
  1269.      * Set estimate options for a specific group of items (for split orders)
  1270.      * This calculates estimates separately for each group without affecting other groups
  1271.      * 
  1272.      * @param OrderItem[] $Items
  1273.      * @return void
  1274.      */
  1275.     public function SetEstimateOptionsForGroup($Items)
  1276.     {
  1277.         $EstimetIds = [];
  1278.         $Options = [];
  1279.         $I null;
  1280.         $Num 1;
  1281.         $ItemCount 0;
  1282.         
  1283.         foreach ($Items as $Item) {
  1284.             $ProductClass $Item->getProductClass();
  1285.             $Product $ProductClass->getProduct();
  1286.             $EstimetIds[$Product->getId()][$Item->getEstimateId()] = $Item->getId();
  1287.             $Options[$Item->getId()] = $Item->getOptions();
  1288.             $this->ItemIdToEstimateId[$Item->getId()] = is_object($Item->getEstimateId()) ? (int) (string) $Item->getEstimateId() : (int) $Item->getEstimateId();
  1289.             $L $Product->getId() . '-' $Item->getEstimateId();
  1290.             if ($I != $L) {
  1291.                 $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['h'] = $Item->getId();
  1292.                 $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['n'] = $Num;
  1293.                 $Num++;
  1294.                 $ItemCount 0;
  1295.             }
  1296.             $I $L;
  1297.             $ItemCount++;
  1298.             $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['f'] = $Item->getId();
  1299.             $this->CartSortFlg[$Product->getId()][$Item->getEstimateId()]['ItemCount'] = $ItemCount;
  1300.         }
  1301.         
  1302.         // Bind merged options to the head item id per estimate
  1303.         foreach ($EstimetIds as $ProductId => $estimateMap) {
  1304.             foreach ($estimateMap as $estimateId => $headCandidateId) {
  1305.                 $headId $this->CartSortFlg[$ProductId][$estimateId]['h'] ?? $headCandidateId;
  1306.                 $this->EstimateOptions[$headId] = $Options[$headId] ?? null;
  1307.             }
  1308.         }
  1309.         // Calculate estimates separately for this group only
  1310.         list($total$optionsByEstimateId) = $this->EstimateCharacterizer->SetEstimateOption($Items, [], 'shopping');
  1311.         
  1312.         // Merge the results into the main EstimateOptionsByEstimateId
  1313.         foreach ($optionsByEstimateId as $estimateId => $options) {
  1314.             $this->EstimateOptionsByEstimateId[$estimateId] = $options;
  1315.         }
  1316.     }
  1317.     public function GetEstimateOption($Id$Page 'Shopping')
  1318.     {
  1319.         $estimateId $this->ItemIdToEstimateId[$Id] ?? null;
  1320.         
  1321.         if (!$estimateId || !isset($this->EstimateOptionsByEstimateId[$estimateId])) {
  1322.             return;
  1323.         }
  1324.         $EstimateOption $this->EstimateOptionsByEstimateId[$estimateId];
  1325.         return [
  1326.             'print' => $EstimateOption['print'] ?? [],
  1327.             'susoage' => $EstimateOption['susoage'] ?? '',
  1328.             'lot' => $EstimateOption['lot'] ?? null,
  1329.         ];
  1330.     }
  1331.     public function ShowEstimateOptions($Id)
  1332.     {
  1333.         $estimateId $this->ItemIdToEstimateId[$Id] ?? null;
  1334.         
  1335.         if (!$estimateId || !isset($this->EstimateOptionsByEstimateId[$estimateId])) {
  1336.             return;
  1337.         }
  1338.         $Option $this->EstimateOptionsByEstimateId[$estimateId];
  1339.         return $this->Twig->render(self::ShoppingEstimate, [
  1340.             'Prints' => $Option['print'] ?? [],
  1341.             'Susoage' => $Option['susoage'] ?? '',
  1342.             'Lot' => $Option['lot'] ?? null,
  1343.         ]);
  1344.     }
  1345.     public function ShowEstimateMobileOptions($item)
  1346.     {
  1347.         $estimateId $this->ItemIdToEstimateId[$item->getId()] ?? null;
  1348.         
  1349.         if (!$estimateId || !isset($this->EstimateOptionsByEstimateId[$estimateId])) {
  1350.             return;
  1351.         }
  1352.         $Option $this->EstimateOptionsByEstimateId[$estimateId];
  1353.         return $this->Twig->render(self::MobileShoppingEstimate, [
  1354.             'orderItem' => $item,
  1355.             'Prints' => $Option['print'] ?? [],
  1356.             'Susoage' => $Option['susoage'] ?? '',
  1357.             'Lot' => $Option['lot'] ?? null,
  1358.             'ProductClass' => $item->getProductClass(),
  1359.         ]);
  1360.     }
  1361.     public function ShowEstimateOptionsMail($Id$SubTotal)
  1362.     {
  1363.         $estimateId $this->ItemIdToEstimateId[$Id] ?? null;
  1364.         
  1365.         if (!$estimateId || !isset($this->EstimateOptionsByEstimateId[$estimateId])) {
  1366.             return;
  1367.         }
  1368.         $Option $this->EstimateOptionsByEstimateId[$estimateId];
  1369.         return $this->Twig->render(self::MailEstimate, [
  1370.             'Prints' => $Option['print'] ?? [],
  1371.             'Susoage' => $Option['susoage'] ?? '',
  1372.             'Lot' => $Option['lot'] ?? null,
  1373.             'kakouhi' => $Option['total'] ?? 0,
  1374.             'OptionSubTotal' => ($Option['total'] ?? 0) + ($Option['lot']['total'] ?? 0) + ($Option['product_total'] ?? 0),
  1375.         ]);
  1376.     }
  1377.     public function GetCartSortFlg($Item$Flg 'h')
  1378.     {
  1379.         $ProductClass $Item->getProductClass();
  1380.         $Product $ProductClass->getProduct();
  1381.         $ProductId $Product->getId();
  1382.         $EstimateId $Item->getEstimateId();
  1383.         $ItemId $Item->getId();
  1384.         switch ($Flg) {
  1385.             case 'f' :
  1386.                 return $this->CartSortFlg[$ProductId][$EstimateId][$Flg] == $ItemId true false;
  1387.                 break;
  1388.             case 'n':
  1389.                 return $this->CartSortFlg[$ProductId][$EstimateId][$Flg];
  1390.                 break;
  1391.             case 'ItemCount':
  1392.                 return $this->CartSortFlg[$ProductId][$EstimateId][$Flg];
  1393.             case 'h':
  1394.             default:
  1395.                 return $this->CartSortFlg[$ProductId][$EstimateId][$Flg] == $ItemId true false;
  1396.                 break;
  1397.         }
  1398.     }
  1399.     public function GetZeusCardDatas($Name$Order)
  1400.     {
  1401.         $Value '';
  1402.         switch ($Name) {
  1403.             case 'money':
  1404.                 $Value $this->OrderService->calculateCreditTotal($Order);
  1405.                 break;
  1406.             case 'sendid':
  1407.                 $Customer $Order->getCustomer();
  1408.                 $LmCustomer $this->CustomerService->GetLandMarkCustomerId($Customer->getLmCustomerId(), true);
  1409.                 $Value $LmCustomer['customer_bangou'];
  1410.                 break;
  1411.             case 'sendpoint':
  1412.                 $Value $Order->getZeusRequestData();
  1413.                 break;
  1414.             case 'telno':
  1415.                 $Value $Order->getPhoneNumber();
  1416.                 break;
  1417.             case 'email':
  1418.                 $Value $Order->getEmail();
  1419.                 break;
  1420.         }
  1421.         return $Value;
  1422.     }
  1423.     /**
  1424.      * ZeusCardError
  1425.      * カードエラーの場合表示する
  1426.      *
  1427.      */
  1428.     public function GetZeusCardError()
  1429.     {
  1430.         $CardError false;
  1431.         if ($OrderId $this->Session->get(OrderHelper::SESSION_ORDER_ID)) {
  1432.             $Order $this->OrderRepository->find($OrderId);
  1433.             $Paymenr $Order->getPayment();
  1434.             if ($this->CommonService->GetConfig('ZEUS_CARD_PAYMAET_ID') == $Paymenr->getId()) {
  1435.                 $CardError $Order->getLmOrderId();
  1436.             }
  1437.             $this->Session->get(OrderHelper::SESSION_ORDER_IDnull);
  1438.         }
  1439.         return $CardError;
  1440.     }
  1441.     public function GetEstimateType()
  1442.     {
  1443.         if ($this->CommonService->getConfig('BunkaruFlg')) {
  1444.             return 0;
  1445.         }
  1446.         switch ($this->CartService->GetCartType()) {
  1447.             case CartService::CartTypeEstimate:
  1448.                 return $this->CartService->getEstimateType();
  1449.                 break;
  1450.             case CartService::CartTypeNormal:
  1451.             default:
  1452.                 return 0;
  1453.                 break;
  1454.         }
  1455.     }
  1456.     public function GetCartAddLine($CartItem)
  1457.     {
  1458.         $Item $this->GetCartItemData($CartItem);
  1459.         $lineItemId $Item['EstimateId'] . '-' $Item['ProductId'];
  1460.         return $this->Twig->render(self::CartAddLineTwig, [
  1461.             'num' => $this->GetCartSortFlg($CartItem'n'),
  1462.             'ItemId' => $CartItem->getId(),
  1463.             'ProductId' => $Item['ProductId'],
  1464.             'ProductClass' => $Item['ProductClass'],
  1465.             'ClassCategory1Id' => $Item['ClassCategory1Id'],
  1466.             'ClassCategory2Id' => $Item['ClassCategory2Id'],
  1467.             'EstimateId' => $Item['EstimateId'],
  1468.             'lineItemId' => $lineItemId,
  1469.         ]);
  1470.     }
  1471.     protected function GetCartItemData($CartItem)
  1472.     {
  1473.         $ProductClass $CartItem->getProductClass();
  1474.         $Product $ProductClass->getProduct();
  1475.         $ClassCategory1 is_null($ProductClass) ? null $ProductClass->getClassCategory1();
  1476.         $ClassCategory1Id is_null($ClassCategory1) ? null $ClassCategory1->getId();
  1477.         $ClassCategory2 is_null($ProductClass) ? null $ProductClass->getClassCategory2();
  1478.         $ClassCategory2Id is_null($ClassCategory2) ? null $ClassCategory2->getId();
  1479.         return [
  1480.             'ProductClass' => $ProductClass,
  1481.             'Product' => $Product,
  1482.             'ProductId' => $Product->getId(),
  1483.             'ClassCategory1Id' => $ClassCategory1Id,
  1484.             'ClassCategory2Id' => $ClassCategory2Id,
  1485.             'EstimateId' => $CartItem->getEstimateId(),
  1486.         ];
  1487.     }
  1488.     public function GetCartBackBtn()
  1489.     {
  1490.         return $this->LmHelper->getBackUrl();
  1491.     }
  1492.     /********************************************************************************************************************* */
  1493.     /**
  1494.      * メッセージのbaseinfo config Messegeを 変換する
  1495.      * 例 
  1496.      *  {{BaseInfo.shop_name}}
  1497.      *  {{Config.Payment_Charge_free}}
  1498.      *  {{message.common.ResetPassward_messeg02}} or {{trans.common.ResetPassward_messeg02}}
  1499.      */
  1500.     public function BaseInfo($Text)
  1501.     {
  1502.         //     return $Text;
  1503.         return $this->CommonService->BaseInfo($Text);
  1504.     }
  1505.     /**
  1506.      * LMのプライス出力フォーマット
  1507.      * @param int $Price
  1508.      * @param string|false $yen
  1509.      */
  1510.     public function GetLmPrice($Price$yen '円')
  1511.     {
  1512.         if (!is_numeric($Price)) {
  1513.             return $Price;
  1514.         }
  1515.         if ($yen === false) {
  1516.             $yen '';
  1517.         }
  1518.         return number_format($Price) . $yen;
  1519.     }
  1520.     public function FormatPrice($Price)
  1521.     {
  1522.         if (!is_numeric($Price)) {
  1523.             return $Price;
  1524.         }
  1525.         return number_format($Price) . '<span class="prices-unit">円</span>';
  1526.     }
  1527.     /**
  1528.      * LMのプライス出力フォーマット
  1529.      *
  1530.      */
  1531.     public function SetPhone($Phone)
  1532.     {
  1533.         return $this->CommonService->GetPhoneNumber($Phonefalse);
  1534.     }
  1535.     public function SetPost($Post)
  1536.     {
  1537.         $Post str_replace('-'''$Post);
  1538.         if (strlen($Post) < 7) {
  1539.             return $Post;
  1540.         }
  1541.         return substr($Post03) . '-' substr($Post34);
  1542.     }
  1543.     public function SetJWeek($Da)
  1544.     {
  1545.         return \Lm\Util\Date::weekDay($Da\Lm\Util\Date::COUNTRY_JP);
  1546.     }
  1547.     public function GetLmCssList()
  1548.     {
  1549.         //
  1550.         $context = [];
  1551.         //
  1552.         $cssConfig $this->CommonService->GetConfig('Css');
  1553.         $cssRoot $cssConfig['Root'];
  1554.         $cssIndex $cssConfig['CssList'];
  1555.         $cssList = [];
  1556.         //
  1557.         $deviceType strtolower($this->CommonService->GetDevice(false$this->LmMobileDetector));
  1558.         //
  1559.         $pageTypeConfig $this->LmHelper->getPageType();
  1560.         $pageType $pageTypeConfig['type'];
  1561.         //
  1562.         $cssList array_merge($cssList$cssIndex[$deviceType]['common']);
  1563.         $cssList array_merge($cssList$cssIndex[$deviceType][$pageType]);
  1564.         //
  1565.         foreach ($cssList as $css) {
  1566.             $context['CssList'][] = [
  1567.                 'href' => "{$cssRoot}/{$deviceType}/{$css}",
  1568.             ];
  1569.         }
  1570.         //
  1571.         return $this->Twig->render('Common/CssList.twig'$context);
  1572.     }
  1573.     public function isSliderEnabled()
  1574.     {
  1575.         return $this->LmHelper->filterSliderEnabled();
  1576.     }
  1577.     public function GetCustomerBangou($lmCustomerId)
  1578.     {
  1579.         //
  1580.         $result = (new SqlService())
  1581.             ->Select('customer_bangou')
  1582.             ->Table('customer_table')
  1583.             ->Set('customer_id'$lmCustomerId)
  1584.             ->Find();
  1585.         //
  1586.         $customerBangou $result['customer_bangou'];
  1587.         //
  1588.         return $customerBangou;
  1589.     }
  1590.     public function getCatalogNoukiSchedule()
  1591.     {
  1592.         //
  1593.         return (new NoukiEngine())
  1594.             ->getCatalogSendDate();
  1595.     }
  1596.     public function getPageType()
  1597.     {
  1598.         return $this->LmHelper->getPageType();
  1599.     }
  1600.     /**
  1601.      * @param bool|false $strict
  1602.      * @return bool
  1603.      */
  1604.     public function isMobile($strict false)
  1605.     {
  1606.         if ($strict) {
  1607.             return $this->mobileDetector->isMobile();
  1608.         } else {
  1609.             return $this->LmMobileDetector->isMobile();
  1610.         }
  1611.     }
  1612.     /**
  1613.      * @return bool
  1614.      */
  1615.     public function wannaSeePc()
  1616.     {
  1617.         return !$this->isMobile() && $this->isMobile(true);
  1618.     }
  1619.     /**
  1620.      * @param array $paramsAdd
  1621.      * @param array $params
  1622.      * @return string
  1623.      */
  1624.     public function WithGetParams($paramsAdd$params = [])
  1625.     {
  1626.         if (is_array($params) && count($params) === 0) {
  1627.             $params $this->Request->query->all();
  1628.         }
  1629.         $params array_merge($params$paramsAdd);
  1630.         $result http_build_query($params);
  1631.         return $result;
  1632.     }
  1633.     /**
  1634.      * @param int $page
  1635.      * @return string
  1636.      */
  1637.     public function PageWithGetParams($page)
  1638.     {
  1639.         return $this->WithGetParams([
  1640.             'page' => $page,
  1641.         ]);
  1642.     }
  1643.     /**
  1644.      * @param OrderHeader|array|int $order
  1645.      * @return string|null
  1646.      * @throws \Exception
  1647.      */
  1648.     public function showSendScheduleDate($order)
  1649.     {
  1650.         try {
  1651.             /**
  1652.              * @var OrderHeader $orderHeader
  1653.              */
  1654.             if(!$order instanceof OrderHeaderExtended){
  1655.                 throw new \Exception('ERROR');
  1656.             }
  1657.             if ($orderHeader OrderHeader::factory($order)) {
  1658.                 //
  1659.                 return NoukiEngine::showSendScheduleByOrder($orderHeader);
  1660.             } else {
  1661.                 //
  1662.                 return null;
  1663.             }
  1664.         } catch (\Exception $e) {
  1665.             //
  1666.             if (is_string($order)) {
  1667.                 //
  1668.                 if (Date::validate($order'Y/m/d')) {
  1669.                     //
  1670.                     return NoukiEngine::showSendSchedule($order);
  1671.                 } else {
  1672.                     //
  1673.                     return $order;
  1674.                 }
  1675.             } else {
  1676.                 //
  1677.                 throw new \Exception('お届け予定日の計算処理に失敗しました'0$e);
  1678.             }
  1679.         }
  1680.     }
  1681.     /**
  1682.      * お届け予定の説明 HTML(Common/SendScheduleDate*.twig)を返す。
  1683.      *
  1684.      * 1. Lm 受注ヘッダを {@see OrderHeader::factory} でテンプレ用に正規化する。
  1685.      * 2. お届け日文字列(sendSchedule)を {@see self::showSendScheduleDate} で求める。
  1686.      * 3. 予約時の To 表記(sendScheduleTo)は {@see ShoppingConfirmSendScheduleHelper::getSendScheduleToLabel}。ここで例外が出ても
  1687.      *    注文確認画面全体を落とさないよう空文字にフォールバックする。
  1688.      *
  1689.      * @param OrderHeader|array|int $order
  1690.      * @return string
  1691.      * @throws \Exception showSendScheduleDate が失敗した場合(従来どおり)
  1692.      */
  1693.     public function showSendScheduleMessage($order$isMail false)
  1694.     {
  1695.         $orderHeader OrderHeader::factory($order);
  1696.         $sendSchedule $this->showSendScheduleDate($order);
  1697.         $sendScheduleTo '';
  1698.         try {
  1699.             $sendScheduleTo ShoppingConfirmSendScheduleHelper::getSendScheduleToLabel($order$sendSchedulefalse);
  1700.         } catch (\Throwable $e) {
  1701.             // 注文確認など「まだ DB に明細が無い/ogl_id が無い」状態でTo計算が失敗しても画面は継続する
  1702.             $sendScheduleTo '';
  1703.         }
  1704.         return $this->Twig->render(
  1705.             $isMail 'Common/SendScheduleDateMail.twig' 'Common/SendScheduleDate.twig',
  1706.             [
  1707.                 'orderHeader' => $orderHeader,
  1708.                 'isMobile' => $this->isMobile(),
  1709.                 'sendSchedule' => $sendSchedule,
  1710.                 'sendScheduleTo' => $sendScheduleTo,
  1711.                 'paymentAtobarai' => [OrderHeader::PAYMENT_TYPE_ATOBARAIOrderHeader::PAYMENT_TYPE_ATOBARAI_MONTHLY],
  1712.             ]);
  1713.     }
  1714.     public function getOrderPaymentId($Order)
  1715.     {
  1716.         return !empty($Order->getPayment()) ? $Order->getPayment()->getId() : null;
  1717.     }
  1718.     public function getCategoryImageUrlById($categoryId)
  1719.     {
  1720.         return "/category_images/{$categoryId}.webp";
  1721.     }
  1722.     public function showFileSizeUpload($name 'default')
  1723.     {
  1724.         //
  1725.         $config $this->CommonService->GetConfig('FILE_UPLOAD');
  1726.         //
  1727.         if (!isset($config[$name])) {
  1728.             //
  1729.             throw new \Exception('Config name specified is invalid.');
  1730.         }
  1731.         //
  1732.         $FileUploadConfig $config[$name];
  1733.         //
  1734.         return $this->Twig->render('Common/FileUploadNotice.twig', [
  1735.             'FileUploadConfig' => $FileUploadConfig,
  1736.         ]);
  1737.     }
  1738.     public function showInventoryMatrix(GoodsWithRelated $goods)
  1739.     {
  1740.         //
  1741.         $id $goods->getGoodsId();
  1742.         $data $this->GoodsService->getGoodsById($id);
  1743.         $Product $this->ProductRepository->find($id);
  1744.         // $matrixData = $this->inventoryMatrixService->getInventoryMatrixData($goods, $color, $size);
  1745.         $inventoryMatrix = (new InventoryMatrix())
  1746.             ->getMatrixStock($goodsfalse$color$size)
  1747.         ;
  1748.         $colorCnt count($color);
  1749.         $sizeCnt count($size);
  1750.         $SellingColor $this->GoodsService->getSellingColorSql($idcount($color));
  1751.         $isShowMatrixButtonAbove = (($colorCnt * (intval(($sizeCnt 1) / 6) + 1)) >= 10);
  1752.         //
  1753.         return $this->Twig->render('Item/matrix.twig', [
  1754.             'isShowMatrixButtonAbove' => $isShowMatrixButtonAbove,
  1755.             'data' => $data,
  1756.             'goods' => $goods,
  1757.             // 'matrixData' => $matrixData,
  1758.             'Product' => $Product,
  1759.             'SellingColor' => $SellingColor,
  1760.             'inventoryMatrix' => $inventoryMatrix,
  1761.         ]);
  1762.     }
  1763.     /**
  1764.      * Handle format Object or array to json
  1765.      *
  1766.      * @param $data
  1767.      * @return string|null
  1768.      */
  1769.     public function formatDataToJson($data)
  1770.     {
  1771.         if (empty($data)) {
  1772.             return null;
  1773.         }
  1774.         return json_encode($dataJSON_UNESCAPED_UNICODE JSON_UNESCAPED_SLASHES);
  1775.     }
  1776.     public function getCartSessionName($key)
  1777.     {
  1778.         switch ($key) {
  1779.             case 'GROUP_1_NORMAL':
  1780.                 return '通常注文';
  1781.             case 'GROUP_2_RESERVATION':
  1782.                 return '予約注文';
  1783.             case 'GROUP_3_KYOUEI':
  1784.                 return 'メーカー「共栄-KYOEI」';
  1785.             default:
  1786.                 return '商品一覧';
  1787.         }
  1788.     }
  1789.     public function groupItemsHasSameProductId($items)
  1790.     {
  1791.         $result = [];
  1792.         foreach ($items as $item) {
  1793.             $productId $item->getProduct()->getId();
  1794.             if (!isset($result[$productId])) {
  1795.                 $result[$productId] = [];
  1796.             }
  1797.             $result[$productId][] = $item;
  1798.         }
  1799.         return $result;
  1800.     }
  1801.     /**
  1802.      * Get format date. Example: 2023/09/15 -> 2023年9月15日(金)
  1803.      *
  1804.      * @param string $date
  1805.      * @return string
  1806.      */
  1807.     public function formatDate(string $datebool $showDay true)
  1808.     {
  1809.         if (!empty($date) && strtotime($date) !== false) {
  1810.             $weekdays = [
  1811.                 => '月',
  1812.                 => '火',
  1813.                 => '水',
  1814.                 => '木',
  1815.                 => '金',
  1816.                 => '土',
  1817.                 => '日'
  1818.             ];
  1819.             $dateString date('Y年n月j日'strtotime($date));
  1820.             if ($showDay == false) {
  1821.                 return $dateString;
  1822.             }
  1823.             $dayOfWeek date('N'strtotime($date));
  1824.             $day $weekdays[$dayOfWeek];
  1825.             return $dateString '(' $day ')';
  1826.         }
  1827.         return $date;
  1828.     }
  1829.     /**
  1830.      * 日付を Common/SendScheduleDate.twig(arrivalPeriod)と同様の「n月上旬〜順次」表記にする.
  1831.      * formatDate と同様にまず strtotime、効かない文字列は「n月j日」パターンを試す。それ以外はそのまま返す.
  1832.      *
  1833.      * @param string|\DateTimeInterface|null $date
  1834.      */
  1835.     public function formatSendScheduleArrivalPeriod($date): string
  1836.     {
  1837.         if ($date === null || $date === '') {
  1838.             return '';
  1839.         }
  1840.         $monthDay $this->monthDayForJunPeriod($date);
  1841.         if ($monthDay !== null) {
  1842.             return $this->formatJunPeriodFromMonthDay($monthDay[0], $monthDay[1]);
  1843.         }
  1844.         return is_string($date) ? $date : (string) $date;
  1845.     }
  1846.     /**
  1847.      * @param string|\DateTimeInterface $date
  1848.      *
  1849.      * @return array{0: int, 1: int}|null
  1850.      */
  1851.     private function monthDayForJunPeriod($date): ?array
  1852.     {
  1853.         if ($date instanceof \DateTimeInterface) {
  1854.             return [(int) $date->format('n'), (int) $date->format('j')];
  1855.         }
  1856.         if (!is_string($date)) {
  1857.             return null;
  1858.         }
  1859.         if ($date !== '' && ($ts strtotime($date)) !== false) {
  1860.             return [(int) date('n'$ts), (int) date('j'$ts)];
  1861.         }
  1862.         if (preg_match('/(\d+)\s*月\s*(\d+)\s*日/u'$date$m)) {
  1863.             return [(int) $m[1], (int) $m[2]];
  1864.         }
  1865.         return null;
  1866.     }
  1867.     private function formatJunPeriodFromMonthDay(int $monthint $day): string
  1868.     {
  1869.         if ($day >= && $day <= 10) {
  1870.             return $month '月上旬〜順次';
  1871.         }
  1872.         if ($day >= 11 && $day <= 20) {
  1873.             return $month '月中旬〜順次';
  1874.         }
  1875.         return $month '月下旬〜順次';
  1876.     }
  1877.     public function formatMonthAndDay(string $datebool $showDay true$format "n/j")
  1878.     {
  1879.         if (!empty($date) && strtotime($date) !== false) {
  1880.             $weekdays = [
  1881.                 => '月',
  1882.                 => '火',
  1883.                 => '水',
  1884.                 => '木',
  1885.                 => '金',
  1886.                 => '土',
  1887.                 => '日'
  1888.             ];
  1889.             $dateString date($formatstrtotime($date));
  1890.             if ($showDay == false) {
  1891.                 return $dateString;
  1892.             }
  1893.             $dayOfWeek date('N'strtotime($date));
  1894.             $day $weekdays[$dayOfWeek];
  1895.             return $dateString '(' $day ')' ' 頃';
  1896.         }
  1897.         return $date;
  1898.     }
  1899.     /**
  1900.      * Format stock arrival date to a human-readable format
  1901.      *
  1902.      * @param string $date 入荷予定日 (YYYY-MM-DD または MM-DD 形式)
  1903.      * @return string 変換された入荷予定日(例: "3月上旬")
  1904.      * @throws \InvalidArgumentException 無効な日付形式の場合に例外をスロー
  1905.      */
  1906.     public function formatStockArrivalDate(string $date)
  1907.     {
  1908.         // 日付が `MM-DD` 形式でも許容する
  1909.         if (preg_match('/^(\d{1,2})[-\/](\d{1,2})$/'$date$matches)) {
  1910.             $month = (int)$matches[1];
  1911.             $day = (int)$matches[2];
  1912.         } elseif (strtotime($date) !== false) {
  1913.             $month = (int)date('n'strtotime($date));
  1914.             $day = (int)date('j'strtotime($date));
  1915.         } else {
  1916.             throw new \InvalidArgumentException('無効な日付形式です。MM-DD または YYYY-MM-DD 形式で入力してください。');
  1917.         }
  1918.         if ($day >= && $day <= 10) {
  1919.             return "{$month}月上旬〜順次";
  1920.         } elseif ($day >= 11 && $day <= 20) {
  1921.             return "{$month}月中旬〜順次";
  1922.         } else {
  1923.             return "{$month}月下旬〜順次";
  1924.         }
  1925.     }
  1926.     public function getDayOfWeek(string $date)
  1927.     {
  1928.         if (!empty($date) && strtotime($date) !== false) {
  1929.             $weekdays = [
  1930.                 => '月',
  1931.                 => '火',
  1932.                 => '水',
  1933.                 => '木',
  1934.                 => '金',
  1935.                 => '土',
  1936.                 => '日'
  1937.             ];
  1938.             $dayOfWeek date('N'strtotime($date));
  1939.             return $weekdays[$dayOfWeek];
  1940.         }
  1941.         return null;
  1942.     }
  1943.     /**
  1944.      * @param int $goodsId
  1945.      * @param int $janId
  1946.      * @return string
  1947.      */
  1948.     public function showYoyakuFlag($goodsId$janId)
  1949.     {
  1950.         //
  1951.         return Yoyaku::check($goodsIdfalse$janId) ? '(予約)' null;
  1952.     }
  1953.     /**
  1954.      * @param Item|Goods|int
  1955.      * @return string
  1956.      */
  1957.     public function filterLmWebTeika($item) {
  1958.         /**
  1959.          * @var Item $Item
  1960.          */
  1961.         $item Item::factory($item);
  1962.         //
  1963.         return $this->Twig->render('Common/LmWebPrice.twig', [
  1964.             'minPrice' => $item->getMinTeika(),
  1965.             'maxPrice' => $item->getMaxTeika(),
  1966.         ]);
  1967.     }
  1968.     /**
  1969.      * @param Item|Goods|int
  1970.      * @return string
  1971.      */
  1972.     public function filterLmWebPrice($item) {
  1973.         /**
  1974.          * @var Item $Item
  1975.          */
  1976.         $item Item::factory($item);
  1977.         //
  1978.         return $this->Twig->render('Common/LmWebPrice.twig', [
  1979.             'minPrice' => $item->getMinPrice(),
  1980.             'maxPrice' => $item->getMaxPrice(),
  1981.         ]);
  1982.     }
  1983.     /**
  1984.      * @param Goods $goods
  1985.      * @return string
  1986.      */
  1987.     public function showSokujitsuHassouBannerIfSo(Goods $goods)
  1988.     {
  1989.         /**
  1990.          * @var GoodsWithRelated $goods
  1991.          */
  1992.         $goods GoodsWithRelated::factory($goods);
  1993.         //
  1994.         return $this->Twig->render('Common/SokujitsuHassouBanner.twig', [
  1995.             'goods' => $goods,
  1996.         ]);
  1997.     }
  1998. }