Merge pull request #33107 from barredterra/german-tax-templates
feat: german tax templates
diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
index 3e0b82c..1e2e2ac 100644
--- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
+++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json
@@ -91,7 +91,7 @@
},
{
"default": "0",
- "description": "Enabling ensure each Sales Invoice has a unique value in Supplier Invoice No. field",
+ "description": "Enabling ensure each Purchase Invoice has a unique value in Supplier Invoice No. field",
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"label": "Check Supplier Invoice Number Uniqueness"
@@ -354,7 +354,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2022-07-11 13:37:50.605141",
+ "modified": "2022-11-27 21:49:52.538655",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index a5981fd..a03157e 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -69,6 +69,7 @@
"tax_category",
"column_break_49",
"shipping_rule",
+ "incoterm",
"section_break_51",
"taxes",
"totals",
@@ -1534,13 +1535,19 @@
"oldfieldtype": "Section Break",
"options": "fa fa-file-text",
"print_hide": 1
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-file-text",
"idx": 204,
"is_submittable": 1,
"links": [],
- "modified": "2022-11-22 12:44:29.935567",
+ "modified": "2022-11-25 12:44:29.935567",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index dc2f9a9..18d2b5c 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -64,6 +64,7 @@
"taxes_and_charges",
"column_break_38",
"shipping_rule",
+ "incoterm",
"column_break_55",
"tax_category",
"section_break_40",
@@ -2114,6 +2115,12 @@
"label": "Repost Required",
"no_copy": 1,
"read_only": 1
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-file-text",
@@ -2126,7 +2133,7 @@
"link_fieldname": "consolidated_invoice"
}
],
- "modified": "2022-11-15 09:33:47.870616",
+ "modified": "2022-11-17 17:17:10.883487",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index e2a70c2..9349626 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -67,6 +67,7 @@
"tax_category",
"column_break_50",
"shipping_rule",
+ "incoterm",
"section_break_52",
"taxes",
"totals",
@@ -1249,13 +1250,19 @@
{
"fieldname": "column_break_103",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
"links": [],
- "modified": "2022-11-17 12:34:36.033363",
+ "modified": "2022-11-17 17:28:07.729943",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
index 083cab7..019d45b 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.json
@@ -28,6 +28,7 @@
"sec_break_email_2",
"message_for_supplier",
"terms_section_break",
+ "incoterm",
"tc_name",
"terms",
"printing_settings",
@@ -271,13 +272,19 @@
"fieldname": "schedule_date",
"fieldtype": "Date",
"label": "Required Date"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-shopping-cart",
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2022-04-06 17:47:49.909000",
+ "modified": "2022-11-17 17:26:33.770993",
"modified_by": "Administrator",
"module": "Buying",
"name": "Request for Quotation",
@@ -345,5 +352,6 @@
"search_fields": "status, transaction_date",
"show_name_in_global_search": 1,
"sort_field": "modified",
- "sort_order": "DESC"
-}
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
index 1636561..7776ab8 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
@@ -45,6 +45,7 @@
"tax_category",
"column_break_36",
"shipping_rule",
+ "incoterm",
"section_break_38",
"taxes",
"totals",
@@ -823,6 +824,12 @@
{
"fieldname": "column_break_85",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-shopping-cart",
@@ -830,7 +837,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2022-09-27 18:20:09.462037",
+ "modified": "2022-11-17 17:27:32.179686",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",
diff --git a/erpnext/crm/utils.py b/erpnext/crm/utils.py
index 433d974..7374520 100644
--- a/erpnext/crm/utils.py
+++ b/erpnext/crm/utils.py
@@ -120,7 +120,7 @@
todo_doc = frappe.get_doc("ToDo", todo.name)
todo_doc.reference_type = doc.doctype
todo_doc.reference_name = doc.name
- todo_doc.db_update()
+ todo_doc.save()
def link_open_events(ref_doctype, ref_docname, doc):
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index b73dee2..51bf327 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -191,7 +191,9 @@
for security, qty in pledged_securities.items():
after_haircut_percentage = 100 - hair_cut_map.get(security)
- security_value += (loan_security_price_map.get(security) * qty * after_haircut_percentage) / 100
+ security_value += (
+ loan_security_price_map.get(security, 0) * qty * after_haircut_percentage
+ ) / 100
return security_value
diff --git a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
index 27d7c41..8c61d54 100644
--- a/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
+++ b/erpnext/manufacturing/doctype/material_request_plan_item/material_request_plan_item.json
@@ -47,7 +47,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
- "label": "Warehouse",
+ "label": "For Warehouse",
"options": "Warehouse",
"reqd": 1
},
@@ -173,7 +173,7 @@
],
"istable": 1,
"links": [],
- "modified": "2021-08-23 18:17:58.400462",
+ "modified": "2022-11-26 14:59:25.879631",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Material Request Plan Item",
@@ -182,5 +182,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
+ "states": [],
"track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 59ddf1f..62715e6 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -3,13 +3,13 @@
frappe.ui.form.on('Production Plan', {
- before_save: function(frm) {
+ before_save(frm) {
// preserve temporary names on production plan item to re-link sub-assembly items
frm.doc.po_items.forEach(item => {
item.temporary_name = item.name;
});
},
- setup: function(frm) {
+ setup(frm) {
frm.custom_make_buttons = {
'Work Order': 'Work Order / Subcontract PO',
'Material Request': 'Material Request',
@@ -70,7 +70,7 @@
}
},
- refresh: function(frm) {
+ refresh(frm) {
if (frm.doc.docstatus === 1) {
frm.trigger("show_progress");
@@ -158,7 +158,7 @@
set_field_options("projected_qty_formula", projected_qty_formula);
},
- close_open_production_plan: (frm, close=false) => {
+ close_open_production_plan(frm, close=false) {
frappe.call({
method: "set_status",
freeze: true,
@@ -170,7 +170,7 @@
});
},
- make_work_order: function(frm) {
+ make_work_order(frm) {
frappe.call({
method: "make_work_order",
freeze: true,
@@ -181,7 +181,7 @@
});
},
- make_material_request: function(frm) {
+ make_material_request(frm) {
frappe.confirm(__("Do you want to submit the material request"),
function() {
@@ -193,7 +193,7 @@
);
},
- create_material_request: function(frm, submit) {
+ create_material_request(frm, submit) {
frm.doc.submit_material_request = submit;
frappe.call({
@@ -206,7 +206,7 @@
});
},
- get_sales_orders: function(frm) {
+ get_sales_orders(frm) {
frappe.call({
method: "get_open_sales_orders",
doc: frm.doc,
@@ -216,7 +216,7 @@
});
},
- get_material_request: function(frm) {
+ get_material_request(frm) {
frappe.call({
method: "get_pending_material_requests",
doc: frm.doc,
@@ -226,7 +226,7 @@
});
},
- get_items: function (frm) {
+ get_items(frm) {
frm.clear_table('prod_plan_references');
frappe.call({
@@ -238,7 +238,7 @@
}
});
},
- combine_items: function (frm) {
+ combine_items(frm) {
frm.clear_table("prod_plan_references");
frappe.call({
@@ -254,14 +254,14 @@
});
},
- combine_sub_items: (frm) => {
+ combine_sub_items(frm) {
if (frm.doc.sub_assembly_items.length > 0) {
frm.clear_table("sub_assembly_items");
frm.trigger("get_sub_assembly_items");
}
},
- get_sub_assembly_items: function(frm) {
+ get_sub_assembly_items(frm) {
frm.dirty();
frappe.call({
@@ -274,9 +274,25 @@
});
},
- get_items_for_mr: function(frm) {
+ toggle_for_warehouse(frm) {
+ frm.toggle_reqd("for_warehouse", true);
+ },
+
+ get_items_for_mr(frm) {
if (!frm.doc.for_warehouse) {
- frappe.throw(__("To make material requests, 'Make Material Request for Warehouse' field is mandatory"));
+ frm.trigger("toggle_for_warehouse");
+ frappe.throw(__("Select the Warehouse"));
+ }
+
+ frm.events.get_items_for_material_requests(frm, [{
+ warehouse: frm.doc.for_warehouse
+ }]);
+ },
+
+ transfer_materials(frm) {
+ if (!frm.doc.for_warehouse) {
+ frm.trigger("toggle_for_warehouse");
+ frappe.throw(__("Select the Warehouse"));
}
if (frm.doc.ignore_existing_ordered_qty) {
@@ -287,18 +303,10 @@
title: title,
fields: [
{
- 'label': __('Target Warehouse'),
- 'fieldtype': 'Link',
- 'fieldname': 'target_warehouse',
- 'read_only': true,
- 'default': frm.doc.for_warehouse
- },
- {
- 'label': __('Source Warehouses (Optional)'),
+ 'label': __('Transfer From Warehouses'),
'fieldtype': 'Table MultiSelect',
'fieldname': 'warehouses',
'options': 'Production Plan Material Request Warehouse',
- 'description': __('If source warehouse selected then system will create the material request with type Material Transfer from Source to Target warehouse. If not selected then will create the material request with type Purchase for the target warehouse.'),
get_query: function () {
return {
filters: {
@@ -307,6 +315,13 @@
};
},
},
+ {
+ 'label': __('For Warehouse'),
+ 'fieldtype': 'Link',
+ 'fieldname': 'target_warehouse',
+ 'read_only': true,
+ 'default': frm.doc.for_warehouse
+ }
]
});
@@ -320,8 +335,8 @@
}
},
- get_items_for_material_requests: function(frm, warehouses) {
- const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse',
+ get_items_for_material_requests(frm, warehouses) {
+ let set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 'from_warehouse',
'min_order_qty', 'required_bom_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'ordered_qty',
'reserved_qty_for_production', 'material_request_type'];
@@ -335,13 +350,13 @@
callback: function(r) {
if(r.message) {
frm.set_value('mr_items', []);
- $.each(r.message, function(i, d) {
- var item = frm.add_child('mr_items');
- for (let key in d) {
- if (d[key] && in_list(set_fields, key)) {
- item[key] = d[key];
+ r.message.forEach(row => {
+ let d = frm.add_child('mr_items');
+ set_fields.forEach(field => {
+ if (row[field]) {
+ d[field] = row[field];
}
- }
+ });
});
}
refresh_field('mr_items');
@@ -349,13 +364,7 @@
});
},
- for_warehouse: function(frm) {
- if (frm.doc.mr_items && frm.doc.for_warehouse) {
- frm.trigger("get_items_for_mr");
- }
- },
-
- download_materials_required: function(frm) {
+ download_materials_required(frm) {
const fields = [{
fieldname: 'warehouses',
fieldtype: 'Table MultiSelect',
@@ -381,7 +390,7 @@
}, __('Select Warehouses to get Stock for Materials Planning'), __('Get Stock'));
},
- show_progress: function(frm) {
+ show_progress(frm) {
var bars = [];
var message = '';
var title = '';
@@ -416,7 +425,7 @@
});
frappe.ui.form.on("Production Plan Item", {
- item_code: function(frm, cdt, cdn) {
+ item_code(frm, cdt, cdn) {
const row = locals[cdt][cdn];
if (row.item_code) {
frappe.call({
@@ -435,7 +444,7 @@
});
frappe.ui.form.on("Material Request Plan Item", {
- warehouse: function(frm, cdt, cdn) {
+ warehouse(frm, cdt, cdn) {
const row = locals[cdt][cdn];
if (row.warehouse && row.item_code && frm.doc.company) {
frappe.call({
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.json b/erpnext/manufacturing/doctype/production_plan/production_plan.json
index 85f9843..2624daa 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.json
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.json
@@ -38,6 +38,8 @@
"get_sub_assembly_items",
"combine_sub_items",
"sub_assembly_items",
+ "download_materials_request_plan_section_section",
+ "download_materials_required",
"material_request_planning",
"include_non_stock_items",
"include_subcontracted_items",
@@ -45,8 +47,8 @@
"ignore_existing_ordered_qty",
"column_break_25",
"for_warehouse",
- "download_materials_required",
"get_items_for_mr",
+ "transfer_materials",
"section_break_27",
"mr_items",
"other_details",
@@ -206,7 +208,7 @@
{
"fieldname": "material_request_planning",
"fieldtype": "Section Break",
- "label": "Material Requirement Planning"
+ "label": "Material Request Planning"
},
{
"default": "1",
@@ -235,12 +237,12 @@
"depends_on": "eval:!doc.__islocal",
"fieldname": "download_materials_required",
"fieldtype": "Button",
- "label": "Download Required Materials"
+ "label": "Download Materials Request Plan"
},
{
"fieldname": "get_items_for_mr",
"fieldtype": "Button",
- "label": "Get Raw Materials For Production"
+ "label": "Get Raw Materials for Purchase"
},
{
"fieldname": "section_break_27",
@@ -304,7 +306,7 @@
{
"fieldname": "for_warehouse",
"fieldtype": "Link",
- "label": "Make Material Request for Warehouse",
+ "label": "Raw Materials Warehouse",
"options": "Warehouse"
},
{
@@ -378,13 +380,24 @@
"fieldname": "combine_sub_items",
"fieldtype": "Check",
"label": "Consolidate Sub Assembly Items"
+ },
+ {
+ "fieldname": "transfer_materials",
+ "fieldtype": "Button",
+ "label": "Get Raw Materials for Transfer"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "download_materials_request_plan_section_section",
+ "fieldtype": "Section Break",
+ "label": "Download Materials Request Plan Section"
}
],
"icon": "fa fa-calendar",
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
- "modified": "2022-03-25 09:15:25.017664",
+ "modified": "2022-11-26 14:51:08.774372",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index caff0a3..0cc0f80 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -312,6 +312,9 @@
def add_items(self, items):
refs = {}
for data in items:
+ if not data.pending_qty:
+ continue
+
item_details = get_item_details(data.item_code)
if self.combine_items:
if item_details.bom_no in refs:
@@ -518,6 +521,9 @@
subcontracted_po.setdefault(row.supplier, []).append(row)
continue
+ if row.type_of_manufacturing == "Material Request":
+ continue
+
work_order_data = {
"wip_warehouse": default_warehouses.get("wip_warehouse"),
"fg_warehouse": default_warehouses.get("fg_warehouse"),
@@ -1158,6 +1164,7 @@
subquery = frappe.qb.from_(wh).select(wh.name).where(wh.company == company)
+ warehouse = ""
if not all_warehouse:
warehouse = for_warehouse or row.get("source_warehouse") or row.get("default_warehouse")
@@ -1223,6 +1230,21 @@
doc["mr_items"] = []
po_items = doc.get("po_items") if doc.get("po_items") else doc.get("items")
+
+ if doc.get("sub_assembly_items"):
+ for sa_row in doc.sub_assembly_items:
+ sa_row = frappe._dict(sa_row)
+ if sa_row.type_of_manufacturing == "Material Request":
+ po_items.append(
+ frappe._dict(
+ {
+ "item_code": sa_row.production_item,
+ "required_qty": sa_row.qty,
+ "include_exploded_items": 0,
+ }
+ )
+ )
+
# Check for empty table or empty rows
if not po_items or not [row.get("item_code") for row in po_items if row.get("item_code")]:
frappe.throw(
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index a6d034d..2bf14c2 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -840,6 +840,34 @@
self.assertEqual(row.uom, "Nos")
self.assertEqual(row.qty, 1)
+ def test_material_request_for_sub_assembly_items(self):
+ from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+
+ bom_tree = {
+ "Fininshed Goods1 For MR": {
+ "SubAssembly1 For MR": {"SubAssembly1-1 For MR": {"ChildPart1 For MR": {}}}
+ }
+ }
+
+ parent_bom = create_nested_bom(bom_tree, prefix="")
+ plan = create_production_plan(
+ item_code=parent_bom.item, planned_qty=10, ignore_existing_ordered_qty=1, do_not_submit=1
+ )
+
+ plan.get_sub_assembly_items()
+
+ mr_items = []
+ for row in plan.sub_assembly_items:
+ mr_items.append(row.production_item)
+ row.type_of_manufacturing = "Material Request"
+
+ plan.save()
+ items = get_items_for_material_requests(plan.as_dict())
+
+ validate_mr_items = [d.get("item_code") for d in items]
+ for item_code in mr_items:
+ self.assertTrue(item_code in validate_mr_items)
+
def create_production_plan(**args):
"""
diff --git a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
index df5862f..0688278 100644
--- a/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_item/production_plan_item.json
@@ -83,7 +83,7 @@
"fieldname": "warehouse",
"fieldtype": "Link",
"in_list_view": 1,
- "label": "For Warehouse",
+ "label": "FG Warehouse",
"options": "Warehouse"
},
{
@@ -216,7 +216,7 @@
"idx": 1,
"istable": 1,
"links": [],
- "modified": "2022-03-24 04:54:09.940224",
+ "modified": "2022-11-25 14:15:40.061514",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan Item",
diff --git a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
index 45ea26c..4eb6bf6 100644
--- a/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
+++ b/erpnext/manufacturing/doctype/production_plan_sub_assembly_item/production_plan_sub_assembly_item.json
@@ -169,7 +169,7 @@
"fieldtype": "Select",
"in_list_view": 1,
"label": "Manufacturing Type",
- "options": "In House\nSubcontract"
+ "options": "In House\nSubcontract\nMaterial Request"
},
{
"fieldname": "supplier",
@@ -188,7 +188,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2022-01-30 21:31:10.527559",
+ "modified": "2022-11-28 13:50:15.116082",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Plan Sub Assembly Item",
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.js b/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
index cb771e4..782ce81 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.js
@@ -54,11 +54,11 @@
options: ["", "Open", "Work In Progress", "Completed", "On Hold"]
},
{
- label: __("Sales Orders"),
- fieldname: "sales_order",
+ label: __("Work Orders"),
+ fieldname: "work_order",
fieldtype: "MultiSelectList",
get_data: function(txt) {
- return frappe.db.get_link_options('Sales Order', txt);
+ return frappe.db.get_link_options('Work Order', txt);
}
},
{
diff --git a/erpnext/manufacturing/report/job_card_summary/job_card_summary.py b/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
index 63c2d97..8d72ef1 100644
--- a/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
+++ b/erpnext/manufacturing/report/job_card_summary/job_card_summary.py
@@ -36,10 +36,14 @@
"total_time_in_mins",
]
- for field in ["work_order", "workstation", "operation", "status", "company"]:
+ for field in ["work_order", "production_item"]:
if filters.get(field):
query_filters[field] = ("in", filters.get(field))
+ for field in ["workstation", "operation", "status", "company"]:
+ if filters.get(field):
+ query_filters[field] = filters.get(field)
+
data = frappe.get_all("Job Card", fields=fields, filters=query_filters)
if not data:
diff --git a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
index 41ffcbb..b69ad07 100644
--- a/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
+++ b/erpnext/manufacturing/report/work_order_summary/work_order_summary.py
@@ -39,10 +39,14 @@
"lead_time",
]
- for field in ["sales_order", "production_item", "status", "company"]:
+ for field in ["sales_order", "production_item"]:
if filters.get(field):
query_filters[field] = ("in", filters.get(field))
+ for field in ["status", "company"]:
+ if filters.get(field):
+ query_filters[field] = filters.get(field)
+
query_filters["planned_start_date"] = (">=", filters.get("from_date"))
query_filters["planned_end_date"] = ("<=", filters.get("to_date"))
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 639809d..166faf9 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -317,3 +317,4 @@
erpnext.patches.v13_0.update_schedule_type_in_loans
erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
erpnext.patches.v14_0.update_partial_tds_fields
+erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
diff --git a/erpnext/patches/v14_0/create_incoterms_and_migrate_shipment.py b/erpnext/patches/v14_0/create_incoterms_and_migrate_shipment.py
new file mode 100644
index 0000000..6e1e09a
--- /dev/null
+++ b/erpnext/patches/v14_0/create_incoterms_and_migrate_shipment.py
@@ -0,0 +1,31 @@
+import frappe
+
+from erpnext.setup.doctype.incoterm.incoterm import create_incoterms
+
+
+def execute():
+ create_incoterms()
+ migrate_shipments()
+
+
+def migrate_shipments():
+ if not frappe.db.count("Shipment"):
+ return
+
+ OLD_VALUES = [
+ "EXW (Ex Works)",
+ "FCA (Free Carrier)",
+ "FOB (Free On Board)",
+ "FAS (Free Alongside Ship)",
+ "CPT (Carriage Paid To)",
+ "CIP (Carriage and Insurance Paid to)",
+ "CFR (Cost and Freight)",
+ "DPU (Delivered At Place Unloaded)",
+ "DAP (Delivered At Place)",
+ "DDP (Delivered Duty Paid)",
+ ]
+ shipment = frappe.qb.DocType("Shipment")
+ for old_value in OLD_VALUES:
+ frappe.qb.update(shipment).set(shipment.incoterm, old_value[:3]).where(
+ shipment.incoterm == old_value
+ ).run()
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index fa64b16..08918f4 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -48,6 +48,7 @@
"tax_category",
"column_break_34",
"shipping_rule",
+ "incoterm",
"section_break_36",
"taxes",
"section_break_39",
@@ -1052,13 +1053,19 @@
{
"fieldname": "column_break_108",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-shopping-cart",
"idx": 82,
"is_submittable": 1,
"links": [],
- "modified": "2022-10-11 13:06:33.479650",
+ "modified": "2022-11-17 17:20:54.984348",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index e6ff39d..9ec32cb 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -63,6 +63,7 @@
"tax_category",
"column_break_49",
"shipping_rule",
+ "incoterm",
"section_break_40",
"taxes",
"section_break_43",
@@ -1623,13 +1624,19 @@
{
"fieldname": "column_break_152",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
"links": [],
- "modified": "2022-10-11 13:06:10.469796",
+ "modified": "2022-11-17 17:22:00.413878",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
diff --git a/erpnext/setup/doctype/incoterm/__init__.py b/erpnext/setup/doctype/incoterm/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/setup/doctype/incoterm/__init__.py
diff --git a/erpnext/setup/doctype/incoterm/incoterm.js b/erpnext/setup/doctype/incoterm/incoterm.js
new file mode 100644
index 0000000..bc65123
--- /dev/null
+++ b/erpnext/setup/doctype/incoterm/incoterm.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+// frappe.ui.form.on("Incoterm", {
+// refresh(frm) {
+
+// },
+// });
diff --git a/erpnext/setup/doctype/incoterm/incoterm.json b/erpnext/setup/doctype/incoterm/incoterm.json
new file mode 100644
index 0000000..c547b7c
--- /dev/null
+++ b/erpnext/setup/doctype/incoterm/incoterm.json
@@ -0,0 +1,168 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "field:code",
+ "creation": "2022-11-17 15:17:34.717467",
+ "default_view": "List",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "code",
+ "title",
+ "description"
+ ],
+ "fields": [
+ {
+ "fieldname": "code",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Code",
+ "length": 3,
+ "reqd": 1,
+ "unique": 1
+ },
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Title",
+ "reqd": 1
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Long Text",
+ "label": "Description"
+ }
+ ],
+ "links": [
+ {
+ "group": "Selling",
+ "link_doctype": "Quotation",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Selling",
+ "link_doctype": "Sales Order",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Buying",
+ "link_doctype": "Request for Quotation",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Buying",
+ "link_doctype": "Supplier Quotation",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Buying",
+ "link_doctype": "Purchase Order",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Stock",
+ "link_doctype": "Delivery Note",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Stock",
+ "link_doctype": "Purchase Receipt",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Stock",
+ "link_doctype": "Shipment",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Accounts",
+ "link_doctype": "Sales Invoice",
+ "link_fieldname": "incoterm"
+ },
+ {
+ "group": "Accounts",
+ "link_doctype": "Purchase Invoice",
+ "link_fieldname": "incoterm"
+ }
+ ],
+ "modified": "2022-11-17 22:35:52.084553",
+ "modified_by": "Administrator",
+ "module": "Setup",
+ "name": "Incoterm",
+ "naming_rule": "By fieldname",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts Manager",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Sales Manager",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Purchase Manager",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Stock Manager",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "read": 1,
+ "role": "Purchase User"
+ },
+ {
+ "read": 1,
+ "role": "Sales User"
+ },
+ {
+ "read": 1,
+ "role": "Accounts User"
+ },
+ {
+ "read": 1,
+ "role": "Stock User"
+ }
+ ],
+ "show_title_field_in_link": 1,
+ "sort_field": "name",
+ "sort_order": "ASC",
+ "states": [],
+ "title_field": "title",
+ "translated_doctype": 1
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/incoterm/incoterm.py b/erpnext/setup/doctype/incoterm/incoterm.py
new file mode 100644
index 0000000..7e2e622
--- /dev/null
+++ b/erpnext/setup/doctype/incoterm/incoterm.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe.model.document import Document
+
+
+class Incoterm(Document):
+ pass
+
+
+def create_incoterms():
+ """Create Incoterm records from incoterms.csv."""
+ import os
+ from csv import DictReader
+
+ with open(os.path.join(os.path.dirname(__file__), "incoterms.csv"), "r") as f:
+ for incoterm in DictReader(f):
+ if frappe.db.exists("Incoterm", incoterm["code"]):
+ continue
+
+ doc = frappe.new_doc("Incoterm")
+ doc.update(incoterm)
+ doc.save()
diff --git a/erpnext/setup/doctype/incoterm/incoterms.csv b/erpnext/setup/doctype/incoterm/incoterms.csv
new file mode 100644
index 0000000..af532cf
--- /dev/null
+++ b/erpnext/setup/doctype/incoterm/incoterms.csv
@@ -0,0 +1,12 @@
+code,title
+EXW,Ex Works
+FCA,Free Carrier
+FAS,Free Alongside Ship
+FOB,Free On Board
+CPT,Carriage Paid To
+CIP,Carriage and Insurance Paid to
+CFR,Cost and Freight
+CIF,"Cost, Insurance and Freight"
+DAP,Delivered At Place
+DPU,Delivered At Place Unloaded
+DDP,Delivered Duty Paid
diff --git a/erpnext/setup/doctype/incoterm/test_incoterm.py b/erpnext/setup/doctype/incoterm/test_incoterm.py
new file mode 100644
index 0000000..06b8c3b
--- /dev/null
+++ b/erpnext/setup/doctype/incoterm/test_incoterm.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestIncoterm(FrappeTestCase):
+ pass
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 2076dde..d3b47f9 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -10,6 +10,7 @@
from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS
from erpnext.setup.default_energy_point_rules import get_default_energy_point_rules
+from erpnext.setup.doctype.incoterm.incoterm import create_incoterms
from .default_success_action import get_default_success_action
@@ -25,6 +26,7 @@
create_default_cash_flow_mapper_templates()
create_default_success_action()
create_default_energy_point_rules()
+ create_incoterms()
add_company_to_session_defaults()
add_standard_navbar_items()
add_app_name()
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 0ca3e69..80e4bcb 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -62,6 +62,7 @@
"tax_category",
"column_break_39",
"shipping_rule",
+ "incoterm",
"section_break_41",
"taxes",
"section_break_44",
@@ -1381,13 +1382,19 @@
{
"fieldname": "column_break_18",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-truck",
"idx": 146,
"is_submittable": 1,
"links": [],
- "modified": "2022-10-11 13:06:58.655635",
+ "modified": "2022-11-17 17:22:42.860790",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index e68b0ab..5f05de6 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -370,9 +370,6 @@
if (flt(d.qty) < flt(d.min_order_qty)) {
frappe.msgprint(__("Warning: Material Requested Qty is less than Minimum Order Qty"));
}
-
- const item = locals[doctype][name];
- frm.events.get_item_data(frm, item, false);
},
from_warehouse: function(frm, doctype, name) {
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index 3141212..ab91d7c 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -63,6 +63,7 @@
"tax_category",
"column_break_53",
"shipping_rule",
+ "incoterm",
"taxes_section",
"taxes",
"totals",
@@ -1218,13 +1219,19 @@
{
"fieldname": "column_break_104",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "incoterm",
+ "fieldtype": "Link",
+ "label": "Incoterm",
+ "options": "Incoterm"
}
],
"icon": "fa fa-truck",
"idx": 261,
"is_submittable": 1,
"links": [],
- "modified": "2022-10-11 13:02:31.776256",
+ "modified": "2022-11-17 17:29:30.067536",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/shipment/shipment.json b/erpnext/stock/doctype/shipment/shipment.json
index a33cbc2..53b549d 100644
--- a/erpnext/stock/doctype/shipment/shipment.json
+++ b/erpnext/stock/doctype/shipment/shipment.json
@@ -412,9 +412,9 @@
},
{
"fieldname": "incoterm",
- "fieldtype": "Select",
+ "fieldtype": "Link",
"label": "Incoterm",
- "options": "EXW (Ex Works)\nFCA (Free Carrier)\nCPT (Carriage Paid To)\nCIP (Carriage and Insurance Paid to)\nDPU (Delivered At Place Unloaded)\nDAP (Delivered At Place)\nDDP (Delivered Duty Paid)"
+ "options": "Incoterm"
},
{
"fieldname": "shipment_delivery_note",
@@ -433,10 +433,11 @@
],
"is_submittable": 1,
"links": [],
- "modified": "2021-04-13 17:14:18.181818",
+ "modified": "2022-11-17 17:23:27.025802",
"modified_by": "Administrator",
"module": "Stock",
"name": "Shipment",
+ "naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
@@ -470,5 +471,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
+ "states": [],
"track_changes": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index cdf6e89..e7f55e9 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -263,8 +263,8 @@
def validate_item_warehouse(args):
for field in ["item_code", "warehouse", "posting_date", "posting_time"]:
- if not args.get(field):
- validation_msg = f"The field {frappe.unscrub(args.get(field))} is required for the reposting"
+ if args.get(field) in [None, ""]:
+ validation_msg = f"The field {frappe.unscrub(field)} is required for the reposting"
frappe.throw(_(validation_msg))
diff --git a/erpnext/templates/generators/item/item.html b/erpnext/templates/generators/item/item.html
index 4070d40..358c1c5 100644
--- a/erpnext/templates/generators/item/item.html
+++ b/erpnext/templates/generators/item/item.html
@@ -32,7 +32,7 @@
<div class="product-container mt-4 {{ padding_top }} {{ info_col }}">
<div class="item-content {{ 'mt-minus-2' if (show_tabs and tabs) else '' }}">
- <div class="product-page-content" itemscope itemtype="http://schema.org/Product">
+ <div class="product-page-content">
<!-- Product Specifications Table Section -->
{% if show_tabs and tabs %}
<div class="category-tabs">
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index 0caea25..0fdd3c9 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -9903,3 +9903,14 @@
Total Liability,Verbindlichkeiten,
Total Equity,Eigenkapital,
Warehouse wise Stock Value,Warenwert nach Lager,
+Ex Works,Ab Werk,
+Free Carrier,Frei Frachtführer,
+Free Alongside Ship,Frei Längsseite Schiff,
+Free on Board,Frei an Bord,
+Carriage Paid To,Frachtfrei,
+Carriage and Insurance Paid to,Frachtfrei versichert,
+Cost and Freight,Kosten und Fracht,
+"Cost, Insurance and Freight","Kosten, Versicherung und Fracht",
+Delivered at Place,Geliefert benannter Ort,
+Delivered at Place Unloaded,Geliefert benannter Ort entladen,
+Delivered Duty Paid,Geliefert verzollt,