How to create Filter Doctype

@Devershi_Vashistha Yes, it helps a lot. It was a spelling mistake. Here is the updated code.

After trying this code, please check the console log again.

frappe.ui.form.on("Filter", {
    refresh: function(frm) {
        if (!frm.is_new()) {
            frm.add_custom_button('Apply Filter', () => frm.trigger('add_filtered_emails'));
            frm.change_custom_button_type('Apply Filter', null, 'success');
        }
    },
    add_filtered_emails: function(frm) {
        let emails = [];
        let pipe = new Promise ((resolve) => { resolve(frm.doc); });
        pipe.then(doc => {
            let filter = {};
            if (!!doc.country) filter.country = doc.country;
            if (!!doc.city) filter.city = doc.city;
            frappe.db.get_list('Address', {
                fields: ['email_id'],
                filters: filter
            }).then(data => {
                $.each(data, function(i, v) {
                    emails.push(v.email_id);
                });
            });
            return doc;
        }).then(doc => {
            let filter = {};
            if (!!doc.intent) filter.intent = doc.intent;
            if (!!doc.package) filter.package = doc.package;
            if (!!doc.start_date && !!doc.end_date) {
                filter.datetime = [
                    'between',
                    [doc.start_date + ' 00:00:00', doc.end_date + ' 00:00:00']
                ];
            } else if (!!doc.start_date) {
                filter.datetime = ['>=', doc.start_date + ' 00:00:00'];
            } else if (!!doc.end_date) {
                filter.datetime = ['<=', doc.end_date + ' 00:00:00'];
            }
            frappe.db.get_list('Session History Collection', {
                fields: ['email'],
                filters: filter
            }).then(data => {
                $.each(data, function(i, v) {
                    if (emails.indexOf(v.email) < 0) emails.push(v.email);
                });
            });
            return doc;
        })
        .then(doc => {
            frappe.db.get_list('Email Group Member', {
                fields: ['email'],
                filters: {
                    email: ['in', emails]
                }
            }).then(data => {
                if (data.length) {
                    $.each(data, function(i, v) {
                        let idx = emails.indexOf(v.email);
                        if (idx >= 0) emails.splice(idx, 1);
                    });
                }
                let docs = [];
                let args = [];
                $.each(emails, function(i, v) {
                    docs.push({
                        doctype: 'Email Group Member',
                        email_group: doc.email_group,
                        email: v,
                    });
                });
                if (docs.length > 200) {
                    for (var i = 0, l = docs.length; i < l; i += 200) {
                        args.push(docs.slice(i, i + 200));
                    }
                } else {
                    args = [docs];
                }
                let result = [];
                $.each(args, function(i, arg) {
                    let ret = frappe.call({
                        type: 'POST',
                        method: 'frappe.client.insert_many',
                        args: {
                            docs: arg,
                        }
                    });
                    result.push.apply(result, ret);
                });
                // for debugging purpose only
                console.log(
                    'Total existing members: ' + data.length,
                    'Total filtered emails: ' + emails.length,
                    'Total inserted emails: ' + result.length
                );
            });
        });
    }
});

23
It shows this but it is working.
let me check more.

@Devershi_Vashistha

Change this at the end

result.push(...ret);

To this

result.push.apply(result, ret);

Or this

Array.prototype.push.apply(result, ret);

It’s a way to push multiple items in an array to another. So instead of using a loop and push items one by one, I do it all together.

I also updated the code above.


it is showing this

@kid1194 If possible can we connect?

@Devershi_Vashistha sorry, I’m using my phone now.

I believe that the error is from your Email Group Member doctype. You have set the email group field as unique.

@kid1194 unique is not checked in email group member doctype.

@Devershi_Vashistha Check also the email_group field in Filter doctype.


its not checked there as well

@kid1194 this is an error I am getting.

@Devershi_Vashistha I know what is the problem. Multiple insert is not supported the way it should, so I will update the code and post it for you.

ok Thank you

@Devershi_Vashistha This is the code.

It insert emails to Email Group Member one by one.

frappe.ui.form.on("Filter", {
    refresh: function(frm) {
        if (!frm.is_new()) {
            frm.add_custom_button('Apply Filter', () => frm.trigger('add_filtered_emails'));
            frm.change_custom_button_type('Apply Filter', null, 'success');
        }
    },
    add_filtered_emails: function(frm) {
        let emails = [];
        let pipe = new Promise ((resolve) => { resolve(frm.doc); });
        pipe.then(doc => {
            let filter = {};
            if (!!doc.country) filter.country = doc.country;
            if (!!doc.city) filter.city = doc.city;
            frappe.db.get_list('Address', {
                fields: ['email_id'],
                filters: filter
            }).then(data => {
                $.each(data, function(i, v) {
                    emails.push(v.email_id);
                });
            });
            return doc;
        }).then(doc => {
            let filter = {};
            if (!!doc.intent) filter.intent = doc.intent;
            if (!!doc.package) filter.package = doc.package;
            if (!!doc.start_date && !!doc.end_date) {
                filter.datetime = [
                    'between',
                    [doc.start_date + ' 00:00:00', doc.end_date + ' 00:00:00']
                ];
            } else if (!!doc.start_date) {
                filter.datetime = ['>=', doc.start_date + ' 00:00:00'];
            } else if (!!doc.end_date) {
                filter.datetime = ['<=', doc.end_date + ' 00:00:00'];
            }
            frappe.db.get_list('Session History Collection', {
                fields: ['email'],
                filters: filter
            }).then(data => {
                $.each(data, function(i, v) {
                    if (emails.indexOf(v.email) < 0) emails.push(v.email);
                });
            });
            return doc;
        })
        .then(doc => {
            frappe.db.get_list('Email Group Member', {
                fields: ['email'],
                filters: {
                    email: ['in', emails]
                }
            }).then(data => {
                if (data.length) {
                    $.each(data, function(i, v) {
                        let idx = emails.indexOf(v.email);
                        if (idx >= 0) emails.splice(idx, 1);
                    });
                }
                let result = [];
                $.each(emails, function(i, v) {
                    frappe.db.insert({
                        doctype: 'Email Group Member',
                        email_group: doc.email_group,
                        email: v,
                    }).then(d => {
                        result.push(d);
                    });
                });
                
                // for debugging purpose only
                console.log(
                    'Total existing members: ' + data.length,
                    'Total filtered emails: ' + emails.length,
                    'Total inserted emails: ' + result.length
                );
            });
        });
    }
});

@kid1194 It shows this

@Devershi_Vashistha There must be some duplicated emails from Address doctype. This code checks for duplicates everywhere.

frappe.ui.form.on("Filter", {
    refresh: function(frm) {
        if (!frm.is_new()) {
            frm.add_custom_button('Apply Filter', () => frm.trigger('add_filtered_emails'));
            frm.change_custom_button_type('Apply Filter', null, 'success');
        }
    },
    add_filtered_emails: function(frm) {
        let emails = [];
        let pipe = new Promise ((resolve) => { resolve(frm.doc); });
        pipe.then(doc => {
            let filter = {};
            if (!!doc.country) filter.country = doc.country;
            if (!!doc.city) filter.city = doc.city;
            frappe.db.get_list('Address', {
                fields: ['email_id'],
                filters: filter
            }).then(data => {
                $.each(data, function(i, v) {
                    if (emails.indexOf(v.email_id) < 0) emails.push(v.email_id);
                });
            });
            return doc;
        }).then(doc => {
            let filter = {};
            if (!!doc.intent) filter.intent = doc.intent;
            if (!!doc.package) filter.package = doc.package;
            if (!!doc.start_date && !!doc.end_date) {
                filter.datetime = [
                    'between',
                    [doc.start_date + ' 00:00:00', doc.end_date + ' 00:00:00']
                ];
            } else if (!!doc.start_date) {
                filter.datetime = ['>=', doc.start_date + ' 00:00:00'];
            } else if (!!doc.end_date) {
                filter.datetime = ['<=', doc.end_date + ' 00:00:00'];
            }
            frappe.db.get_list('Session History Collection', {
                fields: ['email'],
                filters: filter
            }).then(data => {
                $.each(data, function(i, v) {
                    if (emails.indexOf(v.email) < 0) emails.push(v.email);
                });
            });
            return doc;
        })
        .then(doc => {
            frappe.db.get_list('Email Group Member', {
                fields: ['email'],
                filters: {
                    email: ['in', emails]
                }
            }).then(data => {
                if (data.length) {
                    $.each(data, function(i, v) {
                        var idx = emails.indexOf(v.email);
                        if (idx >= 0) emails.splice(idx, 1);
                    });
                }
                let result = [];
                $.each(emails, function(i, v) {
                    frappe.db.insert({
                        doctype: 'Email Group Member',
                        email_group: doc.email_group,
                        email: v,
                    }).then(d => {
                        result.push(d);
                    });
                });
                
                // for debugging purpose only
                console.log(
                    'Total existing members: ' + data.length,
                    'Total filtered emails: ' + emails.length,
                    'Total inserted emails: ' + result.length
                );
            });
        });
    }
});

But it is working. let me check more

@Devershi_Vashistha Try the code above. If it works, please let me know so I can post the code without debugging data/functions.

And sorry about these mistakes. I thought that emails from Address doctype are unique.

@kid1194 There is a strange problem as when I just entered Mumbai in city and pressed apply filter once it showed this.
29
and it didn’t add any emails but when I pressed it again it showed this.


and added 4 emails but in reality there are only two address with city Mumbai.

@Devershi_Vashistha This shows an error in the console log. Can you expand the error and post a screenshot of it. I will check the structure of the code at the moment.

@kid1194 Yes