我在mongo集合中循环了一些付款。payoutdate==today()的所有付款必须导出并写入sepa文件,以便我们可以通过银行处理付款。
付款在创建时没有发票号,我们在处理付款时生成一个发票号(通过上述函数导出)。
问题是,当我们运行要导出多个付款的函数时,所有付款都得到相同的发票号。所以看起来,在处理下一笔付款之前,最后一次保存操作没有完成。
const fs = require('fs');
const async = require('async');
const DateDiff = require('date-diff');
const SEPA = require('sepa');
const shopService = require(path.join(__dirname, '..', 'services', 'shop.service'));
async.forEachOf(payments, function(payment, key, paymentDone){
var diff = new DateDiff(new Date(payment.payoutDate), new Date());
if(payment.payoutDate && payment.amount > 0 && payment.completed == false && payment.exported == false && diff.days() <= 0){
//payment has amount, is not completed and is not exported, create an SEPA transfer, and set the payment to completed
//but first create an invoicenumber
orderService.updateOrderPayment(payment.orderId, {generateInvoiceNumber: true}, function(err, result){
if(err){
console.log("error updating payment", err);
}
//reget the payment to avoid duplicated invoice numbers
orderService.getPayment(result.orderId, function(err, payment){
if(err){
console.log("error getting payment", err);
}
Shop.findOne({_id: payment.shopId}).exec(function(err, shop){
if(shop && shop.bankAccountNumber && shop.accountHolder && shop.bicCode){
//create transaction and add this to the file
}else{
var result = {
paymentID: payment._id,
orderId: payment.orderId,
status: payment.status,
message: "shop does not have an iban, accountholder or biccode",
shop: shop.nameSlug
}
resultArray.push(result);
console.log("shop does not have an iban, accountholder or biccode", shop.nameSlug);
paymentDone();
}
orderService.updateOrderPayment(payment.orderId, {status: 'completed'}, function(err, result){
orderService.updateOrderStatusById(payment.orderId, {status: 'Granted', date: new Date(), comment: null});
var result = {
paymentID: payment._id,
orderId: payment.orderId,
status: payment.status,
message: "payment exported",
}
resultArray.push(result);
counter++;
paymentDone();
})
})
})
})
}else{
var result = {
paymentID: payment._id,
orderId: payment.orderId,
status: payment.status,
message: "order already processed"
}
resultArray.push(result);
paymentDone();
}
}, function(){
if(resultArray.length == payments.length){
//console.log("Result", resultArray);
if(counter == 0){
res.status(200).json({"message":"No orders to export", resultArray});
}else{
res.set({"Content-Disposition":"attachment; filename=\"sepa.xml\""});
res.send(doc.toString());
}
}
})
function updateOrderPayment(orderId, paymentStatus, callback){
console.log("updateOrderPayment");
if(!paymentStatus){
return callback("No payment details provided");
}else{
if(!paymentStatus.comment){
paymentStatus.comment = null;
}
}
getPayment(orderId, function(err, payment){
if(err)
return callback(err);
handlePayment(payment, paymentStatus, function(result){
result.save(function(err, result){
if(err){
return callback(err);
}
console.log("payment saved");
return callback(null, result);
})
})
})
}
function handlePayment(payment, paymentStatus, callback){
if(paymentStatus.status){
var status = {
status: paymentStatus.status,
comment: paymentStatus.comment,
date: Date.now()
}
payment.status.push(status);
}
if(paymentStatus.generateInvoiceNumber){
console.log("generateInvoiceNumber");
var invoiceNumber =0;
Payment.findOne({invoiceNumber: {$exists:true}}).sort({_id: -1}).exec(function(err, latestPaymentsWithNumber){
if(latestPaymentsWithNumber && latestPaymentsWithNumber.invoiceNumber){
invoiceNumber = latestPaymentsWithNumber.invoiceNumber.split("-")[1];
}
var date = new Date();
payment.invoiceNumber = date.getFullYear().toString() + date.getMonth().toString() + "-" + (parseInt(invoiceNumber)+1);
console.log("number", payment.invoiceNumber);
return callback(payment);
})
}
if(paymentStatus.status == 'returned' || paymentStatus.status == 'cancelled'){
payment.cancelled = true;
payment.amount = 0;
payment.payoutDate = null;
return callback(payment);
}
if(paymentStatus.status == 'completed'){
payment.completed = true;
payment.exported = true;
payment.payoutDate = null;
return callback(payment);
}
}
function getPayment(orderId, callback){
Payment.findOne({orderId: orderId}).exec(function(err, payment){
if(err){
return callback(err);
}
return callback(null, payment);
})
}