server script:
request_data = frappe.form_dict
frappe.log(request_data)
filters = request_data.get(‘filters’)
order_by = request_data.get(‘order_by’)
limit_lead = int(request_data.get(‘limit_lead’))
person_to_start = int(request_data.get(‘person_to_start’))
table_main = json.loads(request_data.get(‘table_main’))
leadAssignment =
counter = 0
total_daily_limit = 0
for value in table_main:
temp_var = {
‘name’: value.get(‘name’),
“sales_person”: value.get(‘sales_person’),
“user_email”: value.get(‘user_email’),
‘daily_total_count’: value.get(‘daily_total_count’),
‘daily_limit’: value.get(‘daily_limit’),
‘assign_leads’: ,
‘last_active’: value.get(‘last_active’)
}
# Get All Data present in table of Lead Rule
leadAssignment.append(temp_var)
counter = counter + value.get(‘daily_total_count’)
total_daily_limit = total_daily_limit + value.get(‘daily_limit’)
Condition Defined for to check daliy limit
if total_daily_limit > counter:
# Length Of table is defined
tableLength = len(table_main)
# Total number of available Lead
leadList = frappe.db.get_list(‘Lead’, filters=filters, fields=[“*”], order_by=order_by)
leadListLength = len(leadList)
temp_leadListLength = leadListLength if leadListLength < limit_lead else limit_lead
# Flag to check the number of Lead Assignments
total_lead_assigned = 0
# Create A Lead Queue and Table Queue to distibute in round robin:---
table_queue = [x for x in range(tableLength)]
lead_queue = [x for x in range(leadListLength)]
lead_received = {person : leadAssignment[person].get('daily_total_count') for person in table_queue}
max_lead_per_person = {person : leadAssignment[person].get('daily_limit') for person in table_queue}
# total_expected_lead = temp_leadListLength if temp_leadListLength < total_daily_limit else total_daily_limit
total_lead_assigned = counter
total_lead_to_be_assign = total_daily_limit
rem_no_lead_to_be_assign = total_lead_to_be_assign - total_lead_assigned
total_expected_lead = temp_leadListLength if temp_leadListLength < rem_no_lead_to_be_assign else rem_no_lead_to_be_assign
lead_assigned_counter = 0
temp_person_to_start = person_to_start
# frappe.log_error(table_queue)
# tt = True
no_lead_assigned = False
while (lead_queue and lead_assigned_counter < total_expected_lead):
# while(tt):
total_no_of_lead_to_be_assined = 0
lead_assigned = 0
for person in table_queue:
person = (person + temp_person_to_start) % tableLength
person_to_start = person
userDoc = ''
last_active = ''
if leadAssignment[person].get('user_email'):
userDoc = frappe.get_cached_doc('User', leadAssignment[person].get('user_email'))
last_active = userDoc.get('last_active')
# frappe.log_error([last_active,lead_queue, leadAssignment[person].get('user_email'), leadAssignment[person]['daily_total_count'] , max_lead_per_person[person], leadAssignment[person].get('user_email') , frappe.utils.date_diff(last_active, frappe.utils.now_datetime())])
if lead_queue and leadAssignment[person]['daily_total_count'] < max_lead_per_person[person] and leadAssignment[person].get('user_email') and frappe.utils.date_diff(last_active, frappe.utils.now_datetime()) == 0: # max_lead_per_person is dynamic need to check..
# frappe.log_error([lead_queue, leadAssignment[person].get('user_email'), leadAssignment[person]['daily_total_count'] , max_lead_per_person[person], leadAssignment[person].get('user_email') , frappe.utils.date_diff(last_active, frappe.utils.now_datetime())])
lead_popped = lead_queue.pop(0)
# if (
# leadAssignment[person].get('daily_limit') > leadAssignment[person].get('daily_total_count')
# and leadAssignment[person].get('user_email')
# and frappe.utils.date_diff(last_active, frappe.utils.now_datetime()) == 0
# ):
if not leadAssignment[person].get('last_active'):
leadAssignment[person]['last_active'] = last_active #if not leadAssignment[person].get('last_active') else leadAssignment[person].get('last_active')
leadAssignment[person]['daily_total_count'] = leadAssignment[person]['daily_total_count'] + 1
leadAssignment[person]['assign_leads'].append(leadList[lead_popped].name)
# frappe.log_error([lead_popped],"lead_popped")
leadDoc = frappe.get_cached_doc('Lead', leadList[lead_popped].name)
leadDoc.lead_owner = leadAssignment[person].get('user_email')
leadDoc.contact_date = ''
leadDoc.sales_person = leadAssignment[person].get('sales_person')
leadDoc.lead_owner_counter = leadDoc.lead_owner_counter + 1
leadDoc.lead_assign_time = frappe.utils.now_datetime()
leadDoc.save(ignore_permissions=1)
lead_assigned_counter = lead_assigned_counter + 1
total_no_of_lead_to_be_assined = total_no_of_lead_to_be_assined + max_lead_per_person[person]
lead_assigned = lead_assigned + leadAssignment[person]['daily_total_count']
if (lead_assigned_counter >= total_expected_lead):
# no_lead_assigned = True
break
if total_no_of_lead_to_be_assined == 0 and lead_assigned == 0:
no_lead_assigned = True
break
# tt = False
base_condition = len(lead_queue) if (rem_no_lead_to_be_assign - lead_assigned_counter) > len(lead_queue) else (rem_no_lead_to_be_assign - lead_assigned_counter)
frappe.response['result'] = leadAssignment, leadListLength,len(lead_queue),base_condition, person_to_start + 1, no_lead_assigned
client script:
frappe.ui.form.on(“Lead Rule”, {
validate: function(frm){
// All the variables of fields to filter out the data
let name = frm.doc.name;
let stage = frm.doc.stage;
let leadStatus = frm.doc.contact_status;
let temperature = frm.doc.lead_status;
let converted = frm.doc.converted;
let dndCheck = frm.doc.dnd;
let assign_count_from = frm.doc.assign_count_from;
let assign_count_to = frm.doc.assign_count_to;
let contactStatus = frm.doc.contact_status;
let routing_method = frm.doc.routing_method;
let leadOwnerLR = frm.doc.sales_person;
let leadReply = frm.doc.lead_reply;
let leadRuleTable = frm.doc.table_main;
let leadRuleCondition = frm.doc.attempted_reply; // attempted_reply
let leadRuleSecondCond = frm.doc.lead_reply; // lead_reply
// let assignvaluesSeperated = frm.doc.assign_count;
let from_date = frm.doc.from_date;
let to_date = frm.doc.to_date;
let campaign_name = frm.doc.campaign_name;
let grade = frm.doc.grade;
let final_array_dist = ;
let creationTimeLead = “”;
let attemptedReply = “”;
let dateTimeNow = frappe.datetime.now_date();
let filters = ;
let order_by = “”;
let modified_from_date = frm.doc.modified_from_date;
let modified_to_date = frm.doc.modified_to_date;
// Take all the filters and consolidate at one place
if (contactStatus === "Not Contacted"){
leadReply = "";
attemptedReply = "";
}else if(contactStatus === "Attempted to Contact"){
leadReply = "";
attemptedReply = leadRuleCondition;
}else if(contactStatus === "Contacted"){
leadReply = leadRuleSecondCond;
attemptedReply = "";
}
if(routing_method === "Created LIFO"){
order_by = "creation DESC";
}else if(routing_method === "Created FIFO"){
order_by = "creation ASC";
}
if(leadOwnerLR){
filters.push(["Lead","sales_person","=",leadOwnerLR]);
}
if(from_date && to_date){
filters.push(["Lead","creation","between",[from_date,to_date]]);
}
if(modified_from_date && modified_to_date){
filters.push(["Lead","modified","between",[modified_from_date,modified_to_date]]);
}
if(assign_count_from){
filters.push(["Lead","lead_owner_counter",">=",assign_count_from]);
}
if(assign_count_to){
filters.push(["Lead","lead_owner_counter","<=",assign_count_to]);
}
if(attemptedReply){
filters.push(["Lead","attempted_reply","=",attemptedReply]);
}
if(leadReply){
filters.push(["Lead", "lead_reply", "=", leadReply]);
}
if(dndCheck){
filters.push(["Lead", "dnd", "=", dndCheck]);
}
if(converted){
filters.push(["Lead", "converted_lead", "=", converted]);
}
if(leadStatus){
filters.push(["Lead", "lead_status", "=", leadStatus]);
}
if(stage){
filters.push(["Lead", "status", "=", stage]);
}
if(temperature){
filters.push(["Lead", "temperature", "=", temperature]);
}
if(campaign_name){
filters.push(["Lead", "campaign_name", "=", campaign_name]);
}
if(grade){
filters.push(["Lead", "grade", "=", grade]);
}
// Append Filtered records in single array
// console.log(filters,"filters");
// Frappe to custom created API to set the data based on filters
frappe.call({
method:"get_lead_count",
type:"POST",
args:{
filters:filters,
order_by: order_by,
},
callback: function(r){
// console.log(r,'r');
let result = r.result;
// console.log(result,'result');
// Set value of lead count
if(frm.doc.lead_count || frm.doc.lead_count === 0){
frm.set_value('lead_count',result);
// frm.save();
}
}
});
},
before_save: function (frm) {
// Function to make attempted reply and lead reply as blank when Contact Status is Contacted
action_on_contact_status(frm);
},
refresh: function (frm) {
// Lead rule Execution on click of button
frm.add_custom_button(__("Execute"), function(){
// All the variables of fields to filter out the data
let name = frm.doc.name;
let stage = frm.doc.stage;
let leadStatus = frm.doc.contact_status;
let temperature = frm.doc.lead_status;
let converted = frm.doc.converted;
let dndCheck = frm.doc.dnd;
let assign_count_from = frm.doc.assign_count_from;
let assign_count_to = frm.doc.assign_count_to;
let contactStatus = frm.doc.contact_status;
let routing_method = frm.doc.routing_method;
let leadOwnerLR = frm.doc.sales_person;
let leadReply = frm.doc.lead_reply;
let leadRuleTable = frm.doc.table_main;
// let assignvaluesSeperated = frm.doc.assign_count;
let leadRuleCondition = frm.doc.attempted_reply; // attempted_reply
let leadRuleSecondCond = frm.doc.lead_reply; // lead_reply
let from_date = frm.doc.from_date;
let to_date = frm.doc.to_date;
let campaign_name = frm.doc.campaign_name;
let grade = frm.doc.grade;
let final_array_dist = [];
let creationTimeLead = "";
let attemptedReply = "";
let dateTimeNow = frappe.datetime.now_date();
let filters = [];
let order_by = "";
let modified_from_date = frm.doc.modified_from_date;
let modified_to_date = frm.doc.modified_to_date;
// Take all the filters and consolidate at one place
if (contactStatus === "Not Contacted"){
leadReply = "";
attemptedReply = "";
}else if(contactStatus === "Attempted to Contact"){
leadReply = "";
attemptedReply = leadRuleCondition;
}else if(contactStatus === "Contacted"){
leadReply = leadRuleSecondCond;
attemptedReply = "";
}
if(routing_method === "Created LIFO"){
order_by = "creation DESC";
}else if(routing_method === "Created FIFO"){
order_by = "creation ASC";
}
if(leadOwnerLR){
filters.push(["Lead","sales_person","=",leadOwnerLR]);
}
if(from_date && to_date){
filters.push(["Lead","creation","between",[from_date,to_date]]);
}
if(modified_from_date && modified_to_date){
filters.push(["Lead","modified","between",[modified_from_date,modified_to_date]]);
}
if(assign_count_from){
filters.push(["Lead","lead_owner_counter",">=",assign_count_from]);
}
if(assign_count_to){
filters.push(["Lead","lead_owner_counter","<=",assign_count_to]);
}
if(attemptedReply){
filters.push(["Lead","attempted_reply","=",attemptedReply]);
}
if(leadReply){
filters.push(["Lead", "lead_reply", "=", leadReply]);
}
if(dndCheck){
filters.push(["Lead", "dnd", "=", dndCheck]);
}
if(converted){
filters.push(["Lead", "converted_lead", "=", converted]);
}
if(leadStatus){
filters.push(["Lead", "lead_status", "=", leadStatus]);
}
if(stage){
filters.push(["Lead", "status", "=", stage]);
}
if(temperature){
filters.push(["Lead", "temperature", "=", temperature]);
}
if(campaign_name){
filters.push(["Lead", "campaign_name", "=", campaign_name]);
}
if(grade){
filters.push(["Lead", "grade", "=", grade]);
}
// Append Filtered records in single array
// console.log(filters,"filters");
// Frappe to custom created API to set the data based on filters
let updated_table_value = []
let lead_count_after_assignment = undefined;
let count = 0
let flag = true
let person_to_start = 0;
let limit_lead = 200;
let table_main = cur_frm.doc.table_main
async function to_call_once(){
while(flag){
async function lead_assignment(){
await frappe.call({
method:"assign_leads_based_on_filters",
type:"POST",
args:{
filters:filters,
order_by: order_by,
table_main:table_main,
limit_lead:limit_lead,
person_to_start: person_to_start
},
freeze: true,
timeout: 300000,
callback: function(r){
console.log(r,'r');
let result = r.result;
// console.log(result,'result')
let usersLead = result[0];
// Set value of lead count
frm.set_value('lead_count',r.result[2]);
lead_count_after_assignment = r.result[2]
if(limit_lead > lead_count_after_assignment){
limit_lead = lead_count_after_assignment;
}
person_to_start = r.result[4]
if(r.result[1] === 0){
frappe.msgprint(__("No Filtered Leads Found To Assign"));
}
if(r.result[3] <= 0){
flag = false
}
if(r.result[5] == 1){
frappe.msgprint("Lead Can't be Assigned")
flag = false
}
else{
count += 1;
let user_activity = []
table_main = usersLead
updated_table_value = usersLead
// console.log(usersLead,'usersLead')
// usersLead.forEach((values) =>{
// frappe.model.set_value('Lead Rule Table', values.name, "daily_total_count", values.daily_total_count);
// frappe.model.set_value('Lead Rule Table', values.name, "last_activity_time", values.last_active);
// user_activity.push(values.last_active);
// refresh_field(frm.doc.table_main);
// });
// frm.save();
}
},
error: function(err) {
frappe.msgprint(__('Error during API call. Please try again.'));
console.error(err);
}
});
}
// flag = false;
await lead_assignment()
}
console.log(updated_table_value, lead_count_after_assignment, count, person_to_start,table_main)
frm.set_value('lead_count',lead_count_after_assignment);
updated_table_value.forEach((values) =>{
frappe.model.set_value('Lead Rule Table', values.name, "daily_total_count", values.daily_total_count);
frappe.model.set_value('Lead Rule Table', values.name, "last_activity_time", values.last_active);
// user_activity.push(values.last_active);
refresh_field(frm.doc.table_main);
});
frm.save()
}
to_call_once()
});
}
});
I am facing the error request timed out when hitting the execute button. Can anyone help me, please?