frappe.provide('frappe.ui.form'); frappe.ui.form.ItemQuickEntryForm = class ItemQuickEntryForm extends frappe.ui.form.QuickEntryForm { constructor(doctype, after_insert) { super(doctype, after_insert); } render_dialog() { this.mandatory = this.get_variant_fields().concat(this.mandatory); this.mandatory = this.mandatory.concat(this.get_attributes_fields()); this.check_naming_series_based_on(); super.render_dialog(); this.init_post_render_dialog_operations(); this.preset_fields_for_template(); this.dialog.$wrapper.find('.edit-full').text(__('Edit in full page for more options like assets, serial nos, batches etc.')) } check_naming_series_based_on() { if (frappe.defaults.get_default("item_naming_by") === "Naming Series") { this.mandatory = this.mandatory.filter(d => d.fieldname !== "item_code"); } } init_post_render_dialog_operations() { this.dialog.fields_dict.attribute_html.$wrapper.append(frappe.render_template("item_quick_entry")); this.init_for_create_variant_trigger(); this.init_for_item_template_trigger(); // explicitly hide manufacturing fields as hidden not working. this.toggle_manufacturer_fields(); this.dialog.get_field("item_template").df.hidden = 1; this.dialog.get_field("item_template").refresh(); } register_primary_action() { var me = this; this.dialog.set_primary_action(__('Save'), function() { if (me.dialog.working) return; var data = me.dialog.get_values(); var variant_values = {}; if (me.dialog.fields_dict.create_variant.$input.prop("checked")) { variant_values = me.get_variant_doc(); if (!Object.keys(variant_values).length) { data = null; } variant_values.stock_uom = me.template_doc.stock_uom; variant_values.item_group = me.template_doc.item_group; } if (data) { me.dialog.working = true; var values = me.update_doc(); //patch for manufacturer type variants as extend is overwriting it. if (variant_values['variant_based_on'] == "Manufacturer") { values['variant_based_on'] = "Manufacturer"; } $.extend(variant_values, values); me.insert(variant_values); } }); } insert(variant_values) { let me = this; return new Promise(resolve => { frappe.call({ method: "frappe.client.insert", args: { doc: variant_values }, callback: function(r) { me.dialog.hide(); // delete the old doc frappe.model.clear_doc(me.dialog.doc.doctype, me.dialog.doc.name); me.dialog.doc = r.message; if (frappe._from_link) { frappe.ui.form.update_calling_link(me.dialog.doc); } else { if (me.after_insert) { me.after_insert(me.dialog.doc); } else { me.open_form_if_not_list(); } } }, error: function() { me.open_doc(); }, always: function() { me.dialog.working = false; resolve(me.dialog.doc); }, freeze: true }); }); } open_doc() { this.dialog.hide(); this.update_doc(); if (this.dialog.fields_dict.create_variant.$input.prop("checked")) { var template = this.dialog.fields_dict.item_template.input.value; if (template) frappe.set_route("Form", this.doctype, template); } else { frappe.set_route('Form', this.doctype, this.doc.name); } } get_variant_fields() { var variant_fields = [{ fieldname: "create_variant", fieldtype: "Check", label: __("Create Variant") }, { fieldname: 'item_template', label: __('Item Template'), reqd: 0, fieldtype: 'Link', options: "Item", get_query: function() { return { filters: { "has_variants": 1 } }; } }]; return variant_fields; } get_manufacturing_fields() { this.manufacturer_fields = [{ fieldtype: 'Link', options: 'Manufacturer', label: 'Manufacturer', fieldname: "manufacturer", hidden: 1, reqd: 0 }, { fieldtype: 'Data', label: 'Manufacturer Part Number', fieldname: 'manufacturer_part_no', hidden: 1, reqd: 0 }]; return this.manufacturer_fields; } get_attributes_fields() { var attribute_fields = [{ fieldname: 'attribute_html', fieldtype: 'HTML' }] attribute_fields = attribute_fields.concat(this.get_manufacturing_fields()); return attribute_fields; } init_for_create_variant_trigger() { var me = this; this.dialog.fields_dict.create_variant.$input.on("click", function() { me.preset_fields_for_template(); me.init_post_template_trigger_operations(false, [], true); }); } preset_fields_for_template() { var for_variant = this.dialog.get_value('create_variant'); // setup template field, seen and mandatory if variant let template_field = this.dialog.get_field("item_template"); template_field.df.reqd = for_variant; template_field.set_value(''); template_field.df.hidden = !for_variant; template_field.refresh(); // hide properties for variant ['item_code', 'item_name', 'item_group', 'stock_uom'].forEach((d) => { let f = this.dialog.get_field(d); f.df.hidden = for_variant; f.refresh(); }); this.dialog.get_field('attribute_html').toggle(false); // non mandatory for variants ['item_code', 'stock_uom', 'item_group'].forEach((d) => { let f = this.dialog.get_field(d); f.df.reqd = !for_variant; f.refresh(); }); } init_for_item_template_trigger() { var me = this; me.dialog.fields_dict["item_template"].df.onchange = () => { var template = me.dialog.fields_dict.item_template.input.value; me.template_doc = null; if (template) { frappe.call({ method: "frappe.client.get", args: { doctype: "Item", name: template }, callback: function(r) { me.template_doc = r.message; me.is_manufacturer = false; if (me.template_doc.variant_based_on === "Manufacturer") { me.init_post_template_trigger_operations(true, [], true); } else { me.init_post_template_trigger_operations(false, me.template_doc.attributes, false); me.render_attributes(me.template_doc.attributes); } } }); } else { me.dialog.get_field('attribute_html').toggle(false); me.init_post_template_trigger_operations(false, [], true); } } } init_post_template_trigger_operations(is_manufacturer, attributes, attributes_flag) { this.attributes = attributes; this.attribute_values = {}; this.attributes_count = attributes.length; this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes").empty(); this.is_manufacturer = is_manufacturer; this.toggle_manufacturer_fields(); this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes").toggleClass("hide-control", attributes_flag); this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes-header").toggleClass("hide-control", attributes_flag); } toggle_manufacturer_fields() { var me = this; $.each(this.manufacturer_fields, function(i, dialog_field) { me.dialog.get_field(dialog_field.fieldname).df.hidden = !me.is_manufacturer; me.dialog.get_field(dialog_field.fieldname).df.reqd = dialog_field.fieldname == 'manufacturer' ? me.is_manufacturer : false; me.dialog.get_field(dialog_field.fieldname).refresh(); }); } initiate_render_attributes() { this.dialog.fields_dict.attribute_html.$wrapper.find(".attributes").empty(); this.render_attributes(this.attributes); } render_attributes(attributes) { var me = this; this.dialog.get_field('attribute_html').toggle(true); $.each(attributes, function(index, row) { var desc = ""; var fieldtype = "Data"; if (row.numeric_values) { fieldtype = "Float"; desc = "Min Value: " + row.from_range + " , Max Value: " + row.to_range + ", in Increments of: " + row.increment; } me.init_make_control(fieldtype, row); me[row.attribute].set_value(me.attribute_values[row.attribute] || ""); me[row.attribute].$wrapper.toggleClass("has-error", me.attribute_values[row.attribute] ? false : true); // Set Label explicitly as make_control is not displaying label $(me[row.attribute].label_area).text(__(row.attribute)); if (desc) { $(repl(`<p class="help-box small text-muted hidden-xs">%(desc)s</p>`, { "desc": desc })).insertAfter(me[row.attribute].input_area); } if (!row.numeric_values) { me.init_awesomplete_for_attribute(row); } else { me[row.attribute].$input.on("change", function() { me.attribute_values[row.attribute] = $(this).val(); $(this).closest(".frappe-control").toggleClass("has-error", $(this).val() ? false : true); }); } }); } init_make_control(fieldtype, row) { this[row.attribute] = frappe.ui.form.make_control({ df: { "fieldtype": fieldtype, "label": row.attribute, "fieldname": row.attribute, "options": row.options || "" }, parent: $(this.dialog.fields_dict.attribute_html.wrapper).find(".attributes"), only_input: false }); this[row.attribute].make_input(); } init_awesomplete_for_attribute(row) { var me = this; this[row.attribute].input.awesomplete = new Awesomplete(this[row.attribute].input, { minChars: 0, maxItems: 99, autoFirst: true, list: [], }); this[row.attribute].$input.on('input', function(e) { frappe.call({ method: "frappe.client.get_list", args: { doctype: "Item Attribute Value", filters: [ ["parent", "=", $(e.target).attr("data-fieldname")], ["attribute_value", "like", e.target.value + "%"] ], fields: ["attribute_value"], parent: "Item Attribute" }, callback: function(r) { if (r.message) { e.target.awesomplete.list = r.message.map(function(d) { return d.attribute_value; }); } } }); }).on('focus', function(e) { $(e.target).val('').trigger('input'); }).on("awesomplete-close", function (e) { me.attribute_values[$(e.target).attr("data-fieldname")] = e.target.value; $(e.target).closest(".frappe-control").toggleClass("has-error", e.target.value ? false : true); }); } get_variant_doc() { var me = this; var variant_doc = {}; var attribute = this.validate_mandatory_attributes(); if (Object.keys(attribute).length) { frappe.call({ method: "erpnext.controllers.item_variant.create_variant_doc_for_quick_entry", args: { "template": me.dialog.fields_dict.item_template.$input.val(), args: attribute }, async: false, callback: function(r) { if (Object.prototype.toString.call(r.message) == "[object Object]") { variant_doc = r.message; } else { var msgprint_dialog = frappe.msgprint(__("Item Variant {0} already exists with same attributes", [repl('<a class="strong variant-click" data-item-code="%(item)s" \ >%(item)s</a>', { item: r.message })])); msgprint_dialog.$wrapper.find(".variant-click").on("click", function() { msgprint_dialog.hide(); me.dialog.hide(); if (frappe._from_link) { frappe._from_link.set_value($(this).attr("data-item-code")); } else { frappe.set_route('Form', "Item", $(this).attr("data-item-code")); } }); } } }) } return variant_doc; } validate_mandatory_attributes() { var me = this; var attribute = {}; var mandatory = []; $.each(this.attributes, function(index, attr) { var value = me.attribute_values[attr.attribute] || ""; if (value) { attribute[attr.attribute] = attr.numeric_values ? flt(value) : value; } else { mandatory.push(attr.attribute); } }) if (this.is_manufacturer) { $.each(this.manufacturer_fields, function(index, field) { attribute[field.fieldname] = me.dialog.fields_dict[field.fieldname].input.value; }); } return attribute; } };