mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-31 23:33:43 +00:00
feat: add side-by-side defaults comparison view in item defaults grid (#55017)
* feat: add side-by-side defaults comparison view in item defaults grid * fix: coderabbit suggested changes * fix: change label of the fields * fix: description design
This commit is contained in:
@@ -101,3 +101,139 @@ frappe.ui.form.on("Item Group", {
|
|||||||
|
|
||||||
page_name: frappe.utils.warn_page_name_change,
|
page_name: frappe.utils.warn_page_name_change,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on("Item Default", {
|
||||||
|
form_render: function (frm, cdt, cdn) {
|
||||||
|
if (!frm.fields_dict["item_group_defaults"]) return;
|
||||||
|
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
if (!row || !row.company) {
|
||||||
|
Object.values(COMPANY_DEFAULTS_TO_VF).forEach((vf) => frappe.model.set_value(cdt, cdn, vf, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const $grid_row = frm.fields_dict["item_group_defaults"].grid.wrapper.find(
|
||||||
|
`.grid-row[data-name="${cdn}"]`
|
||||||
|
);
|
||||||
|
$grid_row.find(".column-label").eq(1).text(__("Item Group Override"));
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
const $grid_row = frm.fields_dict["item_group_defaults"].grid.wrapper.find(
|
||||||
|
`.grid-row[data-name="${cdn}"]`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$grid_row.find(".item-defaults-desc").length) {
|
||||||
|
$grid_row.find(".grid-form-body").prepend(`
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<div class="item-defaults-desc" style="
|
||||||
|
background: var(--control-bg);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
padding: 6px 6px 8px 14px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
">
|
||||||
|
${__(
|
||||||
|
"Left column shows system-level defaults (Company / Stock Settings). Right column is where you set overrides for this item group."
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
populate_item_group_company_defaults(frm, cdt, cdn, row);
|
||||||
|
},
|
||||||
|
|
||||||
|
company: function (frm, cdt, cdn) {
|
||||||
|
if (!frm.fields_dict["item_group_defaults"]) return;
|
||||||
|
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
if (!row || !row.company) {
|
||||||
|
Object.values(COMPANY_DEFAULTS_TO_VF).forEach((vf) => frappe.model.set_value(cdt, cdn, vf, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
populate_item_group_company_defaults(frm, cdt, cdn, row);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const COMPANY_DEFAULTS_TO_VF = {
|
||||||
|
default_warehouse: "vf_default_warehouse",
|
||||||
|
default_inventory_account: "vf_default_inventory_account",
|
||||||
|
buying_cost_center: "vf_buying_cost_center",
|
||||||
|
selling_cost_center: "vf_selling_cost_center",
|
||||||
|
expense_account: "vf_expense_account",
|
||||||
|
income_account: "vf_income_account",
|
||||||
|
default_provisional_account: "vf_default_provisional_account",
|
||||||
|
purchase_expense_account: "vf_purchase_expense_account",
|
||||||
|
default_cogs_account: "vf_default_cogs_account",
|
||||||
|
deferred_expense_account: "vf_deferred_expense_account",
|
||||||
|
deferred_revenue_account: "vf_deferred_revenue_account",
|
||||||
|
default_price_list: "vf_default_price_list",
|
||||||
|
default_discount_account: "vf_default_discount_account",
|
||||||
|
default_supplier: "vf_default_supplier",
|
||||||
|
purchase_expense_contra_account: "vf_purchase_expense_contra_account",
|
||||||
|
};
|
||||||
|
|
||||||
|
const FIELD_DEFAULT_SOURCE = {
|
||||||
|
default_warehouse: "Stock Settings",
|
||||||
|
default_inventory_account: "Company",
|
||||||
|
buying_cost_center: "Company",
|
||||||
|
selling_cost_center: "Company",
|
||||||
|
expense_account: "Company",
|
||||||
|
income_account: "Company",
|
||||||
|
default_provisional_account: "Company",
|
||||||
|
purchase_expense_account: "Company",
|
||||||
|
default_cogs_account: "Company",
|
||||||
|
deferred_expense_account: "Company",
|
||||||
|
deferred_revenue_account: "Company",
|
||||||
|
default_price_list: null,
|
||||||
|
default_discount_account: "Company",
|
||||||
|
default_supplier: null,
|
||||||
|
purchase_expense_contra_account: "Company",
|
||||||
|
};
|
||||||
|
|
||||||
|
function populate_item_group_company_defaults(frm, cdt, cdn, row) {
|
||||||
|
const company = row.company;
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.setup.doctype.item_group.item_group.get_company_resolved_defaults",
|
||||||
|
args: { company: company },
|
||||||
|
freeze: false,
|
||||||
|
callback: function (r) {
|
||||||
|
if (!r.message) return;
|
||||||
|
|
||||||
|
const current_row = locals[cdt][cdn];
|
||||||
|
if (!current_row || current_row.company !== company) return;
|
||||||
|
|
||||||
|
const defaults = r.message;
|
||||||
|
|
||||||
|
Object.entries(COMPANY_DEFAULTS_TO_VF).forEach(([key, vf_field]) => {
|
||||||
|
frappe.model.set_value(cdt, cdn, vf_field, defaults[key] || "—");
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => update_item_group_vf_labels(frm, cdn, defaults), 50);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_item_group_vf_labels(frm, cdn, defaults) {
|
||||||
|
const $grid_row = frm.fields_dict["item_group_defaults"].grid.wrapper.find(
|
||||||
|
`.grid-row[data-name="${cdn}"]`
|
||||||
|
);
|
||||||
|
if (!$grid_row.length) return;
|
||||||
|
|
||||||
|
Object.entries(COMPANY_DEFAULTS_TO_VF).forEach(([key, vf_field]) => {
|
||||||
|
const $label = $grid_row.find(`[data-fieldname="${vf_field}"]`).find(".control-label, label").first();
|
||||||
|
if (!$label.length) return;
|
||||||
|
|
||||||
|
if (!$label.data("base-label")) {
|
||||||
|
$label.data("base-label", $label.text().trim());
|
||||||
|
}
|
||||||
|
const base = $label.data("base-label");
|
||||||
|
|
||||||
|
const source = FIELD_DEFAULT_SOURCE[key];
|
||||||
|
$label.text(source ? `${base} (${__(source)})` : base);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -94,3 +94,36 @@ def get_item_group_defaults(item, company):
|
|||||||
return row
|
return row
|
||||||
|
|
||||||
return frappe._dict()
|
return frappe._dict()
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_company_resolved_defaults(company: str) -> dict:
|
||||||
|
"""
|
||||||
|
Returns effective default values for a company by checking:
|
||||||
|
1. Company document
|
||||||
|
2. Stock Settings (for warehouse fallback)
|
||||||
|
3. Accounts Settings (for deferred account fallbacks)
|
||||||
|
"""
|
||||||
|
if not company:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
company_doc = frappe.get_cached_doc("Company", company)
|
||||||
|
default_warehouse = frappe.db.get_single_value("Stock Settings", "default_warehouse")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"default_warehouse": default_warehouse,
|
||||||
|
"default_inventory_account": company_doc.get("default_inventory_account"),
|
||||||
|
"buying_cost_center": company_doc.get("cost_center"),
|
||||||
|
"selling_cost_center": company_doc.get("cost_center"),
|
||||||
|
"expense_account": company_doc.get("default_expense_account"),
|
||||||
|
"income_account": company_doc.get("default_income_account"),
|
||||||
|
"default_provisional_account": company_doc.get("default_provisional_account"),
|
||||||
|
"purchase_expense_account": company_doc.get("purchase_expense_account"),
|
||||||
|
"default_cogs_account": company_doc.get("default_expense_account"),
|
||||||
|
"deferred_expense_account": company_doc.get("default_deferred_expense_account"),
|
||||||
|
"deferred_revenue_account": company_doc.get("default_deferred_revenue_account"),
|
||||||
|
"default_discount_account": company_doc.get("default_discount_account"),
|
||||||
|
"purchase_expense_contra_account": company_doc.get("purchase_expense_contra_account"),
|
||||||
|
"default_price_list": "",
|
||||||
|
"default_supplier": "",
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,24 @@ frappe.provide("erpnext.item");
|
|||||||
const SALES_DOCTYPES = ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"];
|
const SALES_DOCTYPES = ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"];
|
||||||
const PURCHASE_DOCTYPES = ["Purchase Order", "Purchase Receipt", "Purchase Invoice"];
|
const PURCHASE_DOCTYPES = ["Purchase Order", "Purchase Receipt", "Purchase Invoice"];
|
||||||
|
|
||||||
|
const virtual_field_map = {
|
||||||
|
default_warehouse: "vf_default_warehouse",
|
||||||
|
default_price_list: "vf_default_price_list",
|
||||||
|
default_discount_account: "vf_default_discount_account",
|
||||||
|
default_inventory_account: "vf_default_inventory_account",
|
||||||
|
buying_cost_center: "vf_buying_cost_center",
|
||||||
|
default_supplier: "vf_default_supplier",
|
||||||
|
expense_account: "vf_expense_account",
|
||||||
|
default_provisional_account: "vf_default_provisional_account",
|
||||||
|
purchase_expense_account: "vf_purchase_expense_account",
|
||||||
|
purchase_expense_contra_account: "vf_purchase_expense_contra_account",
|
||||||
|
selling_cost_center: "vf_selling_cost_center",
|
||||||
|
income_account: "vf_income_account",
|
||||||
|
default_cogs_account: "vf_default_cogs_account",
|
||||||
|
deferred_expense_account: "vf_deferred_expense_account",
|
||||||
|
deferred_revenue_account: "vf_deferred_revenue_account",
|
||||||
|
};
|
||||||
|
|
||||||
frappe.ui.form.on("Item", {
|
frappe.ui.form.on("Item", {
|
||||||
valuation_method(frm) {
|
valuation_method(frm) {
|
||||||
if (!frm.is_new() && frm.doc.valuation_method === "Moving Average") {
|
if (!frm.is_new() && frm.doc.valuation_method === "Moving Average") {
|
||||||
@@ -346,6 +364,53 @@ frappe.ui.form.on("Item", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on("Item Default", {
|
||||||
|
form_render: function (frm, cdt, cdn) {
|
||||||
|
if (!frm.fields_dict["item_defaults"]) return;
|
||||||
|
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
if (!row || !row.company) {
|
||||||
|
Object.values(virtual_field_map).forEach((vf) => frappe.model.set_value(cdt, cdn, vf, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $grid_row = frm.fields_dict["item_defaults"].grid.wrapper.find(`.grid-row[data-name="${cdn}"]`);
|
||||||
|
|
||||||
|
if (!$grid_row.find(".item-defaults-desc").length) {
|
||||||
|
$grid_row.find(".grid-form-body").prepend(`
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<div class="item-defaults-desc" style="
|
||||||
|
background: var(--control-bg);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
padding: 6px 6px 8px 14px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
|
||||||
|
">
|
||||||
|
${__(
|
||||||
|
"Left column shows inherited defaults (Item Group → Company / Stock Settings). Right column is where you set overrides for this item only."
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.item.populate_virtual_fields(frm, cdt, cdn, row);
|
||||||
|
},
|
||||||
|
|
||||||
|
company: function (frm, cdt, cdn) {
|
||||||
|
if (!frm.fields_dict["item_defaults"]) return;
|
||||||
|
|
||||||
|
const row = locals[cdt][cdn];
|
||||||
|
if (!row || !row.company) {
|
||||||
|
Object.values(virtual_field_map).forEach((vf) => frappe.model.set_value(cdt, cdn, vf, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
erpnext.item.populate_virtual_fields(frm, cdt, cdn, row);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
frappe.ui.form.on("Item Reorder", {
|
frappe.ui.form.on("Item Reorder", {
|
||||||
reorder_levels_add: function (frm, cdt, cdn) {
|
reorder_levels_add: function (frm, cdt, cdn) {
|
||||||
var row = frappe.get_doc(cdt, cdn);
|
var row = frappe.get_doc(cdt, cdn);
|
||||||
@@ -449,6 +514,93 @@ function render_serial_batch_banner(wrapper) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$.extend(erpnext.item, {
|
$.extend(erpnext.item, {
|
||||||
|
populate_virtual_fields: function (frm, cdt, cdn, row) {
|
||||||
|
if (!frm.doc.item_group || !row.company) {
|
||||||
|
Object.values(virtual_field_map).forEach((vf) => frappe.model.set_value(cdt, cdn, vf, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const company = row.company;
|
||||||
|
const item_group = frm.doc.item_group;
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "frappe.client.get",
|
||||||
|
args: { doctype: "Item Group", name: frm.doc.item_group },
|
||||||
|
freeze: false,
|
||||||
|
callback: function (r) {
|
||||||
|
if (!r.message) return;
|
||||||
|
|
||||||
|
const current_row = locals[cdt][cdn];
|
||||||
|
if (!current_row || current_row.company !== company || frm.doc.item_group !== item_group)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const group_defaults =
|
||||||
|
(r.message.item_group_defaults || []).find((d) => d.company === company) || {};
|
||||||
|
|
||||||
|
// Set Item Group values immediately; collect fields that need company fallback
|
||||||
|
const needs_company_fallback = [];
|
||||||
|
Object.entries(virtual_field_map).forEach(([real_field, vf_field]) => {
|
||||||
|
if (group_defaults[real_field]) {
|
||||||
|
frappe.model.set_value(cdt, cdn, vf_field, group_defaults[real_field]);
|
||||||
|
} else {
|
||||||
|
frappe.model.set_value(cdt, cdn, vf_field, "");
|
||||||
|
needs_company_fallback.push(real_field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!needs_company_fallback.length) {
|
||||||
|
setTimeout(() => erpnext.item.update_vf_labels(frm, cdn, {}), 50);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.setup.doctype.item_group.item_group.get_company_resolved_defaults",
|
||||||
|
args: { company: company },
|
||||||
|
freeze: false,
|
||||||
|
callback: function (cr) {
|
||||||
|
const current_row = locals[cdt][cdn];
|
||||||
|
if (
|
||||||
|
!current_row ||
|
||||||
|
current_row.company !== company ||
|
||||||
|
frm.doc.item_group !== item_group
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const company_defaults = cr.message || {};
|
||||||
|
const from_company = {};
|
||||||
|
|
||||||
|
needs_company_fallback.forEach((real_field) => {
|
||||||
|
const val = company_defaults[real_field] || "";
|
||||||
|
if (val) from_company[real_field] = val;
|
||||||
|
frappe.model.set_value(cdt, cdn, virtual_field_map[real_field], val || "—");
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => erpnext.item.update_vf_labels(frm, cdn, from_company), 50);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
update_vf_labels: function (frm, cdn, from_company) {
|
||||||
|
const $grid_row = frm.fields_dict["item_defaults"].grid.wrapper.find(`.grid-row[data-name="${cdn}"]`);
|
||||||
|
if (!$grid_row.length) return;
|
||||||
|
|
||||||
|
Object.entries(virtual_field_map).forEach(([real_field, vf_field]) => {
|
||||||
|
const $label = $grid_row
|
||||||
|
.find(`[data-fieldname="${vf_field}"]`)
|
||||||
|
.find(".control-label, label")
|
||||||
|
.first();
|
||||||
|
if (!$label.length) return;
|
||||||
|
|
||||||
|
if (!$label.data("base-label")) {
|
||||||
|
$label.data("base-label", $label.text().trim());
|
||||||
|
}
|
||||||
|
const base = $label.data("base-label");
|
||||||
|
|
||||||
|
$label.text(from_company[real_field] ? `${base} (Company)` : `${base} (Item Group)`);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
setup_queries: function (frm) {
|
setup_queries: function (frm) {
|
||||||
frm.fields_dict["item_defaults"].grid.get_field("expense_account").get_query = function (
|
frm.fields_dict["item_defaults"].grid.get_field("expense_account").get_query = function (
|
||||||
doc,
|
doc,
|
||||||
|
|||||||
@@ -5,34 +5,60 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
|
"company_section",
|
||||||
"company",
|
"company",
|
||||||
|
"from_section",
|
||||||
|
"column_break_general",
|
||||||
|
"vf_default_warehouse",
|
||||||
|
"vf_default_price_list",
|
||||||
|
"vf_default_discount_account",
|
||||||
|
"vf_default_inventory_account",
|
||||||
|
"column_break_njfg",
|
||||||
"default_warehouse",
|
"default_warehouse",
|
||||||
"column_break_3",
|
|
||||||
"default_price_list",
|
"default_price_list",
|
||||||
"default_discount_account",
|
"default_discount_account",
|
||||||
"default_inventory_account",
|
"default_inventory_account",
|
||||||
"inventory_account_currency",
|
"inventory_account_currency",
|
||||||
"purchase_defaults",
|
"purchase_defaults",
|
||||||
|
"column_break_purchase",
|
||||||
|
"vf_buying_cost_center",
|
||||||
|
"vf_default_supplier",
|
||||||
|
"vf_expense_account",
|
||||||
|
"vf_default_provisional_account",
|
||||||
|
"vf_purchase_expense_account",
|
||||||
|
"vf_purchase_expense_contra_account",
|
||||||
|
"column_break_ghzl",
|
||||||
"buying_cost_center",
|
"buying_cost_center",
|
||||||
"default_supplier",
|
"default_supplier",
|
||||||
"column_break_8",
|
|
||||||
"expense_account",
|
"expense_account",
|
||||||
"default_provisional_account",
|
"default_provisional_account",
|
||||||
"column_break_cpif",
|
|
||||||
"purchase_expense_account",
|
"purchase_expense_account",
|
||||||
"purchase_expense_contra_account",
|
"purchase_expense_contra_account",
|
||||||
"selling_defaults",
|
"selling_defaults",
|
||||||
|
"column_break_sales",
|
||||||
|
"vf_selling_cost_center",
|
||||||
|
"vf_income_account",
|
||||||
|
"column_break_ilsl",
|
||||||
"selling_cost_center",
|
"selling_cost_center",
|
||||||
"column_break_12",
|
|
||||||
"income_account",
|
"income_account",
|
||||||
"cost_of_good_sold_section",
|
"cost_of_good_sold_section",
|
||||||
|
"column_break_cogs",
|
||||||
|
"vf_default_cogs_account",
|
||||||
|
"column_break_vnkl",
|
||||||
"default_cogs_account",
|
"default_cogs_account",
|
||||||
"deferred_accounting_defaults_section",
|
"deferred_accounting_defaults_section",
|
||||||
|
"column_break_deferred",
|
||||||
|
"vf_deferred_expense_account",
|
||||||
|
"vf_deferred_revenue_account",
|
||||||
|
"column_break_okiu",
|
||||||
"deferred_expense_account",
|
"deferred_expense_account",
|
||||||
"column_break_kwad",
|
|
||||||
"deferred_revenue_account"
|
"deferred_revenue_account"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "company_section",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -46,157 +72,30 @@
|
|||||||
"fieldname": "default_warehouse",
|
"fieldname": "default_warehouse",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Default Warehouse",
|
"label": "Warehouse",
|
||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "column_break_3",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": "Default price list for buying or selling this item",
|
"description": "Default price list for buying or selling this item",
|
||||||
"fieldname": "default_price_list",
|
"fieldname": "default_price_list",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Default Price List",
|
"label": "Price List",
|
||||||
"options": "Price List",
|
"options": "Price List",
|
||||||
"show_description_on_click": 1
|
"show_description_on_click": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "purchase_defaults",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Purchase Defaults"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Cost center used for tracking purchase expenses for this item",
|
|
||||||
"fieldname": "buying_cost_center",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default Buying Cost Center",
|
|
||||||
"options": "Cost Center",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "This supplier will be auto-selected in new purchase transactions",
|
|
||||||
"fieldname": "default_supplier",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default Supplier",
|
|
||||||
"options": "Supplier"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_8",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Account where the cost of this item will be debited on purchase",
|
|
||||||
"fieldname": "expense_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default Expense Account",
|
|
||||||
"options": "Account",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "selling_defaults",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Sales Defaults"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Cost center used for tracking sales revenue for this item",
|
|
||||||
"fieldname": "selling_cost_center",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default Selling Cost Center",
|
|
||||||
"options": "Cost Center",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_12",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Account where revenue from selling this item will be credited",
|
|
||||||
"fieldname": "income_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default Income Account",
|
|
||||||
"options": "Account",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "default_discount_account",
|
"fieldname": "default_discount_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default Discount Account",
|
"label": "Discount Account",
|
||||||
"options": "Account"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Provisional liability account used for service items before invoice is received",
|
|
||||||
"fieldname": "default_provisional_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default Provisional Account (Service)",
|
|
||||||
"options": "Account"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "deferred_accounting_defaults_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Deferred Accounting Defaults"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval: parent.enable_deferred_expense",
|
|
||||||
"description": "When you pay for something upfront (like annual insurance), the cost is held here and recognized gradually over time",
|
|
||||||
"fieldname": "deferred_expense_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Deferred Expense Account",
|
|
||||||
"options": "Account",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval: parent.enable_deferred_revenue",
|
|
||||||
"description": "Revenue received in advance (e.g. annual subscription) is held here and recognized gradually over time",
|
|
||||||
"fieldname": "deferred_revenue_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Deferred Revenue Account",
|
|
||||||
"options": "Account",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_kwad",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_cpif",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "cost_of_good_sold_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Cost of Goods Sold"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Account where cost of goods sold will be posted when this item is sold",
|
|
||||||
"fieldname": "default_cogs_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Default COGS Account",
|
|
||||||
"options": "Account",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Account to record additional purchase expenses like freight or customs for this item",
|
|
||||||
"fieldname": "purchase_expense_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Purchase Expense Account",
|
|
||||||
"options": "Account",
|
|
||||||
"show_description_on_click": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Used to balance the books when recording extra purchase costs like freight or customs",
|
|
||||||
"fieldname": "purchase_expense_contra_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Purchase Expense Contra Account",
|
|
||||||
"options": "Account"
|
"options": "Account"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Stock account where inventory value for this item will be tracked",
|
"description": "Stock account where inventory value for this item will be tracked",
|
||||||
"fieldname": "default_inventory_account",
|
"fieldname": "default_inventory_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Default Inventory Account",
|
"label": "Inventory Account",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"show_description_on_click": 1
|
"show_description_on_click": 1
|
||||||
},
|
},
|
||||||
@@ -207,11 +106,257 @@
|
|||||||
"label": "Inventory Account Currency",
|
"label": "Inventory Account Currency",
|
||||||
"options": "Currency",
|
"options": "Currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_general",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"label": "Inherited Default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_warehouse",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_price_list",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Price List"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_discount_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Discount Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_inventory_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Inventory Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "purchase_defaults",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Purchase Defaults"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Cost center used for tracking purchase expenses for this item",
|
||||||
|
"fieldname": "buying_cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Buying Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "This supplier will be auto-selected in new purchase transactions",
|
||||||
|
"fieldname": "default_supplier",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Supplier",
|
||||||
|
"options": "Supplier",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Account where the cost of this item will be debited on purchase",
|
||||||
|
"fieldname": "expense_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Expense Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Provisional liability account used for service items before invoice is received",
|
||||||
|
"fieldname": "default_provisional_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Provisional Account (Service)",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Account to record additional purchase expenses like freight or customs",
|
||||||
|
"fieldname": "purchase_expense_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Purchase Expense Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Used to balance the books when recording extra purchase costs",
|
||||||
|
"fieldname": "purchase_expense_contra_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Purchase Expense Contra Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_purchase",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_buying_cost_center",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Buying Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_supplier",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Supplier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_expense_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Expense Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_provisional_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Provisional Account (Service)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_purchase_expense_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Purchase Expense Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_purchase_expense_contra_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Purchase Expense Contra Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "selling_defaults",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Sales Defaults"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Cost center used for tracking sales revenue for this item",
|
||||||
|
"fieldname": "selling_cost_center",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Selling Cost Center",
|
||||||
|
"options": "Cost Center",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Account where revenue from selling this item will be credited",
|
||||||
|
"fieldname": "income_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Income Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_sales",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_selling_cost_center",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Selling Cost Center"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_income_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Income Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "cost_of_good_sold_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Cost of Goods Sold"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Account where cost of goods sold will be posted when this item is sold",
|
||||||
|
"fieldname": "default_cogs_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "COGS Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_cogs",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "vf_default_cogs_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "COGS Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "deferred_accounting_defaults_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Deferred Accounting Defaults"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: parent.enable_deferred_expense",
|
||||||
|
"fieldname": "deferred_expense_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Expense Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: parent.enable_deferred_revenue",
|
||||||
|
"fieldname": "deferred_revenue_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Revenue Account",
|
||||||
|
"options": "Account",
|
||||||
|
"show_description_on_click": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_deferred",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: parent.enable_deferred_expense",
|
||||||
|
"fieldname": "vf_deferred_expense_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Deferred Expense Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval: parent.enable_deferred_revenue",
|
||||||
|
"fieldname": "vf_deferred_revenue_account",
|
||||||
|
"fieldtype": "Read Only",
|
||||||
|
"is_virtual": 1,
|
||||||
|
"label": "Deferred Revenue Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_njfg",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"label": "Item Override"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_ghzl",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_ilsl",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_vnkl",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_okiu",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "from_section",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2026-04-27 01:49:01.396845",
|
"modified": "2026-06-03 17:25:35.982082",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Default",
|
"name": "Item Default",
|
||||||
|
|||||||
Reference in New Issue
Block a user