#
#	action sequence for object action setPersonAttribute
#
# <<TSTEPNUM:0>>: determine attribute names in database
#
qexpression
  proc: {
	copycvars(this,"action,objtype,attribute,key,value");
	this.attvariant = "SETPERSATT";
	this.uskurzz = getcvar(this,"key");
	switch (this.action) {
		case "SET":			this.actvariant = "SET";	this.attvariant = "SETPERSATT";	break;
		case "DELETE":		this.actvariant = "DEL";	this.attvariant = "DELPERSATT";	break;
		default:			this.errcoll.collect(null,"Illegal action \""+this.action+"\" for setPersonAttribute",{ query: this.query });
							break proc;
	}
	switch (this.attribute) {
		case "TELEFON":					this.attarchtyp=	"PERSINFO";		this.attname =	"FON";					break;
		case "EMAIL":					this.attarchtyp=	"USEMAIL";		this.attname =	"EMAIL";				break;
		case "MOBILE":					this.attarchtyp=	"PERSINFO";		this.attname =	"MOBILE";				break;
		case "DEVOPSUSER":				this.attarchtyp=	"PERSINFO";		this.attname =	"DEVOPSUSER";			break;
		case "TELEFON_PRE_20200101":	this.attarchtyp =	"PERSINFO";		this.attname =	"TELEFON_PRE_20200101";	break;
		case "EMAIL_PRE_20200101":		this.attarchtyp =	"USEMAIL";		this.attname =	"EMAIL_PRE_20200101";	break;
		case "FAX":						this.attarchtyp =	"PERSINFO";		this.attname =	"FAX";					break;
		case "GRUPPE":					this.attvariant =	this.actvariant + "PERSGROUP";							break;
		case "NAME":					this.attvariant =	this.actvariant + "PERSNAME";							break;
		case "TITELVORNE":				this.attarchtyp =	"PERSINFO";		this.attname =	"TITELVORNE";			break;
		case "TITELHINTEN":				this.attarchtyp =	"PERSINFO";		this.attname =	"TITELHINTEN";			break;
		case "VORNAME":					this.attvariant =	this.actvariant + "PERSVORNAME";						break;
		case "FAMILIENNAME": 			this.attvariant =	this.actvariant + "PERSFAMNAME";						break;
		case "USKURZZ":					is.attvariant =		this.actvariant + "PERSKURZZ";							break;
		default:	this.errcoll.collect(null,"Illegal Person Attribute "+this.attribute);
	}
	this.att_insertsql = "insert into CCATT(ATTARCHTYP,ATTPARTYPE,ATTPARKURZ,ATTNAME,ATTVALUE) values(::attarchtyp::,'CCUS',::key::,::attname::,::value::)";
	this.att_updatesql = "update CCATT set ATTVALUE=::value:: where ATTARCHTYP=::attarchtyp:: and ATTPARTYPE='CCUS' and ATTPARKURZ=::key:: and ATTNAME=::attname::";
	this.att_deletesql = "delete from CCATT where ATTARCHTYP=::attarchtyp:: and ATTPARTYPE='CCUS' and ATTPARKURZ=::key:: and ATTNAME=::attname::";
  }

#
# <<TSTEPNUM:1>>: check which type of attribute to set
#
pre_qexpression	
proc: {
		if (!this.labels[this.attvariant]) {
			this.errcoll.collect(null,"cannot "+this.action+"("+this.actvariant+") attribute "+this.attribute+" of person "+this.key+", sequence label \""+this.attvariant+"\" does not exist",
								{ query: this.query, actvariant: this.actvariant, attvariant:  this.attvariant });
			break proc;
		}
	}
goto	@@attvariant@@

#
# -------------------------------------------
#

#
# <<TSTEPNUM:2>>: variant SETPERSATT, check if attribute is already set in database
#
SETPERSATT:
sql 			select * from CCATT where ATTARCHTYP=::attarchtyp:: and ATTPARTYPE='CCUS' and ATTPARKURZ=::key:: and ATTNAME=::attname::
named_params	attarchtyp,key,attname
result_varname	cqpares

#
# <<TSTEPNUM:3>>: determine the database statement to use, dependent if previous select delivered rows or not
#
qexpression
	if (this.cqpares.getRowCount()>0) {
		this.actsql = this.att_updatesql;
	} else {
		this.actsql = this.att_insertsql;
	}

#
# <<TSTEPNUM:4>>: perform the appropriate SQL
#
sql_varname actsql
named_params	attarchtyp,key,attname,value

#
# <<TSTEPNUM:5>>: variant SETPERSATT is complete
#
goto done

# -------------------------------
#
# <<TSTEPNUM:6>>: variant DELPERSATT
#
DELPERSATT:
sql				@@att_deletesql@@
named_params	attarchtyp,key,attname,value
then_goto		done

# -------------------------------
#
# <<TSTEPNUM:7>>: variant SETPERSGROUP
#
SETPERSGROUP:
pre_qexpression
	logger.debug("setPersonAttribute.SETPERSGROUP.USKURZZ="+this.uskurzz+".attribute="+this.attribute+".value="+this.value);
sql select * from CCUSAS where USKURZZ=::uskurzz:: and GRP=::value::
named_params	uskurzz,value
result_varname	cagmres

#
# <<TSTEPNUM:8>>: check if person already in group
#
if (this.cagmres.getRowCount()>0)
goto already_in_group

#
# <<TSTEPNUM:9>>: get OE for which to join the group
#
sql select ATTVALUE from CCATT where ATTARCHTYP='ORGINFO' and ATTPARTYPE='CCUS' and ATTPARKURZ=::uskurzz:: and ATTNAME='HOME_OE'
named_params	uskurzz
result_varname	hoeres

#
# <<TSTEPNUM:10>>: check if we have a home OE
#
if (this.hoeres.getRowCount!=1)
goto no_valid_home_oe

#
# <<TSTEPNUM:11>>: prepare parameters for group membership record
#
qexpression
	this.nowdate = new Date();
	this.vonjahr = this.nowdate.getFullYear();
	this.vonmonat = this.nowdate.getMonth()+1;
	this.homeoe   = this.hoeres.getCellValue(0,0);
	this.role     = 'MEMBER';

#	
# <<TSTEPNUM:12>>: create group membership record
#
sql insert into CCUSAS(uskurzz,grp,oe,role,vonjahr,vonmonat,bisjahr,bismonat,assfte) values(::uskurzz::,::value::,::homeoe::,::role::,::vonjahr::,::vonmonat::,null,null,1)
named_params	uskurzz,value,homeoe,role,vonjahr,vonmonat

#
# <<TSTEPNUM:13>>: SETPERSGROUP complete
#
goto done

#
# <<TSTEPNUM:14>>: collect error for person already in group, this will cause the action to fail
#
already_in_group:
qexpression 
	this.errcoll.collect(null,"Person "+this.uskurzz+" already in group "+this.value);

#
# <<TSTEPNUM:15>>: terminate processing
#
goto done

#
# <<TSTEPNUM:16>>: collect error for person not having a home-OE
#
no_valid_home_oe:
qexpression this.errcoll.collect(null,"Person "+this.uskurzz+" has no valid home Org.-Einheit");

#
# <<TSTEPNUM:17>>: terminate processing
#
goto done

#
# -------------------------------------------------------------------------------
#
# <<TSTEPNUM:18>>:	variant DELPERSGROUP - get group membership record
#
DELPERSGROUP:
sql				SELECT * from CCUSAS where USKURZZ=::key:: and GRP=::value::
named_params	key,value
result_varname	gmres
post_qexpression
	proc: {
		if (this.gmres.getRowCount()!=1) {
			this.errcoll.collect(null,"more than one group membership record for person \""+this.uskurzz+"\" in group \""+this.value+"\"",
									{ memberships: this.gmres });
			break proc;
		}

#
# <<TSTEPNUM:19>>: delete group membership record
#
sql				DELETE from CCUSAS where USKURZZ=::key:: and GRP=::value::
named_params	key,value
then_goto		done

#
# -------------------------------------------------------------------------------
#
# <<TSTEPNUM:20>>: variant SETPERSVORNAME
#
SETPERSVORNAME:
sql				update CCUS set USVORNAME=::value:: where USKURZZ=::key::
named_params	key,value

#
# <<TSTEPNUM:21>>: SETPERSVORNAME complete
#
goto done

#
# -------------------------------------------------------------------------------
#
# <<TSTEPNUM:22>>: variant SETPERSFAMNAME
#
SETPERSFAMNAME:
sql				update CCUS set USFAMILIENNAME=::value:: where USKURZZ=::key::
named_params	key,value

#
# <<TSTEPNUM:23>>: SETPERSFAMNAME complete
#
goto done

#
# -------------------------------------------------------------------------------
#
# <<TSTEPNUM:24>>: variant SETEPRSKURZZ - start with getting person info
#
SETPERSKURZZ:
sql				select ATTNAME,ATTWERT from CCVUSATT where USKURZZ=::key::
named_params	key
result_varname	ccvusatt_result

#
# <<TSTEPNUM:25>>: extract person attributes from CCVUSATT result
#
qexpression
	this.acn = this.ccvusatt_result.findColumn("ATTNAME");
	if (this.acn<0) throw new Error("ATTNAME not found in CCVUSATT result");
	this.avn = this.ccvusatt_result.findColumn("ATTWERT");
	if (this.avn<0) throw new Error("ATTWERT not found in CCVUSATT result");
	this.oas = {};
	for (let ai=0; ai<this.ccvusatt_result.getRowCount(); ai++) {
		this.oas[this.ccvusatt_result.getCellValue(ai,this.acn)] = this.ccvusatt_result.getCellValue(ai,this.avn);
	}

#
# <<TSTEPNUM:26>>: check if USKURZZ has changed
#
if (this.oas.USKURZZ == this.value)
goto done

#
# <<TSTEPNUM:27>>: check if new USKURZZ not yet in use
#
sql				select USKURZZ,USVORNAME,USFAMILIENNAME from CCUS where USKURZZ=::value::
named_params	value
result_varname	uskinuse

#
# <<TSTEPNUM:28>>: error stop if already in use
#
qexpression
	if (this.uskinuse.getRowCount()>0) {
		/* the new USKURZZ is already in use, throw an error, this will cancel the whole operation */
		throw new Error("USKURZZ \""+this.value+"\" already in use for "+this.uskinuse.getRowCount()+" person(s): "+aux.objTxt(this.uskinuse.getRowObject(0)));
	}

#
# <<TSTEPNUM:29>>: change USKURZZ in CCATT
#
sql				update CCATT set ATTPARKURZ=::value:: where ATTPARTYPE='CCUS' and ATTPARKURZ=::key::
named_params	value,key

#
# <<TSTEPNUM:30>>: get all tables having USKURZZs
#
sql select TABLE_NAME from information_schema.COLUMNS where COLUMN_NAME='USKURZZ'
result_varname uskt

#
# <<TSTEPNUM:31>>: prepare table loop
#
qexpression
	this.tli = 0;

#
# <<TSTEPNUM:32>>: check if complete
#
nxtusk:
if (this.tli>=this.uskt.getRowCount())
goto setusk_done

#
# <<TSTEPNUM:33>>:
#
qexpression		
	this.usktable = this.uskt.getCellValue(this.tli,0);
	this.sql_usktab = "update "+this.usktable+" set USKURZZ=::value:: where USKURZZ=::key::";

#
# <<TSTEPNUM:34>>: skip views (by convention, views in CCDB start with "CCV" or "ccv")
#	
if (this.usktable.toUpperCase().startsWith("CCV"))
goto usk_skip

#
# <<TSTEPNUM:35>>: execute update in <.usktable>
#	
sql_varname		sql_usktab
named_params	value,key

#
# <<TSTEPNUM:36>>: one USK-table done
#
usk_skip:
qexpression		this.tli++;

#
# <<TSTEPNUM:37>>: 
#
goto nxtusk

#
# <<TSTEPNUM:38>>: change of USKURZZ done (or not necessary), redirect key to new USKURZZ to show the same person, but with new USKURZZ in the chain_query
#
setusk_done:
qexpression		this.key = this.value

#
# <<TSTEPNUM:39>>: terminate processing
#
goto done

#
# -------------------------------------------------------------------------------
#
# <<TSTEPNUM:40>>: variant SETPERSNAME - determine new parts values
#
SETPERSNAME:
qexpression 
	this.nameutils = require("./nameutils.js");
	this.nas = this.nameutils.parseName(this.value);

#
# <<TSTEPNUM:41>>: get person record from CCVUSATT
#
sql select ATTNAME,ATTWERT from CCVUSATT where USKURZZ=::key::
named_params key
result_varname ccvusatt_result

#
# <<TSTEPNUM:42>>: extract person attributes from CCVUSATT result_varname
#
qexpression
	this.acn = this.ccvusatt_result.findColumn("ATTNAME");
	if (this.acn<0) throw new Error("ATTNAME not found in CCVUSATT result");
	this.avn = this.ccvusatt_result.findColumn("ATTWERT");
	if (this.avn<0) throw new Error("ATTWERT not found in CCVUSATT result");
	this.oas = {};
	for (let ai=0; ai<this.ccvusatt_result.getRowCount(); ai++) {
		this.oas[this.ccvusatt_result.getCellValue(ai,this.acn)] = this.ccvusatt_result.getCellValue(ai,this.avn);
	}
	
#
# <<TSTEPNUM:43>>: check which name attributes have changed in what way
#
qexpression
	/* ccl dictates which attributes of the name to be checked for a change:                                    */
	/*           nan: new attribute name    oan: old attribute name cat: category       caa: CCATT archetype    */
	let ccl = [ {nan: 	'titelvorne',		oan: 	'TITELVORNE',	cat:	"ATT",		caa:	"PERSINFO"	},
				{nan:	'vorname',			oan:	'VORNAME',		cat:	"VNAME",	caa:	"CCUS"		},
				{nan:	'familienname',		oan:	'FAMILIENNAME',	cat:	"FNAME",	caa:	"CCUS"		},
				{nam:	'titelhinten',		oan:	'TITELHINTEN',	cat:	"ATT",		caa:	"PERSINFO"	} ];
	let ca;
	/*	build a sequence of instructions in this.ccs based on the changed attributes */
	this.ccs = new Array();
	for (let ai=0; ai<ccl.length; ai++) {
		ca = ccl[ai];
		if 		(!this.oas[ca.oan] && this.nas[ca.nan]) 	this.ccs.push({cop: "NEW", can: ca.oan, cav: this.nas[ca.nan],	cat:	ca.cat,	caa:	ca.caa});
		else if (this.oas[ca.oan] && !this.nas[ca.nan])		this.ccs.push({cop: "DEL", can: ca.oan,							cat:	ca.cat,	caa:	ca.caa});
		else if (!this.oas[ca.oan] && !this.nas[ca.nan])	this.ccs.push({cop: "NOP",										cat:	ca.cat,	caa:	ca.caa});
		else 												this.ccs.push({cop: "UPD", can: ca.oan, cav: this.nas[ca.nan],	cat:	ca.cat,	caa:	ca.caa});
	}
	this.cci = 0;
	
#
# <<TSTEPNUM:44>>: process all queued name attribute change instructions: - check if we're ready
#
chgnxtatt:
if (this.cci>=this.ccs.length)
goto nameset_done

#
# <<TSTEPNUM:45>>: prepare current name attribute change
#
qexpression
	this.cop = this.ccs[this.cci].cop;
	this.can = this.ccs[this.cci].can;
	this.cav = this.ccs[this.cci].cav;
	this.cat = this.ccs[this.cci].cat;
	this.caa = this.ccs[this.cci].caa;
	this.cpstepname = this.cop + "_" + this.cat;

#
# <<TSTEPNUM:46>>: branch to appropriate processing step
#		
goto	@@pstepname@@

#
# <<TSTEPNUM:47>>:	NOP_ATT - nothing to be done for a generic attribute
#
NOP_ATT:
goto	chgnamattdon

#
# <<TSTEPNUM:48>>: NEW_ATT - have to ADD a generic attribute
#
NEW_ATT:
sql 			INSERT INTO CCATT(ATTARCHTYP,ATTPARTYP,ATTPARKURZ,ATTNAME,ATTVALUE) values(::caa::,'CCUS',::key::,::can::,::cav::)
named_params	caa,key,can,cav
then_goto		chgnamattdon

#
# <<TSTEPNUM:49>>:	DEL_ATT - have to delete a generic attribtues
#
DEL_ATT:
sql 			DELETE FROM CCATT WHERE ATTARCHTYP=::caa:: and ATTPARTYP='CCUS' and ATTPARKURZ=::key:: and ATTNAME=::can::
named_params	caa,key,can
then_goto 		chgnamattdon

#
# <<TSTEPNUM:50>>:	UPD_ATT - have to UPDATE a generic attributes' value
#
UPD_ATT:
sql 			UPDATE CCATT SET ATTVALUE=::cav:: WHERE ATTARCHTYP=::caa:: and ATTPARTYP='CCUS' and ATTPARKURZ=::key:: and ATTNAME=::can::
then_goto 		chgnamattdon

#
# <<TSTEPNUM:51>>:	NEW_VNAME - have to add specific attribute VNAME
#
NEW_VNAME:
sql				UPDATE CCUS set USVORNAME=::cav:: where USKURZZ=::key::
named_params	cav,key
then_goto		chgnamattdon

#
#  <<TSTEPNUM:52>>:	DEL_VNAME - have to delete specific attribute VNAME
#
DEL_VNAME:
sql				UPDATE CCUS set USVORNAME='' where USKURZZ=::key::
named_params	key
then_goto		chgnamattdon

#
# <<TSTEPNUM:53>>:	UPD_VNAME - have to update specific attribute VNAME (VORNAME of a person)
#
UPD_VNAME:
sql				UPDATE CCUS set USVORNAME=::cav:: where USKURZZ=::key::
named_params	cav,key
then_goto		chgnamattdon

#
# <<TSTEPNUM:54>>:	NEW_FNAME
#
NEW_FNAME:
sql				UPDATE CCUS set USFAMILIENNAME=::cav:: where USKURZZ=::key::
named_params	cav,key
then_goto		chgnamattdon

#
# <<TSTEPNUM:55>>:	DEL_FNAME
#
DEL_FNAME:
sql				UPDATE CCUS set USFAMILIENNAME='' where USKURZZ=::key::
named_params	key
then_goto		chgnamattdon

#
# <<TSTEPNUM:56>>:	UPD_FNAME
#
UPD_FNAME:
sql				UPDATE CCUS set USFAMILIENNAME=::cav:: where USKURZZ=::key::
named_params	cav,key
then_goto		chgnamattdon

#
# <<TSTEPNUM:57>>: one name attribute change done, increment counter at repeat loop
#
chgnamattdon:
pre_qexpression	this.cci++;
goto			chgnxtatt

#
# <<TSTEPNUM:58>>: NAME set complete
#
nameset_done:
goto			done

#
# <<TSTEPNUM:59>>: finally, set chain query to re-display person info after having performed the action
#
done:
qexpression 
	this.query.chain_query = {dataname: "personinfo", uskurzz: this.key};