Merge remote-tracking branch 'frappe/develop' into wip-4.1
This commit is contained in:
commit
d1419edfd0
@ -1,226 +1,229 @@
|
||||
{
|
||||
"autoname": "GL.#######",
|
||||
"creation": "2013-01-10 16:34:06",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"autoname": "GL.#######",
|
||||
"creation": "2013-01-10 16:34:06",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Posting Date",
|
||||
"oldfieldname": "posting_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Posting Date",
|
||||
"oldfieldname": "posting_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "transaction_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Transaction Date",
|
||||
"oldfieldname": "transaction_date",
|
||||
"oldfieldtype": "Date",
|
||||
"fieldname": "transaction_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Transaction Date",
|
||||
"oldfieldname": "transaction_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "aging_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Aging Date",
|
||||
"oldfieldname": "aging_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"fieldname": "aging_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Aging Date",
|
||||
"oldfieldname": "aging_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Account",
|
||||
"oldfieldname": "account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Account",
|
||||
"oldfieldname": "account",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Cost Center",
|
||||
"oldfieldname": "cost_center",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "debit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Debit Amt",
|
||||
"oldfieldname": "debit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"fieldname": "debit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Debit Amt",
|
||||
"oldfieldname": "debit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "credit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Credit Amt",
|
||||
"oldfieldname": "credit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"fieldname": "credit",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Credit Amt",
|
||||
"oldfieldname": "credit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "against",
|
||||
"fieldtype": "Text",
|
||||
"in_filter": 1,
|
||||
"label": "Against",
|
||||
"oldfieldname": "against",
|
||||
"oldfieldtype": "Text",
|
||||
"fieldname": "against",
|
||||
"fieldtype": "Text",
|
||||
"in_filter": 1,
|
||||
"label": "Against",
|
||||
"oldfieldname": "against",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "against_voucher",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
"label": "Against Voucher",
|
||||
"oldfieldname": "against_voucher",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"fieldname": "against_voucher_type",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 0,
|
||||
"label": "Against Voucher Type",
|
||||
"oldfieldname": "against_voucher_type",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "against_voucher_type",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 0,
|
||||
"label": "Against Voucher Type",
|
||||
"oldfieldname": "against_voucher_type",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"fieldname": "against_voucher",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_filter": 1,
|
||||
"label": "Against Voucher",
|
||||
"oldfieldname": "against_voucher",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "against_voucher_type",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_type",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher Type",
|
||||
"oldfieldname": "voucher_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Journal Voucher\nSales Invoice\nPurchase Invoice\nPeriod Closing Voucher\nPurchase Receipt\nDelivery Note\nStock Entry\nStock Reconciliation",
|
||||
"permlevel": 0,
|
||||
"fieldname": "voucher_type",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher Type",
|
||||
"oldfieldname": "voucher_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_no",
|
||||
"fieldtype": "Data",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher No",
|
||||
"oldfieldname": "voucher_no",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"fieldname": "voucher_no",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher No",
|
||||
"oldfieldname": "voucher_no",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "voucher_type",
|
||||
"permlevel": 0,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "remarks",
|
||||
"fieldtype": "Text",
|
||||
"in_filter": 1,
|
||||
"label": "Remarks",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "remarks",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"fieldname": "remarks",
|
||||
"fieldtype": "Text",
|
||||
"in_filter": 1,
|
||||
"label": "Remarks",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "remarks",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "is_opening",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"label": "Is Opening",
|
||||
"oldfieldname": "is_opening",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0,
|
||||
"fieldname": "is_opening",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"label": "Is Opening",
|
||||
"oldfieldname": "is_opening",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "is_advance",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 0,
|
||||
"label": "Is Advance",
|
||||
"oldfieldname": "is_advance",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0,
|
||||
"fieldname": "is_advance",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 0,
|
||||
"label": "Is Advance",
|
||||
"oldfieldname": "is_advance",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "No\nYes",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Fiscal Year",
|
||||
"oldfieldname": "fiscal_year",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Fiscal Year",
|
||||
"permlevel": 0,
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Fiscal Year",
|
||||
"oldfieldname": "fiscal_year",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Fiscal Year",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-list",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-06-19 01:51:29.340077",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GL Entry",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-list",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-06-23 08:07:30.678730",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GL Entry",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"create": 0,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"search_fields": "voucher_no,account,posting_date,against_voucher",
|
||||
"sort_field": "modified",
|
||||
],
|
||||
"search_fields": "voucher_no,account,posting_date,against_voucher",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
}
|
@ -43,13 +43,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Period Closing Voucher",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
@ -101,7 +102,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-26 03:05:50.722547",
|
||||
"modified": "2014-06-23 07:55:49.946225",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Period Closing Voucher",
|
||||
|
@ -62,7 +62,7 @@
|
||||
"options": "Price List",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
@ -147,7 +147,7 @@
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
@ -205,7 +205,7 @@
|
||||
],
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"modified": "2014-05-27 03:49:14.735138",
|
||||
"modified": "2014-06-23 16:40:59.510132",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Setting",
|
||||
|
@ -61,4 +61,31 @@ frappe.ui.form.on("Pricing Rule", "refresh", function(frm) {
|
||||
'</table>'].join("\n");
|
||||
|
||||
set_field_options("pricing_rule_help", help_content);
|
||||
|
||||
cur_frm.cscript.set_options_for_applicable_for();
|
||||
});
|
||||
|
||||
cur_frm.cscript.set_options_for_applicable_for = function() {
|
||||
var options = [""];
|
||||
var applicable_for = cur_frm.doc.applicable_for;
|
||||
|
||||
if(cur_frm.doc.selling) {
|
||||
options = $.merge(options, ["Customer", "Customer Group", "Territory", "Sales Partner", "Campaign"]);
|
||||
}
|
||||
if(cur_frm.doc.buying) {
|
||||
$.merge(options, ["Supplier", "Supplier Type"]);
|
||||
}
|
||||
|
||||
set_field_options("applicable_for", options.join("\n"));
|
||||
|
||||
if(!in_list(options, applicable_for)) applicable_for = null;
|
||||
cur_frm.set_value("applicable_for", applicable_for)
|
||||
}
|
||||
|
||||
cur_frm.cscript.selling = function() {
|
||||
cur_frm.cscript.set_options_for_applicable_for();
|
||||
}
|
||||
|
||||
cur_frm.cscript.buying = function() {
|
||||
cur_frm.cscript.set_options_for_applicable_for();
|
||||
}
|
||||
|
@ -1,288 +1,299 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "PRULE.#####",
|
||||
"creation": "2014-02-21 15:02:51",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"allow_import": 1,
|
||||
"autoname": "PRULE.#####",
|
||||
"creation": "2014-02-21 15:02:51",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "applicability_section",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Applicability",
|
||||
"fieldname": "applicability_section",
|
||||
"fieldtype": "Section Break",
|
||||
"in_list_view": 0,
|
||||
"label": "Applicability",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Item Code",
|
||||
"fieldname": "apply_on",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Apply On",
|
||||
"options": "\nItem Code\nItem Group\nBrand",
|
||||
"permlevel": 0,
|
||||
"default": "Item Code",
|
||||
"fieldname": "apply_on",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Apply On",
|
||||
"options": "\nItem Code\nItem Group\nBrand",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.apply_on==\"Item Code\"",
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"depends_on": "eval:doc.apply_on==\"Item Code\"",
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.apply_on==\"Item Group\"",
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Group",
|
||||
"options": "Item Group",
|
||||
"depends_on": "eval:doc.apply_on==\"Item Group\"",
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Group",
|
||||
"options": "Item Group",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.apply_on==\"Brand\"",
|
||||
"fieldname": "brand",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Brand",
|
||||
"options": "Brand",
|
||||
"depends_on": "eval:doc.apply_on==\"Brand\"",
|
||||
"fieldname": "brand",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Brand",
|
||||
"options": "Brand",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "applicable_for",
|
||||
"fieldtype": "Select",
|
||||
"label": "Applicable For",
|
||||
"options": "\nCustomer\nCustomer Group\nTerritory\nSales Partner\nCampaign\nSupplier\nSupplier Type",
|
||||
"fieldname": "selling",
|
||||
"fieldtype": "Check",
|
||||
"label": "Selling",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Customer\"",
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer",
|
||||
"options": "Customer",
|
||||
"fieldname": "buying",
|
||||
"fieldtype": "Check",
|
||||
"label": "Buying",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Customer Group\"",
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer Group",
|
||||
"options": "Customer Group",
|
||||
"fieldname": "applicable_for",
|
||||
"fieldtype": "Select",
|
||||
"label": "Applicable For",
|
||||
"options": "\nCustomer\nCustomer Group\nTerritory\nSales Partner\nCampaign\nSupplier\nSupplier Type",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Territory\"",
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"label": "Territory",
|
||||
"options": "Territory",
|
||||
"depends_on": "eval:doc.applicable_for==\"Customer\"",
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer",
|
||||
"options": "Customer",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Sales Partner\"",
|
||||
"fieldname": "sales_partner",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Partner",
|
||||
"options": "Sales Partner",
|
||||
"depends_on": "eval:doc.applicable_for==\"Customer Group\"",
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Customer Group",
|
||||
"options": "Customer Group",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Campaign\"",
|
||||
"fieldname": "campaign",
|
||||
"fieldtype": "Link",
|
||||
"label": "Campaign",
|
||||
"options": "Campaign",
|
||||
"depends_on": "eval:doc.applicable_for==\"Territory\"",
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"label": "Territory",
|
||||
"options": "Territory",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Supplier\"",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supplier",
|
||||
"options": "Supplier",
|
||||
"depends_on": "eval:doc.applicable_for==\"Sales Partner\"",
|
||||
"fieldname": "sales_partner",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Partner",
|
||||
"options": "Sales Partner",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.applicable_for==\"Supplier Type\"",
|
||||
"fieldname": "supplier_type",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supplier Type",
|
||||
"options": "Supplier Type",
|
||||
"depends_on": "eval:doc.applicable_for==\"Campaign\"",
|
||||
"fieldname": "campaign",
|
||||
"fieldtype": "Link",
|
||||
"label": "Campaign",
|
||||
"options": "Campaign",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "min_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Min Qty",
|
||||
"depends_on": "eval:doc.applicable_for==\"Supplier\"",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supplier",
|
||||
"options": "Supplier",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "max_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Max Qty",
|
||||
"depends_on": "eval:doc.applicable_for==\"Supplier Type\"",
|
||||
"fieldname": "supplier_type",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supplier Type",
|
||||
"options": "Supplier Type",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"fieldname": "min_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Min Qty",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"fieldname": "max_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Max Qty",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "valid_from",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid From",
|
||||
"fieldname": "col_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "valid_upto",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid Upto",
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"options": "Company",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "priority",
|
||||
"fieldtype": "Select",
|
||||
"label": "Priority",
|
||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20",
|
||||
"default": "Today",
|
||||
"fieldname": "valid_from",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid From",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "disable",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable",
|
||||
"fieldname": "valid_upto",
|
||||
"fieldtype": "Date",
|
||||
"label": "Valid Upto",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "price_discount_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price / Discount",
|
||||
"fieldname": "priority",
|
||||
"fieldtype": "Select",
|
||||
"label": "Priority",
|
||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Discount Percentage",
|
||||
"fieldname": "price_or_discount",
|
||||
"fieldtype": "Select",
|
||||
"label": "Price or Discount",
|
||||
"options": "\nPrice\nDiscount Percentage",
|
||||
"permlevel": 0,
|
||||
"fieldname": "disable",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "price_discount_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price / Discount",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"default": "Discount Percentage",
|
||||
"fieldname": "price_or_discount",
|
||||
"fieldtype": "Select",
|
||||
"label": "Price or Discount",
|
||||
"options": "\nPrice\nDiscount Percentage",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "col_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"fieldname": "col_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.price_or_discount==\"Price\"",
|
||||
"fieldname": "price",
|
||||
"fieldtype": "Float",
|
||||
"label": "Price",
|
||||
"depends_on": "eval:doc.price_or_discount==\"Price\"",
|
||||
"fieldname": "price",
|
||||
"fieldtype": "Float",
|
||||
"label": "Price",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.price_or_discount==\"Discount Percentage\"",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount Percentage",
|
||||
"depends_on": "eval:doc.price_or_discount==\"Discount Percentage\"",
|
||||
"fieldname": "discount_percentage",
|
||||
"fieldtype": "Float",
|
||||
"label": "Discount Percentage",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.price_or_discount==\"Discount Percentage\"",
|
||||
"fieldname": "for_price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "For Price List",
|
||||
"options": "Price List",
|
||||
"depends_on": "eval:doc.price_or_discount==\"Discount Percentage\"",
|
||||
"fieldname": "for_price_list",
|
||||
"fieldtype": "Link",
|
||||
"label": "For Price List",
|
||||
"options": "Price List",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "help_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"options": "Simple",
|
||||
"fieldname": "help_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"options": "Simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "pricing_rule_help",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Pricing Rule Help",
|
||||
"fieldname": "pricing_rule_help",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Pricing Rule Help",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-gift",
|
||||
"idx": 1,
|
||||
"istable": 0,
|
||||
"modified": "2014-05-28 15:36:29.403659",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-gift",
|
||||
"idx": 1,
|
||||
"istable": 0,
|
||||
"modified": "2014-06-20 19:36:22.502381",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Purchase Manager",
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Purchase Manager",
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Website Manager",
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Website Manager",
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"set_user_permissions": 1,
|
||||
"role": "System Manager",
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
||||
}
|
@ -5,16 +5,22 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
import copy
|
||||
from frappe import throw, _
|
||||
from frappe.utils import flt
|
||||
from frappe.utils import flt, cint
|
||||
from frappe.model.document import Document
|
||||
|
||||
class MultiplePricingRuleConflict(frappe.ValidationError): pass
|
||||
|
||||
class PricingRule(Document):
|
||||
def validate(self):
|
||||
self.validate_mandatory()
|
||||
self.validate_applicable_for_selling_or_buying()
|
||||
self.validate_min_max_qty()
|
||||
self.cleanup_fields_value()
|
||||
self.validate_price_or_discount()
|
||||
self.validate_max_discount()
|
||||
|
||||
def validate_mandatory(self):
|
||||
for field in ["apply_on", "applicable_for"]:
|
||||
@ -22,6 +28,18 @@ class PricingRule(Document):
|
||||
if tocheck and not self.get(tocheck):
|
||||
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
||||
|
||||
def validate_applicable_for_selling_or_buying(self):
|
||||
if not self.selling and not self.buying:
|
||||
throw(_("Atleast one of the Selling or Buying must be selected"))
|
||||
|
||||
if not self.selling and self.applicable_for in ["Customer", "Customer Group",
|
||||
"Territory", "Sales Partner", "Campaign"]:
|
||||
throw(_("Selling must be checked, if Applicable For is selected as {0}"
|
||||
.format(self.applicable_for)))
|
||||
|
||||
if not self.buying and self.applicable_for in ["Supplier", "Supplier Type"]:
|
||||
throw(_("Buying must be checked, if Applicable For is selected as {0}"
|
||||
.format(self.applicable_for)))
|
||||
|
||||
def validate_min_max_qty(self):
|
||||
if self.min_qty and self.max_qty and flt(self.min_qty) > flt(self.max_qty):
|
||||
@ -44,3 +62,192 @@ class PricingRule(Document):
|
||||
for field in ["Price", "Discount Percentage"]:
|
||||
if flt(self.get(frappe.scrub(field))) < 0:
|
||||
throw(_("{0} can not be negative").format(field))
|
||||
|
||||
def validate_max_discount(self):
|
||||
if self.price_or_discount == "Discount Percentage" and self.item_code:
|
||||
max_discount = frappe.db.get_value("Item", self.item_code, "max_discount")
|
||||
if max_discount and flt(self.discount_percentage) > flt(max_discount):
|
||||
throw(_("Max discount allowed for item: {0} is {1}%").format(self.item_code, max_discount))
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
@frappe.whitelist()
|
||||
def apply_pricing_rule(args):
|
||||
"""
|
||||
args = {
|
||||
"item_list": [{"doctype": "", "name": "", "item_code": "", "brand": "", "item_group": ""}, ...],
|
||||
"customer": "something",
|
||||
"customer_group": "something",
|
||||
"territory": "something",
|
||||
"supplier": "something",
|
||||
"supplier_type": "something",
|
||||
"currency": "something",
|
||||
"conversion_rate": "something",
|
||||
"price_list": "something",
|
||||
"plc_conversion_rate": "something",
|
||||
"company": "something",
|
||||
"transaction_date": "something",
|
||||
"campaign": "something",
|
||||
"sales_partner": "something",
|
||||
"ignore_pricing_rule": "something"
|
||||
}
|
||||
"""
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
args = frappe._dict(args)
|
||||
|
||||
# list of dictionaries
|
||||
out = []
|
||||
|
||||
if args.get("parenttype") == "Material Request": return out
|
||||
|
||||
if not args.transaction_type:
|
||||
args.transaction_type = "buying" if frappe.get_meta(args.parenttype).get_field("supplier") \
|
||||
else "selling"
|
||||
|
||||
item_list = args.get("item_list")
|
||||
args.pop("item_list")
|
||||
|
||||
for item in item_list:
|
||||
args_copy = copy.deepcopy(args)
|
||||
args_copy.update(item)
|
||||
out.append(get_pricing_rule_for_item(args_copy))
|
||||
|
||||
return out
|
||||
|
||||
def get_pricing_rule_for_item(args):
|
||||
if args.get("parenttype") == "Material Request": return {}
|
||||
|
||||
item_details = frappe._dict({
|
||||
"doctype": args.doctype,
|
||||
"name": args.name,
|
||||
"pricing_rule": None
|
||||
})
|
||||
|
||||
if args.ignore_pricing_rule or not args.item_code:
|
||||
return item_details
|
||||
|
||||
if not (args.item_group and args.brand):
|
||||
args.item_group, args.brand = frappe.db.get_value("Item", args.item_code, ["item_group", "brand"])
|
||||
|
||||
if args.customer and not (args.customer_group and args.territory):
|
||||
args.customer_group, args.territory = frappe.db.get_value("Customer", args.customer,
|
||||
["customer_group", "territory"])
|
||||
elif args.supplier and not args.supplier_type:
|
||||
args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type")
|
||||
|
||||
pricing_rules = get_pricing_rules(args)
|
||||
pricing_rule = filter_pricing_rules(args, pricing_rules)
|
||||
|
||||
if pricing_rule:
|
||||
item_details.pricing_rule = pricing_rule.name
|
||||
if pricing_rule.price_or_discount == "Price":
|
||||
item_details.update({
|
||||
"price_list_rate": pricing_rule.price/flt(args.conversion_rate) \
|
||||
if args.conversion_rate else 0.0,
|
||||
"discount_percentage": 0.0
|
||||
})
|
||||
else:
|
||||
item_details.discount_percentage = pricing_rule.discount_percentage
|
||||
|
||||
return item_details
|
||||
|
||||
def get_pricing_rules(args):
|
||||
def _get_tree_conditions(parenttype, allow_blank=True):
|
||||
field = frappe.scrub(parenttype)
|
||||
condition = ""
|
||||
if args.get(field):
|
||||
lft, rgt = frappe.db.get_value(parenttype, args[field], ["lft", "rgt"])
|
||||
parent_groups = frappe.db.sql_list("""select name from `tab%s`
|
||||
where lft<=%s and rgt>=%s""" % (parenttype, '%s', '%s'), (lft, rgt))
|
||||
|
||||
if parent_groups:
|
||||
if allow_blank: parent_groups.append('')
|
||||
condition = " ifnull("+field+", '') in ('" + "', '".join(parent_groups)+"')"
|
||||
|
||||
return condition
|
||||
|
||||
|
||||
conditions = ""
|
||||
for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
|
||||
if args.get(field):
|
||||
conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
|
||||
else:
|
||||
conditions += " and ifnull("+field+", '') = ''"
|
||||
|
||||
for parenttype in ["Customer Group", "Territory"]:
|
||||
group_condition = _get_tree_conditions(parenttype)
|
||||
if group_condition:
|
||||
conditions += " and " + group_condition
|
||||
|
||||
conditions += " and ifnull(for_price_list, '') in (%(price_list)s, '')"
|
||||
|
||||
if args.get("transaction_date"):
|
||||
conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01')
|
||||
and ifnull(valid_upto, '2500-12-31')"""
|
||||
|
||||
return frappe.db.sql("""select * from `tabPricing Rule`
|
||||
where (item_code=%(item_code)s or {item_group_condition} or brand=%(brand)s)
|
||||
and docstatus < 2 and ifnull(disable, 0) = 0
|
||||
and ifnull({transaction_type}, 0) = 1 {conditions}
|
||||
order by priority desc, name desc""".format(
|
||||
item_group_condition=_get_tree_conditions("Item Group", False),
|
||||
transaction_type=args.transaction_type, conditions=conditions), args, as_dict=1)
|
||||
|
||||
def filter_pricing_rules(args, pricing_rules):
|
||||
# filter for qty
|
||||
if pricing_rules and args.get("qty"):
|
||||
pricing_rules = filter(lambda x: (args.qty>=flt(x.min_qty)
|
||||
and (args.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
|
||||
# find pricing rule with highest priority
|
||||
if pricing_rules:
|
||||
max_priority = max([cint(p.priority) for p in pricing_rules])
|
||||
if max_priority:
|
||||
pricing_rules = filter(lambda x: cint(x.priority)==max_priority, pricing_rules)
|
||||
|
||||
# apply internal priority
|
||||
all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory",
|
||||
"supplier", "supplier_type", "campaign", "sales_partner"]
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
for field_set in [["item_code", "item_group", "brand"],
|
||||
["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]:
|
||||
remaining_fields = list(set(all_fields) - set(field_set))
|
||||
if if_all_rules_same(pricing_rules, remaining_fields):
|
||||
pricing_rules = apply_internal_priority(pricing_rules, field_set, args)
|
||||
break
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
price_or_discount = list(set([d.price_or_discount for d in pricing_rules]))
|
||||
if len(price_or_discount) == 1 and price_or_discount[0] == "Discount Percentage":
|
||||
pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
|
||||
or pricing_rules
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
frappe.throw(_("Multiple Price Rule exists with same criteria, please resolve \
|
||||
conflict by assigning priority. Price Rules: {0}")
|
||||
.format("\n".join([d.name for d in pricing_rules])), MultiplePricingRuleConflict)
|
||||
elif pricing_rules:
|
||||
return pricing_rules[0]
|
||||
|
||||
def if_all_rules_same(pricing_rules, fields):
|
||||
all_rules_same = True
|
||||
val = [pricing_rules[0][k] for k in fields]
|
||||
for p in pricing_rules[1:]:
|
||||
if val != [p[k] for k in fields]:
|
||||
all_rules_same = False
|
||||
break
|
||||
|
||||
return all_rules_same
|
||||
|
||||
def apply_internal_priority(pricing_rules, field_set, args):
|
||||
filtered_rules = []
|
||||
for field in field_set:
|
||||
if args.get(field):
|
||||
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
|
||||
if filtered_rules: break
|
||||
|
||||
return filtered_rules or pricing_rules
|
||||
|
@ -17,6 +17,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
"doctype": "Pricing Rule",
|
||||
"apply_on": "Item Code",
|
||||
"item_code": "_Test Item",
|
||||
"selling": 1,
|
||||
"price_or_discount": "Discount Percentage",
|
||||
"price": 0,
|
||||
"discount_percentage": 10,
|
||||
@ -29,13 +30,15 @@ class TestPricingRule(unittest.TestCase):
|
||||
"company": "_Test Company",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Sales Order",
|
||||
"parenttype": "Sales Order",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"order_type": "Sales",
|
||||
"transaction_type": "selling",
|
||||
"customer": "_Test Customer",
|
||||
"doctype": "Sales Order Item",
|
||||
"name": None
|
||||
})
|
||||
details = get_item_details(args)
|
||||
self.assertEquals(details.get("discount_percentage"), 10)
|
||||
@ -71,7 +74,7 @@ class TestPricingRule(unittest.TestCase):
|
||||
self.assertEquals(details.get("discount_percentage"), 5)
|
||||
|
||||
frappe.db.sql("update `tabPricing Rule` set priority=NULL where campaign='_Test Campaign'")
|
||||
from erpnext.stock.get_item_details import MultiplePricingRuleConflict
|
||||
from erpnext.accounts.doctype.pricing_rule.pricing_rule import MultiplePricingRuleConflict
|
||||
self.assertRaises(MultiplePricingRuleConflict, get_item_details, args)
|
||||
|
||||
args.item_code = "_Test Item 2"
|
||||
|
@ -231,6 +231,14 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -744,7 +752,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-06-04 08:45:25.582170",
|
||||
"modified": "2014-06-19 15:50:50.898237",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
@ -823,6 +831,12 @@
|
||||
"role": "Auditor",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Accounts Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -241,6 +241,14 @@
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -1180,7 +1188,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:17.806077",
|
||||
"modified": "2014-06-19 16:01:19.720382",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
@ -1225,6 +1233,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Customer"
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Accounts Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -263,10 +263,10 @@ class SalesInvoice(SellingController):
|
||||
for d in self.get('entries'):
|
||||
item = frappe.db.sql("""select name,is_asset_item,is_sales_item from `tabItem`
|
||||
where name = %s and (ifnull(end_of_life,'')='' or end_of_life > now())""", d.item_code)
|
||||
acc = frappe.db.sql("""select account_type from `tabAccount`
|
||||
acc = frappe.db.sql("""select account_type from `tabAccount`
|
||||
where name = %s and docstatus != 2""", d.income_account)
|
||||
if item and item[0][1] == 'Yes' and not acc[0][0] == 'Fixed Asset':
|
||||
msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(d.item_code), raise_exception=True)
|
||||
if item and item[0][1] == 'Yes' and acc and acc[0][0] != 'Fixed Asset':
|
||||
msgprint(_("Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item").format(acc[0][0], d.item_code), raise_exception=True)
|
||||
|
||||
def validate_with_previous_doc(self):
|
||||
super(SalesInvoice, self).validate_with_previous_doc(self.tname, {
|
||||
@ -732,7 +732,7 @@ def notify_errors(inv, customer, owner):
|
||||
|
||||
frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")],
|
||||
subject="[Urgent] Error while creating recurring invoice for %s" % inv,
|
||||
message = frappe.get_template("template/emails/recurring_invoice_failed.html").render({
|
||||
message = frappe.get_template("templates/emails/recurring_invoice_failed.html").render({
|
||||
"name": inv,
|
||||
"customer": customer
|
||||
}))
|
||||
|
@ -232,7 +232,7 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
indent: 0,
|
||||
opening: 0,
|
||||
checked: false,
|
||||
report_type: me.pl_or_bs,
|
||||
report_type: me.pl_or_bs=="Balance Sheet"? "Balance Sheet" : "Profit and Loss",
|
||||
};
|
||||
me.item_by_name[net_profit.name] = net_profit;
|
||||
|
||||
@ -244,7 +244,7 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
|
||||
|
||||
$.each(me.data, function(i, ac) {
|
||||
if(!ac.parent_account && me.apply_filter(ac, "company") &&
|
||||
ac.report_type==me.pl_or_bs) {
|
||||
ac.report_type==net_profit.report_type) {
|
||||
$.each(me.columns, function(i, col) {
|
||||
if(col.formatter==me.currency_formatter && col.balance_type=="Dr") {
|
||||
var bal = net_profit[col.date+"_dr"] -
|
||||
|
@ -104,13 +104,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Purchase Order",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -197,6 +198,14 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -636,7 +645,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:15.948363",
|
||||
"modified": "2014-06-23 07:55:50.372486",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
@ -696,6 +705,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Supplier"
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Purchase Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -187,12 +187,13 @@ class PurchaseOrder(BuyingController):
|
||||
def on_update(self):
|
||||
pass
|
||||
|
||||
def set_missing_values(source, target):
|
||||
target.ignore_pricing_rule = 1
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_purchase_receipt(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
def update_item(obj, target, source_parent):
|
||||
target.qty = flt(obj.qty) - flt(obj.received_qty)
|
||||
target.stock_qty = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)
|
||||
@ -226,10 +227,6 @@ def make_purchase_receipt(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_purchase_invoice(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
def update_item(obj, target, source_parent):
|
||||
target.amount = flt(obj.amount) - flt(obj.billed_amt)
|
||||
target.base_amount = target.amount * flt(source_parent.conversion_rate)
|
||||
|
@ -168,12 +168,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Quality Inspection",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@ -206,7 +207,7 @@
|
||||
"icon": "icon-search",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-26 03:05:52.140251",
|
||||
"modified": "2014-06-23 07:55:51.183113",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Quality Inspection",
|
||||
|
@ -104,13 +104,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Supplier Quotation",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -196,6 +197,14 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -562,7 +571,7 @@
|
||||
"icon": "icon-shopping-cart",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:20.226683",
|
||||
"modified": "2014-06-23 07:55:52.993616",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation",
|
||||
@ -640,6 +649,12 @@
|
||||
"role": "Supplier",
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Purchase Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -54,6 +54,7 @@ class SupplierQuotation(BuyingController):
|
||||
@frappe.whitelist()
|
||||
def make_purchase_order(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
target.ignore_pricing_rule = 1
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("get_schedule_dates")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
@ -89,14 +89,14 @@ class AccountsController(TransactionBase):
|
||||
"""set missing item values"""
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
if hasattr(self, "fname"):
|
||||
parent_dict = {"doctype": self.doctype}
|
||||
parent_dict = {}
|
||||
for fieldname in self.meta.get_valid_columns():
|
||||
parent_dict[fieldname] = self.get(fieldname)
|
||||
|
||||
for item in self.get(self.fname):
|
||||
if item.get("item_code"):
|
||||
args = item.as_dict()
|
||||
args.update(parent_dict)
|
||||
args = parent_dict.copy()
|
||||
args.update(item.as_dict())
|
||||
ret = get_item_details(args)
|
||||
|
||||
for fieldname, value in ret.items():
|
||||
|
@ -141,7 +141,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
concat(substr(tabItem.description, 1, 40), "..."), description) as decription
|
||||
from tabItem
|
||||
where tabItem.docstatus < 2
|
||||
and (tabItem.end_of_life is null or tabItem.end_of_life > %(today)s)
|
||||
and (tabItem.end_of_life > %(today)s or ifnull(tabItem.end_of_life, '0000-00-00')='0000-00-00')
|
||||
and (tabItem.`{key}` LIKE %(txt)s
|
||||
or tabItem.item_name LIKE %(txt)s)
|
||||
{fcond} {mcond}
|
||||
@ -254,3 +254,4 @@ def get_account_list(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.widgets.reportview.execute("Account", filters = filter_list,
|
||||
fields = ["name", "parent_account"],
|
||||
limit_start=start, limit_page_length=page_len, as_list=True)
|
||||
|
||||
|
@ -237,8 +237,11 @@ class StockController(AccountsController):
|
||||
if not item.get("expense_account"):
|
||||
frappe.throw(_("Expense or Difference account is mandatory for Item {0} as it impacts overall stock value").format(item.item_code))
|
||||
|
||||
if item.get("expense_account") and not item.get("cost_center"):
|
||||
frappe.throw(_("""Cost Center is mandatory for Item {0}""").format(item.get("item_code")))
|
||||
else:
|
||||
is_expense_account = frappe.db.get_value("Account", item.get("expense_account"), "report_type")=="Profit and Loss"
|
||||
if is_expense_account and not item.get("cost_center"):
|
||||
frappe.throw(_("{0} {1}: Cost Center is mandatory for Item {2}").format(
|
||||
_(self.doctype), self.name, item.get("item_code")))
|
||||
|
||||
def get_sl_entries(self, d, args):
|
||||
sl_dict = {
|
||||
|
@ -179,13 +179,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Appraisal",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -196,7 +197,7 @@
|
||||
"icon": "icon-thumbs-up",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:07.393120",
|
||||
"modified": "2014-06-23 07:55:40.801381",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Appraisal",
|
||||
|
@ -171,12 +171,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Expense Claim",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -187,7 +188,7 @@
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:10.736177",
|
||||
"modified": "2014-06-23 07:55:48.580747",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Claim",
|
||||
|
@ -121,13 +121,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Leave Allocation",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@ -136,7 +137,7 @@
|
||||
"icon": "icon-ok",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:12.744348",
|
||||
"modified": "2014-06-23 07:55:48.989894",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Leave Allocation",
|
||||
|
@ -180,13 +180,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Salary Slip",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"report_hide": 0
|
||||
@ -325,7 +326,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:17.213045",
|
||||
"modified": "2014-06-23 07:55:52.259962",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Slip",
|
||||
|
@ -2,6 +2,7 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
// On REFRESH
|
||||
frappe.provide("erpnext.bom");
|
||||
cur_frm.cscript.refresh = function(doc,dt,dn){
|
||||
cur_frm.toggle_enable("item", doc.__islocal);
|
||||
|
||||
@ -10,7 +11,7 @@ cur_frm.cscript.refresh = function(doc,dt,dn){
|
||||
}
|
||||
|
||||
cur_frm.cscript.with_operations(doc);
|
||||
set_operation_no(doc);
|
||||
erpnext.bom.set_operation_no(doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.update_cost = function() {
|
||||
@ -30,10 +31,10 @@ cur_frm.cscript.with_operations = function(doc) {
|
||||
|
||||
cur_frm.cscript.operation_no = function(doc, cdt, cdn) {
|
||||
var child = locals[cdt][cdn];
|
||||
if(child.parentfield=="bom_operations") set_operation_no(doc);
|
||||
if(child.parentfield=="bom_operations") erpnext.bom.set_operation_no(doc);
|
||||
}
|
||||
|
||||
var set_operation_no = function(doc) {
|
||||
erpnext.bom.set_operation_no = function(doc) {
|
||||
var op_table = doc.bom_operations || [];
|
||||
var operations = [];
|
||||
|
||||
@ -53,7 +54,7 @@ var set_operation_no = function(doc) {
|
||||
}
|
||||
|
||||
cur_frm.fields_dict["bom_operations"].grid.on_row_delete = function(cdt, cdn){
|
||||
set_operation_no(doc);
|
||||
erpnext.bom.set_operation_no(doc);
|
||||
}
|
||||
|
||||
cur_frm.add_fetch("item", "description", "description");
|
||||
@ -64,15 +65,15 @@ cur_frm.cscript.workstation = function(doc,dt,dn) {
|
||||
frappe.model.with_doc("Workstation", d.workstation, function(i, r) {
|
||||
d.hour_rate = r.docs[0].hour_rate;
|
||||
refresh_field("hour_rate", dn, "bom_operations");
|
||||
calculate_op_cost(doc);
|
||||
calculate_total(doc);
|
||||
erpnext.bom.calculate_op_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.hour_rate = function(doc, dt, dn) {
|
||||
calculate_op_cost(doc);
|
||||
calculate_total(doc);
|
||||
erpnext.bom.calculate_op_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
}
|
||||
|
||||
|
||||
@ -106,8 +107,8 @@ var get_bom_material_detail= function(doc, cdt, cdn) {
|
||||
$.extend(d, r.message);
|
||||
refresh_field("bom_materials");
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
calculate_rm_cost(doc);
|
||||
calculate_total(doc);
|
||||
erpnext.bom.calculate_rm_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
},
|
||||
freeze: true
|
||||
});
|
||||
@ -116,8 +117,8 @@ var get_bom_material_detail= function(doc, cdt, cdn) {
|
||||
|
||||
|
||||
cur_frm.cscript.qty = function(doc, cdt, cdn) {
|
||||
calculate_rm_cost(doc);
|
||||
calculate_total(doc);
|
||||
erpnext.bom.calculate_rm_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.rate = function(doc, cdt, cdn) {
|
||||
@ -126,12 +127,12 @@ cur_frm.cscript.rate = function(doc, cdt, cdn) {
|
||||
msgprint(__("You can not change rate if BOM mentioned agianst any item"));
|
||||
get_bom_material_detail(doc, cdt, cdn);
|
||||
} else {
|
||||
calculate_rm_cost(doc);
|
||||
calculate_total(doc);
|
||||
erpnext.bom.calculate_rm_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
}
|
||||
}
|
||||
|
||||
var calculate_op_cost = function(doc) {
|
||||
erpnext.bom.calculate_op_cost = function(doc) {
|
||||
var op = doc.bom_operations || [];
|
||||
total_op_cost = 0;
|
||||
for(var i=0;i<op.length;i++) {
|
||||
@ -143,7 +144,7 @@ var calculate_op_cost = function(doc) {
|
||||
refresh_field('operating_cost');
|
||||
}
|
||||
|
||||
var calculate_rm_cost = function(doc) {
|
||||
erpnext.bom.calculate_rm_cost = function(doc) {
|
||||
var rm = doc.bom_materials || [];
|
||||
total_rm_cost = 0;
|
||||
for(var i=0;i<rm.length;i++) {
|
||||
@ -159,7 +160,7 @@ var calculate_rm_cost = function(doc) {
|
||||
|
||||
|
||||
// Calculate Total Cost
|
||||
var calculate_total = function(doc) {
|
||||
erpnext.bom.calculate_total = function(doc) {
|
||||
doc.total_cost = flt(doc.raw_material_cost) + flt(doc.operating_cost);
|
||||
refresh_field('total_cost');
|
||||
}
|
||||
@ -200,7 +201,7 @@ cur_frm.fields_dict['bom_materials'].grid.get_field('bom_no').get_query = functi
|
||||
}
|
||||
|
||||
cur_frm.cscript.validate = function(doc, dt, dn) {
|
||||
calculate_op_cost(doc);
|
||||
calculate_rm_cost(doc);
|
||||
calculate_total(doc);
|
||||
erpnext.bom.calculate_op_cost(doc);
|
||||
erpnext.bom.calculate_rm_cost(doc);
|
||||
erpnext.bom.calculate_total(doc);
|
||||
}
|
||||
|
@ -1,256 +1,257 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item",
|
||||
"options": "icon-gift",
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Item",
|
||||
"options": "icon-gift",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "PRO-",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "PRO-",
|
||||
"permlevel": 0,
|
||||
"default": "PRO-",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "PRO-",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
|
||||
"permlevel": 0,
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"description": "Bill of Material to be considered for manufacturing",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "production_item",
|
||||
"description": "Bill of Material to be considered for manufacturing",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"default": "1",
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Manufacture against Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"description": "Manufacture against Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "production_item",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"description": "Automatically updated via Stock Entry of type Manufacture/Repack",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Manufactured Qty",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"description": "Automatically updated via Stock Entry of type Manufacture/Repack",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Manufactured Qty",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "sales_order",
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date",
|
||||
"permlevel": 0,
|
||||
"depends_on": "sales_order",
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "icon-building",
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "icon-building",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"description": "Manufactured quantity will be updated in this warehouse",
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "For Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"depends_on": "production_item",
|
||||
"description": "Manufactured quantity will be updated in this warehouse",
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 0,
|
||||
"label": "For Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0,
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description",
|
||||
"permlevel": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Project Name",
|
||||
"oldfieldname": "project_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Project Name",
|
||||
"oldfieldname": "project_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
"depends_on": "production_item",
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Production Order",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "icon-cogs",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:15.008942",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-cogs",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-06-23 07:55:50.092300",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Manufacturing User",
|
||||
"submit": 1,
|
||||
"amend": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Manufacturing User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Material User"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -62,3 +62,5 @@ erpnext.patches.v4_0.update_other_charges_in_custom_purchase_print_formats
|
||||
erpnext.patches.v4_0.create_price_list_if_missing
|
||||
execute:frappe.db.sql("update `tabItem` set end_of_life=null where end_of_life='0000-00-00'") #2014-06-16
|
||||
erpnext.patches.v4_0.update_users_report_view_settings
|
||||
erpnext.patches.v4_0.set_pricing_rule_for_buying_or_selling
|
||||
erpnext.patches.v4_0.set_naming_series_property_setter
|
||||
|
0
erpnext/patches/repair_tools/__init__.py
Normal file
0
erpnext/patches/repair_tools/__init__.py
Normal file
@ -0,0 +1,204 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import json
|
||||
from frappe.model.naming import make_autoname
|
||||
from frappe.utils import cint
|
||||
from frappe.utils.email_lib import sendmail_to_system_managers
|
||||
|
||||
doctype_series_map = {
|
||||
'Attendance': 'ATT-',
|
||||
'C-Form': 'C-FORM-',
|
||||
'Customer': 'CUST-',
|
||||
'Customer Issue': 'CI-',
|
||||
'Delivery Note': 'DN-',
|
||||
'Installation Note': 'IN-',
|
||||
'Item': 'ITEM-',
|
||||
'Journal Voucher': 'JV-',
|
||||
'Lead': 'LEAD-',
|
||||
'Opportunity': 'OPTY-',
|
||||
'Packing Slip': 'PS-',
|
||||
'Production Order': 'PRO-',
|
||||
'Purchase Invoice': 'PINV-',
|
||||
'Purchase Order': 'PO-',
|
||||
'Purchase Receipt': 'PREC-',
|
||||
'Quality Inspection': 'QI-',
|
||||
'Quotation': 'QTN-',
|
||||
'Sales Invoice': 'SINV-',
|
||||
'Sales Order': 'SO-',
|
||||
'Stock Entry': 'STE-',
|
||||
'Supplier': 'SUPP-',
|
||||
'Supplier Quotation': 'SQTN-',
|
||||
'Support Ticket': 'SUP-'
|
||||
}
|
||||
|
||||
def check_docs_to_rename():
|
||||
if "erpnext" not in frappe.get_installed_apps():
|
||||
return
|
||||
|
||||
docs_to_rename = get_docs_to_rename()
|
||||
if docs_to_rename:
|
||||
print "To Rename"
|
||||
print json.dumps(docs_to_rename, indent=1, sort_keys=True)
|
||||
|
||||
frappe.db.rollback()
|
||||
|
||||
def check_gl_sl_entries_to_fix():
|
||||
if "erpnext" not in frappe.get_installed_apps():
|
||||
return
|
||||
|
||||
gl_entries_to_fix = get_gl_entries_to_fix()
|
||||
if gl_entries_to_fix:
|
||||
print "General Ledger Entries to Fix"
|
||||
print json.dumps(gl_entries_to_fix, indent=1, sort_keys=True)
|
||||
|
||||
sl_entries_to_fix = get_sl_entries_to_fix()
|
||||
if sl_entries_to_fix:
|
||||
print "Stock Ledger Entries to Fix"
|
||||
print json.dumps(sl_entries_to_fix, indent=1, sort_keys=True)
|
||||
|
||||
frappe.db.rollback()
|
||||
|
||||
def guess_reference_date():
|
||||
return (frappe.db.get_value("Patch Log", {"patch": "erpnext.patches.v4_0.validate_v3_patch"}, "creation")
|
||||
or "2014-05-06")
|
||||
|
||||
def get_docs_to_rename():
|
||||
reference_date = guess_reference_date()
|
||||
|
||||
docs_to_rename = {}
|
||||
for doctype, new_series in doctype_series_map.items():
|
||||
if doctype in ("Item", "Customer", "Lead", "Supplier"):
|
||||
if not frappe.db.sql("""select name from `tab{doctype}`
|
||||
where ifnull(naming_series, '')!=''
|
||||
and name like concat(naming_series, '%%') limit 1""".format(doctype=doctype)):
|
||||
continue
|
||||
|
||||
# fix newly formed records using old series!
|
||||
records_with_new_series = frappe.db.sql_list("""select name from `tab{doctype}`
|
||||
where date(creation) >= date(%s) and naming_series=%s
|
||||
and exists (select name from `tab{doctype}` where ifnull(naming_series, '') not in ('', %s) limit 1)
|
||||
order by name asc""".format(doctype=doctype), (reference_date, new_series, new_series))
|
||||
|
||||
if records_with_new_series:
|
||||
docs_to_rename[doctype] = records_with_new_series
|
||||
|
||||
return docs_to_rename
|
||||
|
||||
def get_gl_entries_to_fix():
|
||||
bad_gl_entries = {}
|
||||
|
||||
for dt in frappe.db.sql_list("""select distinct voucher_type from `tabGL Entry`
|
||||
where ifnull(voucher_type, '')!=''"""):
|
||||
|
||||
if dt not in doctype_series_map:
|
||||
continue
|
||||
|
||||
out = frappe.db.sql("""select gl.name, gl.voucher_no from `tabGL Entry` gl
|
||||
where ifnull(voucher_type, '')=%s and voucher_no like %s and
|
||||
not exists (select name from `tab{voucher_type}` vt where vt.name=gl.voucher_no)""".format(voucher_type=dt),
|
||||
(dt, doctype_series_map[dt] + "%%"), as_dict=True)
|
||||
|
||||
if out:
|
||||
bad_gl_entries.setdefault(dt, []).extend(out)
|
||||
|
||||
for dt in frappe.db.sql_list("""select distinct against_voucher_type
|
||||
from `tabGL Entry` where ifnull(against_voucher_type, '')!=''"""):
|
||||
|
||||
if dt not in doctype_series_map:
|
||||
continue
|
||||
|
||||
out = frappe.db.sql("""select gl.name, gl.against_voucher from `tabGL Entry` gl
|
||||
where ifnull(against_voucher_type, '')=%s and against_voucher like %s and
|
||||
not exists (select name from `tab{against_voucher_type}` vt
|
||||
where vt.name=gl.against_voucher)""".format(against_voucher_type=dt),
|
||||
(dt, doctype_series_map[dt] + "%%"), as_dict=True)
|
||||
|
||||
if out:
|
||||
bad_gl_entries.setdefault(dt, []).extend(out)
|
||||
|
||||
return bad_gl_entries
|
||||
|
||||
def get_sl_entries_to_fix():
|
||||
bad_sl_entries = {}
|
||||
|
||||
for dt in frappe.db.sql_list("""select distinct voucher_type from `tabStock Ledger Entry`
|
||||
where ifnull(voucher_type, '')!=''"""):
|
||||
|
||||
if dt not in doctype_series_map:
|
||||
continue
|
||||
|
||||
out = frappe.db.sql("""select sl.name, sl.voucher_no from `tabStock Ledger Entry` sl
|
||||
where voucher_type=%s and voucher_no like %s and
|
||||
not exists (select name from `tab{voucher_type}` vt where vt.name=sl.voucher_no)""".format(voucher_type=dt),
|
||||
(dt, doctype_series_map[dt] + "%%"), as_dict=True)
|
||||
if out:
|
||||
bad_sl_entries.setdefault(dt, []).extend(out)
|
||||
|
||||
return bad_sl_entries
|
||||
|
||||
def add_comment(doctype, old_name, new_name):
|
||||
frappe.get_doc({
|
||||
"doctype":"Comment",
|
||||
"comment_by": frappe.session.user,
|
||||
"comment_doctype": doctype,
|
||||
"comment_docname": new_name,
|
||||
"comment": """Renamed from **{old_name}** to {new_name}""".format(old_name=old_name, new_name=new_name)
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
def _rename_doc(doctype, name, naming_series):
|
||||
if frappe.get_meta(doctype).get_field("amended_from"):
|
||||
amended_from = frappe.db.get_value(doctype, name, "amended_from")
|
||||
else:
|
||||
amended_from = None
|
||||
|
||||
if amended_from:
|
||||
am_id = 1
|
||||
am_prefix = amended_from
|
||||
if frappe.db.get_value(doctype, amended_from, "amended_from"):
|
||||
am_id = cint(amended_from.split('-')[-1]) + 1
|
||||
am_prefix = '-'.join(amended_from.split('-')[:-1]) # except the last hyphen
|
||||
|
||||
fixed_name = am_prefix + '-' + str(am_id)
|
||||
else:
|
||||
fixed_name = make_autoname(naming_series+'.#####')
|
||||
|
||||
frappe.db.set_value(doctype, name, "naming_series", naming_series)
|
||||
frappe.rename_doc(doctype, name, fixed_name, force=True)
|
||||
add_comment(doctype, name, fixed_name)
|
||||
|
||||
return fixed_name
|
||||
|
||||
def rename_docs():
|
||||
_log = []
|
||||
def log(msg):
|
||||
_log.append(msg)
|
||||
print msg
|
||||
|
||||
commit = False
|
||||
docs_to_rename = get_docs_to_rename()
|
||||
for doctype, list_of_names in docs_to_rename.items():
|
||||
naming_series_field = frappe.get_meta(doctype).get_field("naming_series")
|
||||
default_series = naming_series_field.default or filter(None, (naming_series_field.options or "").split("\n"))[0]
|
||||
|
||||
print
|
||||
print "Rename", doctype, list_of_names, "using series", default_series
|
||||
confirm = raw_input("do it? (yes / anything else): ")
|
||||
|
||||
if confirm == "yes":
|
||||
commit = True
|
||||
for name in list_of_names:
|
||||
fixed_name = _rename_doc(doctype, name, default_series)
|
||||
log("Renamed {doctype} {name} --> {fixed_name}".format(doctype=doctype, name=name, fixed_name=fixed_name))
|
||||
|
||||
if commit:
|
||||
content = """These documents have been renamed in your ERPNext instance: {site}\n\n{_log}""".format(site=frappe.local.site, _log="\n".join(_log))
|
||||
|
||||
print content
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
sendmail_to_system_managers("[Important] [ERPNext] Renamed Documents via Patch", content)
|
||||
|
@ -24,7 +24,8 @@ def execute():
|
||||
"applicable_for": "Customer",
|
||||
"customer": d.parent,
|
||||
"price_or_discount": "Discount Percentage",
|
||||
"discount_percentage": d.discount
|
||||
"discount_percentage": d.discount,
|
||||
"selling": 1
|
||||
}).insert()
|
||||
|
||||
frappe.db.auto_commit_on_many_writes = False
|
||||
|
98
erpnext/patches/v4_0/set_naming_series_property_setter.py
Normal file
98
erpnext/patches/v4_0/set_naming_series_property_setter.py
Normal file
@ -0,0 +1,98 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
from frappe.core.doctype.property_setter.property_setter import make_property_setter
|
||||
|
||||
doctype_series_map = {
|
||||
'Attendance': 'ATT-',
|
||||
'C-Form': 'C-FORM-',
|
||||
'Customer': 'CUST-',
|
||||
'Customer Issue': 'CI-',
|
||||
'Delivery Note': 'DN-',
|
||||
'Installation Note': 'IN-',
|
||||
'Item': 'ITEM-',
|
||||
'Journal Voucher': 'JV-',
|
||||
'Lead': 'LEAD-',
|
||||
'Opportunity': 'OPTY-',
|
||||
'Packing Slip': 'PS-',
|
||||
'Production Order': 'PRO-',
|
||||
'Purchase Invoice': 'PINV-',
|
||||
'Purchase Order': 'PO-',
|
||||
'Purchase Receipt': 'PREC-',
|
||||
'Quality Inspection': 'QI-',
|
||||
'Quotation': 'QTN-',
|
||||
'Sales Invoice': 'SINV-',
|
||||
'Sales Order': 'SO-',
|
||||
'Stock Entry': 'STE-',
|
||||
'Supplier': 'SUPP-',
|
||||
'Supplier Quotation': 'SQTN-',
|
||||
'Support Ticket': 'SUP-'
|
||||
}
|
||||
|
||||
def execute():
|
||||
series_to_set = get_series_to_set()
|
||||
for doctype, opts in series_to_set.items():
|
||||
print "Setting naming series", doctype, opts
|
||||
set_series(doctype, opts["options"], opts["default"])
|
||||
|
||||
def set_series(doctype, options, default):
|
||||
make_property_setter(doctype, "naming_series", "options", options, "Text")
|
||||
make_property_setter(doctype, "naming_series", "default", default, "Text")
|
||||
|
||||
def get_series_to_set():
|
||||
series_to_set = {}
|
||||
|
||||
for doctype, new_series in doctype_series_map.items():
|
||||
# you can't fix what does not exist :)
|
||||
if not frappe.db.a_row_exists(doctype):
|
||||
continue
|
||||
|
||||
series_to_preserve = get_series_to_preserve(doctype, new_series)
|
||||
|
||||
if not series_to_preserve:
|
||||
continue
|
||||
|
||||
default_series = get_default_series(doctype, new_series)
|
||||
if not default_series:
|
||||
continue
|
||||
|
||||
existing_series = (frappe.get_meta(doctype).get_field("naming_series").options or "").split("\n")
|
||||
existing_series = filter(None, [d.strip() for d in existing_series])
|
||||
|
||||
if (not (set(existing_series).difference(series_to_preserve) or set(series_to_preserve).difference(existing_series))
|
||||
and len(series_to_preserve)==len(existing_series)):
|
||||
# print "No change for", doctype, ":", existing_series, "=", series_to_preserve
|
||||
continue
|
||||
|
||||
# set naming series property setter
|
||||
series_to_preserve = list(set(series_to_preserve + existing_series))
|
||||
if new_series in series_to_preserve:
|
||||
series_to_preserve.remove(new_series)
|
||||
|
||||
if series_to_preserve:
|
||||
series_to_set[doctype] = {"options": "\n".join(series_to_preserve), "default": default_series}
|
||||
|
||||
return series_to_set
|
||||
|
||||
def get_series_to_preserve(doctype, new_series):
|
||||
series_to_preserve = frappe.db.sql_list("""select distinct naming_series from `tab{doctype}`
|
||||
where ifnull(naming_series, '') not in ('', %s)""".format(doctype=doctype), new_series)
|
||||
|
||||
series_to_preserve.sort()
|
||||
|
||||
return series_to_preserve
|
||||
|
||||
def get_default_series(doctype, new_series):
|
||||
default_series = frappe.db.sql("""select naming_series from `tab{doctype}` where ifnull(naming_series, '') not in ('', %s)
|
||||
and creation=(select max(creation) from `tab{doctype}`
|
||||
where ifnull(naming_series, '') not in ('', %s)) order by creation desc limit 1""".format(doctype=doctype),
|
||||
(new_series, new_series))
|
||||
|
||||
if not (default_series and default_series[0][0]):
|
||||
print "[Skipping] Cannot guess which naming series to use for", doctype
|
||||
return
|
||||
|
||||
return default_series[0][0]
|
@ -0,0 +1,13 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("accounts", "doctype", "pricing_rule")
|
||||
frappe.db.sql("""update `tabPricing Rule` set selling=1 where ifnull(applicable_for, '') in
|
||||
('', 'Customer', 'Customer Group', 'Territory', 'Sales Partner', 'Campaign')""")
|
||||
|
||||
frappe.db.sql("""update `tabPricing Rule` set buying=1 where ifnull(applicable_for, '') in
|
||||
('', 'Supplier', 'Supplier Type')""")
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"allow_attach": 1,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:project_name",
|
||||
"creation": "2013-03-07 11:55:07",
|
||||
"docstatus": 0,
|
||||
@ -258,7 +259,7 @@
|
||||
"icon": "icon-puzzle-piece",
|
||||
"idx": 1,
|
||||
"max_attachments": 4,
|
||||
"modified": "2014-05-27 03:49:15.252736",
|
||||
"modified": "2014-06-24 12:44:19.530707",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Project",
|
||||
|
@ -52,7 +52,7 @@ def get_events(start, end, filters=None):
|
||||
frappe.msgprint(_("No Permission"), raise_exception=1)
|
||||
|
||||
conditions = build_match_conditions("Task")
|
||||
conditions and (" and " + conditions) or ""
|
||||
conditions = conditions and (" and " + conditions) or ""
|
||||
|
||||
if filters:
|
||||
filters = json.loads(filters)
|
||||
|
@ -4,6 +4,37 @@
|
||||
frappe.provide("erpnext.stock");
|
||||
|
||||
erpnext.stock.StockController = frappe.ui.form.Controller.extend({
|
||||
onload: function() {
|
||||
// warehouse query if company
|
||||
if (this.frm.fields_dict.company) {
|
||||
this.setup_warehouse_query();
|
||||
}
|
||||
},
|
||||
|
||||
setup_warehouse_query: function() {
|
||||
var me = this;
|
||||
|
||||
var _set_warehouse_query = function(doctype, parentfield) {
|
||||
var warehouse_link_fields = frappe.meta.get_docfields(doctype, me.frm.doc.name,
|
||||
{"fieldtype": "Link", "options": "Warehouse"});
|
||||
$.each(warehouse_link_fields, function(i, df) {
|
||||
me.frm.set_query(df.fieldname, parentfield, function() {
|
||||
return erpnext.queries.warehouse(me.frm.doc);
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
_set_warehouse_query(me.frm.doc.doctype);
|
||||
|
||||
// warehouse field in tables
|
||||
var table_fields = frappe.meta.get_docfields(me.frm.doc.doctype, me.frm.doc.name,
|
||||
{"fieldtype": "Table"});
|
||||
|
||||
$.each(table_fields, function(i, df) {
|
||||
_set_warehouse_query(df.options, df.fieldname);
|
||||
});
|
||||
},
|
||||
|
||||
show_stock_ledger: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.docstatus===1) {
|
||||
@ -17,12 +48,12 @@ erpnext.stock.StockController = frappe.ui.form.Controller.extend({
|
||||
frappe.set_route("query-report", "Stock Ledger");
|
||||
}, "icon-bar-chart");
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
show_general_ledger: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.docstatus===1 && cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
if(this.frm.doc.docstatus===1 && cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
cur_frm.appframe.add_button(__('Accounting Ledger'), function() {
|
||||
frappe.route_options = {
|
||||
voucher_no: me.frm.doc.name,
|
||||
@ -46,4 +77,4 @@ erpnext.stock.StockController = frappe.ui.form.Controller.extend({
|
||||
}
|
||||
refresh_field(this.frm.cscript.fname);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -67,5 +67,11 @@ $.extend(erpnext.queries, {
|
||||
|
||||
employee: function() {
|
||||
return { query: "erpnext.controllers.queries.employee_query" }
|
||||
},
|
||||
|
||||
warehouse: function(doc) {
|
||||
return {
|
||||
filters: [["Warehouse", "company", "in", ["", doc.company]]]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -7,6 +7,8 @@ frappe.require("assets/erpnext/js/controllers/stock_controller.js");
|
||||
erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
onload: function() {
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
if(this.frm.doc.__islocal) {
|
||||
var today = get_today(),
|
||||
currency = frappe.defaults.get_user_default("currency");
|
||||
@ -116,8 +118,8 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
barcode: item.barcode,
|
||||
serial_no: item.serial_no,
|
||||
warehouse: item.warehouse,
|
||||
doctype: me.frm.doc.doctype,
|
||||
docname: me.frm.doc.name,
|
||||
parenttype: me.frm.doc.doctype,
|
||||
parent: me.frm.doc.name,
|
||||
customer: me.frm.doc.customer,
|
||||
supplier: me.frm.doc.supplier,
|
||||
currency: me.frm.doc.currency,
|
||||
@ -130,7 +132,10 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
order_type: me.frm.doc.order_type,
|
||||
is_pos: cint(me.frm.doc.is_pos),
|
||||
is_subcontracted: me.frm.doc.is_subcontracted,
|
||||
transaction_date: me.frm.doc.transaction_date
|
||||
transaction_date: me.frm.doc.transaction_date,
|
||||
ignore_pricing_rule: me.frm.doc.ignore_pricing_rule,
|
||||
doctype: item.doctype,
|
||||
name: item.name
|
||||
}
|
||||
},
|
||||
callback: function(r) {
|
||||
@ -196,7 +201,7 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
}
|
||||
|
||||
this.frm.script_manager.trigger("currency");
|
||||
this.apply_pricing_rule()
|
||||
this.apply_pricing_rule();
|
||||
}
|
||||
},
|
||||
|
||||
@ -229,7 +234,12 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
this.frm.set_value("plc_conversion_rate", this.frm.doc.conversion_rate);
|
||||
}
|
||||
if(flt(this.frm.doc.conversion_rate)>0.0) {
|
||||
this.apply_pricing_rule();
|
||||
if(this.frm.doc.ignore_pricing_rule) {
|
||||
this.calculate_taxes_and_totals();
|
||||
} else {
|
||||
this.apply_pricing_rule();
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
@ -283,12 +293,11 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
}
|
||||
if(this.frm.doc.price_list_currency === this.frm.doc.currency) {
|
||||
this.frm.set_value("conversion_rate", this.frm.doc.plc_conversion_rate);
|
||||
this.apply_pricing_rule();
|
||||
}
|
||||
},
|
||||
|
||||
qty: function(doc, cdt, cdn) {
|
||||
this.apply_pricing_rule(frappe.get_doc(cdt, cdn));
|
||||
this.apply_pricing_rule(frappe.get_doc(cdt, cdn), true);
|
||||
},
|
||||
|
||||
// tax rate
|
||||
@ -331,51 +340,71 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
this.calculate_taxes_and_totals();
|
||||
},
|
||||
|
||||
apply_pricing_rule: function(item) {
|
||||
ignore_pricing_rule: function() {
|
||||
this.apply_pricing_rule();
|
||||
},
|
||||
|
||||
apply_pricing_rule: function(item, calculate_taxes_and_totals) {
|
||||
var me = this;
|
||||
|
||||
var _apply_pricing_rule = function(item) {
|
||||
return me.frm.call({
|
||||
method: "erpnext.stock.get_item_details.apply_pricing_rule",
|
||||
child: item,
|
||||
args: {
|
||||
args: {
|
||||
item_code: item.item_code,
|
||||
item_group: item.item_group,
|
||||
brand: item.brand,
|
||||
qty: item.qty,
|
||||
customer: me.frm.doc.customer,
|
||||
customer_group: me.frm.doc.customer_group,
|
||||
territory: me.frm.doc.territory,
|
||||
supplier: me.frm.doc.supplier,
|
||||
supplier_type: me.frm.doc.supplier_type,
|
||||
currency: me.frm.doc.currency,
|
||||
conversion_rate: me.frm.doc.conversion_rate,
|
||||
price_list: me.frm.doc.selling_price_list ||
|
||||
me.frm.doc.buying_price_list,
|
||||
plc_conversion_rate: me.frm.doc.plc_conversion_rate,
|
||||
company: me.frm.doc.company,
|
||||
transaction_date: me.frm.doc.transaction_date || me.frm.doc.posting_date,
|
||||
campaign: me.frm.doc.campaign,
|
||||
sales_partner: me.frm.doc.sales_partner
|
||||
}
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
me.frm.script_manager.trigger("price_list_rate", item.doctype, item.name);
|
||||
}
|
||||
var item_list = this._get_item_list(item);
|
||||
var args = {
|
||||
"item_list": item_list,
|
||||
"customer": me.frm.doc.customer,
|
||||
"customer_group": me.frm.doc.customer_group,
|
||||
"territory": me.frm.doc.territory,
|
||||
"supplier": me.frm.doc.supplier,
|
||||
"supplier_type": me.frm.doc.supplier_type,
|
||||
"currency": me.frm.doc.currency,
|
||||
"conversion_rate": me.frm.doc.conversion_rate,
|
||||
"price_list": me.frm.doc.selling_price_list || me.frm.doc.buying_price_list,
|
||||
"plc_conversion_rate": me.frm.doc.plc_conversion_rate,
|
||||
"company": me.frm.doc.company,
|
||||
"transaction_date": me.frm.doc.transaction_date || me.frm.doc.posting_date,
|
||||
"campaign": me.frm.doc.campaign,
|
||||
"sales_partner": me.frm.doc.sales_partner,
|
||||
"ignore_pricing_rule": me.frm.doc.ignore_pricing_rule,
|
||||
"parenttype": me.frm.doc.doctype,
|
||||
"parent": me.frm.doc.name
|
||||
};
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.doctype.pricing_rule.pricing_rule.apply_pricing_rule",
|
||||
args: { args: args },
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
$.each(r.message, function(i, d) {
|
||||
$.each(d, function(k, v) {
|
||||
if (["doctype", "name"].indexOf(k)===-1) {
|
||||
frappe.model.set_value(d.doctype, d.name, k, v);
|
||||
}
|
||||
});
|
||||
});
|
||||
if(calculate_taxes_and_totals) me.calculate_taxes_and_totals();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_get_item_list: function(item) {
|
||||
var item_list = [];
|
||||
var append_item = function(d) {
|
||||
item_list.push({
|
||||
"doctype": d.doctype,
|
||||
"name": d.name,
|
||||
"item_code": d.item_code,
|
||||
"item_group": d.item_group,
|
||||
"brand": d.brand,
|
||||
"qty": d.qty
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if(item) {
|
||||
_apply_pricing_rule(item);
|
||||
if (item) {
|
||||
append_item(item);
|
||||
} else {
|
||||
$.each(this.get_item_doclist(), function(n, item) {
|
||||
_apply_pricing_rule(item);
|
||||
$.each(this.get_item_doclist(), function(i, d) {
|
||||
append_item(d);
|
||||
});
|
||||
}
|
||||
return item_list;
|
||||
},
|
||||
|
||||
included_in_print_rate: function(doc, cdt, cdn) {
|
||||
|
@ -195,12 +195,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Installation Note",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@ -235,7 +236,7 @@
|
||||
"icon": "icon-wrench",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:11.449598",
|
||||
"modified": "2014-06-23 07:55:48.805241",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Installation Note",
|
||||
|
@ -385,12 +385,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Opportunity",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -409,7 +410,7 @@
|
||||
"icon": "icon-info-sign",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:14.057062",
|
||||
"modified": "2014-06-23 07:55:49.718301",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Opportunity",
|
||||
|
@ -139,12 +139,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Quotation",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -274,6 +275,14 @@
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -818,7 +827,7 @@
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"max_attachments": 1,
|
||||
"modified": "2014-05-27 03:49:16.670976",
|
||||
"modified": "2014-06-23 07:55:51.859025",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation",
|
||||
@ -896,6 +905,12 @@
|
||||
"role": "Maintenance User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Sales Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -102,7 +102,7 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False):
|
||||
if customer:
|
||||
target.customer = customer.name
|
||||
target.customer_name = customer.customer_name
|
||||
|
||||
target.ignore_pricing_rule = 1
|
||||
target.ignore_permissions = ignore_permissions
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
@ -112,13 +112,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -285,6 +286,14 @@
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -874,7 +883,7 @@
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"modified": "2014-05-27 08:39:19.027965",
|
||||
"modified": "2014-06-23 07:55:52.555192",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order",
|
||||
@ -953,6 +962,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Material User"
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Sales Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -245,9 +245,6 @@ class SalesOrder(SellingController):
|
||||
def get_portal_page(self):
|
||||
return "order" if self.docstatus==1 else None
|
||||
|
||||
def set_missing_values(source, target):
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_material_request(source_name, target_doc=None):
|
||||
@ -274,6 +271,11 @@ def make_material_request(source_name, target_doc=None):
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_delivery_note(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
target.ignore_pricing_rule = 1
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
def update_item(source, target, source_parent):
|
||||
target.base_amount = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.base_rate)
|
||||
target.amount = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.rate)
|
||||
@ -312,6 +314,7 @@ def make_delivery_note(source_name, target_doc=None):
|
||||
def make_sales_invoice(source_name, target_doc=None):
|
||||
def set_missing_values(source, target):
|
||||
target.is_pos = 0
|
||||
target.ignore_pricing_rule = 1
|
||||
target.run_method("set_missing_values")
|
||||
target.run_method("calculate_taxes_and_totals")
|
||||
|
||||
|
@ -12,7 +12,6 @@ from frappe.model.document import Document
|
||||
from erpnext.setup.doctype.sms_settings.sms_settings import send_sms
|
||||
|
||||
class SMSCenter(Document):
|
||||
|
||||
def create_receiver_list(self):
|
||||
rec, where_clause = '', ''
|
||||
if self.send_to == 'All Customer Contact':
|
||||
@ -71,6 +70,7 @@ class SMSCenter(Document):
|
||||
return receiver_nos
|
||||
|
||||
def send_sms(self):
|
||||
receiver_list = []
|
||||
if not self.message:
|
||||
msgprint(_("Please enter message before sending"))
|
||||
else:
|
||||
|
@ -481,7 +481,27 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
|
||||
set_dynamic_labels: function() {
|
||||
this._super();
|
||||
set_sales_bom_help(this.frm.doc);
|
||||
this.set_sales_bom_help(this.frm.doc);
|
||||
},
|
||||
|
||||
set_sales_bom_help: function(doc) {
|
||||
if(!cur_frm.fields_dict.packing_list) return;
|
||||
if ((doc.packing_details || []).length) {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
help_msg = "<div class='alert alert-warning'>" +
|
||||
__("For 'Sales BOM' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Sales BOM' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table.")+
|
||||
"</div>";
|
||||
frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
|
||||
}
|
||||
} else {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = '';
|
||||
}
|
||||
}
|
||||
refresh_field('sales_bom_help');
|
||||
},
|
||||
|
||||
change_form_labels: function(company_currency) {
|
||||
@ -574,26 +594,5 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
var df = frappe.meta.get_docfield(fname[0], fname[1], me.frm.doc.name);
|
||||
if(df) df.label = label;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Help for Sales BOM items
|
||||
var set_sales_bom_help = function(doc) {
|
||||
if(!cur_frm.fields_dict.packing_list) return;
|
||||
if ((doc.packing_details || []).length) {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
help_msg = "<div class='alert alert-warning'>" +
|
||||
__("For 'Sales BOM' items, warehouse, serial no and batch no will be considered from the 'Packing List' table. If warehouse and batch no are same for all packing items for any 'Sales BOM' item, those values can be entered in the main item table, values will be copied to 'Packing List' table.")+
|
||||
"</div>";
|
||||
frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
|
||||
}
|
||||
} else {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
frappe.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = '';
|
||||
}
|
||||
}
|
||||
refresh_field('sales_bom_help');
|
||||
}
|
||||
});
|
||||
|
@ -139,19 +139,10 @@ cur_frm.cscript.delete_doc = function(doctype, name) {
|
||||
var go_ahead = confirm(__("Delete {0} {1}?", [doctype, name]));
|
||||
if (!go_ahead) return;
|
||||
|
||||
return frappe.call({
|
||||
method: 'frappe.model.delete_doc',
|
||||
args: {
|
||||
dt: doctype,
|
||||
dn: name
|
||||
},
|
||||
callback: function(r) {
|
||||
//console.log(r);
|
||||
if (!r.exc) {
|
||||
// run the correct list
|
||||
var list_name = doctype.toLowerCase() + '_list';
|
||||
cur_frm[list_name].run();
|
||||
}
|
||||
frappe.model.delete_doc(doctype, name, function(r) {
|
||||
if (!r.exc) {
|
||||
var list_name = doctype.toLowerCase() + '_list';
|
||||
cur_frm[list_name].run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class NamingSeries(Document):
|
||||
'field_name': 'naming_series',
|
||||
'property': prop,
|
||||
'value': prop_dict[prop],
|
||||
'property_type': 'Select',
|
||||
'property_type': 'Text',
|
||||
'__islocal': 1
|
||||
})
|
||||
ps.save()
|
||||
|
@ -16,8 +16,7 @@ def validate_receiver_nos(receiver_list):
|
||||
validated_receiver_list = []
|
||||
for d in receiver_list:
|
||||
# remove invalid character
|
||||
invalid_char_list = [' ', '+', '-', '(', ')']
|
||||
for x in invalid_char_list:
|
||||
for x in [' ', '+', '-', '(', ')']:
|
||||
d = d.replace(x, '')
|
||||
|
||||
validated_receiver_list.append(d)
|
||||
@ -48,6 +47,13 @@ def get_contact_number(contact_name, value, key):
|
||||
|
||||
@frappe.whitelist()
|
||||
def send_sms(receiver_list, msg, sender_name = ''):
|
||||
|
||||
import json
|
||||
if isinstance(receiver_list, basestring):
|
||||
receiver_list = json.loads(receiver_list)
|
||||
if not isinstance(receiver_list, list):
|
||||
receiver_list = [receiver_list]
|
||||
|
||||
receiver_list = validate_receiver_nos(receiver_list)
|
||||
|
||||
arg = {
|
||||
|
@ -129,12 +129,13 @@
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Delivery Note",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
@ -275,6 +276,14 @@
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -999,7 +1008,7 @@
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:09.721622",
|
||||
"modified": "2014-06-23 07:55:47.859869",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note",
|
||||
@ -1073,6 +1082,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Customer"
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Material Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -280,6 +280,7 @@ def make_sales_invoice(source_name, target_doc=None):
|
||||
|
||||
def update_accounts(source, target):
|
||||
target.is_pos = 0
|
||||
target.ignore_pricing_rule = 1
|
||||
target.run_method("set_missing_values")
|
||||
|
||||
if len(target.get("entries")) == 0:
|
||||
|
@ -17,7 +17,7 @@ class TestItem(unittest.TestCase):
|
||||
item.is_stock_item = "Yes"
|
||||
item.default_warehouse = None
|
||||
self.assertRaises(WarehouseNotSet, item.insert)
|
||||
|
||||
|
||||
def test_get_item_details(self):
|
||||
from erpnext.stock.get_item_details import get_item_details
|
||||
to_check = {
|
||||
@ -41,23 +41,23 @@ class TestItem(unittest.TestCase):
|
||||
"uom": "_Test UOM",
|
||||
"conversion_factor": 1.0,
|
||||
}
|
||||
|
||||
|
||||
make_test_records("Item Price")
|
||||
|
||||
|
||||
details = get_item_details({
|
||||
"item_code": "_Test Item",
|
||||
"company": "_Test Company",
|
||||
"price_list": "_Test Price List",
|
||||
"currency": "_Test Currency",
|
||||
"doctype": "Sales Order",
|
||||
"parenttype": "Sales Order",
|
||||
"conversion_rate": 1,
|
||||
"price_list_currency": "_Test Currency",
|
||||
"plc_conversion_rate": 1,
|
||||
"order_type": "Sales",
|
||||
"transaction_type": "selling"
|
||||
})
|
||||
|
||||
|
||||
for key, value in to_check.iteritems():
|
||||
self.assertEquals(value, details.get(key))
|
||||
|
||||
test_records = frappe.get_test_records('Item')
|
||||
test_records = frappe.get_test_records('Item')
|
||||
|
@ -41,12 +41,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Material Request",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
@ -229,7 +230,7 @@
|
||||
"icon": "icon-ticket",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:13.642995",
|
||||
"modified": "2014-06-23 07:55:49.393708",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request",
|
||||
|
@ -195,6 +195,14 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "ignore_pricing_rule",
|
||||
"fieldtype": "Check",
|
||||
"label": "Ignore Pricing Rule",
|
||||
"no_copy": 1,
|
||||
"permlevel": 1,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
@ -516,7 +524,7 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
@ -754,7 +762,7 @@
|
||||
"icon": "icon-truck",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:16.302198",
|
||||
"modified": "2014-06-23 07:55:50.761516",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt",
|
||||
@ -821,6 +829,12 @@
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Supplier"
|
||||
},
|
||||
{
|
||||
"permlevel": 1,
|
||||
"read": 1,
|
||||
"role": "Material Manager",
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only_onload": 1,
|
||||
|
@ -287,6 +287,7 @@ def make_purchase_invoice(source_name, target_doc=None):
|
||||
frappe.throw(_("All items have already been invoiced"))
|
||||
|
||||
doc = frappe.get_doc(target)
|
||||
doc.ignore_pricing_rule = 1
|
||||
doc.run_method("set_missing_values")
|
||||
doc.run_method("calculate_taxes_and_totals")
|
||||
|
||||
|
@ -17,4 +17,10 @@ cur_frm.cscript.onload = function() {
|
||||
|
||||
frappe.ui.form.on("Serial No", "refresh", function(frm) {
|
||||
frm.toggle_enable("item_code", frm.doc.__islocal);
|
||||
|
||||
if(frm.doc.status == "Sales Returned" && frm.doc.warehouse)
|
||||
cur_frm.add_custom_button(__('Set Status as Available'), function() {
|
||||
cur_frm.set_value("status", "Available");
|
||||
cur_frm.save();
|
||||
});
|
||||
});
|
||||
|
@ -220,8 +220,8 @@ class StockEntry(StockController):
|
||||
# get incoming rate
|
||||
if not d.bom_no:
|
||||
if not flt(d.incoming_rate) or d.s_warehouse or self.purpose == "Sales Return":
|
||||
incoming_rate = self.get_incoming_rate(args)
|
||||
if flt(incoming_rate) > 0:
|
||||
incoming_rate = flt(self.get_incoming_rate(args), self.precision("incoming_rate", d))
|
||||
if incoming_rate > 0:
|
||||
d.incoming_rate = incoming_rate
|
||||
|
||||
d.amount = flt(d.transfer_qty) * flt(d.incoming_rate)
|
||||
|
@ -91,11 +91,12 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_type",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher Type",
|
||||
"oldfieldname": "voucher_type",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
@ -104,11 +105,12 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "voucher_no",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"in_filter": 1,
|
||||
"label": "Voucher No",
|
||||
"oldfieldname": "voucher_no",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "voucher_type",
|
||||
"permlevel": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
@ -264,7 +266,7 @@
|
||||
"icon": "icon-list",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"modified": "2014-06-09 01:51:44.014466",
|
||||
"modified": "2014-06-23 08:07:56.370276",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Ledger Entry",
|
||||
|
@ -6,8 +6,7 @@ import frappe
|
||||
from frappe import _, throw
|
||||
from frappe.utils import flt, cint, add_days
|
||||
import json
|
||||
|
||||
class MultiplePricingRuleConflict(frappe.ValidationError): pass
|
||||
from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_for_item
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_details(args):
|
||||
@ -20,14 +19,15 @@ def get_item_details(args):
|
||||
"selling_price_list": None,
|
||||
"price_list_currency": None,
|
||||
"plc_conversion_rate": 1.0,
|
||||
"doctype": "",
|
||||
"docname": "",
|
||||
"parenttype": "",
|
||||
"parent": "",
|
||||
"supplier": None,
|
||||
"transaction_date": None,
|
||||
"conversion_rate": 1.0,
|
||||
"buying_price_list": None,
|
||||
"is_subcontracted": "Yes" / "No",
|
||||
"transaction_type": "selling"
|
||||
"transaction_type": "selling",
|
||||
"ignore_pricing_rule": 0/1
|
||||
}
|
||||
"""
|
||||
|
||||
@ -37,7 +37,8 @@ def get_item_details(args):
|
||||
args = frappe._dict(args)
|
||||
|
||||
if not args.get("transaction_type"):
|
||||
if args.get("doctype")=="Material Request" or frappe.get_meta(args.get("doctype")).get_field("supplier"):
|
||||
if args.get("parenttype")=="Material Request" or \
|
||||
frappe.get_meta(args.get("parenttype")).get_field("supplier"):
|
||||
args.transaction_type = "buying"
|
||||
else:
|
||||
args.transaction_type = "selling"
|
||||
@ -73,9 +74,9 @@ def get_item_details(args):
|
||||
if args.get(key) is None:
|
||||
args[key] = value
|
||||
|
||||
out.update(apply_pricing_rule(args))
|
||||
out.update(get_pricing_rule_for_item(args))
|
||||
|
||||
if args.get("doctype") in ("Sales Invoice", "Delivery Note"):
|
||||
if args.get("parenttype") in ("Sales Invoice", "Delivery Note"):
|
||||
if item_doc.has_serial_no == "Yes" and not args.serial_no:
|
||||
out.serial_no = get_serial_nos_by_fifo(args, item_doc)
|
||||
|
||||
@ -113,7 +114,7 @@ def validate_item_details(args, item):
|
||||
elif item.is_sales_item != "Yes":
|
||||
throw(_("Item {0} must be a Sales Item").format(item.name))
|
||||
|
||||
elif args.transaction_type == "buying" and args.doctype != "Material Request":
|
||||
elif args.transaction_type == "buying" and args.parenttype != "Material Request":
|
||||
# validate if purchase item or subcontracted item
|
||||
if item.is_purchase_item != "Yes":
|
||||
throw(_("Item {0} must be a Purchase Item").format(item.name))
|
||||
@ -144,7 +145,7 @@ def get_basic_details(args, item_doc):
|
||||
"item_tax_rate": json.dumps(dict(([d.tax_type, d.tax_rate] for d in
|
||||
item_doc.get("item_tax")))),
|
||||
"uom": item.stock_uom,
|
||||
"min_order_qty": flt(item.min_order_qty) if args.doctype == "Material Request" else "",
|
||||
"min_order_qty": flt(item.min_order_qty) if args.parenttype == "Material Request" else "",
|
||||
"conversion_factor": 1.0,
|
||||
"qty": 1.0,
|
||||
"price_list_rate": 0.0,
|
||||
@ -162,7 +163,7 @@ def get_basic_details(args, item_doc):
|
||||
return out
|
||||
|
||||
def get_price_list_rate(args, item_doc, out):
|
||||
meta = frappe.get_meta(args.doctype)
|
||||
meta = frappe.get_meta(args.parenttype)
|
||||
|
||||
if meta.get_field("currency"):
|
||||
validate_price_list(args)
|
||||
@ -179,7 +180,7 @@ def get_price_list_rate(args, item_doc, out):
|
||||
if not out.price_list_rate and args.transaction_type == "buying":
|
||||
from erpnext.stock.doctype.item.item import get_last_purchase_details
|
||||
out.update(get_last_purchase_details(item_doc.name,
|
||||
args.docname, args.conversion_rate))
|
||||
args.parent, args.conversion_rate))
|
||||
|
||||
def validate_price_list(args):
|
||||
if args.get("price_list"):
|
||||
@ -248,142 +249,6 @@ def get_pos_settings(company):
|
||||
|
||||
return pos_settings and pos_settings[0] or None
|
||||
|
||||
@frappe.whitelist()
|
||||
def apply_pricing_rule(args):
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
args = frappe._dict(args)
|
||||
out = frappe._dict()
|
||||
if args.get("doctype") == "Material Request" or not args.get("item_code"): return out
|
||||
|
||||
if not args.get("item_group") or not args.get("brand"):
|
||||
args.item_group, args.brand = frappe.db.get_value("Item",
|
||||
args.item_code, ["item_group", "brand"])
|
||||
|
||||
if args.get("customer") and (not args.get("customer_group") or not args.get("territory")):
|
||||
args.customer_group, args.territory = frappe.db.get_value("Customer",
|
||||
args.customer, ["customer_group", "territory"])
|
||||
|
||||
if args.get("supplier") and not args.get("supplier_type"):
|
||||
args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type")
|
||||
|
||||
pricing_rules = get_pricing_rules(args)
|
||||
|
||||
pricing_rule = filter_pricing_rules(args, pricing_rules)
|
||||
|
||||
if pricing_rule:
|
||||
out.pricing_rule = pricing_rule.name
|
||||
if pricing_rule.price_or_discount == "Price":
|
||||
out.base_price_list_rate = pricing_rule.price
|
||||
out.price_list_rate = pricing_rule.price*flt(args.plc_conversion_rate)/flt(args.conversion_rate)
|
||||
out.base_rate = out.base_price_list_rate
|
||||
out.rate = out.price_list_rate
|
||||
out.discount_percentage = 0.0
|
||||
else:
|
||||
out.discount_percentage = pricing_rule.discount_percentage
|
||||
else:
|
||||
out.pricing_rule = None
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def get_pricing_rules(args):
|
||||
def _get_tree_conditions(doctype, allow_blank=True):
|
||||
field = frappe.scrub(doctype)
|
||||
condition = ""
|
||||
if args.get(field):
|
||||
lft, rgt = frappe.db.get_value(doctype, args[field], ["lft", "rgt"])
|
||||
parent_groups = frappe.db.sql_list("""select name from `tab%s`
|
||||
where lft<=%s and rgt>=%s""" % (doctype, '%s', '%s'), (lft, rgt))
|
||||
|
||||
if parent_groups:
|
||||
if allow_blank: parent_groups.append('')
|
||||
condition = " ifnull("+field+", '') in ('" + "', '".join(parent_groups)+"')"
|
||||
|
||||
return condition
|
||||
|
||||
|
||||
conditions = ""
|
||||
for field in ["company", "customer", "supplier", "supplier_type", "campaign", "sales_partner"]:
|
||||
if args.get(field):
|
||||
conditions += " and ifnull("+field+", '') in (%("+field+")s, '')"
|
||||
else:
|
||||
conditions += " and ifnull("+field+", '') = ''"
|
||||
|
||||
for doctype in ["Customer Group", "Territory"]:
|
||||
group_condition = _get_tree_conditions(doctype)
|
||||
if group_condition:
|
||||
conditions += " and " + group_condition
|
||||
|
||||
conditions += " and ifnull(for_price_list, '') in (%(price_list)s, '')"
|
||||
|
||||
if args.get("transaction_date"):
|
||||
conditions += """ and %(transaction_date)s between ifnull(valid_from, '2000-01-01')
|
||||
and ifnull(valid_upto, '2500-12-31')"""
|
||||
|
||||
return frappe.db.sql("""select * from `tabPricing Rule`
|
||||
where (item_code=%(item_code)s or {item_group_condition} or brand=%(brand)s)
|
||||
and docstatus < 2 and ifnull(disable, 0) = 0 {conditions}
|
||||
order by priority desc, name desc""".format(
|
||||
item_group_condition=_get_tree_conditions("Item Group", False), conditions=conditions),
|
||||
args, as_dict=1)
|
||||
|
||||
def filter_pricing_rules(args, pricing_rules):
|
||||
# filter for qty
|
||||
if pricing_rules and args.get("qty"):
|
||||
pricing_rules = filter(lambda x: (args.qty>=flt(x.min_qty)
|
||||
and (args.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
|
||||
# find pricing rule with highest priority
|
||||
if pricing_rules:
|
||||
max_priority = max([cint(p.priority) for p in pricing_rules])
|
||||
if max_priority:
|
||||
pricing_rules = filter(lambda x: cint(x.priority)==max_priority, pricing_rules)
|
||||
|
||||
# apply internal priority
|
||||
all_fields = ["item_code", "item_group", "brand", "customer", "customer_group", "territory",
|
||||
"supplier", "supplier_type", "campaign", "sales_partner"]
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
for field_set in [["item_code", "item_group", "brand"],
|
||||
["customer", "customer_group", "territory"], ["supplier", "supplier_type"]]:
|
||||
remaining_fields = list(set(all_fields) - set(field_set))
|
||||
if if_all_rules_same(pricing_rules, remaining_fields):
|
||||
pricing_rules = apply_internal_priority(pricing_rules, field_set, args)
|
||||
break
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
price_or_discount = list(set([d.price_or_discount for d in pricing_rules]))
|
||||
if len(price_or_discount) == 1 and price_or_discount[0] == "Discount Percentage":
|
||||
pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
|
||||
or pricing_rules
|
||||
|
||||
if len(pricing_rules) > 1:
|
||||
frappe.throw(_("Multiple Price Rule exists with same criteria, please resolve \
|
||||
conflict by assigning priority. Price Rules: {0}")
|
||||
.format("\n".join([d.name for d in pricing_rules])), MultiplePricingRuleConflict)
|
||||
elif pricing_rules:
|
||||
return pricing_rules[0]
|
||||
|
||||
def if_all_rules_same(pricing_rules, fields):
|
||||
all_rules_same = True
|
||||
val = [pricing_rules[0][k] for k in fields]
|
||||
for p in pricing_rules[1:]:
|
||||
if val != [p[k] for k in fields]:
|
||||
all_rules_same = False
|
||||
break
|
||||
|
||||
return all_rules_same
|
||||
|
||||
def apply_internal_priority(pricing_rules, field_set, args):
|
||||
filtered_rules = []
|
||||
for field in field_set:
|
||||
if args.get(field):
|
||||
filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
|
||||
if filtered_rules: break
|
||||
|
||||
return filtered_rules or pricing_rules
|
||||
|
||||
def get_serial_nos_by_fifo(args, item_doc):
|
||||
return "\n".join(frappe.db.sql_list("""select name from `tabSerial No`
|
||||
|
@ -379,13 +379,14 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Customer Issue",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"width": "150px"
|
||||
@ -394,7 +395,7 @@
|
||||
"icon": "icon-bug",
|
||||
"idx": 1,
|
||||
"is_submittable": 0,
|
||||
"modified": "2014-05-27 03:49:09.483145",
|
||||
"modified": "2014-06-23 07:55:47.488335",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Support",
|
||||
"name": "Customer Issue",
|
||||
|
@ -190,12 +190,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Maintenance Visit",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
@ -278,7 +279,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-05-27 03:49:13.466221",
|
||||
"modified": "2014-06-23 07:55:49.200714",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Support",
|
||||
"name": "Maintenance Visit",
|
||||
|
Loading…
x
Reference in New Issue
Block a user