Yii2中的平板电费计算
Slab wise electricity bill calculation in Yii2
我正在研究 yii2
。我想明智地计算电费。为此,我已经在 table 中插入了 slab 及其各自的比率。现在我要计算一下。
我的单位是128.82
,下面是我的平板和它们的费率。
我可以使用以下查询来执行 slab
$mData = \Yii::$app->db->createCommand("SELECT s.`slab_start`, s.`slab_end`, s.`rate`, r.`cust_id`
FROM `mdc_tariff_slabs` s
INNER JOIN `mdc_meter_cust_rel` r ON s.`t_id` = r.`tariff_id`
WHERE r.`cust_id` = $consumer_no")->queryAll();
array(3) { [0]=> array(3) { ["slab_start"]=> string(1) "1" ["slab_end"]=> string(3) "100" ["rate"]=> string(2) "10" } [1]=> array(3) { ["slab_start"]=> string(3) "101" ["slab_end"]=> string(3) "150" ["rate"]=> string(2) "12" } [2]=> array(3) { ["slab_start"]=> string(3) "151" ["slab_end"]=> NULL ["rate"]=> string(2) "14" } }
注意:以后的slab可能会有所不同
我已经试过下面的代码,按照我的要求设置slabs并尝试拿到账单
public static function calcBill($units)
{
if($units < 100){
$bill = $units*10;
}elseif($units > 100 && $units <=150){
$temp = 100*10;
$remaining_units = $units - 100;
$bill = $temp + ($remaining_units *12);
}else{
$temp = (100*10)+ (100*12);
$remaining_units = $units - 150;
$bill = $temp + ($remaining_units *14);
}
echo $bill;
die();
}
帐单是1345.84
。
现在我要做的是也通过 slab,而不是对它们进行硬编码。我觉得有点难。
更新 1
我有 3 个 slabs/units 限制。每个平板都有自己的速率。费率用于计算账单。下面是场景。
- 如果单位 <= 100,则收取 10 卢比 rupee/unit
- 如果单位 > 100 && <= 150 则收取 12 卢比 rupee/unit
- 如果单位 > 150,则收取 14 卢比 rupee/unit
在我的数组中,我拥有所有三个值,除了最后一个只有 slab_start
和 rate
。
通过对 slab 和费率进行硬编码,我可以计算账单,但我想在使用数组时进行计算。
所以代码可能看起来像
if($units < slab_end){
$bill = $units*rate;
}elseif($units > slab_start && $units <=slab_end){<=slab_end
$temp = prev_slab_start *rate;
$remaining_units = $units - prev_slab;
$bill = $temp + ($remaining_units *rate);
}else{
$temp = (prev_slab*10)+ (prev_slab*12);
$remaining_units = $units - slab_start;
$bill = $temp + ($remaining_units *14);
}
不知道上面的逻辑对不对
注意:板坯范围和数量可能会发生变化。所以我想要一个通用函数来完成需要的工作
更新 2
按照提到的解决方案。
$array = ArrayHelper::map($mData, 'slab_end', 'rate');
var_dump($array);
die();
以上给了我
array(3) { [100]=> string(2) "10" [150]=> string(2) "12" [""]=> string(2) "14" }
那我加了个功能
public function billCalc($input, $slabs)
{
$result = [];
$bill = 0;
$previous_slab = 0;
foreach($slabs as $slab => $rate)
{
// calculate distance between current and previous slab
$slab_distance = $slab - $previous_slab;
// if current remainder of input value is >= distance, add distance to result,
// and subtract distance from remainder of input
if( $input >= $slab_distance )
{
$result[] = $slab_distance;
$bill += $slab_distance * $rate;
$input -= $slab_distance;
}// otherwise, add remainder as last item of result, and break out of the loop here
else
{
$result[] = $input;
$bill += $input * $rate;
break;
}
$previous_slab = $slab;
}
var_dump($result, $bill);
exit();
}
现在我遇到了一个问题。当输入小于 150
结果完全没问题,但当它大于或等于 150
我得到低于错误
A non-numeric value encountered
它在
给我这个错误
$slab_distance = $slab - $previous_slab;
非常感谢任何帮助。
所以您只想将每个平板(“单位”)覆盖的数量乘以速率 - 所以我将创建一个平板末端为 key 的数组,并将速率作为值 - 然后您可以使用扩展的 foreach 语法简单地循环它,并始终访问与平板对应的速率。
在 my answer to the previous question 上扩展,然后看起来像这样:
$input = '128.82';
$slabs = [100 => 10, 150 => 12, PHP_INT_MAX => 14];
$result = [];
$bill = 0;
$previous_slab = 0;
foreach($slabs as $slab => $rate) {
// calculate distance between current and previous slab
$slab_distance = $slab - $previous_slab;
// if current remainder of input value is >= distance, add distance to result,
// and subtract distance from remainder of input
if( $input >= $slab_distance ) {
$result[] = $slab_distance;
$bill += $slab_distance * $rate;
$input -= $slab_distance;
}
// otherwise, add remainder as last item of result, and break out of the loop here
else {
$result[] = $input;
$bill += $input * $rate;
break;
}
$previous_slab = $slab;
}
var_dump($result, $bill);
结果:
array (size=2)
0 => int 100
1 => float 28.82
float 1345.84
我的方法在这里再次只使用上板边界——你在数据库的最后一条记录中没有上边界,所以我在这里用 PHP_INT_MAX 代替 NULL 值。考虑到这一点,我希望当您从数据库内容创建该数组时,应该不是挑战。
(如果您只需要 1345.84
作为结果,而不是显示各个 slab 分布的数组,那么您可以删除所有包含 $result
的行。)
我正在研究 yii2
。我想明智地计算电费。为此,我已经在 table 中插入了 slab 及其各自的比率。现在我要计算一下。
我的单位是128.82
,下面是我的平板和它们的费率。
我可以使用以下查询来执行 slab
$mData = \Yii::$app->db->createCommand("SELECT s.`slab_start`, s.`slab_end`, s.`rate`, r.`cust_id`
FROM `mdc_tariff_slabs` s
INNER JOIN `mdc_meter_cust_rel` r ON s.`t_id` = r.`tariff_id`
WHERE r.`cust_id` = $consumer_no")->queryAll();
array(3) { [0]=> array(3) { ["slab_start"]=> string(1) "1" ["slab_end"]=> string(3) "100" ["rate"]=> string(2) "10" } [1]=> array(3) { ["slab_start"]=> string(3) "101" ["slab_end"]=> string(3) "150" ["rate"]=> string(2) "12" } [2]=> array(3) { ["slab_start"]=> string(3) "151" ["slab_end"]=> NULL ["rate"]=> string(2) "14" } }
注意:以后的slab可能会有所不同
我已经试过下面的代码,按照我的要求设置slabs并尝试拿到账单
public static function calcBill($units)
{
if($units < 100){
$bill = $units*10;
}elseif($units > 100 && $units <=150){
$temp = 100*10;
$remaining_units = $units - 100;
$bill = $temp + ($remaining_units *12);
}else{
$temp = (100*10)+ (100*12);
$remaining_units = $units - 150;
$bill = $temp + ($remaining_units *14);
}
echo $bill;
die();
}
帐单是1345.84
。
现在我要做的是也通过 slab,而不是对它们进行硬编码。我觉得有点难。
更新 1
我有 3 个 slabs/units 限制。每个平板都有自己的速率。费率用于计算账单。下面是场景。
- 如果单位 <= 100,则收取 10 卢比 rupee/unit
- 如果单位 > 100 && <= 150 则收取 12 卢比 rupee/unit
- 如果单位 > 150,则收取 14 卢比 rupee/unit
在我的数组中,我拥有所有三个值,除了最后一个只有 slab_start
和 rate
。
通过对 slab 和费率进行硬编码,我可以计算账单,但我想在使用数组时进行计算。
所以代码可能看起来像
if($units < slab_end){
$bill = $units*rate;
}elseif($units > slab_start && $units <=slab_end){<=slab_end
$temp = prev_slab_start *rate;
$remaining_units = $units - prev_slab;
$bill = $temp + ($remaining_units *rate);
}else{
$temp = (prev_slab*10)+ (prev_slab*12);
$remaining_units = $units - slab_start;
$bill = $temp + ($remaining_units *14);
}
不知道上面的逻辑对不对
注意:板坯范围和数量可能会发生变化。所以我想要一个通用函数来完成需要的工作
更新 2
按照提到的解决方案。
$array = ArrayHelper::map($mData, 'slab_end', 'rate');
var_dump($array);
die();
以上给了我
array(3) { [100]=> string(2) "10" [150]=> string(2) "12" [""]=> string(2) "14" }
那我加了个功能
public function billCalc($input, $slabs)
{
$result = [];
$bill = 0;
$previous_slab = 0;
foreach($slabs as $slab => $rate)
{
// calculate distance between current and previous slab
$slab_distance = $slab - $previous_slab;
// if current remainder of input value is >= distance, add distance to result,
// and subtract distance from remainder of input
if( $input >= $slab_distance )
{
$result[] = $slab_distance;
$bill += $slab_distance * $rate;
$input -= $slab_distance;
}// otherwise, add remainder as last item of result, and break out of the loop here
else
{
$result[] = $input;
$bill += $input * $rate;
break;
}
$previous_slab = $slab;
}
var_dump($result, $bill);
exit();
}
现在我遇到了一个问题。当输入小于 150
结果完全没问题,但当它大于或等于 150
我得到低于错误
A non-numeric value encountered
它在
给我这个错误$slab_distance = $slab - $previous_slab;
非常感谢任何帮助。
所以您只想将每个平板(“单位”)覆盖的数量乘以速率 - 所以我将创建一个平板末端为 key 的数组,并将速率作为值 - 然后您可以使用扩展的 foreach 语法简单地循环它,并始终访问与平板对应的速率。
在 my answer to the previous question 上扩展,然后看起来像这样:
$input = '128.82';
$slabs = [100 => 10, 150 => 12, PHP_INT_MAX => 14];
$result = [];
$bill = 0;
$previous_slab = 0;
foreach($slabs as $slab => $rate) {
// calculate distance between current and previous slab
$slab_distance = $slab - $previous_slab;
// if current remainder of input value is >= distance, add distance to result,
// and subtract distance from remainder of input
if( $input >= $slab_distance ) {
$result[] = $slab_distance;
$bill += $slab_distance * $rate;
$input -= $slab_distance;
}
// otherwise, add remainder as last item of result, and break out of the loop here
else {
$result[] = $input;
$bill += $input * $rate;
break;
}
$previous_slab = $slab;
}
var_dump($result, $bill);
结果:
array (size=2)
0 => int 100
1 => float 28.82
float 1345.84
我的方法在这里再次只使用上板边界——你在数据库的最后一条记录中没有上边界,所以我在这里用 PHP_INT_MAX 代替 NULL 值。考虑到这一点,我希望当您从数据库内容创建该数组时,应该不是挑战。
(如果您只需要 1345.84
作为结果,而不是显示各个 slab 分布的数组,那么您可以删除所有包含 $result
的行。)