ChangeCalendar/backend/src/main/java/com/nttdata/calender/changes/Change.java

328 lines
17 KiB
Java

package com.nttdata.calender.changes;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Optional;
import java.util.TimeZone;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bmc.arsys.api.ARException;
import com.bmc.arsys.api.Entry;
import com.bmc.arsys.api.SortInfo;
import com.bmc.arsys.api.Timestamp;
import com.bmc.arsys.api.Value;
import com.nttdata.calender.DateConverter;
import com.nttdata.calender.LoggerTemplates;
import com.nttdata.calender.api.Query;
import com.nttdata.calender.api.RemedyJavaAPI;
import com.nttdata.calender.changes.query.FilterElement;
import com.nttdata.calender.errorhandling.ErrorTypes.NotFoundError;
import com.nttdata.calender.errorhandling.ErrorTypes.ValidationError;
/**
* Class representing the change with all of the change specific attributes.
*/
@Service
public class Change {
private Query queryChange;
private RemedyJavaAPI api;
private final static String formName = "ASF:WI_TAS_Paket";
/**
* Constructor for the {@link Change} class which gets autowired with the
* {@link RemedyJavaAPI} api.
*
* @param api the RemedyJavaAPI instance to be injected
*/
@Autowired
public Change(RemedyJavaAPI api) {
this.api = api;
this.queryChange = new Query.QueryBuilder(formName)
.addFieldId("ChangeNr", 1000000182)
.addFieldId("SupportGroup", 1000000015)
.addFieldId("ManagerGroup", 1000003229)
.addFieldId("State", 7)
.addFieldId("PackageInstanceId", 179)
.addFieldId("ResourceName", 1000000000)
.addFieldId("D1", 1000000349)
.addFieldId("D2", 1000000350)
.addFieldId("D3", 666000350)
.addFieldId("D4", 1000000364)
.addFieldId("StatusReason", 1000000150)
.addFieldId("ApprovalStatus", 1000003264)
.addFieldId("CoordinatorSg", 1000003229)
.addFieldId("CoordinatorSgId", 1000003234)
.addFieldId("ChangeCoordinator", 1000003230)
.addFieldId("SupportGroupId", 1000000079)
.addFieldId("ProviderCluster", 610020002)
.addFieldId("ChangeImplementer", 610023230)
.addFieldId("ChangeImplementerLogin", 610023231)
.addFieldId("ChangeImplementerPersonId", 610023232)
.addFieldId("PackageType", 670031016)
.addFieldId("Contract", 670031002)
.addFieldId("PlanTimeHours", 666000009)
.addFieldId("PlanTimeMinutes", 666000010)
.addFieldId("Approval", 1000003278)
.addFieldId("ApprovalProcessName", 301322300)
.addFieldId("CurrentStageNumber", 301541700)
.addFieldId("Plantime", 666000001)
.build();
}
/**
* Retrieves entries from the form using the given qualification. With the
* returned entry set,
* prints out the ID of each entry and the contents in its shortDescription
* field.
*
* @param request the defined qualifier for specific selection
* @return a List of Change for every entry found
* @throws ARException if an error occurs during the retrieval process
* @throws NotFoundError if no user is found with the specified login ID
* @throws ValidationError if there is an invalid filter or qualification
*/
public ChangeResponse get(ChangeRequest request) throws ARException, NotFoundError, ValidationError {
LoggerTemplates log = new LoggerTemplates(api);
var peopleFullName = processPeopleInfo(request);
var filter = request.getFilter();
var qualifier = filter.constructQualifier(queryChange, api);
SortInfo sort = request.constructSortInfo(queryChange);
log.initLog("getChanges", api.getUser()); // Logging
var entries = api.queryFieldsById(qualifier, this.queryChange.getFieldIds(),
this.queryChange.getFormName(),
sort, request.getSliceStart(),
request.getSliceEnd());
log.qualifierLog(queryChange.getFormName(), qualifier); // Logging
System.out.println(qualifier);
var entriesSize = api.getFormSize(qualifier, this.queryChange.getFormName());
var changes = new ArrayList<ChangeItem>();
for (var entry : entries) {
var change = new ChangeItem(entry.getEntryId());
boolean approval = getValueStringByID(entry, "Approval").equals("0") ? true : false;
if (approval) {
var queryApproval = new Query.QueryBuilder("CHG:ChangeAPDetailSignature")
.addFieldId("Approvers", 13207).build();
String qual = "(\'1000000182\' = \"" + getValueStringByID(entry, "ChangeNr")
+ "\") AND (\'10000\' = \""
+ getValueStringByID(entry, "ApprovalProcessName")
+ "\") AND (\'13207\' LIKE \"%" + api.getUser() + "%\")";
var queryApprovalProcessName = api.queryFieldsById(qual,
queryApproval.getFieldIds(), queryApproval.getFormName(), sort, 0, 0);
log.qualifierLog(queryApproval.getFormName(), qual);
if (!queryApprovalProcessName.isEmpty() && queryApprovalProcessName != null
&& queryApprovalProcessName.size() > 0)
change.setApproval(true);
else
change.setApproval(false);
}
change.setChangeNr(getValueStringByID(entry, "ChangeNr"));
change.setSupportGroup(getValueStringByID(entry, "SupportGroup"));
change.setStatusReason(getValueStringByID(entry, "StatusReason"));
if(Optional.ofNullable(getValue(entry, "State")).map(Value::getIntValue).orElse(-1)== 10 || Optional.ofNullable(getValue(entry, "State")).map(Value::getIntValue).orElse(-1)== 9){
if(Optional.ofNullable(getValue(entry, "State")).map(Value::getIntValue).orElse(-1)== 10){
if(change.getStatusReason().equals("9000")){
change.setState(10);
}else{
change.setState(101);
}
}
if(Optional.ofNullable(getValue(entry, "State")).map(Value::getIntValue).orElse(-1)== 9){
if(getValueStringByID(entry, "CurrentStageNumber").equals("1")){
change.setState(9);
}else{
change.setState(91);
}
}
}else{
change.setState(Optional.ofNullable(getValue(entry, "State"))
.map(Value::getIntValue)
.orElse(-1));
}
change.setPackageInstanceId(getValueStringByID(entry, "PackageInstanceId"));
change.setResourceName(getValueStringByID(entry, "ResourceName"));
change.setD1(timestampToDateById(entry, "D1"));
change.setD2(timestampToDateById(entry, "D2"));
change.setD3(timestampToDateById(entry, "D3"));
change.setD4(timestampToDateById(entry, "D4"));
change.setApprovalStatus(getValueStringByID(entry, "ApprovalStatus"));
change.setCoordinatorSg(getValueStringByID(entry, "CoordinatorSg"));
change.setCoordinatorSgId(getValueStringByID(entry, "CoordinatorSgId"));
change.setSupportGroupId(getValueStringByID(entry, "SupportGroupId"));
change.setProviderCluster(getValueStringByID(entry, "ProviderCluster"));
change.setChangeImplementer(getValueStringByID(entry, "ChangeImplementer"));
change.setChangeImplementerLogin(getValueStringByID(entry, "ChangeImplementerLogin"));
change.setChangeImplementerPersonId(getValueStringByID(entry, "ChangeImplementerPersonId"));
change.setPackageType(getValueStringByID(entry, "PackageType"));
change.setContract(getValueStringByID(entry, "Contract"));
change.setImplementerEdit(
Optional.ofNullable(entry.get(queryChange.getFieldId("ChangeCoordinator")))
.map(Object::toString)
.filter(peopleFullName::equals)
.isPresent());
var ptMinutes = getValueStringByID(entry, "PlanTimeMinutes").isEmpty() ? "00"
: getValueStringByID(entry, "PlanTimeMinutes");
var ptHours = getValueStringByID(entry, "PlanTimeHours").isEmpty() ? "00"
: getValueStringByID(entry, "PlanTimeHours");
change.setPlanTime(convertPlanTime(ptHours, ptMinutes));
changes.add(change);
}
api.freeImpersonatedUser();
return new ChangeResponse(entriesSize, changes);
}
/**
* Processes the people information based on the provided change request.
* Returns the full name of the impersonated user after querying for the support
* group.
*
* @param request the change request object
* @return the full name of the impersonated user
* @throws ARException if an AR exception occurs
* @throws NotFoundError if no user or support groups are found with the
* provi1ded login ID
*/
private String processPeopleInfo(ChangeRequest request) throws ARException, NotFoundError {
// Queries for SupportGroup of impersonated User
var queryPerson = new Query.QueryBuilder("CTM:Support Group Association")
.addFieldId("FullName", 1000000017)
.addFieldId("SupportGroupId", 1000000079)
.build();
System.out.println(api.getUser());
var peopleInfos = api.queryFieldsById("\'Login ID\' = \"" + api.getUser() + "\"",
queryPerson.getFieldIds(),
queryPerson.getFormName(), null, 0, 0);
if (peopleInfos.isEmpty()) {
throw new NotFoundError("No user found with this loginId");
}
// constructs set of supportGroups and full name of impersonated User
String[] peopleSupportGroup = peopleInfos.stream()
.map(entry -> entry.get(queryPerson.getFieldId("SupportGroupId")).toString())
.toArray(String[]::new);
if (peopleSupportGroup.length <= 0) {
throw new NotFoundError("No supportGroups associated to the loginId ");
}
// request.addFilter(
// new FilterElement("SupportGroupId", "equals", peopleSupportGroup));
return peopleInfos.get(0).get(queryPerson.getFieldId("FullName")).toString();
}
/**
* Converts the planned time which is passed in hours and minutes to total hours
*
* @param hours the hours as a String
* @param minutes the minutes as a String
* @return the hours and minutes as total hours
* @throws ARException
*/
public double convertPlanTime(String hours, String minutes) throws ARException {
double totalHours = Integer.valueOf(hours) + (Integer.valueOf(minutes) / 60.0);
return totalHours;
}
/**
* Returns the {@link Value} of an entry based on the provided description.
*
* @param entry the {@link Entry} from which a value will be retrieved
* @param description the name of the field from which the value should be
* retrieved
* @return the value of the entry
*/
private Value getValue(Entry entry, String description) {
return entry.get(this.queryChange.getFieldId(description));
}
/**
* Converts a {@link Timestamp} to a {@link Date} format or returns null if the
* timestamp is null.
*
* @param entry the {@link Entry} containing the timestamp value
* @param description the description of the field containing the timestamp
* value
* @return the converted {@link Date} or null if the timestamp is null
*/
private Date timestampToDateById(Entry entry, String description) {
return Optional.ofNullable(getValue(entry, description))
.map(Value::getValue)
.map(Timestamp.class::cast)
.map(Timestamp::toDate)
.orElse(null);
}
/**
* Remaps a {@link Value} to a String if possible, or returns null.
*
* @param entry the {@link Entry} from which the value should be retrieved
* @param description the description of the field containing the value
* @return the value as a {@link String} or null
*/
private String getValueStringByID(Entry entry, String description) {
return Optional.ofNullable(getValue(entry, description))
.map(Value::toString)
.orElse("");
}
/**
* Updates the timestamp of a change entry or modifies the short description
* field on the specified entry.
* Extracts data from the request object.
* Builds the query to update the d2 field.
* Modifies the entry on one of two forms according to the state.
*
* @param request the object containing the ID of the change entry and the new
* timestamp
* @throws ARException if an error occurs during the modification process
* @throws ValidationError
*/
public void modifyTimestamp(ChangeUpdateRequest request) throws ARException, ValidationError {
String entryId = request.getResourceId();
String d2 = request.getD2();
var dateConverter = new DateConverter();
int state = request.getState();
String changeNr = request.getChangeNr();
var ts = dateConverter.convertTimestamp(d2);
if (state == 0) {
Query query = new Query.QueryBuilder("ASF:WI_TAS_Paket")
.addFieldValue("d2", 1000000350, new Value(ts)).build();
api.modifyEntry(entryId, query);
} else {
Query queryInfrastructureChange = new Query.QueryBuilder("CHG:Infrastructure Change")
.addFieldValue("d2", 1000000350, new Value(ts)).build();
var change = api.queryFieldsById("\'Infrastructure Change ID\' = \"" + changeNr + "\"",
queryInfrastructureChange.getFieldIds(),
queryInfrastructureChange.getFormName(), null, 0, 0);
api.modifyEntry(change.get(0).getEntryId(), queryInfrastructureChange);
}
}
}