Merge branch 'develop' into naming-series-proj
This commit is contained in:
commit
06f522cb27
@ -23,7 +23,7 @@
|
|||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"label": "Reports",
|
"label": "Reports",
|
||||||
"links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n }\n]"
|
"links": "[\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"Trial Balance for Party\",\n \"name\": \"Trial Balance for Party\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Journal Entry\"\n ],\n \"doctype\": \"Journal Entry\",\n \"is_query_report\": true,\n \"label\": \"Payment Period Based On Invoice Date\",\n \"name\": \"Payment Period Based On Invoice Date\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Partners Commission\",\n \"name\": \"Sales Partners Commission\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Customer\"\n ],\n \"doctype\": \"Customer\",\n \"is_query_report\": true,\n \"label\": \"Customer Credit Balance\",\n \"name\": \"Customer Credit Balance\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Sales Invoice\"\n ],\n \"doctype\": \"Sales Invoice\",\n \"is_query_report\": true,\n \"label\": \"Sales Payment Summary\",\n \"name\": \"Sales Payment Summary\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"Address\"\n ],\n \"doctype\": \"Address\",\n \"is_query_report\": true,\n \"label\": \"Address And Contacts\",\n \"name\": \"Address And Contacts\",\n \"type\": \"report\"\n },\n {\n \"dependencies\": [\n \"GL Entry\"\n ],\n \"doctype\": \"GL Entry\",\n \"is_query_report\": true,\n \"label\": \"DATEV Export\",\n \"name\": \"DATEV\",\n \"type\": \"report\"\n }\n]"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
@ -98,7 +98,7 @@
|
|||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"label": "Accounting",
|
"label": "Accounting",
|
||||||
"modified": "2020-11-06 13:05:58.650150",
|
"modified": "2020-11-11 18:35:11.542909",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounting",
|
"name": "Accounting",
|
||||||
|
@ -9,11 +9,7 @@ frappe.ui.form.on('Fiscal Year', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
refresh: function (frm) {
|
refresh: function (frm) {
|
||||||
let doc = frm.doc;
|
if (!frm.doc.__islocal && (frm.doc.name != frappe.sys_defaults.fiscal_year)) {
|
||||||
frm.toggle_enable('year_start_date', doc.__islocal);
|
|
||||||
frm.toggle_enable('year_end_date', doc.__islocal);
|
|
||||||
|
|
||||||
if (!doc.__islocal && (doc.name != frappe.sys_defaults.fiscal_year)) {
|
|
||||||
frm.add_custom_button(__("Set as Default"), () => frm.events.set_as_default(frm));
|
frm.add_custom_button(__("Set as Default"), () => frm.events.set_as_default(frm));
|
||||||
frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'"));
|
frm.set_intro(__("To set this Fiscal Year as Default, click on 'Set as Default'"));
|
||||||
} else {
|
} else {
|
||||||
@ -24,8 +20,10 @@ frappe.ui.form.on('Fiscal Year', {
|
|||||||
return frm.call('set_as_default');
|
return frm.call('set_as_default');
|
||||||
},
|
},
|
||||||
year_start_date: function(frm) {
|
year_start_date: function(frm) {
|
||||||
let year_end_date =
|
if (!frm.doc.is_short_year) {
|
||||||
frappe.datetime.add_days(frappe.datetime.add_months(frm.doc.year_start_date, 12), -1);
|
let year_end_date =
|
||||||
frm.set_value("year_end_date", year_end_date);
|
frappe.datetime.add_days(frappe.datetime.add_months(frm.doc.year_start_date, 12), -1);
|
||||||
|
frm.set_value("year_end_date", year_end_date);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,347 +1,126 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"actions": [],
|
||||||
"allow_guest_to_view": 0,
|
"allow_import": 1,
|
||||||
"allow_import": 1,
|
"autoname": "field:year",
|
||||||
"allow_rename": 0,
|
"creation": "2013-01-22 16:50:25",
|
||||||
"autoname": "field:year",
|
"description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.",
|
||||||
"beta": 0,
|
"doctype": "DocType",
|
||||||
"creation": "2013-01-22 16:50:25",
|
"document_type": "Setup",
|
||||||
"custom": 0,
|
"engine": "InnoDB",
|
||||||
"description": "**Fiscal Year** represents a Financial Year. All accounting entries and other major transactions are tracked against **Fiscal Year**.",
|
"field_order": [
|
||||||
"docstatus": 0,
|
"year",
|
||||||
"doctype": "DocType",
|
"disabled",
|
||||||
"document_type": "Setup",
|
"is_short_year",
|
||||||
"editable_grid": 0,
|
"year_start_date",
|
||||||
|
"year_end_date",
|
||||||
|
"companies",
|
||||||
|
"auto_created"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "For e.g. 2012, 2012-13",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "year",
|
||||||
"bold": 0,
|
"fieldtype": "Data",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Year Name",
|
||||||
"description": "For e.g. 2012, 2012-13",
|
"oldfieldname": "year",
|
||||||
"fieldname": "year",
|
"oldfieldtype": "Data",
|
||||||
"fieldtype": "Data",
|
"reqd": 1,
|
||||||
"hidden": 0,
|
"unique": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Year Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "year",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "disabled",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"label": "Disabled"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "disabled",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Disabled",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "year_start_date",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Date",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Year Start Date",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"fieldname": "year_start_date",
|
"oldfieldname": "year_start_date",
|
||||||
"fieldtype": "Date",
|
"oldfieldtype": "Date",
|
||||||
"hidden": 0,
|
"reqd": 1,
|
||||||
"ignore_user_permissions": 0,
|
"set_only_once": 1
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Year Start Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"oldfieldname": "year_start_date",
|
|
||||||
"oldfieldtype": "Date",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "year_end_date",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Date",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Year End Date",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"fieldname": "year_end_date",
|
"reqd": 1,
|
||||||
"fieldtype": "Date",
|
"set_only_once": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Year End Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "companies",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Table",
|
||||||
"bold": 0,
|
"label": "Companies",
|
||||||
"collapsible": 0,
|
"options": "Fiscal Year Company"
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "companies",
|
|
||||||
"fieldtype": "Table",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Companies",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Fiscal Year Company",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "auto_created",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"hidden": 1,
|
||||||
"columns": 0,
|
"label": "Auto Created",
|
||||||
"default": "0",
|
"no_copy": 1,
|
||||||
"fieldname": "auto_created",
|
"print_hide": 1,
|
||||||
"fieldtype": "Check",
|
"read_only": 1
|
||||||
"hidden": 1,
|
},
|
||||||
"ignore_user_permissions": 0,
|
{
|
||||||
"ignore_xss_filter": 0,
|
"default": "0",
|
||||||
"in_filter": 0,
|
"description": "Less than 12 months.",
|
||||||
"in_global_search": 0,
|
"fieldname": "is_short_year",
|
||||||
"in_list_view": 0,
|
"fieldtype": "Check",
|
||||||
"in_standard_filter": 0,
|
"label": "Is Short Year",
|
||||||
"label": "Auto Created",
|
"set_only_once": 1
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"icon": "fa fa-calendar",
|
||||||
"hide_heading": 0,
|
"idx": 1,
|
||||||
"hide_toolbar": 0,
|
"links": [],
|
||||||
"icon": "fa fa-calendar",
|
"modified": "2020-11-05 12:16:53.081573",
|
||||||
"idx": 1,
|
"modified_by": "Administrator",
|
||||||
"image_view": 0,
|
"module": "Accounts",
|
||||||
"in_create": 0,
|
"name": "Fiscal Year",
|
||||||
"is_submittable": 0,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-04-25 14:21:41.273354",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Fiscal Year",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"create": 1,
|
||||||
"cancel": 0,
|
"delete": 1,
|
||||||
"create": 1,
|
"email": 1,
|
||||||
"delete": 1,
|
"print": 1,
|
||||||
"email": 1,
|
"read": 1,
|
||||||
"export": 0,
|
"report": 1,
|
||||||
"if_owner": 0,
|
"role": "System Manager",
|
||||||
"import": 0,
|
"share": 1,
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"read": 1,
|
||||||
"cancel": 0,
|
"role": "Sales User"
|
||||||
"create": 0,
|
},
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "Sales User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"read": 1,
|
||||||
"cancel": 0,
|
"role": "Purchase User"
|
||||||
"create": 0,
|
},
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "Purchase User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"read": 1,
|
||||||
"cancel": 0,
|
"role": "Accounts User"
|
||||||
"create": 0,
|
},
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "Accounts User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"read": 1,
|
||||||
"cancel": 0,
|
"role": "Stock User"
|
||||||
"create": 0,
|
},
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "Stock User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"read": 1,
|
||||||
"cancel": 0,
|
"role": "Employee"
|
||||||
"create": 0,
|
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "Employee",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 0,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"show_name_in_global_search": 1,
|
||||||
"read_only": 0,
|
"sort_field": "name",
|
||||||
"read_only_onload": 0,
|
"sort_order": "DESC"
|
||||||
"show_name_in_global_search": 1,
|
|
||||||
"sort_field": "name",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -36,6 +36,11 @@ class FiscalYear(Document):
|
|||||||
frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved."))
|
frappe.throw(_("Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved."))
|
||||||
|
|
||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
|
if self.is_short_year:
|
||||||
|
# Fiscal Year can be shorter than one year, in some jurisdictions
|
||||||
|
# under certain circumstances. For example, in the USA and Germany.
|
||||||
|
return
|
||||||
|
|
||||||
if getdate(self.year_start_date) > getdate(self.year_end_date):
|
if getdate(self.year_start_date) > getdate(self.year_end_date):
|
||||||
frappe.throw(_("Fiscal Year Start Date should be one year earlier than Fiscal Year End Date"),
|
frappe.throw(_("Fiscal Year Start Date should be one year earlier than Fiscal Year End Date"),
|
||||||
FiscalYearIncorrectDate)
|
FiscalYearIncorrectDate)
|
||||||
@ -116,12 +121,8 @@ def auto_create_fiscal_year():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def get_from_and_to_date(fiscal_year):
|
def get_from_and_to_date(fiscal_year):
|
||||||
from_and_to_date_tuple = frappe.db.sql("""select year_start_date, year_end_date
|
fields = [
|
||||||
from `tabFiscal Year` where name=%s""", (fiscal_year))[0]
|
"year_start_date as from_date",
|
||||||
|
"year_end_date as to_date"
|
||||||
from_and_to_date = {
|
]
|
||||||
"from_date": from_and_to_date_tuple[0],
|
return frappe.db.get_value("Fiscal Year", fiscal_year, fields, as_dict=1)
|
||||||
"to_date": from_and_to_date_tuple[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return from_and_to_date
|
|
||||||
|
@ -11,6 +11,7 @@ test_records = frappe.get_test_records('Fiscal Year')
|
|||||||
test_ignore = ["Company"]
|
test_ignore = ["Company"]
|
||||||
|
|
||||||
class TestFiscalYear(unittest.TestCase):
|
class TestFiscalYear(unittest.TestCase):
|
||||||
|
|
||||||
def test_extra_year(self):
|
def test_extra_year(self):
|
||||||
if frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2000"):
|
if frappe.db.exists("Fiscal Year", "_Test Fiscal Year 2000"):
|
||||||
frappe.delete_doc("Fiscal Year", "_Test Fiscal Year 2000")
|
frappe.delete_doc("Fiscal Year", "_Test Fiscal Year 2000")
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"doctype": "Fiscal Year",
|
||||||
|
"year": "_Test Short Fiscal Year 2011",
|
||||||
|
"is_short_year": 1,
|
||||||
|
"year_end_date": "2011-04-01",
|
||||||
|
"year_start_date": "2011-12-31"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Fiscal Year",
|
"doctype": "Fiscal Year",
|
||||||
"year": "_Test Fiscal Year 2012",
|
"year": "_Test Fiscal Year 2012",
|
||||||
|
@ -352,8 +352,14 @@ def apply_price_discount_rule(pricing_rule, item_details, args):
|
|||||||
pricing_rule_rate = 0.0
|
pricing_rule_rate = 0.0
|
||||||
if pricing_rule.currency == args.currency:
|
if pricing_rule.currency == args.currency:
|
||||||
pricing_rule_rate = pricing_rule.rate
|
pricing_rule_rate = pricing_rule.rate
|
||||||
|
|
||||||
|
if pricing_rule_rate:
|
||||||
|
# Override already set price list rate (from item price)
|
||||||
|
# if pricing_rule_rate > 0
|
||||||
|
item_details.update({
|
||||||
|
"price_list_rate": pricing_rule_rate * args.get("conversion_factor", 1),
|
||||||
|
})
|
||||||
item_details.update({
|
item_details.update({
|
||||||
"price_list_rate": pricing_rule_rate * args.get("conversion_factor", 1),
|
|
||||||
"discount_percentage": 0.0
|
"discount_percentage": 0.0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -484,6 +484,43 @@ class TestPricingRule(unittest.TestCase):
|
|||||||
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
|
||||||
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
|
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
|
||||||
|
|
||||||
|
def test_item_price_with_pricing_rule(self):
|
||||||
|
item = make_item("Water Flask")
|
||||||
|
make_item_price("Water Flask", "_Test Price List", 100)
|
||||||
|
|
||||||
|
pricing_rule_record = {
|
||||||
|
"doctype": "Pricing Rule",
|
||||||
|
"title": "_Test Water Flask Rule",
|
||||||
|
"apply_on": "Item Code",
|
||||||
|
"items": [{
|
||||||
|
"item_code": "Water Flask",
|
||||||
|
}],
|
||||||
|
"selling": 1,
|
||||||
|
"currency": "INR",
|
||||||
|
"rate_or_discount": "Rate",
|
||||||
|
"rate": 0,
|
||||||
|
"margin_type": "Percentage",
|
||||||
|
"margin_rate_or_amount": 2,
|
||||||
|
"company": "_Test Company"
|
||||||
|
}
|
||||||
|
rule = frappe.get_doc(pricing_rule_record)
|
||||||
|
rule.insert()
|
||||||
|
|
||||||
|
si = create_sales_invoice(do_not_save=True, item_code="Water Flask")
|
||||||
|
si.selling_price_list = "_Test Price List"
|
||||||
|
si.save()
|
||||||
|
|
||||||
|
# If rate in Rule is 0, give preference to Item Price if it exists
|
||||||
|
self.assertEqual(si.items[0].price_list_rate, 100)
|
||||||
|
self.assertEqual(si.items[0].margin_rate_or_amount, 2)
|
||||||
|
self.assertEqual(si.items[0].rate_with_margin, 102)
|
||||||
|
self.assertEqual(si.items[0].rate, 102)
|
||||||
|
|
||||||
|
si.delete()
|
||||||
|
rule.delete()
|
||||||
|
frappe.get_doc("Item Price", {"item_code": "Water Flask"}).delete()
|
||||||
|
item.delete()
|
||||||
|
|
||||||
def make_pricing_rule(**args):
|
def make_pricing_rule(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
@ -90,6 +90,11 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
this.frm.set_df_property("drop_ship", "hidden", !is_drop_ship);
|
this.frm.set_df_property("drop_ship", "hidden", !is_drop_ship);
|
||||||
|
|
||||||
if(doc.docstatus == 1) {
|
if(doc.docstatus == 1) {
|
||||||
|
this.frm.fields_dict.items_section.wrapper.addClass("hide-border");
|
||||||
|
if(!this.frm.doc.set_warehouse) {
|
||||||
|
this.frm.fields_dict.items_section.wrapper.removeClass("hide-border");
|
||||||
|
}
|
||||||
|
|
||||||
if(!in_list(["Closed", "Delivered"], doc.status)) {
|
if(!in_list(["Closed", "Delivered"], doc.status)) {
|
||||||
if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received) < 100 && flt(this.frm.doc.per_billed) < 100) {
|
if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received) < 100 && flt(this.frm.doc.per_billed) < 100) {
|
||||||
this.frm.add_custom_button(__('Update Items'), () => {
|
this.frm.add_custom_button(__('Update Items'), () => {
|
||||||
@ -126,16 +131,25 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
if(doc.status != "Closed") {
|
if(doc.status != "Closed") {
|
||||||
if (doc.status != "On Hold") {
|
if (doc.status != "On Hold") {
|
||||||
if(flt(doc.per_received) < 100 && allow_receipt) {
|
if(flt(doc.per_received) < 100 && allow_receipt) {
|
||||||
cur_frm.add_custom_button(__('Receipt'), this.make_purchase_receipt, __('Create'));
|
cur_frm.add_custom_button(__('Purchase Receipt'), this.make_purchase_receipt, __('Create'));
|
||||||
if(doc.is_subcontracted==="Yes" && me.has_unsupplied_items()) {
|
if(doc.is_subcontracted==="Yes" && me.has_unsupplied_items()) {
|
||||||
cur_frm.add_custom_button(__('Material to Supplier'),
|
cur_frm.add_custom_button(__('Material to Supplier'),
|
||||||
function() { me.make_stock_entry(); }, __("Transfer"));
|
function() { me.make_stock_entry(); }, __("Transfer"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(flt(doc.per_billed) < 100)
|
if(flt(doc.per_billed) < 100)
|
||||||
cur_frm.add_custom_button(__('Invoice'),
|
cur_frm.add_custom_button(__('Purchase Invoice'),
|
||||||
this.make_purchase_invoice, __('Create'));
|
this.make_purchase_invoice, __('Create'));
|
||||||
|
|
||||||
|
if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
|
||||||
|
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __('Create'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flt(doc.per_billed)==0) {
|
||||||
|
this.frm.add_custom_button(__('Payment Request'),
|
||||||
|
function() { me.make_payment_request() }, __('Create'));
|
||||||
|
}
|
||||||
|
|
||||||
if(!doc.auto_repeat) {
|
if(!doc.auto_repeat) {
|
||||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||||
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
||||||
@ -156,13 +170,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(flt(doc.per_billed)==0) {
|
|
||||||
this.frm.add_custom_button(__('Payment Request'),
|
|
||||||
function() { me.make_payment_request() }, __('Create'));
|
|
||||||
}
|
|
||||||
if(flt(doc.per_billed)==0 && doc.status != "Delivered") {
|
|
||||||
cur_frm.add_custom_button(__('Payment'), cur_frm.cscript.make_payment_entry, __('Create'));
|
|
||||||
}
|
|
||||||
cur_frm.page.set_inner_btn_group_as_primary(__('Create'));
|
cur_frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||||
}
|
}
|
||||||
} else if(doc.docstatus===0) {
|
} else if(doc.docstatus===0) {
|
||||||
@ -358,12 +366,16 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
|
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
|
||||||
source_doctype: "Material Request",
|
source_doctype: "Material Request",
|
||||||
target: me.frm,
|
target: me.frm,
|
||||||
setters: {},
|
setters: {
|
||||||
|
schedule_date: undefined,
|
||||||
|
status: undefined
|
||||||
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
material_request_type: "Purchase",
|
material_request_type: "Purchase",
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
status: ["!=", "Stopped"],
|
status: ["!=", "Stopped"],
|
||||||
per_ordered: ["<", 99.99],
|
per_ordered: ["<", 99.99],
|
||||||
|
company: me.frm.doc.company
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, __("Get Items From"));
|
}, __("Get Items From"));
|
||||||
@ -375,16 +387,17 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
|||||||
source_doctype: "Supplier Quotation",
|
source_doctype: "Supplier Quotation",
|
||||||
target: me.frm,
|
target: me.frm,
|
||||||
setters: {
|
setters: {
|
||||||
supplier: me.frm.doc.supplier
|
supplier: me.frm.doc.supplier,
|
||||||
|
valid_till: undefined
|
||||||
},
|
},
|
||||||
get_query_filters: {
|
get_query_filters: {
|
||||||
docstatus: 1,
|
docstatus: 1,
|
||||||
status: ["!=", "Stopped"],
|
status: ["not in", ["Stopped", "Expired"]],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, __("Get Items From"));
|
}, __("Get Items From"));
|
||||||
|
|
||||||
this.frm.add_custom_button(__('Update rate as per last purchase'),
|
this.frm.add_custom_button(__('Update Rate as per Last Purchase'),
|
||||||
function() {
|
function() {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
"method": "get_last_purchase_rate",
|
"method": "get_last_purchase_rate",
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
"customer_contact_email",
|
"customer_contact_email",
|
||||||
"section_addresses",
|
"section_addresses",
|
||||||
"supplier_address",
|
"supplier_address",
|
||||||
"contact_person",
|
|
||||||
"address_display",
|
"address_display",
|
||||||
|
"contact_person",
|
||||||
"contact_display",
|
"contact_display",
|
||||||
"contact_mobile",
|
"contact_mobile",
|
||||||
"contact_email",
|
"contact_email",
|
||||||
@ -49,12 +49,14 @@
|
|||||||
"plc_conversion_rate",
|
"plc_conversion_rate",
|
||||||
"ignore_pricing_rule",
|
"ignore_pricing_rule",
|
||||||
"sec_warehouse",
|
"sec_warehouse",
|
||||||
"set_warehouse",
|
|
||||||
"col_break_warehouse",
|
|
||||||
"is_subcontracted",
|
"is_subcontracted",
|
||||||
|
"col_break_warehouse",
|
||||||
"supplier_warehouse",
|
"supplier_warehouse",
|
||||||
"items_section",
|
"before_items_section",
|
||||||
"scan_barcode",
|
"scan_barcode",
|
||||||
|
"items_col_break",
|
||||||
|
"set_warehouse",
|
||||||
|
"items_section",
|
||||||
"items",
|
"items",
|
||||||
"sb_last_purchase",
|
"sb_last_purchase",
|
||||||
"total_qty",
|
"total_qty",
|
||||||
@ -108,18 +110,13 @@
|
|||||||
"payment_terms_template",
|
"payment_terms_template",
|
||||||
"payment_schedule",
|
"payment_schedule",
|
||||||
"tracking_section",
|
"tracking_section",
|
||||||
"per_billed",
|
"status",
|
||||||
"column_break_75",
|
"column_break_75",
|
||||||
|
"per_billed",
|
||||||
"per_received",
|
"per_received",
|
||||||
"terms_section_break",
|
"terms_section_break",
|
||||||
"tc_name",
|
"tc_name",
|
||||||
"terms",
|
"terms",
|
||||||
"more_info",
|
|
||||||
"status",
|
|
||||||
"ref_sq",
|
|
||||||
"column_break_74",
|
|
||||||
"party_account_currency",
|
|
||||||
"inter_company_order_reference",
|
|
||||||
"column_break5",
|
"column_break5",
|
||||||
"letter_head",
|
"letter_head",
|
||||||
"select_print_heading",
|
"select_print_heading",
|
||||||
@ -131,7 +128,12 @@
|
|||||||
"to_date",
|
"to_date",
|
||||||
"column_break_97",
|
"column_break_97",
|
||||||
"auto_repeat",
|
"auto_repeat",
|
||||||
"update_auto_repeat_reference"
|
"update_auto_repeat_reference",
|
||||||
|
"more_info",
|
||||||
|
"ref_sq",
|
||||||
|
"column_break_74",
|
||||||
|
"party_account_currency",
|
||||||
|
"inter_company_order_reference"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -313,34 +315,34 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "supplier_address",
|
"fieldname": "supplier_address",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Select Supplier Address",
|
"label": "Supplier Address",
|
||||||
"options": "Address",
|
"options": "Address",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "contact_person",
|
"fieldname": "contact_person",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Contact Person",
|
"label": "Supplier Contact",
|
||||||
"options": "Contact",
|
"options": "Contact",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "address_display",
|
"fieldname": "address_display",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Address",
|
"label": "Supplier Address Details",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "contact_display",
|
"fieldname": "contact_display",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"label": "Contact",
|
"label": "Contact Name",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "contact_mobile",
|
"fieldname": "contact_mobile",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Mobile No",
|
"label": "Contact Mobile No",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -358,14 +360,14 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "shipping_address",
|
"fieldname": "shipping_address",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Select Shipping Address",
|
"label": "Company Shipping Address",
|
||||||
"options": "Address",
|
"options": "Address",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "shipping_address_display",
|
"fieldname": "shipping_address_display",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Shipping Address",
|
"label": "Shipping Address Details",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@ -433,7 +435,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "sec_warehouse",
|
"fieldname": "sec_warehouse",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Subcontracting"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Sets 'Warehouse' in each row of the Items table.",
|
"description": "Sets 'Warehouse' in each row of the Items table.",
|
||||||
@ -466,6 +469,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "items_section",
|
"fieldname": "items_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
|
"hide_border": 1,
|
||||||
"oldfieldtype": "Section Break",
|
"oldfieldtype": "Section Break",
|
||||||
"options": "fa fa-shopping-cart"
|
"options": "fa fa-shopping-cart"
|
||||||
},
|
},
|
||||||
@ -598,7 +602,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_52",
|
"fieldname": "section_break_52",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break",
|
||||||
|
"hide_border": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "taxes",
|
"fieldname": "taxes",
|
||||||
@ -626,10 +631,12 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "totals",
|
"fieldname": "totals",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Taxes and Charges",
|
||||||
"oldfieldtype": "Section Break",
|
"oldfieldtype": "Section Break",
|
||||||
"options": "fa fa-money"
|
"options": "fa fa-money"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "base_taxes_and_charges_added",
|
||||||
"fieldname": "base_taxes_and_charges_added",
|
"fieldname": "base_taxes_and_charges_added",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Taxes and Charges Added (Company Currency)",
|
"label": "Taxes and Charges Added (Company Currency)",
|
||||||
@ -640,6 +647,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "base_taxes_and_charges_deducted",
|
||||||
"fieldname": "base_taxes_and_charges_deducted",
|
"fieldname": "base_taxes_and_charges_deducted",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Taxes and Charges Deducted (Company Currency)",
|
"label": "Taxes and Charges Deducted (Company Currency)",
|
||||||
@ -650,6 +658,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "base_total_taxes_and_charges",
|
||||||
"fieldname": "base_total_taxes_and_charges",
|
"fieldname": "base_total_taxes_and_charges",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Taxes and Charges (Company Currency)",
|
"label": "Total Taxes and Charges (Company Currency)",
|
||||||
@ -665,6 +674,7 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "taxes_and_charges_added",
|
||||||
"fieldname": "taxes_and_charges_added",
|
"fieldname": "taxes_and_charges_added",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Taxes and Charges Added",
|
"label": "Taxes and Charges Added",
|
||||||
@ -675,6 +685,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "taxes_and_charges_deducted",
|
||||||
"fieldname": "taxes_and_charges_deducted",
|
"fieldname": "taxes_and_charges_deducted",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Taxes and Charges Deducted",
|
"label": "Taxes and Charges Deducted",
|
||||||
@ -685,6 +696,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "total_taxes_and_charges",
|
||||||
"fieldname": "total_taxes_and_charges",
|
"fieldname": "total_taxes_and_charges",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total Taxes and Charges",
|
"label": "Total Taxes and Charges",
|
||||||
@ -694,7 +706,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"collapsible_depends_on": "discount_amount",
|
"collapsible_depends_on": "apply_discount_on",
|
||||||
"fieldname": "discount_section",
|
"fieldname": "discount_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Additional Discount"
|
"label": "Additional Discount"
|
||||||
@ -734,7 +746,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "totals_section",
|
"fieldname": "totals_section",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Totals"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_grand_total",
|
"fieldname": "base_grand_total",
|
||||||
@ -902,12 +915,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "ref_sq",
|
"fieldname": "ref_sq",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"label": "Supplier Quotation",
|
||||||
"label": "Ref SQ",
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "ref_sq",
|
"oldfieldname": "ref_sq",
|
||||||
"oldfieldtype": "Data",
|
"oldfieldtype": "Data",
|
||||||
|
"options": "Supplier Quotation",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@ -1061,7 +1074,7 @@
|
|||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "tracking_section",
|
"fieldname": "tracking_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Tracking"
|
"label": "Order Status"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_75",
|
"fieldname": "column_break_75",
|
||||||
@ -1070,21 +1083,29 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "billing_address",
|
"fieldname": "billing_address",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Select Billing Address",
|
"label": "Company Billing Address",
|
||||||
"options": "Address"
|
"options": "Address"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "billing_address_display",
|
"fieldname": "billing_address_display",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Billing Address",
|
"label": "Billing Address Details",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "before_items_section",
|
||||||
|
"fieldtype": "Section Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "items_col_break",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-file-text",
|
"icon": "fa fa-file-text",
|
||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-10-07 14:31:57.661221",
|
"modified": "2020-10-30 11:39:37.388249",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"col_break2",
|
"col_break2",
|
||||||
"uom",
|
"uom",
|
||||||
"conversion_factor",
|
"conversion_factor",
|
||||||
|
"stock_qty",
|
||||||
"sec_break1",
|
"sec_break1",
|
||||||
"price_list_rate",
|
"price_list_rate",
|
||||||
"discount_percentage",
|
"discount_percentage",
|
||||||
@ -46,11 +47,8 @@
|
|||||||
"column_break_32",
|
"column_break_32",
|
||||||
"base_net_rate",
|
"base_net_rate",
|
||||||
"base_net_amount",
|
"base_net_amount",
|
||||||
"billed_amt",
|
|
||||||
"warehouse_and_reference",
|
"warehouse_and_reference",
|
||||||
"warehouse",
|
"warehouse",
|
||||||
"delivered_by_supplier",
|
|
||||||
"project",
|
|
||||||
"material_request",
|
"material_request",
|
||||||
"material_request_item",
|
"material_request_item",
|
||||||
"sales_order",
|
"sales_order",
|
||||||
@ -58,36 +56,37 @@
|
|||||||
"supplier_quotation",
|
"supplier_quotation",
|
||||||
"supplier_quotation_item",
|
"supplier_quotation_item",
|
||||||
"col_break5",
|
"col_break5",
|
||||||
|
"delivered_by_supplier",
|
||||||
"against_blanket_order",
|
"against_blanket_order",
|
||||||
"blanket_order",
|
"blanket_order",
|
||||||
"blanket_order_rate",
|
"blanket_order_rate",
|
||||||
"item_group",
|
"item_group",
|
||||||
"brand",
|
"brand",
|
||||||
"bom",
|
|
||||||
"include_exploded_items",
|
|
||||||
"section_break_56",
|
"section_break_56",
|
||||||
"stock_qty",
|
|
||||||
"column_break_60",
|
|
||||||
"received_qty",
|
"received_qty",
|
||||||
"returned_qty",
|
"returned_qty",
|
||||||
"manufacture_details",
|
"column_break_60",
|
||||||
"manufacturer",
|
"billed_amt",
|
||||||
"column_break_14",
|
|
||||||
"manufacturer_part_no",
|
|
||||||
"more_info_section_break",
|
|
||||||
"is_fixed_asset",
|
|
||||||
"item_tax_rate",
|
|
||||||
"accounting_details",
|
"accounting_details",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
"column_break_68",
|
"manufacture_details",
|
||||||
|
"manufacturer",
|
||||||
|
"manufacturer_part_no",
|
||||||
|
"column_break_14",
|
||||||
|
"bom",
|
||||||
|
"include_exploded_items",
|
||||||
"item_weight_details",
|
"item_weight_details",
|
||||||
"weight_per_unit",
|
"weight_per_unit",
|
||||||
"total_weight",
|
"total_weight",
|
||||||
"column_break_40",
|
"column_break_40",
|
||||||
"weight_uom",
|
"weight_uom",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"project",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
|
"cost_center",
|
||||||
|
"more_info_section_break",
|
||||||
|
"is_fixed_asset",
|
||||||
|
"item_tax_rate",
|
||||||
"section_break_72",
|
"section_break_72",
|
||||||
"page_break"
|
"page_break"
|
||||||
],
|
],
|
||||||
@ -346,6 +345,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"depends_on": "is_free_item",
|
||||||
"fieldname": "is_free_item",
|
"fieldname": "is_free_item",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Free Item",
|
"label": "Is Free Item",
|
||||||
@ -508,9 +508,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"depends_on": "delivered_by_supplier",
|
||||||
"fieldname": "delivered_by_supplier",
|
"fieldname": "delivered_by_supplier",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "To be delivered to customer",
|
"label": "To be Delivered to Customer",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
@ -558,6 +559,7 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "eval:parent.is_subcontracted == 'Yes'",
|
||||||
"fieldname": "bom",
|
"fieldname": "bom",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "BOM",
|
"label": "BOM",
|
||||||
@ -574,21 +576,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_56",
|
"fieldname": "section_break_56",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Billed, Received & Returned"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "stock_qty",
|
"fieldname": "stock_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Qty as per Stock UOM",
|
"label": "Qty in Stock UOM",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "stock_qty",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"print_width": "100px",
|
"print_width": "100px",
|
||||||
"read_only": 1,
|
"read_only": 1,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "received_qty",
|
||||||
"fieldname": "received_qty",
|
"fieldname": "received_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Received Qty",
|
"label": "Received Qty",
|
||||||
@ -612,9 +614,10 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"depends_on": "billed_amt",
|
||||||
"fieldname": "billed_amt",
|
"fieldname": "billed_amt",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Billed Amt",
|
"label": "Billed Amount",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "currency",
|
"options": "currency",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
@ -633,6 +636,7 @@
|
|||||||
"report_hide": 1
|
"report_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"collapsible": 1,
|
||||||
"fieldname": "accounting_details",
|
"fieldname": "accounting_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Accounting Details"
|
"label": "Accounting Details"
|
||||||
@ -644,10 +648,6 @@
|
|||||||
"options": "Account",
|
"options": "Account",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "column_break_68",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@ -715,6 +715,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
"depends_on": "is_fixed_asset",
|
||||||
"fetch_from": "item_code.is_fixed_asset",
|
"fetch_from": "item_code.is_fixed_asset",
|
||||||
"fieldname": "is_fixed_asset",
|
"fieldname": "is_fixed_asset",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
@ -728,9 +729,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-21 11:55:58.643393",
|
"modified": "2020-10-30 11:59:47.670951",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order Item",
|
"name": "Purchase Order Item",
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "contract_terms",
|
"fieldname": "contract_terms",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"label": "Contract Terms and Conditions",
|
"label": "Contract Terms and Conditions"
|
||||||
"read_only": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "sb_fulfilment",
|
"fieldname": "sb_fulfilment",
|
||||||
@ -45,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-03 00:24:58.179816",
|
"modified": "2020-11-11 17:49:44.879363",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "CRM",
|
"module": "CRM",
|
||||||
"name": "Contract Template",
|
"name": "Contract Template",
|
||||||
|
@ -2,12 +2,13 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
import json
|
import json
|
||||||
from frappe.utils import cstr, cint, nowdate, flt
|
from frappe.utils import cstr, cint, nowdate, getdate, flt, get_request_session, get_datetime
|
||||||
from erpnext.erpnext_integrations.utils import validate_webhooks_request
|
from erpnext.erpnext_integrations.utils import validate_webhooks_request
|
||||||
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice
|
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note, make_sales_invoice
|
||||||
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_product import sync_item_from_shopify
|
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_product import sync_item_from_shopify
|
||||||
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_customer import create_customer
|
from erpnext.erpnext_integrations.doctype.shopify_settings.sync_customer import create_customer
|
||||||
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log, dump_request_data
|
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log, dump_request_data
|
||||||
|
from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import get_shopify_url, get_header
|
||||||
|
|
||||||
@frappe.whitelist(allow_guest=True)
|
@frappe.whitelist(allow_guest=True)
|
||||||
@validate_webhooks_request("Shopify Settings", 'X-Shopify-Hmac-Sha256', secret_key='shared_secret')
|
@validate_webhooks_request("Shopify Settings", 'X-Shopify-Hmac-Sha256', secret_key='shared_secret')
|
||||||
@ -18,7 +19,7 @@ def store_request_data(order=None, event=None):
|
|||||||
|
|
||||||
dump_request_data(order, event)
|
dump_request_data(order, event)
|
||||||
|
|
||||||
def sync_sales_order(order, request_id=None):
|
def sync_sales_order(order, request_id=None, old_order_sync=False):
|
||||||
frappe.set_user('Administrator')
|
frappe.set_user('Administrator')
|
||||||
shopify_settings = frappe.get_doc("Shopify Settings")
|
shopify_settings = frappe.get_doc("Shopify Settings")
|
||||||
frappe.flags.request_id = request_id
|
frappe.flags.request_id = request_id
|
||||||
@ -27,7 +28,7 @@ def sync_sales_order(order, request_id=None):
|
|||||||
try:
|
try:
|
||||||
validate_customer(order, shopify_settings)
|
validate_customer(order, shopify_settings)
|
||||||
validate_item(order, shopify_settings)
|
validate_item(order, shopify_settings)
|
||||||
create_order(order, shopify_settings)
|
create_order(order, shopify_settings, old_order_sync=old_order_sync)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
make_shopify_log(status="Error", exception=e)
|
make_shopify_log(status="Error", exception=e)
|
||||||
|
|
||||||
@ -77,13 +78,13 @@ def validate_item(order, shopify_settings):
|
|||||||
if item.get("product_id") and not frappe.db.get_value("Item", {"shopify_product_id": item.get("product_id")}, "name"):
|
if item.get("product_id") and not frappe.db.get_value("Item", {"shopify_product_id": item.get("product_id")}, "name"):
|
||||||
sync_item_from_shopify(shopify_settings, item)
|
sync_item_from_shopify(shopify_settings, item)
|
||||||
|
|
||||||
def create_order(order, shopify_settings, company=None):
|
def create_order(order, shopify_settings, old_order_sync=False, company=None):
|
||||||
so = create_sales_order(order, shopify_settings, company)
|
so = create_sales_order(order, shopify_settings, company)
|
||||||
if so:
|
if so:
|
||||||
if order.get("financial_status") == "paid":
|
if order.get("financial_status") == "paid":
|
||||||
create_sales_invoice(order, shopify_settings, so)
|
create_sales_invoice(order, shopify_settings, so, old_order_sync=old_order_sync)
|
||||||
|
|
||||||
if order.get("fulfillments"):
|
if order.get("fulfillments") and not old_order_sync:
|
||||||
create_delivery_note(order, shopify_settings, so)
|
create_delivery_note(order, shopify_settings, so)
|
||||||
|
|
||||||
def create_sales_order(shopify_order, shopify_settings, company=None):
|
def create_sales_order(shopify_order, shopify_settings, company=None):
|
||||||
@ -92,7 +93,7 @@ def create_sales_order(shopify_order, shopify_settings, company=None):
|
|||||||
so = frappe.db.get_value("Sales Order", {"shopify_order_id": shopify_order.get("id")}, "name")
|
so = frappe.db.get_value("Sales Order", {"shopify_order_id": shopify_order.get("id")}, "name")
|
||||||
|
|
||||||
if not so:
|
if not so:
|
||||||
items = get_order_items(shopify_order.get("line_items"), shopify_settings)
|
items = get_order_items(shopify_order.get("line_items"), shopify_settings, getdate(shopify_order.get('created_at')))
|
||||||
|
|
||||||
if not items:
|
if not items:
|
||||||
message = 'Following items exists in the shopify order but relevant records were not found in the shopify Product master'
|
message = 'Following items exists in the shopify order but relevant records were not found in the shopify Product master'
|
||||||
@ -106,8 +107,10 @@ def create_sales_order(shopify_order, shopify_settings, company=None):
|
|||||||
"doctype": "Sales Order",
|
"doctype": "Sales Order",
|
||||||
"naming_series": shopify_settings.sales_order_series or "SO-Shopify-",
|
"naming_series": shopify_settings.sales_order_series or "SO-Shopify-",
|
||||||
"shopify_order_id": shopify_order.get("id"),
|
"shopify_order_id": shopify_order.get("id"),
|
||||||
|
"shopify_order_number": shopify_order.get("name"),
|
||||||
"customer": customer or shopify_settings.default_customer,
|
"customer": customer or shopify_settings.default_customer,
|
||||||
"delivery_date": nowdate(),
|
"transaction_date": getdate(shopify_order.get("created_at")) or nowdate(),
|
||||||
|
"delivery_date": getdate(shopify_order.get("created_at")) or nowdate(),
|
||||||
"company": shopify_settings.company,
|
"company": shopify_settings.company,
|
||||||
"selling_price_list": shopify_settings.price_list,
|
"selling_price_list": shopify_settings.price_list,
|
||||||
"ignore_pricing_rule": 1,
|
"ignore_pricing_rule": 1,
|
||||||
@ -132,12 +135,20 @@ def create_sales_order(shopify_order, shopify_settings, company=None):
|
|||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
return so
|
return so
|
||||||
|
|
||||||
def create_sales_invoice(shopify_order, shopify_settings, so):
|
def create_sales_invoice(shopify_order, shopify_settings, so, old_order_sync=False):
|
||||||
if not frappe.db.get_value("Sales Invoice", {"shopify_order_id": shopify_order.get("id")}, "name")\
|
if not frappe.db.get_value("Sales Invoice", {"shopify_order_id": shopify_order.get("id")}, "name")\
|
||||||
and so.docstatus==1 and not so.per_billed and cint(shopify_settings.sync_sales_invoice):
|
and so.docstatus==1 and not so.per_billed and cint(shopify_settings.sync_sales_invoice):
|
||||||
|
|
||||||
|
if old_order_sync:
|
||||||
|
posting_date = getdate(shopify_order.get('created_at'))
|
||||||
|
else:
|
||||||
|
posting_date = nowdate()
|
||||||
|
|
||||||
si = make_sales_invoice(so.name, ignore_permissions=True)
|
si = make_sales_invoice(so.name, ignore_permissions=True)
|
||||||
si.shopify_order_id = shopify_order.get("id")
|
si.shopify_order_id = shopify_order.get("id")
|
||||||
|
si.shopify_order_number = shopify_order.get("name")
|
||||||
|
si.set_posting_time = 1
|
||||||
|
si.posting_date = posting_date
|
||||||
si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-"
|
si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-"
|
||||||
si.flags.ignore_mandatory = True
|
si.flags.ignore_mandatory = True
|
||||||
set_cost_center(si.items, shopify_settings.cost_center)
|
set_cost_center(si.items, shopify_settings.cost_center)
|
||||||
@ -169,6 +180,9 @@ def create_delivery_note(shopify_order, shopify_settings, so):
|
|||||||
|
|
||||||
dn = make_delivery_note(so.name)
|
dn = make_delivery_note(so.name)
|
||||||
dn.shopify_order_id = fulfillment.get("order_id")
|
dn.shopify_order_id = fulfillment.get("order_id")
|
||||||
|
dn.shopify_order_number = shopify_order.get("name")
|
||||||
|
dn.set_posting_time = 1
|
||||||
|
dn.posting_date = getdate(fulfillment.get("created_at"))
|
||||||
dn.shopify_fulfillment_id = fulfillment.get("id")
|
dn.shopify_fulfillment_id = fulfillment.get("id")
|
||||||
dn.naming_series = shopify_settings.delivery_note_series or "DN-Shopify-"
|
dn.naming_series = shopify_settings.delivery_note_series or "DN-Shopify-"
|
||||||
dn.items = get_fulfillment_items(dn.items, fulfillment.get("line_items"), shopify_settings)
|
dn.items = get_fulfillment_items(dn.items, fulfillment.get("line_items"), shopify_settings)
|
||||||
@ -187,7 +201,7 @@ def get_discounted_amount(order):
|
|||||||
discounted_amount += flt(discount.get("amount"))
|
discounted_amount += flt(discount.get("amount"))
|
||||||
return discounted_amount
|
return discounted_amount
|
||||||
|
|
||||||
def get_order_items(order_items, shopify_settings):
|
def get_order_items(order_items, shopify_settings, delivery_date):
|
||||||
items = []
|
items = []
|
||||||
all_product_exists = True
|
all_product_exists = True
|
||||||
product_not_exists = []
|
product_not_exists = []
|
||||||
@ -205,7 +219,7 @@ def get_order_items(order_items, shopify_settings):
|
|||||||
"item_code": item_code,
|
"item_code": item_code,
|
||||||
"item_name": shopify_item.get("name"),
|
"item_name": shopify_item.get("name"),
|
||||||
"rate": shopify_item.get("price"),
|
"rate": shopify_item.get("price"),
|
||||||
"delivery_date": nowdate(),
|
"delivery_date": delivery_date,
|
||||||
"qty": shopify_item.get("quantity"),
|
"qty": shopify_item.get("quantity"),
|
||||||
"stock_uom": shopify_item.get("uom") or _("Nos"),
|
"stock_uom": shopify_item.get("uom") or _("Nos"),
|
||||||
"warehouse": shopify_settings.warehouse
|
"warehouse": shopify_settings.warehouse
|
||||||
@ -265,3 +279,64 @@ def get_tax_account_head(tax):
|
|||||||
frappe.throw(_("Tax Account not specified for Shopify Tax {0}").format(tax.get("title")))
|
frappe.throw(_("Tax Account not specified for Shopify Tax {0}").format(tax.get("title")))
|
||||||
|
|
||||||
return tax_account
|
return tax_account
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def sync_old_orders():
|
||||||
|
frappe.set_user('Administrator')
|
||||||
|
shopify_settings = frappe.get_doc('Shopify Settings')
|
||||||
|
|
||||||
|
if not shopify_settings.sync_missing_orders:
|
||||||
|
return
|
||||||
|
|
||||||
|
url = get_url(shopify_settings)
|
||||||
|
session = get_request_session()
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = session.get(url, headers=get_header(shopify_settings))
|
||||||
|
res.raise_for_status()
|
||||||
|
orders = res.json()["orders"]
|
||||||
|
|
||||||
|
for order in orders:
|
||||||
|
if is_sync_complete(shopify_settings, order):
|
||||||
|
stop_sync(shopify_settings)
|
||||||
|
return
|
||||||
|
|
||||||
|
sync_sales_order(order=order, old_order_sync=True)
|
||||||
|
last_order_id = order.get('id')
|
||||||
|
|
||||||
|
if last_order_id:
|
||||||
|
shopify_settings.load_from_db()
|
||||||
|
shopify_settings.last_order_id = last_order_id
|
||||||
|
shopify_settings.save()
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
def stop_sync(shopify_settings):
|
||||||
|
shopify_settings.sync_missing_orders = 0
|
||||||
|
shopify_settings.last_order_id = ''
|
||||||
|
shopify_settings.save()
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
def get_url(shopify_settings):
|
||||||
|
last_order_id = shopify_settings.last_order_id
|
||||||
|
|
||||||
|
if not last_order_id:
|
||||||
|
if shopify_settings.sync_based_on == 'Date':
|
||||||
|
url = get_shopify_url("admin/api/2020-10/orders.json?limit=250&created_at_min={0}&since_id=0".format(
|
||||||
|
get_datetime(shopify_settings.from_date)), shopify_settings)
|
||||||
|
else:
|
||||||
|
url = get_shopify_url("admin/api/2020-10/orders.json?limit=250&since_id={0}".format(
|
||||||
|
shopify_settings.from_order_id), shopify_settings)
|
||||||
|
else:
|
||||||
|
url = get_shopify_url("admin/api/2020-10/orders.json?limit=250&since_id={0}".format(last_order_id), shopify_settings)
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
|
def is_sync_complete(shopify_settings, order):
|
||||||
|
if shopify_settings.sync_based_on == 'Date':
|
||||||
|
return getdate(shopify_settings.to_date) < getdate(order.get('created_at'))
|
||||||
|
else:
|
||||||
|
return cstr(order.get('id')) == cstr(shopify_settings.to_order_id)
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"creation": "2015-05-18 05:21:07.270859",
|
"creation": "2015-05-18 05:21:07.270859",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "System",
|
"document_type": "System",
|
||||||
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"status_html",
|
"status_html",
|
||||||
"enable_shopify",
|
"enable_shopify",
|
||||||
@ -40,7 +42,16 @@
|
|||||||
"sales_invoice_series",
|
"sales_invoice_series",
|
||||||
"section_break_22",
|
"section_break_22",
|
||||||
"html_16",
|
"html_16",
|
||||||
"taxes"
|
"taxes",
|
||||||
|
"syncing_details_section",
|
||||||
|
"sync_missing_orders",
|
||||||
|
"sync_based_on",
|
||||||
|
"column_break_41",
|
||||||
|
"from_date",
|
||||||
|
"to_date",
|
||||||
|
"from_order_id",
|
||||||
|
"to_order_id",
|
||||||
|
"last_order_id"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -255,10 +266,71 @@
|
|||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Shopify Tax Account",
|
"label": "Shopify Tax Account",
|
||||||
"options": "Shopify Tax Account"
|
"options": "Shopify Tax Account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collapsible": 1,
|
||||||
|
"fieldname": "syncing_details_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Syncing Missing Orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.sync_missing_orders",
|
||||||
|
"fieldname": "last_order_id",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Last Order Id",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_41",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"description": "On checking this Order from the ",
|
||||||
|
"fieldname": "sync_missing_orders",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Sync Missing Old Shopify Orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.sync_missing_orders",
|
||||||
|
"fieldname": "sync_based_on",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Sync Based On",
|
||||||
|
"mandatory_depends_on": "eval:doc.sync_missing_orders",
|
||||||
|
"options": "\nDate\nShopify Order Id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders",
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "From Date",
|
||||||
|
"mandatory_depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders",
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "To Date",
|
||||||
|
"mandatory_depends_on": "eval:doc.sync_based_on == 'Date' && doc.sync_missing_orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders",
|
||||||
|
"fieldname": "from_order_id",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "From Order Id",
|
||||||
|
"mandatory_depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders",
|
||||||
|
"fieldname": "to_order_id",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "To Order Id",
|
||||||
|
"mandatory_depends_on": "eval:doc.sync_based_on == 'Shopify Order Id' && doc.sync_missing_orders"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2020-09-18 17:26:09.703215",
|
"links": [],
|
||||||
|
"modified": "2020-11-05 20:44:03.664891",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "ERPNext Integrations",
|
"module": "ERPNext Integrations",
|
||||||
"name": "Shopify Settings",
|
"name": "Shopify Settings",
|
||||||
@ -277,4 +349,4 @@
|
|||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC"
|
"sort_order": "DESC"
|
||||||
}
|
}
|
@ -87,7 +87,7 @@ def get_shopify_url(path, settings):
|
|||||||
def get_header(settings):
|
def get_header(settings):
|
||||||
header = {'Content-Type': 'application/json'}
|
header = {'Content-Type': 'application/json'}
|
||||||
|
|
||||||
return header;
|
return header
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_series():
|
def get_series():
|
||||||
@ -121,17 +121,23 @@ def setup_custom_fields():
|
|||||||
],
|
],
|
||||||
"Sales Order": [
|
"Sales Order": [
|
||||||
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
||||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1)
|
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
||||||
|
dict(fieldname='shopify_order_number', label='Shopify Order Number',
|
||||||
|
fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1)
|
||||||
],
|
],
|
||||||
"Delivery Note":[
|
"Delivery Note":[
|
||||||
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
||||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
||||||
|
dict(fieldname='shopify_order_number', label='Shopify Order Number',
|
||||||
|
fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1),
|
||||||
dict(fieldname='shopify_fulfillment_id', label='Shopify Fulfillment Id',
|
dict(fieldname='shopify_fulfillment_id', label='Shopify Fulfillment Id',
|
||||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1)
|
fieldtype='Data', insert_after='title', read_only=1, print_hide=1)
|
||||||
],
|
],
|
||||||
"Sales Invoice": [
|
"Sales Invoice": [
|
||||||
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
dict(fieldname='shopify_order_id', label='Shopify Order Id',
|
||||||
fieldtype='Data', insert_after='title', read_only=1, print_hide=1)
|
fieldtype='Data', insert_after='title', read_only=1, print_hide=1),
|
||||||
|
dict(fieldname='shopify_order_number', label='Shopify Order Number',
|
||||||
|
fieldtype='Data', insert_after='shopify_order_id', read_only=1, print_hide=1)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ class ShopifySettings(unittest.TestCase):
|
|||||||
}).save(ignore_permissions=True)
|
}).save(ignore_permissions=True)
|
||||||
|
|
||||||
self.shopify_settings = shopify_settings
|
self.shopify_settings = shopify_settings
|
||||||
|
|
||||||
def test_order(self):
|
def test_order(self):
|
||||||
### Create Customer ###
|
### Create Customer ###
|
||||||
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_customer.json")) as shopify_customer:
|
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_customer.json")) as shopify_customer:
|
||||||
@ -75,7 +75,7 @@ class ShopifySettings(unittest.TestCase):
|
|||||||
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_order.json")) as shopify_order:
|
with open (os.path.join(os.path.dirname(__file__), "test_data", "shopify_order.json")) as shopify_order:
|
||||||
shopify_order = json.load(shopify_order)
|
shopify_order = json.load(shopify_order)
|
||||||
|
|
||||||
create_order(shopify_order.get("order"), self.shopify_settings, "_Test Company")
|
create_order(shopify_order.get("order"), self.shopify_settings, False, company="_Test Company")
|
||||||
|
|
||||||
sales_order = frappe.get_doc("Sales Order", {"shopify_order_id": cstr(shopify_order.get("order").get("id"))})
|
sales_order = frappe.get_doc("Sales Order", {"shopify_order_id": cstr(shopify_order.get("order").get("id"))})
|
||||||
|
|
||||||
|
@ -307,6 +307,7 @@ scheduler_events = {
|
|||||||
"erpnext.projects.doctype.project.project.collect_project_status",
|
"erpnext.projects.doctype.project.project.collect_project_status",
|
||||||
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
|
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
|
||||||
"erpnext.support.doctype.issue.issue.set_service_level_agreement_variance",
|
"erpnext.support.doctype.issue.issue.set_service_level_agreement_variance",
|
||||||
|
"erpnext.erpnext_integrations.connectors.shopify_connection.sync_old_orders",
|
||||||
],
|
],
|
||||||
"daily": [
|
"daily": [
|
||||||
"erpnext.stock.reorder_item.reorder_item",
|
"erpnext.stock.reorder_item.reorder_item",
|
||||||
|
@ -24,10 +24,10 @@ erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({
|
|||||||
}
|
}
|
||||||
window.location.href = repl(frappe.request.url +
|
window.location.href = repl(frappe.request.url +
|
||||||
'?cmd=%(cmd)s&from_date=%(from_date)s&to_date=%(to_date)s', {
|
'?cmd=%(cmd)s&from_date=%(from_date)s&to_date=%(to_date)s', {
|
||||||
cmd: "erpnext.hr.doctype.upload_attendance.upload_attendance.get_template",
|
cmd: "erpnext.hr.doctype.upload_attendance.upload_attendance.get_template",
|
||||||
from_date: this.frm.doc.att_fr_date,
|
from_date: this.frm.doc.att_fr_date,
|
||||||
to_date: this.frm.doc.att_to_date,
|
to_date: this.frm.doc.att_to_date,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
show_upload() {
|
show_upload() {
|
||||||
|
@ -28,7 +28,12 @@ def get_template():
|
|||||||
w = UnicodeWriter()
|
w = UnicodeWriter()
|
||||||
w = add_header(w)
|
w = add_header(w)
|
||||||
|
|
||||||
w = add_data(w, args)
|
try:
|
||||||
|
w = add_data(w, args)
|
||||||
|
except Exception as e:
|
||||||
|
frappe.clear_messages()
|
||||||
|
frappe.respond_as_web_page("Holiday List Missing", html=e)
|
||||||
|
return
|
||||||
|
|
||||||
# write out response as a type csv
|
# write out response as a type csv
|
||||||
frappe.response['result'] = cstr(w.getvalue())
|
frappe.response['result'] = cstr(w.getvalue())
|
||||||
|
@ -76,6 +76,7 @@ class BOM(WebsiteGenerator):
|
|||||||
self.set_routing_operations()
|
self.set_routing_operations()
|
||||||
self.validate_operations()
|
self.validate_operations()
|
||||||
self.calculate_cost()
|
self.calculate_cost()
|
||||||
|
self.update_stock_qty()
|
||||||
self.update_cost(update_parent=False, from_child_bom=True, save=False)
|
self.update_cost(update_parent=False, from_child_bom=True, save=False)
|
||||||
|
|
||||||
def get_context(self, context):
|
def get_context(self, context):
|
||||||
@ -84,8 +85,6 @@ class BOM(WebsiteGenerator):
|
|||||||
def on_update(self):
|
def on_update(self):
|
||||||
frappe.cache().hdel('bom_children', self.name)
|
frappe.cache().hdel('bom_children', self.name)
|
||||||
self.check_recursion()
|
self.check_recursion()
|
||||||
self.update_stock_qty()
|
|
||||||
self.update_exploded_items()
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.manage_default_bom()
|
self.manage_default_bom()
|
||||||
@ -237,7 +236,8 @@ class BOM(WebsiteGenerator):
|
|||||||
self.calculate_cost()
|
self.calculate_cost()
|
||||||
if save:
|
if save:
|
||||||
self.db_update()
|
self.db_update()
|
||||||
self.update_exploded_items()
|
|
||||||
|
self.update_exploded_items(save=save)
|
||||||
|
|
||||||
# update parent BOMs
|
# update parent BOMs
|
||||||
if self.total_cost != existing_bom_cost and update_parent:
|
if self.total_cost != existing_bom_cost and update_parent:
|
||||||
@ -318,8 +318,6 @@ class BOM(WebsiteGenerator):
|
|||||||
m.uom = m.stock_uom
|
m.uom = m.stock_uom
|
||||||
m.qty = m.stock_qty
|
m.qty = m.stock_qty
|
||||||
|
|
||||||
m.db_update()
|
|
||||||
|
|
||||||
def validate_uom_is_interger(self):
|
def validate_uom_is_interger(self):
|
||||||
from erpnext.utilities.transaction_base import validate_uom_is_integer
|
from erpnext.utilities.transaction_base import validate_uom_is_integer
|
||||||
validate_uom_is_integer(self, "uom", "qty", "BOM Item")
|
validate_uom_is_integer(self, "uom", "qty", "BOM Item")
|
||||||
@ -372,15 +370,6 @@ class BOM(WebsiteGenerator):
|
|||||||
if raise_exception:
|
if raise_exception:
|
||||||
frappe.throw(_("BOM recursion: {0} cannot be parent or child of {1}").format(self.name, self.name))
|
frappe.throw(_("BOM recursion: {0} cannot be parent or child of {1}").format(self.name, self.name))
|
||||||
|
|
||||||
def update_cost_and_exploded_items(self, bom_list=[]):
|
|
||||||
bom_list = self.traverse_tree(bom_list)
|
|
||||||
for bom in bom_list:
|
|
||||||
bom_obj = frappe.get_doc("BOM", bom)
|
|
||||||
bom_obj.check_recursion(bom_list=bom_list)
|
|
||||||
bom_obj.update_exploded_items()
|
|
||||||
|
|
||||||
return bom_list
|
|
||||||
|
|
||||||
def traverse_tree(self, bom_list=None):
|
def traverse_tree(self, bom_list=None):
|
||||||
def _get_children(bom_no):
|
def _get_children(bom_no):
|
||||||
children = frappe.cache().hget('bom_children', bom_no)
|
children = frappe.cache().hget('bom_children', bom_no)
|
||||||
@ -472,10 +461,10 @@ class BOM(WebsiteGenerator):
|
|||||||
d.rate = rate
|
d.rate = rate
|
||||||
d.amount = (d.stock_qty or d.qty) * rate
|
d.amount = (d.stock_qty or d.qty) * rate
|
||||||
|
|
||||||
def update_exploded_items(self):
|
def update_exploded_items(self, save=True):
|
||||||
""" Update Flat BOM, following will be correct data"""
|
""" Update Flat BOM, following will be correct data"""
|
||||||
self.get_exploded_items()
|
self.get_exploded_items()
|
||||||
self.add_exploded_items()
|
self.add_exploded_items(save=save)
|
||||||
|
|
||||||
def get_exploded_items(self):
|
def get_exploded_items(self):
|
||||||
""" Get all raw materials including items from child bom"""
|
""" Get all raw materials including items from child bom"""
|
||||||
@ -544,11 +533,13 @@ class BOM(WebsiteGenerator):
|
|||||||
'sourced_by_supplier': d.get('sourced_by_supplier', 0)
|
'sourced_by_supplier': d.get('sourced_by_supplier', 0)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
def add_exploded_items(self):
|
def add_exploded_items(self, save=True):
|
||||||
"Add items to Flat BOM table"
|
"Add items to Flat BOM table"
|
||||||
frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name)
|
|
||||||
self.set('exploded_items', [])
|
self.set('exploded_items', [])
|
||||||
|
|
||||||
|
if save:
|
||||||
|
frappe.db.sql("""delete from `tabBOM Explosion Item` where parent=%s""", self.name)
|
||||||
|
|
||||||
for d in sorted(self.cur_exploded_items, key=itemgetter(0)):
|
for d in sorted(self.cur_exploded_items, key=itemgetter(0)):
|
||||||
ch = self.append('exploded_items', {})
|
ch = self.append('exploded_items', {})
|
||||||
for i in self.cur_exploded_items[d].keys():
|
for i in self.cur_exploded_items[d].keys():
|
||||||
@ -556,7 +547,9 @@ class BOM(WebsiteGenerator):
|
|||||||
ch.amount = flt(ch.stock_qty) * flt(ch.rate)
|
ch.amount = flt(ch.stock_qty) * flt(ch.rate)
|
||||||
ch.qty_consumed_per_unit = flt(ch.stock_qty) / flt(self.quantity)
|
ch.qty_consumed_per_unit = flt(ch.stock_qty) / flt(self.quantity)
|
||||||
ch.docstatus = self.docstatus
|
ch.docstatus = self.docstatus
|
||||||
ch.db_insert()
|
|
||||||
|
if save:
|
||||||
|
ch.db_insert()
|
||||||
|
|
||||||
def validate_bom_links(self):
|
def validate_bom_links(self):
|
||||||
if not self.is_active:
|
if not self.is_active:
|
||||||
|
@ -443,6 +443,11 @@ class TestWorkOrder(unittest.TestCase):
|
|||||||
ste1 = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1))
|
ste1 = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1))
|
||||||
self.assertEqual(len(ste1.items), 3)
|
self.assertEqual(len(ste1.items), 3)
|
||||||
|
|
||||||
|
def test_cost_center_for_manufacture(self):
|
||||||
|
wo_order = make_wo_order_test_record()
|
||||||
|
ste = make_stock_entry(wo_order.name, "Material Transfer for Manufacture", wo_order.qty)
|
||||||
|
self.assertEquals(ste.get("items")[0].get("cost_center"), "_Test Cost Center - _TC")
|
||||||
|
|
||||||
def test_operation_time_with_batch_size(self):
|
def test_operation_time_with_batch_size(self):
|
||||||
fg_item = "Test Batch Size Item For BOM"
|
fg_item = "Test Batch Size Item For BOM"
|
||||||
rm1 = "Test Batch Size Item RM 1 For BOM"
|
rm1 = "Test Batch Size Item RM 1 For BOM"
|
||||||
|
@ -733,4 +733,5 @@ erpnext.patches.v13_0.print_uom_after_quantity_patch
|
|||||||
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
|
erpnext.patches.v13_0.set_payment_channel_in_payment_gateway_account
|
||||||
erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail
|
erpnext.patches.v13_0.create_healthcare_custom_fields_in_stock_entry_detail
|
||||||
erpnext.patches.v13_0.update_reason_for_resignation_in_employee
|
erpnext.patches.v13_0.update_reason_for_resignation_in_employee
|
||||||
execute:frappe.delete_doc("Report", "Quoted Item Comparison")
|
erpnext.patches.v13_0.update_custom_fields_for_shopify
|
||||||
|
execute:frappe.delete_doc("Report", "Quoted Item Comparison")
|
||||||
|
10
erpnext/patches/v13_0/update_custom_fields_for_shopify.py
Normal file
10
erpnext/patches/v13_0/update_custom_fields_for_shopify.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# MIT License. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings import setup_custom_fields
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
if frappe.db.get_single_value('Shopify Settings', 'enable_shopify'):
|
||||||
|
setup_custom_fields()
|
@ -2,7 +2,7 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('DATEV Settings', {
|
frappe.ui.form.on('DATEV Settings', {
|
||||||
// refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
frm.add_custom_button('Show Report', () => frappe.set_route('query-report', 'DATEV'), "fa fa-table");
|
||||||
// }
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "field:client",
|
"autoname": "field:client",
|
||||||
"creation": "2019-08-13 23:56:34.259906",
|
"creation": "2019-08-13 23:56:34.259906",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
@ -6,6 +7,7 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"client",
|
"client",
|
||||||
|
"account_number_length",
|
||||||
"column_break_2",
|
"column_break_2",
|
||||||
"client_number",
|
"client_number",
|
||||||
"section_break_4",
|
"section_break_4",
|
||||||
@ -28,8 +30,8 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Client ID",
|
"label": "Client ID",
|
||||||
"reqd": 1,
|
"length": 5,
|
||||||
"length": 5
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "consultant",
|
"fieldname": "consultant",
|
||||||
@ -43,8 +45,8 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Consultant ID",
|
"label": "Consultant ID",
|
||||||
"reqd": 1,
|
"length": 7,
|
||||||
"length": 7
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_2",
|
"fieldname": "column_break_2",
|
||||||
@ -57,9 +59,17 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "column_break_6",
|
"fieldname": "column_break_6",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "4",
|
||||||
|
"fieldname": "account_number_length",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"label": "Account Number Length",
|
||||||
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-08-14 00:03:26.616460",
|
"links": [],
|
||||||
|
"modified": "2020-11-05 17:52:11.674329",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Regional",
|
"module": "Regional",
|
||||||
"name": "DATEV Settings",
|
"name": "DATEV Settings",
|
||||||
@ -104,4 +114,4 @@
|
|||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
@ -106,7 +106,7 @@ def get_header(filters, csv_class):
|
|||||||
# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
|
# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
|
||||||
frappe.utils.formatdate(filters.get('fiscal_year_start'), 'yyyyMMdd'),
|
frappe.utils.formatdate(filters.get('fiscal_year_start'), 'yyyyMMdd'),
|
||||||
# N = Length of account numbers (Sachkontenlänge)
|
# N = Length of account numbers (Sachkontenlänge)
|
||||||
datev_settings.get('account_number_length', '4'),
|
str(filters.get('account_number_length', 4)),
|
||||||
# O = Transaction batch start date (YYYYMMDD)
|
# O = Transaction batch start date (YYYYMMDD)
|
||||||
frappe.utils.formatdate(filters.get('from_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
frappe.utils.formatdate(filters.get('from_date'), 'yyyyMMdd') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
|
||||||
# P = Transaction batch end date (YYYYMMDD)
|
# P = Transaction batch end date (YYYYMMDD)
|
||||||
|
@ -11,14 +11,14 @@ frappe.query_reports["DATEV"] = {
|
|||||||
{
|
{
|
||||||
"fieldname": "from_date",
|
"fieldname": "from_date",
|
||||||
"label": __("From Date"),
|
"label": __("From Date"),
|
||||||
"default": frappe.datetime.month_start(),
|
"default": moment().subtract(1, 'month').startOf('month').format(),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "to_date",
|
"fieldname": "to_date",
|
||||||
"label": __("To Date"),
|
"label": __("To Date"),
|
||||||
"default": frappe.datetime.now_date(),
|
"default": moment().subtract(1, 'month').endOf('month').format(),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@ -30,9 +30,23 @@ frappe.query_reports["DATEV"] = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
onload: function(query_report) {
|
onload: function(query_report) {
|
||||||
|
let company = frappe.query_report.get_filter_value('company');
|
||||||
|
frappe.db.exists('DATEV Settings', company).then((settings_exist) => {
|
||||||
|
if (!settings_exist) {
|
||||||
|
frappe.confirm(__('DATEV Settings for your Company are missing. Would you like to create them now?'),
|
||||||
|
() => frappe.new_doc('DATEV Settings', {'company': company})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
query_report.page.add_menu_item(__("Download DATEV File"), () => {
|
query_report.page.add_menu_item(__("Download DATEV File"), () => {
|
||||||
const filters = JSON.stringify(query_report.get_values());
|
const filters = JSON.stringify(query_report.get_values());
|
||||||
window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`);
|
window.open(`/api/method/erpnext.regional.report.datev.datev.download_datev_csv?filters=${filters}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
query_report.page.add_menu_item(__("Change DATEV Settings"), () => {
|
||||||
|
let company = frappe.query_report.get_filter_value('company'); // read company from filters again – it might have changed by now.
|
||||||
|
frappe.set_route('Form', 'DATEV Settings', company);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -94,8 +94,11 @@ COLUMNS = [
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
"""Entry point for frappe."""
|
"""Entry point for frappe."""
|
||||||
validate(filters)
|
data = []
|
||||||
return COLUMNS, get_transactions(filters, as_dict=0)
|
if filters and validate(filters):
|
||||||
|
data = get_transactions(filters, as_dict=0)
|
||||||
|
|
||||||
|
return COLUMNS, data
|
||||||
|
|
||||||
|
|
||||||
def validate(filters):
|
def validate(filters):
|
||||||
@ -114,10 +117,14 @@ def validate(filters):
|
|||||||
|
|
||||||
validate_fiscal_year(from_date, to_date, company)
|
validate_fiscal_year(from_date, to_date, company)
|
||||||
|
|
||||||
try:
|
if not frappe.db.exists('DATEV Settings', filters.get('company')):
|
||||||
frappe.get_doc('DATEV Settings', filters.get('company'))
|
frappe.log_error(_('Please create {} for Company {}.').format(
|
||||||
except frappe.DoesNotExistError:
|
'<a href="desk#List/DATEV%20Settings/List">{}</a>'.format(_('DATEV Settings')),
|
||||||
frappe.throw(_('Please create <b>DATEV Settings</b> for Company <b>{}</b>.').format(filters.get('company')))
|
frappe.bold(filters.get('company'))
|
||||||
|
))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def validate_fiscal_year(from_date, to_date, company):
|
def validate_fiscal_year(from_date, to_date, company):
|
||||||
@ -340,6 +347,8 @@ def download_datev_csv(filters):
|
|||||||
coa = frappe.get_value('Company', company, 'chart_of_accounts')
|
coa = frappe.get_value('Company', company, 'chart_of_accounts')
|
||||||
filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
|
filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
|
||||||
|
|
||||||
|
filters['account_number_length'] = frappe.get_value('DATEV Settings', company, 'account_number_length')
|
||||||
|
|
||||||
transactions = get_transactions(filters)
|
transactions = get_transactions(filters)
|
||||||
account_names = get_account_names(filters)
|
account_names = get_account_names(filters)
|
||||||
customers = get_customers(filters)
|
customers = get_customers(filters)
|
||||||
|
@ -1227,8 +1227,6 @@ class StockEntry(StockController):
|
|||||||
return item_dict
|
return item_dict
|
||||||
|
|
||||||
def add_to_stock_entry_detail(self, item_dict, bom_no=None):
|
def add_to_stock_entry_detail(self, item_dict, bom_no=None):
|
||||||
cost_center = frappe.db.get_value("Company", self.company, 'cost_center')
|
|
||||||
|
|
||||||
for d in item_dict:
|
for d in item_dict:
|
||||||
stock_uom = item_dict[d].get("stock_uom") or frappe.db.get_value("Item", d, "stock_uom")
|
stock_uom = item_dict[d].get("stock_uom") or frappe.db.get_value("Item", d, "stock_uom")
|
||||||
|
|
||||||
@ -1239,9 +1237,10 @@ class StockEntry(StockController):
|
|||||||
se_child.uom = item_dict[d]["uom"] if item_dict[d].get("uom") else stock_uom
|
se_child.uom = item_dict[d]["uom"] if item_dict[d].get("uom") else stock_uom
|
||||||
se_child.stock_uom = stock_uom
|
se_child.stock_uom = stock_uom
|
||||||
se_child.qty = flt(item_dict[d]["qty"], se_child.precision("qty"))
|
se_child.qty = flt(item_dict[d]["qty"], se_child.precision("qty"))
|
||||||
se_child.cost_center = item_dict[d].get("cost_center") or cost_center
|
|
||||||
se_child.allow_alternative_item = item_dict[d].get("allow_alternative_item", 0)
|
se_child.allow_alternative_item = item_dict[d].get("allow_alternative_item", 0)
|
||||||
se_child.subcontracted_item = item_dict[d].get("main_item_code")
|
se_child.subcontracted_item = item_dict[d].get("main_item_code")
|
||||||
|
se_child.cost_center = (item_dict[d].get("cost_center") or
|
||||||
|
get_default_cost_center(item_dict[d], company = self.company))
|
||||||
|
|
||||||
for field in ["idx", "po_detail", "original_item",
|
for field in ["idx", "po_detail", "original_item",
|
||||||
"expense_account", "description", "item_name"]:
|
"expense_account", "description", "item_name"]:
|
||||||
|
@ -559,23 +559,40 @@ def get_default_deferred_account(args, item, fieldname=None):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_default_cost_center(args, item, item_group, brand, company=None):
|
def get_default_cost_center(args, item=None, item_group=None, brand=None, company=None):
|
||||||
cost_center = None
|
cost_center = None
|
||||||
|
|
||||||
|
if not company and args.get("company"):
|
||||||
|
company = args.get("company")
|
||||||
|
|
||||||
if args.get('project'):
|
if args.get('project'):
|
||||||
cost_center = frappe.db.get_value("Project", args.get("project"), "cost_center", cache=True)
|
cost_center = frappe.db.get_value("Project", args.get("project"), "cost_center", cache=True)
|
||||||
|
|
||||||
if not cost_center:
|
if not cost_center and (item and item_group and brand):
|
||||||
if args.get('customer'):
|
if args.get('customer'):
|
||||||
cost_center = item.get('selling_cost_center') or item_group.get('selling_cost_center') or brand.get('selling_cost_center')
|
cost_center = item.get('selling_cost_center') or item_group.get('selling_cost_center') or brand.get('selling_cost_center')
|
||||||
else:
|
else:
|
||||||
cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center') or brand.get('buying_cost_center')
|
cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center') or brand.get('buying_cost_center')
|
||||||
|
|
||||||
cost_center = cost_center or args.get("cost_center")
|
elif not cost_center and args.get("item_code") and company:
|
||||||
|
for method in ["get_item_defaults", "get_item_group_defaults", "get_brand_defaults"]:
|
||||||
|
path = "erpnext.stock.get_item_details.{0}".format(method)
|
||||||
|
data = frappe.get_attr(path)(args.get("item_code"), company)
|
||||||
|
|
||||||
|
if data and (data.selling_cost_center or data.buying_cost_center):
|
||||||
|
return data.selling_cost_center or data.buying_cost_center
|
||||||
|
|
||||||
|
if not cost_center and args.get("cost_center"):
|
||||||
|
cost_center = args.get("cost_center")
|
||||||
|
|
||||||
if (company and cost_center
|
if (company and cost_center
|
||||||
and frappe.get_cached_value("Cost Center", cost_center, "company") != company):
|
and frappe.get_cached_value("Cost Center", cost_center, "company") != company):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if not cost_center and company:
|
||||||
|
cost_center = frappe.get_cached_value("Company",
|
||||||
|
company, "cost_center")
|
||||||
|
|
||||||
return cost_center
|
return cost_center
|
||||||
|
|
||||||
def get_default_supplier(args, item, item_group, brand):
|
def get_default_supplier(args, item, item_group, brand):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user