Quickly Upload attachement in List View for Payment Entry in Frappe/ERPNext

I’m sharing a custom script we’have implement for “Payment Entry” doctype, that adds an “Attachments” button directly in the list view. Click on button to open a dialog showing all existing attachments for the selected document, if need to upload additional attachment then click on the “Upload File” button on opened dialog to allow quick uploads.

Additionaly: Also highlight the button with “btn-success” if attachment already exist to idintify the document contain attachment

  • Client Script
  • Doctype: Payment Entry
  • Apply to: List
// payment_entry_list.js
frappe.listview_settings['Payment Entry'] = {
    hide_name_column: true,
    add_fields: ["name"],

    button: {
        show: function(doc) {
            return true;
        },
        get_label: function(doc) {
            return '<svg class="icon icon-sm"><use href="#icon-attachment"></use></svg> Attachments';
        },
        get_description: function(doc) {
            return __("Add/Edit Attachment for " + doc.name);
        },
        action: function(doc) {
            frappe.db.get_list('File', {
                fields: ['file_name', 'file_type', 'attached_to_doctype', 'attached_to_name'],
                filters: {
                    attached_to_doctype: "Payment Entry",
                    attached_to_name: doc.name
                },
                limit: null
            }).then(function(attachments) {
                let d = new frappe.ui.Dialog({
                    title: doc.name + ': Attachments',
                    fields: [
                        {
                            label: 'Existing Attachments',
                            fieldname: 'attachment_table',
                            fieldtype: 'Table',
                            cannot_add_rows: 1,
                            cannot_delete_rows: 1,
                            in_place_edit: 1,
                            fields: [
                                { label: 'Name', fieldname: 'name', fieldtype: 'Data', hidden: 1 },
                                { label: 'Attachment Name', fieldname: 'file_name', fieldtype: 'Data', read_only: 1, in_list_view: 1 },
                                { label: 'File Type', fieldname: 'file_type', fieldtype: 'Data', read_only: 1, in_list_view: 1 }
                            ],
                            data: attachments
                        },
                        {
                            fieldname: 'upload_button_html',
                            fieldtype: 'HTML'
                        }
                    ],
                    size: 'large',
                    primary_action_label: 'Close',
                    primary_action() {
                        d.hide();
                    }
                });

                d.show();

                // Upload File button inside dialog
                const $btn = $(`<button class="btn btn-primary"><i class="fa fa-upload"></i> Upload File</button>`);
                $btn.on('click', function () {
                    const uploader = new frappe.ui.FileUploader({
                        allow_multiple: false,
                        upload_notes: __('Attach a file to {0}', [doc.name]),
                        doctype: "Payment Entry",
                        docname: doc.name,
                        folder: "Home/Attachments",
                        on_success(file_doc) {
                            frappe.show_alert({ message: __('File Uploaded'), indicator: 'green' });
                            d.hide();
                            frappe.set_route("Form", "Payment Entry", doc.name);
                        }
                    });
                    uploader.show();
                });

                d.fields_dict.upload_button_html.$wrapper.empty().append($btn);
            });
        }
    },

    refresh: function(listview) {
        // Change button color if attachments exist
        listview.data.forEach(function(doc, idx) {
            frappe.db.count('File', {
                filters: {
                    attached_to_doctype: "Payment Entry",
                    attached_to_name: doc.name
                }
            }).then(function(count) {
                const $btn = listview.$page.find(`.btn[data-idx="${idx}"]`);
                if ($btn.length && count > 0) {
                    $btn.addClass("btn-success").removeClass("btn-default btn-info");
                }
            });
        });
    }
};

3 Likes