#
#
#			ITSV GmbH
#	CCDB - Command and Control Database
#
#	FILE:			dquerymfile_infoquery.txt
#	DESCRIPTION:	DQUERY definition for DQUERY infoquery
#
@querytitle			Multi-Informations Abfrage
@querydescription	delivers an assortment of information items, depending on selection
@group				INFO
@attributenames		infotype:string:{{infotypeopts}},p1:string:{{p1opts}}
@infotypeopts {
	labeltext:		"Informations-Typ",
	typedesc:		"Typ der Information, der abgefragt werden soll: workdays ... Anzahl von Arbeitstage zwischen Daten, ostersonntag ... Datum des Ostersonntags in einem Jahr",
	type:	{	structure:	"scalar.enum",
				vlist:		"workdays:Arbeitstage im Zeitraum:Zahl der Arbeitstage von <fromday> bis <untilday> in der Form YYYYMMDD,ostersonntag:Ostersonntagds-Datum: Datum des Ostersonntags im Jahr <year>"
	} }
@querytype			function
@function			seqtrans.seqtrans
#
@init.qexpression	
	this.reqtypes = {	workdays:		{	subname:	'INFO_WORKDAYS'	},
						ostersonntag:	{	subname:	'INFO_OSTERSONNTAG' }
					};
	this.extractparams = function(paramstring) {
		return aux.txtObjDecode(paramstring);
	}
		
~query.tsteps

#
# <<TSTEPNUM:0>>: determine request type
#
pre_qexpression
	proc: {
		this.ps = this.extractparams(this.query.p1);
		if (!this.reqtypes[this.query.infotype]) {
			this.errcoll.collect(null,"Undefined Infotype \""+this.query.infotype+"\"",this.query);
			break proc;
		}
		this.reqcb = this.reqtypes[this.query.infotype];
		if (this.reqcb.subname) {
			this.rqptype = 'SUB';
		} else {
			this.errcoll.collect(null,"cannot determine request processing method for infotype \""+this.query.infotype+"\"",this.reqcb);
			break proc;
		}
	}
goto	reqproc_@@rqptype@@

#
# <<TSTEPNUM:1>>: request processing type SUB: execute the subroutine in <subname>
#
reqproc_SUB:
pre_qexpression
		this.execsub = this.reqcb.subname;
gosub	@@execsub@@

#
# <<TSTEPNUM:2>>: end of SUB request processing
#
end

#
# ------------------------------------------------------------------------------
#
# subroutine INFO_WORKDAYS
# parameters must have "fromday" and "untilday" in YYYYMMDD format
# this subroutine calculates workdays between fromday and untilday, including both
#
# <<TSTEPNUM:3>>: get all holidays from CCRW
#
INFO_WORKDAYS:
sql				select * from CCRW where RWTYP='HOLIDAY'
result_varname	hres
post_qexpression
	this.holidays = new Array();
	let cr;
	for (let ri=0; ri<this.hres.getRowCount(); ri++) {
		cr = this.hres.getRowObject(ri);
		this.holidays.push(cr.RWNAME);
	}

#
# <<TSTEPNUM:4>>: calculate calendar days between dates and then subtract all non-work-days
#
qexpression
	let msecsperday = 24*60*60*1000;
	this.ps.fromday = aux.dateFromSerialString(String(this.ps.fromday));
	this.ps.untilday = aux.dateFromSerialString(String(this.ps.untilday));
	let days = Math.round((this.ps.untilday-this.ps.fromday)/msecsperday)+1; /* +1 to include both range limits */
    let wd = 0;
	let hi;
    let dat = new Date(this.ps.fromday);
    while (dat<=this.ps.untilday) {									/* iterate over all days in the range */
      wd = dat.getDay();
	  hi = this.holidays.indexOf(aux.serialDate(dat));
      if ((wd==0) || 												/* it's a sunday */
		  (wd==6) ||                         						/* it's a saturday */
          (hi>=0)) {												/* there is a holiday */
        days--;
      }
      dat = new Date(dat.getTime()+msecsperday);					/* next (following) day */
    }
    this.result = new aux.Result({resulttype: 'object', resultobject: { fromday: aux.serialDate(this.ps.fromday), untilday: aux.serialDate(this.ps.untilday), workdays: days}});

#
# <<TSTEPNUM:5>>: workdays calculation complete
#
return

#
# ------------------------------------------------------------------------------
#
# <<TSTEPNUM:6>>: subroutine INFO_OSTERSONNTAG
# parameter "year" must be a year in format YYYY
#
INFO_OSTERSONNTAG:
qexpression
	this.result = new aux.Result({resulttype: 'object', resultobject: { year: this.ps.year, ostersonntag: aux.svDate(aux.easterDate(this.ps.year)) } } );

#
# <<TSTEPNUM:7>>: ostersonntag calculation complete
#
return


