Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]商品一覧と商品詳細で商品別税率が反映されないのを修正 #298

Closed
wants to merge 9 commits into from

Conversation

nanasess
Copy link
Contributor

@nanasess nanasess commented Aug 14, 2019

  • 商品別税率機能の不具合 #99 の対応
  • 税込価格計算時に、商品別税率を取得するよう修正
  • SC_Product::sfCalcIncTax() に product_class_id を渡すよう修正
  • SC_DB_DBFactory::alldtlSQL などの SQL をカスタマイズしている場合でも影響を受けにくいように SC_Product のみの修正で対応
  • 他に良い修正方法のアイディアありましたらご教授ください

課題点

同一商品で規格ごとに税率も価格も異なり、税抜と税込で最小値、最大値の規格が変わるというケースは正確な処理ができない

具体的にはprice02が 1000円×10%=1100円というproduct_class_id=1と、1010円×8%=1091円というproduct_class_id=2があった場合、findProductClassIdByRuleは product_class_id=2をminとして採用してしまう
#298 (comment)

このようなケースは希だと思われるため、実運用で発生する場合は以下のパッチを推奨

see https://github.com/EC-CUBE/eccube-2_13/issues/99#issuecomment-518100061

 diff --git a/data/class/SC_Product.php b/data/class/SC_Product.php
index c5ea95f..6dfa386 100644
--- a/data/class/SC_Product.php
+++ b/data/class/SC_Product.php
@@ -135,6 +135,10 @@ class SC_Product
             ,price01_max
             ,price02_min
             ,price02_max
+            ,price01_min_inctax
+            ,price01_max_inctax
+            ,price02_min_inctax
+            ,price02_max_inctax
             ,stock_min
             ,stock_max
             ,stock_unlimited_min
@@ -185,9 +189,6 @@ __EOS__;
             unset($arrTmp);
         }
 
-        // 税込金額を設定する
-        SC_Product_Ex::setIncTaxToProducts($arrProducts);
-
         return $arrProducts;
     }
 
@@ -206,9 +207,6 @@ __EOS__;
         $arrWhereVal = array($product_id);
         $arrProduct = (array)$objQuery->getRow('*', $from, $where, $arrWhereVal);
 
-        // 税込金額を設定する
-        SC_Product_Ex::setIncTaxToProduct($arrProduct);
-
         return $arrProduct;
     }
 
@@ -569,8 +567,6 @@ __EOS__;
             $arrProduct['price02_min_format'] = number_format($arrProduct['price02_min']);
             $arrProduct['price02_max_format'] = number_format($arrProduct['price02_max']);
 
-            SC_Product_Ex::setIncTaxToProduct($arrProduct);
-
             $arrProduct['price01_min_inctax_format'] = number_format($arrProduct['price01_min_inctax']);
             $arrProduct['price01_max_inctax_format'] = number_format($arrProduct['price01_max_inctax']);
             $arrProduct['price02_min_inctax_format'] = number_format($arrProduct['price02_min_inctax']);
@@ -591,7 +587,7 @@ __EOS__;
     }
 
     /**
-     * 商品情報の配列に税込金額を設定する
+     * 商品情報の配列に税込金額を設定する ※独自改造等での使用を配慮して残す
      *
      * @param  array $arrProducts 商品情報の配列
      * @return void
@@ -604,7 +600,7 @@ __EOS__;
     }
 
     /**
-     * 商品情報の配列に税込金額を設定する
+     * 商品情報の配列に税込金額を設定する ※独自改造等での使用を配慮して残す
      *
      * @param  array $arrProduct 商品情報の配列
      * @return void
diff --git a/data/class/db/SC_DB_DBFactory.php b/data/class/db/SC_DB_DBFactory.php
index 6dfab82..ffaae62 100644
--- a/data/class/db/SC_DB_DBFactory.php
+++ b/data/class/db/SC_DB_DBFactory.php
@@ -247,6 +247,20 @@ class SC_DB_DBFactory
         if (!SC_Utils_Ex::isBlank($where_products_class)) {
             $where_products_class = 'AND (' . $where_products_class . ')';
         }
+        $taxRule = SC_Helper_TaxRule_Ex::getTaxRule();
+        if ($taxRule['calc_rule'] == '1') {
+            $rule = 'ROUND';
+        } elseif ($taxRule['calc_rule'] == '2') {
+            $rule = 'FLOOR';
+        } elseif ($taxRule['calc_rule'] == '3') {
+            $rule = 'CEIL';
+        }
+        $base_rate = $taxRule['tax_rate'];
+        if (OPTION_PRODUCT_TAX_RULE) {
+            $tax_rate = "COALESCE((SELECT tax_rate FROM dtb_tax_rule WHERE del_flg=0 AND product_class_id=dtb_products_class.product_class_id),$base_rate)";
+        } else {
+            $tax_rate = $base_rate;
+        }
         /*
          * point_rate, deliv_fee は商品規格(dtb_products_class)ごとに保持しているが,
          * 商品(dtb_products)ごとの設定なので MAX のみを取得する.
@@ -261,6 +275,10 @@ class SC_DB_DBFactory
                     ,T4.price01_max
                     ,T4.price02_min
                     ,T4.price02_max
+                    ,T4.price01_min_inctax
+                    ,T4.price01_max_inctax
+                    ,T4.price02_min_inctax
+                    ,T4.price02_max_inctax
                     ,T4.price_first_min
                     ,T4.price_first_max
                     ,T4.stock_min
@@ -279,6 +297,10 @@ class SC_DB_DBFactory
                             ,MAX(price01) AS price01_max
                             ,MIN(price02) AS price02_min
                             ,MAX(price02) AS price02_max
+                            ,MIN($rule(price01 * (100 + $tax_rate) / 100)) AS price01_min_inctax
+                            ,MAX($rule(price01 * (100 + $tax_rate) / 100)) AS price01_max_inctax
+                            ,MIN($rule(price02 * (100 + $tax_rate) / 100)) AS price02_min_inctax
+                            ,MAX($rule(price02 * (100 + $tax_rate) / 100)) AS price02_max_inctax
                             ,MIN(price_first) AS price_first_min
                             ,MAX(price_first) AS price_first_max
                             ,MIN(stock) AS stock_min
diff --git a/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Recommend.php b/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Recommend.php
index 7fbcaa5..af3651a 100644
--- a/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Recommend.php
+++ b/data/class/pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Recommend.php
@@ -92,9 +92,6 @@ class LC_Page_FrontParts_Bloc_Recommend extends LC_Page_FrontParts_Bloc_Ex
             }
             $arrProducts = $objProduct->getListByProductIds($objQuery, $arrProductId);
 
-            // 税込金額を設定する
-            SC_Product_Ex::setIncTaxToProducts($arrProducts);
-
             // おすすめ商品情報にマージ
             foreach ($arrRecommends as $key => $value) {
                 if (isset($arrProducts[$value['product_id']])) {
diff --git a/data/class/pages/mypage/LC_Page_Mypage_Favorite.php b/data/class/pages/mypage/LC_Page_Mypage_Favorite.php
index 344533b..a39294c 100644
--- a/data/class/pages/mypage/LC_Page_Mypage_Favorite.php
+++ b/data/class/pages/mypage/LC_Page_Mypage_Favorite.php
@@ -157,9 +157,6 @@ class LC_Page_Mypage_Favorite extends LC_Page_AbstractMypage_Ex
             $arrProductsList[] = $arrProducts2[$product_id];
         }
 
-        // 税込金額を設定する
-        SC_Product_Ex::setIncTaxToProducts($arrProductsList);
-
         return $arrProductsList;
     }
 
diff --git a/data/class/pages/rss/LC_Page_Rss_Products.php b/data/class/pages/rss/LC_Page_Rss_Products.php
index 368ea22..f222fee 100644
--- a/data/class/pages/rss/LC_Page_Rss_Products.php
+++ b/data/class/pages/rss/LC_Page_Rss_Products.php
@@ -309,9 +309,6 @@ class LC_Page_Rss_Products extends LC_Page_Ex
             }
         }
 
-        // 税込金額を設定する
-        SC_Product_Ex::setIncTaxToProducts($arrProducts);
-
         return $arrProducts;
     }
 }

@nanasess nanasess changed the title 商品一覧と商品詳細で商品別税率が反映されないのを修正 [WIP]商品一覧と商品詳細で商品別税率が反映されないのを修正 Aug 15, 2019
@coveralls
Copy link

coveralls commented Aug 15, 2019

Coverage Status

Coverage increased (+0.3%) to 43.33% when pulling 20d57e0 on nanasess:fix-intax into b19397d on EC-CUBE:improve/php7.

@nobuhiko
Copy link
Contributor

重そうな処理ですねぇ。。

@nanasess
Copy link
Contributor Author

@nobuhiko この処理よりも、商品別税率を ON にしたとき products_class_id ごとに dtb_tax_rule を取得しにいくので、そちらの方がボトルネックだったりします。
(商品一覧15商品で9個ずつ規格がついていたら135回 コールされる。3系4系も同様)
せめて product_id ごとにキャッシュするようにしたいです

@nanasess nanasess changed the title [WIP]商品一覧と商品詳細で商品別税率が反映されないのを修正 商品一覧と商品詳細で商品別税率が反映されないのを修正 Aug 16, 2019
@nomoto-neo
Copy link

nomoto-neo commented Aug 16, 2019

ざっと処理内容を見ただけなので勘違いならすみません。

function setIncTaxToProduct 内で、SC_Helper_TaxRule_Ex::sfCalcIncTax に渡す product_class_id を見つけてくるために、 SC_Product_Ex::findProductClassIdByRule を使って price02に税金を掛けた金額がminになる product_class_id を見つけてきていますが、これって確かに price02×税率 がminではありますが、それは price02_min に掛けても良い税率なのでしょうか?

具体的にはprice02が 1000円×10%=1100円というproduct_class_id=1と、1010円×8%=1091円というproduct_class_id=2があった場合、findProductClassIdByRuleは product_class_id=2をminとして採用してしまうのではないでしょうか。
それだとprice02_minに対して8%を掛けてしまうので setIncTaxToProduct の計算結果は price02_min=1000 で price02_min_inctax=1080 になってしまう気がします

@nanasess
Copy link
Contributor Author

@nomoto-neo 貴重なご意見ありがとうございます。
こちらのコメントでいただいたパッチ のように処理するのが本筋だと思うのですが、 #296 のような高速化施策も入れたいため、ここでのサブクエリは増やしたくないのが本音です。
同一商品で規格ごとに税率も価格も異なり、税抜と税込で最小値、最大値の規格が変わるというケースは、実運用では希だと思いますので、本PRはこのままの実装としようと思います。
(いただいたパッチはサンプルコードとして載せておきます)

@nobuhiko
Copy link
Contributor

@nanasess 規格毎に税率を設定できる機能をなくしましょう。ほぼtplの変更だけで大丈夫だと思いますし

@nanasess
Copy link
Contributor Author

@nobuhiko それも手ですね。他の方の意見も伺いたいところです

@nomoto-neo
Copy link

税率が変わるのは商品に含まれる食品の比率が2/3を超えるかどうかなので、規格単位で税率が変わる事はないと思います。
なので、規格単位に税率を設定できる機能を削る案に賛成です。
むしろ税率が変わる商品なら説明文をつけて別商品として登録してもらう方が購入者にも親切だと思いますし。
規格単位の税率が統一されていれば、setIncTaxToProduct 内で税率計算する処理もかなりシンプルに軽くできそうですね。

@seasoftjapan
Copy link
Contributor

うちのお客様でも何件か軽減税率対応を進めていますが、今のところ商品(商品ID)単位で足りています。

@nanasess
Copy link
Contributor Author

規格単位の税率設定を削ったパターンも実装してみますね

@chihiro-adachi chihiro-adachi added this to the 2.17.0 milestone Aug 21, 2019
@nanasess nanasess changed the title 商品一覧と商品詳細で商品別税率が反映されないのを修正 [WIP]商品一覧と商品詳細で商品別税率が反映されないのを修正 Aug 21, 2019
@nanasess
Copy link
Contributor Author

@nobuhiko @nomoto-neo @seasoftjapan
実装してみました #301

@nanasess
Copy link
Contributor Author

#301 のほうが有用そうですので、こちらはクローズします

@nanasess nanasess closed this Aug 22, 2019
@nanasess nanasess deleted the fix-intax branch October 3, 2022 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants