I’ve created a client script to easily attach files from the selected items.
Basically, it creates a “Get Item Attachments” button to the current document. It lists file extensions and file counts which are attached to the items. You can select file extensions. Then all the files with selected extensions are added to the current document.
Source: This client script will attach files from the items by types to the current document. · GitHub
function GetFileAttachments(frm, arrItemCode) {
//Get files which are added to given items
frappe.db.get_list("File", {
filters: [
['attached_to_name', 'in', arrItemCode],
['attached_to_doctype', '=', "Item"]
],
fields: ["file_name", "file_url", "folder"],
limit: 9999
}).then((data) => {
let arrFileExt = [];//File extensions
let arrFileExtInfo = [];//json
let strFileExt = "";
let jsonFileInfo = {
file_ext: [],
file_count: []
}
let dIndex = -1;//File index search
for(let i=0; i<data.length; i++) {
strFileExt = data[i].file_name.substring(data[i].file_name.lastIndexOf(".")+1);
if(arrFileExt.indexOf(strFileExt) === -1) {
arrFileExt.push(strFileExt);
arrFileExtInfo.push({'file_ext': strFileExt});
jsonFileInfo.file_ext.push(strFileExt);
jsonFileInfo.file_count.push(1);
} else {
dIndex = jsonFileInfo.file_ext.indexOf(strFileExt);
jsonFileInfo.file_count[dIndex] = jsonFileInfo.file_count[dIndex] + 1;
}
}
for(let i=0; i<arrFileExtInfo.length; i++) {
strFileExt = arrFileExtInfo[i].file_ext;
dIndex = jsonFileInfo.file_ext.indexOf(strFileExt);
arrFileExtInfo[i].file_count = jsonFileInfo.file_count[dIndex];
}
const fields = [
{
label: 'Files',
fieldtype: 'Table',
fieldname: 'files',
description: __('Select File Types'),
fields: [
{
fieldtype: 'Data',
fieldname: 'file_ext',
options: '',
reqd: 0,
readonly: 1,
label: __('File Type'),
in_list_view: 1
},
{
fieldtype: 'Int',
fieldname: 'file_count',
options: '',
reqd: 0,
readonly: 1,
label: __('File Count'),
in_list_view: 1
}
],
data: arrFileExtInfo,
get_data: () => {
return r.message//ERR
}
}]
var d = new frappe.ui.Dialog({
title: __('Select File Types'),
fields: fields,
primary_action: function(dataTable) {
let arrPromFile = [];
for(let i=0; i<d.fields_dict.files.df.data.length; i++) {//Her dosya turu icin
strFileExt = d.fields_dict.files.df.data[i].file_ext;
//Does the file type is selected?
if (typeof d.fields_dict.files.df.data[i].__checked !== 'undefined') {
if (d.fields_dict.files.df.data[i].__checked === 1) {
//Select the files which have the same extension
for(let j=0; j<data.length; j++) {//For each file
if (strFileExt == data[j].file_name.substring(data[j].file_name.lastIndexOf(".")+1)) {
//Extensions match
const docFile = frappe.model.get_new_doc('File');
docFile.file_name = data[j].file_name;
docFile.attached_to_doctype = frm.doctype;
docFile.attached_to_name = frm.docname;
docFile.file_url = data[j].file_url;
docFile.folder = data[j].folder;
arrPromFile.push(frappe.db.insert(docFile));
}
}
}
}
}//File operations are completed.
d.hide();
Promise.all(arrPromFile).then((result) => {
frm.reload_doc();
})
},
primary_action_label: __('Attach Files')
});
d.show();
});
}
frappe.ui.form.on('Request for Quotation', {
refresh(frm) {
frm.add_custom_button(__('Get Item Attachments'), function(){
let arrItemCode = [];
$.each(frm.doc.items, function(i, d) {
arrItemCode.push(d.item_code);
});
GetFileAttachments(frm, arrItemCode);
});
}
});
PS: To make it work on document types other than the “Request for Quotation” you need to change line 105 to needed document type. Like “Purchase Order”.