duplicate records with its related foundsets

I have a problem to get my duplicate method working for all related records of the master record.

The szenario is very simple. There is:

invoice.table
order.table
article.table

The relations are:

invoice_to_order_id_invoice [1>n]
order_to_article_id_order [1>n]

The invoice can have n orders and the orders n articles. For duplicate the invoice with all the related records, I run this methods:

function duplicateIvoice() {

	var fs = foundset;
	var relArr = new Array(‘invoice_to_orders__id_invoice');
	var id = 'id_invoice’;
	var fsRel = invoice_to_orders__id_invoice;
	var relArrRel = new Array(‘order_to_order_items__id_order');
	var idRel = 'id_order’;
	var _idDup = scopes.globals.duplicate(fs,relArr,id,fsRel,relArrRel,idRel);
/**
 * @param {JSFoundset} fs == master record(s) foundset
 * @param {Array} relArr == array of masters relation(s) records
 * @param {String} id == id_<table> (e.g. id_order)
 * @param {JSFoundset} fsRel == related record(s) foundset
 * @param {Array} relArrRel == array of related relation(s) records
 * @param {String} idRel == id_<table> (e.g. id_order)
 * @properties={typeid:24,uuid:"E964EAF4-1018-485F-9DAC-37896CD170A4"}
 */
function duplicate(fs,relArr,id,fsRel,relArrRel,idRel) {
	
	// duplicate master record
	var dup = fs.getRecord(fs.duplicateRecord(false,false));
	var pk = dup[id]; //id duplicated record (master)
	
	if(databaseManager.saveData()){
		// duplicate related record(s)
		for(var k = 0;k < relArr.length;k++){
			/** @type {JSFoundset} */
			var related = fs[relArr[k]];
			for(var i = 1;i <= related.getSize();i++){
				var relatedOriginal = related.getRecord(i);
				var relatedDup = dup[relArr[k]].getRecord(dup[relArr[k]].newRecord(false,false));
				databaseManager.copyMatchingFields(relatedOriginal,relatedDup);
				
				if(fsRel){// duplicate related relation record(s)
					var _rec = databaseManager.getFoundSetCount(fsRel);
					application.output('fsRel: ' + _rec);
					/** @type {JSFoundset} */
					var relatedRel = fsRel[relArrRel[i]];
					if(relatedRel){
						for (var ii = 1; ii <= relatedRel.getSize(); ii++) {
							var relatedOriginal2 = relatedRel.getRecord(ii);
							var relatedDup2 = relatedDup[relRelArr[i]].getRecord(relatedDup[relRelArr[i]].newRecord(false,false));
							databaseManager.copyMatchingFields(relatedOriginal2,relatedDup2);
						}
					}
				}
			}
		}

So far so good. I get a invoice duplicated with also correct duplicated related order items, but without the article items!?
The variable fsRel has a value and _rec get an integer as result, but the issue is that the output for var relatedRel = fsRel[relArrRel*][/b] is “undefined” although the relations parameter exists and is working.*
Does anybody have an idea for fixing that?

In the variable relArrRel you put this as the relation name: order_to_order_items__id_order

It looks like that should have been: order_to_article_id_order

Joas you are right, but it’s an typo error and correct in real.

But Birgit Rieder (7r) helped me to get this working.
This is the new code:

function onActionDuplicate(event) {
	var fs = foundset;
	var relArr = new Array('invoices_to_orders');
	var relRelArray = new Array('orders_to_articles');
	var _idDup = scopes.globals.duplicateRecLevel(fs, relArr, relRelArray);
	application.output(_idDup);
}


 * @param {JSFoundset<db:/yomotec/invoices>} fs == master record(s) foundset
 * @param {Array} relArr == array of masters relation(s) records
 * @param {Array} relRelArray == array of related relation(s) records
 * 
 * @returns	{Number}
 */
function duplicateRecLevel(fs, relArr, relRelArray) {
	// Use a transaction for all the operations!
	databaseManager.startTransaction();
	try {
		// Duplicate master record.
		var dup = fs.getRecord(fs.duplicateRecord(false,false));
		
		if (databaseManager.saveData()) {
			// Iterate over relations.
			for (var k = 0; k < relArr.length; k++) {
				/** @type {JSFoundset<db:/yomotec/orders>} */
				var relatedOrders = fs[relArr[k]];
				
				// Iterate over records in one of the relations and duplicate them.
				for (var i = 1; i <= relatedOrders.getSize();i++) {
					var relatedOriginalOrder = relatedOrders.getRecord(i);
					var indexDupOrder = dup[relArr[k]].newRecord(false, false);
					var relatedDupOrder = dup[relArr[k]].getRecord(indexDupOrder);
					databaseManager.copyMatchingFields(relatedOriginalOrder, relatedDupOrder);
					
					// Iterate over related relations.					
					for (var j = 0; j < relRelArray.length; j++){
						/** @type {JSFoundset<db:/yomotec/articles>} */
						var relatedArticles = relatedOriginalOrder[relRelArray[j]];	
						
						// Iterate over records in one of the related relations and duplicate them.						
						for (var m = 1; m <= relatedArticles.getSize();m++) {
							var relatedOriginalArticle = relatedArticles.getRecord(m);
							var indexDupArticle = relatedDupOrder[relRelArray[j]].newRecord(false, false);
							var relatedDupArticle = relatedDupOrder[relRelArray[j]].getRecord(indexDupArticle);
							databaseManager.copyMatchingFields(relatedOriginalArticle, relatedDupArticle);
						}
					}
				}
			}
			if (databaseManager.saveData()) {
				databaseManager.commitTransaction();
				return dup.getPKs()[0]; //returns id of duplicated record (master)
			} 
			else {
				throw ('Error');
			}
		} 
		else {
			throw ('Error');
		}
	}
	catch (e) {
		databaseManager.rollbackTransaction();
		return null;
	}
}