wfStartLogicCall
Empty start logic

			true;
		

checkDataAndEndValidator
Questa validazione controlla che se il bando di finanziamento viene marcato come "con scadenza" allora deve essere specificata la data di scadenza
Per maggiori dettagli cfr. excel modello dati dell'entità Bando di finanziamento

		
			if(object.getBooleanMap().get("openEnded")!=null){
				if((object.getBooleanMap().get("openEnded")==false)&&(object.getDateMap().get("endDate")==null)){
					errors.reject("error.date.startDateEndDateNotCompatible");	
				}
			}			
		

isNotLegacyAndYearIsGreaterOrEqualThan2019Contract
Questa è la descrizione della logica di validazione Questa è un'applicability rule che viene valutata prima di eseguire altre validazioni.
Se ritorna true allora vengono eseguite le altre validazioni altrimenti no.
Oltre al check previsto da isNotLegacy , verifica anche che il contratto in questione sia relativo ad un anno maggiore o uguale a 2019, altrimenti vengono disattivate le validazioni e le sincronizzazioni.
Questo approccio è stao scelto per evitare lo scatenarsi delle validazioni su vecchi contratti che non rispettano le nuove e più stringenti validazioni, ed evitare quindi di dovere fare una bonifica a tappeto.

	
			(
				object.getYear()!=null 
				&& 
				object.getYear().compareTo(2019)>=0
			) 
			&& 
			(
				object.getBooleanMap().get('legacy')==null 
				|| 
				Packages.java.lang.Boolean.FALSE.equals(object.getBooleanMap().get('legacy'))
			)
		

wfIdentityLogicResearchDivisionProjectPermissionsJs
Questa è una permissions logic che costruisce dinamicamente i permessi per i contratti per il team Divisione Ricerca.
Se l'utente che sta effettuando la creazione del contratto appartiene alla Divisione Ricerca, vengono assegnati i permessi di scrittura a questo team e quelli di sola lettura a livello dipartimentale.

			var wfTask=object;
			var wfItem=wfService.getWfItem(wfTask.getWfItemId());
			var permissions="r";			
			var hasPowerPermissions=Packages.it.cilea.wf.util.WfUtil.isAnyItemCreatorIdentityMatchingThisTaskIdentity(wfTask, wfService);			
			if (Packages.java.lang.Boolean.TRUE.equals(hasPowerPermissions))
				hasPowerPermissions=true;
			else 
				hasPowerPermissions=false;
			
			var hasHelpdeskStartedFlow=Packages.it.cilea.wf.util.WfUtil.isAnyItemCreatorIdentityMatchingAuthoritiesWithThisResource(wfTask, "/HELPDESK/ap/contract.profile", wfService, gaAuthorizationService);
			if (Packages.java.lang.Boolean.TRUE.equals(hasHelpdeskStartedFlow))
				hasHelpdeskStartedFlow=true;
			else 
				hasHelpdeskStartedFlow=false;				
						
			switch(String(wfItem.getWfState().getDescription())){
				case "draft": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow) 
						permissions="crwfd" 
					else 
						permissions="r";
				break;
				
				case "inquiry": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow) 
						permissions="rwfd" 
					else 
						permissions="r";
				break;
				
				case "fiscalCheck": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow)
						permissions="r" 
					else 
						permissions="r";
				break;
				
				case "revisionAfterFiscalCheck": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow) 
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "approval": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow) 
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "approvedAwaitingCountersignedContract": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow)
						permissions="rwf" 
					else 
						permissions="r";
				break;				
				
				case "signed": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow)
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "closed": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow)
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "suspended": 
					if(hasPowerPermissions||hasHelpdeskStartedFlow)
						permissions="rwf" 
					else 
						permissions="r";
				break;
			}
			
			wfTask.setPermissions(permissions);
			
		

wfIdentityLogicMultipleHeadOfDepartmentProjectPermissionsJs
Questa è una permissions logic che costruisce dinamicamente i permessi per i contratti per il team dipartimentali
Se l'utente che sta effettuando la creazione del contratto è in visione dipartimentale e appartiene ad un team dipartimentale, vengono assegnati i permessi di scrittura a questo team e quelli di sola lettura a livello Divisione Ricerca.

			var wfTask=object;
			var wfItem=wfService.getWfItem(wfTask.getWfItemId());
			var permissions="r";			
			var isOnlyRead=true;
			
			//recupero l'unità organizzativa associata (dipartimento) all'identity/team di questo task
			var organizationUnitFromIdentity=Packages.it.cilea.ga.util.GaUtil.getOrganizationUnitFromIdentyForDepartment(gaAuthorizationService.getIdentity(wfTask.getIdentityId()), gaService);			
			
			//recupero dall'item la lista dei dipartimenti
			var internalOrganizationUnitList=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem,
				"it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
			var internalOrganizationUnitListIterator = internalOrganizationUnitList.iterator();
			
			//controllo il ruolo del dipartimento
			//isOnlyRead è false se il dipartimento è principale
			//isOnlyRead è true se il dipartimento è aggregato
			while(internalOrganizationUnitListIterator.hasNext()){
				var internalOrganizationUnit=internalOrganizationUnitListIterator.next();
				var ou = internalOrganizationUnit.getOrganizationUnitMap().get("ouId");
				
				if (ou.getId().equals(organizationUnitFromIdentity.getId())){
					//cerco prima roleId che è il ruolo standard.
					//se non lo trovo ricado in ouRole che è quello legacy
					var role=internalOrganizationUnit.getWfDictionaryMap().get("roleId");
					if (role==null)
						role=internalOrganizationUnit.getWfDictionaryMap().get("ouRole");
					isOnlyRead=Packages.it.cilea.wf.util.WfUtil.isOnlyReadPermission(role, wfItem, "wfIdentityLogicMultipleHeadOfDepartment");
					if (Packages.java.lang.Boolean.TRUE.equals(isOnlyRead))
						isOnlyRead=true;
					else
						isOnlyRead=false;

					break;
				}					
			}
			
			//verifico se c'è match tra le identity di chi ha creato l'item e l'identity di questo task
			//serve per capire se il contratto in questione è stato creato da Divisione Ricerca o da Dipartimento
			//e per dare "power permissions" solo al team che ha fatto la creazione.
			var hasPowerPermissions=Packages.it.cilea.wf.util.WfUtil.isAnyItemCreatorIdentityMatchingThisTaskIdentity(wfTask, wfService);
			
			if (Packages.java.lang.Boolean.TRUE.equals(hasPowerPermissions))
				hasPowerPermissions=true;
			else {
				//se hasPowerPermissions è false allora dovrebbe essere stato creato dalla Divisione Ricerca
				//se però viene cambiato in corso d'opera il dipartimento, non ci sarà più match tra il team dipartimentale che ha creato l'item e il team dipartimentale che dovrebbe accederci.
				//per gestire questo scenario controllo se le identity di chi ha effettuao la creazione sono quelle dipartimentali.				
				var isItemCreatedByDepartmentAuthority=Packages.it.cilea.wf.util.WfUtil.isAllItemCreatorIdentityOfGivenAuthority(wfTask, wfService, gaAuthorizationService, "ROLE_DEPARTMENT");
				
				//se chi ha creato aveva identity dipartimentali...
				if (Packages.java.lang.Boolean.TRUE.equals(isItemCreatedByDepartmentAuthority)){															
					if (isOnlyRead)
						hasPowerPermissions=false;
					else 
						hasPowerPermissions=true;
				} else {
					//se chi ha creato NON aveva identity dipartimentali (Helpdesk o Divisione Ricerca)...
					hasPowerPermissions=false;
				}				
			}
			
			switch(String(wfItem.getWfState().getDescription())){
				case "draft": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="crwfd" 
					else 
						permissions="r";
				break;
				
				case "inquiry": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwfd" 
					else 
						permissions="r";
				break;
				
				case "fiscalCheck": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="r" 
					else 
						permissions="r";
				break;
				
				case "revisionAfterFiscalCheck": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "approval": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "approvedAwaitingCountersignedContract": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwf" 
					else 
						permissions="r";
				break;				
				
				case "signed": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "closed": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwf" 
					else 
						permissions="r";
				break;
				
				case "suspended": 
					if(hasPowerPermissions && !isOnlyRead) 
						permissions="rwf" 
					else 
						permissions="r";
				break;	
			}
			
			wfTask.setPermissions(permissions);			
					
		

wfStartLogicContract
Questa logica viene eseguita in fase di creazione di un nuovo contratto.
Vengono effettuate le seguenti operazioni:

Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			var person=wfItem.getPersonMap().get("owner");
			person=gaService.getPerson(person.getId());
			var startDate=wfItem.getDateMap().get("proposalStartDate");
			var ownerElement=new Packages.it.cilea.wf.model.WfItemElement();
			ownerElement.setDiscriminator("owner");
			ownerElement.setWfItemId(wfItem.getId());
			ownerElement.getPersonMap().put("ownerId", person);
	
			wfService.saveOrUpdate(ownerElement);
			wfItem.getWfItemElementSet().add(ownerElement);
			wfItem.getPersonMap().put("owner", null);
			
			var positionLastSet = person.getPositionLastSet();											
			var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(positionLastSet, "research", "department");
			positionLastSetIterator=positionLastSet.iterator();											
			while (positionLastSetIterator.hasNext()){
				var position=positionLastSetIterator.next();
				if (maxPriority == null || maxPriority.equals(position.getPriority())) {
					if ("research".equals(position.getDiscriminator()) && "department"
								.equals(position.getOrganizationUnit().getOrganizationUnitType().getDescription())) {
						var internalOrganizationUnitElement=new Packages.it.cilea.wf.model.WfItemElement();
						internalOrganizationUnitElement.setDiscriminator("internalOrganizationUnit");
						internalOrganizationUnitElement.setWfItemId(wfItem.getId());
						var internalOrganizationUnitRoleId = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.contract.internalOrganizationUnit.role.main");
						var internalOrganizationUnitRole = wfService.getWfDictionary(new Packages.java.lang.Integer(internalOrganizationUnitRoleId));
						internalOrganizationUnitElement.getOrganizationUnitMap().put("ouId", position.getOrganizationUnit());
						internalOrganizationUnitElement.getWfDictionaryMap().put("ouRole", internalOrganizationUnitRole);
						wfService.saveOrUpdate(internalOrganizationUnitElement);
						wfItem.getWfItemElementSet().add(internalOrganizationUnitElement);
						break;
					}
				}
			}		
			
			var year=startDate.get(Packages.java.util.Calendar.YEAR);
			wfItem.setYear(new Packages.java.lang.Integer(year));
			
			true;
			
			

ownerValidatorContract
Questa validazione controlla che esista almeno un responsabile scientifico nel tab "Soggetti interni".
Dal punto di vista del modello dati si tratta degli elementi di tipo owner
Per maggiori dettagli cfr. excel modello dati dell'entità Contratto

			if (object.getId()==null){
				if (object.getPersonMap().get("owner")==null)
					errors.rejectValue("personMap[owner]","error.contract.owner.required");
			} else {
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				if (
				!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))
				&&
				ownerSet.size()<1 
				&& 
				object.getPersonMap().get("owner")==null
				)
					errors.reject("error.contract.owner.atLeast1");
			}
		

ownerValidatorWithStartEndDateContract

		
			if (object.getId()==null){
				if (object.getPersonMap().get("owner")==null)
					errors.rejectValue("personMap[owner]","error.contract.owner.required");
			} else {
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){
					if (ownerSet.size()<1 && object.getPersonMap().get("owner")==null)
						errors.reject("error.contract.owner.atLeast1");
						
					var ownerSetIterator=ownerSet.iterator();
					
					var wfItemStartDate=object.getDateMap().get("startDate");
					var wfItemEndDate=object.getDateMap().get("endDate");
					var formatter =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
					var ownerWithWrongInterval=[];
								
					while (ownerSetIterator.hasNext()){										
						var owner=ownerSetIterator.next();
						var wfItemElementStartDate=owner.getDateMap().get("startDate");
						
						if( wfItemElementStartDate!= null && wfItemStartDate && (wfItemElementStartDate.before(wfItemStartDate) || (wfItemEndDate!=null && wfItemElementStartDate.after(wfItemEndDate)))  ){
							ownerWithWrongInterval.push(owner.getPersonMap().get("ownerId").getDisplayValue());
						}								
					}
					
					if (ownerWithWrongInterval.length>0){
						errors.reject("error.contract.owner.wrongInterval", [ownerWithWrongInterval.toString()], "error.contract.owner.wrongInterval");
					}
				}
			}	
		

contributorValidatorWithStartEndDateContract

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){						
				var contributorSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "contributor", wfService);
				if (contributorSet.size()>0){
					var contributorSetIterator=contributorSet.iterator();				
					var wfItemStartDate=object.getDateMap().get("startDate");
					var wfItemEndDate=object.getDateMap().get("endDate");
					var formatter =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
					var contributorWithWrongInterval=[];
								
					while (contributorSetIterator.hasNext()){										
						var contributor=contributorSetIterator.next();												
						var wfItemElementStartDate=contributor.getDateMap().get("startDate");
						
						if( wfItemElementStartDate!= null && wfItemStartDate && (wfItemElementStartDate.before(wfItemStartDate) || (wfItemEndDate!=null && wfItemElementStartDate.after(wfItemEndDate)))  ){
							contributorWithWrongInterval.push(contributor.getPersonMap().get("contributorId").getDisplayValue());
						}								
					}
					
					if (contributorWithWrongInterval.length>0){
						errors.reject("error.contract.contributor.wrongInterval", [contributorWithWrongInterval.toString()], "error.contract.contributor.wrongInterval");
					}			
				}				
			}
		

administrativeOwnerValidatorContract
Questa validazione controlla che esista almeno un referente amministrativo nel tab "Soggetti interni".
Dal punto di vista del modello dati si tratta degli elementi di tipo administrativeOwner
Per maggiori dettagli cfr. excel modello dati dell'entità Contratto

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){						
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "administrativeOwner", wfService);
				if (ownerSet.size()<1)
					errors.reject("error.contract.administrativeOwner.atLeast1");
			}
		

organizationUnitValidatorContract
Questa validazione controlla che esista almeno una unità organizzativa interna nel tab "Soggetti interni".
Dal punto di vista del modello dati si tratta degli elementi di tipo internalOrganizationUnit
Per maggiori dettagli cfr. excel modello dati dell'entità Contratto

		
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
				if (orgUnitSet.size()<1)
					errors.reject("error.contract.multipleInternalOrganization.atLeast1");
			}		
		

organizationUnitRoleValidatorContract
Questa validazione controlla che esista almeno un dipartimento specificato e che uno ed uno solo sia marcato come "Principale"
Per maggiori dettagli cfr. excel modello dati dell'entità in questione

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){			
				var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
				if (orgUnitSet.size()<1){
					errors.reject("error.contract.multipleInternalOrganization.atLeast1");
				} else {
					var internalOrganizationUnitCoordinatorRole=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.contract.internalOrganizationUnit.role.main");
					if (!internalOrganizationUnitCoordinatorRole){
						throw "Configuration variable ap.contract.internalOrganizationUnit.role.main MUST BE DEFINED"; 								
					} else {
						internalOrganizationUnitCoordinatorRole=new Packages.java.lang.Integer(internalOrganizationUnitCoordinatorRole);
					}
					var orgUnitSetIterator=orgUnitSet.iterator();
					var count=0;											
					while (orgUnitSetIterator.hasNext()){											
						var element=orgUnitSetIterator.next();												
						var ouRole=element.getWfDictionaryMap().get("ouRole");
						if (ouRole!=null && internalOrganizationUnitCoordinatorRole.equals(ouRole.getId())){
							count++;	
						}												
					}
					if (count==0){
						errors.reject("error.contract.multipleInternalOrganization.missingMain");
					}
					else if (count>1) {
						errors.reject("error.contract.multipleInternalOrganization.tooManyMain");
					}
				}     
			}   								       										
		

ownerAndOrganizationUnitMatchValidatorContract

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				var ownerDepartmentSet=new Packages.java.util.HashSet();
				var internalOrganizationUnitSet=new Packages.java.util.HashSet();
				
				var startDateFromWfItem=wfItem.getDateMap().get("startDate");
				if (startDateFromWfItem!=null){	
					startDateFromWfItem=startDateFromWfItem.getTime();	
				
					if (ownerSet.size()>0){
						var ownerSetIterator=ownerSet.iterator();			
						while (ownerSetIterator.hasNext()){
							var ownerElement=ownerSetIterator.next();			
							var person=ownerElement.getPersonMap().get("ownerId");
							
							var ownerDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
							ownerDepartmentPositionSearch.setPersonId(person.getId());
							ownerDepartmentPositionSearch.setDate(startDateFromWfItem);
							ownerDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
							ownerDepartmentPositionSearch.setDiscriminator("research");							
							var ownerDepartmentPositionSet = gaService.getPositionSearchList(ownerDepartmentPositionSearch, 0);
							var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(ownerDepartmentPositionSet, "research", "department");
							
							var ownerDepartmentPositionSetIterator=ownerDepartmentPositionSet.iterator();							
							while (ownerDepartmentPositionSetIterator.hasNext()){
								var position=ownerDepartmentPositionSetIterator.next();
								if (maxPriority == null || maxPriority.equals(position.getPriority())) {
									ownerDepartmentSet.add(position.getOrganizationUnit());														
									break;
								}
							}
						}
					}
					if (ownerDepartmentSet.size()>0){
						if (orgUnitSet.size()>0){
				 			var orgUnitSetIterator=orgUnitSet.iterator();			
							while (orgUnitSetIterator.hasNext()){											
								var wfItemElement=orgUnitSetIterator.next();												
								var orgUnit=wfItemElement.getOrganizationUnitMap().get("ouId");
								internalOrganizationUnitSet.add(orgUnit);
							}
						}
					}
					
					if(!internalOrganizationUnitSet.containsAll(ownerDepartmentSet)){
						var nonMatchedDepartmentCollection=Packages.org.apache.commons.collections.CollectionUtils.subtract(ownerDepartmentSet, internalOrganizationUnitSet);
						var nonMatchedDepartmentCollectionIterator=nonMatchedDepartmentCollection.iterator();
						var nonMatchedDepartmentString="";
						var counter=0;
						while(nonMatchedDepartmentCollectionIterator.hasNext()){
							var nonMatchedDepartment=nonMatchedDepartmentCollectionIterator.next();
							if (counter++>0)
								nonMatchedDepartmentString+=", ";
							nonMatchedDepartmentString+=nonMatchedDepartment.getDescription();
						}
						var df =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
						var dateAsString=df.format(startDateFromWfItem);
						errors.reject("error.contract.multipleInternalOrganization.matchWithDepartmentOwnerNotFound", [dateAsString, nonMatchedDepartmentString], null);       								
					}        
				}	
			}							       										
		

customerValidatorContract
Questa validazione controlla che esista almeno un committente nel tab "Dati generali".
Dal punto di vista del modello dati si tratta degli elementi di tipo customer
Per maggiori dettagli cfr. excel modello dati dell'entità Contratto

		
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){					
				var customerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "customer", wfService);
				if (customerSet.size()<1)
					errors.reject("error.contract.customer.atLeast1");        						
			}		       										
		

currencyAndTotalAmountValidatorContract
Questa validazione controlla che nel tab "Corrispettivi", nel caso di selezione di valuta diversa da EURO, vengano specificati


Dal punto di vista del modello dati si tratta degli attributi:

Per maggiori dettagli cfr. excel modello dati dell'entità Contratto

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){		
				var currency = object.getWfDictionaryMap().get("currency");	
				if(currency != null){
					var currencyId = object.getWfDictionaryMap().get("currency").getId();
					var dictionary = wfService.getWfDictionary(currencyId);
					var currencyCode = dictionary.getStringMap().get("code");
				
					if (currencyCode != "currency.eur"){
						if (!object.getNumberMap().get("totalAmountOriginalCurrency")){       										
							errors.rejectValue("numberMap[totalAmountOriginalCurrency]","error.contract.funding.totalAmountOriginalCurrency.required");									
						}
						if (!object.getNumberMap().get("exchangeRate")){
							errors.rejectValue("numberMap[exchangeRate]","error.contract.funding.exchangeRate.required");									
						}
						if (!object.getDateMap().get("exchangeRateDate")){
							errors.rejectValue("dateMap[exchangeRateDate]","error.contract.funding.exchangeRateDate.required");									
						}
					}
				}				
				
			}	       							        								       										
		

wfUgovPjSenderValidatorContract
Questa logica, effettua check di consistenza sulle mappature degli oggetti IRIS/UGOV e, se superati, invia il contratto verso UGOV PJ rispettando le regole di NON SOVRASCRITTURA lato UGOV PJ.
Per maggiori dettagli su queste regole consultare il team di UGOV PJ.
Le controparti dei contratti IRIS vengono create su UGOV con le regole di mappature delle tassonomie che vengono condivise in fase di attivazione.
Se in corso d'opera dovesse nascere l'esigenza di censire delle nuove tipologie è possibile contattare l'HD.
Di seguito vengono riportate le informazioni inviate ad UGOV PJ, con la specifica dell'attributo del modello dell'entità Contratto IRIS


Per maggiori dettagli cfr. excel modello dati dell'entità Contratto

			var Logic = function(wfItem, dtoPj, superLogic, errors, messageUtil, request, gaService, wfService, wfTaskService, searchBuilderTemplate, log) {
			this.wfItem=wfItem;
			this.dtoPj=dtoPj;
			this.superLogic=superLogic;
			this.errors=errors;
			this.messageUtil=messageUtil;
			this.request=request;
			this.gaService=gaService;
			this.wfService=wfService;
			this.wfTaskService=wfTaskService;
			this.searchBuilderTemplate=searchBuilderTemplate;
			this.log=log;
			this.setInternalOrgUnitList = function() {
				var internalOrganizationUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);
				var internalOrganizationUnitSetIterator=internalOrganizationUnitSet.iterator();
				while (internalOrganizationUnitSetIterator.hasNext()){
					var element=internalOrganizationUnitSetIterator.next();
					var orgUnit = element.getOrganizationUnitMap().get("ouId");
					var orgUnitRole = element.getWfDictionaryMap().get("ouRole");
					dtoPj.getDTOUoPjs().add(superLogic.getOrganizationUnit(orgUnit, orgUnitRole, errors));
				}
			};			
			this.setFinanciers = function() {
				var sendCustomer2Ugov=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.contract.customer.send2ugov.enable");
				if (sendCustomer2Ugov && sendCustomer2Ugov.trim().equalsIgnoreCase("true")){
					var contractorSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement", "customer",wfService);
					var contractorSetIterator=contractorSet.iterator();
					while (contractorSetIterator.hasNext()){
						var element=contractorSetIterator.next();
						var organizationUnit = element.getOrganizationUnitMap().get("customerId");
						var enteFinanziatore = superLogic.getEnteFinanziatore(organizationUnit, this.getFinancing(), contractorSet.size(), errors);
						dtoPj.getDTOEfPjs().add(enteFinanziatore);
					}
				}
			};
			this.setPartners = function() {};
			this.getFinancing = function() {				
				return wfItem.getNumberMap().get("totalAmount");
			};
			this.getStartDate = function() {
				return wfItem.getDateMap().get("startDate");			    	
			};
			this.getEndDate = function() {
				return wfItem.getDateMap().get("endDate");			    
			};
			this.getIdentifier = function() {	
				return wfItem.getIdentifier();
			};
			this.getDescription = function() {
				if(wfItem.getDescription()!=null){
					var length=wfItem.getDescription().length();
					return wfItem.getDescription().substring(0,(length>255)?255:length);
				} else {
					return null;
				}
			};
			this.getCup = function() {
				return null;
			};
			this.getAcronym = function() {
				return wfItem.getStringMap().get("acronym");
			};
			this.getExternalDmsIdentifier = function() {
				return wfItem.getStringMap().get("externalDmsIdentifier");
			};						
			this.isSynchronizable = function() {
				var financing=this.getFinancing();
				var legacy=wfItem.getBooleanMap().get("legacy");
				if (Packages.java.lang.Boolean.TRUE.equals(legacy) || financing==null || Packages.java.math.BigDecimal.ZERO.equals(financing))
					return Packages.java.lang.Boolean.FALSE;
				else			    
					return Packages.java.lang.Boolean.TRUE;
			};
			this.getProjectType = function() {
				return superLogic.getProjectType(wfItem);
			};
			this.getFinanceSchema = function() {
				return this.getProjectType();
			};
			this.getPjInternalCode = function() {
				return null;
			};
			this.isContributorStartDateRequired = function() {						
				var contributorStartDateRequired=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.contract.contributor.starDate.required");
				if (contributorStartDateRequired){
					if (contributorStartDateRequired.trim().equalsIgnoreCase("true")){
						return Packages.java.lang.Boolean.TRUE;
					} else if (contributorStartDateRequired.trim().equalsIgnoreCase("false")){
						return Packages.java.lang.Boolean.FALSE;
					} else {
						throw "ap.contract.contributor.starDate.required MUST BE true or false";
					}
				} else {
					return Packages.java.lang.Boolean.TRUE;
				}							    
			};				
			this.isOwnerStartDateRequired = function() {
				var ownerStartDateRequired=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.contract.owner.starDate.required");
				if (ownerStartDateRequired){
					if (ownerStartDateRequired.trim().equalsIgnoreCase("true")){
						return Packages.java.lang.Boolean.TRUE;
					} else if (ownerStartDateRequired.trim().equalsIgnoreCase("false")){
						return Packages.java.lang.Boolean.FALSE;
					} else {
						throw "ap.contract.owner.starDate.required MUST BE true or false";
					}
				} else {
					return Packages.java.lang.Boolean.TRUE;
				}
			};
		};
		new Logic(wfItem, dtoPj, superLogic, errors, messageUtil, request, gaService, wfService, wfTaskService, searchBuilderTemplate, log);
		

uniqueIdentifierContract
Questa validazione controlla l'unicità dell'identificativo dell'oggetto.
Questa verifica viene fatta per i casi di generazione di codice "parlante" con possibile collisione con identificativi già presenti.

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var paramMap = new Packages.java.util.HashMap();
				paramMap.put("identifier", object.getIdentifier());			
				
				var count=searchBuilderTemplate.getSingleObject("getWfItemCount", paramMap);
				if (count>1)
					errors.reject("error.contract.identifier.notUnique");			
			}
		

fiscalCheckFieldsetValidatorContract

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var reject = 0;
				//var discriminator = ["fiscalCheckPerson", "fiscalCheckDate", "fiscalCheckTariff", "fiscalCheckVatCode", "fiscalCheckNotes"];
				var discriminator = ["fiscalCheckTariff", "fiscalCheckVatCode", "fiscalCheckNotes"];
				//var column = ["fk_person","date","string","string","string"];
				var column = ["string","string","string"];
				columnLen = column.length;
				var value = [];
				for (i = 0; i < columnLen; i++) {
					var list = wfService.getWfItemDataValue(object.getId(), discriminator[i], column[i]);
					var listIterator=list.iterator();						
					if(listIterator.hasNext()){										
						value[i] = listIterator.next();
					} else {
						value[i] = null;
					}
				}
				//if(!Packages.java.lang.Boolean.TRUE.equals(wfService.compareCommandToPersistedValue(object.getPersonMap().get("fiscalCheckPerson"), value[0]))){
				//	if(value[0]){
				//		object.getPersonMap().put("fiscalCheckPerson", gaService.getPerson(value[0].intValueExact()));
				//	} else {
				//		object.getPersonMap().put("fiscalCheckPerson", null);
				//	}
				//	reject = 1;
				//}
				//if(!Packages.java.lang.Boolean.TRUE.equals(wfService.compareCommandToPersistedValue(object.getDateMap().get("fiscalCheckDate"), value[1]))){
				//	object.getDateMap().put("fiscalCheckDate", value[1]);	
				//	reject = 1;
				//}
				if(!Packages.java.lang.Boolean.TRUE.equals(wfService.compareCommandToPersistedValue(object.getStringMap().get("fiscalCheckTariff"), value[0]))){
					object.getStringMap().put("fiscalCheckTariff", value[0]);	
					reject = 1;
				}
				if(!Packages.java.lang.Boolean.TRUE.equals(wfService.compareCommandToPersistedValue(object.getStringMap().get("fiscalCheckVatCode"), value[1]))){
					object.getStringMap().put("fiscalCheckVatCode", value[1]);	
					reject = 1;
				}
				if(!Packages.java.lang.Boolean.TRUE.equals(wfService.compareCommandToPersistedValue(object.getStringMap().get("fiscalCheckNotes"), value[2]))){
					object.getStringMap().put("fiscalCheckNotes", value[2]);	
					reject = 1;
				}
				if(reject > 0){
					errors.reject("error.contract.fiscalCheck.edit.notAllowed");
				}
			}		
		

wfActionLogicEnterEquipmentOwnerMailSender

			X={
			subjectLabel:'label.ap.equipment.mail.subject',
			textLabel:'label.ap.equipment.mail.text',
			sendEnable:'ap.itemType.eqp.mail.enable',
			htmlEnable:'ap.itemType.eqp.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleOwners',
			to:'',
			from:''
			}; X;
		

wfActionLogicEnterEquipmentHeadOfDepartmentMailSender

			X={
			subjectLabel:'label.ap.equipment.mail.subject',
			textLabel:'label.ap.equipment.mail.text',
			sendEnable:'ap.itemType.eqp.mail.enable',
			htmlEnable:'ap.itemType.eqp.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleHeadOfDepartment',
			to:'',
			from:''
			}; X;
		

wfActionLogicCreateRmItem

			function createNewOrgUnitElementEquipment(department, rmItem){
				
				var orgUnitElement= Packages.it.cilea.ga.model.OrganizationUnitElement();
				
				orgUnitElement.setDiscriminator("equipment");
				orgUnitElement.setOrganizationUnit(department);
				orgUnitElement.setOrganizationUnitId(department.getOrganizationUnitId());
				orgUnitElement.getRmItemMap().put("equipment", rmItem);
				
				return orgUnitElement;
			}
			
			//log.error("Sono nella action //logic di enter wfAction//logicCreateRmItem -updated");
			
			var wfItem= wfService.getWfItem(object.getId());
			var rmItemMap=wfItem.getRmItemMap();
			var rmItem=rmItemMap.get("equipment");
			
			if(rmItem==null){
				rmItem= Packages.it.cilea.ga.model.RmItem();
				
				var today = new Date();
				rmItem.setCreateDate(today);
				
				rmItem.setRmItemTypeId(10);
				
				rmItem.getIntegerMap().put("apItemSourceId", object.getId());
			}
			rmItem.setDescription(wfItem.getDescription());
			rmItem.getStringMap().put("apItemSourceIdentifier", object.getIdentifier());
			
			//aggiungo o sovrascrivo l'rmItem
			rmItemMap.put("equipment", rmItem);
			//sovrascrivo la mappa, ci metto quella aggiornata
			wfItem.setRmItemMap(rmItemMap);
			
			//mi tengo da parte l'id prima del salvataggio
			//lo userò dopo per vedere se devo cercare orgUnitElement
			var rmItemId=rmItem.getId();
			
			//log.error("rmItemId prima del salvataggio: "+rmItemId);
			
			//salvo
			gaService.saveOrUpdate(rmItem);
			wfService.saveOrUpdate(wfItem);
			//log.error("Salvato rmItem e wfItem");
			
			
			//PARTE PER AGGIUNTA AL DIPARTIMENTO
			
			//prima tolgo tutti gli orgUnitElement, se ce ne sono attaccati all'rmItem
			//poi li riaggiungo tutti
			
			if(rmItemId!=null){
				//log.error("rmItem non nuovo");
				
				var paramMap = new Packages.java.util.HashMap();
				paramMap.put("rmItemValueId", rmItem.getId());	
				var orgUnitElementList=searchBuilderTemplate.query("getOrganizationUnitElementByRmItemId", paramMap);
				
				var orgUnitElementListIter= orgUnitElementList.iterator();
				while(orgUnitElementListIter.hasNext()){
					var orgUnitElement=orgUnitElementListIter.next();
					gaService.deleteOrganizationUnitElement(orgUnitElement.getId());
					//log.error("Eliminato orgUnitElement con id: "+orgUnitElement.getId());
				}
			}
			
			/*
			var paramMap = new Packages.java.util.HashMap();
			paramMap.put("rmItemValueId", 10);			
			var orgUnitList=searchBuilderTemplate.query("getOrganizationUnitElementByRmItemId", paramMap);
			*/
			
			var departmentSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);
			var departmentSetIterator = departmentSet.iterator();
			
			while(departmentSetIterator.hasNext()){
				
				var departmentElement=departmentSetIterator.next();
				var departmentEmpty= departmentElement.getOrganizationUnitMap().get("ouId");
				var department=gaService.getOrganizationUnit(departmentEmpty.getId());
				//log.error("Dipartimento: "+department.getDescription());
				
				//a differenza della versione di prima, so già che non ci sono orgUnitElement attaccati al mio rmItem
				//quindi ne aggiungo direttamente uno
				
				department.getOrganizationUnitElementSet().add(
						createNewOrgUnitElementEquipment(department, rmItem)
					);
				//log.error("Aggiunto nuovo orgUnitElement");
				
				gaService.saveOrUpdate(department);
				//log.error("Salvato il dipartimento");
			}
			
			
			//log.error("fine action di enter");
			
			
			
		

wfActionLogicEnterLaboratoryOwnerMailSender

			X={
			subjectLabel:'label.ap.laboratory.mail.subject',
			textLabel:'label.ap.laboratory.mail.text',
			sendEnable:'ap.itemType.lab.mail.enable',
			htmlEnable:'ap.itemType.lab.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleOwners',
			to:'',
			from:''
			}; X;
		

wfActionLogicEnterLaboratoryHeadOfDepartmentMailSender

			X={
			subjectLabel:'label.ap.laboratory.mail.subject',
			textLabel:'label.ap.laboratory.mail.text',
			sendEnable:'ap.itemType.lab.mail.enable',
			htmlEnable:'ap.itemType.lab.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleHeadOfDepartment',
			to:'',
			from:''
			}; X;
		

equipmentValidatorLaboratory

		//log.error("entro nel validator");
		var equipmentSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "laboratoryEquipmentLink", wfService);
		
		//log.error("equipmentSet size= "+equipmentSet.size());
		if(equipmentSet.size()>0){
			var equipmentSetIterator = equipmentSet.iterator();
			while (equipmentSetIterator.hasNext()) {
				var equipmentElement = equipmentSetIterator.next();
			    var equipment = equipmentElement.getChild();
			    var equipmentState = equipment.getWfState().getDescription();
			    //log.error("stato dell'equipment"+equipmentState);
			    if(!Packages.org.apache.commons.lang.StringUtils.equals("approved", equipmentState)){
			    	//log.error("trovato un laboratory non approvato");
			    	errors.reject("error.laboratory.equipment.mustBeApproved");
			    }
			}
		 }		 
  		

wfActionLogicCreatePersonElementIncoming

			
			function obtainIncomingTypeDictionary(incomingTypeDescription){
				//prima di tutto ne cerco
				var incomingTypeDictionaryList = gaService.getGaDictionarySearchList(incomingTypeDescription, "incomingType", null, null, null);
				
				//se non ne trovo allora creo da zero il dizionario, lo salvo e lo restituisco
				if(incomingTypeDictionaryList.size()==0){
					var newIncomingTypeDictionary = Packages.it.cilea.ga.model.GaDictionary();
					newIncomingTypeDictionary.setDescription(incomingTypeDescription);
					newIncomingTypeDictionary.setDiscriminator("incomingType");
					//newIncomingTypeDictionary.setId(gaService.saveOrUpdate(newIncomingTypeDictionary));
					newIncomingTypeDictionary.getStringMap().put("MANAGED_BY", "system");	//in modo tale che non possa essere modificato da interfaccia
					gaService.saveOrUpdate(newIncomingTypeDictionary);
					return newIncomingTypeDictionary;
				}else{	//altrimenti lo restituisco direttamente
					//non vado a ciclare tutta la lista, ne ho solo uno di dictionary fatto così
					return incomingTypeDictionaryList.get(0);
				}
				
			}
		
			//log.error("wfActionLogicCreatePersonElementIncoming");
			//prima di tutto ricavo l'oggetto completo, già salvato
			var wfItem = wfService.getWfItem(object.getId());
			
			//ora ricavo tutte le info che mi serviranno più tardi

			//inizio a ricavare l'identificativo numerico
			//potrei non creare una variabile apposta, ma così è più chiaro
			var wfItemId = wfItem.getId();
			//e poi quello testuale
			var wfItemIdentifier = wfItem.getIdentifier();

			//poi vado a ricavare tutti i tutor inseriti
			//var tutorWfItemElementSet = wfItem.getWfItemElementSet("tutor");	//restituisce sempre un oggetto, mai null
			var tutorWfItemElementSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement","tutor", wfService);

			//solo se ne trovo, allora eseguo il resto della procedura			
			if(!tutorWfItemElementSet.isEmpty()){
				//ora per vado a ciclare ogni wfItemElement, ricavando poi la persona collegata
				var tutorWfItemElementSetIterator = tutorWfItemElementSet.iterator();
				while(tutorWfItemElementSetIterator.hasNext()){
					var tutorWfItemElement = tutorWfItemElementSetIterator.next();
					
					//ora ricavo la person
					var tutorPerson = tutorWfItemElement.getPersonMap().get("contributorId");	//restituisce la person completa?
					tutorPerson = gaService.getPerson(tutorPerson.getId());	//nel dubbio la ricavo dal service
					
					//ora che ho la persona, ne vado a ricavare gli element di incoming che mi servono
					var incomingPersonElementSet = tutorPerson.getPersonElementSet("incoming");
					var incomingPersonElementSetIterator = incomingPersonElementSet.iterator();

					
					//vado a ciclare il set per vedere se quell'element esiste già
					//se esiste già, lo rimuovo
					//e dopo ne aggiungo uno nuovo nuovo appena creato
					while(incomingPersonElementSetIterator.hasNext()){
						
						var  incomingPersonElement = incomingPersonElementSetIterator.next();

						var  incomingPersonElementSourceIdentifier = incomingPersonElement.getStringMap().get("apItemSourceIdentifier");
						var  incomingPersonElementSourceId = incomingPersonElement.getIntegerMap().get("apItemSourceId");
						
						//doppio controllo, così gestisco il caso in cui l'item non abbia un identifier come può succedere se proviene da tabelle di frontiera
						if(Packages.org.apache.commons.lang.StringUtils.equals(wfItemIdentifier, incomingPersonElementSourceIdentifier) || (wfItemId==incomingPersonElementSourceId) ){
							//così lo tolgo dal set che contiene tutti i personElement
							tutorPerson.getPersonElementSet().remove(incomingPersonElement);
							//mentre così lo vado ad eliminare da db
							gaService.deletePersonElement(incomingPersonElement.getId());
							//ed ora salvo la person per accertarmi che sia stato eliminato
							gaService.saveOrUpdate(tutorPerson);
							//log.error("delete old personelement");
						}
					}

					//ora che mi sono accertato che per certo non ho quel personElement, me ne vado a creare uno completamente nuovo ed aggiornato
					//log.error("new person element");
					var newPersonElementIncoming = Packages.it.cilea.ga.model.PersonElement();
				
					//ed ora passo ad agganciarci tutte le informazioni che gli servono
					newPersonElementIncoming.setPersonId(tutorPerson.getPersonId());
					//newPersonElementIncoming.setPerson(tutorPerson);
					newPersonElementIncoming.setDiscriminator("incoming");
					newPersonElementIncoming.getPersonMap().put("tutoree", wfItem.getPersonMap().get("owner"));
					
					//visto che il miurExternalOrganization è un element ma unico, ricavo il primo elemento e da lì il tutto
					var miurExternalOrganizationUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement","miurExternalOrganization", wfService);
					//controllo ulteriore nel caso in cui cambino le validazioni e non sia più obbligatorio
					if(!miurExternalOrganizationUnitSet.isEmpty()){
						var miurExternalOrganizationUnit = miurExternalOrganizationUnitSet.iterator().next().getOrganizationUnitMap().get("externalOrganization");
						//var miurExternalOrganizationUnit = wfItem.getWfItemElementSet("miurExternalOrganization").first().getOrganizationUnitMap().get("externalOrganization");
						newPersonElementIncoming.getOrganizationUnitMap().put("miurExternalOrganization", miurExternalOrganizationUnit);
					}
					
					newPersonElementIncoming.getStringMap().put("apItemSourceIdentifier", wfItemIdentifier);
					newPersonElementIncoming.getIntegerMap().put("apItemSourceId", wfItemId);
					
					if(tutorWfItemElement.getDateMap().get("startDate")!=null)
						newPersonElementIncoming.getDateMap().put("startDate", tutorWfItemElement.getDateMap().get("startDate"));
					if(tutorWfItemElement.getDateMap().get("endDate")!=null)
						newPersonElementIncoming.getDateMap().put("endDate", tutorWfItemElement.getDateMap().get("endDate"));
					
					//gestione dictionary
					var incomingTypeDescription = wfItem.getWfItemType().getDescription();
					var incomingTypeDictionary = obtainIncomingTypeDictionary(incomingTypeDescription);
					newPersonElementIncoming.getDictionaryMap().put("incomingType", incomingTypeDictionary);
					
					//aggiungo metadato per marcare come è stato gestito
					newPersonElementIncoming.getStringMap().put("managedBy", "system");
					
					//ora che è completo, vado a salvarlo
					gaService.saveOrUpdate(newPersonElementIncoming);
					
					//lo aggiungo alla person e salvo la person
					tutorPerson.getPersonElementSet().add(newPersonElementIncoming);
					gaService.saveOrUpdate(tutorPerson);
					//log.error("Saved person");
	
				}//tutorWfItemElementSetIterator
				
			}//fine tutorWfItemElementSet.isEmpty
			
		

deletePersonElementLinked

		
			//è identica alla logica che li creare
			//qua a me serve solo eliminarli
			//log.error("deletePersonElementLinked");
			//prima di tutto ricavo l'oggetto completo, già salvato
			var wfItem = wfService.getWfItem(object.getId());
			
			//ora ricavo tutte le info che mi serviranno più tardi

			//inizio a ricavare l'identificativo numerico
			//potrei non creare una variabile apposta, ma così è più chiaro
			var wfItemId = wfItem.getId();
			//e poi quello testuale
			var wfItemIdentifier = wfItem.getIdentifier();

			//poi vado a ricavare tutti i tutor inseriti
			//var tutorWfItemElementSet = wfItem.getWfItemElementSet("tutor");	//restituisce sempre un oggetto, mai null
			var tutorWfItemElementSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement","tutor", wfService)

			//solo se ne trovo, allora eseguo il resto della procedura			
			if(!tutorWfItemElementSet.isEmpty()){
				//ora per vado a ciclare ogni wfItemElement, ricavando poi la persona collegata
				var tutorWfItemElementSetIterator = tutorWfItemElementSet.iterator();
				while(tutorWfItemElementSetIterator.hasNext()){
					var tutorWfItemElement = tutorWfItemElementSetIterator.next();
					
					//ora ricavo la person
					var tutorPerson = tutorWfItemElement.getPersonMap().get("contributorId");	//restituisce la person completa?
					tutorPerson = gaService.getPerson(tutorPerson.getId());	//nel dubbio la ricavo dal service
					
					//ora che ho la persona, ne vado a ricavare gli element di incoming che mi servono
					var incomingPersonElementSet = tutorPerson.getPersonElementSet("incoming");
					var incomingPersonElementSetIterator = incomingPersonElementSet.iterator();

					
					//vado a ciclare il set per vedere se quell'element esiste già
					//se esiste già, lo rimuovo
					//e dopo ne aggiungo uno nuovo nuovo appena creato
					while(incomingPersonElementSetIterator.hasNext()){
						
						var  incomingPersonElement = incomingPersonElementSetIterator.next();

						var  incomingPersonElementSourceIdentifier = incomingPersonElement.getStringMap().get("apItemSourceIdentifier");
						var  incomingPersonElementSourceId = incomingPersonElement.getIntegerMap().get("apItemSourceId");
						
						//doppio controllo, così gestisco il caso in cui l'item non abbia un identifier come può succedere se proviene da tabelle di frontiera
						if(Packages.org.apache.commons.lang.StringUtils.equals(wfItemIdentifier, incomingPersonElementSourceIdentifier) || (wfItemId==incomingPersonElementSourceId) ){
							//così lo tolgo dal set che contiene tutti i personElement
							tutorPerson.getPersonElementSet().remove(incomingPersonElement);
							//mentre così lo vado ad eliminare da db
							gaService.deletePersonElement(incomingPersonElement.getId());
							//ed ora salvo la person per accertarmi che sia stato eliminato
							gaService.saveOrUpdate(tutorPerson);
							//log.error("delete old personelement");
						}
					}
				}//tutorWfItemElementSetIterator
			}//fine tutorWfItemElementSet.isEmpty
			
		

wfStartLogicPatent

			var applicationNumber=wfItem.getStringMap().get("applicationNumber");
			wfItem.setIdentifier(applicationNumber);
			
			var applicationDate=wfItem.getDateMap().get("applicationDate");
			var year=applicationDate.get(Packages.java.util.Calendar.YEAR);
			wfItem.setYear(year);
			
			if(Packages.java.lang.Boolean.FALSE.equals(wfItem.getBooleanMap().get("recoveryMetadataFromEPO"))){
				var linkedInventionId = wfItem.getIntegerMap().get("linkedInventionId");
			
				var linkedInvention = wfService.getWfItem(linkedInventionId);
				
				var inventionIprLink = new Packages.it.cilea.wf.model.WfItemLink();
				
				inventionIprLink.setParentId(linkedInventionId);
				inventionIprLink.setChildId(wfItem.getId());
				inventionIprLink.setDiscriminator("inventionIprLink");
				
				var parentWfItemLinkSet = wfItem.getParentWfItemLinkSet();
				parentWfItemLinkSet.add(inventionIprLink);
				wfItem.setParentWfItemLinkSet(parentWfItemLinkSet);
								
				wfItem.getIntegerMap().put("linkedInventionId", null);				
				wfService.saveOrUpdate(inventionIprLink);				
			}
			wfService.saveOrUpdate(wfItem);
			
		

wfActionLogicSaveRPDFV3Evaluation

it.cilea.wf.surplus.logic.action.save.rpdf.WfActionLogicSaveRPDFV3Evaluation

isNotLegacyAndYearIsGreaterOrEqualThan2019Project
Questa è un'applicability rule che viene valutata prima di eseguire altre validazioni.
Se ritorna true allora vengono eseguite le altre validazioni altrimenti no.
Oltre al check previsto da isNotLegacy , verifica anche che il progetto in questione sia relativo ad un anno maggiore o uguale del 2019, altrimenti vengono disattivate le validazioni e le sincronizzazioni.
Questo approccio è stao scelto per evitare lo scatenarsi delle validazioni su vecchi progetti che non rispettano le nuove e più stringenti validazioni, ed evitare quindi di dovere fare una bonifica a tappeto.

			log.error("Sono in isNotLegacyAndYearIsGreaterOrEqualThan2019Project");
			(
				object.getYear()!=null 
				&& 
				object.getYear().compareTo(2019)>=0
			) 
			&& 
			(
				object.getBooleanMap().get('legacy')==null 
				|| 
				Packages.java.lang.Boolean.FALSE.equals(object.getBooleanMap().get('legacy'))
			)
		

wfStartLogicProject
Questa logica viene eseguita in fase di creazione di un nuovo progetto.
Vengono effettuate le seguenti operazioni:

Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

					
								
				var person=null;
				var startDate=wfItem.getDateMap().get("proposalStartDate");			
			    person=wfItem.getPersonMap().get("owner");			
				var person2 = gaService.getPerson(person.getId());
				var ownerElement=new Packages.it.cilea.wf.model.WfItemElement();
				ownerElement.setDiscriminator("owner");
				ownerElement.setWfItemId(wfItem.getId());
				ownerElement.getPersonMap().put("ownerId", person);				
		
				wfService.saveOrUpdate(ownerElement);
				wfItem.getWfItemElementSet().add(ownerElement);				
				
				var positionLastSet = person2.getPositionLastSet();											
				var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(positionLastSet, "research", "department");
				//var maxPriority2 = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(positionSet, "research", "academicField2000");
				
				
				positionLastSetIterator=positionLastSet.iterator();											
				while (positionLastSetIterator.hasNext()){
					var position=positionLastSetIterator.next();
					if (maxPriority == null || maxPriority.equals(position.getPriority())) {
						if ("research".equals(position.getDiscriminator()) && "department"
									.equals(position.getOrganizationUnit().getOrganizationUnitType().getDescription())) {
							var internalOrganizationUnitElement=new Packages.it.cilea.wf.model.WfItemElement();
							internalOrganizationUnitElement.setDiscriminator("internalOrganizationUnit");
							internalOrganizationUnitElement.setWfItemId(wfItem.getId());
							var internalOrganizationUnitRoleId = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.internalOrganizationUnit.role.main");
							var internalOrganizationUnitRole = wfService.getWfDictionary(new Packages.java.lang.Integer(internalOrganizationUnitRoleId));
							internalOrganizationUnitElement.getOrganizationUnitMap().put("ouId", position.getOrganizationUnit());
							internalOrganizationUnitElement.getWfDictionaryMap().put("ouRole", internalOrganizationUnitRole);						
							wfService.saveOrUpdate(internalOrganizationUnitElement);
							wfItem.getWfItemElementSet().add(internalOrganizationUnitElement);
							break;
						}
					}
				}
								
				//partner
				var uniquePartnerRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.uniquePartner");
				var myOrganization=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.myOrganization");
				if (uniquePartnerRoleId==null || myOrganization==null){
					throw "Configuration variables ap.project.partner.role.uniquePartner and ap.project.partner.myOrganization MUST BE DEFINED";
				} else {
					uniquePartnerRoleId=wfService.getWfDictionary(new Packages.java.lang.Integer(uniquePartnerRoleId));				
					myOrganization=gaService.getOrganizationUnit(new Packages.java.lang.Integer(myOrganization));
					var partnerElement=new Packages.it.cilea.wf.model.WfItemElement();
					partnerElement.setDiscriminator("partner");
					partnerElement.setWfItemId(wfItem.getId());
					partnerElement.getOrganizationUnitMap().put("partnerId", myOrganization);
					partnerElement.getWfDictionaryMap().put("partnerRole", uniquePartnerRoleId);
					wfService.saveOrUpdate(partnerElement);				
				}
			
				
				wfItem.getPersonMap().put("owner", null);			
				var year=startDate.get(Packages.java.util.Calendar.YEAR);			
				wfItem.setYear(new Packages.java.lang.Integer(year));			
				true;
			

wfActionLogicEnterProjectOwnerMailSender

			X={
			subjectLabel:'label.ap.project.mail.subject',
			textLabel:'label.ap.project.mail.text',
			sendEnable:'ap.project.mail.enable',
			htmlEnable:'ap.project.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleOwners',
			to:'',
			from:''
			}; X;
		

wfActionLogicEnterProjectContributorMailSender

			X={
			subjectLabel:'label.ap.project.mail.subject',
			textLabel:'label.ap.project.mail.text',
			sendEnable:'ap.project.mail.enable',
			htmlEnable:'ap.project.mail.html.enable',
			identityLogic:'wfIdentityLogicContributor',
			to:'',
			from:''
			};X;
		

wfActionLogicEnterProjectHeadOfDepartmentMailSender

			X={
			subjectLabel:'label.ap.project.mail.subject',
			textLabel:'label.ap.project.mail.text',
			sendEnable:'ap.project.mail.enable',
			htmlEnable:'ap.project.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleHeadOfDepartment',
			to:'',
			from:''
			};X;
		

wfActionLogicEnterProjectMailSender

			var mailEnableParam = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.mail.enable");
			var mailHtmlEnableParam = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.mail.html.enable");
			var isHtml;
			if(mailHtmlEnableParam.equalsIgnoreCase("true")){
				isHtml = true;
			}
			else{
				isHtml = false;
			}
			if (mailEnableParam!=null && mailEnableParam.equalsIgnoreCase("true")){
				var wfItemIdentifier = wfItem.getIdentifier();
				var wfItemDescription = wfItem.getDescription();
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				var ownerSetIterator=ownerSet.iterator();
				while(ownerSetIterator.hasNext()){
					var ownerElement=ownerSetIterator.next();
					var person = ownerElement.getPersonMap().get("ownerId");
					person = gaService.getPerson(person.getId());
					var contact=person.getPrincipalContactMap().get("mail");
					var surnameName = person.getLastName()+" "+person.getFirstName();
					var subjectLabel=messageUtil.findMessage("label.ap.project.mail.subject", [wfItemIdentifier]);
					var textLabel=messageUtil.findMessage("label.ap.project.mail.text",[wfItemIdentifier, surnameName, wfItemDescription, wfItem.getWfState().getDisplayValue()]);
					mailService.send("no-reply@cineca.it", [contact], null, null, subjectLabel, textLabel, null, isHtml);
				}
			}
		

wfUgovPjSenderValidatorProject
Questa logica, effettua check di consistenza sulle mappature degli oggetti IRIS/UGOV e, se superati, invia il progetto verso UGOV PJ rispettando le regole di NON SOVRASCRITTURA lato UGOV PJ.
Per maggiori dettagli su queste regole consultare il team di UGOV PJ.
Le controparti dei progetti IRIS vengono create su UGOV con le regole di mappature delle tassonomie che vengono condivise in fase di attivazione.
Se in corso d'opera dovesse nascere l'esigenza di censire delle nuove tipologie è possibile contattare l'HD.
Di seguito vengono riportate le informazioni inviate ad UGOV PJ, con la specifica dell'attributo del modello dell'entità Progetto IRIS


Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			var Logic = function(wfItem, dtoPj, superLogic, errors, messageUtil, request, gaService, wfService, wfTaskService, searchBuilderTemplate, log) {
			this.wfItem=wfItem;
			this.dtoPj=dtoPj;
			this.superLogic=superLogic;
			this.errors=errors;
			this.messageUtil=messageUtil;
			this.request=request;
			this.gaService=gaService;
			this.wfService=wfService;
			this.wfTaskService=wfTaskService;
			this.searchBuilderTemplate=searchBuilderTemplate;
			this.log=log;
			this.setInternalOrgUnitList = function() {
				var internalOrganizationUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);
				var internalOrganizationUnitSetIterator=internalOrganizationUnitSet.iterator();
				while (internalOrganizationUnitSetIterator.hasNext()){
					var element=internalOrganizationUnitSetIterator.next();
					var orgUnit = element.getOrganizationUnitMap().get("ouId");
					var orgUnitRole = element.getWfDictionaryMap().get("ouRole");
					dtoPj.getDTOUoPjs().add(superLogic.getOrganizationUnit(orgUnit, orgUnitRole, errors));
				}
			};			
			this.setFinanciers = function() {
				var sendGrantor2Ugov=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.grantor.send2ugov.enable");
				if (sendGrantor2Ugov && sendGrantor2Ugov.trim().equalsIgnoreCase("true")){
					var contractorSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement", "grantor",wfService);
					var contractorSetIterator=contractorSet.iterator();
					while (contractorSetIterator.hasNext()){
						var element=contractorSetIterator.next();
						var organizationUnit = element.getOrganizationUnitMap().get("grantorId");
						var enteFinanziatore = superLogic.getEnteFinanziatore(organizationUnit, this.getFinancing(), contractorSet.size(), errors);
						dtoPj.getDTOEfPjs().add(enteFinanziatore);
					}
				}
			};
			this.setPartners = function() {
				var sendPartner2Ugov=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.send2ugov.enable");
				if (sendPartner2Ugov && sendPartner2Ugov.trim().equalsIgnoreCase("true")){
					var partnerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement", "partner",wfService);
					var partnerSetIterator=partnerSet.iterator();
					while (partnerSetIterator.hasNext()){
						var element=partnerSetIterator.next();
						var organizationUnit = element.getOrganizationUnitMap().get("partnerId");
						var partnerRole = element.getWfDictionaryMap().get("partnerRole");
						var partecipante = superLogic.getPartecipante(organizationUnit,  partnerRole, errors);
						dtoPj.getDTOPartPjs().add(partecipante)
					}
				}			
			};
			this.getFinancing = function() {
				var coordinatorRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.main");
				var myOrganization=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.myOrganization");
				var forcedPjInternalCost=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.financing.internalCost.send2ugov.forced");
				if (forcedPjInternalCost==null)
					forcedPjInternalCost=false;
				else if (forcedPjInternalCost.equalsIgnoreCase("true")){				
					forcedPjInternalCost=true;
				} else {
					forcedPjInternalCost=false;
				}
				
				if (!forcedPjInternalCost){
					if (coordinatorRoleId==null || myOrganization==null){
						throw "Configuration variables ap.project.partner.role.main and ap.project.partner.myOrganization MUST BE DEFINED";
					} else {
						coordinatorRoleId=new Packages.java.lang.Integer(coordinatorRoleId);
						myOrganization=new Packages.java.lang.Integer(myOrganization);
					}		
					var partnerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement", "partner",wfService);
					var partnerSetIterator=partnerSet.iterator();
					while (partnerSetIterator.hasNext()){
						var element=partnerSetIterator.next();			 
						var orgUnitRole = element.getWfDictionaryMap().get("partnerRole");
						if (orgUnitRole==null){
							errors.reject("error.project.partner.missingRole");
							throw "Detected partner without role";
						}
						
						var orgUnit = element.getOrganizationUnitMap().get("partnerId");
						if(myOrganization.equals(orgUnit.getId()) && coordinatorRoleId.equals(orgUnitRole.getId())){				
							var globalCost=wfItem.getNumberMap().get("globalCost");
							if (globalCost==null)
								globalCost=Packages.java.math.BigDecimal.ZERO;
							
							var globalContribution=wfItem.getNumberMap().get("globalContribution");
							if (globalContribution==null)
								globalContribution=Packages.java.math.BigDecimal.ZERO;
							
							var internalCofinancing=wfItem.getNumberMap().get("internalCofinancing");
							if (internalCofinancing==null)
								internalCofinancing=Packages.java.math.BigDecimal.ZERO;
							
							return globalCost.subtract(globalCost.subtract(globalContribution).subtract(internalCofinancing));
						}			
					}
				}				
				return wfItem.getNumberMap().get("internalCost");
			};
			this.getStartDate = function() {
				var expenditureDateEnabled=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.date.expenditure.send2ugov.enabled");
				if (expenditureDateEnabled && expenditureDateEnabled.trim().equalsIgnoreCase("true")){
					if (wfItem.getDateMap().get("expenditureStartDate")!=null)
						return wfItem.getDateMap().get("expenditureStartDate");
					else
						return wfItem.getDateMap().get("startDate");
				} else {
					return wfItem.getDateMap().get("startDate");
				}							    	
			};
			this.getEndDate = function() {
				var expenditureDateEnabled=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.date.expenditure.send2ugov.enabled");
				if (expenditureDateEnabled && expenditureDateEnabled.trim().equalsIgnoreCase("true")){
					if (wfItem.getDateMap().get("expenditureEndDate")!=null)
						return wfItem.getDateMap().get("expenditureEndDate");
					else
						return wfItem.getDateMap().get("endDate");
				} else {
					return wfItem.getDateMap().get("endDate");
				}		
			};
			this.getIdentifier = function() {	
				return wfItem.getIdentifier();
			};
			this.getDescription = function() {
				if(wfItem.getDescription()!=null){
					var length=wfItem.getDescription().length();
					return wfItem.getDescription().substring(0,(length>255)?255:length);
				} else {
					return null;
				}
			};
			this.getCup = function() {
				var sendCup2Ugov = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.cup.send2ugov.enable");
				if (sendCup2Ugov && sendCup2Ugov.trim().equalsIgnoreCase("true")){
					return wfItem.getStringMap().get("cup");
				} else {
					return null;
				}				
			};
			this.getAcronym = function() {
				return wfItem.getStringMap().get("acronym");
			};
			this.getExternalDmsIdentifier = function() {
				return wfItem.getStringMap().get("externalDmsIdentifier");
			};
			this.isSynchronizable = function() {
				var legacy=wfItem.getBooleanMap().get("legacy");
				var financing=this.getFinancing();				
				if (Packages.java.lang.Boolean.TRUE.equals(legacy) || financing==null || Packages.java.math.BigDecimal.ZERO.equals(financing))
					return Packages.java.lang.Boolean.FALSE;
				else			    
					return Packages.java.lang.Boolean.TRUE;
			};
			this.getProjectType = function() {
				return superLogic.getProjectType(wfItem);
			};
			this.getFinanceSchema = function() {
				return this.getProjectType();
			};
			this.getPjInternalCode = function() {
				return null;
			};
			this.isContributorStartDateRequired = function() {						
				var contributorStartDateRequired=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.contributor.starDate.required");
				if (contributorStartDateRequired){
					if (contributorStartDateRequired.trim().equalsIgnoreCase("true")){
						return Packages.java.lang.Boolean.TRUE;
					} else if (contributorStartDateRequired.trim().equalsIgnoreCase("false")){
						return Packages.java.lang.Boolean.FALSE;
					} else {
						throw "ap.project.contributor.starDate.required MUST BE true or false";
					}
				} else {
					return Packages.java.lang.Boolean.TRUE;
				}							    
			};				
			this.isOwnerStartDateRequired = function() {
				var ownerStartDateRequired=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.owner.starDate.required");
				if (ownerStartDateRequired){
					if (ownerStartDateRequired.trim().equalsIgnoreCase("true")){
						return Packages.java.lang.Boolean.TRUE;
					} else if (ownerStartDateRequired.trim().equalsIgnoreCase("false")){
						return Packages.java.lang.Boolean.FALSE;
					} else {
						throw "ap.project.owner.starDate.required MUST BE true or false";
					}
				} else {
					return Packages.java.lang.Boolean.TRUE;
				}
			};
		};
		new Logic(wfItem, dtoPj, superLogic, errors, messageUtil, request, gaService, wfService, wfTaskService, searchBuilderTemplate, log);
		

ethicCommiteeDeleteInconsistentDataProject
Questa validazione controlla che se non sono previste attività di ricerca che prevedono sperimentazioni passibili di giudizio da parte del Comitato Etico
e controlla che se non E' stata presentata la richiesta di parere all'OPBA o al Comitato Etico di Ateneo di riferimento o al Comitato Etico di un Ente Terzo che ha facoltà di concedere questo tipo di autorizzazioni.
I dati particolari di queste sottosezioni vengono svuotati se viene selezionato NO.
Dal punto di vista del modello dati si tratta degli elementi di tipo ethicCommiteeTopic
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

		//questa funzione elimina tutti i dati del tab, tranne ovviamente ethicCommiteeApplicability
		//viene chiamata quando non è applicabile
		function deleteAll(){
			
			//dati riguardanti il topic
			var wfItemElementSet = object.getWfItemElementSet();
			var ethicCommiteeTopicSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "ethicCommiteeTopic", wfService);
			
			var ethicCommiteeTopicSetIterator=ethicCommiteeTopicSet.iterator();
			while(ethicCommiteeTopicSetIterator.hasNext()){
				var wfItemElement=ethicCommiteeTopicSetIterator.next();
				
				var ethicCommiteeTopic= wfItemElement.getWfDictionaryMap().get("ethicCommiteeTopicId");
				var description= ethicCommiteeTopic.getDescription();
				//log.error("Topic description (ethicCommiteeTopicSet): "+description);
				
				wfService.deleteWfItemElement(wfItemElement.getId());
				//log.error("Eliminato con wfService");
				
				wfItemElementSet.remove(wfItemElement);
				//log.error("Eliminato dal set");
			}
			
			object.setWfItemElementSet(wfItemElementSet);
			//log.error("Sostituito set con nuovo");
			
			//dati riguardanti l'autorizzazione
			//log.error("ethicCommiteeSubmitted: "+object.getBooleanMap().get("ethicCommiteeSubmitted"));
			object.getBooleanMap().put("ethicCommiteeSubmitted", null);
			
			//log.error("ethicCommiteeSubmitDate: "+object.getDateMap().get("ethicCommiteeSubmitDate"));
			object.getDateMap().put("ethicCommiteeSubmitDate", null);
			
			//log.error("ethicCommiteeAuthorization: "+object.getWfDictionaryMap().get("ethicCommiteeAuthorization"));
			object.getWfDictionaryMap().put("ethicCommiteeAuthorization", null);
			
			deleteAuthorizationData();
		}
		
		//questa funzione elimina i dati riguardanti l'autorizzazione
		//viene chiamata quando non viene concessa
		function deleteAuthorizationData(){
			//log.error("ethicCommiteeAuthorizationNumber: "+object.getNumberMap().get("ethicCommiteeAuthorizationNumber"));
			object.getNumberMap().put("ethicCommiteeAuthorizationNumber", null);
			
			//log.error("ethicCommiteeAuthorizationDate: "+object.getDateMap().get("ethicCommiteeAuthorizationDate"));
			object.getDateMap().put("ethicCommiteeAuthorizationDate", null);
			
			//log.error("ethicCommiteeAuthorizationOrganization: "+object.getOrganizationUnitMap().get("ethicCommiteeAuthorizationOrganization"));
			var orgUnitMap=object.getOrganizationUnitMap().put("ethicCommiteeAuthorizationOrganization", null);
			
			wfService.saveOrUpdate(object);
			//log.error("SALVATO!");
		}
		
		//quando elimino da una mappa, non mi importa gestire se fosse popolata o meno
		//al massimo il remove mi restituisce null
		
		//log.error("Sono nel ethicCommiteeDeleteInconsistentData");
		
		//prima di tutto vado a vedere ethicCommiteeApplicability
		//SE NON E' SI (true), allora cancello tutti i dati sottostanti
		
		var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
		if (ethicCommiteeApplicability!=true){
			//chiamo la funzione per eliminare tutto
			deleteAll();
		}else{
			//non mi interessa ethicCommiteeSubmitted, deve essere per forza true se sono qui
			
			//SE E' SI, allora vado a vedere ethicCommiteeAuthorization
			var ethicCommiteeAuthorization= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
			
			//SE NON E' SPECIFICATO (null) O 'NON CONCESSO', allora cancello i dati relativi
			//TRANNE la data di presentazione
			//ci può essere il caso che sia stata fatta la richiesta e si stia aspettando il responso
			
			//non specificato, caso per evitare eccezioni
			if(ethicCommiteeAuthorization==null){
				deleteAuthorizationData();
			}else{
				var ethicCommiteeAuthorizationDescription= wfService.getWfDictionary(ethicCommiteeAuthorization.getId()).getDescription();
				if (!Packages.org.apache.commons.lang.StringUtils.equals("Concessa", ethicCommiteeAuthorizationDescription)){
					deleteAuthorizationData();
				}
			}
		}	
		

ownerValidatorProject
Questa validazione controlla che esista almeno un responsabile scientifico nel tab "Soggetti interni".
Dal punto di vista del modello dati si tratta degli elementi di tipo owner
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

		
			if (object.getId()==null){
				if (object.getPersonMap().get("owner")==null)
					errors.rejectValue("personMap[owner]","error.project.owner.required");
			} else {
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				if (
				!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))
				&&
				ownerSet.size()<1 
				&& 
				object.getPersonMap().get("owner")==null
				)
					errors.reject("error.project.owner.atLeast1");
			}
		

ownerValidatorWithStartEndDateProject
Questa validazione opera sugli elementi owner (responsabile scientifico) figli dell'oggetto radice.
Viene verificato che esista almeno un responsabile scientifico e, se specificato un intervallo di validità per il singolo owner, viene verificato che sia compreso all'interno della validità dell'oggetto padre.
Gli attributi per le date di inizio e fine sono startDate e endDate sia per l'elemento owner che per l'oggetto padre.

			if (object.getId()==null){
				if (object.getPersonMap().get("owner")==null)
					errors.rejectValue("personMap[owner]","error.project.owner.required");
			} else {
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){
					if (ownerSet.size()<1 && object.getPersonMap().get("owner")==null)
						errors.reject("error.project.owner.atLeast1");
						
					var ownerSetIterator=ownerSet.iterator();
					
					var wfItemStartDate=object.getDateMap().get("startDate");
					var wfItemEndDate=object.getDateMap().get("endDate");
					var formatter =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
					var ownerWithWrongInterval=[];
								
					while (ownerSetIterator.hasNext()){										
						var owner=ownerSetIterator.next();
						var wfItemElementStartDate=owner.getDateMap().get("startDate");
						
						if( wfItemElementStartDate!= null && wfItemStartDate && (wfItemElementStartDate.before(wfItemStartDate) || (wfItemEndDate!=null && wfItemElementStartDate.after(wfItemEndDate)))  ){
							ownerWithWrongInterval.push(owner.getPersonMap().get("ownerId").getDisplayValue());
						}								
					}
					
					if (ownerWithWrongInterval.length>0){
						errors.reject("error.project.owner.wrongInterval", [ownerWithWrongInterval.toString()], "error.project.owner.wrongInterval");
					}
				}
			}
		

organizationUnitValidatorProject
Questa validazione controlla che esista almeno una unità organizzativa interna nel tab "Soggetti interni".
Dal punto di vista del modello dati si tratta degli elementi di tipo internalOrganizationUnit
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
				if (orgUnitSet.size()<1)
					errors.reject("error.project.multipleInternalOrganization.atLeast1");		
			}
		

ethicCommiteeApplicabilityValidatorProject

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){		
				var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
				if(ethicCommiteeApplicability == null){
					errors.reject("error.project.ethicCommiteeApplicability.required");
				}
			}
		

ethicCommiteeTopicValidatorProject
Questa validazione controlla che esista almeno un Comitato Etico nel tab "Comitato Etico".
Dal punto di vista del modello dati si tratta degli elementi di tipo ethicCommiteeTopic
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			
			//log.error("Sono nel ethicCommiteeTopicValidatorProject");
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
				if (ethicCommiteeApplicability==true){
					//log.error("ethicCommiteeApplicability è true")
					//var ethicCommiteeTopicSet= object.getWfItemElementSet("ethicCommiteeTopic");
					var ethicCommiteeTopicSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "ethicCommiteeTopic", wfService);
					if(ethicCommiteeTopicSet.isEmpty()){
						//log.error("Nessun topic!");
						errors.reject("error.project.ethicCommiteeTopic.atLeast1");
					}	
				}
			}
		

ethicCommiteeSubmittedValidatorProject
Questa validazione controlla che deve essere stata presentata la richiesta di parere all'OPBA o al Comitato Etico di Ateneo di riferimento o al Comitato Etico di un Ente Terzo che ha facoltà di concedere questo tipo di autorizzazioni nel tab "Comitato Etico".
Dal punto di vista del modello dati si tratta degli elementi di tipo ethicCommiteeTopic
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

	
			//log.error("Sono nel ethicCommiteeSubmittedValidatorProject");		
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
				if (ethicCommiteeApplicability==true){
					//log.error("ethicCommiteeApplicability è true")
					var ethicCommiteeSubmitted= object.getBooleanMap().get("ethicCommiteeSubmitted");
					if(ethicCommiteeSubmitted!=true){
						//log.error("ethicCommiteeSubmitted è falso!");
						errors.reject("error.project.ethicCommiteeSubmitted.required");
					}	
				}
			}
		

ethicCommiteeAuthorizationNumberValidatorProject
Questa validazione controlla che se l'autorizzazione del Comitato Etico è stata concessa, deve essere presente il relativo numero identificativo nel tab "Comitato Etico".
Dal punto di vista del modello dati si tratta degli elementi di tipo ethicCommiteeTopic
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

	
			//log.error("Sono nel ethicCommiteeAuthorizationNumberValidatorProject");
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
				//prima di tutto si deve attivare solo se ethicCommiteeApplicability è su true
				if (ethicCommiteeApplicability==true){
					
					var ethicCommiteeSubmitted = object.getBooleanMap().get("ethicCommiteeSubmitted");
					//poi solo se ethicCommiteeSubmitted è su true
					if(ethicCommiteeSubmitted==true){
					
						var ethicCommiteeAuthorizationDictionary= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
						
						if(ethicCommiteeAuthorizationDictionary!=null){
						
							var ethicCommiteeAuthorizationDictionaryDescription= wfService.getWfDictionary(ethicCommiteeAuthorizationDictionary.getId()).getDescription();
							
							if (ethicCommiteeAuthorizationDictionaryDescription.equals("Concessa")){
								//se concessa allora il validator si deve attivare
								var ethicCommiteeAuthorizationNumber = object.getNumberMap().get("ethicCommiteeAuthorizationNumber");
								if(ethicCommiteeAuthorizationNumber==null){
									errors.reject("error.project.ethicCommiteeAuthorizationNumber.requiredIfGranted");
								}
							}
						}
					}
				}
			}
		

ethicCommiteeAuthorizationDateValidatorProject
Questa validazione controlla che se l'autorizzazione del Comitato Etico è stata concessa, deve essere presente la relativa data di concessione nel tab "Comitato Etico".
Dal punto di vista del modello dati si tratta degli elementi di tipo ethicCommiteeTopic
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

	
			//log.error("Sono nel ethicCommiteeAuthorizationDateValidatorProject");
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
				//prima di tutto si deve attivare solo se ethicCommiteeApplicability è su true
				if (ethicCommiteeApplicability==true){
					
					var ethicCommiteeSubmitted = object.getBooleanMap().get("ethicCommiteeSubmitted");
					//poi solo se ethicCommiteeSubmitted è su true
					if(ethicCommiteeSubmitted==true){
					
						var ethicCommiteeAuthorizationDictionary= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
						
						if(ethicCommiteeAuthorizationDictionary!=null){
						
							var ethicCommiteeAuthorizationDictionaryDescription= wfService.getWfDictionary(ethicCommiteeAuthorizationDictionary.getId()).getDescription();
							
							if (ethicCommiteeAuthorizationDictionaryDescription.equals("Concessa")){
								//se concessa allora il validator si deve attivare
								var ethicCommiteeAuthorizationDate = object.getDateMap().get("ethicCommiteeAuthorizationDate");
								if(ethicCommiteeAuthorizationDate==null){
									errors.reject("error.project.ethicCommiteeAuthorizationDate.requiredIfGranted");
								}
							}
						}
					}
				}
			}
		

ethicCommiteeAuthorizationOrganizationValidatorProject
Questa validazione controlla che Se l'autorizzazione è stata concessa, deve essere presente l'ente che l'ha concessa nel tab "Comitato Etico".
Dal punto di vista del modello dati si tratta degli elementi di tipo ethicCommiteeTopic
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

	
			//log.error("Sono nel ethicCommiteeAuthorizationOrganizationValidatorProject");
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
				//prima di tutto si deve attivare solo se ethicCommiteeApplicability è su true
				if (ethicCommiteeApplicability==true){
					
					var ethicCommiteeSubmitted = object.getBooleanMap().get("ethicCommiteeSubmitted");
					//poi solo se ethicCommiteeSubmitted è su true
					if(ethicCommiteeSubmitted==true){
					
						var ethicCommiteeAuthorizationDictionary= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
						
						if(ethicCommiteeAuthorizationDictionary!=null){
						
							var ethicCommiteeAuthorizationDictionaryDescription= wfService.getWfDictionary(ethicCommiteeAuthorizationDictionary.getId()).getDescription();
							
							if (ethicCommiteeAuthorizationDictionaryDescription.equals("Concessa")){
								//se concessa allora il validator si deve attivare
								var ethicCommiteeAuthorizationOrganization = object.getOrganizationUnitMap().get("ethicCommiteeAuthorizationOrganization");
								if(ethicCommiteeAuthorizationOrganization==null){
									errors.reject("error.project.ethicCommiteeAuthorizationOrganization.requiredIfGranted");
								}
							}
						}
					}
				}
			}
		

organizationUnitRoleValidatorProject
Questa validazione controlla che esista almeno una unità organizzativa interna, se esiste un ruolo principale deve essere definito.
Ci deve essere uno e un solo ruolo Principale (Main)
Dal punto di vista del modello dati si tratta degli elementi di tipo internalOrganizationUnit
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
				if (orgUnitSet.size()<1){
					errors.reject("error.project.multipleInternalOrganization.atLeast1");
				} else {
					var internalOrganizationUnitCoordinatorRole=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.internalOrganizationUnit.role.main");
					if (!internalOrganizationUnitCoordinatorRole){
						throw "Configuration variable ap.project.internalOrganizationUnit.role.main MUST BE DEFINED"; 								
					} else {
						internalOrganizationUnitCoordinatorRole=new Packages.java.lang.Integer(internalOrganizationUnitCoordinatorRole);
					}
					var orgUnitSetIterator=orgUnitSet.iterator();
					var count=0;											
					while (orgUnitSetIterator.hasNext()){											
						var element=orgUnitSetIterator.next();												
						var ouRole=element.getWfDictionaryMap().get("ouRole");
						if (ouRole!=null && internalOrganizationUnitCoordinatorRole.equals(ouRole.getId())){
							count++;	
						}												
					}
					if (count==0){
						errors.reject("error.project.multipleInternalOrganization.missingMain");
					}
					else if (count>1) {
						errors.reject("error.project.multipleInternalOrganization.tooManyMain");
					}
			} 		
		}
		

ownerAndOrganizationUnitMatchValidatorProject
Questa validazione controlla che esista per ogni responsabile scientifico del progetto, una unità organizzativa che sia interna nel momento della data di avvio del progetto (startDate) oppure se non c'è questa data in questo momento.
dal punto di vista del modello sono dei dati di tipo: internalOrganizationUnit, owner
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);				
				var ownerDepartmentSet=new Packages.java.util.HashSet();				
				var internalOrganizationUnitSet=new Packages.java.util.HashSet();
				
				var startDateFromWfItem=wfItem.getDateMap().get("startDate");
				if (startDateFromWfItem!=null){
					startDateFromWfItem=startDateFromWfItem.getTime();	
					if (ownerSet.size()>0){
						var ownerSetIterator=ownerSet.iterator();			
						while (ownerSetIterator.hasNext()){
							var ownerElement=ownerSetIterator.next();			
							var person=ownerElement.getPersonMap().get("ownerId");
							
							var ownerDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
							ownerDepartmentPositionSearch.setPersonId(person.getId());
							ownerDepartmentPositionSearch.setDate(startDateFromWfItem);
							ownerDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
							ownerDepartmentPositionSearch.setDiscriminator("research");							
							var ownerDepartmentPositionSet = gaService.getPositionSearchList(ownerDepartmentPositionSearch, 0);
							var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(ownerDepartmentPositionSet, "research", "department");
							
							var ownerDepartmentPositionSetIterator=ownerDepartmentPositionSet.iterator();							
							while (ownerDepartmentPositionSetIterator.hasNext()){
								var position=ownerDepartmentPositionSetIterator.next();
								if (maxPriority == null || maxPriority.equals(position.getPriority())) {
									ownerDepartmentSet.add(position.getOrganizationUnit());														
									break;
								}
							}
						}
					}
					if (ownerDepartmentSet.size()>0){
						if (orgUnitSet.size()>0){
				 			var orgUnitSetIterator=orgUnitSet.iterator();			
							while (orgUnitSetIterator.hasNext()){											
								var wfItemElement=orgUnitSetIterator.next();												
								var orgUnit=wfItemElement.getOrganizationUnitMap().get("ouId");
								internalOrganizationUnitSet.add(orgUnit);
							}
						}
					}
					
					if(!internalOrganizationUnitSet.containsAll(ownerDepartmentSet)){
						var nonMatchedDepartmentCollection=Packages.org.apache.commons.collections.CollectionUtils.subtract(ownerDepartmentSet, internalOrganizationUnitSet);
						var nonMatchedDepartmentCollectionIterator=nonMatchedDepartmentCollection.iterator();
						var nonMatchedDepartmentString="";
						var counter=0;
						while(nonMatchedDepartmentCollectionIterator.hasNext()){
							var nonMatchedDepartment=nonMatchedDepartmentCollectionIterator.next();
							if (counter++>0)
								nonMatchedDepartmentString+=", ";
							nonMatchedDepartmentString+=nonMatchedDepartment.getDescription();
						}
						var df =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
						var dateAsString=df.format(startDateFromWfItem);
						errors.reject("error.project.multipleInternalOrganization.matchWithDepartmentOwnerNotFound", [dateAsString, nonMatchedDepartmentString], null);
					}
				}
			}
		

grantorValidatorProject
Questa validazione controlla che esista almeno un ente finanziatore nel tab "Dati generali".
Dal punto di vista del modello dati si tratta degli elementi di tipo grantor
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){							
				var grantorSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "grantor", wfService);
				if (grantorSet.size()<1)
					errors.reject("error.project.grantor.atLeast1");
			}			
		

grantorApprovalDateValidatorProject

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var grantorApprovalDateFound=false;						
				var approvalSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "approval", wfService);
				var approvalSetIterator=approvalSet.iterator();
				while(approvalSetIterator.hasNext()){
					var approval=approvalSetIterator.next();
					var approvalType=approval.getWfDictionaryMap().get("approvalType");
					if (approvalType!=null && "approvalType.grantor".equals(approvalType.getInternalSourceIdentifier()) && approval.getDateMap().get("approvalDate")!=null){
						grantorApprovalDateFound=true;
						break;
					}					
				}
				if (!grantorApprovalDateFound){
					errors.reject("error.project.grantorApprovalDate.required");
				}			
			}			
		

administrativeOwnerValidatorProject
Questa validazione controlla che esista almeno un referente amministrativo nel tab "Soggetti interni".
Dal punto di vista del modello dati si tratta degli elementi di tipo administrativeOwner
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){						
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "administrativeOwner", wfService);
				if (ownerSet.size()<1)
					errors.reject("error.project.administrativeOwner.atLeast1");
			}
		

currencyAndInternalContributionValidatorProject
Questa validazione controlla che nel tab "Finanziamento", nel caso di selezione di valuta diversa da EURO, vengano specificati


Dal punto di vista del modello dati si tratta degli attributi:

Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){	
				var currency = object.getWfDictionaryMap().get("currency");	
				if(currency != null){			
					var currencyId = object.getWfDictionaryMap().get("currency").getId();
					var dictionary = wfService.getWfDictionary(currencyId);
					var currencyCode = dictionary.getStringMap().get("code");
					
					if (currencyCode != "currency.eur"){
						if (!object.getNumberMap().get("internalContributionOriginalCurrency")){       										
							errors.rejectValue("numberMap[internalContributionOriginalCurrency]","error.project.funding.internalContributionOriginalCurrency.required");									
						}
						if (!object.getNumberMap().get("exchangeRate")){
							errors.rejectValue("numberMap[exchangeRate]","error.project.funding.exchangeRate.required");									
						}
						if (!object.getDateMap().get("exchangeRateDate")){
							errors.rejectValue("dateMap[exchangeRateDate]","error.project.funding.exchangeRateDate.required");									
						}
					}
				}
			}
		

partnerAndGlobalCostValidatorProject
Questa validazione controlla la coerenza delle informazioni inserite nel tab "Partner".
Precisamente viene verificato che:

Inoltre nel caso in cui l'Ateneo risulti Coordinatore viene imposto che siano compilati i seguenti attributi nel fieldset "Dati finanziamento assegnato" del tab "Finanziamento":

Per maggiori dettagli cfr. excel modello dati dell'entità Progetto.
Questa validazione si aspetta che siano definite le seguenti variabili di configurazione:

			
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var coordinatorRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.main");
				var uniquePartnerRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.uniquePartner");
				
				var myOrganization=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.myOrganization");
				if (coordinatorRoleId==null || myOrganization==null || uniquePartnerRoleId==null){
					throw "Configuration variables ap.project.partner.role.main, ap.project.partner.role.uniquePartner and ap.project.partner.myOrganization MUST BE DEFINED";
				} else {
					coordinatorRoleId=new Packages.java.lang.Integer(coordinatorRoleId);
					uniquePartnerRoleId=new Packages.java.lang.Integer(uniquePartnerRoleId);
					myOrganization=new Packages.java.lang.Integer(myOrganization);				
				}		
				var partnerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement", "partner",wfService);
				var partnerSetIterator=partnerSet.iterator();
				var counterOtherPartner=0;
				var counterCoordinator=0;
				var counterUniquePartner=0;
				var counterMyOrganization=0;
				while (partnerSetIterator.hasNext()){
					var element=partnerSetIterator.next();			 
					var orgUnitRole = element.getWfDictionaryMap().get("partnerRole");				
					if (orgUnitRole==null){
						errors.reject("error.project.partner.missingRole");
						break;					
					}					
					var orgUnit = element.getOrganizationUnitMap().get("partnerId");
					if (orgUnit==null){
						errors.reject("error.project.partner.missingOrgUnit");
						break;					
					}
					
					if (coordinatorRoleId.equals(orgUnitRole.getId())){
						counterCoordinator++;
					} else 	if (uniquePartnerRoleId.equals(orgUnitRole.getId())){
						counterUniquePartner++;
					} else {
						counterOtherPartner++;
					}
					
					if(myOrganization.equals(orgUnit.getId())){
						counterMyOrganization++;
					} 
					
					if(myOrganization.equals(orgUnit.getId()) && coordinatorRoleId.equals(orgUnitRole.getId())){
						
						if (!object.getNumberMap().get("globalContribution")){
							errors.rejectValue("numberMap[globalContribution]","error.project.funding.globalContribution.required");											
						}
						
						if (!object.getNumberMap().get("globalCost")){
							errors.rejectValue("numberMap[globalCost]","error.project.funding.globalCost.required");											
						}
						var currency = object.getWfDictionaryMap().get("currency");	
						if(currency != null){
							var currencyId = object.getWfDictionaryMap().get("currency").getId();
							var dictionary = wfService.getWfDictionary(currencyId);
							var currencyCode = dictionary.getStringMap().get("code");
							if (currencyCode != "currency.eur"){	
								if (!object.getNumberMap().get("globalCostOriginalCurrency")){
									errors.rejectValue("numberMap[globalCostOriginalCurrency]","error.project.funding.globalCostOriginalCurrency.required");											
								}										
								
								if (!object.getNumberMap().get("globalContributionOriginalCurrency")){
									errors.rejectValue("numberMap[globalContributionOriginalCurrency]","error.project.funding.globalContributionOriginalCurrency.required");											
								}
							}
						}
					}			
				}
				if (!errors.hasErrors()){
					if (counterCoordinator>1){									
					errors.reject("error.project.partner.tooManyMain");
					} else if (counterUniquePartner>1){									
						errors.reject("error.project.partner.tooManyUniquePartner");
					} else if (counterMyOrganization>1){
						errors.reject("error.project.partner.tooManyMyOrganization");
					} else if (partnerSet.size()>0){
						if (counterMyOrganization==0){
							errors.reject("error.project.partner.myOrganizationRequired");
						} else if (counterCoordinator>0 && counterUniquePartner>0){
							errors.reject("error.project.partner.coordinatorAndUniquePartner");
						} else if (counterOtherPartner>0 && counterCoordinator==0){
							errors.reject("error.project.partner.missingMain");
						} else if (counterOtherPartner>0 && counterUniquePartner>0){
							errors.reject("error.project.partner.otherPartnerAndUniquePartner");
						} else if (counterOtherPartner==0 && counterCoordinator>0){
							errors.reject("error.project.partner.coordinatorAndNoOtherPartner");
						}
					}
				}	
			}		
		

checkInconsistentFundingValidatorProject
Questa validazione controlla la coerenza delle informazioni di finanziamento assegnato sia per le internalOganizationUnit (unità organizzative interne) che per i partner (Partner)
Viene controllato che le somme dei costi, contributi e cofinanziamenti per internalOrganizationUnit e partner coincidano con i totali specificati a livello di progetto.
Questa validazione viene attivata SOLO se ap.project.financing.consistence.validation.enabled=true
Viene fatta anche la validazione del finanziamento richiesto se e solo se ap.project.finacing.requested.enabled=true
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto.

	
			if (Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.financing.consistence.validation.enabled").equalsIgnoreCase("true")){
				if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){		
					var checkRequested = false;
					if (!Packages.java.lang.Boolean.TRUE.equals(Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.finacing.requested.enabled"))){
						checkRequested = true;
					}
					var iouSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement", "internalOrganizationUnitCost", wfService);
					var iouSetIterator=iouSet.iterator();	 
					var cost = 0;	
					var contribution = 0;
					var cofinancing = 0;
					var cost2 = 0;	
					var contribution2 = 0;
					var cofinancing2 = 0;
					while (iouSetIterator.hasNext()){
						var element = iouSetIterator.next();	
						if(checkRequested){
							cost = +cost + +element.getNumberMap().get("ouRequestedCost");	
							contribution = +contribution + +element.getNumberMap().get("ouRequestedContribution");
							cofinancing = +cofinancing + +element.getNumberMap().get("ouRequestedCofinancing");
						}		 
						cost2 = +cost2 + +element.getNumberMap().get("ouCost");	
						contribution2 = +contribution2 + +element.getNumberMap().get("ouContribution");
						cofinancing2 = +cofinancing2 + +element.getNumberMap().get("ouCofinancing");
					}
					if(cost != 0){
						if(wfItem.getNumberMap().get("requestedInternalCost") != cost){
							errors.rejectValue("numberMap[requestedInternalCost]","error.project.internalOrganizationUnit.requested.cost.inconsistent");
						}
					}
					if(contribution != 0){
						if(wfItem.getNumberMap().get("requestedInternalContribution") != contribution){
							errors.rejectValue("numberMap[requestedInternalContribution]","error.project.internalOrganizationUnit.requested.contribution.inconsistent");
						}
					}
					if(cofinancing != 0){
						if(wfItem.getNumberMap().get("requestedInternalCofinancing") != cofinancing){
							errors.rejectValue("numberMap[requestedInternalCofinancing]","error.project.internalOrganizationUnit.requested.cofinancing.inconsistent");
						}
					}
								
					if(cost2 != 0){
						if(wfItem.getNumberMap().get("internalCost") != cost2){
							errors.rejectValue("numberMap[internalCost]","error.project.internalOrganizationUnit.cost.inconsistent");
						}
					}
					if(contribution2 != 0){
						if(wfItem.getNumberMap().get("internalContribution") != contribution2){
							errors.rejectValue("numberMap[internalContribution]","error.project.internalOrganizationUnit.contribution.inconsistent");
						}
					}
					if(cofinancing2 != 0){
						if(wfItem.getNumberMap().get("internalCofinancing") != cofinancing2){
							errors.rejectValue("numberMap[internalCofinancing]","error.project.internalOrganizationUnit.cofinancing.inconsistent");
						}
					}
								
					var partnerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement", "partnerCost", wfService);
					var partnerSetIterator=partnerSet.iterator();	 
					cost = 0;	
					contribution = 0;
					var cost2 = 0;	
					var contribution2 = 0;
					while (partnerSetIterator.hasNext()){
						var element = partnerSetIterator.next();	
						if(checkRequested){		 
							cost = +cost + +element.getNumberMap().get("partnerRequestedCost");	
							contribution = +contribution + +element.getNumberMap().get("partnerRequestedContribution");
						}
						cost2 = +cost2 + +element.getNumberMap().get("partnerCost");	
						contribution2 = +contribution2 + +element.getNumberMap().get("partnerContribution");
					}
					if(cost != 0){
						if(wfItem.getNumberMap().get("requestedGlobalCost") != cost){
							errors.rejectValue("numberMap[requestedGlobalCost]","error.project.partner.requested.cost.inconsistent");
						}
					}
					if(contribution != 0){
						if(wfItem.getNumberMap().get("requestedGlobalContribution") != contribution){
							errors.rejectValue("numberMap[requestedGlobalContribution]","error.project.partner.requested.contribution.inconsistent");
						}
					}
									
				
					if(cost2 != 0){
						if(wfItem.getNumberMap().get("globalCost") != cost2){
							errors.rejectValue("numberMap[globalCost]","error.project.partner.cost.inconsistent");
						}
					}
					if(contribution2 != 0){
						if(wfItem.getNumberMap().get("globalContribution") != contribution2){
							errors.rejectValue("numberMap[globalContribution]","error.project.partner.contribution.inconsistent");
						}
					}
				}
			}
			
		

uniqueIdentifierProject
Questa validazione controlla l'unicità dell'identificativo dell'oggetto.
Questa verifica viene fatta per i casi di generazione di codice "parlante" con possibile collisione con identificativi già presenti.

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){				
				var paramMap = new Packages.java.util.HashMap();
				paramMap.put("identifier", object.getIdentifier());			
				
				var count=searchBuilderTemplate.getSingleObject("getWfItemCount", paramMap);
				if (count>1)
					errors.reject("error.project.identifier.notUnique");			
			}
		

internalOrganizationUnitEditValidator

	
			if (!Packages.java.lang.Boolean.TRUE.equals(object.getWfItem().getBooleanMap().get("legacy"))){		
				var iouSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);				
				var iouCostSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnitCost", wfService);				
				var iouSetIterator=iouSet.iterator();
				var iouCostSetIterator=iouCostSet.iterator();
				var ouSet = new Packages.java.util.HashSet();
				while (iouSetIterator.hasNext()){
					var element = iouSetIterator.next();
					ouSet.add(element.getOrganizationUnitMap().get("ouId"));
				}
				var ouCostSet = new Packages.java.util.HashSet();
				while (iouCostSetIterator.hasNext()){
					var element = iouCostSetIterator.next();
					ouCostSet.add(element.getOrganizationUnitMap().get("ouId"));
				}
				if(!ouSet.containsAll(ouCostSet)){
					errors.reject("error.project.internalOrganizationUnit.editOrDelete");
				}
			}
		

internalOrganizationUnitDeleteValidator

	
			if (!Packages.java.lang.Boolean.TRUE.equals(object.getWfItem().getBooleanMap().get("legacy"))){		
				var iouCostSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnitCost", wfService);				
				var iouCostSetIterator=iouCostSet.iterator();
				var ouCostSet = new Packages.java.util.HashSet();
				while (iouCostSetIterator.hasNext()){
					var element = iouCostSetIterator.next();
					ouCostSet.add(element.getOrganizationUnitMap().get("ouId"));
				}
				if(ouCostSet.contains(object.getOrganizationUnitMap().get("ouId"))){
					errors.reject("error.project.internalOrganizationUnit.editOrDelete");
				}
			}
		

internalOrganizationUnitCostEditValidator

	
			if (!Packages.java.lang.Boolean.TRUE.equals(object.getWfItem().getBooleanMap().get("legacy"))){		
				var iouSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);				
				var iouSetIterator=iouSet.iterator();
				var ouSet = new Packages.java.util.HashSet();
				while (iouSetIterator.hasNext()){
					var element = iouSetIterator.next();
					ouSet.add(element.getOrganizationUnitMap().get("ouId"));
				}
				if(!ouSet.contains(object.getOrganizationUnitMap().get("ouId"))){
					errors.reject("error.project.internalOrganizationUnitCost.editOrAdd");
				}
			}
		

partnerEditValidator

	
			if (!Packages.java.lang.Boolean.TRUE.equals(object.getWfItem().getBooleanMap().get("legacy"))){		
				var partnerSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "partner", wfService);				
				var partnerCostSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "partnerCost", wfService);				
				var partnerSetIterator = partnerSet.iterator();
				var partnerCostSetIterator = partnerCostSet.iterator();
				var partnerSet = new Packages.java.util.HashSet();
				while (partnerSetIterator.hasNext()){
					var element = partnerSetIterator.next();
					partnerSet.add(element.getOrganizationUnitMap().get("partnerId"));
				}
				var partnerCostSet = new Packages.java.util.HashSet();
				while (partnerCostSetIterator.hasNext()){
					var element = partnerCostSetIterator.next();
					partnerCostSet.add(element.getOrganizationUnitMap().get("partnerId"));
				}
				if(!partnerSet.containsAll(partnerCostSet)){
					errors.reject("error.project.partner.editOrDelete");
				}
			}
		

partnerDeleteValidator

	
			if (!Packages.java.lang.Boolean.TRUE.equals(object.getWfItem().getBooleanMap().get("legacy"))){		
				var partnerCostSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "partnerCost", wfService);				
				var partnerCostSetIterator= partnerCostSet.iterator();
				
				var partnerCostSet = new Packages.java.util.HashSet();
				while (partnerCostSetIterator.hasNext()){
					var element = partnerCostSetIterator.next();
					partnerCostSet.add(element.getOrganizationUnitMap().get("partnerId"));
				}
				if(partnerCostSet.contains(object.getOrganizationUnitMap().get("partnerId"))){
					errors.reject("error.project.partner.editOrDelete");
				}
			}
		

partnerCostEditValidator

	
			if (!Packages.java.lang.Boolean.TRUE.equals(object.getWfItem().getBooleanMap().get("legacy"))){		
				var partnerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object.getWfItem(), "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "partner", wfService);				
				var partnerSetIterator = partnerSet.iterator();
				var partnerSet = new Packages.java.util.HashSet();
				while (partnerSetIterator.hasNext()){
					var element = partnerSetIterator.next();
					partnerSet.add(element.getOrganizationUnitMap().get("partnerId"));
				}
				if(!partnerSet.contains(object.getOrganizationUnitMap().get("partnerId"))){
					errors.reject("error.project.partnerCost.editOrAdd");
				}
			}
		

projectCallValidator
Questa validazione controlla che esista uno ed un solo bando di finanziamento associato a questo progetto nel tab "Dati generali".
Viene verificato inoltre che il bando di finanziamento sia in stato approvato
Dal punto di vista del modello dati si tratta degli elementi di tipo callProjectLink
Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){
				var linkSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getParentWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "callProjectLink", wfService);
				//log.error("linkSet: " + linkSet);			
				if (linkSet.size()>1){
					errors.reject("error.project.call.moreThanOne");
				} else if (linkSet.size()==1){
					var linkSetIterator = linkSet.iterator();
					if( linkSetIterator.hasNext() ){
						var linkElement = linkSetIterator.next();
						var call = linkElement.getParent();
		                var callState = call.getWfState().getDescription();	 
						if (
						 	!Packages.org.apache.commons.lang.StringUtils.equals("approved", callState)
						 	){
						 		errors.reject("error.project.call.notApproved");
						 	}
					}
				}
			}
		

wfStartLogicProposal

			var person=wfItem.getPersonMap().get("owner");
			person=gaService.getPerson(person.getId());
			
			var ownerElement=new Packages.it.cilea.wf.model.WfItemElement();
			ownerElement.setDiscriminator("owner");
			ownerElement.setWfItemId(wfItem.getId());
			ownerElement.getPersonMap().put("ownerId", person);			
			wfService.saveOrUpdate(ownerElement);
			wfItem.getPersonMap().put("owner", null);
			
			
			var positionLastSet = person.getPositionLastSet();											
			var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(positionLastSet, "research", "department");
			positionLastSetIterator=positionLastSet.iterator();											
			while (positionLastSetIterator.hasNext()){
				var position=positionLastSetIterator.next();
				if (maxPriority == null || maxPriority.equals(position.getPriority())) {
					if ("research".equals(position.getDiscriminator()) && "department"
								.equals(position.getOrganizationUnit().getOrganizationUnitType().getDescription())) {
						var internalOrganizationUnitElement=new Packages.it.cilea.wf.model.WfItemElement();
						internalOrganizationUnitElement.setDiscriminator("internalOrganizationUnit");
						internalOrganizationUnitElement.setWfItemId(wfItem.getId());
						var internalOrganizationUnitRoleId = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.internalOrganizationUnit.role.main");
						if (internalOrganizationUnitRoleId==null) 
							throw "ERROR on wfStartLogicProposal: internalOrganizationUnitRoleId is NULL ";
						var internalOrganizationUnitRole = wfService.getWfDictionary(new Packages.java.lang.Integer(internalOrganizationUnitRoleId));
						if (internalOrganizationUnitRole==null) 
							throw "ERROR on wfStartLogicProposal: internalOrganizationUnitRole is NULL ";
						internalOrganizationUnitElement.getOrganizationUnitMap().put("ouId", position.getOrganizationUnit());
						internalOrganizationUnitElement.getWfDictionaryMap().put("ouRole", internalOrganizationUnitRole);						
						wfService.saveOrUpdate(internalOrganizationUnitElement);
						break;
					}
				}
			}		
			
			//partner
			var uniquePartnerRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.uniquePartner");
			var myOrganization=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.myOrganization");
			if (uniquePartnerRoleId==null || myOrganization==null){
				throw "Configuration variables ap.project.partner.role.uniquePartner and ap.project.partner.myOrganization MUST BE DEFINED";
			} else {				
				uniquePartnerRoleId=wfService.getWfDictionary(new Packages.java.lang.Integer(uniquePartnerRoleId));				
				myOrganization=gaService.getOrganizationUnit(new Packages.java.lang.Integer(myOrganization));
				
				var partnerElement=new Packages.it.cilea.wf.model.WfItemElement();
				partnerElement.setDiscriminator("partner");
				partnerElement.setWfItemId(wfItem.getId());
				partnerElement.getOrganizationUnitMap().put("partnerId", myOrganization);
				partnerElement.getWfDictionaryMap().put("partnerRole", uniquePartnerRoleId);
				wfService.saveOrUpdate(partnerElement);				
			}
			
			
			var lastName=person.getLastName().replaceAll("\\s", "");
			lastName=lastName.replaceAll("'", "");
			lastName=(lastName.length()>=4)?lastName.substring(0,4):lastName.substring(0,lastName.length());
			lastName=lastName.toUpperCase();
			
			var firstName=person.getFirstName().substring(0,1);
			firstName=firstName.toUpperCase();	
			
			var startDate=wfItem.getDateMap().get("startDate");
			var year=startDate.get(Packages.java.util.Calendar.YEAR);
			
			var yearString=new Packages.java.lang.Integer(year).toString();
			yearString=yearString.substring(2);			
			
			var sourceItemTypeCode=wfItem.getWfItemType().getCode();
			var identifier="PRO_"+sourceItemTypeCode+yearString+firstName+lastName+"_";
			
			var paramMap = new Packages.java.util.HashMap();
			paramMap.put("identifier", identifier);
			paramMap.put("excludeIdentifier", identifier+"M");
			
			var count=searchBuilderTemplate.getSingleObject("getMaxItemCountForGivenIdentifier", paramMap);
			var countString="";
			if (count<9)
				countString+="0";			
			countString+=(count.intValue()+1);
			identifier+=countString;			
			wfItem.setIdentifier(identifier);
			wfItem.setYear(new Packages.java.lang.Integer(year));
			true;
			

wfActionLogicEnterProposalMailSender

			var mailEnableParam = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.proposal.mail.enable");
			var mailHtmlEnableParam = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.proposal.mail.html.enable");
			var isHtml;
			if(mailHtmlEnableParam.equalsIgnoreCase("true")){
				isHtml = true;
			}
			else{
				isHtml = false;
			}
			if (mailEnableParam!=null && mailEnableParam.equalsIgnoreCase("true")){
				var wfItemIdentifier = wfItem.getIdentifier();
				var wfItemDescription = wfItem.getDescription();
				var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
				var ownerSetIterator=ownerSet.iterator();
				while(ownerSetIterator.hasNext()){
					var ownerElement=ownerSetIterator.next();
					var person = ownerElement.getPersonMap().get("ownerId");
					person = gaService.getPerson(person.getId());
					var contact=person.getPrincipalContactMap().get("mail");
					var surnameName = person.getLastName()+" "+person.getFirstName();
					var subjectLabel=messageUtil.findMessage("label.ap.proposal.mail.subject", [wfItemIdentifier]);
					var textLabel=messageUtil.findMessage("label.ap.proposal.mail.text",[wfItemIdentifier, surnameName, wfItemDescription, wfItem.getWfState().getDisplayValue()]);
					mailService.send("no-reply@cineca.it", [contact], null, null, subjectLabel, textLabel, null, isHtml);
				}
			}
		

ethicCommiteeDeleteInconsistentDataProposal

		//questa funzione elimina tutti i dati del tab, tranne ovviamente ethicCommiteeApplicability
		//viene chiamata quando non è applicabile
		function deleteAll(){
			
			//dati riguardanti il topic
			var wfItemElementSet = object.getWfItemElementSet();
			var ethicCommiteeTopicSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "ethicCommiteeTopic", wfService);
			
			var ethicCommiteeTopicSetIterator=ethicCommiteeTopicSet.iterator();
			while(ethicCommiteeTopicSetIterator.hasNext()){
				var wfItemElement=ethicCommiteeTopicSetIterator.next();
				
				var ethicCommiteeTopic= wfItemElement.getWfDictionaryMap().get("ethicCommiteeTopicId");
				var description= ethicCommiteeTopic.getDescription();
				//log.error("Topic description (ethicCommiteeTopicSet): "+description);
				
				wfService.deleteWfItemElement(wfItemElement.getId());
				//log.error("Eliminato con wfService");
				
				wfItemElementSet.remove(wfItemElement);
				//log.error("Eliminato dal set");
			}
			
			object.setWfItemElementSet(wfItemElementSet);
			//log.error("Sostituito set con nuovo");
			
			//dati riguardanti l'autorizzazione
			//log.error("ethicCommiteeSubmitted: "+object.getBooleanMap().get("ethicCommiteeSubmitted"));
			object.getBooleanMap().put("ethicCommiteeSubmitted", null);
			
			//log.error("ethicCommiteeSubmitDate: "+object.getDateMap().get("ethicCommiteeSubmitDate"));
			object.getDateMap().put("ethicCommiteeSubmitDate", null);
			
			//log.error("ethicCommiteeAuthorization: "+object.getWfDictionaryMap().get("ethicCommiteeAuthorization"));
			object.getWfDictionaryMap().put("ethicCommiteeAuthorization", null);
			
			deleteAuthorizationData();
		}
		
		//questa funzione elimina i dati riguardanti l'autorizzazione
		//viene chiamata quando non viene concessa
		function deleteAuthorizationData(){
			//log.error("ethicCommiteeAuthorizationNumber: "+object.getNumberMap().get("ethicCommiteeAuthorizationNumber"));
			object.getNumberMap().put("ethicCommiteeAuthorizationNumber", null);
			
			//log.error("ethicCommiteeAuthorizationDate: "+object.getDateMap().get("ethicCommiteeAuthorizationDate"));
			object.getDateMap().put("ethicCommiteeAuthorizationDate", null);
			
			//log.error("ethicCommiteeAuthorizationOrganization: "+object.getOrganizationUnitMap().get("ethicCommiteeAuthorizationOrganization"));
			var orgUnitMap=object.getOrganizationUnitMap().put("ethicCommiteeAuthorizationOrganization", null);
			
			wfService.saveOrUpdate(object);
			//log.error("SALVATO!");
		}
		
		//quando elimino da una mappa, non mi importa gestire se fosse popolata o meno
		//al massimo il remove mi restituisce null
		
		//log.error("Sono nel ethicCommiteeDeleteInconsistentData");
		
		//prima di tutto vado a vedere ethicCommiteeApplicability
		//SE NON E' SI (true), allora cancello tutti i dati sottostanti
		
		var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
		if (ethicCommiteeApplicability!=true){
			//chiamo la funzione per eliminare tutto
			deleteAll();
		}else{
			//non mi interessa ethicCommiteeSubmitted, deve essere per forza true se sono qui
			
			//SE E' SI, allora vado a vedere ethicCommiteeAuthorization
			var ethicCommiteeAuthorization= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
			
			//SE NON E' SPECIFICATO (null) O 'NON CONCESSO', allora cancello i dati relativi
			//TRANNE la data di presentazione
			//ci può essere il caso che sia stata fatta la richiesta e si stia aspettando il responso
			
			//non specificato, caso per evitare eccezioni
			if(ethicCommiteeAuthorization==null){
				deleteAuthorizationData();
			}else{
				var ethicCommiteeAuthorizationDescription= wfService.getWfDictionary(ethicCommiteeAuthorization.getId()).getDescription();
				if (!Packages.org.apache.commons.lang.StringUtils.equals("Concessa", ethicCommiteeAuthorizationDescription)){
					deleteAuthorizationData();
				}
			}
		}	
		

ownerStartValidatorProposal

			if (object.getId()==null && object.getPersonMap().get("owner")==null){
				errors.rejectValue("personMap[owner]","error.proposal.owner.required");
			}
		

ownerValidatorProposal

			
			var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
			if (ownerSet.size()<1)
				errors.reject("error.proposal.owner.atLeast1");		
		

organizationUnitValidatorProposal

			
			var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
			if (orgUnitSet.size()<1)
				errors.reject("error.proposal.multipleInternalOrganization.atLeast1");		
		

ethicCommiteeTopicValidatorProposal

			
			//log.error("Sono nel ethicCommiteeTopicValidatorProposal");
			var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
			if (ethicCommiteeApplicability==true){
				//log.error("ethicCommiteeApplicability è true")
				//var ethicCommiteeTopicSet= object.getWfItemElementSet("ethicCommiteeTopic");
				var ethicCommiteeTopicSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "ethicCommiteeTopic", wfService);
				if(ethicCommiteeTopicSet.isEmpty()){
					//log.error("Nessun topic!");
					errors.reject("error.proposal.ethicCommiteeTopic.atLeast1");
				}	
			}
		

ethicCommiteeSubmittedValidatorProposal

	
			//log.error("Sono nel ethicCommiteeSubmittedValidatorProposal");		
			var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
			if (ethicCommiteeApplicability==true){
				//log.error("ethicCommiteeApplicability è true")
				var ethicCommiteeSubmitted= object.getBooleanMap().get("ethicCommiteeSubmitted");
				if(ethicCommiteeSubmitted!=true){
					//log.error("ethicCommiteeSubmitted è falso!");
					errors.reject("error.proposal.ethicCommiteeSubmitted.required");
				}	
			}
		

ethicCommiteeAuthorizationNumberValidatorProposal

	
			//log.error("Sono nel ethicCommiteeAuthorizationNumberValidatorProposal");
			var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
			//prima di tutto si deve attivare solo se ethicCommiteeApplicability è su true
			if (ethicCommiteeApplicability==true){
				
				var ethicCommiteeSubmitted = object.getBooleanMap().get("ethicCommiteeSubmitted");
				//poi solo se ethicCommiteeSubmitted è su true
				if(ethicCommiteeSubmitted==true){
				
					var ethicCommiteeAuthorizationDictionary= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
					
					if(ethicCommiteeAuthorizationDictionary!=null){
					
						var ethicCommiteeAuthorizationDictionaryDescription= wfService.getWfDictionary(ethicCommiteeAuthorizationDictionary.getId()).getDescription();
						
						if (ethicCommiteeAuthorizationDictionaryDescription.equals("Concessa")){
							//se concessa allora il validator si deve attivare
							var ethicCommiteeAuthorizationNumber = object.getNumberMap().get("ethicCommiteeAuthorizationNumber");
							if(ethicCommiteeAuthorizationNumber==null){
								errors.reject("error.proposal.ethicCommiteeAuthorizationNumber.requiredIfGranted");
							}
						}
					}
				}
			}
			
		

ethicCommiteeAuthorizationDateValidatorProposal

	
			//log.error("Sono nel ethicCommiteeAuthorizationDateValidatorProposal");
			var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
			//prima di tutto si deve attivare solo se ethicCommiteeApplicability è su true
			if (ethicCommiteeApplicability==true){
				
				var ethicCommiteeSubmitted = object.getBooleanMap().get("ethicCommiteeSubmitted");
				//poi solo se ethicCommiteeSubmitted è su true
				if(ethicCommiteeSubmitted==true){
				
					var ethicCommiteeAuthorizationDictionary= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
					
					if(ethicCommiteeAuthorizationDictionary!=null){
					
						var ethicCommiteeAuthorizationDictionaryDescription= wfService.getWfDictionary(ethicCommiteeAuthorizationDictionary.getId()).getDescription();
						
						if (ethicCommiteeAuthorizationDictionaryDescription.equals("Concessa")){
							//se concessa allora il validator si deve attivare
							var ethicCommiteeAuthorizationDate = object.getDateMap().get("ethicCommiteeAuthorizationDate");
							if(ethicCommiteeAuthorizationDate==null){
								errors.reject("error.proposal.ethicCommiteeAuthorizationDate.requiredIfGranted");
							}
						}
					}
				}
			}
			
		

ethicCommiteeAuthorizationOrganizationValidatorProposal

	
			//log.error("Sono nel ethicCommiteeAuthorizationOrganizationValidatorProposal");
			var ethicCommiteeApplicability = object.getBooleanMap().get("ethicCommiteeApplicability");
			//prima di tutto si deve attivare solo se ethicCommiteeApplicability è su true
			if (ethicCommiteeApplicability==true){
				
				var ethicCommiteeSubmitted = object.getBooleanMap().get("ethicCommiteeSubmitted");
				//poi solo se ethicCommiteeSubmitted è su true
				if(ethicCommiteeSubmitted==true){
				
					var ethicCommiteeAuthorizationDictionary= object.getWfDictionaryMap().get("ethicCommiteeAuthorization");
					
					if(ethicCommiteeAuthorizationDictionary!=null){
					
						var ethicCommiteeAuthorizationDictionaryDescription= wfService.getWfDictionary(ethicCommiteeAuthorizationDictionary.getId()).getDescription();
						
						if (ethicCommiteeAuthorizationDictionaryDescription.equals("Concessa")){
							//se concessa allora il validator si deve attivare
							var ethicCommiteeAuthorizationOrganization = object.getOrganizationUnitMap().get("ethicCommiteeAuthorizationOrganization");
							if(ethicCommiteeAuthorizationOrganization==null){
								errors.reject("error.proposal.ethicCommiteeAuthorizationOrganization.requiredIfGranted");
							}
						}
					}
				}
			}
			
		

uniqueParentProject

			var linkSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "link", wfService);
			//log.error("linkSet: " + linkSet);			
			if (linkSet.size()>1){
				errors.reject("error.proposal.parentProject.moreThanOneParentProposal");
			} else if (linkSet.size()==1){
				var linkSetIterator = linkSet.iterator();
				if( linkSetIterator.hasNext() ){
					var linkElement = linkSetIterator.next();
					var project = linkElement.getParent();
	                var projectState = project.getWfState().getDescription();	 
					if (
					 	!Packages.org.apache.commons.lang.StringUtils.equals("approved", projectState) 
					 	&&
					 	!Packages.org.apache.commons.lang.StringUtils.equals("concluded", projectState)
					 	){
					 		errors.reject("error.proposal.parentProject.notApprovedOrConcluded");
					 	} else {					 		
					 		var paramMap = new Packages.java.util.HashMap();
							paramMap.put("parentId", project.getId());
							var count=searchBuilderTemplate.getSingleObject("getProposalChildProject", paramMap);
							if (count>0)
								errors.reject("error.proposal.parentProject.notUnique");
					 	}					 
				}
			} else if (linkSet.size()==0) {
				//ok don't do anythig, just chill out bro
			}
		

organizationUnitRoleValidatorProposal

			
			var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
			if (orgUnitSet.size()<1){
				errors.reject("error.proposal.multipleInternalOrganization.atLeast1");
			} else {
				var internalOrganizationUnitCoordinatorRole=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.internalOrganizationUnit.role.main");
				if (!internalOrganizationUnitCoordinatorRole){
					throw "Configuration variable ap.proposal.internalOrganizationUnit.role.main MUST BE DEFINED"; 								
				} else {
					internalOrganizationUnitCoordinatorRole=new Packages.java.lang.Integer(internalOrganizationUnitCoordinatorRole);
				}
				var orgUnitSetIterator=orgUnitSet.iterator();
				var count=0;											
				while (orgUnitSetIterator.hasNext()){											
					var element=orgUnitSetIterator.next();												
					var ouRole=element.getWfDictionaryMap().get("ouRole");
					if (ouRole!=null && internalOrganizationUnitCoordinatorRole.equals(ouRole.getId())){
						count++;	
					}												
				}
				if (count==0){
					errors.reject("error.proposal.multipleInternalOrganization.missingMain");
				}
				else if (count>1) {
					errors.reject("error.proposal.multipleInternalOrganization.tooManyMain");
				}
		} 		
		

ownerAndOrganizationUnitMatchValidatorProposal

			
			var orgUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "internalOrganizationUnit", wfService);
			var ownerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService);
			var ownerDepartmentSet=new Packages.java.util.HashSet();
			var internalOrganizationUnitSet=new Packages.java.util.HashSet();
			
			var startDateFromWfItem=wfItem.getDateMap().get("startDate");
			if (startDateFromWfItem!=null){
				startDateFromWfItem=startDateFromWfItem.getTime();
							
				if (ownerSet.size()>0){
					var ownerSetIterator=ownerSet.iterator();			
					while (ownerSetIterator.hasNext()){
						var ownerElement=ownerSetIterator.next();			
						var person=ownerElement.getPersonMap().get("ownerId");
						
						var ownerDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
						ownerDepartmentPositionSearch.setPersonId(person.getId());
						ownerDepartmentPositionSearch.setDate(startDateFromWfItem);
						ownerDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
						ownerDepartmentPositionSearch.setDiscriminator("research");							
						var ownerDepartmentPositionSet = gaService.getPositionSearchList(ownerDepartmentPositionSearch, 0);
						var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(ownerDepartmentPositionSet, "research", "department");
						
						var ownerDepartmentPositionSetIterator=ownerDepartmentPositionSet.iterator();							
						while (ownerDepartmentPositionSetIterator.hasNext()){
							var position=ownerDepartmentPositionSetIterator.next();
							if (maxPriority == null || maxPriority.equals(position.getPriority())) {
								ownerDepartmentSet.add(position.getOrganizationUnit());														
								break;
							}
						}										
					}
				}
				if (ownerDepartmentSet.size()>0){
					if (orgUnitSet.size()>0){
			 			var orgUnitSetIterator=orgUnitSet.iterator();			
						while (orgUnitSetIterator.hasNext()){											
							var wfItemElement=orgUnitSetIterator.next();												
							var orgUnit=wfItemElement.getOrganizationUnitMap().get("ouId");
							internalOrganizationUnitSet.add(orgUnit);
						}
					}
				}
				
				if(!internalOrganizationUnitSet.containsAll(ownerDepartmentSet)){
					var nonMatchedDepartmentCollection=Packages.org.apache.commons.collections.CollectionUtils.subtract(ownerDepartmentSet, internalOrganizationUnitSet);
					var nonMatchedDepartmentCollectionIterator=nonMatchedDepartmentCollection.iterator();
					var nonMatchedDepartmentString="";
					var counter=0;
					while(nonMatchedDepartmentCollectionIterator.hasNext()){
						var nonMatchedDepartment=nonMatchedDepartmentCollectionIterator.next();
						if (counter++>0)
							nonMatchedDepartmentString+=", ";
						nonMatchedDepartmentString+=nonMatchedDepartment.getDescription();
					}
					var df =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
					var dateAsString=df.format(startDateFromWfItem);
					errors.reject("error.proposal.multipleInternalOrganization.matchWithDepartmentOwnerNotFound", [nonMatchedDepartmentString], null);       								
				} 	
			}	
		

grantorValidatorProposal

			
			var grantorSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "grantor", wfService);
			if (grantorSet.size()<1)
				errors.reject("error.proposal.grantor.atLeast1");
		

currencyAndInternalContributionValidatorProposal

			
			var currency=object.getWfDictionaryMap().get("currency");
			var euroCurrency=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.dictionary.currency.euro");
			if (!euroCurrency){
				throw "Configuration variable ap.dictionary.currency.euro MUST BE DEFINED"; 								
			}
			if (currency && currency.getId()!=euroCurrency){
				if (!object.getNumberMap().get("internalContributionOriginalCurrency")){       										
					errors.rejectValue("numberMap[internalContributionOriginalCurrency]","error.proposal.funding.internalContributionOriginalCurrency.required");									
				}
				if (!object.getNumberMap().get("exchangeRate")){
					errors.rejectValue("numberMap[exchangeRate]","error.proposal.funding.exchangeRate.required");									
				}
				if (!object.getDateMap().get("exchangeRateDate")){
					errors.rejectValue("dateMap[exchangeRateDate]","error.proposal.funding.exchangeRateDate.required");									
				}
			}	       							
		

partnerAndGlobalCostValidatorProposal

			
			var coordinatorRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.main");
			var uniquePartnerRoleId=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.role.uniquePartner");
			
			var myOrganization=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.project.partner.myOrganization");
			if (coordinatorRoleId==null || myOrganization==null || uniquePartnerRoleId==null){
				throw "Configuration variables ap.project.partner.role.main, ap.project.partner.role.uniquePartner and ap.project.partner.myOrganization MUST BE DEFINED";
			} else {
				coordinatorRoleId=new Packages.java.lang.Integer(coordinatorRoleId);
				uniquePartnerRoleId=new Packages.java.lang.Integer(uniquePartnerRoleId);
				myOrganization=new Packages.java.lang.Integer(myOrganization);				
			}		
			var partnerSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement", "partner",wfService);
			var partnerSetIterator=partnerSet.iterator();
			var counterOtherPartner=0;
			var counterCoordinator=0;
			var counterUniquePartner=0;
			while (partnerSetIterator.hasNext()){
				var element=partnerSetIterator.next();			 
				var orgUnitRole = element.getWfDictionaryMap().get("partnerRole");
				var orgUnit = element.getOrganizationUnitMap().get("partnerId");
				if (coordinatorRoleId.equals(orgUnitRole.getId())){
					counterCoordinator++;
				} else 	if (uniquePartnerRoleId.equals(orgUnitRole.getId())){
					counterUniquePartner++;
				} else {
					counterOtherPartner++;
				}
				if(myOrganization.equals(orgUnit.getId()) && coordinatorRoleId.equals(orgUnitRole.getId())){
					
					if (!object.getNumberMap().get("globalContribution")){
						errors.rejectValue("numberMap[globalContribution]","error.proposal.funding.globalContribution.required");											
					}
					
					if (!object.getNumberMap().get("globalCost")){
						errors.rejectValue("numberMap[globalCost]","error.proposal.funding.globalCost.required");											
					}
					
					var currency=object.getWfDictionaryMap().get("currency");
					var euroCurrency=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.dictionary.currency.euro");
					if (!euroCurrency){
						throw "Configuration variable ap.dictionary.currency.euro MUST BE DEFINED"; 								
					}
					if (currency && currency.getId()!=euroCurrency){
						if (!object.getNumberMap().get("globalCostOriginalCurrency")){
							errors.rejectValue("numberMap[globalCostOriginalCurrency]","error.proposal.funding.globalCostOriginalCurrency.required");											
						}										
						
						if (!object.getNumberMap().get("globalContributionOriginalCurrency")){
							errors.rejectValue("numberMap[globalContributionOriginalCurrency]","error.proposal.funding.globalContributionOriginalCurrency.required");											
						}
					}
				}			
			}
			if (counterCoordinator>1){									
				errors.reject("error.proposal.partner.tooManyMain");
			} else if (counterUniquePartner>1){									
				errors.reject("error.proposal.partner.tooManyUniquePartner");
			} else if (partnerSet.size()>0){
				if (counterCoordinator>0 && counterUniquePartner>0){
					errors.reject("error.proposal.partner.coordinatorAndUniquePartner");
				} else if (counterOtherPartner>0 && counterCoordinator==0){
					errors.reject("error.proposal.partner.missingMain");
				} else if (counterOtherPartner>0 && counterUniquePartner>0){
					errors.reject("error.proposal.partner.otherPartnerAndUniquePartner");
				} else if (counterOtherPartner==0 && counterCoordinator>0){
					errors.reject("error.proposal.partner.coordinatorAndNoOtherPartner");
				}				
			}	       							
	       							
		

wfStartLogicPublicEngagement

			if(wfItem.getBooleanMap().get("periodicEvent")==null){
				wfItem.getBooleanMap().put("periodicEvent",false);
			}					
			if(wfItem.getBooleanMap().get("istitutionalInitiative")==null){
				wfItem.getBooleanMap().put("istitutionalInitiative",false);
			}
			if(wfItem.getBooleanMap().get("evaluationEnable")==null){
				wfItem.getBooleanMap().put("evaluationEnable",false);
			}			
			if(wfItem.getNumberMap().get("externalFinancing")==null){
				wfItem.getNumberMap().put("externalFinancing",new java.math.BigDecimal("0"));
			}
			if(wfItem.getNumberMap().get("totalBudget")==null){
				wfItem.getNumberMap().put("totalBudget", new java.math.BigDecimal("0"));
			}	
			if(wfItem.getNumberMap().get("numTotalDay")==null){
				wfItem.getNumberMap().put("numTotalDay", new java.math.BigDecimal("1"));
			}
			if(wfItem.getBooleanMap().get("personOrDepartment")!=null){			
				wfItem.getBooleanMap().put("personOrDepartment",null);
			}			
			true;
		

validatorDepartmentPublicEngagement

			var personOrDepartment =wfItem.getBooleanMap().get("personOrDepartment");
			if (personOrDepartment==true){			
				var person=wfItem.getPersonMap().get("owner");
				if(person!=null){
					var mandatory=Packages.it.cilea.wf.util.WfUtil.getMandatory(object,"owner");
					if(mandatory){					
						person=gaService.getPerson(person.getId());				
						var startDate=wfItem.getDateMap().get("startDate");
						if(startDate!=null){
							//setto il positionSearch in modo da trovare se ho delle position di ricerca per quella data
							var ownerPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();							
							ownerPositionSearch.setPersonId(person.getId());
							ownerPositionSearch.setDate(startDate.getTime());
							ownerPositionSearch.setOrganizationUnitTypeDescription("department");
							ownerPositionSearch.setDiscriminator("research");
							var ownerPositionSet = gaService.getPositionSearchList(ownerPositionSearch, 0);
							if(ownerPositionSet.isEmpty()){
								  errors.reject("error.publicEngagement.start.organizationUnitMap.required");
							}
						}else {
							errors.reject("error.startDate.required");
						}
					}		
				}
			}
		

ownerStartValidatorPublicEngagement

			
			if (object.getId()==null){		
				var personOrDepartment =object.getBooleanMap().get("personOrDepartment");					
				if  ((personOrDepartment==true)&&(object.getPersonMap().get("owner")==null)){
					errors.rejectValue("personMap[owner]","error.publicEngagement.owner.required");					
				}else if ((personOrDepartment==false)&&(object.getOrganizationUnitMap().get("ouId")==null)){			
					errors.rejectValue("organizationUnitMap[ouId]","error.publicEngagement.organizationUnitMap.required");
				}
			}			
		

checkToolEvaluation

			var isToolEnable=object.getBooleanMap().get("evaluationEnable");
			var listEvaluation=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "evaluationTool", wfService);			
			if ((isToolEnable==true)&&(listEvaluation.size()==0)){
			errors.rejectValue("booleanMap[evaluationEnable]","error.publicEngagement.toolEvaluationEngagement.required");				
		}

ownerDeleteValidatorPublicEngagement

	
			var personalUserName=request.getUserPrincipal().getName();
			var personId=gaService.getUser(personalUserName).getPersonId();
			var ownerId =object.getPersonMap().get("ownerId").getId();			
			//log.error("personId "+personId+" ownerId "+ownerId);						
			if (ownerId==personId){
				errors.reject("error.publicEngagement.notallowed");
			}
		

internalRepresentativeDeleteValidatorPublicEngagement

	
			// Elenco dei miei dipartimenti 
		    var list=gaAuthorizationService.getAuthoritiesInfoSelectableDisplayList("/DEPARTMENT/ap.profile");
			//controllo per verificare se sono in visione dipartimentale o no
			var listIterator=list.iterator();		
			while(listIterator.hasNext()){
				var selectable=listIterator.next();			
				if(object.getOrganizationUnitMap().get("ouId").getId()==selectable.getIdentifyingValue()){
					errors.reject("error.publicEngagement.notallowed");
				}	
			}
			var personalUserName=request.getUserPrincipal().getName();
			var personId=gaService.getUser(personalUserName).getPersonId();
			var ownerId =object.getPersonMap().get("ownerId").getId();			
			//log.error("personId "+personId+" ownerId "+ownerId);						
			if (ownerId==personId){
				errors.reject("error.publicEngagement.notallowed");
			}
		

internalRepresentativeCannotEditOwnersValidator

			
			//ricavo dalla request l'utente loggato in quel momento //NOTA: in caso di loginAs restituisce l'user impersonato
			var personalUserName=request.getUserPrincipal().getName();
			var personId=gaService.getUser(personalUserName).getPersonId();			
			//ricavo wfItem completo, non mi serve il fragment dato che non posso comunque 
			var wfItem= wfService.getWfItem(object.getWfItemId());			
			//cerco tra gli internalRepresentative se c'è la persona al momento loggata
			var internalRepresentativeWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalRepresentative", wfService);
			var internalRepresentativeWfElementSetIterator=internalRepresentativeWfElementSet.iterator();			
			while(internalRepresentativeWfElementSetIterator.hasNext()){
				var internalRepresentativeElement=internalRepresentativeWfElementSetIterator.next();
				var internalRepresentative=internalRepresentativeElement.getPersonMap().get("internalRepresentative");
				//log.error("personId "+personId+" internalRepresentative "+internalRepresentative);
				if(internalRepresentative.getId()==personId){
					errors.reject("error.publicEngagement.notallowed");
				}
			}
		

suardDepartmentHelpdeskInitiativeValidatorPublicEngagement

			var suardUniversityInitiative =wfItem.getBooleanMap().get("suardUniversityInitiative");
			if (suardUniversityInitiative==false){			
				var actualDipartment =object.getOrganizationUnitMap().get("suardDepartmentInitiative");	
				if(actualDipartment==null){
					errors.reject("error.publicEngagement.organizationUnitMap.required");
				}else { 
					var wfItem= wfService.getWfItem(object.getWfItemId());			
					var dipartementList=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);					
					var departmentWfElementSetIterator=dipartementList.iterator();
					var isPresent=false;		
					while(departmentWfElementSetIterator.hasNext()){
						var department=departmentWfElementSetIterator.next();
						var departmentOwner =department.getOrganizationUnitMap().get("ouId");
				        if(actualDipartment.getId().equals(departmentOwner.getId())){
							isPresent=true;
							break;
						}
					}
					if(false==isPresent){
						errors.reject("error.publicEngagement.notallowed.suardDepartmentInitiative");
					}
				}
			}
		

suardDepartmentInitiativeValidatorPublicEngagement

			var suardUniversityInitiative =wfItem.getBooleanMap().get("suardUniversityInitiative");
			if (suardUniversityInitiative==false){			
				var actualDipartment =object.getOrganizationUnitMap().get("suardDepartmentInitiative");	
				if(actualDipartment==null){
					errors.reject("error.publicEngagement.organizationUnitMap.required");
				}else { 
					var wfItem= wfService.getWfItem(object.getWfItemId());			
					var dipartementList=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);					
					var departmentWfElementSetIterator=dipartementList.iterator();
					var isPresent=false;		
					while(departmentWfElementSetIterator.hasNext()){
						var department=departmentWfElementSetIterator.next();
						var departmentOwner =department.getOrganizationUnitMap().get("ouId");
				        if(actualDipartment.getId().equals(departmentOwner.getId())){
							isPresent=true;
							break;
						}
					}
					if(false==isPresent){
						errors.reject("error.publicEngagement.notallowed.suardDepartmentInitiative");
					}
				}
			}else {
				errors.reject("error.publicEngagement.notallowed");
			}
		

deleteValidatorParentDetectorPublicEngagement

			
			var wfItem = wfService.getWfItem(object.getWfItemId());
			var identifier = wfItem.getIdentifier();
			
			if(!wfItem.getChildWfItemLinkSet("publicEngagementLink").isEmpty())
				errors.reject("error.publicEngagement.childDetected");
			
		

deleteValidatorChildDetectorPublicEngagement

			
			var wfItem = wfService.getWfItem(object.getWfItemId());
			var identifier = wfItem.getIdentifier();
			
			if(!wfItem.getParentWfItemLinkSet("publicEngagementLink").isEmpty())
				errors.reject("error.publicEngagement.parentDetected");
			
		

wfActionLogicEnterWorkgroupOwnerMailSender

			X={
			subjectLabel:'label.ap.workgroup.mail.subject',
			textLabel:'label.ap.workgroup.mail.text',
			sendEnable:'ap.itemType.wkg.mail.enable',
			htmlEnable:'ap.itemType.wkg.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleOwners',
			to:'',
			from:''
			}; X;
		

wfActionLogicEnterWorkgroupHeadOfDepartmentMailSender

			X={
			subjectLabel:'label.ap.workgroup.mail.subject',
			textLabel:'label.ap.workgroup.mail.text',
			sendEnable:'ap.itemType.wkg.mail.enable',
			htmlEnable:'ap.itemType.wkg.mail.html.enable',
			identityLogic:'wfIdentityLogicMultipleHeadOfDepartment',
			to:'',
			from:''
			}; X;
		

laboratoryValidatorWorkgroup

			
			//ricavo dal fragment dei laboratory
			var laboratorySet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "workgroupLaboratoryLink", wfService);
			//controllo banale, controllo che ci sia almeno un link, sennò non vado avanti
			if(laboratorySet.size()>0){
			
				//ricavo l'iteratore lo uso per ciclare il set
				var laboratorySetIterator = laboratorySet.iterator();
				while( laboratorySetIterator.hasNext() ){
				
					//ricavo il singolo link e prendo il child che è il laboratory
					var laboratoryLinkElement = laboratorySetIterator.next();
					var laboratory= laboratoryLinkElement.getChild();
					//poi ricavo il suo stato e controllo che sia in approved
					var laboratoryState = laboratory.getWfState().getDescription();
					
					if(!(Packages.org.apache.commons.lang.StringUtils.equals("approved", laboratoryState) || Packages.org.apache.commons.lang.StringUtils.equals("reopened", laboratoryState))){
						//se non è approved o reopened allora lancia l'errore
						errors.reject("error.workgroup.laboratory.mustBeApproved");
					}
					
				}
			
			}
		

equipmentValidatorWorkgroup

			
			//ricavo dal fragment dei equipment
			var equipmentSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "workgroupEquipmentLink", wfService);
			//controllo banale, controllo che ci sia almeno un link, sennò non vado avanti
			if(equipmentSet.size()>0){
			
				//ricavo l'iteratore lo uso per ciclare il set
				var equipmentSetIterator = equipmentSet.iterator();
				while( equipmentSetIterator.hasNext() ){
				
					//ricavo il singolo link e prendo il child che è il equipment
					var equipmentLinkElement = equipmentSetIterator.next();
					var equipment= equipmentLinkElement.getChild();
					//poi ricavo il suo stato e controllo che sia in approved
					var equipmentState = equipment.getWfState().getDescription();
					
					 if(!(Packages.org.apache.commons.lang.StringUtils.equals("approved", equipmentState) || Packages.org.apache.commons.lang.StringUtils.equals("reopened", equipmentState))){
						//se non è approved o reopened allora lancia l'errore
						errors.reject("error.workgroup.equipment.mustBeApproved");
					}
					
				}
			
			}
		

selfLinkedWorkgroupValidator

            
            //ricavo dal fragment dei workgroup
            var workgroupSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "workgroupLink", wfService);
            //controllo banale, controllo che ci sia almeno un link, sennò non vado avanti
            if(workgroupSet.size()>0){
            
                //ricavo l'iteratore lo uso per ciclare il set
                var workgroupSetIterator = workgroupSet.iterator();
                while( workgroupSetIterator.hasNext() ){
                
                    //ricavo il singolo link e prendo il child che è il workgroup collegato
                    var workgroupLinkElement = workgroupSetIterator.next();
                    var workgroup= workgroupLinkElement.getChild();
                    
                    if(object.getWfItemId()==workgroup.getWfItemId()){
                        //se sono uguali allora lancia l'errore
                        errors.reject("error.workgroup.workgroupLink.linkedToItself");
                    }
                }
            }            
        

approvedWorkgroupValidator

            
            //ricavo dal fragment dei workgroup
            var workgroupSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "workgroupLink", wfService);
            //controllo banale, controllo che ci sia almeno un link, sennò non vado avanti
            if(workgroupSet.size()>0){
            
                //ricavo l'iteratore lo uso per ciclare il set
                var workgroupSetIterator = workgroupSet.iterator();
                while( workgroupSetIterator.hasNext() ){
                
                    //ricavo il singolo link e prendo il child che è il workgroup collegato
                    var workgroupLinkElement = workgroupSetIterator.next();
                    var workgroup= workgroupLinkElement.getChild();
                   //poi ricavo il suo stato e controllo che sia in approved o reopened
                    var workgroupState= workgroup.getWfState().getDescription();
                    
                    if(!(Packages.org.apache.commons.lang.StringUtils.equals("approved", workgroupState) || Packages.org.apache.commons.lang.StringUtils.equals("reopened", workgroupState))){
						//se non è approved o reopened allora lancia l'errore
						errors.reject("error.workgroup.workgroupLink.mustBeApproved");
					}
                }
            }            
        

projectValidatorWorkgroup

			
			//ricavo dal fragment dei project
			var projectSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getChildWfItemLinkSet", "it.cilea.wf.model.WfItemLink", "workgroupProjectLink", wfService);
			//controllo banale, controllo che ci sia almeno un link, sennò non vado avanti
			if(projectSet.size()>0){
				
				//variabile che mi servirà più tardi
				var configStatesArray=[];
				
				//controllo per vedere se è definita la variabile di configurazione con gli stati accettati
				var csvAllowedProjectState=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.wkg.workgroupProjectLink.csvAllowedProjectState");
				if (!csvAllowedProjectState){
					//nel caso non sia definita
					throw "Configuration variable ap.wkg.workgroupProjectLink.csvAllowedProjectState MUST BE DEFINED";
				}else{
					//vado a immettere in una lista tutti gli stati ricavati
					configStatesArray = csvAllowedProjectState.split(',');
				}
				
				//ricavo l'iteratore lo uso per ciclare il set
				var projectSetIterator = projectSet.iterator();
				while( projectSetIterator.hasNext() ){
				
					//ricavo il singolo link e prendo il child che è il project
					var projectLinkElement = projectSetIterator.next();
					var project = projectLinkElement.getChild();
					//poi ricavo il suo stato e controllo che sia in uno degli stati ricavati dalla config
					var projectState = project.getWfState().getDescription();
					
					//vado a confrontare lo stato del progetto con tutti quelli ricavati
					//se non è tra quelli in configurazione, scateno il messaggio di errore
					//variabile per controllo, viene rigenerata per ogni progetto collegato
					var isPermited=false;
					for(var i=0; i<configStatesArray.length; i++){
						if(Packages.org.apache.commons.lang.StringUtils.equals(configStatesArray[i], projectState))
							isPermited=true;
					}
					
					if(isPermited==false){
						//uso questo stratagemma visto che non conosco quanti stati possano essere accettati
						var arrayStatesNamesAllArray = [];
						var arrayStatesNamesAllString="";
						
						//ciclo i nomi degli stati permessi e vado a ricavare il loro nome 'normale'
						for(var i=0; i<configStatesArray.length; i++){
							if(i>0)
								arrayStatesNamesAllString+=", ";
							
							arrayStatesNamesAllString += Packages.it.cilea.core.util.MessageUtilConstant.messageUtil.findMessage("wfState." + configStatesArray[i]);
						}
						arrayStatesNamesAllArray.push(arrayStatesNamesAllString);
						errors.reject("error.workgroup.project.stateMustBeAccepted", arrayStatesNamesAllArray, null);
					}
				}
			}
		

emailValidator

			
			var wfItemElement=object;
			var contactTypeId=wfItemElement.getGaDictionaryMap().get("contactType").getId();
			var contactTypeDictionary=gaService.getGaDictionary(contactTypeId);
			if (contactTypeDictionary.getDescription().equals("mail")){
				var pattern = Packages.java.util.regex.Pattern
						.compile("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[\\-A-Za-z0-9]+(\\.[\\-A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");
				var matcher = pattern.matcher(wfItemElement.getStringMap().get("description"));
				if (!matcher.matches()) {
					errors.rejectValue("stringMap[description]", "error.workgroup.contact.mail.invalidValue");
				}
			}
		

ownerCannotAddOtherOnesValidator

			
			//ricavo dalla request l'utente loggato in quel momento
			//NOTA: in caso di loginAs restituisce l'user impersonato
			var personalUserName=request.getUserPrincipal().getName();
			var personId=gaService.getUser(personalUserName).getPersonId();
			
			//inutile, ma mi serve per ricordarmi il contesto
			var wfItemElement=object;
			//ricavo wfItem completo, non mi serve il fragment dato che non posso comunque 
			var wfItem= wfService.getWfItem(wfItemElement.getWfItemId()); 
			
			//cerco tra gli owner se c'è la persona al momento loggata
			var ownerWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","owner", wfService);
			var ownerWfElementSetIterator=ownerWfElementSet.iterator();
			
			while(ownerWfElementSetIterator.hasNext()){
				var ownerElement=ownerWfElementSetIterator.next();
				var owner=ownerElement.getPersonMap().get("ownerId");
				if(owner.getId()==personId){
					errors.reject("error.workgroup.owner.cannotAddOtherOnes");
				}
			}
		

ownerCannotDeleteOtherOnesValidator

			
			//ricavo dalla request l'utente loggato in quel momento
			//NOTA: in caso di loginAs restituisce l'user impersonato
			var personalUserName=request.getUserPrincipal().getName();
			var personId=gaService.getUser(personalUserName).getPersonId();
			
			//inutile, ma mi serve per ricordarmi il contesto
			var wfItemElement=object;
			//ricavo wfItem completo, non mi serve il fragment dato che non posso comunque 
			var wfItem= wfService.getWfItem(wfItemElement.getWfItemId()); 
			
			//cerco tra gli owner se c'è la persona al momento loggata
			var ownerWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","owner", wfService);
			var ownerWfElementSetIterator=ownerWfElementSet.iterator();
			
			while(ownerWfElementSetIterator.hasNext()){
				var ownerElement=ownerWfElementSetIterator.next();
				var owner=ownerElement.getPersonMap().get("ownerId");
				if(owner.getId()==personId){
					errors.reject("error.workgroup.owner.cannotDeleteOtherOnes");
				}
			}
		

internalRepresentativeCannotEditOwnersValidator

			
			//ricavo dalla request l'utente loggato in quel momento
			//NOTA: in caso di loginAs restituisce l'user impersonato
			var personalUserName=request.getUserPrincipal().getName();
			var personId=gaService.getUser(personalUserName).getPersonId();
			
			//inutile, ma mi serve per ricordarmi il contesto
			var wfItemElement=object;
			//ricavo wfItem completo, non mi serve il fragment dato che non posso comunque 
			var wfItem= wfService.getWfItem(wfItemElement.getWfItemId()); 
			
			//cerco tra gli internalRepresentative se c'è la persona al momento loggata
			var internalRepresentativeWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalRepresentative", wfService);
			var internalRepresentativeWfElementSetIterator=internalRepresentativeWfElementSet.iterator();
			
			while(internalRepresentativeWfElementSetIterator.hasNext()){
				var internalRepresentativeElement=internalRepresentativeWfElementSetIterator.next();
				var internalRepresentative=internalRepresentativeElement.getPersonMap().get("internalRepresentative");
				if(internalRepresentative.getId()==personId){
					errors.reject("error.workgroup.internalRepresentative.cannotEditOwners");
				}
			}
		

wfActionLogicSaveExCoordinatorToContributor

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveExCoordinatorToContributor

wfActionLogicSaveContributorDefault
Questa action logic serve per generare i task necessari per rendere visibile l'oggetto nella visione personale dei partecipanti.
I task vengono generati in automatico in fase di transizione da uno stato ad un altro.
Ci sono casi però dove vengono modificate delle informazioni senza effettuare nessuna transizione di stato come ad esempio il caso in cui venga aggiunto un nuovo partecipante ad un progetto che è già nello stato corretto.
Questa action logic, se agganciata in save, consente di generare i task per rendere visibile l'oggetto anche in visione personale del nuovo partecipante.

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveContributorDefault

wfActionLogicSaveTutorDefault

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveTutorDefault

wfActionLogicSaveOtherCoordinatorDefault

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveOtherCoordinatorDefault

wfActionLogicSaveDateHistory

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveDateHistory

wfActionLogicSaveInvolvedDepartment

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveInvolvedDepartment

wfActionLogicSaveProjectNazInternazDepartmentValidation

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveProjectNazInternazDepartmentValidation

wfActionLogicLoadNazInternaz

it.cilea.wf.surplus.logic.action.load.WfActionLogicLoadNazInternaz

wfActionLogicEnterSetForwardInConfirmedDate

if (wfItem.getDateMap().get('forwardInConfirmedDate')==null) wfItem.getDateMap().put('forwardInConfirmedDate',java.util.Calendar.getInstance());

wfActionLogicEnterSetForwardInCompliantDate

if (wfItem.getDateMap().get('forwardInCompliantDate')==null) wfItem.getDateMap().put('forwardInCompliantDate',java.util.Calendar.getInstance());

wfActionLogicSaveContributorInvitation

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveContributorInvitation

wfActionLogicSaveMultipleOrganizationUnit
Questa action logic serve per generare i task necessari per rendere visibile l'oggetto in visione dipartimentale.
I task vengono generati in automatico in fase di transizione da uno stato ad un altro.
Ci sono casi però dove vengono modificate delle informazioni senza effettuare nessuna transizione di stato come ad esempio il caso in cui venga aggiunto un dipartimento ad un progetto che è già nello stato corretto.
Questa action logic, se agganciata in save, consente di generare i task per rendere visibile l'oggetto anche in visione dipartimentale.

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveMultipleOrganizationUnit

wfActionLogicSaveMultipleOwner
Questa action logic serve per generare i task necessari per rendere visibile l'oggetto nella visione personale dei responsabili scientifici
I task vengono generati in automatico in fase di transizione da uno stato ad un altro.
Ci sono casi però dove vengono modificate delle informazioni senza effettuare nessuna transizione di stato come ad esempio il caso in cui venga aggiunto un nuovo responsabile scientifico ad un progetto che è già nello stato corretto.
Questa action logic, se agganciata in save, consente di generare i task per rendere visibile l'oggetto anche in visione personale del nuovo responsabile scientifico.

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveMultipleOwner

wfActionLogicSaveMultipleAdministrativeOwner
Questa action logic serve per generare i task necessari per rendere visibile l'oggetto nella visione personale dei referenti amministrativi
I task vengono generati in automatico in fase di transizione da uno stato ad un altro.
Ci sono casi però dove vengono modificate delle informazioni senza effettuare nessuna transizione di stato come ad esempio il caso in cui venga aggiunto un nuovo referente amministrativo ad un progetto che è già nello stato corretto.
Questa action logic, se agganciata in save, consente di generare i task per rendere visibile l'oggetto anche in visione personale del nuovo referente amministrativo.

it.cilea.wf.surplus.logic.action.save.WfActionLogicSaveMultipleAdministrativeOwner

wfActionLogicVersionize

it.cilea.wf.logic.WfActionLogicVersionize

wfActionLogicEnterMailSender
Questa action logic serve per inviare segnalazioni via mail ai vari attori del flusso.
TODO

wfStartLogicStandardIdentifier
Questa logica viene eseguita in fase di creazione di un nuovo oggetto.
Viene effetuata la costruzione dell'identificativo dell'oggetto seguendo le seguenti regole:
<CODICE>-<PROGRESSIVO>

Per maggiori dettagli cfr. excel modello dati dell'entità in questione e la tassonomia ap-item-type.xls

			var sourceItemTypeCode=wfService.getWfItemType(wfItem.getWfItemTypeId()).getCode();		
			var identifier=sourceItemTypeCode+"-";
						
			var sequenceName = "item_" + sourceItemTypeCode + "_seq";
			var counter = wfService.updateSequence(sequenceName);
				
			var counterString;
			if (counter < 10)
				counterString = "000" + counter;
			else if (counter < 100)
				counterString = "00" + counter;
			else if (counter < 1000)
				counterString = "0" + counter;
			else
				counterString = "" + counter;
			
			identifier+=counterString;			
			wfItem.setIdentifier(identifier);						
			

wfStartLogicYearFromProposalStartDateIdentifier
Questa logica viene eseguita in fase di creazione di un nuovo progetto.
Viene effetuata la costruzione dell'identificativo dell'oggetto seguendo le seguenti regole:
<ANNO>-<CODICE>-<PROGRESSIVO>

Per maggiori dettagli cfr. excel modello dati dell'entità Progetto e la tassonomia ap-item-type.xls

			var startDate=wfItem.getDateMap().get("proposalStartDate");
			var year=startDate.get(Packages.java.util.Calendar.YEAR);
			
			var yearString=new Packages.java.lang.Integer(year).toString();
			
			var sourceItemTypeCode=wfItem.getWfItemType().getCode();
			
			var identifier=yearString+"-"+sourceItemTypeCode+"-";
						
			var sequenceName = "item_" + sourceItemTypeCode + "_" + year + "_seq";
			var counter = wfService.updateSequence(sequenceName);
	
			var counterString;
			if (counter < 10)
				counterString = "000" + counter;
			else if (counter < 100)
				counterString = "00" + counter;
			else if (counter < 1000)
				counterString = "0" + counter;
			else
				counterString = "" + counter;
			
			identifier+=counterString;			
			wfItem.setIdentifier(identifier);
		

wfStartLogicYearFromStartDate
Questa logica viene eseguita in fase di creazione di un nuovo oggetto. Viene recuperato l'anno dalla data di inizio startDate

			var startDate=wfItem.getDateMap().get("startDate");
			var year=startDate.get(Packages.java.util.Calendar.YEAR);
			wfItem.setYear(new Packages.java.lang.Integer(year));									
			

wfStartLogicOwnerDependentIdentifier

		
			var person = null;
			var ownerElementSetIterator=wfItem.getWfItemElementMap().get("owner").iterator();
			var min = 0;
			while(ownerElementSetIterator.hasNext()){
				var element = ownerElementSetIterator.next()
				if(min == 0){
					min = element.getId;
					person = element.getPersonMap().get("ownerId");
				} else {
					if(min > element.getId){
						min = element.getId;
						person = element.getPersonMap().get("ownerId");
					}
				}
			}
			var startDate=wfItem.getDateMap().get("proposalStartDate");
			var year=startDate.get(Packages.java.util.Calendar.YEAR);
			var yearString=new Packages.java.lang.Integer(year).toString();
			yearString=yearString.substring(2);
			var sourceItemTypeCode=wfService.getWfItemType(wfItem.getWfItemTypeId()).getCode();

			var lastName=person.getLastName().replaceAll("\\s", "");
			lastName=lastName.replaceAll("'", "");
			lastName=(lastName.length()>=4)?lastName.substring(0,4):lastName.substring(0,lastName.length());
			lastName=lastName.toUpperCase();
			var firstName=person.getFirstName().substring(0,1);
			firstName=firstName.toUpperCase();	
			var identifier=sourceItemTypeCode+yearString+firstName+lastName+"_";
			var paramMap = new Packages.java.util.HashMap();
			paramMap.put("identifier", identifier);
			paramMap.put("excludeIdentifier", identifier+"M");
			var count=searchBuilderTemplate.getSingleObject("getMaxItemCountForGivenIdentifier", paramMap);
			var countString="";
			if (count<9)
				countString+="0";			
			countString+=(count.intValue()+1);
			identifier+=countString;			
			
			wfItem.setIdentifier(identifier);						
			

wfStartLogicAcademicField2000
Questa logica viene eseguita in fase di creazione di un nuovo oggetto.
Recupera il responsabile scientifico (owner), estrae il SSD relativo all'ultimo rapporto di lavoro valido prioritario relativo al contesto ricerca ed aggancia questa informazione all'oggetto radice.

								
				var person=null;	
			    person=wfItem.getPersonMap().get("owner");			
				var person2 = gaService.getPerson(person.getId());
				var positionLastSet = person2.getPositionLastSet();											
				var maxPriority2 = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(positionLastSet, "research", "academicField2000");
				positionLastSetIterator=positionLastSet.iterator();											
				while (positionLastSetIterator.hasNext()){
					var position=positionLastSetIterator.next();					
					if (maxPriority2 == null || maxPriority2.equals(position.getPriority())) {
						if ("research".equals(position.getDiscriminator()) && "academicField2000"
									.equals(position.getOrganizationUnit().getOrganizationUnitType().getDescription())) {
								var ssdElement=new Packages.it.cilea.wf.model.WfItemElement();
								ssdElement.setDiscriminator("academicField2000");
								ssdElement.setWfItemId(wfItem.getId());
								ssdElement.getOrganizationUnitMap().put("organizationUnit", position.getOrganizationUnit());
								wfService.saveOrUpdate(ssdElement);
								wfItem.getWfItemElementSet().add(ssdElement);
								break;			
						}
					}
				}
								
				true;
			

wfStartLogicMultipleOwners

			//caricamento owner
			var person=wfItem.getPersonMap().get("owner");
			if (person!=null){
				var startDate=wfItem.getDateMap().get("startDate");
				person=gaService.getPerson(person.getId());
				var ownerElement=new Packages.it.cilea.wf.model.WfItemElement();
				ownerElement.setDiscriminator("owner");
				ownerElement.setWfItemId(wfItem.getId());
				ownerElement.getPersonMap().put("ownerId", person);
				ownerElement.getDateMap().put("startDate", startDate);
				Packages.it.cilea.wf.util.WfUtil.addRoleInElementIfDefined(wfItem, ownerElement, wfService);			
				wfService.saveOrUpdate(ownerElement);
				wfItem.getWfItemElementSet().add(ownerElement);			
				wfItem.getPersonMap().put("owner", null);
					
				//caricamento dipartimento con data
				var ownerDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
				ownerDepartmentPositionSearch.setPersonId(person.getId());
				ownerDepartmentPositionSearch.setDate(startDate.getTime());
				ownerDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
				ownerDepartmentPositionSearch.setDiscriminator("research");
				var ownerDepartmentPositionSet = gaService.getPositionSearchList(ownerDepartmentPositionSearch, 0);
				var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(ownerDepartmentPositionSet, "research", "department");
				
				var ownerDepartmentPositionSetIterator=ownerDepartmentPositionSet.iterator();							
				while (ownerDepartmentPositionSetIterator.hasNext()){
					var position=ownerDepartmentPositionSetIterator.next();
					if (maxPriority == null || maxPriority.equals(position.getPriority())) {
						var internalOrganizationUnitElement=new Packages.it.cilea.wf.model.WfItemElement();
						internalOrganizationUnitElement.setDiscriminator("internalOrganizationUnit");
						internalOrganizationUnitElement.setWfItemId(wfItem.getId());
						internalOrganizationUnitElement.getOrganizationUnitMap().put("ouId", position.getOrganizationUnit());
						Packages.it.cilea.wf.util.WfUtil.addRoleInElementIfDefined(wfItem, internalOrganizationUnitElement, wfService);
						wfService.saveOrUpdate(internalOrganizationUnitElement);
						wfItem.getWfItemElementSet().add(internalOrganizationUnitElement);
						break;					
					}
				}
			}				
			true;
		

wfStartLogicMultipleInternalOrganizationUnits

			//caricamento internalOrganizationUnit			
			var internalOrganizationUnit=wfItem.getOrganizationUnitMap().get("ouId");
			if (internalOrganizationUnit!=null){
				internalOrganizationUnit=gaService.getOrganizationUnit(internalOrganizationUnit.getId());
				var internalOrganizationUnitElement=new Packages.it.cilea.wf.model.WfItemElement();						
				internalOrganizationUnitElement.setDiscriminator("internalOrganizationUnit");
				internalOrganizationUnitElement.setWfItemId(wfItem.getId());
				internalOrganizationUnitElement.getOrganizationUnitMap().put("ouId",internalOrganizationUnit);			
				Packages.it.cilea.wf.util.WfUtil.addRoleInElementIfDefined(wfItem, internalOrganizationUnitElement, wfService);
				wfService.saveOrUpdate(internalOrganizationUnitElement);
				wfItem.getWfItemElementSet().add(internalOrganizationUnitElement);
				wfItem.getOrganizationUnitMap().put("ouId", null);
			}			
			true;
		

wfStartLogicAdministrativeOwnerFromUser
Questa logica viene eseguita in fase di creazione di un nuovo oggetto.
Aggiunge il referente amministrativo all'oggetto che si sta creando.
Precisamente:

Ad esempio supponiamo la variabile di conf ap.prj.administrativeOwner.inheritFromLoggedUserIfResourcePresent=/DEPARTMENT.profile,/RESEARCH_DIVISION.profile.
Questo vuol dire che se un utente che appartiene a un team con profili dipartimentali o divisione ricerca effettua la creazione di un oggetto, verrà inserito lui stesso come referente amministrativo. Per maggiori dettagli cfr. excel modello dati dell'entità in questione.

			var typeForConfig;
			var itemType = wfService.getWfItemType(wfItem.getWfItemTypeId());
			if (!itemType.getParentWfItemTypeSet().isEmpty()) {
				var parentSetIterator = itemType.getParentWfItemTypeSet().iterator();
				while (parentSetIterator.hasNext()){
					var parent = parentSetIterator.next();
					if (!parent.getParentWfItemTypeSet().isEmpty()) {
						var parentParentSetIterator = parent.getParentWfItemTypeSet().iterator();
						while (parentParentSetIterator.hasNext()){
							var parentParent = parentParentSetIterator.next();
							typeForConfig = parentParent;
							break;
						}
					}
					break;
				}
			}
			var profiles = '';
			if(typeForConfig.getIdentifier() == 'CON' || typeForConfig.getIdentifier() == 'PRJ'){
				profiles = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap."+ typeForConfig.getIdentifier().toLowerCase() +".administrativeOwner.inheritFromLoggedUserIfResourcePresent");
				var profileArray = profiles.split(",");
				var gaUserDetail = Packages.it.cilea.ga.authorization.context.GaAuthorizationUserHolder.getUser();	
				for(i in profileArray){
					if(gaUserDetail.hasAuthorities(profileArray[i])){
						var administrativeOwnerElement = new Packages.it.cilea.wf.model.WfItemElement();
						administrativeOwnerElement.setDiscriminator("administrativeOwner");
						administrativeOwnerElement.setWfItemId(wfItem.getId());
						
						var person = gaService.getPerson(gaUserDetail.getPersonId())
						
						administrativeOwnerElement.getPersonMap().put("administrativeOwner", person);
						
						wfService.saveOrUpdate(administrativeOwnerElement);
						wfItem.getWfItemElementSet().add(administrativeOwnerElement);			
						
						break;
					}
				}
			}
					
			true;
		

multipleOwnerValidator

			
			var ownerWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","owner", wfService);
			if(ownerWfElementSet.isEmpty()){
				errors.reject("error.owner.required");
			}
			
		

intellectualPropertyOwnerValidator

			
			//non mi importa in che stato sono, vado sempre a controllare dove potrei trovare l'owner
			var ownerInMap = object.getPersonMap().get("owner");
			var ownerWfElementSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","owner", wfService);
			
			if(ownerInMap==null){
				if(ownerWfElementSet.isEmpty())
					errors.reject("error.intellectualProperty.owner.required");
			}
			
		

startDateAndEndDateValidator
Questa validazione controlla che le date di inizio e fine siano coerenti
Dal punto di vista del modello dati si tratta degli attributi startDate e endDate
Per maggiori dettagli cfr. excel modello dati dell'entità in questione

		
			if(object.getDateMap().get("endDate") != null && object.getDateMap().get("startDate") != null){
				if(object.getDateMap().get("startDate").getTime().after(object.getDateMap().get("endDate").getTime())){
					errors.reject("error.date.startDateEndDateNotCompatible");					
				}			
			}
		

startDateOfElementAfterStartDateOfItemValidator

			var wfItemElementStartDate=object.getDateMap().get("startDate");
			var wfItemStartDate=object.getWfItem().getDateMap().get("startDate");
			var wfItemEndDate=object.getWfItem().getDateMap().get("endDate");
			
			var formatter =  Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");						
			
			if( wfItemElementStartDate!= null && wfItemStartDate && (wfItemElementStartDate.before(wfItemStartDate) || (wfItemEndDate!=null && wfItemElementStartDate.after(wfItemEndDate)))  ){
				var suffixMessage=" - ";
				if (wfItemEndDate!=null){
					suffixMessage+=formatter.format(wfItemEndDate.getTime());
				} else 
					suffixMessage+="<QUALSIASI DATA MAGGIORE DELLA DATA DI INIZIO>";
				errors.rejectValue("dateMap[startDate]", "error.date.startDateOfElementAfterStartDateOfItemValidator", [formatter.format(wfItemStartDate.getTime())+suffixMessage], null);					
			}			
			
		

internalOrganizationUnitValidator

			
			var internalOrganizationUnitWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);
			if(internalOrganizationUnitWfElementSet.isEmpty()){
				errors.reject("error.internalOrganizationUnit.required");
			}
		

contributorValidator

			
			var contributorWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","contributor", wfService);
			if(contributorWfElementSet.isEmpty()){
				errors.reject("error.contributor.required");
			}
		

keywordErcValidator

			
			var keywordErcWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","keywordErc", wfService);
			if(keywordErcWfElementSet.isEmpty()){
				errors.reject("error.keywordErc.required");
			}
		

keywordAtecoValidator

			
			var keywordAtecoWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","keywordAteco", wfService);
			if(keywordAtecoWfElementSet.isEmpty()){
				errors.reject("error.keywordAteco.required");
			}
		

researchLineValidator

			
			var researchLineWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","researchLine", wfService);
			if(researchLineWfElementSet.isEmpty()){
				errors.reject("error.researchLine.required");
			}
		

checkDateExtensionValidator
Questa validazione controlla la coerenza delle date inserite.
Precisamente, viene controllato che:


Per maggiori dettagli cfr. excel modello dati dell'entità in questione.
Questa validazione viene attivata SOLO se ap.checkDateExtensionValidator.enabled=true

	
			var enable=Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.checkDateExtensionValidator.enabled");
			if(enable.equalsIgnoreCase("true")){					   
				var startDate=object.getDateMap().get("startDate");
				var endDate=object.getDateMap().get("endDate");		
				if(startDate ==null){
					errors.reject("error.notNull.fieldLabelKey", [messageUtil.findMessage("label.project.startDate")], null);		
				}
				if(endDate ==null){
					errors.reject("error.notNull.fieldLabelKey", [messageUtil.findMessage("label.project.endDate")], null);			
				}			
				if(endDate != null && startDate != null){
					if(startDate.getTime().after(endDate.getTime())){
						errors.reject("error.date.startDateEndDateNotCompatible");					
					}			
				}
				var durationInMonth=object.getIntegerMap().get("durationInMonth");
				if(durationInMonth==null||durationInMonth<0){
						errors.reject("error.project.durationInMonth");		
				}
			    var wfItemElementSet = object.getWfItemElementSet();			
				if(endDate!=null&&startDate!=null){													
					var extensionSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "extension", wfService);
					var extensionSetIterator=extensionSet.iterator();
					while(extensionSetIterator.hasNext()){
						var extensionElement=extensionSetIterator.next();	
						if (endDate.compareTo(extensionElement.getDateMap().get("currentEndDate"))<0 ||
							durationInMonth<extensionElement.getIntegerMap().get("currentDurationInMonth")){	
							errors.reject("error.project.extension.date");					
						}
						if(extensionElement.getDateMap().get("previousEndDate").getTime().after(extensionElement.getDateMap().get("currentEndDate").getTime())){
							errors.reject("error.date.startDateEndDateNotCompatible");					
						}							
					}
					
					approvalSet= Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "approval", wfService);
					var approvalSetIterator=approvalSet.iterator();
					while(approvalSetIterator.hasNext()){
						var approvalElement=approvalSetIterator.next();	
						var approvalDate=approvalElement.getDateMap().get("approvalDate");
						if (approvalDate!=null){
							if(approvalDate.getTime().after(startDate.getTime())){
							  errors.reject("error.project.approval.date");
							}
						}					
					}					
				};
			}	
		

ownerPositionStartValidator

			function showOrHiddenError(error, mandatory){
				if(mandatory){				
					errors.reject(error);
				}else {			
					log.error(error);					
				}	
			}			
			function showOrHiddenValueError(value,error, mandatory){
				if(mandatory){				
					errors.rejectValue(value,error);
				}else {			
					log.error(error);					
				}	
			}
			if (object.getId()==null){
				var mandatory=Packages.it.cilea.wf.util.WfUtil.getMandatory(object,"owner");							
				if (object.getPersonMap().get("owner")==null)
					showOrHiddenValueError("personMap[owner]","error.owner.required", mandatory);					
				else{
					var typeForConfig = wfService.getWfItemType(wfItem.getWfItemTypeId());
					if (!typeForConfig.getParentWfItemTypeSet().isEmpty()) {
						var parentSetIterator = typeForConfig.getParentWfItemTypeSet().iterator();
						while (parentSetIterator.hasNext()){
							typeForConfig = parentSetIterator.next();
							if (!typeForConfig.getParentWfItemTypeSet().isEmpty()) {
								var parentParentSetIterator = typeForConfig.getParentWfItemTypeSet().iterator();
								while (parentParentSetIterator.hasNext()){
									typeForConfig = parentParentSetIterator.next();
									break;
								}
							}
							break;
						}
					}
				
					var dateDiscriminator = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap." + typeForConfig.getIdentifier().toLowerCase() + ".ownerPositionStartValidator.dateMap.discriminator");
					if(dateDiscriminator == null){
						dateDiscriminator = 'startDate';
					}
					if(object.getDateMap().get(dateDiscriminator)==null)
						showOrHiddenValueError("dateMap["+ dateDiscriminator +"]","error."+dateDiscriminator+".required", mandatory);						
					else{
					
						var owner= object.getPersonMap().get("owner");		
						var ownerPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
						ownerPositionSearch.setPersonId(owner.getId());
						ownerPositionSearch.setDate(object.getDateMap().get(dateDiscriminator).getTime());
						ownerPositionSearch.setOrganizationUnitTypeDescription("department");
						ownerPositionSearch.setDiscriminator("research");
						var ownerPositionSet = gaService.getPositionSearchList(ownerPositionSearch, 0);
							
						if(ownerPositionSet.isEmpty()){
							showOrHiddenError("error.owner.emptyResearchPosition",mandatory);							
						}
					}	
				}
			}
		

multipleOwnerPositionConsistencyStartDateValidator

			//innanzitutto controllo che non sia un oggetto appena creato
			if (object.getId()!=null){
			
				//poi controllo che non ci siano stati errori, se non ce ne sono stati allora vado avanti
				//controllo io se le info che mi servono ci sono o meno
				//if(!errors.hasErrors()){
				
					//poi ricavo se la variabile di configurazione per il controllo è attiva o meno
					//se lo è, allora scateno la validazione
					var mandatory=Packages.it.cilea.wf.util.WfUtil.getMandatory(object,"owner");
					if(mandatory){
					
						//poi controllo che il fragment degli owner non sia vuoto
						var ownerWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "it.cilea.wf.model.WfItemElement","owner", wfService);
						if(!ownerWfElementSet.isEmpty()){
						
							//poi controllo che vi sia la data di inizio
							var startDate=object.getDateMap().get("startDate");
							//log.error("startDate: "+startDate.getTime());
							if(startDate!=null){
							
								//a questo punto ho tutte le informazioni che mi servono per la validazione
								//vado a ciclare il set degli owner alla ricerca di qualcuno che non abbia una posizione nella data di inizio specificata
								//se ne trovo anche solo uno scateno il messaggio di errore
								
								var ownerSetIterator = ownerWfElementSet.iterator();
								while (ownerSetIterator.hasNext()){
									var ownerElement = ownerSetIterator.next();	//ricavo il singolo element
									var ownerPerson= ownerElement.getPersonMap().get("ownerId");	//ricavo l'owner
									
									//setto il positionSearch in modo da trovare se ho delle position di ricerca per quella data
									var ownerPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
									//log.error("owner id: "+ownerPerson.getId());
									ownerPositionSearch.setPersonId(ownerPerson.getId());
									ownerPositionSearch.setDate(startDate.getTime());
									ownerPositionSearch.setOrganizationUnitTypeDescription("department");
									ownerPositionSearch.setDiscriminator("research");
									var ownerPositionSet = gaService.getPositionSearchList(ownerPositionSearch, 0);
										
									if(ownerPositionSet.isEmpty()){
										errors.reject("error.multipleOwner.emptyResearchPosition");
									}
								}//fine ciclo tra gli owner
								
							}else{
								errors.reject("error.startDate.required");
							}
						}else{
							errors.reject("error.owner.required");
						}
					}
				//}//controllo errori
			}
		

getYearFromStartDateValidator

			var startDate=object.getDateMap().get("startDate");
			//log.error("startDate: "+startDate.getTime());
			if(startDate!=null){
				object.year=startDate.get(startDate.YEAR);
			}else{
				errors.reject("error.startDate.required");
			}
		

addOrgUnitFromNewOwnerValidator

			function showOrHiddenError(error, mandatory){
				if(mandatory){				
					errors.reject(error);
				}else {			
					log.error(error);					
				}	
			}
			//script per aggiunta nuovo dipartimento nuovo owner
			//prima controllo che non ci siano stati errori
			//se non ci sono stati allora vado avanti
			if(!errors.hasErrors()){
				
				//inutile, ma mi serve per ricordarmi il contesto
				var wfItemElement=object;							
				var wfItem= wfService.getWfItem(wfItemElement.getWfItemId()); 
				var fragmentInfo=Packages.it.cilea.core.fragment.util.FragmentUtil.getFragmentableInfo(wfItemElement);
				var newOwnerToAdd= wfItemElement.getPersonMap().get(fragmentInfo.getDiscriminator()+"Id");
				var person= gaService.getPerson(newOwnerToAdd.getPersonId());
				var mandatory=Packages.it.cilea.wf.util.WfUtil.getMandatory(wfItem,fragmentInfo.getDiscriminator());
				if(wfItem.getDateMap().get("startDate")==null)
					showOrHiddenError("error.startDate.required",mandatory);
				else{					
					//ricerca del dipartimento associato alla persona
					var ownerDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
					ownerDepartmentPositionSearch.setPersonId(person.getId());
					ownerDepartmentPositionSearch.setDate(wfItem.getDateMap().get("startDate").getTime());
					ownerDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
					ownerDepartmentPositionSearch.setDiscriminator("research");
					var ownerDepartmentPositionSet = gaService.getPositionSearchList(ownerDepartmentPositionSearch, 0);
					
					if(ownerDepartmentPositionSet.isEmpty()){
						showOrHiddenError("error.owner.emptyResearchPosition",mandatory);

					}else{
					
						var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(ownerDepartmentPositionSet, "research", "department");
					
						//ciclo posittion in cerca del dipartimento del nuovo owner
						var newOwnerOrgUnit= null;
						var ownerDepartmentPositionSetIterator=ownerDepartmentPositionSet.iterator();							
						while (ownerDepartmentPositionSetIterator.hasNext()){
							var position=ownerDepartmentPositionSetIterator.next();
							if (maxPriority == null || maxPriority.equals(position.getPriority())) {
								newOwnerOrgUnit=position.getOrganizationUnit();
							}
						}
						
						//cerco se c'è già il dipartimento, se no lo aggiungo
						var orgUnitWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);
						var orgUnitWfElementSetIterator=orgUnitWfElementSet.iterator();
						var alreadyAdded=false;
						while(orgUnitWfElementSetIterator.hasNext()){
							var orgUnitElement=orgUnitWfElementSetIterator.next();
							var orgUnit= orgUnitElement.getOrganizationUnitMap().get("ouId");
							if(orgUnit.getOrganizationUnitId()==newOwnerOrgUnit.getOrganizationUnitId()){
								alreadyAdded=true;
							}
						}
						
						if(!alreadyAdded){
							var ouIe=new Packages.it.cilea.wf.model.WfItemElement();
							ouIe.setDiscriminator("internalOrganizationUnit");
							ouIe.setWfItemId(wfItem.getId());
							ouIe.getOrganizationUnitMap().put("ouId", newOwnerOrgUnit);
							var roleId=wfItemElement.getWfDictionaryMap().get("roleId");
							if (roleId!=null&&fragmentInfo!=null){
								Packages.it.cilea.wf.util.WfUtil.addRoleInElementIfPresent(wfItem,roleId,fragmentInfo, ouIe, wfService);
							}					
							Packages.it.cilea.core.fragment.util.FragmentUtil.addNewFragment(ouIe, wfService);				
						}
					}
				}
			}
		

notEmptyResearchPositionValidatorTutor

			
			//validator che controlla se il tutor inserito abbia una posizione di ricerca presso un dipartimento
			
			function showOrHiddenError(error, mandatory){
				if(mandatory){				
					errors.reject(error);
				}else {			
					//log.error(error);					
				}	
			}
			
			//prima controllo che non ci siano stati errori
			//se non ci sono stati allora vado avanti
			if(!errors.hasErrors()){
				
				//inutile, ma mi serve per ricordarmi il contesto
				var wfItemElement=object;							
				
				var fragmentInfo=Packages.it.cilea.core.fragment.util.FragmentUtil.getFragmentableInfo(wfItemElement);
				
				//var newTutorToAdd= wfItemElement.getPersonMap().get(fragmentInfo.getDiscriminator()+"Id");	//no così visto che ha discriminator particolare
				var newTutorToAdd= wfItemElement.getPersonMap().get("contributorId");
				var person= gaService.getPerson(newTutorToAdd.getPersonId());
				
				var wfItem= wfService.getWfItem(wfItemElement.getWfItemId());
				var mandatory=Packages.it.cilea.wf.util.WfUtil.getMandatory(wfItem,fragmentInfo.getDiscriminator());
				
				if(wfItemElement.getDateMap().get("startDate")==null)
					errors.reject("error.startDate.required");
				else{					
					//ricerca del dipartimento associato alla persona
					var tutorDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
					tutorDepartmentPositionSearch.setPersonId(person.getId());
					tutorDepartmentPositionSearch.setDate(wfItemElement.getDateMap().get("startDate").getTime());
					tutorDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
					tutorDepartmentPositionSearch.setDiscriminator("research");
					var tutorDepartmentPositionSet = gaService.getPositionSearchList(tutorDepartmentPositionSearch, 0);
					
					if(tutorDepartmentPositionSet.isEmpty()){
						showOrHiddenError("error.tutor.emptyResearchPosition",mandatory);
					}
				}
			}
		

deleteOrgUnitFromOldOwnerValidator

			//script per eliminazione dipartimento vecchio owner
			
			function getDepartmentFromPerson(wfItem, person){
				//ricerca del dipartimento associato alla persona
				var personDepartmentPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
				personDepartmentPositionSearch.setPersonId(person.getId());
				personDepartmentPositionSearch.setDate(wfItem.getDateMap().get("startDate").getTime());
				personDepartmentPositionSearch.setOrganizationUnitTypeDescription("department");
				personDepartmentPositionSearch.setDiscriminator("research");
				var personDepartmentPositionSet = gaService.getPositionSearchList(personDepartmentPositionSearch, 0);
				var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(personDepartmentPositionSet, "research", "department");
				
				//ciclo posittion in cerca del dipartimento della person
				var personDepartmentPositionSetIterator=personDepartmentPositionSet.iterator();							
				while (personDepartmentPositionSetIterator.hasNext()){
					var position=personDepartmentPositionSetIterator.next();
					if (maxPriority == null || maxPriority.equals(position.getPriority())) {
						return position.getOrganizationUnit();
					}
				}
			}
			
			//prima controllo che non ci siano stati errori
			//se non ci sono stati allora vado avanti
			if(!errors.hasErrors()){
				
				//inutile, ma mi serve per ricordarmi il contesto
				var wfItemElement=object;
				var wfItem= wfService.getWfItem(wfItemElement.getWfItemId()); 
				
				var oldOwnerToDelete= wfItemElement.getPersonMap().get("ownerId");
				var person= gaService.getPerson(oldOwnerToDelete.getPersonId());
				//ricavo il dipartimento della persona
				var oldOwnerOrgUnit= getDepartmentFromPerson(wfItem, person);
				
				//cerco tra gli owner se c'è già qualcuno associato allo stesso dipartimento
				var ownerWfElementSet=Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","owner", wfService);
				var ownerWfElementSetIterator=ownerWfElementSet.iterator();
				
				//mi serve per verificare se altri owner hanno il dipartimento in comune
				//se ne trovo un altro con lo stesso dipartimento, incremento
				var ownersWithCommonDepartment=0;
				
				while(ownerWfElementSetIterator.hasNext()){
					var ownerElement=ownerWfElementSetIterator.next();
					var owner=ownerElement.getPersonMap().get("ownerId");
					//per non contare  anche l'owner che sto togliendo
					if(owner.getId()!=person.getId()){
						var ownerOrgUnit=getDepartmentFromPerson(wfItem, owner);
						if(ownerOrgUnit.getOrganizationUnitId()==oldOwnerOrgUnit.getOrganizationUnitId()){
							ownersWithCommonDepartment++;
						}
					}
				}
				
				if(ownersWithCommonDepartment==0){
					var ouIe=null;
					var internalOrganizationUnitSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(wfItem, "it.cilea.wf.model.WfItemElement","internalOrganizationUnit", wfService);
					var internalOrganizationUnitSetIterator=internalOrganizationUnitSet.iterator();
					while(internalOrganizationUnitSetIterator.hasNext()){
						var orgUnitElement=internalOrganizationUnitSetIterator.next();
						var orgUnit= orgUnitElement.getOrganizationUnitMap().get("ouId");
						if(orgUnit.getOrganizationUnitId()==oldOwnerOrgUnit.getOrganizationUnitId()){
							ouIe=orgUnitElement;
						}
					}
					Packages.it.cilea.core.fragment.util.FragmentUtil.deleteFragment(ouIe, wfService);
				}
			}
		

ownerWithSameDepartmentAsHeadValidator
Questa validazione viene triggerata in fase di creazione di un nuovo oggetto in visione dipartimentale.
Verifica che l'utente che sta creando un nuovo oggetto a livello dipartimentale, specifichi come responsabile scientifico una persona che afferisce al proprio dipartimento (alla data di inizio specificata per l'oggetto creato).
La variabile di configurazione ap.<tipologia>.ownerWithSameDepartmentAsHeadValidator.dateMap.discriminator contiene il nome dell'attributo da usare per recuperare la data di inizio relativa all'oggetto creato.
Questa validazione prende in considerazione anche la variabile di configurazione ap.<tipologia>.owner.internalOrganizationUnit.mandatory che specifica se il responsabile scientifico debba obbligatoriamente avere un'afferenza su un dipartimento.

			//validator per headofdepartment
			//prima controllo che non ci siano stati errori		
			if(!errors.hasErrors()){				
				var list=gaAuthorizationService.getAuthoritiesInfoSelectableDisplayList("/DEPARTMENT/ap.profile");
				//controllo per verificare se sono in visione dipartimentale o no
				
				if(list.get(0).getIdentifyingValue()!=-1){
					if (object.getId()==null){			
						//gli altri controlli non li faccio, ci pensano gli altri validator
						
						var owner= object.getPersonMap().get("owner");		
						var ownerPositionSearch = new Packages.it.cilea.ga.command.PositionSearchCommand();
						ownerPositionSearch.setPersonId(owner.getId());
						
						var typeForConfig = wfService.getWfItemType(object.getWfItemTypeId());
						if (!typeForConfig.getParentWfItemTypeSet().isEmpty()) {
							var parentSetIterator = typeForConfig.getParentWfItemTypeSet().iterator();
							while (parentSetIterator.hasNext()){
								typeForConfig = parentSetIterator.next();
								if (!typeForConfig.getParentWfItemTypeSet().isEmpty()) {
									var parentParentSetIterator = typeForConfig.getParentWfItemTypeSet().iterator();
									while (parentParentSetIterator.hasNext()){
										typeForConfig = parentParentSetIterator.next();
										break;
									}
								}
								break;
							}
						}
					
						var dateDiscriminator = Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap." + typeForConfig.getIdentifier().toLowerCase() + ".ownerWithSameDepartmentAsHeadValidator.dateMap.discriminator");
						if(dateDiscriminator == null){
							dateDiscriminator = 'startDate';
						}						
						
						ownerPositionSearch.setDate(object.getDateMap().get(dateDiscriminator).getTime());
						ownerPositionSearch.setOrganizationUnitTypeDescription("department");
						ownerPositionSearch.setDiscriminator("research");
						var ownerPositionSet = gaService.getPositionSearchList(ownerPositionSearch, 0);
						var maxPriority = Packages.it.cilea.ga.util.GaUtil.getMaxPriority(ownerPositionSet, "research", "department");						
						var mandatory=Packages.it.cilea.wf.util.WfUtil.getMandatory(object,"owner");							
						if(mandatory){
							//ciclo posittion in cerca del dipartimento della person
							var department=null;
							var ownerPositionSetIterator=ownerPositionSet.iterator();							
							while (ownerPositionSetIterator.hasNext()){
								var position=ownerPositionSetIterator.next();
								if (maxPriority == null || maxPriority.equals(position.getPriority())) {
									department=position.getOrganizationUnit();
									//log.error("department id: "+department.getOrganizationUnitId());
								}
							}						
							//uso un flag dato che devo ciclare su tutti i possibili dipartimenti
							var flag=false;
							var listIterator=list.iterator();
							if (department!=null){
								while(listIterator.hasNext()){
									var selectable=listIterator.next();
									//log.error("selectable getIdentifyingValue: "+selectable.getIdentifyingValue());							
									if(department.getOrganizationUnitId()==selectable.getIdentifyingValue()){
										flag=true;
									}	
								}
							}						
							if(!flag){
								errors.reject("error.owner.mustBeSameAsHead");
							}
						}
					}
				}
			}
		

departmentChangeRoleValidator
Questa validazione opera sull'elemento internalOrganizationUnit figlio dell'oggetto radice.
Se l'utente è in visione dipartimentale per il dipartimento X e tenta di modificare il ruolo del dipartimento X nell'oggetto radice, viene sollevato un errore se il nuovo ruolo prevede diritti inferiori.
Questa operazione viene impedita in quanto la modifica del ruolo porterebbe l'utente a non potere più operare su quell'oggetto.
Ad esempio se un utente accede in visione dipartimentale ad un progetto e cambia il ruolo del suo dipartimento da "Principale" ad "Aggregato", l'operazione viene impedita perché il ruolo "Aggregato" prevede diritti inferiori.
Questa operazione è consentita in visione completa per i team abilitati.
Per maggiori dettagli cfr. excel modello dati dell'entità in questione

	
			var ouIdToCheck = object.getIntegerMap().get("ouIdPreviousValue");			
			if (ouIdToCheck==null){
				ouIdToCheck=object.getOrganizationUnitMap().get("ouId").getId();
			}	
			
			var ouRoleToCheck = object.getIntegerMap().get("ouRolePreviousValue");			
			if (ouRoleToCheck==null){
				ouRoleToCheck=object.getWfDictionaryMap().get("ouRole").getId();
			}
					
		    var list=gaAuthorizationService.getAuthoritiesInfoSelectableDisplayList("/DEPARTMENT/ap.profile");
			//controllo per verificare se sono in visione dipartimentale o no
			var listIterator=list.iterator();				
			while(listIterator.hasNext()){
				var selectable=listIterator.next();				
				if(ouIdToCheck==selectable.getIdentifyingValue()){
					object.getOrganizationUnitMap().put("ouId",gaService.getOrganizationUnit(ouIdToCheck));
					object.getWfDictionaryMap().put("ouRole",wfService.getWfDictionary(ouRoleToCheck));
					wfService.saveOrUpdate(object);						 	
					errors.reject("error.changeRole.department.notAllowed");
				}	
			}		
		

departmentDeleteValidator
Questa validazione opera sull'elemento internalOrganizationUnit figlio dell'oggetto radice.
Se l'utente è in visione dipartimentale per il dipartimento X e tenta di eliminare il dipartimento X dall'oggetto radice, viene sollevato un errore in quanto cancellando questa associazione, l'utente non potrebbe più operare su quell'oggetto.
Questa operazione è consentita in visione completa per i team abilitati.
Per maggiori dettagli cfr. excel modello dati dell'entità in questione

	
			// Elenco dei miei dipartimenti 
		    var list=gaAuthorizationService.getAuthoritiesInfoSelectableDisplayList("/DEPARTMENT/ap.profile");
			//controllo per verificare se sono in visione dipartimentale o no
			var listIterator=list.iterator();		
			while(listIterator.hasNext()){
				var selectable=listIterator.next();			
				if(object.getOrganizationUnitMap().get("ouId").getId()==selectable.getIdentifyingValue()){
					errors.reject("error.changeRole.department.notAllowed");
				}	
			}
		

contributorAndOwnerValidatorWithStartEndDate
Questa validazione opera sugli elementi owner (responsabile scientifico) e contributor (partecipante) figli dell'oggetto radice.
Viene verificato che l'intervallo di validità degli oggetti figli siano compresi all'interno della validità dell'oggetto padre.
Gli attributi per le date di inizio e fine sono startDate e endDate sia per gli elementi owner e contributor che per l'oggetto padre.
Per maggiori dettagli cfr. excel modello dati dell'entità in questione.

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){						
				var elementSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "contributor", wfService);
				elementSet.addAll(Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService));
				if (elementSet.size()>0){
					var elementSetIterator = elementSet.iterator();				
					var wfItemStartDate = object.getDateMap().get("startDate");
					var wfItemEndDate = object.getDateMap().get("endDate");
					var formatter = Packages.org.apache.commons.lang.time.FastDateFormat.getInstance("dd/MM/yyyy");
					var elementWithWrongInterval=[];
								
					while (elementSetIterator.hasNext()){										
						var element = elementSetIterator.next();												
						var wfItemElementStartDate = element.getDateMap().get("startDate");
						
						if( wfItemElementStartDate != null && wfItemStartDate && (wfItemElementStartDate.before(wfItemStartDate) || (wfItemEndDate!=null && wfItemElementStartDate.after(wfItemEndDate)))  ){
							var discriminator = element.getDiscriminator();
							if(element.getDiscriminator().contains(".")){
							 	discriminator = element.getDiscriminator().substring(0, element.getDiscriminator().indexOf("."))
							}
							elementToEdit.push(element.getPersonMap().get(discriminator + "Id").getDisplayValue());
						}								
					}
					
					if (elementWithWrongInterval.length>0){
						errors.reject("error.contributorAndOwner.wrongInterval", [elementWithWrongInterval.toString()], "error.contributorAndOwner.wrongInterval");
					}			
				}				
			}
		

contributorAndOwnerStartDateValidator
Questa validazione opera sugli elementi owner (responsabile scientifico) e contributor (partecipante) figli dell'oggetto radice.
Viene verificato che per ogni owner e contributor, sia specificata la data di inizio validità (attributo startDate)
Per maggiori dettagli cfr. excel modello dati dell'entità in questione

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){						
				var elementSet = Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "contributor", wfService);
				elementSet.addAll(Packages.it.cilea.core.fragment.util.FragmentUtil.getCurrentFragmentSetByParentAndDiscriminator(object, "getWfItemElementSet", "it.cilea.wf.model.WfItemElement", "owner", wfService));
				if (elementSet.size()>0){
					var elementSetIterator = elementSet.iterator();				
					var elementToEdit = [];
								
					while (elementSetIterator.hasNext()){										
						var element = elementSetIterator.next();												
						var wfItemElementStartDate = element.getDateMap().get("startDate");
						
						if(wfItemElementStartDate == null && !wfItemElementStartDate){
							var discriminator = element.getDiscriminator();
							if(element.getDiscriminator().contains(".")){
							 	discriminator = element.getDiscriminator().substring(0, element.getDiscriminator().indexOf("."))
							}
							elementToEdit.push(element.getPersonMap().get(discriminator + "Id").getDisplayValue());
						}								
					}
					
					if (elementToEdit.length > 0){
						errors.reject("error.contributorAndOwner.startDate.required", [elementToEdit.toString()], "error.contributorAndOwner.startDate.required");
					}			
				}				
			}
		

notEditableByDepartmentValidator
Questa validazione controlla che l'utente corrente NON appartenga al team "Direttori di dipartimento cui negare accesso in modifica ai Progetti/Contratti".
Questo è un team con agganciata la funzione "Risorsa per Direttori di dipartimento cui negare accesso in modifica ai Progetti/Contratti" (/ap/department/onlyRead.function)

La visione dipartimentale consente a chiunque appartenga ai team "Profilo di dipartimento per XXX" di accedere con i diritti dipartimentali al flusso.
In questo team sono presenti sia i direttori di dipartimento che i referenti amministrativi.
Questa validazione consente l'accesso in scrittura ai soli referenti amministrativi.

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){		
				var gaUserDetail = Packages.it.cilea.ga.authorization.context.GaAuthorizationUserHolder.getUser();	
				var userId = gaUserDetail.getUserId();
				
				var searchCommand = new Packages.it.cilea.ga.command.TeamUserLinkSearchCommand();
				searchCommand.setUserId(userId);
				var linkList = gaService.getTeamUserLinkSearchList(searchCommand, 0);
				var listIterator = linkList.iterator();				
				while(listIterator.hasNext()){
					var teamUserLink = listIterator.next();		
					if(teamUserLink.getTeamId() == Packages.it.cilea.core.configuration.util.ConfigurationUtil.getConfigValue("ap.department.onlyRead.team")){
						errors.reject("error.operation.notallowed");
						break;
					}
				}	
			}
		

notCreatableByDepartmentValidator
Questa validazione controlla che l'utente corrente NON appartenga al team "Direttori di dipartimento cui negare accesso in creazione ai Progetti/Contratti".
Questo è un team con agganciata la funzione "Risorsa per Direttori di dipartimento cui negare accesso in modifica ai Progetti/Contratti" (/ap/department/onlyRead.function)

La visione dipartimentale consente a chiunque appartenga ai team "Profilo di dipartimento per XXX" di accedere con i diritti dipartimentali al flusso.
In questo team sono presenti sia i direttori di dipartimento che i referenti amministrativi.
Questa validazione consente l'accesso in scrittura ai soli referenti amministrativi.

	
			if (!Packages.java.lang.Boolean.TRUE.equals(wfItem.getBooleanMap().get("legacy"))){		
				var gaUserDetail = Packages.it.cilea.ga.authorization.context.GaAuthorizationUserHolder.getUser();	
				var authority = gaUserDetail.getCurrentAuthorityIdentifier();
				if(authority == "ROLE_DEPARTMENT"){
					var validateLogic = Packages.it.cilea.wf.WfConstant.VALIDATE_LOGIC_MAP.get("notEditableByDepartmentValidator");
					validateLogic.validate(request, object, errors);
				}
			}
		

wfActionLogicSaveDisplayAsDefault

it.cilea.wf.logic.action.save.WfActionLogicSaveDisplayAsDefault

wfActionLogicSaveYearFromStartDate

it.cilea.wf.logic.action.save.WfActionLogicSaveYearFromStartDate

notAllowedValidator

			
			errors.reject("error.operation.notallowed");				
		

checkCreationPermissionsValidator
Questa validazione viene scatenata in fase di creazione dell'oggetto.
Controlla che l'utente corrente abbia i permessi per creare la tipologia di oggetto in questione.
Agli utenti viene presentata sempre la lista dei tipi di oggetto che possono creare.
Questa validazione, comunque, serve per prevenire eventuali "hacking" di utenti che modificano volutamente il markup del form inserendo un tipo di oggetto per il quale non hanno le autorizzazioni.

			//da controllare solo in fase di prima creazione
			if (wfItem.getId()==null){
				var isCreateAllowed=Packages.it.cilea.wf.util.WfUtil.isWfItemTypeAllowedForCurrentUser(wfItem.getWfItemTypeId(), applicationContext);
				if (!isCreateAllowed){
					errors.reject("error.ap.wfItemType.creationNotAllowed");					
				}
			}				
		

sameDefinitionForGenericItemValidator
Questa validazione viene scatenata in fase di cambio di Tipo dell'oggetto.
Validatore che controlla che se si cambia tipo di flusso, questo nuovo tipo sia compatibile (same definition number) in modo che un tipo di progetto rimanga un tipo di progetto.

	
			//estraggo il wfItemId
			//log.error("entro nel validator sameDefinitionForGenericProjectValidator");
			var myNEWWfItemType = object.getWfItemTypeId();
			var myOLDWfItemType = object.getIntegerMap().get("wfItemTypeIdPreviousValue");
			if (myOLDWfItemType==null)
				throw "To use sameDefinitionForGenericItemValidator you MUST specify wfItemTypeIdPreviousValue hidden value";
			//log.error("dovrebbe essere il mio definition new:" + myNEWWfItemType + " old: " + myOLDWfItemType);
			
			//con il wfItemID tiro fuori tramite il wfservice la definition
			var newItemType=wfService.getWfItemType(myNEWWfItemType);
			var oldItemType=wfService.getWfItemType(myOLDWfItemType);
			//log.error("newItemType:"+newItemType+" oldItemType:"+oldItemType);
			
			//confronto le due definition se sono diverse vuol dire che il cambio di flusso non è compatibile
			if(!newItemType.getWfDefaultDefinitionId().equals(oldItemType.getWfDefaultDefinitionId())){
				object.setWfItemTypeId(myOLDWfItemType);
				errors.reject("error.ap.definitionError");
			}
		

changeItemTypeForNotSynchronizedItemValidator
Questa validazione viene scatenata in fase di cambio di Tipo dell'oggetto.
Non è possibile cambiare la tipologia, la scheda è già stata sincronizzata con U-GOV o l'utente non possiede i permessi sulla nuova tipologia selezionata.

	
			//estraggo il wfItemId
			
			var myNEWWfItemType = object.getWfItemTypeId();
			var myOLDWfItemType = object.getIntegerMap().get("wfItemTypeIdPreviousValue");
			if (myOLDWfItemType==null)
				throw "To use changeItemTypeValidator you MUST specify wfItemTypeIdPreviousValue hidden value";
			
			//confronto le due tipologie, se sono diverse e ho già sincronizzato vuol dire che il cambio di tipologia non è compatibile
			
			if(myNEWWfItemType != myOLDWfItemType){
				
				if(object.getStringMap().get("ugovIdentifier") != null){
					object.setWfItemTypeId(myOLDWfItemType);
					errors.reject("error.ap.itemTypeError");
				} else {
					var isCreateAllowed=Packages.it.cilea.wf.util.WfUtil.isWfItemTypeAllowedForCurrentUser(myOLDWfItemType, applicationContext);
					if(!Packages.java.lang.Boolean.TRUE.equals(isCreateAllowed)){
						errors.reject("error.ap.itemTypeError");
					}
				}
			
			}
		

changeItemTypeForSynchronizedItemValidator
Questa validazione viene scatenata in fase di cambio di Tipo dell'oggetto in un determinato stato del flusso.
Non è possibile cambiare la tipologia in questo stato del flusso in quanto non compatibile con altri stati di altri flussi.

	
			//estraggo il wfItemId
			
			var myNEWWfItemType = object.getWfItemTypeId();
			var myOLDWfItemType = object.getIntegerMap().get("wfItemTypeIdPreviousValue");
			if (myOLDWfItemType==null)
				throw "To use changeItemTypeValidator you MUST specify wfItemTypeIdPreviousValue hidden value";
			
			if(myNEWWfItemType != myOLDWfItemType){
				object.setWfItemTypeId(myOLDWfItemType);
				errors.reject("error.ap.itemTypeError.step2");
			}
		

wfActionLogicSaveOwnerDependentNewIdentifier

			var myNEWWfItemType = object.getWfItemTypeId();
			var myOLDWfItemType = object.getIntegerMap().get("wfItemTypeIdPreviousValue");
			
			if (myOLDWfItemType==null)
				throw "To use changeItemTypeValidator you MUST specify wfItemTypeIdPreviousValue hidden value";
			
			if(myNEWWfItemType != myOLDWfItemType){
				var startLogic = Packages.it.cilea.wf.WfConstant.START_LOGIC_MAP.get("wfStartLogicOwnerDependentIdentifier");
				startLogic.start(object, request);
				object.getIntegerMap().put("wfItemTypeIdPreviousValue",object.getWfItemTypeId());

			}
		

wfActionLogicSaveStandardNewIdentifier

			var myNEWWfItemType = object.getWfItemTypeId();
			var myOLDWfItemType = object.getIntegerMap().get("wfItemTypeIdPreviousValue");
			if (myOLDWfItemType==null)
				throw "To use changeItemTypeValidator you MUST specify wfItemTypeIdPreviousValue hidden value";
			
			if(myNEWWfItemType != myOLDWfItemType){
				var startLogic = Packages.it.cilea.wf.WfConstant.START_LOGIC_MAP.get("wfStartLogicStandardIdentifier");
				startLogic.start(object, request);
				object.getIntegerMap().put("wfItemTypeIdPreviousValue",object.getWfItemTypeId());
			}
		

wfActionLogicTransitionLogger
Questa logica serve per la gestione del logging delle transizioni di stato.
E' necessario inserirla come enter action logic per tutti gli stati nei flussi che prevedono il logging delle transizioni di stato.
Nel caso in cui sia ritenuto necessario, è possibile richiedere all'utente che sta effettuando la transizione di stato di inserire un messaggio.
Questo messaggio verrà conservato nel log delle transizioni.

La gestione del messaggio opzionale è gestito dall'attributo transitionComment che deve essere configurato come validazione di enter con il validator @Required.

			var formatter=new Packages.java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
			var currentDate="["+formatter.format(new Packages.java.util.Date())+"]";
			var user=Packages.it.cilea.ga.authorization.context.GaAuthorizationUserHolder.getUser();
			
			if (user!=null){
				var message="";
				if(Packages.org.apache.commons.lang.StringUtils.isNotBlank(wfItem.getClobMap().get("transitionsLog"))){
					message+="_______________________________________________________________"+ "\n\n";
				} else {				
					wfItem.getClobMap().put("transitionsLog", "");
				}
				message+=currentDate+" <strong>"+user.getLastName()+" "+user.getFirstName()+"</strong> ("+user.getUsername()+")"+"\n";
				message+="Transizione verso \"<strong>"+wfItem.getWfState().getDisplayValue()+"</strong>\" ("+wfItem.getWfState().getDescription()+")";
				if (Packages.org.apache.commons.lang.StringUtils.isNotBlank(wfItem.getStringMap().get("transitionComment"))){			
					message+="\n<strong>Motivazione transizione di stato</strong>\n";
					message+="<i>"+wfItem.getStringMap().get("transitionComment")+"</i>";				
				}
				message+="\n";			
				wfItem.getClobMap().put("transitionsLog", wfItem.getClobMap().get("transitionsLog")+message);
				wfItem.getStringMap().put("transitionComment", null);
			}
		

wfActionLogicWarningHandler
Questa logica serve per la gestione dei messaggi di warning.
E' necessario inserirla come enter action logic per tutti gli stati di tutti i flussi che prevedono messaggi di warning.
La gestione dei warning è pilotata dall'attributo booleano warningAcknowlegement che deve essere configurato come validazione di enter con il validator @Boolean.TRUE specificando di volta in volta il messaggio di warning da presentare. Per maggiori dettagli cfr. excel modello dati dell'entità Progetto

			wfItem.getBooleanMap().put("warningAcknowlegement", null);
		

isNotLegacy
Questa è un'applicability rule che viene valutata prima di eseguire altre validazioni.
Se ritorna true allora vengono eseguite le altre validazioni altrimenti no.
Questa regola considera l'attributo legacy, tipicamente con etichetta "Disattivazione validazioni" (cfr il modello dati)
Per tutti gli oggetti che hanno questo attributo valorizzato a true vengono disattivate le validazioni e le eventuali sincronizzazioni.

			(
				object.getBooleanMap().get('legacy')==null 
				|| 
				Packages.java.lang.Boolean.FALSE.equals(object.getBooleanMap().get('legacy'))
			)