You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel客房登记系统Register_update函数商品计费错误问题

问题分析与解决方案

核心问题

  1. 累加变量未初始化:$igv_first、$gravada_first等变量未初始化为0,累加时会引入非预期初始值(如null或旧数据残留),导致计算失真。
  2. 字符串累加错误:number_format()返回字符串类型,直接用字符串做加法会触发PHP类型转换bug,数值计算逻辑完全错误。
  3. 遗漏客房动态费用:当前代码仅计算商品费用,完全未将客房根据入住时长生成的动态费用纳入总账单,导致商品费用直接覆盖原有客房费用,而非累加。
  4. 冗余操作:$inafecta_first中的str_replace(',', '', $inafecta_first)属于多余操作,number_format已指定.作为小数点分隔符,不会生成带逗号的字符串。

修复后的代码

// 初始化所有累加变量为0,避免非预期初始值
$igv_first = $gravada_first = $exonerada_first = $inafecta_first = 0;
$igv_last = $gravada_last = $exonerada_last = $inafecta_last = 0;

foreach($detalle_first as $product) {
    $precio = (float)$product['precio_unitario'];
    $cantidad = (int)$product['cantidad'];
    $importe = $precio * $cantidad;

    if ($product['impuesto'] == 1) {
        $igv = ($precio - $precio / 1.18) * $cantidad;
        $igv_first += $this->redondeado($igv);
    }

    switch($product["codigo_igv"]) {
        case "10":
            $gravada = ($precio / 1.18) * $cantidad;
            $gravada_first += $this->redondeado($gravada);
            break;
        case "20":
            $exonerada_first += $this->redondeado($importe);
            break;
        case "30":
            $inafecta_first += $this->redondeado($importe);
            break;
    }
}
$subtotal_first = $exonerada_first + $gravada_first + $inafecta_first;

if(!empty($detalle_last)) {
    foreach($detalle_last as $product) {
        $precio = (float)$product['precio_unitario'];
        $cantidad = (int)$product['cantidad'];
        $importe = $precio * $cantidad;

        if ($product['impuesto'] == 1) {
            $igv = ($precio - $precio / 1.18) * $cantidad;
            $igv_last += $this->redondeado($igv);
        }

        switch($product["codigo_igv"]) {
            case "10":
                $gravada = ($precio / 1.18) * $cantidad;
                $gravada_last += $this->redondeado($gravada);
                break;
            case "20":
                $exonerada_last += $this->redondeado($importe);
                break;
            case "30":
                $inafecta_last += $this->redondeado($importe);
                break;
        }
    }
}
$subtotal_last = $exonerada_last + $gravada_last + $inafecta_last;

// 关键步骤:获取并拆分客房动态费用(根据你的业务逻辑实现)
// 示例:假设客房费用属于gravada税目,需替换为实际计算逻辑
$room_cost = $this->calculateRoomDynamicCost($fecha_salida, $idrecepcion);
$room_gravada = $room_cost / 1.18;
$room_igv = $room_cost - $room_gravada;

// 合并客房费用与商品费用
$total_exonerada = $exonerada_first + $exonerada_last;
$total_gravada = $gravada_first + $gravada_last + $room_gravada;
$total_inafecta = $inafecta_first + $inafecta_last;
$total_igv = $igv_first + $igv_last + $room_igv;
$grand_total = ($total_exonerada + $total_gravada + $total_inafecta) + $total_igv;

Reception::where('id', $idrecepcion)->update([
    'fecha_salida'  => $fecha_salida,
    'exonerada'     => $total_exonerada,
    'inafecta'      => $total_inafecta,
    'gravada'       => $total_gravada,
    'anticipo'      => "0.00",
    'igv'           => $total_igv,
    'gratuita'      => "0.00",
    'otros_cargos'  => "0.00",
    'total'         => $grand_total,
    'observaciones' => mb_strtoupper($observaciones),
]);

关键说明

  • 变量初始化:所有累加变量必须初始化为0,避免PHP自动类型转换带来的计算错误。
  • 数值优先计算:先完成所有数值运算,最后再处理格式化需求,禁止用number_format处理中间计算值。
  • 客房费用合并:必须将客房动态费用拆分到对应税目字段(exonerada/gravada/inafecta),再与商品费用累加,确保总账单包含客房+商品的全部费用。
  • 代码优化:用switch替代多if判断提升可读性,提取重复的价格、数量计算逻辑减少冗余。

内容的提问来源于stack exchange,提问作者Bayron Ordoñez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:45:13