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

解决Next.js CreatePurchase API异步变量更新延迟导致计算错误

问题与解决方案:药品采购API应付金额计算异常

问题描述

在使用Next.js开发药品供应商应付总额仪表盘时,createPurchase API中计算供应商新应付金额newOutstanding时,totalOrderAmount和totalPaybleGst始终为0,导致供应商应付金额更新错误。

原因分析

原代码使用forEach循环遍历药品列表,循环内部包含异步操作(查询并更新药品库存),但forEach不支持异步等待——循环会立即启动所有迭代的异步任务,不会等待每个任务完成,后续计算newOutstanding、更新供应商、创建采购单的代码会在循环内异步操作完成前执行,此时两个累加变量仍为初始值0。

解决方案

将forEach替换为for...of循环,for...of可与await配合,确保每个异步操作完成后再执行下一次迭代,保证变量累加逻辑正确执行。

修改后的createPurchase API代码:

import PurchaseOrder from '../../models/PurchaseOrder'
import Supplier from '../../models/Supplier'
import connectDB from '../../middleware/mongoose';
import Medicine from '../../models/Medicine';

const handler = async (req, res) => {
    if (req.method === 'POST') {

        const medicines = [];
        let totalOrderAmount = 0;
        let totalPaybleGst = 0;

        // 替换forEach为for...of,支持await等待异步操作完成
        for (const medicine of req.body.medicines) {
            let medicineOne = await Medicine.findById(medicine.medicine)
            let newQuantity = parseInt(medicineOne.quantity) + parseInt(medicine.quantity)
            const filter = { _id: medicine.medicine };
            const update = { quantity: newQuantity };

            await Medicine.findByIdAndUpdate(filter, update);

            let newmedi = {
                name: medicine.name,
                company: medicine.company,
                medicine: medicineOne,
                quantity: newQuantity,
                pack_detail: medicine.pack_detail,
                category: medicine.category,
                batch: medicine.batch,
                mrp: medicine.mrp,
                rate: medicine.rate,
                gst: medicine.gst,
                totalAmount: medicine.totalAmount,
                expiryDate: medicine.expiryDate
            }

            totalOrderAmount += medicine.totalAmount;
            totalPaybleGst += medicine.gst * medicine.rate * medicine.quantity * 0.01;
            medicines.push(newmedi);
        }

        const paidAmount = req.body.paidAmount

        const supplierBeforeUpdate = await Supplier.findById(req.body.supplier);
        const newOustanding = supplierBeforeUpdate.totalOutstanding + totalPaybleGst + totalOrderAmount - paidAmount;

        const filter = { _id: req.body.supplier };
        const update = { totalOutstanding: newOustanding };

        await Supplier.findOneAndUpdate(filter, update);
        const supplierAffterUpdate = await Supplier.findById(req.body.supplier);

        const purchaseOrder = await PurchaseOrder.create({
            supplier: supplierAffterUpdate,
            createdBy: req.body.createdBy,
            medicines: medicines,
            paybleGst: totalPaybleGst,
            totalAmount: totalOrderAmount,
            grandTotal: totalPaybleGst + totalOrderAmount,
            paidAmount: paidAmount
        })
        res.status(200).json({ success: true, purchaseOrder: purchaseOrder })
    }
    else {
        res.status(400).json({ error: "This method is not allowed" })
    }
}

export default connectDB(handler);

补充说明

  1. 若需提升性能,可使用Promise.all并行处理所有药品的异步操作,统一计算累加值:
// 示例:Promise.all并行处理
const medicinePromises = req.body.medicines.map(async medicine => {
    let medicineOne = await Medicine.findById(medicine.medicine)
    let newQuantity = parseInt(medicineOne.quantity) + parseInt(medicine.quantity)
    await Medicine.findByIdAndUpdate({ _id: medicine.medicine }, { quantity: newQuantity });

    return {
        newmedi: {
            name: medicine.name,
            company: medicine.company,
            medicine: medicineOne,
            quantity: newQuantity,
            pack_detail: medicine.pack_detail,
            category: medicine.category,
            batch: medicine.batch,
            mrp: medicine.mrp,
            rate: medicine.rate,
            gst: medicine.gst,
            totalAmount: medicine.totalAmount,
            expiryDate: medicine.expiryDate
        },
        totalAmount: medicine.totalAmount,
        gstAmount: medicine.gst * medicine.rate * medicine.quantity * 0.01
    }
})

const results = await Promise.all(medicinePromises);
results.forEach(result => {
    medicines.push(result.newmedi);
    totalOrderAmount += result.totalAmount;
    totalPaybleGst += result.gstAmount;
})
  1. 验证totalPaybleGst的计算逻辑是否符合业务需求,确保税率百分比转换(乘以0.01)的逻辑正确。

内容的提问来源于stack exchange,提问作者Imtiyaz Nandasaniya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:50:20