src/Eccube/Repository/OrderRepository.php line 51

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Repository;
  13. use Doctrine\ORM\NoResultException;
  14. use Doctrine\ORM\QueryBuilder;
  15. use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
  16. use Eccube\Doctrine\Query\Queries;
  17. use Eccube\Entity\Customer;
  18. use Eccube\Entity\Master\OrderStatus;
  19. use Eccube\Entity\Master\Sex;
  20. use Eccube\Entity\Order;
  21. use Eccube\Entity\Payment;
  22. use Eccube\Entity\Shipping;
  23. use Eccube\Util\StringUtil;
  24. /**
  25.  * OrderRepository
  26.  *
  27.  * This class was generated by the Doctrine ORM. Add your own custom
  28.  * repository methods below.
  29.  */
  30. class OrderRepository extends AbstractRepository
  31. {
  32.     /**
  33.      * @var Queries
  34.      */
  35.     protected $queries;
  36.     public const COLUMNS = [
  37.         'order' => 'o.name01''orderer' => 'o.id''shipping_id' => 's.id''purchase_product' => 'oi.product_name''quantity' => 'oi.quantity''payment_method' => 'o.payment_method''order_status' => 'o.OrderStatus''purchase_price' => 'o.total''shipping_status' => 's.shipping_date''tracking_number' => 's.tracking_number''delivery' => 's.name01',
  38.     ];
  39.     /**
  40.      * OrderRepository constructor.
  41.      *
  42.      * @param RegistryInterface $registry
  43.      * @param Queries $queries
  44.      */
  45.     public function __construct(RegistryInterface $registryQueries $queries)
  46.     {
  47.         parent::__construct($registryOrder::class);
  48.         $this->queries $queries;
  49.     }
  50.     /**
  51.      * @param int $orderId
  52.      * @param OrderStatus $Status
  53.      */
  54.     public function changeStatus($orderIdOrderStatus $Status)
  55.     {
  56.         $Order $this
  57.             ->find($orderId)
  58.             ->setOrderStatus($Status)
  59.         ;
  60.         switch ($Status->getId()) {
  61.             case '6'// 入金済へ
  62.                 $Order->setPaymentDate(new \DateTime());
  63.                 break;
  64.         }
  65.         $em $this->getEntityManager();
  66.         $em->persist($Order);
  67.         $em->flush();
  68.     }
  69.     /**
  70.      * @param array{
  71.      *         order_id?:string|int,
  72.      *         order_no?:string,
  73.      *         order_id_start?:string|int,
  74.      *         order_id_end?:string|int,
  75.      *         multi?:string|int|null,
  76.      *         status?:OrderStatus[]|int[],
  77.      *         company_name?:string,
  78.      *         name?:string,
  79.      *         kana?:string,
  80.      *         email?:string,
  81.      *         phone_number?:string,
  82.      *         sex?:Sex[],
  83.      *         payment?:Payment[],
  84.      *         order_datetime_start?:\DateTime,
  85.      *         order_datetime_end?:\DateTime,
  86.      *         order_date_start?:\DateTime,
  87.      *         order_date_end?:\DateTime,
  88.      *         payment_datetime_start?:\DateTime,
  89.      *         payment_datetime_end?:\DateTime,
  90.      *         payment_date_start?:\DateTime,
  91.      *         payment_date_end?:\DateTime,
  92.      *         update_datetime_start?:\DateTime,
  93.      *         update_datetime_end?:\DateTime,
  94.      *         update_date_start?:\DateTime,
  95.      *         update_date_end?:\DateTime,
  96.      *         payment_total_start?:string|int,
  97.      *         payment_total_end?:string|int,
  98.      *         payment_product_name?:string,
  99.      *         shipping_mail?:Shipping::SHIPPING_MAIL_UNSENT|Shipping::SHIPPING_MAIL_SENT,
  100.      *         tracking_number?:string,
  101.      *         shipping_delivery_datetime_start?:\DateTime,
  102.      *         shipping_delivery_datetime_end?:\DateTime,
  103.      *         shipping_delivery_date_start?:\DateTime,
  104.      *         shipping_delivery_date_end?:\DateTime,
  105.      *         sortkey?:string,
  106.      *         sorttype?:string
  107.      *     } $searchData
  108.      *
  109.      * @return QueryBuilder
  110.      */
  111.     public function getQueryBuilderBySearchDataForAdmin($searchData)
  112.     {
  113.         $qb $this->createQueryBuilder('o')
  114.             ->select('o, s')
  115.             ->addSelect('oi''pref')
  116.             ->leftJoin('o.OrderItems''oi')
  117.             ->leftJoin('o.Pref''pref')
  118.             ->innerJoin('o.Shippings''s');
  119.         // order_id_start
  120.         if (isset($searchData['order_id']) && StringUtil::isNotBlank($searchData['order_id'])) {
  121.             $qb
  122.                 ->andWhere('o.id = :order_id')
  123.                 ->setParameter('order_id'$searchData['order_id']);
  124.         }
  125.         // order_no
  126.         if (isset($searchData['order_no']) && StringUtil::isNotBlank($searchData['order_no'])) {
  127.             $qb
  128.                 ->andWhere('o.order_no = :order_no')
  129.                 ->setParameter('order_no'$searchData['order_no']);
  130.         }
  131.         // order_id_start
  132.         if (isset($searchData['order_id_start']) && StringUtil::isNotBlank($searchData['order_id_start'])) {
  133.             $qb
  134.                 ->andWhere('o.id >= :order_id_start')
  135.                 ->setParameter('order_id_start'$searchData['order_id_start']);
  136.         }
  137.         // multi
  138.         if (isset($searchData['multi']) && StringUtil::isNotBlank($searchData['multi'])) {
  139.             // スペース除去
  140.             $clean_key_multi preg_replace('/\s+|[ ]+/u'''$searchData['multi']);
  141.             $multi preg_match('/^\d{0,10}$/'$clean_key_multi) ? $clean_key_multi null;
  142.             if ($multi && $multi '2147483647' && $this->isPostgreSQL()) {
  143.                 $multi null;
  144.             }
  145.             $qb
  146.                 ->andWhere('o.id = :multi OR CONCAT(o.name01, o.name02) LIKE :likemulti OR '.
  147.                     "CONCAT(COALESCE(o.kana01, ''), COALESCE(o.kana02, '')) LIKE :likemulti OR o.company_name LIKE :multi_company_name OR ".
  148.                     'o.order_no LIKE :likemulti OR o.email LIKE :likemulti OR o.phone_number LIKE :likemulti')
  149.                 ->setParameter('multi'$multi)
  150.                 ->setParameter('likemulti''%'.$clean_key_multi.'%')
  151.                 ->setParameter('multi_company_name''%'.$searchData['multi'].'%'); // 会社名はスペースを除去せず検索
  152.         }
  153.         // order_id_end
  154.         if (isset($searchData['order_id_end']) && StringUtil::isNotBlank($searchData['order_id_end'])) {
  155.             $qb
  156.                 ->andWhere('o.id <= :order_id_end')
  157.                 ->setParameter('order_id_end'$searchData['order_id_end']);
  158.         }
  159.         // status
  160.         $filterStatus false;
  161.         if (!empty($searchData['status']) && count($searchData['status'])) {
  162.             $qb
  163.                 ->andWhere($qb->expr()->in('o.OrderStatus'':status'))
  164.                 ->setParameter('status'$searchData['status']);
  165.             $filterStatus true;
  166.         }
  167.         if (!$filterStatus) {
  168.             // 購入処理中, 決済処理中は検索対象から除外
  169.             $qb->andWhere($qb->expr()->notIn('o.OrderStatus'':status'))
  170.                 ->setParameter('status', [OrderStatus::PROCESSINGOrderStatus::PENDING]);
  171.         }
  172.         // company_name
  173.         if (isset($searchData['company_name']) && StringUtil::isNotBlank($searchData['company_name'])) {
  174.             $qb
  175.                 ->andWhere('o.company_name LIKE :company_name')
  176.                 ->setParameter('company_name''%'.$searchData['company_name'].'%');
  177.         }
  178.         // name
  179.         if (isset($searchData['name']) && StringUtil::isNotBlank($searchData['name'])) {
  180.             $clean_name preg_replace('/\s+|[ ]+/u'''$searchData['name']);
  181.             $qb
  182.                 ->andWhere('CONCAT(o.name01, o.name02) LIKE :name')
  183.                 ->setParameter('name''%'.$clean_name.'%');
  184.         }
  185.         // kana
  186.         if (isset($searchData['kana']) && StringUtil::isNotBlank($searchData['kana'])) {
  187.             $clean_kana preg_replace('/\s+|[ ]+/u'''$searchData['kana']);
  188.             $qb
  189.                 ->andWhere("CONCAT(COALESCE(o.kana01, ''), COALESCE(o.kana02, '')) LIKE :kana")
  190.                 ->setParameter('kana''%'.$clean_kana.'%');
  191.         }
  192.         // email
  193.         if (isset($searchData['email']) && StringUtil::isNotBlank($searchData['email'])) {
  194.             $qb
  195.                 ->andWhere('o.email like :email')
  196.                 ->setParameter('email''%'.$searchData['email'].'%');
  197.         }
  198.         // tel
  199.         if (isset($searchData['phone_number']) && StringUtil::isNotBlank($searchData['phone_number'])) {
  200.             $tel preg_replace('/[^0-9]/'''$searchData['phone_number']);
  201.             $qb
  202.                 ->andWhere('o.phone_number LIKE :phone_number')
  203.                 ->setParameter('phone_number''%'.$tel.'%');
  204.         }
  205.         // sex
  206.         if (!empty($searchData['sex']) && count($searchData['sex']) > 0) {
  207.             $qb
  208.                 ->andWhere($qb->expr()->in('o.Sex'':sex'))
  209.                 ->setParameter('sex'$searchData['sex']->toArray());
  210.         }
  211.         // payment
  212.         if (!empty($searchData['payment']) && count($searchData['payment'])) {
  213.             $payments = [];
  214.             foreach ($searchData['payment'] as $payment) {
  215.                 $payments[] = $payment->getId();
  216.             }
  217.             $qb
  218.                 ->leftJoin('o.Payment''p')
  219.                 ->andWhere($qb->expr()->in('p.id'':payments'))
  220.                 ->setParameter('payments'$payments);
  221.         }
  222.         // oreder_date
  223.         if (!empty($searchData['order_datetime_start']) && $searchData['order_datetime_start']) {
  224.             $date $searchData['order_datetime_start'];
  225.             $qb
  226.                 ->andWhere('o.order_date >= :order_date_start')
  227.                 ->setParameter('order_date_start'$date);
  228.         } elseif (!empty($searchData['order_date_start']) && $searchData['order_date_start']) {
  229.             $date $searchData['order_date_start'];
  230.             $qb
  231.                 ->andWhere('o.order_date >= :order_date_start')
  232.                 ->setParameter('order_date_start'$date);
  233.         }
  234.         if (!empty($searchData['order_datetime_end']) && $searchData['order_datetime_end']) {
  235.             $date $searchData['order_datetime_end'];
  236.             $qb
  237.                 ->andWhere('o.order_date < :order_date_end')
  238.                 ->setParameter('order_date_end'$date);
  239.         } elseif (!empty($searchData['order_date_end']) && $searchData['order_date_end']) {
  240.             $date = clone $searchData['order_date_end'];
  241.             $date $date
  242.                 ->modify('+1 days');
  243.             $qb
  244.                 ->andWhere('o.order_date < :order_date_end')
  245.                 ->setParameter('order_date_end'$date);
  246.         }
  247.         // payment_date
  248.         if (!empty($searchData['payment_datetime_start']) && $searchData['payment_datetime_start']) {
  249.             $date $searchData['payment_datetime_start'];
  250.             $qb
  251.                 ->andWhere('o.payment_date >= :payment_date_start')
  252.                 ->setParameter('payment_date_start'$date);
  253.         } elseif (!empty($searchData['payment_date_start']) && $searchData['payment_date_start']) {
  254.             $date $searchData['payment_date_start'];
  255.             $qb
  256.                 ->andWhere('o.payment_date >= :payment_date_start')
  257.                 ->setParameter('payment_date_start'$date);
  258.         }
  259.         if (!empty($searchData['payment_datetime_end']) && $searchData['payment_datetime_end']) {
  260.             $date $searchData['payment_datetime_end'];
  261.             $qb
  262.                 ->andWhere('o.payment_date < :payment_date_end')
  263.                 ->setParameter('payment_date_end'$date);
  264.         } elseif (!empty($searchData['payment_date_end']) && $searchData['payment_date_end']) {
  265.             $date = clone $searchData['payment_date_end'];
  266.             $date $date
  267.                 ->modify('+1 days');
  268.             $qb
  269.                 ->andWhere('o.payment_date < :payment_date_end')
  270.                 ->setParameter('payment_date_end'$date);
  271.         }
  272.         // update_date
  273.         if (!empty($searchData['update_datetime_start']) && $searchData['update_datetime_start']) {
  274.             $date $searchData['update_datetime_start'];
  275.             $qb
  276.                 ->andWhere('o.update_date >= :update_date_start')
  277.                 ->setParameter('update_date_start'$date);
  278.         } elseif (!empty($searchData['update_date_start']) && $searchData['update_date_start']) {
  279.             $date $searchData['update_date_start'];
  280.             $qb
  281.                 ->andWhere('o.update_date >= :update_date_start')
  282.                 ->setParameter('update_date_start'$date);
  283.         }
  284.         if (!empty($searchData['update_datetime_end']) && $searchData['update_datetime_end']) {
  285.             $date $searchData['update_datetime_end'];
  286.             $qb
  287.                 ->andWhere('o.update_date < :update_date_end')
  288.                 ->setParameter('update_date_end'$date);
  289.         } elseif (!empty($searchData['update_date_end']) && $searchData['update_date_end']) {
  290.             $date = clone $searchData['update_date_end'];
  291.             $date $date
  292.                 ->modify('+1 days');
  293.             $qb
  294.                 ->andWhere('o.update_date < :update_date_end')
  295.                 ->setParameter('update_date_end'$date);
  296.         }
  297.         // payment_total
  298.         if (isset($searchData['payment_total_start']) && StringUtil::isNotBlank($searchData['payment_total_start'])) {
  299.             $qb
  300.                 ->andWhere('o.payment_total >= :payment_total_start')
  301.                 ->setParameter('payment_total_start'$searchData['payment_total_start']);
  302.         }
  303.         if (isset($searchData['payment_total_end']) && StringUtil::isNotBlank($searchData['payment_total_end'])) {
  304.             $qb
  305.                 ->andWhere('o.payment_total <= :payment_total_end')
  306.                 ->setParameter('payment_total_end'$searchData['payment_total_end']);
  307.         }
  308.         // buy_product_name
  309.         if (isset($searchData['buy_product_name']) && StringUtil::isNotBlank($searchData['buy_product_name'])) {
  310.             $qb
  311.                 ->andWhere('oi.product_name LIKE :buy_product_name')
  312.                 ->setParameter('buy_product_name''%'.$searchData['buy_product_name'].'%');
  313.         }
  314.         // apparel
  315.         if (!empty($searchData['apparel']) && $searchData['apparel']) {
  316.             $qb
  317.                 ->innerJoin('oi.ProductClass''pc')
  318.                 ->innerJoin('pc.Product''p')
  319.                 ->andWhere('p.Apparel = :apparel')
  320.                 ->setParameter('apparel'$searchData['apparel']);
  321.         }
  322.         // target_student (対象生徒)
  323.         if (!empty($searchData['target_student']) && count($searchData['target_student']) > 0) {
  324.             $qb
  325.                 ->leftJoin('Customize\Entity\School''sch''WITH''o.school_id = sch.school_id')
  326.                 ->andWhere($qb->expr()->in('sch.target_student'':target_student'))
  327.                 ->setParameter('target_student'$searchData['target_student']);
  328.         }
  329.         // 発送メール送信/未送信.
  330.         if (isset($searchData['shipping_mail']) && $count count($searchData['shipping_mail'])) {
  331.             // 送信済/未送信両方にチェックされている場合は検索条件に追加しない
  332.             if ($count 2) {
  333.                 $checked current($searchData['shipping_mail']);
  334.                 if ($checked == Shipping::SHIPPING_MAIL_UNSENT) {
  335.                     // 未送信
  336.                     $qb
  337.                         ->andWhere('s.mail_send_date IS NULL');
  338.                 } elseif ($checked == Shipping::SHIPPING_MAIL_SENT) {
  339.                     // 送信
  340.                     $qb
  341.                         ->andWhere('s.mail_send_date IS NOT NULL');
  342.                 }
  343.             }
  344.         }
  345.         // 送り状番号.
  346.         if (!empty($searchData['tracking_number'])) {
  347.             $qb
  348.                 ->andWhere('s.tracking_number = :tracking_number')
  349.                 ->setParameter('tracking_number'$searchData['tracking_number']);
  350.         }
  351.         // お届け予定日(Shipping.delivery_date)
  352.         if (!empty($searchData['shipping_delivery_datetime_start']) && $searchData['shipping_delivery_datetime_start']) {
  353.             $date $searchData['shipping_delivery_datetime_start'];
  354.             $qb
  355.                 ->andWhere('s.shipping_delivery_date >= :shipping_delivery_date_start')
  356.                 ->setParameter('shipping_delivery_date_start'$date);
  357.         } elseif (!empty($searchData['shipping_delivery_date_start']) && $searchData['shipping_delivery_date_start']) {
  358.             $date $searchData['shipping_delivery_date_start'];
  359.             $qb
  360.                 ->andWhere('s.shipping_delivery_date >= :shipping_delivery_date_start')
  361.                 ->setParameter('shipping_delivery_date_start'$date);
  362.         }
  363.         if (!empty($searchData['shipping_delivery_datetime_end']) && $searchData['shipping_delivery_datetime_end']) {
  364.             $date $searchData['shipping_delivery_datetime_end'];
  365.             $qb
  366.                 ->andWhere('s.shipping_delivery_date < :shipping_delivery_date_end')
  367.                 ->setParameter('shipping_delivery_date_end'$date);
  368.         } elseif (!empty($searchData['shipping_delivery_date_end']) && $searchData['shipping_delivery_date_end']) {
  369.             $date = clone $searchData['shipping_delivery_date_end'];
  370.             $date $date
  371.                 ->modify('+1 days');
  372.             $qb
  373.                 ->andWhere('s.shipping_delivery_date < :shipping_delivery_date_end')
  374.                 ->setParameter('shipping_delivery_date_end'$date);
  375.         }
  376.         // Order By
  377.         if (isset($searchData['sortkey']) && !empty($searchData['sortkey'])) {
  378.             $sortOrder = (isset($searchData['sorttype']) && $searchData['sorttype'] == 'a') ? 'ASC' 'DESC';
  379.             $qb->orderBy(self::COLUMNS[$searchData['sortkey']], $sortOrder);
  380.             $qb->addOrderBy('o.update_date''DESC');
  381.             $qb->addOrderBy('o.id''DESC');
  382.         } else {
  383.             $qb->orderBy('o.update_date''DESC');
  384.             $qb->addorderBy('o.id''DESC');
  385.         }
  386.         return $this->queries->customize(QueryKey::ORDER_SEARCH_ADMIN$qb$searchData);
  387.     }
  388.     /**
  389.      * @param  \Eccube\Entity\Customer $Customer
  390.      *
  391.      * @return QueryBuilder
  392.      */
  393.     public function getQueryBuilderByCustomer(Customer $Customer)
  394.     {
  395.         $qb $this->createQueryBuilder('o')
  396.             ->where('o.Customer = :Customer')
  397.             ->setParameter('Customer'$Customer);
  398.         // Order By
  399.         $qb->addOrderBy('o.id''DESC');
  400.         return $this->queries->customize(QueryKey::ORDER_SEARCH_BY_CUSTOMER$qb, ['customer' => $Customer]);
  401.     }
  402.     /**
  403.      * ステータスごとの受注件数を取得する.
  404.      *
  405.      * @param integer $OrderStatusOrId
  406.      *
  407.      * @return int
  408.      *
  409.      * @throws \Doctrine\ORM\NoResultException
  410.      * @throws \Doctrine\ORM\NonUniqueResultException
  411.      */
  412.     public function countByOrderStatus($OrderStatusOrId)
  413.     {
  414.         return (int) $this->createQueryBuilder('o')
  415.             ->select('COALESCE(COUNT(o.id), 0)')
  416.             ->where('o.OrderStatus = :OrderStatus')
  417.             ->setParameter('OrderStatus'$OrderStatusOrId)
  418.             ->getQuery()
  419.             ->getSingleScalarResult();
  420.     }
  421.     /**
  422.      * 会員の購入金額, 購入回数, 初回購入日, 最終購入費を更新する
  423.      *
  424.      * @param Customer $Customer
  425.      * @param array $OrderStatuses
  426.      */
  427.     public function updateOrderSummary(Customer $Customer, array $OrderStatuses = [OrderStatus::NEW, OrderStatus::PAIDOrderStatus::DELIVEREDOrderStatus::IN_PROGRESS])
  428.     {
  429.         try {
  430.             $result $this->createQueryBuilder('o')
  431.                 ->select('COUNT(o.id) AS buy_times, SUM(o.total) AS buy_total, MIN(o.id) AS first_order_id, MAX(o.id) AS last_order_id')
  432.                 ->where('o.Customer = :Customer')
  433.                 ->andWhere('o.OrderStatus in (:OrderStatuses)')
  434.                 ->setParameter('Customer'$Customer)
  435.                 ->setParameter('OrderStatuses'$OrderStatuses)
  436.                 ->groupBy('o.Customer')
  437.                 ->getQuery()
  438.                 ->getSingleResult();
  439.         } catch (NoResultException $e) {
  440.             // 受注データが存在しなければ初期化
  441.             $Customer->setFirstBuyDate(null);
  442.             $Customer->setLastBuyDate(null);
  443.             $Customer->setBuyTimes(0);
  444.             $Customer->setBuyTotal(0);
  445.             return;
  446.         }
  447.         $FirstOrder $this->find(['id' => $result['first_order_id']]);
  448.         $LastOrder $this->find(['id' => $result['last_order_id']]);
  449.         $Customer->setBuyTimes($result['buy_times']);
  450.         $Customer->setBuyTotal($result['buy_total']);
  451.         $Customer->setFirstBuyDate($FirstOrder->getOrderDate());
  452.         $Customer->setLastBuyDate($LastOrder->getOrderDate());
  453.     }
  454.     /**
  455.      * 特定の商品に対する顧客の過去の購入数量を取得
  456.      *
  457.      * @param Customer|null $Customer
  458.      * @param int $productId
  459.      * @param array $OrderStatuses
  460.      * @return int
  461.      */
  462.     public function getPurchasedQuantityByProduct($Customer$productId, array $OrderStatuses = [OrderStatus::NEW, OrderStatus::PAIDOrderStatus::DELIVEREDOrderStatus::IN_PROGRESS])
  463.     {
  464.         if (!$Customer) {
  465.             return 0;
  466.         }
  467.         try {
  468.             $qb $this->createQueryBuilder('o')
  469.                 ->select('SUM(oi.quantity) as total_quantity')
  470.                 ->innerJoin('o.OrderItems''oi')
  471.                 ->innerJoin('oi.ProductClass''pc')
  472.                 ->innerJoin('pc.Product''p')
  473.                 ->where('o.Customer = :Customer')
  474.                 ->andWhere('p.id = :productId')
  475.                 ->andWhere('o.OrderStatus in (:OrderStatuses)')
  476.                 ->setParameter('Customer'$Customer)
  477.                 ->setParameter('productId'$productId)
  478.                 ->setParameter('OrderStatuses'$OrderStatuses);
  479.             $result $qb->getQuery()->getSingleScalarResult();
  480.             return (int)($result ?? 0);
  481.         } catch (NoResultException $e) {
  482.             return 0;
  483.         } catch (\Exception $e) {
  484.             return 0;
  485.         }
  486.     }
  487. }