#
#			ITSV GmbH
#	CCDB - Command and Control Database
#
#	FILE:			dquerymfile_SVCL440204.txt
#	DESCRIPTION:	DQUERY definition for DQUERY SVCL440204
#					this query enriches a set of records in table CCCFUNZ by "zuordnungsinfo"
#
@querytitle			SVCL440204 - CCCFUNZ um zuordnungsinfo ergänzen
@querydescription	Ergänzt unzustellbare Clearingfälle in CCCFUNZ um Informationen um Informationen über Zuordnungen aus SVCLZUODUMP. 
					Es werden alle Zuordnungen gefunden, die die selbe Kombination traeger/bknr wie der Clearingfall haben. 
					Daher können zu einem Clearingfall mehrere Zuordnungen gefunden werden.
@group				SVCLCFSTATCFENZ
@attributenames		selsql:string:{{selsqloptions}},maxrecords:integer:{{maxrecordsoptions}},mode:string:{{modeoptions}},newrepdatnum:string:{{newrepdatnumoptions}}
@querytype			tseq
@selsqloptions {
	labeltext:		"Auswahl(SQL)",
	typedesc:		"komplettes SQL-Statement, das Einträge aus der Tabelle CCCFUNZ auswählt, die mit Zuordnungsinformationen versehen werden sollen",
	is_optional:	false,
	default:		"select * from CCCFUNZ where repdatnum='20201211' and ((zuordnungsinfo is null) or (zuordnungsinfo='')) limit 1,200" }
@maxrecordsoptions {
	labeltext:		"MaximumDatensätze",
	typedesc:		"Maximale Anzahl von Datensätzen, die bearbeitet werden sollen. Wählt die \"Auswahl\" mehr Datensätze aus, wird die Verarbeitung abgebrochen",
	is_optional:	false,
	default:		21000 }
@modeoptions {
	labeltext:		"Betriebsart",
	typdedesc:		"Art der Verarbeitung: mem ... speichere Zuordnungen im Speicher, newmem ... speichere Zuordnungen im Speicher und lege ergänzte Datensätz mit neuem repdatenum neu an, db ... Frage Zuordnungen bei jedem Datensatz aus Datenbank ab",
	type:	{
		structure:	"scalar.enum",
		vlist:		"mem:Speicher:speichere Zuordnungen im Speicher,newmem:Neu aus Speicher:erzeuge neuen Datenbereich (neues Berichtsdatum) und halte Zuordnungen im Speicher,db:Datenbank:Frage Zuordnungen bei jedem Datensatz aus Datenbank ab"
	} }
@newrepdatnumoptions {
	labeltext:		"neues Berichtsdatum",
	typedesc:		"neues Berichtsdatum in der Form YYYYMMDD, mit dem neue Einträge angelegt werden sollen",
	is_optional:	true
	}
@puth				1

~query.tsteps

#
# <<TSTEPNUM:0>>: 	get the selection data
#
pre_qexpression
	proc: {
		this.options.maxrecsteps = 9000000;
		this.startmillis = Date.now();
		if (!this.query.selsql || this.query.selsql=='DEF') {
			let oldval = this.query.selsql;
			this.query.selsql = this.query.selsqloptions.default;
			this.ppush([this.phead("INITPARAM"),"selsql defaulted from \""+oldval+"\" to "+this.query.selsql,"",""]);
		}
		if (!(this.query.hasOwnProperty("maxrecords"))) {
			this.query.maxrecords = 10000;
			this.ppush([this.phead("INITPARAM"),"maxrecords defaulted to "+this.query.maxrecords,"",""]);
		}
		if (this.query.hasOwnProperty("mode")) {
			this.mode = this.query.mode;
		} else {
			this.mode = "mem";
		}
		if (this.mode=="newmem") {
			if (this.query.hasOwnProperty("newrepdatnum")) {
				this.newrepdatnum = this.query.newrepdatnum;
			} else {
				this.errcoll.collect(null,"mode is newmem, but there is no newrepdatnum",{ query: this.query });
				break proc;
			}
		}
	}
sql				@@selsql@@
result_varname	sres
post_qexpression
	proc: {
		this.recstoprocess = this.sres.getRowCount();
		this.recindex = 0;
		this.recsprocessed = 0;
		this.zuordnungengefunden = 0;
		this.ppush([this.phead("STARTED"),"RECSTOPROCESS="+this.recstoprocess,"",""]);
		if (this.query.hasOwnProperty("maxrecords")) {
			if (this.recstoprocess>this.query.maxrecords) {
				this.errcoll.collect(null,"there are "+this.recstoprocess+" records to process but the maximum allowed number is "+this.query.maxrecords+" records.");
				break proc;
			}
		}
		this.beginmillis = Date.now();
	}

#
# <<TSTEPNUM:1>>: if mode is "mem" ("Memory") or "newmem" ("new" and "memory"), get all Zuordnungen from SVCLZUODUMP to memory
#
if	(this.mode=="mem" || this.mode=="newmem")
sql				SELECT * FROM SVCLZUODUMP
result_varname	zres
post_qexpression
	this.zuos = new Array();
	for (let ri=0; ri<this.zres.getRowCount(); ri++) {
		this.zuos.push(this.zres.getRowObject(ri));
	}

#
# <<TSTEPNUM:2>>: process next record - check if any left
#
next_record:
if		(this.recindex>=this.recstoprocess) 
goto	data_done

#
# <<TSTEPNUM:3>>: enrich one record
#
pre_qexpression
	this.cdata = this.sres.getRowObject(this.recindex);
	this.progstat.SVCL440204 = { recstoprocess: this.recstoprocess, record_index: this.recindex, record_sequence: this.cdata.laufnummer, referenzwert: this.cdata.referenzwert }; 
	let zuoinfo = new Array();
	let ro;
	for (let ri=0; ri<this.zuos.length; ri++) {
		ro = this.zuos[ri];
		if (ro.traeger==this.cdata.traeger && ro.bknr==this.cdata.bknr) {
			zuoinfo.push(ro.seriennummer+"/"+ro.name_kunde);
		}
	}
	delete this.cdata.zuordnungsinfo;
	this.zuosmade = zuoinfo.length;
	if (zuoinfo.length<1) {
		this.zuordnungsinfo = "{}";
	} else {
		this.zuordnungsinfo = zuoinfo.join(",");
	}
	switch (this.mode) {
		case "newmem":		this.tstep.sql = this.tstep.sql_newmem;
							this.uaction = "INSERTED";
							break;
		case "mem":			this.tstep.sql = this.tstep.sql_mem;
							this.uaction = "MEM_UPDATED";
							break;
		case "db":			this.tstep.sql = this.tstep.sql_db;
							this.uaction = "DB_UPDATED"
							break;
		default:			this.errcoll.collect(null,"illegal mode \""+this.mode+"\" for determining SQL to enrich");
	}
sql				select 'no correct SQL calculated'
sql_db			update CCCFUNZ unz set zuordnungsinfo=IFNULL((select group_concat(concat(seriennummer,'/',name_kunde)) from SVCLZUODUMP zuo where zuo.traeger_mst=unz.traeger and zuo.bknr=unz.bknr),'{}')
				 where unz.laufnummer=::laufnummer::
sql_mem			update CCCFUNZ unz set zuordnungsinfo=::zuordnungsinfo::
				 where unz.laufnummer=::laufnummer::
sql_newmem		insert into CCCFUNZ(repdatnum,traeger,bknr,status,referenzwert,einlange_dat,vsnr,parparrolleid_partner,partnerrollenart_kurz,rueckfrageinfo,zuordnungsinfo)
				       values(::repdatnum::,::traeger::,::bknr::,::status::,::referenzwert,::einlange_dat::,::vsnr::,::parparrolleid_partner::,::partnerrollenart_kurz::,::rueckfrageinfo::,::zuordnungsinfo::)
				  returning laufnummer
named_params	laufnummer,repdatnum,traeger,bknr,status,referenzwert,einlange_dat,vsnr,parparrolleid_partner,partnerrollenart_kurz,rueckfrageinfo,zuordnungsinfo
result_varname	dres
post_qexpression
	proc: {
		if (this.mode=="db" || this.mode=="mem") {
			if (this.dres.resulttype && this.dres.resulttype=='object' && this.dres.resultobject && this.dres.resultobject.affectedRows) {
				this.ppush([this.phead(this.uaction),
							"records_changed="+this.dres.resultobject.affectedRows,
							"referenzwert="+this.cdata.referenzwert+".vsnr="+this.cdata.vsnr+".laufnummer="+this.cdata.laufnummer,
							(this.zuordnungsinfo?("zuordnungsinfo="+this.zuordnungsinfo):"")
							]);
			} else {
				this.errcoll.collect(null,"Unknown result in inserting/updating CCCFUNZ record",{ result: this.dres, cdata: this.cdata } );
				break proc;
			}
		} else if (this.mode=="newmem") {                /* mode "newmem": returns a dbresult */
			if (this.dbresult.resulttype!="dbresult") {
				this.ppush([this.phead(this.uaction),
							"record inserted",
							"referenzwert="+this.cdata.referenzwert+".vsnr="+this.cdata.vsnr+".laufnummer="+this.dres.getCellValue(0,0),
							(this.zuordnungsinfo?("zuordnungsinfo="+this.zuordnungsinfo):"")
							]);
			} else {
				this.errcoll.collect(null,"SQL enrich statement in mode \"newmem\" should return a \"dbresult\" but got \""+this.dres.resulttype+"\"", { dres: this.dres });
				break proc;
			}
		} else {
			this.errcoll.collect(null,"unrecognized mode \""+this.mode+"\" after enrichment SQL");
			break proc;
		}
		delete this.zuordnungsinfo;
		this.recsprocessed++;
		if (this.zuosmade>0) {
			this.zuordnungengefunden++;
		}
		this.recindex++;
	}

#
# <<TSTEPNUM:3>>: move on to next record
#
goto	next_record

#
# <<TSTEPNUM:4>>: finish update
#
data_done:
pre_qexpression
	this.endmillis = Date.now();
	this.ppush([this.phead("FINISHED"),
				"RECSPROCESSED="+this.recsprocessed+",RECSWITHZUORDNUNGEN="+this.zuordnungengefunden,
				"TIMETOSELECT="+(this.beginmillis-this.startmillis)/1000+"sec",
				"TOTALTIME="+(this.endmillis-this.startmillis)/1000+"sec"]);
end