diff --git a/erpnext/__init__.py b/erpnext/__init__.py index a4647e3b0ac..7ffd424c31f 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.7' +__version__ = '10.1.8' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 90bb0bb807e..9fc37f1582d 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -139,7 +139,10 @@ def set_price_list(out, party, party_type, given_price_list): price_list = get_default_price_list(party) if not price_list: - price_list = given_price_list + if party.doctype == "Customer": + price_list = frappe.db.get_single_value('Selling Settings', 'selling_price_list') + else: + price_list = frappe.db.get_single_value('Buying Settings', 'buying_price_list') if price_list: out.price_list_currency = frappe.db.get_value("Price List", price_list, "currency") diff --git a/erpnext/agriculture/doctype/crop/crop.py b/erpnext/agriculture/doctype/crop/crop.py index 9121b544975..52594f4d5a2 100644 --- a/erpnext/agriculture/doctype/crop/crop.py +++ b/erpnext/agriculture/doctype/crop/crop.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document +from frappe import _ class Crop(Document): def validate(self): @@ -13,7 +14,7 @@ class Crop(Document): for task in self.agriculture_task: # validate start_day is not > end_day if task.start_day > task.end_day: - frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.subject)) + frappe.throw(_("Start day is greater than end day in task '{0}'").format(task.task_name)) # to calculate the period of the Crop Cycle if task.end_day > max_period: max_period = task.end_day if max_period > self.period: self.period = max_period diff --git a/erpnext/agriculture/doctype/disease/disease.py b/erpnext/agriculture/doctype/disease/disease.py index 8a0e6f33d68..c7707a54652 100644 --- a/erpnext/agriculture/doctype/disease/disease.py +++ b/erpnext/agriculture/doctype/disease/disease.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document +from frappe import _ class Disease(Document): def validate(self): diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.py b/erpnext/agriculture/doctype/soil_texture/soil_texture.py index b66d00cbfdf..8c1d7ed5ac1 100644 --- a/erpnext/agriculture/doctype/soil_texture/soil_texture.py +++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.py @@ -7,6 +7,7 @@ import frappe from frappe import _ from frappe.model.document import Document from frappe.utils import flt, cint +from frappe import _ class SoilTexture(Document): soil_edit_order = [2, 1, 0] diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.py b/erpnext/agriculture/doctype/water_analysis/water_analysis.py index bd2cd118e1d..88f1fbd9cce 100644 --- a/erpnext/agriculture/doctype/water_analysis/water_analysis.py +++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.py @@ -6,6 +6,7 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document +from frappe import _ class WaterAnalysis(Document): def load_contents(self): diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index 3635b0b58e4..fdf74ccbfbe 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -24,6 +24,15 @@ frappe.ui.form.on("Purchase Order", { frm.set_indicator_formatter('item_code', function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" }) + + frm.set_query("reserve_warehouse", "supplied_items", function() { + return { + filters: { + "company": frm.doc.company, + "is_group": 0 + } + } + }); }, onload: function(frm) { @@ -210,8 +219,8 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend( ] me.dialog = new frappe.ui.Dialog({ - title: title,fields: fields - }); + title: title, fields: fields + }); if (me.frm.doc['supplied_items']) { me.frm.doc['supplied_items'].forEach((item, index) => { diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 926331bbda6..4956b6e626c 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -407,24 +407,26 @@ def make_purchase_invoice(source_name, target_doc=None): @frappe.whitelist() def make_rm_stock_entry(purchase_order, rm_items): - if isinstance(rm_items, basestring): rm_items_list = json.loads(rm_items) else: frappe.throw(_("No Items available for transfer")) if rm_items_list: - item_code_list = list(set(d["item_code"] for d in rm_items_list)) + fg_items = list(set(d["item_code"] for d in rm_items_list)) else: frappe.throw(_("No Items selected for transfer")) if purchase_order: purchase_order = frappe.get_doc("Purchase Order", purchase_order) - if item_code_list: - item_wh = frappe._dict(frappe.db.sql("""select item_code, description - from `tabItem` where name in ({0})""". - format(", ".join(["%s"] * len(item_code_list))), item_code_list)) + if fg_items: + items = tuple(set(d["rm_item_code"] for d in rm_items_list)) + item_wh = frappe._dict(frappe.db.sql(""" + select item_code, description + from `tabItem` where name in ({0}) + """.format(", ".join(["%s"] * len(items))), items)) + stock_entry = frappe.new_doc("Stock Entry") stock_entry.purpose = "Subcontract" stock_entry.purchase_order = purchase_order.name @@ -434,20 +436,20 @@ def make_rm_stock_entry(purchase_order, rm_items): stock_entry.address_display = purchase_order.address_display stock_entry.company = purchase_order.company stock_entry.to_warehouse = purchase_order.supplier_warehouse - stock_entry.from_bom = 1 - for item_code in item_code_list: - po_item = [d for d in purchase_order.items if d.item_code == item_code][0] - bom_no = po_item.bom + + for item_code in fg_items: for rm_item_data in rm_items_list: if rm_item_data["item_code"] == item_code: - items_dict = {rm_item_data["rm_item_code"]: - {"item_name":rm_item_data["item_name"], - "description":item_wh.get(rm_item_data["rm_item_code"]), - 'qty':rm_item_data["qty"], - 'from_warehouse':rm_item_data["warehouse"], - 'stock_uom':rm_item_data["stock_uom"], - 'bom_no':bom_no}} - stock_entry.add_to_stock_entry_detail(items_dict, bom_no) + items_dict = { + rm_item_data["rm_item_code"]: { + "item_name": rm_item_data["item_name"], + "description": item_wh.get(rm_item_data["rm_item_code"]), + 'qty': rm_item_data["qty"], + 'from_warehouse': rm_item_data["warehouse"], + 'stock_uom': rm_item_data["stock_uom"] + } + } + stock_entry.add_to_stock_entry_detail(items_dict) return stock_entry.as_dict() else: frappe.throw(_("No Items selected for transfer")) diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 1df4a7d30d7..5dacfc268ff 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -199,8 +199,9 @@ class TestPurchaseOrder(unittest.TestCase): bin2 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1) - self.assertEqual(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10) - self.assertEqual(bin2.projected_qty, bin1.projected_qty - 10) + + self.assertEquals(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10) + self.assertEquals(bin2.projected_qty, bin1.projected_qty - 10) # Create stock transfer rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item", @@ -215,7 +216,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) + self.assertEquals(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # close PO po.update_status("Closed") @@ -223,7 +224,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) + self.assertEquals(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) # Re-open PO po.update_status("Submitted") @@ -231,7 +232,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) + self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # make Purchase Receipt against PO pr = make_purchase_receipt(po.name) @@ -243,7 +244,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) + self.assertEquals(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) # Cancel PR pr.cancel() @@ -251,7 +252,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) + self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # Make Purchase Invoice pi = make_purchase_invoice(po.name) @@ -263,7 +264,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) + self.assertEquals(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) # Cancel PR pi.cancel() @@ -271,14 +272,15 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) + self.assertEquals(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # Cancel Stock Entry se.cancel() bin10 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10) + + self.assertEquals(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10) # Cancel PO po.reload() @@ -287,7 +289,7 @@ class TestPurchaseOrder(unittest.TestCase): filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) - self.assertEqual(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) + self.assertEquals(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) def get_same_items(): return [ diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index 4b8bbee7497..ab189cf1afe 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -239,6 +239,7 @@ def make_return_doc(doctype, source_name, target_doc=None): target_doc.received_qty = -1* source_doc.received_qty target_doc.rejected_qty = -1* source_doc.rejected_qty target_doc.qty = -1* source_doc.qty + target_doc.stock_qty = -1 * source_doc.stock_qty target_doc.purchase_order = source_doc.purchase_order target_doc.purchase_order_item = source_doc.purchase_order_item target_doc.rejected_warehouse = source_doc.rejected_warehouse @@ -246,6 +247,7 @@ def make_return_doc(doctype, source_name, target_doc=None): target_doc.received_qty = -1* source_doc.received_qty target_doc.rejected_qty = -1* source_doc.rejected_qty target_doc.qty = -1* source_doc.qty + target_doc.stock_qty = -1 * source_doc.stock_qty target_doc.purchase_order = source_doc.purchase_order target_doc.purchase_receipt = source_doc.purchase_receipt target_doc.rejected_warehouse = source_doc.rejected_warehouse diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index b46c752aa64..df0fec833d9 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -156,6 +156,9 @@ class StatusUpdater(Document): # get unique transactions to update for d in self.get_all_children(): + if hasattr(d, 'qty') and d.qty < 0 and not self.get('is_return'): + frappe.throw(_("For an item {0}, quantity must be positive number").format(d.item_code)) + if d.doctype == args['source_dt'] and d.get(args["join_field"]): args['name'] = d.get(args['join_field']) diff --git a/erpnext/healthcare/doctype/physician/physician.json b/erpnext/healthcare/doctype/physician/physician.json index 300dc9707d2..7fb1a564d78 100644 --- a/erpnext/healthcare/doctype/physician/physician.json +++ b/erpnext/healthcare/doctype/physician/physician.json @@ -40,6 +40,7 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -70,6 +71,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -100,6 +102,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -126,10 +129,11 @@ "print_hide_if_no_value": 0, "read_only": 0, "remember_last_selected_value": 0, - "report_hide": 1, + "report_hide": 0, "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -161,6 +165,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -192,6 +197,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -223,6 +229,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -254,6 +261,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -283,6 +291,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -313,6 +322,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -343,6 +353,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -373,6 +384,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -403,6 +415,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -433,6 +446,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -464,6 +478,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -494,6 +509,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -525,6 +541,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -555,6 +572,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -585,6 +603,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -614,6 +633,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -644,6 +664,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -674,6 +695,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -705,6 +727,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { @@ -736,6 +759,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], diff --git a/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py b/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py index 658cabb9209..681296de888 100644 --- a/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py +++ b/erpnext/patches/v10_0/update_reserved_qty_for_purchase_order.py @@ -1,5 +1,4 @@ import frappe -from frappe import _ from erpnext.stock.utils import get_bin def execute(): @@ -24,7 +23,7 @@ def execute(): # Update reserved warehouse for item in po_item: reserve_warehouse = get_warehouse(item.rm_item_code, item.company, company_warehouse, item_wh) - update_res_warehouse = frappe.db.sql("""update `tabPurchase Order Item Supplied` + frappe.db.sql("""update `tabPurchase Order Item Supplied` set reserve_warehouse = %s where parent = %s and rm_item_code = %s """, (reserve_warehouse, item["poname"], item["rm_item_code"])) diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 06c00539bff..d4b015a9f69 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -567,7 +567,6 @@ class TestStockEntry(unittest.TestCase): for d in stock_entry.get("items"): if d.item_code != "_Test FG Item 2": rm_cost += flt(d.amount) - fg_cost = filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items"))[0].amount self.assertEqual(fg_cost, flt(rm_cost + bom_operation_cost + production_order.additional_operating_cost, 2))