我在生产服务器中遇到了一个非常奇怪的问题。我正在开发MLM项目,用户可以从他们的个人文件柜中订购产品。当他们刷新(更改所选项目的数量)在购物车页面上时出现问题,如果用户更改数量并刷新购物车价格计算错误,但一切都在我的本地机器上正常工作:
以下是代码的简化版本:
QuantityType
....
public function buildForm(FormBuilderInterface $builder, array $options)
{
$productLineItems = $options['productLineItems'];
/** @var ProductLineItem $productLineItem */
foreach ($productLineItems as $productLineItem) {
$builder
->add(
$builder
->create($productLineItem->getId(), 'form', [
'data' => $productLineItem
])
->add('quantity', 'number', [
'data' => $productLineItem->getQuantity()
])
->add('remove', 'submit')
);
}
}
CartType
...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('productLineItems', 'sl_core_quantity', [
'productLineItems' => $options['productLineItems']
])
->add('update', 'submit')
;
...
}
控制器:
$partner = $this->getEntityManager()->getRepository('SLCoreBundle:User')->find($partnerId);
/** @var BaseOrderManager $orderManager */
$orderManager = $this->get('sl.core.manager.base_order');
$order = $orderManager->getOrderByUserAndStatus($partner, BaseOrder::STATUS_CART, BaseOrderManager::TYPE_PARTNER);
$cartProductLineItems = $orderManager->getProductLineItemsByOrder($order);
$cartForm = null;
if (null != $cartProductLineItems) {
$cartForm = $this->createForm('sl_core_cart', null, [
'productLineItems' => $cartProductLineItems,
'user' => $partner,
'action' => $this->generateUrl('ACTION', ['partnerId' => $partnerId])
]);
$cartForm->handleRequest($request);
if ($cartForm->isValid()) {
$clickedButton = $cartForm->getClickedButton();
if ($clickedButton->getName() == 'remove') {
$selectedItem = $clickedButton->getParent()->getData();
$label = $selectedItem->getLabel();
$orderManager->removeItemFromOrder($order, $selectedItem);
$this->get('session')->getFlashBag()->add('notice', $label . ' removed from your cart.');
}
else if ($clickedButton->getName() == 'update') {
$submittedData = $cartForm->getData();
$submittedProductLineItems = $submittedData['productLineItems'];
$orderManager->updateProductLineItems($order, $submittedProductLineItems);
$this->get('session')->getFlashBag()->add('notice', 'Shopping cart updated.');
}
else if ($clickedButton->getName() == 'checkout') {
$submittedData = $cartForm->getData();
$submittedProductLineItems = $submittedData['productLineItems'];
$orderManager->updateProductLineItems($order, $submittedProductLineItems);
return $this->redirect($this->generateUrl('ACTION', ['partnerId' => $partnerId]));
}
return $this->redirect($this->generateUrl('ACTOPN', ['partnerId' => $partnerId]));
}
}
return $this->render('@SLWeb/BackOffice/Order/create_partner_order.cart.html.twig', [
'currency_code' => $request->cookies->get('sl_currency_code'),
'cart_form' => null != $cartForm ? $cartForm->createView() : null,
'cart_product_line_items' => $cartProductLineItems,
'order' => $order,
'partner' => $partner
]);
BaseOrderManager
public function updateProductLineItems(BaseOrder $order, array $lineItems)
{
$quantityChanged = false;
$orderLineItems = $this->entityManager->getRepository('SLCoreBundle:ProductLineItem')->fetchAllUnchangedQuantityByOrder($order);
/**
* @var int $key
* @var ProductLineItem $submittedLineItem
*/
foreach (array_values($lineItems) as $key => $submittedLineItem) {
$submittedLineItemQuantity = $submittedLineItem->getQuantity();
$orderLineItemQuantity = $orderLineItems[$key]['quantity'];
if ($submittedLineItemQuantity == $orderLineItemQuantity) {
continue;
}
....
$productLineItemPrices = $submittedLineItem->getLineItemPrices();
/** @var LineItemPrice $productLineItemPrice */
foreach ($productLineItemPrices as $productLineItemPrice) {
$priceValue = $productLineItemPrice->getValue();
$productLineItemPrice->setTotalPrice($priceValue * $submittedLineItem->getQuantity());
if ($submittedLineItemQuantity < $orderLineItemQuantity) {
$quantityDiff = $orderLineItemQuantity - $submittedLineItemQuantity;
$this->updateOrderPrice($order, $productLineItemPrice, $quantityDiff, self::QUANTITY_DECREASED);
....
}
else {
$quantityDiff = $submittedLineItemQuantity - $orderLineItemQuantity;
$this->updateOrderPrice($order, $productLineItemPrice, $quantityDiff, self::QUANTITY_INCREASED);
....
}
}
$quantityChanged = true;
}
if ($quantityChanged) {
$this->entityManager->flush();
}
}
public function updateOrderPrice(BaseOrder $order, LineItemPrice $lineItemPrice, $quantity, $operation = self::QUANTITY_INCREASED)
{
$priceCurrency = $lineItemPrice->getCurrencyCode();
$priceValue = $lineItemPrice->getValue();
$orderPrice = $this->getPriceByCurrencyCode($order, $priceCurrency);
$orderPriceValue = $orderPrice->getValue();
...
if ($operation == self::QUANTITY_INCREASED) {
$orderPrice->setValue($orderPriceValue + ($quantity * $priceValue));
}
else if ($operation == self::QUANTITY_DECREASED) {
$orderPrice->setValue($orderPriceValue - ($quantity * $priceValue));
}
else {
throw new \Exception();
}
}
生产服务器屏幕(错误): 更糟糕的是(下次刷新后)
本地版本(正确):
我甚至不明白为什么相同版本的代码工作方式如此不同,项目版本是相同的,php,nginx,mysql版本和配置是相同的,禁用缓存没有帮助,在哪里挖? / p>
答案 0 :(得分:0)
可能是我以某种方式解决了问题,但我完全不了解问题和解决方案:)
在我的fetchAllUnchangedQuantityByOrder($order)
方法中,我正在直接查询数据库以获取未更改的行,就像这样(因为,我的getters在表单绑定后返回更改的表单值):
public function fetchAllUnchangedQuantityByOrder(BaseOrder $order)
{
$orderId = $order->getId();
$connection = $this->getEntityManager()->getConnection()->prepare('
SELECT li.quantity
FROM sl_product_line_item AS li
INNER JOIN
sl_base_line_item AS bli ON li.id = bli.id
WHERE bli.order_id = :order_id
ORDER BY bli.created_at ASC
');
$connection->bindParam(':order_id', $orderId, \PDO::PARAM_INT);
$connection->execute();
return $connection->fetchAll();
}
我认为这是问题,有时它会返回错误的价值,我不明白为什么......
我改变了这一行,问题就消失了。
...
$orderLineItem = $this->entityManager->getUnitOfWork()->getOriginalEntityData($submittedLineItem);
if ($submittedLineItemQuantity == $orderLineItem['quantity']) {
continue;
}
...