Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 38 | class OrderHelper |
||
| 39 | { |
||
| 40 | /** |
||
| 41 | * @Inject(OrderItemTypeRepository::class) |
||
| 42 | * @var OrderItemTypeRepository |
||
| 43 | */ |
||
| 44 | protected $orderItemTypeRepository; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @Inject(OrderStatusRepository::class) |
||
| 48 | * @var OrderStatusRepository |
||
| 49 | */ |
||
| 50 | protected $orderStatusRepository; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @Inject(TaxRuleRepository::class) |
||
| 54 | * @var TaxRuleRepository |
||
| 55 | */ |
||
| 56 | protected $taxRuleRepository; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @Inject(DeliveryFeeRepository::class) |
||
| 60 | * @var DeliveryFeeRepository |
||
| 61 | */ |
||
| 62 | protected $deliveryFeeRepository; |
||
| 63 | |||
| 64 | /** |
||
| 65 | * @Inject(DeliveryRepository::class) |
||
| 66 | * @var DeliveryRepository |
||
| 67 | */ |
||
| 68 | protected $deliveryRepository; |
||
| 69 | |||
| 70 | /** |
||
| 71 | * @Inject(PaymentRepository::class) |
||
| 72 | * @var PaymentRepository |
||
| 73 | */ |
||
| 74 | protected $paymentRepository; |
||
| 75 | |||
| 76 | /** |
||
| 77 | * @Inject(OrderRepository::class) |
||
| 78 | * @var OrderRepository |
||
| 79 | */ |
||
| 80 | protected $orderRepository; |
||
| 81 | |||
| 82 | /** |
||
| 83 | * @Inject(ShippingStatusRepository::class) |
||
| 84 | * @var ShippingStatusRepository |
||
| 85 | */ |
||
| 86 | protected $shippingStatusRepository; |
||
| 87 | |||
| 88 | /** |
||
| 89 | * @Inject("orm.em") |
||
| 90 | * @var EntityManager |
||
| 91 | */ |
||
| 92 | protected $entityManager; |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @Inject("config") |
||
| 96 | * @var array |
||
| 97 | */ |
||
| 98 | protected $appConfig; |
||
| 99 | |||
| 100 | /** |
||
| 101 | * 購入処理中の受注データを生成する. |
||
| 102 | * |
||
| 103 | * @param Customer $Customer |
||
|
|
|||
| 104 | * @param CustomerAddress $CustomerAddress |
||
| 105 | * @param array $CartItems |
||
| 106 | * @return Order |
||
| 107 | */ |
||
| 108 | public function createProcessingOrder(Customer $Customer, CustomerAddress $CustomerAddress, $CartItems) |
||
| 109 | { |
||
| 110 | $OrderStatus = $this->orderStatusRepository->find($this->appConfig['order_processing']); |
||
| 111 | $Order = new Order($OrderStatus); |
||
| 112 | |||
| 113 | // pre_order_idを生成 |
||
| 114 | $Order->setPreOrderId($this->createPreOrderId()); |
||
| 115 | |||
| 116 | // 顧客情報の設定 |
||
| 117 | $this->setCustomer($Order, $Customer); |
||
| 118 | |||
| 119 | // 明細情報の設定 |
||
| 120 | $OrderItems = $this->createOrderItemsFromCartItems($CartItems); |
||
| 121 | $OrderItemsGroupByProductType = array_reduce($OrderItems, function($result, $item) { |
||
| 122 | /* @var OrderItem $item */ |
||
| 123 | $productTypeId = $item->getProductClass()->getProductType()->getId(); |
||
| 124 | $result[$productTypeId][] = $item; |
||
| 125 | return $result; |
||
| 126 | }, []); |
||
| 127 | |||
| 128 | foreach ($OrderItemsGroupByProductType as $OrderItems) { |
||
| 129 | $Shipping = $this->createShippingFromCustomerAddress($CustomerAddress); |
||
| 130 | $this->addOrderItems($Order, $Shipping, $OrderItems); |
||
| 131 | $this->setDefaultDelivery($Shipping); |
||
| 132 | $this->entityManager->persist($Shipping); |
||
| 133 | } |
||
| 134 | |||
| 135 | $this->setDefaultPayment($Order); |
||
| 136 | |||
| 137 | $this->entityManager->persist($Order); |
||
| 138 | $this->entityManager->flush(); |
||
| 139 | |||
| 140 | return $Order; |
||
| 141 | } |
||
| 142 | |||
| 143 | public function createPreOrderId() |
||
| 144 | { |
||
| 145 | // ランダムなpre_order_idを作成 |
||
| 146 | View Code Duplication | do { |
|
| 147 | $preOrderId = sha1(Str::random(32)); |
||
| 148 | |||
| 149 | $Order = $this->orderRepository->findOneBy( |
||
| 150 | [ |
||
| 151 | 'pre_order_id' => $preOrderId, |
||
| 152 | 'OrderStatus' => $this->appConfig['order_processing'], |
||
| 153 | ] |
||
| 154 | ); |
||
| 155 | } while ($Order); |
||
| 156 | |||
| 157 | return $preOrderId; |
||
| 158 | } |
||
| 159 | |||
| 160 | public function setCustomer(Order $Order, Customer $Customer) |
||
| 161 | { |
||
| 162 | if ($Customer->getId()) { |
||
| 163 | $Order->setCustomer($Customer); |
||
| 164 | } |
||
| 165 | |||
| 166 | $Order->copyProperties( |
||
| 167 | $Customer, |
||
| 168 | [ |
||
| 169 | 'id', |
||
| 170 | 'create_date', |
||
| 171 | 'update_date', |
||
| 172 | 'del_flg', |
||
| 173 | ] |
||
| 174 | ); |
||
| 175 | } |
||
| 176 | |||
| 177 | /** |
||
| 178 | * @param ArrayCollection $CartItems |
||
| 179 | * @return OrderItem[] |
||
| 180 | */ |
||
| 181 | private function createOrderItemsFromCartItems($CartItems) |
||
| 182 | { |
||
| 183 | $ProductItemType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT); |
||
| 184 | // TODO |
||
| 185 | $TaxExclude = $this->entityManager->getRepository(TaxDisplayType::class)->find(TaxDisplayType::EXCLUDED); |
||
| 186 | $Taxion = $this->entityManager->getRepository(TaxType::class)->find(TaxType::TAXATION); |
||
| 187 | |||
| 188 | return array_map(function($item) use ($ProductItemType, $TaxExclude, $Taxion) { |
||
| 189 | /* @var $item CartItem */ |
||
| 190 | /* @var $ProductClass \Eccube\Entity\ProductClass */ |
||
| 191 | $ProductClass = $item->getObject(); |
||
| 192 | /* @var $Product \Eccube\Entity\Product */ |
||
| 193 | $Product = $ProductClass->getProduct(); |
||
| 194 | $TaxRule = $this->taxRuleRepository->getByRule($Product, $ProductClass); |
||
| 195 | |||
| 196 | $OrderItem = new OrderItem(); |
||
| 197 | $OrderItem |
||
| 198 | ->setProduct($Product) |
||
| 199 | ->setProductClass($ProductClass) |
||
| 200 | ->setProductName($Product->getName()) |
||
| 201 | ->setProductCode($ProductClass->getCode()) |
||
| 202 | ->setPrice($ProductClass->getPrice02()) |
||
| 203 | ->setQuantity($item->getQuantity()) |
||
| 204 | ->setTaxRule($TaxRule->getId()) |
||
| 205 | ->setTaxRate($TaxRule->getTaxRate()) |
||
| 206 | ->setOrderItemType($ProductItemType) |
||
| 207 | ->setTaxDisplayType($TaxExclude) |
||
| 208 | ->setTaxType($Taxion); |
||
| 209 | |||
| 210 | $ClassCategory1 = $ProductClass->getClassCategory1(); |
||
| 211 | if (!is_null($ClassCategory1)) { |
||
| 212 | $OrderItem->setClasscategoryName1($ClassCategory1->getName()); |
||
| 213 | $OrderItem->setClassName1($ClassCategory1->getClassName()->getName()); |
||
| 214 | } |
||
| 215 | $ClassCategory2 = $ProductClass->getClassCategory2(); |
||
| 216 | if (!is_null($ClassCategory2)) { |
||
| 217 | $OrderItem->setClasscategoryName2($ClassCategory2->getName()); |
||
| 218 | $OrderItem->setClassName2($ClassCategory2->getClassName()->getName()); |
||
| 219 | } |
||
| 220 | |||
| 221 | return $OrderItem; |
||
| 222 | }, $CartItems->toArray()); |
||
| 223 | } |
||
| 224 | |||
| 225 | /** |
||
| 226 | * @deprecated |
||
| 227 | */ |
||
| 228 | public function createOrderDetailsFromCartItems($CartItems) |
||
| 267 | |||
| 268 | /** |
||
| 269 | * @deprecated |
||
| 270 | */ |
||
| 271 | public function addOrderDetails(Order $Order, array $OrderDetails) |
||
| 279 | |||
| 280 | public function createShippingFromCustomerAddress(CustomerAddress $CustomerAddress) |
||
| 281 | { |
||
| 282 | $Shipping = new Shipping(); |
||
| 283 | $Shipping |
||
| 284 | ->setName01($CustomerAddress->getName01()) |
||
| 285 | ->setName02($CustomerAddress->getName02()) |
||
| 286 | ->setKana01($CustomerAddress->getKana01()) |
||
| 287 | ->setKana02($CustomerAddress->getKana02()) |
||
| 288 | ->setCompanyName($CustomerAddress->getCompanyName()) |
||
| 289 | ->setTel01($CustomerAddress->getTel01()) |
||
| 290 | ->setTel02($CustomerAddress->getTel02()) |
||
| 291 | ->setTel03($CustomerAddress->getTel03()) |
||
| 292 | ->setFax01($CustomerAddress->getFax01()) |
||
| 293 | ->setFax02($CustomerAddress->getFax02()) |
||
| 294 | ->setFax03($CustomerAddress->getFax03()) |
||
| 295 | ->setZip01($CustomerAddress->getZip01()) |
||
| 296 | ->setZip02($CustomerAddress->getZip02()) |
||
| 297 | ->setZipCode($CustomerAddress->getZip01().$CustomerAddress->getZip02()) |
||
| 298 | ->setPref($CustomerAddress->getPref()) |
||
| 299 | ->setAddr01($CustomerAddress->getAddr01()) |
||
| 300 | ->setAddr02($CustomerAddress->getAddr02()); |
||
| 301 | |||
| 302 | $ShippingStatus = $this->shippingStatusRepository->find(ShippingStatus::PREPARED); |
||
| 303 | $Shipping->setShippingStatus($ShippingStatus); |
||
| 304 | |||
| 305 | return $Shipping; |
||
| 306 | } |
||
| 307 | |||
| 308 | /** |
||
| 309 | * @deprecated |
||
| 310 | */ |
||
| 311 | public function addShipping(Order $Order, Shipping $Shipping) |
||
| 317 | |||
| 318 | public function setDefaultDelivery(Shipping $Shipping) |
||
| 319 | { |
||
| 320 | // 配送商品に含まれる商品種別を抽出. |
||
| 321 | $OrderItems = $Shipping->getOrderItems(); |
||
| 322 | $ProductTypes = []; |
||
| 323 | View Code Duplication | foreach ($OrderItems as $OrderItem) { |
|
| 324 | $ProductClass = $OrderItem->getProductClass(); |
||
| 325 | $ProductType = $ProductClass->getProductType(); |
||
| 326 | $ProductTypes[$ProductType->getId()] = $ProductType; |
||
| 327 | } |
||
| 328 | |||
| 329 | // 商品種別に紐づく配送業者を取得. |
||
| 330 | $Deliveries = $this->deliveryRepository->getDeliveries($ProductTypes); |
||
| 331 | |||
| 332 | // 初期の配送業者を設定 |
||
| 333 | $Delivery = current($Deliveries); |
||
| 334 | $Shipping->setDelivery($Delivery); |
||
| 335 | $Shipping->setShippingDeliveryName($Delivery->getName()); |
||
| 336 | |||
| 337 | // TODO 配送料の取得方法はこれで良いか要検討 |
||
| 338 | $deliveryFee = $this->deliveryFeeRepository->findOneBy(array('Delivery' => $Delivery, 'Pref' => $Shipping->getPref())); |
||
| 339 | if ($deliveryFee) { |
||
| 340 | $Shipping->setShippingDeliveryFee($deliveryFee->getFee()); |
||
| 341 | $Shipping->setFeeId($deliveryFee->getId()); |
||
| 342 | } |
||
| 343 | } |
||
| 344 | |||
| 345 | public function setDefaultPayment(Order $Order) |
||
| 346 | { |
||
| 347 | $OrderItems = $Order->getOrderItems(); |
||
| 348 | |||
| 349 | // 受注明細に含まれる商品種別を抽出. |
||
| 350 | $ProductTypes = []; |
||
| 351 | /** @var OrderItem $OrderItem */ |
||
| 352 | View Code Duplication | foreach ($OrderItems as $OrderItem) { |
|
| 353 | $ProductClass = $OrderItem->getProductClass(); |
||
| 354 | if (is_null($ProductClass)) { |
||
| 355 | // 商品明細のみ対象とする. 送料明細等はスキップする. |
||
| 356 | continue; |
||
| 357 | } |
||
| 358 | $ProductType = $ProductClass->getProductType(); |
||
| 359 | $ProductTypes[$ProductType->getId()] = $ProductType; |
||
| 360 | } |
||
| 361 | |||
| 362 | // 商品種別に紐づく配送業者を抽出 |
||
| 363 | $Deliveries = $this->deliveryRepository->getDeliveries($ProductTypes); |
||
| 364 | |||
| 365 | // 利用可能な支払い方法を抽出. |
||
| 366 | $Payments = $this->paymentRepository->findAllowedPayments($Deliveries, true); |
||
| 367 | |||
| 368 | // 初期の支払い方法を設定. |
||
| 369 | $Payment = current($Payments); |
||
| 370 | $Order->setPayment($Payment); |
||
| 371 | $Order->setPaymentMethod($Payment->getMethod()); |
||
| 372 | // TODO CalculateChargeStrategy でセットする |
||
| 373 | // $Order->setCharge($Payment->getCharge()); |
||
| 374 | } |
||
| 375 | |||
| 376 | /** |
||
| 377 | * @deprecated |
||
| 378 | */ |
||
| 379 | public function createOrderItemsFromOrderDetails($OrderDetails, $groupByProductType = true) |
||
| 417 | |||
| 418 | public function addOrderItems(Order $Order, Shipping $Shipping, array $OrderItems) |
||
| 419 | { |
||
| 420 | foreach ($OrderItems as $OrderItem) { |
||
| 421 | $Shipping->addOrderItem($OrderItem); |
||
| 422 | $Order->addOrderItem($OrderItem); |
||
| 423 | $OrderItem->setOrder($Order); |
||
| 424 | $OrderItem->setShipping($Shipping); |
||
| 427 | |||
| 428 | } |
||
| 429 |