This document explains the overall flow and structure of the code in the CRM module. It describes how different parts work together and the main processes used to manage customer relationships effectively.

LEAD MODULE

Lead.js

This document contains information about the customer, such as their first name, source etc. The main functionality focuses on updating the parent status and doc status fields and the probability when activities are performed on the Lead doctype.


if (frm.doc.status == "Enquiry") {
            frm.set_value('probability', '0')
            frm.set_value('parent_status', 'In Process')
        }
        else if (frm.doc.status == "Contacted") {
            frm.set_value('probability', '5')
            frm.set_value('parent_status', 'In Process')
        }
        else if (frm.doc.status == "Need Analysis") {
            frm.set_value('probability', '10')
            frm.set_value('parent_status', 'In Process')
            cur_frm.set_df_property("from_date", "reqd", "1")
            cur_frm.set_df_property("to_date", "reqd", "1")
        }


In the above code, it shows the progress of a Lead through different predefined stages.The probability field shows how likely it is to convert the lead at each stage. The parent_status organizes these stages into broader groups like "In Process" or "Won."


And after the 500-millisecond delay to ensure proper execution it hides the following buttons from the interface .

  • "New Task"

  • "Open Tasks"

  • "New Event"



And in the py file there is a validation over the lead creation for the duplicate lead and another function takes a time value in seconds and converts it into a formatted string representing hours, minutes, and seconds in the format hours, minutes and seconds.

PROPOSAL MODULE


It is a Quotation Doctype including all the calculations over the fields as over the Location Preference if the location preference is there will be callback function to filter the business unit from the comapny address. And on selecting the customer the location preference will be filter.


Now there will be Proposal Item there will be calculation over the item group as calculate the number of days and months between two dates from date & end datef or a specific condition where the item group is "Serviced Office".

Proposal.js


if (row.from_time && row.to_time && row.item_group == "Serviced Office") {
        const start_date = moment(new Date(row.from_time)).format("YYYY-MM")
        const booked_date = moment(new Date(row.from_time)).format("DD")
        // console.log(type_of(parseInt(booked_date)))
        const totalNoOfDaysOfMonth = moment(start_date, "YYYY-MM").daysInMonth()
        console.log(totalNoOfDaysOfMonth)
        const noOfDaysInFirstMonth = (totalNoOfDaysOfMonth - booked_date) + 1
        console.log(noOfDaysInFirstMonth)
        frappe.model.set_value(cdt, cdn, "days", totalNoOfDaysOfMonth == noOfDaysInFirstMonth ? 0 : noOfDaysInFirstMonth)
        frappe.model.set_value(cdt, cdn, "days", totalNoOfDaysOfMonth == noOfDaysInFirstMonth ? 0 : noOfDaysInFirstMonth)
        const months = moment(row.to_time).add(1, 'day').diff(moment(row.from_time), "months")
        console.log("Months: ", months)
        frappe.model.set_value(cdt, cdn, "months", months)
    }


The number of days remaining in the month when the booking starts. The total number of months between the start and end times. It then sets these values days & month in the respective fields for the "Serviced Office" item group.

And the amount will be calculated according to the rate entered and then the prodata will be calculated and on change of the quantity the prodata will be updated.

There is also a function to calculate the terms section date as the function calculates the duration in months between a given start date and end date in a form and sets this value in the duration field.

For the calculation of the format of the date as given below:


function _addOneDay(inputDateString) {
    var inputDate = new Date(inputDateString)
    inputDate.setDate(inputDate.getDate() + 1);
    var year = inputDate.getFullYear();
    var month = String(inputDate.getMonth() + 1).padStart(2, '0');
    var day = String(inputDate.getDate()).padStart(2, '0');
    var hours = String(inputDate.getHours()).padStart(2, '0');
    var minutes = String(inputDate.getMinutes()).padStart(2, '0');
    var seconds = String(inputDate.getSeconds()).padStart(2, '0');
    var formattedDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
    return formattedDate;
}


This functiond gives the functionality of the returining the formated date as a string. Uses the setDate method to increase the day of the month by 1. The getDate method fetches the current day, and adding 1 shifts it forward.

After this, there is amount calculation function which performs the calculation on a form.


function _global_amount_calculation(frm) {
    let amt_aft_dis = 0;
    let total_discount = 0;
    const items= frm.doc.item ?? [];
    items.forEach(item => {
        amt_aft_dis += item.amount ?? 0
        total_discount += item.discount ?? 0
    })
    const total_cost = amt_aft_dis + total_discount
    const total_percentage = (total_discount / total_cost) * 100
    console.log("AMT AFT DIS: ", amt_aft_dis)
    console.log("TOTAL DISCOUNT: ", total_discount)
    console.log("TOTAL COST: ", total_cost)
    console.log("TOTAL PERCENTAGE: ", total_percentage);
    frm.set_value("amt_aft_dis", amt_aft_dis)
    frm.set_value("total_cost", total_cost)
    frm.set_value("total_discount", total_discount)
    frm.set_value("total_percentage", total_percentage)
    _calculateTerms(frm)
}


The global amount calculation function adds up the amounts and discounts from the items in the form. It calculates the total cost and discount percentage, then updates the form with these values. Finally, it calls another function Calculate terms, to handle any further calculations.


On this page