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.