Optaplanner ScoreDirector continuous planning DayOff Request - optaplanner

I am trying to enable continuous planning and requests. I have tried to follow the computer example provided within the doco. Code below. I can see the values updated during debug. Code below. What am I doing wrong
public void addEmployeeDayOff(final Employee employee,final DayOffRequest dayOffRequest) {
logger.info("Scheduling employee dayoff ({}).", dayOffRequest);
doProblemFactChange(scoreDirector -> {
NurseRoster nurseRoster = scoreDirector.getWorkingSolution();
Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
DayOffRequest dayoffRequest = scoreDirector.lookUpWorkingObject(dayOffRequest);
scoreDirector.beforeProblemPropertyChanged(workingEmployee);
if (workingEmployee == null) {
return;
}
ArrayList<DayOffRequest> requestoffList = new ArrayList<>(nurseRoster.getDayOffRequestList());
nurseRoster.setDayOffRequestList(requestoffList);
scoreDirector.beforeProblemFactAdded(dayoffRequest);
workingEmployee.getDayOffRequestMap().put(dayoffRequest.getShiftDate(), dayoffRequest);
scoreDirector.afterProblemPropertyChanged(workingEmployee);
nurseRoster.getDayOffRequestList().add(dayoffRequest);
scoreDirector.afterProblemPropertyChanged(dayoffRequest);
scoreDirector.triggerVariableListeners();
});
The above is called from here:
List<DayOffRequest> dayOffRequestList;
//updating from database .. not sure if this is the issue
List<DayOffData> dayOffElementList = (List<DayOffData>) rosterService.listDayOffData();
dayOffRequestList = new ArrayList<>(dayOffElementList.size());
long nextdayoffId =0L;
for (DayOffData element : dayOffElementList) {
if (nextdayoffId <= element.getId()) {
nextdayoffId = element.getId() + 1L;
}
DayOffRequest dayOffRequest = new DayOffRequest();
String empID = element.getEmployee().getName();
int weight = element.getWeight();
LocalDate shiftDate = element.getShiftDate();
ShiftDate date1 = shiftDateMap.get(shiftDate);
Employee employee = employeeMap.get(empID);
dayOffRequest.setId(nextdayoffId);
dayOffRequest.setWeight(weight);
dayOffRequest.setEmployee(employee);
dayOffRequest.setShiftDate(date1);
dayOffRequestList.add(dayOffRequest);
//If this is not enabled the values don't pass to the addEmployeeDayOff method is this correct??
scoreDirector.afterProblemFactAdded(dayOffRequest);
scoreDirector.afterProblemFactAdded(employee);
addEmployeeDayOff(employee,dayOffRequest);
}

I found this worked but not sure if this is the correct way to approach the problem.
public void addEmployeeDayOff(final Employee employee, final DayOffRequest dayOffRequest) {
logger.info("Scheduling employee dayoff ({}).", dayOffRequest);
doProblemFactChange(scoreDirector -> {
NurseRoster nurseRoster = (NurseRoster) scoreDirector.getWorkingSolution();
Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
DayOffRequest dayoffRequest = (DayOffRequest) scoreDirector.lookUpWorkingObject(dayOffRequest);
scoreDirector.beforeProblemPropertyChanged(workingEmployee);
if (workingEmployee == null) {
return;
}
ArrayList<DayOffRequest> requestoffList = new ArrayList<>(nurseRoster.getDayOffRequestList());
nurseRoster.setDayOffRequestList(requestoffList);
scoreDirector.afterProblemFactAdded(requestoffList);
scoreDirector.afterProblemPropertyChanged(requestoffList);
ArrayList<Employee> beforeempList = new ArrayList<>(nurseRoster.getEmployeeList());
nurseRoster.setEmployeeList(beforeempList);
nurseRoster.getEmployeeList().remove(workingEmployee);
scoreDirector.beforeProblemFactRemoved(workingEmployee);
scoreDirector.afterProblemFactRemoved(workingEmployee);
ArrayList<Employee> empList = new ArrayList<>(nurseRoster.getEmployeeList());
nurseRoster.setEmployeeList(empList);
workingEmployee.getDayOffRequestMap().put(dayOffRequest.getShiftDate(), dayOffRequest);
nurseRoster.getEmployeeList().add(workingEmployee);
scoreDirector.beforeProblemFactAdded(workingEmployee);
scoreDirector.afterProblemFactAdded(workingEmployee);
scoreDirector.triggerVariableListeners();
});

I have uploaded the xml and Java file here https://github.com/rod182211/Optaplanner in to hope someone can advise why when I advance 14 days not all rule continue to apply. I assumed scoredirector only needed to be made aware of changes.

14 Day advance taking into account Requests via the below.
doProblemFactChange(scoreDirector -> {
NurseRoster nurseRoster = scoreDirector.getWorkingSolution();
NurseRosterParametrization nurseRosterParametrization = nurseRoster
.getNurseRosterParametrization();
List<ShiftDate> shiftDateList = nurseRoster.getShiftDateList();
Shift oldLastShift = nurseRoster.getShiftList()
.get(nurseRoster.getShiftList().size() - 1);
long shiftId = oldLastShift.getId() + 1L;
int shiftIndex = oldLastShift.getIndex() + 1;
ShiftDate oldLastShiftDate = shiftDateList
.get(shiftDateList.size() - 1);
long shiftDateId = (oldLastShiftDate.getId() + 1L);
int shiftDayIndex = (oldLastShiftDate.getDayIndex() + 1);
// long parmId = nurseRoster.getNurseRosterParametrization().getId()
// + 1L;
scoreDirector
.beforeProblemPropertyChanged(nurseRosterParametrization);
// Update to get the first day along with adding 14 days to the run
LocalDate startDate = (oldLastShiftDate.getDate().plusDays(1));
LocalDate endDate = (oldLastShiftDate.getDate().plusDays(14));
int maxDayIndex = Math.toIntExact(DAYS.between(startDate, endDate));
int shiftDateSize = maxDayIndex + 1;
List<ShiftDate> shiftDateList1 = new ArrayList<>(shiftDateSize);
shiftDateMap = new HashMap<>(shiftDateSize);
LocalDate date = startDate;
for (int i = 0; i < shiftDateSize; i++) {
ShiftDate shiftDate = new ShiftDate();
shiftDate.setId(shiftDateId);
shiftDate.setDayIndex(shiftDayIndex);
shiftDate.setDate(date);
shiftDate.setShiftList(new ArrayList<>());
shiftDateMap.put(date, shiftDate);
shiftDateId++;
shiftDayIndex++;
date = date.plusDays(1);
nurseRoster.getShiftDateList().add(shiftDate);
shiftDateList1.add(shiftDate);
scoreDirector.afterProblemFactAdded(shiftDate);
}
List<Skill> skillList;
List<Skill> skillElementList = (List<Skill>) nurseRoster
.getSkillList();
skillList = new ArrayList<>(skillElementList.size());
skillMap = new HashMap<>(skillElementList.size());
long id = 0L;
for (Skill element : skillElementList) {
Skill skill = new Skill();
skill.setId(id);
skill.setCode(element.getCode());
skillList.add(skill);
if (skillMap.containsKey(skill.getCode())) {
throw new IllegalArgumentException(
"There are 2 skills with the same code ("
+ skill.getCode() + ").");
}
skillMap.put(skill.getCode(), skill);
id++;
}
List<Contract> contractElementList = (List<Contract>) nurseRoster
.getContractList();
List<Contract> contractList = new ArrayList<>(
contractElementList.size());
contractMap = new HashMap<>(contractElementList.size());
for (Contract element : contractElementList) {
Contract contract = new Contract();
long Id = element.getId();
contract.setId(Id);
contract.setCode(element.getCode());
contract.setDescription(element.getDescription());
WeekendDefinition weekend = element.getWeekendDefinition();
contract.setWeekendDefinition(weekend);
contract.setContractLineList(new ArrayList<ContractLine>());
contractMap.put(contract.getCode(), contract);
contractList.add(contract);
}
List<ShiftTypeSkillRequirement> coverRequirementElementList = (List<ShiftTypeSkillRequirement>) nurseRoster
.getShiftTypeSkillRequirementList();
List<ShiftType> shiftTypeElementList = (List<ShiftType>) rosterService
.listShiftType();
List<ShiftType> shiftTypeList = new ArrayList<>(
shiftTypeElementList.size());
shiftTypeMap = new HashMap<>(shiftTypeElementList.size());
long Id = 0L;
int index = 0;
long shiftTypeSkillRequirementId = 0L;
List<ShiftTypeSkillRequirement> shiftTypeSkillRequirementList = new ArrayList<>(
shiftTypeElementList.size() * 2);
for (ShiftType element : shiftTypeElementList) {
ShiftType shiftType = new ShiftType();
shiftType.setId(Id);
shiftType.setCode(element.getCode());
shiftType.setIndex(index);
String startTimeString = element.getStartTimeString();
shiftType.setStartTimeString(startTimeString);
String endTimeString = element.getEndTimeString();
shiftType.setEndTimeString(endTimeString);
shiftType
.setNight(startTimeString.compareTo(endTimeString) > 0);
shiftType.setDescription(element.getDescription());
for (ShiftTypeSkillRequirement skillElement : coverRequirementElementList) {
ShiftTypeSkillRequirement shiftTypeSkillRequirement = new ShiftTypeSkillRequirement();
shiftTypeSkillRequirement
.setId(shiftTypeSkillRequirementId);
shiftTypeSkillRequirement.setShiftType(shiftType);
Skill skill = skillMap
.get(skillElement.getSkill().getCode());
if (skill == null) {
throw new IllegalArgumentException("The skill ("
+ skillElement.getSkill().getCode()
+ ") of shiftType (" + shiftType.getCode()
+ ") does not exist.");
}
shiftTypeSkillRequirement.setSkill(skill);
shiftTypeSkillRequirementList
.add(shiftTypeSkillRequirement);
shiftTypeSkillRequirementId++;
}
shiftTypeList.add(shiftType);
if (shiftTypeMap.containsKey(shiftType.getCode())) {
throw new IllegalArgumentException(
"There are 2 shiftTypes with the same code ("
+ shiftType.getCode() + ").");
}
shiftTypeMap.put(shiftType.getCode(), shiftType);
Id++;
index++;
}
nurseRoster.setShiftTypeList(shiftTypeList);
nurseRoster.setShiftTypeSkillRequirementList(
shiftTypeSkillRequirementList);
int shiftListSize = shiftDateMap.size() * shiftTypeList.size();
List<Shift> shiftList1 = new ArrayList<>(shiftListSize);
dateAndShiftTypeToShiftMap = new HashMap<>(shiftListSize);
dayOfWeekAndShiftTypeToShiftListMap = new HashMap<>(
7 * shiftTypeList.size());
for (ShiftDate shiftDate : shiftDateList1) {
for (ShiftType shiftType : shiftTypeList) {
Shift shift = new Shift();
shift.setId(shiftId);
shift.setShiftDate(shiftDate);
shiftDate.getShiftList().add(shift);
shift.setShiftType(shiftType);
shift.setIndex(shiftIndex);
shift.setRequiredEmployeeSize(0); // Filled in later
shiftList1.add(shift);
dateAndShiftTypeToShiftMap.put(
Pair.of(shiftDate.getDate(), shiftType.getCode()),
shift);
addShiftToDayOfWeekAndShiftTypeToShiftListMap(shiftDate,
shiftType, shift);
shiftId++;
shiftIndex++;
nurseRoster.getShiftList().add(shift);
scoreDirector.afterProblemFactAdded(shift);
}
}
List<DayOffRequest> dayOffRequestList;
List<DayOffRequest> requestList = (List<DayOffRequest>) nurseRoster.getDayOffRequestList();
DayOffRequest oldLastDayOff = requestList.get(requestList.size() - 1);
long DayOffId = (oldLastDayOff.getId() + 1l);
List<DayOffDate> dayOffElementList = rosterService.listDayOffDate();
dayOffRequestList = new ArrayList<>(dayOffElementList.size());
for (DayOffDate element : dayOffElementList) {
DayOffRequest dayOffRequest = new DayOffRequest();
int weight = element.getWeight();
LocalDate shiftDate = element.getDate();
ShiftDate date1 = shiftDateMap.get(shiftDate);
Employee employee = element.getEmployee();
Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
dayOffRequest.setId(DayOffId);
DayOffId++;
dayOffRequest.setWeight(weight);
dayOffRequest.setEmployee(workingEmployee);
dayOffRequest.setShiftDate(date1);
workingEmployee.getDayOffRequestMap().put(date1, dayOffRequest);
nurseRoster.getDayOffRequestList().add(dayOffRequest);
}
List<DayOnRequest> dayOnRequestList;
List<DayOnDate> dayOnElementList1 = rosterService.listDayOnDate();
dayOnRequestList = new ArrayList<>(dayOnElementList1.size());
for (DayOnDate element : dayOnElementList1) {
DayOnRequest dayOnRequest = new DayOnRequest();
long DayOnId = element.getId();
int weight = element.getWeight();
LocalDate localshiftDate = element.getDate();
ShiftDate dateon = shiftDateMap.get(localshiftDate);
Employee employee = element.getEmployee();
Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
dayOnRequest.setId(DayOnId);
dayOnRequest.setWeight(weight);
dayOnRequest.setEmployee(workingEmployee);
dayOnRequest.setShiftDate(dateon);
dayOnRequestList.add(dayOnRequest);
workingEmployee.getDayOnRequestMap().put(dateon, dayOnRequest);
nurseRoster.getDayOnRequestList().add(dayOnRequest);
}
List<ShiftOffRequest> shiftOffRequestList;
List<ShiftOffDate> shiftOffElementList = (List<ShiftOffDate>) rosterService.listShiftOffDate();
shiftOffRequestList = new ArrayList<>(shiftOffElementList.size());
for (ShiftOffDate element : shiftOffElementList) {
ShiftOffRequest shiftOffRequest = new ShiftOffRequest();
long ShiftonId = element.getId();
int weight = element.getWeight();
Employee employee = element.getEmployee();
Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
LocalDate date1 = element.getDate();
String shiftcode = element.getShiftType().getCode();
Shift shift = dateAndShiftTypeToShiftMap.get(Pair.of(date1, shiftcode));
shiftOffRequest.setId(ShiftonId);
shiftOffRequest.setEmployee(workingEmployee);
shiftOffRequest.setShift(shift);
shiftOffRequest.setWeight(weight);
shiftOffRequestList.add(shiftOffRequest);
workingEmployee.getShiftOffRequestMap().put(shift, shiftOffRequest);
nurseRoster.setShiftOffRequestList(shiftOffRequestList);
}
List<ShiftOnRequest> shiftOnRequestList;
List<ShiftOnDate> shiftOnElementList = (List<ShiftOnDate>) rosterService.listShiftOnDate();
shiftOnRequestList = new ArrayList<>(shiftOnElementList.size());
for (ShiftOnDate element : shiftOnElementList) {
ShiftOnRequest shiftOnRequest = new ShiftOnRequest();
long ShiftonId = element.getId();
int weight = element.getWeight();
Employee employee = element.getEmployee();
Employee workingEmployee = scoreDirector.lookUpWorkingObject(employee);
LocalDate date1 = element.getDate();
String shiftcode = element.getShiftType().getCode();
Shift shift = dateAndShiftTypeToShiftMap.get(Pair.of(date1, shiftcode));
shiftOnRequest.setId(ShiftonId);
shiftOnRequest.setEmployee(workingEmployee);
shiftOnRequest.setShift(shift);
shiftOnRequest.setWeight(weight);
shiftOnRequestList.add(shiftOnRequest);
workingEmployee.getShiftOnRequestMap().put(shift, shiftOnRequest);
nurseRoster.setShiftOnRequestList(shiftOnRequestList);
}
List<CoverRequirements> coverRequirementElementList1 = (List<CoverRequirements>) rosterService
.listCoverRequirements();
for (CoverRequirements element : coverRequirementElementList1) {
String type = element.getShiftType().getCode();
DayOfWeek day = element.getDayOfWeek();
int req = element.getRequiredEmployeesize();
ShiftType shiftType = shiftTypeMap.get(type);
Pair<DayOfWeek, ShiftType> key = Pair.of(day, shiftType);
List<Shift> shiftList = dayOfWeekAndShiftTypeToShiftListMap
.get(key);
for (Shift shift : shiftList) {
shift.setRequiredEmployeeSize(
shift.getRequiredEmployeeSize() + req);
}
}
List<ShiftAssignment> shiftAssignmentList = new ArrayList<>(
shiftList1.size());
long shiftAssignmentId = nurseRoster.getShiftAssignmentList()
.get(nurseRoster.getShiftAssignmentList().size() - 1)
.getId() + 1L;
for (Shift shift : shiftList1) {
for (int i = 0; i < shift.getRequiredEmployeeSize(); i++) {
ShiftAssignment newShiftAssignment = new ShiftAssignment();
newShiftAssignment.setId(shiftAssignmentId);
shiftAssignmentId++;
newShiftAssignment.setShift(shift);
newShiftAssignment.setIndexInShift(i);
shiftAssignmentList.add(newShiftAssignment);
nurseRoster.getShiftAssignmentList()
.add(newShiftAssignment);
scoreDirector.afterEntityAdded(newShiftAssignment);
}
}
//This should move the planning window
nurseRosterParametrization.setFirstShiftDate(shiftDateList1.get(0));
nurseRosterParametrization.setLastShiftDate(shiftDateList1.get(shiftDateList1.size() - 1));
nurseRosterParametrization.setPlanningWindowStart(shiftDateList1.get(0));
nurseRoster.setNurseRosterParametrization(nurseRosterParametrization);
scoreDirector.afterProblemPropertyChanged(nurseRosterParametrization);
scoreDirector.triggerVariableListeners();
}, true);
}

Related

Execution gets stuck at date picking functionality of selenium webdriver

I am new to selenium automation, I have written a script to pick check in and check out dates from webpage of tripadvisor.in. I hope the code and xpaths are correct coz out of 7 or 8 executions the scrips successfully running only once. I thought abt synchronization issue and tried adding all types of waits but still the execution getting stuck as calendar. Sometimes stucking at check-in date, sometimes at check-out date but sometimes working fine. Can I get help to sort this issue plz...
public void selectCheckDate(String date, WebElement forwardArrow) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
try {
Date expectedDate = dateFormat.parse(prop.getProperty(date));
String day = new SimpleDateFormat("dd").format(expectedDate);
String month = new SimpleDateFormat("MMMM").format(expectedDate);
String year = new SimpleDateFormat("yyyy").format(expectedDate);
String expectedMonthYear = month + " " + year;
logger.log(Status.INFO, "Expected Month and year: "+expectedMonthYear);
WebDriverWait wait = new WebDriverWait(driver, 20);
String dd1 = "", dd2 = "";
String d1 = null, d2 = null;
boolean flag1 = false;
boolean flag2 = false;
while (true) {
String displayDate1 = driver.findElement(By.xpath("//*[#class='vr-datepicker-LargeStyles__caption--Srrff']/div")).getText();
String displayDate2 = driver.findElement(By.xpath("(//*[#class='vr-datepicker-LargeStyles__caption--Srrff']/div)[2]")).getText();
if (displayDate1.contains(expectedMonthYear)) {
//addWait();
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 7; j++) {
d1 = "//*[#id='BODY_BLOCK_JQUERY_REFLOW']/div[14]/div/div/div[2]/div/div/div[2]/div[1]/div[3]/div["
+ i + "]/div[" + j + "]";
boolean ex = isElementExists(d1);
if(ex==true) {
dd1 = driver.findElement(By.xpath(d1)).getText();
if (dd1.equals(day)) {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(d1))).click();
//driver.findElement(By.xpath(d1)).click();
flag1 = true;
break;
}
}
}
if (flag1 == true) {
break;
}
}
if (flag1 == true) {
reportPass("Entered date: "+prop.getProperty(date));
break;
}
} else if (displayDate2.contains(expectedMonthYear)) {
//addWait();
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 7; j++) {
d2 = "//*[#id='BODY_BLOCK_JQUERY_REFLOW']/div[14]/div/div/div[2]/div/div/div[2]/div[2]/div[3]/div["
+ i + "]/div[" + j + "]";
boolean ex1 = isElementExists(d2);
if(ex1==true) {
dd2 = driver.findElement(By.xpath(d2)).getText();
if (dd2.equals(day)) {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(d2))).click();
//driver.findElement(By.xpath(d2)).click();
flag2 = true;
break;
}
}
}
if (flag2 == true) {
break;
}
}
if (flag2 == true) {
reportPass("Entered date: "+prop.getProperty(date));
break;
}
} else {
forwardArrow.click();
}
}
} catch (ParseException e) {
reportFail(e.getMessage());
}
}

EPPlus two color conditional date format

I have a column with dates and I want to conditionally color any cell that is older that 2 week yellow, and any that is older than 90 days red. I can't figure out how to do that.
Should be able to just add the conditions like any other. You can use the TODAY() function in excel and subtract:
[TestMethod]
public void Conditional_Formatting_Date()
{
//https://stackoverflow.com/questions/56741642/epplus-two-color-conditional-date-format
var file = new FileInfo(#"c:\temp\Conditional_Formatting_Date.xlsx");
if (file.Exists)
file.Delete();
//Throw in some data
var dataTable = new DataTable("tblData");
dataTable.Columns.AddRange(new[] {
new DataColumn("Col1", typeof(DateTime)),
new DataColumn("Col3", typeof(string))
});
var rnd = new Random();
for (var i = 0; i < 100; i++)
{
var row = dataTable.NewRow();
row[0] = DateTime.Now.AddDays(-rnd.Next(1, 100));
row[1] = $"=TODAY() - A{i +1}";
dataTable.Rows.Add(row);
}
//Create a test file
using (var package = new ExcelPackage(file))
{
//Make the stylesheet
var ws = package.Workbook.Worksheets.Add("table");
var range = ws.Cells[1, 1].LoadFromDataTable(dataTable, false);
ws.Column(1).Style.Numberformat.Format = "mm-dd-yy";
ws.Column(1).AutoFit();
//Add the calc check
var count = 0;
foreach (DataRow row in dataTable.Rows)
ws.Cells[++count, 2].Formula = row[1].ToString();
//Add the conditions - order matters
var rangeA = range.Offset(0, 0, count, 1);
var condition90 = ws.ConditionalFormatting.AddExpression(rangeA);
condition90.Style.Font.Color.Color = Color.White;
condition90.Style.Fill.PatternType = ExcelFillStyle.Solid;
condition90.Style.Fill.BackgroundColor.Color = Color.Red;
condition90.Formula = "TODAY() - A1> 90";
condition90.StopIfTrue = true;
var condition14 = ws.ConditionalFormatting.AddExpression(rangeA);
condition14.Style.Font.Color.Color = Color.Black;
condition14.Style.Fill.PatternType = ExcelFillStyle.Solid;
condition14.Style.Fill.BackgroundColor.Color = Color.Yellow;
condition14.Formula = "TODAY() - A1> 14";
package.Save();
}
}
Which gives this in the output:
I am assuming that you have the column number of the date column and number of rows in your records. Also, the following loop is under assumption that the first row is your column header and records begin from second row. Change the loop counter's initialization and assignment accordingly.
int rowsCount; //get your no of rows
int dateColNumber; //Assign column number in excel file of your date column
string cellValue;
DateTime dateValue;
DateTime today = DateTime.Now;
double daysCount;
for(int i=1;i<rowsCount;i++)
{
cellValue = ws.Cells[i + 1, dateColNumber].Text.ToString(); //First row is header start from second
if(DateTime.TryParse(cellValue,out dateValue))
{
daysCount = (today - dateValue).Days;
if(daysCount>90)
{
ws.Cells[i + 1,dateColNumber].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
ws.Cells[i + 1,dateColNumber].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Red);
}
else if(daysCount>14)
{
ws.Cells[i + 1, dateColNumber].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
ws.Cells[i + 1, dateColNumber].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Yellow);
}
}
}

DocuSign does not pass values to Salesforce

DocuSign doesn't pass values back into Salesforce. And Even doesn't give me any errors in the logs.
I used a Custom Field like source ID and MergeFieldXml tab option with the write-back = true. But it doesn't work.
Please advise what is wrong?
Merge fields are enabled for the DocuSign account.
My code example:
global class AnnualContract
{
webService static string AM_SendToDocuSign(String id, string strObjType)
{
Docusign_API_Setting__c APISetting = Docusign_API_Setting__c.getInstance('API Settings');
String envelopeId = '';
string DealerName = '';
string DealerId = '';
String accountId = APISetting.AccountId__c;
String userId = APISetting.UserId__c;
String password = APISetting.Password__c;
String integratorsKey = APISetting.IntegratorsKey__c;
String webServiceUrl = APISetting.WebServiceUrl__c;
list<Lead> lstLead = new list<Lead>();
list<Contact> lstContact = new list<Contact>();
if(strObjType == 'Lead')
{
lstLead = [SELECT Name,Status,Email,FirstName,LastName,Owner.Name,Title,FROM Lead where id = : Id limit 1];
}
StaticResource objSR = [SELECT Id,name, SystemModStamp FROM StaticResource WHERE Name = 'AnnualContractPDF' LIMIT 1];
String url_file_ref = '/resource/' + String.valueOf(((DateTime)objSR.get('SystemModStamp')).getTime())+ '/' + objSR.get('Name');
if(strObjType == 'Lead')
{
DealerName = lstLead[0].Name;
}
DocuSignAPI.APIServiceSoap dsApiSend = new DocuSignAPI.APIServiceSoap();
dsApiSend.endpoint_x = webServiceUrl;
//Set Authentication
String auth = '<DocuSignCredentials><Username>'+ userId
+'</Username><Password>' + password
+ '</Password><IntegratorKey>' + integratorsKey
+ '</IntegratorKey></DocuSignCredentials>';
System.debug('Setting authentication to: ' + auth);
dsApiSend.inputHttpHeaders_x = new Map<String, String>();
dsApiSend.inputHttpHeaders_x.put('X-DocuSign-Authentication',
auth);
DocuSignAPI.Envelope envelope = new DocuSignAPI.Envelope();
envelope.Subject = 'Please Sign this Contract' + lstLead[0].Name;
envelope.EmailBlurb = 'This is my new eSignature service, it allows me to get your signoff without having to fax, scan, retype, refile and wait forever';
envelope.AccountId = accountId;
// Render the contract
System.debug('Rendering the contract');
PageReference pageRef = new PageReference(url_file_ref);
Blob pdfBlob = pageRef.getContent();
DocuSignAPI.CustomField field = new DocuSignAPI.CustomField ();
field.Name = '##SFLead';
field.Value = lstLead[0].Id; //value of the external source Id
field.Show = 'false';
field.CustomFieldType = 'Text';
envelope.CustomFields = new DocuSignAPI.ArrayOfCustomField();
envelope.CustomFields.CustomField = new DocuSignAPI.CustomField[1];
envelope.CustomFields.CustomField[0] = field;
// Document
DocuSignAPI.Document document = new DocuSignAPI.Document();
document.ID = 1;
document.pdfBytes = EncodingUtil.base64Encode(pdfBlob);
document.Name = 'Annual Contract';
document.FileExtension = 'pdf';
envelope.Documents = new DocuSignAPI.ArrayOfDocument();
envelope.Documents.Document = new DocuSignAPI.Document[1];
envelope.Documents.Document[0] = document;
// Recipient
System.debug('Building up the recipient');
DocuSignAPI.Recipient recipient = new DocuSignAPI.Recipient();
recipient.ID = 1;
recipient.Type_x = 'Signer';
recipient.RoutingOrder = 1;
recipient.Email = lstLead[0].Email;
recipient.UserName = lstLead[0].FirstName + ' ' + lstLead[0].LastName;
recipient.RequireIDLookup = false;
envelope.Recipients = new DocuSignAPI.ArrayOfRecipient();
envelope.Recipients.Recipient = new DocuSignAPI.Recipient[1];
envelope.Recipients.Recipient[0] = recipient;
// Tab
DocuSignAPI.Tab tab1 = new DocuSignAPI.Tab();
tab1.Type_x = 'SignHere';
tab1.RecipientID = 1;
tab1.DocumentID = 1;
tab1.AnchorTabItem = new DocuSignAPI.AnchorTab();
tab1.AnchorTabItem.AnchorTabString = '/t1/';
tab1.AnchorTabItem.XOffset = 100;
DocuSignAPI.Tab tab2 = new DocuSignAPI.Tab();
tab2.Type_x = 'DateSigned';
tab2.RecipientID = 1;
tab2.DocumentID = 1;
tab2.AnchorTabItem = new DocuSignAPI.AnchorTab();
tab2.AnchorTabItem.AnchorTabString = '/d1/';
DocuSignAPI.Tab tab3 = new DocuSignAPI.Tab();
tab3.CustomTabType = 'Text';
tab3.Name = 'Title';
tab3.Type_x = 'Custom';
tab3.RecipientID = 1;
tab3.DocumentID = 1;
tab3.TabLabel = 'Title';
if(strObjType == 'Lead')
{
if(lstLead[0].Title != null)
{
tab3.Value = ''+lstLead[0].Title+'';
}
}
else
{
if(lstContact[0].Title != null)
{
tab3.Value = ''+lstContact[0].Title+'';
}
}
tab3.CustomTabWidth=100;
tab3.CustomTabRequired=false;
tab3.CustomTabLocked=false;
tab3.CustomTabDisableAutoSize=false;
tab3.TemplateLocked=false;
tab3.TemplateRequired=false;
tab3.ConditionalParentLabel='';
tab3.ConditionalParentValue='';
tab3.SharedTab=true;
tab3.RequireInitialOnSharedTabChange=false;
tab3.ConcealValueOnDocument=false;
tab3.AnchorTabItem = new DocuSignAPI.AnchorTab();
tab3.AnchorTabItem.AnchorTabString = '/t2/';
tab3.AnchorTabItem.XOffset = 42;
tab3.AnchorTabItem.YOffset = -5;
tab3.MergeFieldXml = '<mergeField><allowSenderToEdit>true</allowSenderToEdit><configurationType>salesforce</configurationType><path>Lead.Title</path><row>1</row><writeBack>true</writeBack></mergeField>';
envelope.Tabs = new DocuSignAPI.ArrayOfTab();
envelope.Tabs.Tab = new DocuSignAPI.Tab[3];
envelope.Tabs.Tab[0] = tab1;
envelope.Tabs.Tab[1] = tab2;
envelope.Tabs.Tab[2] = tab3;
System.debug('Calling the API');
try {
DocuSignAPI.EnvelopeStatus es = dsApiSend.CreateAndSendEnvelope(envelope);
envelopeId = es.EnvelopeID;
System.debug('Returned successfully, envelope id = ' + envelopeId );
return '';
} catch ( CalloutException e) {
System.debug('Exception - ' + e );
envelopeId = 'Exception - ' + e;
return '';
}
return '';
}
}
I resolved the issue with the DocuSign support.
MergeFieldXml for SOAP should be like this:
tab3.MergeFieldXml ='<mergefieldconfig configversion="1.0" service="salesforce"><mergefield><writeenabled>true</writeenabled><sendercanedit>true</sendercanedit><queryfrom><obj><type>Lead</type><name>Lead</name><field><fieldtype>string</fieldtype><name>Title</name></field></obj></queryfrom></mergefield></mergefieldconfig>';

DHTMLX Scheduler in mVC

I am using DHTMLX Scheduler in my MVC Application. In my scheduler when we drag and the drop the timings a popup will be displayed which is working by default scheduler.js file. My problem is while dragging the time i need to display the custom popup window. Is it possible to do with the scheduler?
Can any one please help me.
Code for scheduler is
public ActionResult CalendarView(int? id, int? CustomerUserid)
{
//id = (int)Session["BUId"];
if (CustomerUserid == (int)Session["UserID"] || (CustomerUserid == (int)Session["UserID"] && id == (int)Session["BusinessId"]))
{
var scheduler = new DHXScheduler(this);
string val = System.Configuration.ConfigurationManager.AppSettings["UserTypeId"];
int code = Convert.ToInt32(val);
//var cuid = (int)Session["UserID"];
// List<tblUser> user = new List<tblUser>();
// var user1 = (from s in user
// where s.UserTypeId == 3 && s.UserID == cuid
// select new Appt
// {
// AddCustomer = s.DependentCustomer.ToString()
// }).ToList();
var cal = (from s
in db.tblUsers
where s.UserTypeId == code && s.UserID == id
select new Appt
{
BusinessName = s.tblBusinessCategory.BusinessName
// StartTime = s.WorkingHour.StartTime,
}).FirstOrDefault();
var sa = (from a
in db.WorkHours
where a.BusinessUserId == id
select new Appt
{
StartTime = a.StartTime,
EndTime = a.EndTime
}).FirstOrDefault();
Session["StartTime"] = sa.StartTime.Hour;
Session["EndTime"] = sa.EndTime.Hour;
Session["BUName"] = cal.BusinessName.ToString();
// var scheduler = new DHXScheduler(this);//{ InitialDate = new DateTime(2015, 1, 30) };
scheduler.Skin = DHXScheduler.Skins.Flat;
scheduler.Data.Loader.PreventCache();
scheduler.EnableDynamicLoading(SchedulerDataLoader.DynamicalLoadingMode.Week);
scheduler.Extensions.Add(SchedulerExtensions.Extension.Recurring);
//scheduler.Extensions.Add(SchedulerExtensions.Extension.ActiveLinks);
//scheduler.Extensions.Add(SchedulerExtensions.Extension.Collision);
scheduler.Extensions.Add(SchedulerExtensions.Extension.Limit);
scheduler.Config.limit_start = new DateTime(2015, 8, 25);
scheduler.Config.limit_end = new DateTime(2015, 9, 25);
scheduler.LoadData = true;
scheduler.EnableDataprocessor = true;
scheduler.Config.show_loading = true;
// scheduler.Config.buttons_left = ["dhx_save_btn","dhx_cancel_btn","locate_button"];
//var button = new LightboxButtonList();
//scheduler.Lightbox.Add();
int days = System.DateTime.Now.Day - 1;
int months = System.DateTime.Now.Month;
int years = System.DateTime.Now.Year;
int ihour = System.DateTime.Now.Hour;
int iminute = System.DateTime.Now.Minute;
int isecond = System.DateTime.Now.Second;
scheduler.TimeSpans.Add(new DHXBlockTime()
{
StartDate = new DateTime(2014, 2, 10),
EndDate = new DateTime(years, months, days + 1, ihour, iminute, isecond),
});
Session["BUId"] = id;
var parameter = new SqlParameter[1];
parameter[0] = new SqlParameter { ParameterName = "UserId", Value = id };
List<Appt> cm = new List<Appt>();
using (SYTEntities context = new SYTEntities())
{
cm = context.Database.SqlQuery<Appt>("exec spHoliday #UserId", parameter).ToList();
}
int iyear = 2015;
int imonth = 8;
int iday = 09;
//int ihour = 10;
int imin = 05;
int isec = 00;
foreach (var cp in cm)
{
iyear = cp.HolidayDate.Year;
imonth = cp.HolidayDate.Month;
iday = cp.HolidayDate.Day;
scheduler.TimeSpans.Add(new DHXMarkTime()
{
StartDate = new DateTime(iyear, imonth, iday), //new DateTime(2015, 8, 06), //hl.HolidayDate ?? default(DateTime),
EndDate = new DateTime(iyear, imonth, iday + 1),
// Day = DayOfWeek.Friday,
CssClass = "red_section",
HTML = "hos",
SpanType = DHXTimeSpan.Type.BlockEvents
});
}
var parameters = new SqlParameter[1];
parameters[0] = new SqlParameter { ParameterName = "BusinessUserId", Value = id };
List<Appt> wt = new List<Appt>();
using (SYTEntities context = new SYTEntities())
{
wt = context.Database.SqlQuery<Appt>("exec spGetWaitingList #BusinessUserId", parameters).ToList();
}
int ihr;
int imts;
int idayd;
int iyr;
int imnth;
int ihrs;
foreach (var cs in wt)
{
iyr = cs.EndTime.Year;// System.DateTime.Now.Year;
imnth = cs.EndTime.Month;// System.DateTime.Now.Month;
idayd = cs.EndTime.Day;// System.DateTime.Now.Day;
ihr = cs.EndTime.Hour; //.Hours; //.Hour;
imts = cs.EndTime.Minute; //.Minutes; //.Minute;
isec = cs.EndTime.Second; //.Seconds;
ihrs = cs.EndTime.Hour - cs.StartTime.Hour;
scheduler.TimeSpans.Add(new DHXMarkTime()
{
StartDate = new DateTime(iyr, imnth, idayd, ihr, imts, isec), //new DateTime(2015, 8, 06), //hl.HolidayDate ?? default(DateTime),
EndDate = new DateTime(iyr, imnth, idayd, ihr, imts, isec),
// Day = DayOfWeek.Friday,
CssClass = "green_section",
HTML = "",
SpanType = DHXTimeSpan.Type.BlockEvents
});
}
//for (int i = 0; i < 4; i++)
//{
// scheduler.TimeSpans.Add(new DHXMarkTime()
// {
// StartDate = new DateTime(iyear, imonth,iday,ihour, imin, isec), //new DateTime(2015, 8, 06), //hl.HolidayDate ?? default(DateTime),
// EndDate = new DateTime(iyear, imonth, iday,ihour, imin, isec),
// CssClass = "red_section",
// SpanType = DHXTimeSpan.Type.BlockEvents
// });
//}
scheduler.BeforeInit.Add("schedulerClient.init()");
//var check = new LightboxCheckbox("highlighting", "Important") { MapTo = "color", CheckedValue = "#FE7510" };
//scheduler.Lightbox.Add(check);
return View(scheduler);
}
return View();
}
Image
Do you mean you need to show some kind of popup showing additional info during task move/resize?
If so, you can use template for task content - if the current task is being dragged or resized, a template should return an absolute positioned popup with a custom content
E.g.
JS:
scheduler.attachEvent("onSchedulerReady", function () {
var headerTemplate = scheduler.templates.event_header;
scheduler.templates.event_header = function (start, end, event) {
var content = headerTemplate(start, end, event);
if (scheduler.getState().drag_id == event.id) {
var dragPopup = "<div class='drag-popup'>" + headerTemplate(start, end, event) + "</div>";
content += dragPopup;
}
return content;
};
});
CSS:
.drag-popup{
position: absolute;
right:0;
top: 0;
margin-right: 120px;
padding: 10px;
width: 100px;
background-color: inherit;
color: inherit;
z-index: 5;
}
Result:
Although, with this approach you'll need to manage tooltip position more thoughtfully than i did in this sample. Since popup is nested in event's DOM element, it will be limited by a scheduler container. E.g. when event is in left-most column - you'll need to locate popup at right, otherwise it will be cutted.
Here are the related API methods
http://docs.dhtmlx.com/scheduler/api__scheduler_getstate.html
http://docs.dhtmlx.com/scheduler/api__scheduler_event_header_template.html

Dhtmlx scheduler in mvc 4

I am using dhtmlx scheduler in my MVC project. My problem is i need to block the previous days in the scheduler. For example today is Monday means the previous day before monday should be blocked. Can anyone please help me?
Thanks in advance..
I added my code below.
public ActionResult CalendarView( int id , tblUser user )
{
string val = System.Configuration.ConfigurationManager.AppSettings["UserTypeId"];
int code = Convert.ToInt32(val);
Session["Butype"] = val;
var cal = (from s
in db.tblUsers
where s.UserTypeId == code && s.UserID == id
select new Appt
{
BusinessName = s.tblBusinessCategory.BusinessName,
StartTime = s.WorkingHour.StartTime
}).FirstOrDefault();
Session["BUName"] = cal.BusinessName.ToString();
var scheduler = new DHXScheduler(this);
scheduler.Skin = DHXScheduler.Skins.Flat;
scheduler.Data.Loader.PreventCache();
scheduler.EnableDynamicLoading(SchedulerDataLoader.DynamicalLoadingMode.Week);
scheduler.Extensions.Add(SchedulerExtensions.Extension.Recurring);
//scheduler.Extensions.Add(SchedulerExtensions.Extension.ActiveLinks);
//scheduler.Extensions.Add(SchedulerExtensions.Extension.Collision);
//scheduler.Extensions.Add(SchedulerExtensions.Extension.Limit);
scheduler.LoadData = true;
scheduler.EnableDataprocessor = true;
scheduler.Config.show_loading = true;
// scheduler.BeforeInit.Add("schedulerClient.init()");
Session["BUId"] = id;
var parameter = new SqlParameter[1];
parameter[0] = new SqlParameter { ParameterName = "UserId", Value = id };
List<Appt> cm = new List<Appt>();
using (SYTEntities context = new SYTEntities())
{
cm = context.Database.SqlQuery<Appt>("exec spHoliday #UserId", parameter).ToList();
}
int iyear = 2015;
int imonth = 8;
int iday = 09;
foreach (var cp in cm)
{
iyear = cp.HolidayDate.Year;
imonth = cp.HolidayDate.Month;
iday = cp.HolidayDate.Day;
scheduler.TimeSpans.Add(new DHXMarkTime()
{
StartDate = new DateTime(iyear, imonth, iday), //new DateTime(2015, 8, 06), //hl.HolidayDate ?? default(DateTime),
EndDate = new DateTime(iyear, imonth, iday + 1),
// Day = DayOfWeek.Friday,
CssClass = "red_section",
HTML = "hos",
SpanType = DHXTimeSpan.Type.BlockEvents
});
}
scheduler.BeforeInit.Add("schedulerClient.init()");
return View(scheduler);
}