corrad-bp/docs/json/form/manager-approval-customScript.js
Md Afiq Iskandar 597a443453 Refactor Travel Workflow Components and Update Form Logic
- Updated VariableManager.vue to change variable type labels for clarity, replacing 'Int' and 'Decimal' with 'Number'.
- Modified manager-approval-customScript.js to correct field references and enhance conditional logic for displaying the custom approved amount.
- Enhanced manager-approval-form.json by adding 'readonly' attributes to several fields, ensuring they are non-editable during the approval process.
- Revised travel-workflow-process.json to improve node connections and labels for better workflow clarity.
- Updated travel-workflow-variables.json to refine variable descriptions and ensure consistency across the workflow.
- Adjusted [id].vue to improve form data handling and loading states, enhancing user experience during workflow execution.
2025-07-25 14:29:04 +08:00

296 lines
8.2 KiB
JavaScript

// Manager Approval Form Custom Script Engine
// This script provides dynamic behavior for the manager approval form
console.log("Manager Approval Form Script Loaded");
// Auto-set approval date to today
const setApprovalDate = () => {
const today = new Date();
const formattedDate = today.toISOString().split("T")[0]; // YYYY-MM-DD format
setField("approval_date", formattedDate);
};
// Calculate and display recommended approval amounts
const calculateRecommendedAmounts = () => {
const totalClaimed = parseFloat(getField("total_cost_display")) || 0;
const policyLimit = parseFloat(getField("policy_limit_display")) || 0;
const overBudget = parseFloat(getField("over_budget_amount")) || 0;
if (totalClaimed > 0 && policyLimit > 0) {
const percentageOver = ((overBudget / policyLimit) * 100).toFixed(1);
showInfo(
`This claim is ${percentageOver}% over the policy limit. Policy limit: RM${policyLimit.toFixed(2)}, Claimed: RM${totalClaimed.toFixed(2)}`
);
}
};
// Validate manager decision and provide guidance
const handleDecisionChange = (decision) => {
const totalClaimed = parseFloat(getField("total_cost_display")) || 0;
const policyLimit = parseFloat(getField("policy_limit_display")) || 0;
console.log("Manager decision changed to:", decision);
switch (decision) {
case "approve_full":
showField("custom_approved_amount");
showInfo(
`💰 Approving full amount: RM${totalClaimed.toFixed(2)}. You can enter a custom amount if needed.`
);
setField("custom_approved_amount", totalClaimed.toString());
break;
case "approve_policy":
hideField("custom_approved_amount");
showInfo(
`⚖️ Approving policy limit only: RM${policyLimit.toFixed(2)}. Employee will be notified of the reduced amount.`
);
break;
case "reject":
hideField("custom_approved_amount");
showError(
"❌ Claim will be rejected. Please provide detailed comments explaining the rejection reason."
);
break;
default:
hideField("custom_approved_amount");
}
};
// Validate custom approved amount
const validateCustomAmount = (amount) => {
const numAmount = parseFloat(amount) || 0;
const totalClaimed = parseFloat(getField("total_cost_display")) || 0;
const policyLimit = parseFloat(getField("policy_limit_display")) || 0;
if (numAmount < 0) {
showError("Approved amount cannot be negative");
return false;
}
if (numAmount > totalClaimed) {
showError(
`Approved amount (RM${numAmount}) cannot exceed claimed amount (RM${totalClaimed})`
);
return false;
}
if (numAmount > 0 && numAmount < policyLimit) {
showInfo(
`Custom amount (RM${numAmount}) is less than policy limit (RM${policyLimit}). Consider approving policy limit instead.`
);
}
return true;
};
// Validate manager comments based on decision
const validateComments = (comments, decision) => {
if (!comments || comments.trim().length < 10) {
showError("Please provide detailed comments (minimum 10 characters)");
return false;
}
if (decision === "reject" && comments.length < 50) {
showError(
"Rejection requires detailed explanation (minimum 50 characters)"
);
return false;
}
if (decision === "approve_full") {
const totalClaimed = parseFloat(getField("total_cost_display")) || 0;
const policyLimit = parseFloat(getField("policy_limit_display")) || 0;
const overBudget = totalClaimed - policyLimit;
if (overBudget > 500 && !comments.toLowerCase().includes("business")) {
showInfo(
"Consider mentioning business justification for approving over-budget amounts > RM500"
);
}
}
return true;
};
// Format manager name (title case)
const formatManagerName = (name) => {
if (!name || typeof name !== "string") return name;
return name
.toLowerCase()
.split(" ")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
};
// Form validation before submission
const validateApprovalForm = () => {
let isValid = true;
const errors = [];
// Check required fields
const requiredFields = {
manager_decision: "Approval Decision",
manager_comments: "Manager Comments",
manager_name: "Manager Name",
approval_date: "Approval Date",
};
Object.entries(requiredFields).forEach(([fieldName, displayName]) => {
const value = getField(fieldName);
if (!value || value.toString().trim() === "") {
errors.push(`${displayName} is required`);
isValid = false;
}
});
// Validate decision-specific requirements
const decision = getField("manager_decision");
const comments = getField("manager_comments");
const customAmount = getField("custom_approved_amount");
if (decision && comments) {
if (!validateComments(comments, decision)) {
isValid = false;
}
}
if (decision === "approve_full" && customAmount) {
if (!validateCustomAmount(customAmount)) {
isValid = false;
}
}
// Validate approval date is not in the future
const approvalDate = getField("approval_date");
if (approvalDate) {
const selectedDate = new Date(approvalDate);
const today = new Date();
today.setHours(23, 59, 59, 999); // End of today
if (selectedDate > today) {
errors.push("Approval date cannot be in the future");
isValid = false;
}
}
// Show validation results
if (errors.length > 0) {
showError(`Please fix the following errors:\n${errors.join("\n• ")}`);
} else {
showSuccess("Form validation passed! Ready to submit approval decision.");
}
return isValid;
};
// Set up field change handlers
onFieldChange("manager_decision", (newValue) => {
if (newValue) {
handleDecisionChange(newValue);
}
});
onFieldChange("custom_approved_amount", (newValue) => {
if (newValue) {
validateCustomAmount(newValue);
}
});
onFieldChange("manager_comments", (newValue) => {
const decision = getField("manager_decision");
if (newValue && decision) {
validateComments(newValue, decision);
}
});
onFieldChange("manager_name", (newValue) => {
if (newValue && typeof newValue === "string") {
const formatted = formatManagerName(newValue);
if (formatted !== newValue) {
setTimeout(() => {
setField("manager_name", formatted);
}, 100);
}
}
});
// Wait until all required fields are present before running initialization
function waitForFields(fields, callback, maxAttempts = 20) {
let attempts = 0;
function check() {
const allPresent = fields.every((f) => getField(f) !== undefined);
if (allPresent) {
callback();
} else if (attempts < maxAttempts) {
attempts++;
setTimeout(check, 100);
} else {
showError("Some required fields are missing. Please reload the page.");
}
}
check();
}
waitForFields(
[
"total_cost_display",
"policy_limit_display",
"over_budget_amount",
// add any other required fields here
],
() => {
setApprovalDate();
calculateRecommendedAmounts();
showInfo(
"Review the claim details above and make your approval decision below."
);
}
);
// Expose validation function for form submission
window.validateManagerApprovalForm = validateApprovalForm;
console.log("Manager Approval Form Script initialized successfully");
// Conditional logic for field: custom_approved_amount
onFieldChange("manager_decision", function () {
if (getField("manager_decision") === "approve_full") {
showField("custom_approved_amount");
} else {
hideField("custom_approved_amount");
}
});
// Initial evaluation for field: custom_approved_amount
(function () {
if (getField("manager_decision") === "approve_full") {
showField("custom_approved_amount");
} else {
hideField("custom_approved_amount");
}
})();
// Conditional Logic Script
// Conditional logic for field: custom_approved_amount
onFieldChange("manager_decision", function () {
if (getField("manager_decision") === "approve_full") {
showField("custom_approved_amount");
} else {
hideField("custom_approved_amount");
}
});
// Initial evaluation for field: custom_approved_amount
(function () {
if (getField("manager_decision") === "approve_full") {
showField("custom_approved_amount");
} else {
hideField("custom_approved_amount");
}
})();