source: branches/version-2_13-dev/data/class/helper/SC_Helper_TaxRule.php @ 23463

Revision 23463, 15.1 KB checked in by shutta, 10 years ago (diff)

#2562 課税規則による端数処理ルーチンの共通関数化
課税規則に応じた端数処理ルーチンを共通関数にまとめた。

RevLine 
[22619]1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2013 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/**
[22626]25 * 税規約を管理するヘルパークラス.
[22619]26 *
27 * @package Helper
28 * @author AMUAMU
29 * @version $Id:$
30 */
31class SC_Helper_TaxRule
32{
33    /**
[22620]34     * 設定情報に基づいて税金付与した金額を返す
[22619]35     *
[23415]36     * @param int $price 計算対象の金額
37     * @param int $product_id 商品ID
38     * @param int $product_class_id 商品規格ID
39     * @param int $pref_id 都道府県ID
40     * @param int $country_id 国ID
41     * @return int 税金付与した金額
[22620]42     */
[23415]43    public static function sfCalcIncTax($price, $product_id = 0, $product_class_id = 0, $pref_id =0, $country_id = 0)
[22620]44    {
[22626]45        return $price + SC_Helper_TaxRule_Ex::sfTax($price, $product_id, $product_class_id, $pref_id, $country_id);
46    }
47
48    /**
49     * 設定情報に基づいて税金の金額を返す
50     *
[23415]51     * @param int $price 計算対象の金額
52     * @param int $product_id 商品ID
53     * @param int $product_class_id 商品規格ID
54     * @param int $pref_id 都道府県ID
55     * @param int $country_id 国ID
56     * @return int 税金付与した金額
[22626]57     */
[23415]58    public static function sfTax($price, $product_id = 0, $product_class_id = 0, $pref_id =0, $country_id = 0)
[22626]59    {
[22623]60        $arrTaxRule = SC_Helper_TaxRule_Ex::getTaxRule($product_id, $product_class_id, $pref_id, $country_id);
[22856]61
[22626]62        return SC_Helper_TaxRule_Ex::calcTax($price, $arrTaxRule['tax_rate'], $arrTaxRule['tax_rule'], $arrTaxRule['tax_adjust']);
[22620]63    }
64
65    /**
[22628]66     * 設定情報IDに基づいて税金付与した金額を返す
67     * (受注データのようにルールが決まっている場合用)
68     *
[23415]69     * @param int $price 計算対象の金額
70     * @param int $tax_rule_id 税規約ID
71     * @return int 税金付与した金額
[22628]72     */
[23415]73    public static function calcIncTaxFromRuleId($price, $tax_rule_id = 0)
[22628]74    {
75        return $price + SC_Helper_TaxRule_Ex::calcTaxFromRuleId($price, $tax_rule_id);
76    }
77
78    /**
79     * 設定情報IDに基づいて税金の金額を返す
80     * (受注データのようにルールが決まっている場合用)
81     *
[23415]82     * @param int $price 計算対象の金額
83     * @param int $tax_rule_id 税規約ID
84     * @return int 税金付与した金額
[22628]85     */
[23415]86    public static function calcTaxFromRuleId($price, $tax_rule_id = 0)
[22628]87    {
88        $arrTaxRule = SC_Helper_TaxRule_Ex::getTaxRuleData($tax_rule_id);
[22856]89
[22628]90        return SC_Helper_TaxRule_Ex::calcTax($price, $arrTaxRule['tax_rate'], $arrTaxRule['tax_rule'], $arrTaxRule['tax_adjust']);
91    }
92
93    /**
[22626]94     * 税金額を計算する
[22620]95     *
[23415]96     * @param int $price 計算対象の金額
97     * @param int $tax 税率(%単位)
98     *     XXX int のみか不明
99     * @param int $calc_rule 端数処理
100     * @param int $tax_adjust 調整額
101     * @return int 税金額
[22619]102     */
[23415]103    public static function calcTax ($price, $tax, $calc_rule, $tax_adjust = 0)
[22619]104    {
[22620]105        $real_tax = $tax / 100;
106        $ret = $price * $real_tax;
[23463]107        $ret = SC_Helper_TaxRule_Ex::roundByCalcRule($ret, $calc_rule);
[22856]108
[22620]109        return $ret + $tax_adjust;
110    }
111
112    /**
[23230]113     * 現在有効な税率設定情報を返す
[22620]114     *
[23415]115     * @param int $product_id 商品ID
116     * @param int $product_class_id 商品規格ID
117     * @param int $pref_id 都道府県ID
118     * @param int $country_id 国ID
119     * @return array 税設定情報
[22620]120     */
[23415]121    public static function getTaxRule($product_id = 0, $product_class_id = 0, $pref_id = 0, $country_id = 0)
[22620]122    {
[23405]123        // 複数回呼出があるのでキャッシュ化
124        static $data_c = array();
125
[22702]126        // 初期化
127        $product_id = $product_id > 0 ? $product_id : 0;
128        $product_class_id = $product_class_id > 0 ? $product_class_id : 0;
129        $pref_id = $pref_id > 0 ? $pref_id : 0;
130        $country_id = $country_id > 0 ? $country_id : 0;
131
[22976]132        // 一覧画面の速度向上のため商品単位税率設定がOFFの時はキャッシュキーを丸めてしまう
133        if (OPTION_PRODUCT_TAX_RULE == 1) {
134            $cache_key = "$product_id,$product_class_id,$pref_id,$country_id";
135        } else {
136            $cache_key = "$pref_id,$country_id";
137        }
[22619]138
[23405]139        if (empty($data_c[$cache_key])) {
140            // ログイン済み会員で国と地域指定が無い場合は、会員情報をデフォルトで利用。管理画面では利用しない
141            if (!(defined('ADMIN_FUNCTION') && ADMIN_FUNCTION == true)) {
142                $objCustomer = new SC_Customer_Ex();
143                if ($objCustomer->isLoginSuccess(true)) {
144                    if ($country_id == 0) {
145                        $country_id = $objCustomer->getValue('country_id');
146                    }
147                    if ($pref_id == 0) {
148                        $pref_id = $objCustomer->getValue('pref');
149                    }
150                }
151            }
[22691]152
153            $arrRet = array();
[22976]154            // リクエストの配列化
155            $arrRequest = array('product_id' => $product_id,
156                            'product_class_id' => $product_class_id,
157                            'pref_id' => $pref_id,
158                            'country_id' => $country_id);
[22691]159
[22976]160            // 地域設定を優先するが、システムパラメーターなどに設定を持っていくか
161            // 後に書いてあるほど優先される、詳細後述MEMO参照
162            $arrPriorityKeys = explode(',', TAX_RULE_PRIORITY);
163
[22691]164            // 条件に基づいて税の設定情報を取得
165            $objQuery =& SC_Query_Ex::getSingletonInstance();
166            $table = 'dtb_tax_rule';
[22976]167            $cols = '*';
[23334]168
[23170]169            // 商品税率有無設定により分岐
170            if(OPTION_PRODUCT_TAX_RULE == 1) {
[23334]171                $where = '
172                        (
173                            (product_id = 0 OR product_id = ?)
174                            AND (product_class_id = 0 OR product_class_id = ?)
175                        )
176                    AND (pref_id = 0 OR pref_id = ?)
177                    AND (country_id = 0 OR country_id = ?)
178                    AND apply_date < CURRENT_TIMESTAMP
179                    AND del_flg = 0';
[23170]180                $arrVal = array($product_id, $product_class_id, $pref_id, $country_id);
181            } else {
182                $where = '     product_id = 0 '
183                       . ' AND product_class_id = 0 '
184                       . ' AND (pref_id = 0 OR pref_id = ?)'
185                       . ' AND (country_id = 0 OR country_id = ?)'
186                       . ' AND apply_date < CURRENT_TIMESTAMP'
187                       . ' AND del_flg = 0';
188                $arrVal = array($pref_id, $country_id);
189            }
[22691]190
[22976]191            $order = 'apply_date DESC';
[22691]192            $objQuery->setOrder($order);
193            $arrData = $objQuery->select($cols, $table, $where, $arrVal);
194            // 優先度付け
195            // MEMO: 税の設定は相反する設定を格納可能だが、その中で優先度を付けるため
196            //       キーの優先度により、利用する税設定を判断する
197            //       優先度が同等の場合、適用日付で判断する
198            foreach ($arrData as $data_key => $data) {
199                $res = 0;
200                foreach ($arrPriorityKeys as $key_no => $key) {
201                    if ($arrRequest[$key] != 0 && $data[$key] == $arrRequest[$key]) {
202                        // 配列の数値添字を重みとして利用する
203                        $res += 1 << ($key_no + 1);
204                    }
205                }
206                $arrData[$data_key]['rank'] = $res;
207            }
208
209            // 優先順位が高いものを返却値として確定
210            // 適用日降順に並んでいるので、単に優先順位比較のみで格納判断可能
211            foreach ($arrData as $data) {
212                if (!isset($arrRet['rank']) || $arrRet['rank'] < $data['rank']) {
213                    // 優先度が高い場合, または空の場合
214                    $arrRet = $data;
215                }
216            }
[22976]217            // XXXX: 互換性のためtax_ruleにもcalc_ruleを設定
218            $arrRet['tax_rule'] = $arrRet['calc_rule'];
[22691]219            $data_c[$cache_key] = $arrRet;
220        }
221
222        return $data_c[$cache_key];
[22620]223    }
[22619]224
[22638]225    /**
[23230]226     * 税率設定情報を登録する(商品管理用)
[22638]227     *
[23415]228     * @param float $tax_rate 消費税率
229     * @param int $product_id 商品ID
230     * @param int $product_class_id 商品規格ID
231     * @param float|int $tax_adjust 消費税加算額
232     * @param int $pref_id 県ID
233     * @param int $country_id 国ID
[22700]234     * @return void
[22638]235     */
[23415]236    public static function setTaxRuleForProduct($tax_rate, $product_id = 0, $product_class_id = 0, $tax_adjust=0, $pref_id = 0, $country_id = 0)
[22638]237    {
[22700]238        // 基本設定を取得
[22976]239        $arrRet = SC_Helper_TaxRule_Ex::getTaxRule($product_id, $product_class_id);
240
[22700]241        // 基本設定の消費税率と一緒であれば設定しない
[23124]242        if ($arrRet['tax_rate'] != $tax_rate) {
[22700]243            // 課税規則は基本設定のものを使用
244            $calc_rule = $arrRet['calc_rule'];
[22976]245            // 日付は登録時点を設定
246            $apply_date = date('Y/m/d H:i:s');
[22700]247            // 税情報を設定
[23088]248            SC_Helper_TaxRule_Ex::setTaxRule($calc_rule, $tax_rate, $apply_date, NULL, $tax_adjust, $product_id, $product_class_id, $pref_id, $country_id);
[22700]249        }
[22638]250    }
[22620]251
[22638]252    /**
[23230]253     * 税率設定情報を登録する(仮)リファクタする(memo:規格設定後に商品編集を行うと消費税が0になるのを対応が必要)
[22638]254     *
[23415]255     * @param int $calc_rule 端数処理
256     * @param int $tax_rate 税率
257     * @param int|string $apply_date 適用日時
258     * @param null $tax_rule_id 税規約ID
259     * @param int $tax_adjust 調整額
260     * @param int $product_id 商品ID
261     * @param int $product_class_id 商品規格ID
262     * @param int $pref_id 都道府県ID
263     * @param int $country_id 国ID
264     * @return void
[22638]265     */
[23124]266    public function setTaxRule($calc_rule, $tax_rate, $apply_date, $tax_rule_id=NULL, $tax_adjust=0, $product_id = 0, $product_class_id = 0, $pref_id = 0, $country_id = 0)
[22638]267    {
[22691]268        $table = 'dtb_tax_rule';
269        $arrValues = array();
270        $arrValues['calc_rule'] = $calc_rule;
271        $arrValues['tax_rate'] = $tax_rate;
272        $arrValues['tax_adjust'] = $tax_adjust;
273        $arrValues['apply_date'] = $apply_date;
274        $arrValues['member_id'] = $_SESSION['member_id'];
275        $arrValues['update_date'] = 'CURRENT_TIMESTAMP';
276
[22653]277        // 新規か更新か?
[22638]278        $objQuery =& SC_Query_Ex::getSingletonInstance();
[23124]279        if ($tax_rule_id == NULL && $product_id != 0 && $product_class_id != 0) {
[22700]280            $where = 'product_id = ? AND product_class_id= ? AND pref_id = ? AND country_id = ?';
281            $arrVal = array($product_id, $product_class_id, $pref_id, $country_id);
282            $arrCheck = $objQuery->getRow('*', 'dtb_tax_rule', $where, $arrVal);
283            $tax_rule_id = $arrCheck['tax_rule_id'];
[22691]284        }
285
[23124]286        if ($tax_rule_id == NULL) {
[22653]287            // 税情報を新規
[22666]288            // INSERTの実行
289            $arrValues['tax_rule_id'] = $objQuery->nextVal('dtb_tax_rule_tax_rule_id');
[22653]290            $arrValues['country_id'] = $country_id;
291            $arrValues['pref_id'] = $pref_id;
292            $arrValues['product_id'] = $product_id;
293            $arrValues['product_class_id'] = $product_class_id;
[22691]294            $arrValues['create_date'] = 'CURRENT_TIMESTAMP';
295
[22653]296            $objQuery->insert($table, $arrValues);
297        } else {
298            // 税情報を更新
[22666]299            $where = 'tax_rule_id = ?';
[22697]300            $objQuery->update($table, $arrValues, $where, array($tax_rule_id));
[22653]301        }
[22638]302    }
[22691]303
[23415]304    /**
305     * @param bool $has_deleted
306     * @return array|null
307     */
[23124]308    public function getTaxRuleList($has_deleted = false)
[22620]309    {
[22644]310        $objQuery =& SC_Query_Ex::getSingletonInstance();
311        $col = 'tax_rule_id, tax_rate, calc_rule, apply_date';
312        $where = '';
313        if (!$has_deleted) {
[22716]314            $where .= 'del_flg = 0 AND product_id = 0 AND product_class_id = 0';
[22644]315        }
316        $table = 'dtb_tax_rule';
[22976]317        // 適用日時順に更新
[22717]318        $objQuery->setOrder('apply_date DESC');
[22644]319        $arrRet = $objQuery->select($col, $table, $where);
[22856]320
[22644]321        return $arrRet;
[22619]322    }
323
[23415]324    /**
325     * @param int $tax_rule_id
326     * @param bool $has_deleted
327     * @return array
328     */
[23124]329    public function getTaxRuleData($tax_rule_id, $has_deleted = false)
[22620]330    {
[22628]331        $objQuery =& SC_Query_Ex::getSingletonInstance();
[22644]332        $where = 'tax_rule_id = ?';
333        if (!$has_deleted) {
334            $where .= ' AND del_flg = 0';
335        }
[22856]336
[22666]337        return $objQuery->getRow('*', 'dtb_tax_rule', $where, array($tax_rule_id));
[22620]338    }
339
[23415]340    /**
341     * @param int|string $apply_date
342     * @param bool $has_deleted
343     * @return mixed
344     */
[23124]345    public function getTaxRuleByTime($apply_date, $has_deleted = false)
[22644]346    {
347        $objQuery =& SC_Query_Ex::getSingletonInstance();
348        $where = 'apply_date = ?';
349        if (!$has_deleted) {
350            $where .= ' AND del_flg = 0';
351        }
352        $arrRet = $objQuery->select('*', 'dtb_tax_rule', $where, array($apply_date));
[22856]353
[22644]354        return $arrRet[0];
[22620]355    }
[22628]356
[22644]357    /**
358     * 税規約の削除.
359     *
[23415]360     * @param  int $tax_rule_id 税規約ID
[22644]361     * @return void
362     */
[23124]363    public function deleteTaxRuleData($tax_rule_id)
[22644]364    {
365        $objQuery =& SC_Query_Ex::getSingletonInstance();
[22666]366
367        $sqlval = array();
[22644]368        $sqlval['del_flg']     = 1;
369        $sqlval['update_date'] = 'CURRENT_TIMESTAMP';
370        $where = 'tax_rule_id = ?';
371        $objQuery->update('dtb_tax_rule', $sqlval, $where, array($tax_rule_id));
372    }
[23463]373
374    /**
375     * 課税規則に応じて端数処理を行う
376     *
377     * @param float|integer $value 端数処理を行う数値
378     * @param integer $calc_rule 課税規則
379     * @return integer 端数処理後の数値
380     */
381    public static function roundByCalcRule($value, $calc_rule)
382    {
383        switch ($calc_rule) {
384            // 四捨五入
385            case 1:
386                $ret = round($value);
387                break;
388            // 切り捨て
389            case 2:
390                $ret = floor($value);
391                break;
392            // 切り上げ
393            case 3:
394                $ret = ceil($value);
395                break;
396            // デフォルト:切り上げ
397            default:
398                $ret = ceil($value);
399                break;
400        }
401
402        return $ret;
403    }
[22619]404}
Note: See TracBrowser for help on using the repository browser.