- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-29-2024 01:42 PM
Hello everyone, could you help me with a problem?
I have a catalog item that has a field called "cr_due_date", in which the user can only select the last day of the month, however, if the last day of the month is a weekend (Saturday or Sunday) or a holiday, it should allow the user to enter the next business day.
I have this script that basically does this, however, what happens is that when I enter today's date, for example 11/29/2024, it should inform the user that the correct date to enter would be 12/02/2024. However, when I enter this date, it clears the field and says that the correct date to enter is 12/31/2024.
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var currentDate = new Date(newValue);
var currentMonth = currentDate.getMonth();
var currentYear = currentDate.getFullYear();
var lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0);
if (lastDayOfMonth.getDay() === 6) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 2);
} else if (lastDayOfMonth.getDay() === 0) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 1);
}
var ga = new GlideAjax('x_itke_csc_latam.getHoliday');
ga.addParam('sysparm_name','findHoliday');
ga.addParam('sysparm_date', formattedDate);
ga.getXML(callbackHoliday);
function callbackHoliday(response){
var resp = response.responseXML.documentElement.getAttribute('answer');
if (resp == "true"){
if(lastDayOfMonth.getDay() === 5){
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 3);
formattedDate = lastDayOfMonth;
}else{
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 1);
}
}
}
var formattedDate = lastDayOfMonth.toISOString().split('T')[0];
if (newValue !== formattedDate){
g_form.clearValue('cr_due_date');
g_form.showFieldMsg('cr_due_date', 'The date provided does not apply to payment rules. The correct date should be: ' + formattedDate, 'info');
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-30-2024 03:56 AM
This script runs fresh every time the Date is changed. The issue is not recursion, rather that your logic doesn't permit the first business day of the month to be selected, even when the previous month ends on a non-working day. Although formatted date ends up being declared before it is used due to hoisting, it would make more sense to follow best practices by declaring the variable at the beginning of the (onChange) function, setting the value before the GlideAjax call, then updating the value where you have it near the end. This will get you closer:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var currentDate = new Date(newValue);
var currentMonth = currentDate.getMonth();
var currentYear = currentDate.getFullYear();
var lastDayOfMonth = new Date();
var formattedDate = '';
var currentDayOfMonth = currentDate.getDate();
if (currentDayOfMonth < 4) { //a date near the beginning of a month was selected, check if the previous month ends on a non-working day
lastDayOfMonth = new Date(currentYear, currentMonth, 0);
} else { //check if selected month ends on a non-working day
lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0);
}
if (lastDayOfMonth.getDay() === 6) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 2);
} else if (lastDayOfMonth.getDay() === 0) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 1);
}
formattedDate = lastDayOfMonth.toISOString().split('T')[0];
var ga = new GlideAjax('x_itke_csc_latam.getHoliday');
ga.addParam('sysparm_name', 'findHoliday');
ga.addParam('sysparm_date', formattedDate);
ga.getXML(callbackHoliday);
function callbackHoliday(response) {
var resp = response.responseXML.documentElement.getAttribute('answer');
if (resp == "true") {
if (lastDayOfMonth.getDay() === 5) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 3);
formattedDate = lastDayOfMonth;
} else {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 1);
}
}
}
formattedDate = lastDayOfMonth.toISOString().split('T')[0];
if (newValue !== formattedDate) {
g_form.clearValue('cr_due_date');
g_form.showFieldMsg('cr_due_date', 'The date provided does not apply to payment rules. The correct date should be: ' + formattedDate, 'info');
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-29-2024 09:51 PM - edited 11-29-2024 09:51 PM
@Guilherme Popo2 Verify below aa looks issue with scope variable :
Variable Scope Issue: The formattedDate variable is used before it is defined. You should define formattedDate before calling GlideAjax for the holiday check, because you use formattedDate in your ga.addParam() call.
Asynchronous GlideAjax: The GlideAjax call is asynchronous. This means that when the callback callbackHoliday runs, the logic following the call (like the comparison with newValue) will execute before the response is received. This will cause issues where the field is cleared or not updated correctly because formattedDate isn't updated yet when the field value is checked.
Hope this will help you.
To fix these issues, you should restructure your script to handle the asynchronous behavior properly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-30-2024 03:56 AM
This script runs fresh every time the Date is changed. The issue is not recursion, rather that your logic doesn't permit the first business day of the month to be selected, even when the previous month ends on a non-working day. Although formatted date ends up being declared before it is used due to hoisting, it would make more sense to follow best practices by declaring the variable at the beginning of the (onChange) function, setting the value before the GlideAjax call, then updating the value where you have it near the end. This will get you closer:
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}
var currentDate = new Date(newValue);
var currentMonth = currentDate.getMonth();
var currentYear = currentDate.getFullYear();
var lastDayOfMonth = new Date();
var formattedDate = '';
var currentDayOfMonth = currentDate.getDate();
if (currentDayOfMonth < 4) { //a date near the beginning of a month was selected, check if the previous month ends on a non-working day
lastDayOfMonth = new Date(currentYear, currentMonth, 0);
} else { //check if selected month ends on a non-working day
lastDayOfMonth = new Date(currentYear, currentMonth + 1, 0);
}
if (lastDayOfMonth.getDay() === 6) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 2);
} else if (lastDayOfMonth.getDay() === 0) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 1);
}
formattedDate = lastDayOfMonth.toISOString().split('T')[0];
var ga = new GlideAjax('x_itke_csc_latam.getHoliday');
ga.addParam('sysparm_name', 'findHoliday');
ga.addParam('sysparm_date', formattedDate);
ga.getXML(callbackHoliday);
function callbackHoliday(response) {
var resp = response.responseXML.documentElement.getAttribute('answer');
if (resp == "true") {
if (lastDayOfMonth.getDay() === 5) {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 3);
formattedDate = lastDayOfMonth;
} else {
lastDayOfMonth.setDate(lastDayOfMonth.getDate() + 1);
}
}
}
formattedDate = lastDayOfMonth.toISOString().split('T')[0];
if (newValue !== formattedDate) {
g_form.clearValue('cr_due_date');
g_form.showFieldMsg('cr_due_date', 'The date provided does not apply to payment rules. The correct date should be: ' + formattedDate, 'info');
}
}