简体   繁体   中英

Process multiple update nodejs mongodb

I have a function to update some values from a subdocument, but I am having troubles updating the data

  let query = InvoiceModel.find({
    is_draft:false
products.product: productid
  })

  query.exec(function (err, data) {
    if (data) {
      data.forEach(function(si) {
        let saleinvoice_id = si._id
        console.log(saleinvoice_id);
        InvoiceMovement(invoice_id, si)

      })
    }
  })

In the InvoiceMovement function I search for the record in the collection PRODUCT to update and try to update the array like this:

       productModel.findOneAndUpdate({
          _id: product_id,
          'warehouses.warehouse': warehouse_id
        }, {
          $set: {
            "warehouses.$.stock": stock_data,
          }
        }, function (errwu, wupdated) {
          if (errwu) {
            console.log(errwu);

          }
          if (wupdated) {

            console.log(wupdated);
          }
        })

But not all the data is processed.

For an specific ID I have 4 invoices records, but only two or less affect the value to update in the product collection

I try using async.forEach , but I get the same result.

UPDATE

Schemas:

INVOICE

const InvoiceSchema = Schema({
  invoice_number: {
    type: String,
  },
  products: [{
    product: {
      type: Schema.Types.ObjectId,
      ref: 'products',
      required: [true, 'Producto no puede estar vacio']
    },
    warehouse: {
      type: Schema.Types.ObjectId,
      ref: 'warehouses'
    },
    work_order: {
      type: Schema.Types.ObjectId,
      ref: 'work_orders'
    },
    quantity: {
      type: Number,
      required: [true, 'Cantidad no puede estar vacio']
    },
    base_price: {
      type: String,
      required: [true, 'Valor Unitario no puede estar vacio']
    },
    sale_price: {
      type: String,
      required: [true, 'Valor Unitario no puede estar vacio']
    },
    discount: {
      type: String,
      default: "0.00"
    },
    subtotal: {
      type: String,
      required: true
    },
    tax: {
      type: String,
      required: true
    },
    total: {
      type: String,
      required: true
    },
  }]
}, {
  timestamps: true
});

PRODUCT

const productSchema = Schema({
  code: {
    type: String,
    index: true
  },
  name: {
    type: String,
    index: true,
    required: [true, 'Nombre no puede estar vacio']
  },
  description: {
    type: String,
    required: [true, 'Descripcion no puede estar vacio']
  },
  unit: {
    type: String,
    index: true,
    required: [true, 'Unidad no puede estar vacio']
  },
  exempt: {
    type: Boolean,
    default: false
  },
  product_category: {
    type: Schema.Types.ObjectId,
    ref: 'product_categories',
    required: [true, 'Categoría de Producto es requerida']
  },
  base_price: {
    type: String,
    default: "0.00"
  },
  unit_cost: {
    type: String,
    default: "0.00"
  },

  warehouses: [
    {
      warehouse: {
        type: Schema.Types.ObjectId,
        ref: 'warehouses',
        required: [true, "Seleccione una caracteristica"]
      },
      stock: {
        type: Number,
      },
      unit:{
        type: String
      }
    }
  ],
  subproducts: [
    {
      subproduct: {
        type: Schema.Types.ObjectId,
        ref: 'characteristics',
        // required: [true, "Seleccione una caracteristica"]
      },
    }
  ],
  stock: {
    type: Number,
    default: 0
  }
}, {timestamps: true});

From the Invoice Schema I go through the products array, to get the product ID and the quantity, with that data I update the stock in the warehouses array inside the PRODUCT schema. I Need to do this for every Invoice. One invoice can have many product registered

Below is one way you can do this. However, this might be easier if you use mongoose.promise .

InvoiceModel.find({}, 'products', function(err, invoice) {
  if(err) throw err
  const products = invoice.products
  // Loop through all the objects in the array 
  products.forEach(function(productsObj) {
    // Get the product model for each product
    ProductModel.findById(productsObj.product, 'warehouses', function(err, product) {
      if(err) throw err
      // Get a new array of only ids
      const warehousesIds = product.warehouses.map(warehousesObj => {
        return warehousesObj.warehouse
       })
      // Get the index of the current warehouse in the warehouses array in your product model
      const warehouseIndex = warehousesIds.indexOf(productsObj.warehouse)
      // Check if warehouse exists and if so assign the new value
      if(warehouseIndex > -1) product.warehouses[warehouseIndex].stock = productsObj.quantity
      // Save your model
      product.save()
    })
  })
})

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM