Prestashop 1.7 Order类:如何更新商品列表、重算运费及增值税?
如何在PrestaShop 1.7中修改现有订单的商品并重新计算运费与增值税
一、核心思路说明
PrestaShop的订单数据分散在order、order_detail、order_tax、order_shipping等表中,所以修改订单商品需要操作OrderDetail实体,之后再同步更新订单的总金额、税费和运费。Order和Product类本身确实没有提供一站式的修改方法,得结合多个关联类来手动处理。
二、具体操作步骤
1. 初始化订单对象
首先要确保你能正确获取到目标订单的实例:
$orderId = 123; // 替换成你的订单ID $order = new Order((int)$orderId); if (!$order->id) { throw new Exception('指定的订单不存在'); }
2. 添加商品到订单
要新增订单商品,需要创建OrderDetail实例,并填充必要的商品信息(注意要和订单的语言、货币、客户组匹配):
$productId = 456; // 要添加的商品ID $product = new Product((int)$productId); if (!$product->id) { throw new Exception('指定的商品不存在'); } // 根据订单上下文获取商品的含税/不含税价格 $priceExclTax = $product->getPrice( true, // true表示获取不含税价格 null, 6, null, false, false, false, 1, false, null, null, null, $order->id_customer // 传入订单客户ID,确保价格匹配客户组 ); $priceInclTax = $product->getPrice( false, // false表示获取含税价格 null, 6, null, false, false, false, 1, false, null, null, null, $order->id_customer ); // 创建订单明细 $orderDetail = new OrderDetail(); $orderDetail->id_order = $order->id; $orderDetail->id_product = $product->id; $orderDetail->id_product_attribute = 0; // 如果是组合商品,替换为对应的属性ID $orderDetail->product_quantity = 1; // 要添加的数量 $orderDetail->product_price = $priceExclTax; $orderDetail->product_price_wt = $priceInclTax; $orderDetail->product_name = $product->name[$order->id_lang]; // 匹配订单语言 $orderDetail->product_reference = $product->reference; $orderDetail->save();
3. 修改订单商品数量
找到目标订单对应的OrderDetail记录,直接修改数量并保存:
$targetProductId = 456; // 要修改的商品ID $newQuantity = 3; // 新的数量 // 查询对应的订单明细 $orderDetailData = OrderDetail::getList( ['id_order_detail'], ['id_order' => $order->id, 'id_product' => $targetProductId] ); if (!empty($orderDetailData)) { $orderDetail = new OrderDetail((int)$orderDetailData[0]['id_order_detail']); $orderDetail->product_quantity = (int)$newQuantity; // 如果商品价格有变动,同步更新product_price和product_price_wt // $orderDetail->product_price = $newPriceExclTax; // $orderDetail->product_price_wt = $newPriceInclTax; $orderDetail->save(); } else { throw new Exception('订单中未找到该商品'); }
4. 删除订单中的商品
找到对应的OrderDetail记录并删除即可:
$targetProductId = 456; // 要删除的商品ID $orderDetailIds = OrderDetail::getList( ['id_order_detail'], ['id_order' => $order->id, 'id_product' => $targetProductId] ); foreach ($orderDetailIds as $odData) { $orderDetail = new OrderDetail((int)$odData['id_order_detail']); $orderDetail->delete(); }
三、重新计算运费与增值税
完成商品修改后,需要同步更新订单的运费、税费和总金额:
1. 重新计算运费
你已经找到的Order::refreshShippingCost()方法可以直接用,第二个参数传true会同时重新计算运费的税费:
// 重新计算运费,true表示同步更新运费税费 $order->refreshShippingCost(true);
2. 重新计算订单总金额与增值税
需要先清理旧的税费记录,再重新计算各项总额并更新订单:
// 启动数据库事务,避免中途出错导致数据不一致 Db::getInstance()->beginTransaction(); try { // 1. 删除旧的订单税费记录 OrderTax::cleanOrdersTaxes($order->id); // 2. 计算商品总金额(含税/不含税) $totalProductsExclTax = 0; $totalProductsInclTax = 0; $orderDetails = OrderDetail::getList( ['product_price', 'product_price_wt', 'product_quantity'], ['id_order' => $order->id] ); foreach ($orderDetails as $od) { $totalProductsExclTax += (float)$od['product_price'] * (int)$od['product_quantity']; $totalProductsInclTax += (float)$od['product_price_wt'] * (int)$od['product_quantity']; } // 3. 获取运费的含税/不含税金额 $shippingExclTax = (float)$order->total_shipping; $shippingInclTax = (float)$order->total_shipping_tax_incl; // 4. 计算订单总金额 $totalExclTax = $totalProductsExclTax + $shippingExclTax; $totalInclTax = $totalProductsInclTax + $shippingInclTax; // 5. 更新订单核心字段 $order->total_products = $totalProductsExclTax; $order->total_products_wt = $totalProductsInclTax; $order->total_paid_tax_excl = $totalExclTax; $order->total_paid_tax_incl = $totalInclTax; $order->total_paid = $totalInclTax; // 注意:如果订单使用非默认货币,需要额外处理汇率转换 $order->save(); // 6. 重新生成订单税费记录 $order->getTaxes(); // 提交事务 Db::getInstance()->commit(); } catch (Exception $e) { // 出错回滚事务 Db::getInstance()->rollback(); throw new Exception('更新订单失败:' . $e->getMessage()); }
四、注意事项
- 事务处理:一定要用数据库事务包裹所有修改操作,防止部分操作失败导致数据混乱。
- 货币与客户组:商品价格要匹配订单的货币和客户组,避免价格计算错误。
- 组合商品:如果操作的是组合商品,要正确传入
id_product_attribute,否则会导致商品信息错误。 - 订单状态通知:修改订单后,建议根据实际情况更新订单状态并通知客户(比如通过邮件)。
内容的提问来源于stack exchange,提问作者JarsOfJam-Scheduler
相关产品推荐
相关产品推荐

