Skip to content

Commit

Permalink
Merge pull request #5974 from takeuji/calc_order_tax
Browse files Browse the repository at this point in the history
受注テーブルのtaxに税率ごとの消費税額の合算を設定する
  • Loading branch information
dotani1111 authored Feb 7, 2024
2 parents 741b785 + 7155a6e commit dbf0f4e
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 30 deletions.
3 changes: 3 additions & 0 deletions src/Eccube/Entity/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ public function getTaxByTaxRate()
$roundingTypes = $this->getRoundingTypeByTaxRate();
$tax = [];
foreach ($this->getTaxableTotalByTaxRate() as $rate => $totalPrice) {
if (is_null($roundingTypes[$rate])) {
continue;
}
$tax[$rate] = TaxRuleService::roundByRoundingType(
$this->getTaxableTotal() ?
($totalPrice - abs($this->getTaxFreeDiscount()) * $totalPrice / $this->getTaxableTotal()) * ($rate / (100 + $rate)) : 0,
Expand Down
19 changes: 10 additions & 9 deletions src/Eccube/Service/PurchaseFlow/PurchaseFlow.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use Eccube\Entity\ItemHolderInterface;
use Eccube\Entity\ItemInterface;
use Eccube\Entity\Order;
use Eccube\Entity\OrderItem;

class PurchaseFlow
{
Expand Down Expand Up @@ -346,16 +345,18 @@ protected function calculateCharge(ItemHolderInterface $itemHolder)
*/
protected function calculateTax(ItemHolderInterface $itemHolder)
{
$total = $itemHolder->getItems()
->reduce(function ($sum, ItemInterface $item) {
if ($item instanceof OrderItem) {
$sum += $item->getTax() * $item->getQuantity();
} else {
if ($itemHolder instanceof Order) {
$total = array_reduce($itemHolder->getTaxByTaxRate(), function ($sum, $tax) {
return $sum + $tax;
}, 0);
} else {
$total = $itemHolder->getItems()
->reduce(function ($sum, ItemInterface $item) {
$sum += ($item->getPriceIncTax() - $item->getPrice()) * $item->getQuantity();
}

return $sum;
}, 0);
return $sum;
}, 0);
}
$itemHolder->setTax($total);
}

Expand Down
15 changes: 14 additions & 1 deletion tests/Eccube/Tests/Fixture/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ public function createOrder(Customer $Customer, array $ProductClasses = [], Deli
$ItemDeliveryFee = $this->entityManager->find(OrderItemType::class, OrderItemType::DELIVERY_FEE);
$ItemCharge = $this->entityManager->find(OrderItemType::class, OrderItemType::CHARGE);
$ItemDiscount = $this->entityManager->find(OrderItemType::class, OrderItemType::DISCOUNT);
$ItemPoint = $this->entityManager->find(OrderItemType::class, OrderItemType::POINT);
$BaseInfo = $this->entityManager->getRepository(BaseInfo::class)->get();

/** @var ProductClass $ProductClass */
Expand Down Expand Up @@ -727,6 +728,19 @@ public function createOrder(Customer $Customer, array $ProductClasses = [], Deli
// $Shipping->addOrderItem($OrderItemDiscount); // Shipping には登録しない
$Order->addOrderItem($OrderItemDiscount);

if (($point = mt_rand(0, min($Customer->getPoint(), $Order->getPaymentTotal()))) > 0) {
$OrderItemPoint = new OrderItem();
$OrderItemPoint
->setOrder($Order)
->setProductName('ポイント')
->setPrice($point * -1)
->setQuantity(1)
->setTaxType($NonTaxable)
->setTaxDisplayType($TaxInclude)
->setOrderItemType($ItemPoint);
$Order->addOrderItem($OrderItemPoint);
}

$this->orderPurchaseFlow->validate($Order, new PurchaseContext($Order));

$this->entityManager->flush();
Expand Down Expand Up @@ -900,7 +914,6 @@ public function createLoginHistory($user_name, $client_ip = null, $status = null
* Faker を生成する.
*
* @return \Faker\Generator
*
*/
protected function getFaker()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,16 @@ public function testSort()
{
shuffle($this->Items);

$this->expected = [1 => '商品', 2 => '送料', 3 => '手数料', 4 => '割引'];
$this->expected = [1 => '商品', 2 => '送料', 3 => '手数料'];
$this->actual = [];
$Items = (new ItemCollection($this->Items))->sort();
foreach ($Items as $Item) {
$this->actual[$Item->getOrderItemType()->getId()] = $Item->getOrderItemType()->getName();
}
if (array_key_exists(6, $this->actual)) {
$this->expected[6] = 'ポイント';
}
$this->expected[4] = '割引';

$this->verify();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eccube\Tests\Service\PurchaseFlow\Processor;

use Eccube\Entity\Cart;
use Eccube\Service\PurchaseFlow\Processor\PaymentTotalNegativeValidator;
use Eccube\Service\PurchaseFlow\PurchaseContext;
use Eccube\Tests\EccubeTestCase;

class PaymentTotalNegativeValidatorTest extends EccubeTestCase
{
public function testPositiveValidate()
{
$validator = $this->newValidator();

$cart = new Cart();
$cart->setTotal(100);

$result = $validator->execute($cart, new PurchaseContext());
self::assertTrue($result->isSuccess());
}

public function testNegativeValidate()
{
$validator = $this->newValidator();

$cart = new Cart();
$cart->setTotal(-100);

$result = $validator->execute($cart, new PurchaseContext());
self::assertTrue($result->isError());
}

/**
* @return PaymentTotalNegativeValidator
*/
private function newValidator()
{
return static::getContainer()->get(PaymentTotalNegativeValidator::class);
}
}
61 changes: 42 additions & 19 deletions tests/Eccube/Tests/Web/Admin/Order/EditControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
use Eccube\Entity\Customer;
use Eccube\Entity\MailHistory;
use Eccube\Entity\Master\Job;
use Eccube\Entity\Master\Sex;
use Eccube\Entity\Master\OrderStatus;
use Eccube\Entity\Master\RoundingType;
use Eccube\Entity\Master\Sex;
use Eccube\Entity\Master\TaxType;
use Eccube\Entity\Order;
use Eccube\Entity\Product;
use Eccube\Entity\ProductClass;
Expand Down Expand Up @@ -174,23 +175,24 @@ public function testNotUpdateLastBuyDate()
* ・ <script> スクリプトインジェクション
*
* @see https://github.com/EC-CUBE/ec-cube/issues/5372
*
* @return void
*/
public function testOrderMailXSSAttackPrevention()
{
// Create a new news item for the homepage with a XSS attack (via <script> AND id attribute injection)
$Customer = $this->createCustomer();
$Order = $this->createOrder($Customer);
$MailHistory = (New MailHistory())->setMailHtmlBody(
"<div id='dangerous-id' class='safe_to_use_class'>
$MailHistory = (new MailHistory())->setMailHtmlBody(
"<div id='dangerous-id' class='safe_to_use_class'>
<p>メール内容#1</p>
<script>alert('XSS Attack')</script>
<a href='https://www.google.com'>safe html</a>
</div>"
)
->setOrder($Order)
->setMailSubject("テスト")
->setMailBody("テスト内容")
->setMailSubject('テスト')
->setMailBody('テスト内容')
->setSendDate(new \DateTime())
->setCreator($this->createMember());
$this->entityManager->persist($MailHistory);
Expand Down Expand Up @@ -448,8 +450,8 @@ public function testOrderProcessingWithTax()
// 管理画面から受注登録
$this->client->request(
'POST', $this->generateUrl('admin_order_edit', ['id' => $Order->getId()]), [
'order' => $formData,
'mode' => 'register',
'order' => $formData,
'mode' => 'register',
]
);

Expand All @@ -458,27 +460,48 @@ public function testOrderProcessingWithTax()
$EditedOrder = $this->orderRepository->find($Order->getId());
$formDataForEdit = $this->createFormDataForEdit($EditedOrder);

//税金計算
$totalTax = 0;
foreach ($formDataForEdit['OrderItems'] as $indx => $orderItem) {
//商品数変更3個追加
$formDataForEdit['OrderItems'][$indx]['quantity'] = $orderItem['quantity'] + 3;
$tax = static::getContainer()->get(TaxRuleService::class)->getTax($orderItem['price']);
$totalTax += $tax * $formDataForEdit['OrderItems'][$indx]['quantity'];
$addingQuantity = 3;
foreach ($formDataForEdit['OrderItems'] as $index => $orderItem) {
// 商品数変更3個追加
$formDataForEdit['OrderItems'][$index]['quantity'] = $orderItem['quantity'] + $addingQuantity;
}

// 管理画面で受注編集する
$this->client->request(
'POST', $this->generateUrl('admin_order_edit', ['id' => $Order->getId()]), [
'order' => $formDataForEdit,
'mode' => 'register',
'order' => $formDataForEdit,
'mode' => 'register',
]
);

$this->assertTrue($this->client->getResponse()->isRedirect($this->generateUrl('admin_order_edit', ['id' => $Order->getId()])));
$EditedOrderafterEdit = $this->orderRepository->find($Order->getId());

//確認する「トータル税金」
// 税金計算
$taxableItem = array_filter($EditedOrder->getOrderItems()->toArray(), function ($OrderItem) {
return !is_null($OrderItem->getTaxType()) && $OrderItem->getTaxType()->getId() === TaxType::TAXATION;
});
$totalTaxByTaxRate = [];
$totalByTaxRate = [];
foreach ($taxableItem as $OrderItem) {
$totalPrice = $OrderItem->getPriceIncTax() * ($OrderItem->getQuantity() + $addingQuantity);
$taxRate = $OrderItem->getTaxRate();
$totalByTaxRate[$taxRate] = isset($totalByTaxRate[$taxRate])
? $totalByTaxRate[$taxRate] + $totalPrice
: $totalPrice;
}
foreach ($totalByTaxRate as $rate => $price) {
$tax = static::getContainer()->get(TaxRuleService::class)
->roundByRoundingType($price * ($rate / (100 + $rate)), \Eccube\Entity\Master\RoundingType::ROUND);
$totalTaxByTaxRate[$rate] = $tax;
}
$totalTax = array_reduce($totalTaxByTaxRate, function ($sum, $tax) {
$sum += $tax;

return $sum;
}, 0);

// 確認する「トータル税金」
$this->expected = $totalTax;
$this->actual = $EditedOrderafterEdit->getTax();
$this->verify();
Expand Down Expand Up @@ -597,8 +620,8 @@ public function testUpdateShippingDeliveryTimeToNoneSpecified()
// 管理画面で受注編集する
$this->client->request(
'POST', $this->generateUrl('admin_order_edit', ['id' => $Order->getId()]), [
'order' => $formDataForEdit,
'mode' => 'register',
'order' => $formDataForEdit,
'mode' => 'register',
]
);
$this->assertTrue($this->client->getResponse()->isRedirect($this->generateUrl('admin_order_edit', ['id' => $Order->getId()])));
Expand Down

0 comments on commit dbf0f4e

Please sign in to comment.