diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py index c5d2b3114ba..3a713042cff 100644 --- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py @@ -129,7 +129,7 @@ def get_serial_no_for_item(args): "name": args.name, "serial_no": args.serial_no }) - if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and args.qty > 0: + if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and args.stock_qty > 0: item_details.serial_no = get_serial_no(args) return item_details diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 890641b8737..b1fe0bec844 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -790,11 +790,11 @@ def make_delivery_note(source_name, target_doc=None): target.run_method("calculate_taxes_and_totals") def update_item(source_doc, target_doc, source_parent): - target_doc.base_amount = (flt(source_doc.qty) - flt(source_doc.delivered_qty)) * \ - flt(source_doc.base_rate) - target_doc.amount = (flt(source_doc.qty) - flt(source_doc.delivered_qty)) * \ - flt(source_doc.rate) target_doc.qty = flt(source_doc.qty) - flt(source_doc.delivered_qty) + target_doc.stock_qty = target_doc.qty * flt(source_doc.conversion_factor) + + target_doc.base_amount = target_doc.qty * flt(source_doc.base_rate) + target_doc.amount = target_doc.qty * flt(source_doc.rate) doclist = get_mapped_doc("Sales Invoice", source_name, { "Sales Invoice": { diff --git a/erpnext/accounts/doctype/sales_invoice/test_records.json b/erpnext/accounts/doctype/sales_invoice/test_records.json index e58c5ab0026..732c4465a80 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_records.json +++ b/erpnext/accounts/doctype/sales_invoice/test_records.json @@ -20,7 +20,10 @@ "item_name": "138-CMS Shoe", "parentfield": "items", "qty": 1.0, - "rate": 500.0 + "rate": 500.0, + "uom": "_Test UOM", + "conversion_factor": 1, + "stock_uom": "_Test UOM" } ], "base_grand_total": 561.8, @@ -89,7 +92,10 @@ "item_name": "_Test Item", "parentfield": "items", "price_list_rate": 500.0, - "qty": 1.0 + "qty": 1.0, + "uom": "_Test UOM", + "conversion_factor": 1, + "stock_uom": "_Test UOM" } ], "base_grand_total": 630.0, @@ -141,6 +147,8 @@ "price_list_rate": 50, "qty": 10, "rate": 50, + "uom": "_Test UOM", + "conversion_factor": 1, "stock_uom": "_Test UOM" }, { @@ -153,6 +161,8 @@ "parentfield": "items", "price_list_rate": 150, "qty": 5, + "uom": "_Test UOM", + "conversion_factor": 1, "rate": 150, "stock_uom": "_Test UOM" } @@ -263,7 +273,10 @@ "parentfield": "items", "price_list_rate": 62.5, "qty": 10, + "uom": "_Test UOM", + "conversion_factor": 1, "stock_uom": "_Test UOM" + }, { "cost_center": "_Test Cost Center - _TC", @@ -275,6 +288,8 @@ "parentfield": "items", "price_list_rate": 190.66, "qty": 5, + "uom": "_Test UOM", + "conversion_factor": 1, "stock_uom": "_Test UOM" } ], diff --git a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json index 42190533c31..64debd3c6a7 100644 --- a/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json +++ b/erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json @@ -366,8 +366,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "price_list_rate", - "fieldtype": "Currency", + "fieldname": "stock_uom", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -375,14 +375,12 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Price List Rate", + "label": "Stock UOM", "length": 0, "no_copy": 0, - "oldfieldname": "ref_rate", - "oldfieldtype": "Currency", - "options": "currency", + "options": "UOM", "permlevel": 0, - "print_hide": 1, + "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, "remember_last_selected_value": 0, @@ -424,7 +422,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "stock_uom", + "fieldname": "uom", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -438,8 +436,97 @@ "no_copy": 0, "options": "UOM", "permlevel": 0, + "precision": "", "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "conversion_factor", + "fieldtype": "Float", + "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": "UOM Conversion Factor", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_17", + "fieldtype": "Section Break", + "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, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "price_list_rate", + "fieldtype": "Currency", + "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": "Price List Rate", + "length": 0, + "no_copy": 0, + "oldfieldname": "ref_rate", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, @@ -1820,6 +1907,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "stock_qty", + "fieldtype": "Float", + "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": "Qty as per Stock UOM", + "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, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1976,7 +2092,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-02-17 16:28:57.719409", + "modified": "2017-02-22 01:46:28.390397", "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Item", diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py index df6cb3c33a6..3c566e9b275 100644 --- a/erpnext/accounts/report/gross_profit/gross_profit.py +++ b/erpnext/accounts/report/gross_profit/gross_profit.py @@ -254,7 +254,7 @@ class GrossProfitGenerator(object): si.customer, si.customer_group, si.territory, item.item_code, item.item_name, item.description, item.warehouse, item.item_group, item.brand, item.dn_detail, item.delivery_note, - item.qty, item.base_net_rate, item.base_net_amount, item.name as "item_row", + item.stock_qty as qty, item.base_net_rate, item.base_net_amount, item.name as "item_row", sales.sales_person, sales.allocated_amount, sales.incentives from `tabSales Invoice` si inner join `tabSales Invoice Item` item on item.parent = si.name diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 46a59b7146f..b6b147cfd26 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -107,26 +107,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ this.price_list_rate(doc, cdt, cdn); }, - uom: function(doc, cdt, cdn) { - var me = this; - var item = frappe.get_doc(cdt, cdn); - if(item.item_code && item.uom) { - return this.frm.call({ - method: "erpnext.stock.get_item_details.get_conversion_factor", - child: item, - args: { - item_code: item.item_code, - uom: item.uom - }, - callback: function(r) { - if(!r.exc) { - me.conversion_factor(me.frm.doc, cdt, cdn); - } - } - }); - } - }, - qty: function(doc, cdt, cdn) { var item = frappe.get_doc(cdt, cdn); if ((doc.doctype == "Purchase Receipt") || (doc.doctype == "Purchase Invoice" && doc.update_stock)) { @@ -140,8 +120,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ } this._super(doc, cdt, cdn); - this.conversion_factor(doc, cdt, cdn); - }, received_qty: function(doc, cdt, cdn) { @@ -160,15 +138,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ this.qty(doc, cdt, cdn); }, - conversion_factor: function(doc, cdt, cdn) { - if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) { - var item = frappe.get_doc(cdt, cdn); - frappe.model.round_floats_in(item, ["qty", "conversion_factor"]); - item.stock_qty = flt(item.qty * item.conversion_factor, precision("stock_qty", item)); - refresh_field("stock_qty", item.name, item.parentfield); - } - }, - warehouse: function(doc, cdt, cdn) { var item = frappe.get_doc(cdt, cdn); if(item.item_code && item.warehouse) { diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 60cd68c6350..5f50ae32a24 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -9,6 +9,7 @@ from frappe import _, throw from erpnext.stock.get_item_details import get_bin_details from erpnext.stock.utils import get_incoming_rate from erpnext.stock.stock_ledger import get_valuation_rate +from erpnext.stock.get_item_details import get_conversion_factor from erpnext.controllers.stock_controller import StockController @@ -34,6 +35,7 @@ class SellingController(StockController): super(SellingController, self).validate() self.validate_max_discount() self.validate_selling_price() + self.set_qty_as_per_stock_uom() check_active_sales_items(self) def set_missing_values(self, for_validate=False): @@ -163,6 +165,13 @@ class SellingController(StockController): if discount and flt(d.discount_percentage) > discount: frappe.throw(_("Maxiumm discount for Item {0} is {1}%").format(d.item_code, discount)) + def set_qty_as_per_stock_uom(self): + for d in self.get("items"): + if d.meta.get_field("stock_qty"): + if not d.conversion_factor: + frappe.throw(_("Row {0}: Conversion Factor is mandatory").format(d.idx)) + d.stock_qty = flt(d.qty) * flt(d.conversion_factor) + def validate_selling_price(self): def throw_message(item_name, rate, ref_rate_field): frappe.throw(_("""Selling price for item {0} is lower than its {1}. Selling price should be atleast {2}""") @@ -211,9 +220,10 @@ class SellingController(StockController): il.append(frappe._dict({ 'warehouse': d.warehouse, 'item_code': d.item_code, - 'qty': d.qty, - 'uom': d.stock_uom, + 'qty': d.stock_qty, + 'uom': d.uom, 'stock_uom': d.stock_uom, + 'conversion_factor': d.conversion_factor, 'batch_no': cstr(d.get("batch_no")).strip(), 'serial_no': cstr(d.get("serial_no")).strip(), 'name': d.name, @@ -282,6 +292,8 @@ class SellingController(StockController): sl_entries = [] for d in self.get_item_list(): if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1 and flt(d.qty): + if flt(d.conversion_factor)==0.0: + d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0 return_rate = 0 if cint(self.is_return) and self.return_against and self.docstatus==1: return_rate = self.get_incoming_rate_for_sales_return(d.item_code, self.return_against) diff --git a/erpnext/controllers/trends.py b/erpnext/controllers/trends.py index d991c15b0dc..c5db2239b3e 100644 --- a/erpnext/controllers/trends.py +++ b/erpnext/controllers/trends.py @@ -147,9 +147,9 @@ def period_wise_columns_query(filters, trans): else: pwc = [_(filters.get("fiscal_year")) + " ("+_("Qty") + "):Float:120", _(filters.get("fiscal_year")) + " ("+ _("Amt") + "):Currency:120"] - query_details = " SUM(t2.qty), SUM(t2.base_net_amount)," + query_details = " SUM(t2.stock_qty), SUM(t2.base_net_amount)," - query_details += 'SUM(t2.qty), SUM(t2.base_net_amount)' + query_details += 'SUM(t2.stock_qty), SUM(t2.base_net_amount)' return pwc, query_details def get_period_wise_columns(bet_dates, period, pwc): @@ -161,7 +161,7 @@ def get_period_wise_columns(bet_dates, period, pwc): _(get_mon(bet_dates[0])) + "-" + _(get_mon(bet_dates[1])) + " (" + _("Amt") + "):Currency:120"] def get_period_wise_query(bet_dates, trans_date, query_details): - query_details += """SUM(IF(t1.%(trans_date)s BETWEEN '%(sd)s' AND '%(ed)s', t2.qty, NULL)), + query_details += """SUM(IF(t1.%(trans_date)s BETWEEN '%(sd)s' AND '%(ed)s', t2.stock_qty, NULL)), SUM(IF(t1.%(trans_date)s BETWEEN '%(sd)s' AND '%(ed)s', t2.base_net_amount, NULL)), """ % {"trans_date": trans_date, "sd": bet_dates[0],"ed": bet_dates[1]} return query_details diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index b39530097e7..af9fff13745 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -90,7 +90,7 @@ class ProductionOrder(Document): total_qty = flt(ordered_qty_against_so) + flt(self.qty) # get qty from Sales Order Item table - so_item_qty = frappe.db.sql("""select sum(qty) from `tabSales Order Item` + so_item_qty = frappe.db.sql("""select sum(stock_qty) from `tabSales Order Item` where parent = %s and item_code = %s""", (self.sales_order, self.production_item))[0][0] # get qty from Packing Item table diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py index 4692118cad3..3ece5faccb0 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -134,7 +134,7 @@ class ProductionPlanningTool(Document): item_condition = ' and so_item.item_code = "{0}"'.format(frappe.db.escape(self.fg_item)) items = frappe.db.sql("""select distinct parent, item_code, warehouse, - (qty - delivered_qty) as pending_qty + (qty - delivered_qty)*conversion_factor as pending_qty from `tabSales Order Item` so_item where parent in (%s) and docstatus = 1 and qty > delivered_qty and exists (select name from `tabBOM` bom where bom.item=so_item.item_code diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 59b2ca07aa7..0e34ee61b34 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -378,3 +378,4 @@ erpnext.patches.v7_2.rename_att_date_attendance erpnext.patches.v7_2.update_attendance_docstatus erpnext.patches.v7_2.move_dates_from_salary_structure_to_employee erpnext.patches.v7_2.make_all_assessment_group +erpnext.patches.v7_2.stock_uom_in_selling diff --git a/erpnext/patches/v7_2/stock_uom_in_selling.py b/erpnext/patches/v7_2/stock_uom_in_selling.py new file mode 100644 index 00000000000..51d6ea74236 --- /dev/null +++ b/erpnext/patches/v7_2/stock_uom_in_selling.py @@ -0,0 +1,13 @@ +import frappe + +def execute(): + frappe.reload_doctype('Sales Order') + frappe.reload_doctype('Sales Invoice') + frappe.reload_doctype('Quotation') + frappe.reload_doctype('Delivery Note') + + doctype_list = ['Sales Order Item', 'Delivery Note Item', 'Quotation Item', 'Sales Invoice Item'] + + for doctype in doctype_list: + frappe.db.sql("""update `tab{doctype}` + set uom = stock_uom, conversion_factor = 1, stock_qty = qty""".format(doctype=doctype)) \ No newline at end of file diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index 4e082870042..02732d24611 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -274,7 +274,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ doctype: me.frm.doc.doctype, name: me.frm.doc.name, project: item.project || me.frm.doc.project, - qty: item.qty + qty: item.qty, + stock_qty: item.stock_qty } }, @@ -318,7 +319,9 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ refresh_field("serial_no", item.name, item.parentfield); if(!doc.is_return) { - frappe.model.set_value(item.doctype, item.name, "qty", sr_no.length); + frappe.model.set_value(item.doctype, item.name, + "qty", sr_no.length / item.conversion_factor); + frappe.model.set_value(item.doctype, item.name, "stock_qty", sr_no.length); } } } @@ -537,8 +540,38 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }, + uom: function(doc, cdt, cdn) { + var me = this; + var item = frappe.get_doc(cdt, cdn); + if(item.item_code && item.uom) { + return this.frm.call({ + method: "erpnext.stock.get_item_details.get_conversion_factor", + child: item, + args: { + item_code: item.item_code, + uom: item.uom + }, + callback: function(r) { + if(!r.exc) { + me.conversion_factor(me.frm.doc, cdt, cdn); + } + } + }); + } + }, + + conversion_factor: function(doc, cdt, cdn) { + if(frappe.meta.get_docfield(cdt, "stock_qty", cdn)) { + var item = frappe.get_doc(cdt, cdn); + frappe.model.round_floats_in(item, ["qty", "conversion_factor"]); + item.stock_qty = flt(item.qty * item.conversion_factor, precision("stock_qty", item)); + refresh_field("stock_qty", item.name, item.parentfield); + } + }, + qty: function(doc, cdt, cdn) { this.apply_pricing_rule(frappe.get_doc(cdt, cdn), true); + this.conversion_factor(doc, cdt, cdn); }, set_dynamic_labels: function() { @@ -995,7 +1028,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ set_gross_profit: function(item) { if (this.frm.doc.doctype == "Sales Order" && item.valuation_rate) { rate = flt(item.rate) * flt(this.frm.doc.conversion_rate || 1); - item.gross_profit = flt(((rate - item.valuation_rate) * item.qty), precision("amount", item)); + item.gross_profit = flt(((rate - item.valuation_rate) * item.stock_qty), precision("amount", item)); } }, diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 56a365edc62..d32fe77d8ea 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe from frappe.model.mapper import get_mapped_doc +from frappe.utils import flt from frappe import _ from erpnext.controllers.selling_controller import SellingController @@ -100,6 +101,9 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False): target.run_method("set_missing_values") target.run_method("calculate_taxes_and_totals") + def update_item(obj, target, source_parent): + target.stock_qty = flt(obj.qty) * flt(obj.conversion_factor) + doclist = get_mapped_doc("Quotation", source_name, { "Quotation": { "doctype": "Sales Order", @@ -111,7 +115,8 @@ def _make_sales_order(source_name, target_doc=None, ignore_permissions=False): "doctype": "Sales Order Item", "field_map": { "parent": "prevdoc_docname" - } + }, + "postprocess": update_item }, "Sales Taxes and Charges": { "doctype": "Sales Taxes and Charges", diff --git a/erpnext/selling/doctype/quotation/test_records.json b/erpnext/selling/doctype/quotation/test_records.json index f173a7c6aa5..8a37dbb7d72 100644 --- a/erpnext/selling/doctype/quotation/test_records.json +++ b/erpnext/selling/doctype/quotation/test_records.json @@ -22,7 +22,10 @@ "item_name": "CPU", "parentfield": "items", "qty": 10.0, - "rate": 100.0 + "rate": 100.0, + "uom": "_Test UOM", + "stock_uom": "_Test UOM", + "conversion_factor": 1.0 } ], "quotation_to": "Customer", diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json index 254e6c348bf..51c0978e9e9 100644 --- a/erpnext/selling/doctype/quotation_item/quotation_item.json +++ b/erpnext/selling/doctype/quotation_item/quotation_item.json @@ -345,8 +345,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "price_list_rate", - "fieldtype": "Currency", + "fieldname": "stock_uom", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -354,14 +354,14 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Price List Rate", + "label": "Stock UOM", "length": 0, "no_copy": 0, - "oldfieldname": "ref_rate", - "oldfieldtype": "Currency", - "options": "currency", + "oldfieldname": "stock_uom", + "oldfieldtype": "Data", + "options": "UOM", "permlevel": 0, - "print_hide": 1, + "print_hide": 0, "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 1, @@ -405,7 +405,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "stock_uom", + "fieldname": "uom", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -417,12 +417,99 @@ "label": "UOM", "length": 0, "no_copy": 0, - "oldfieldname": "stock_uom", - "oldfieldtype": "Data", "options": "UOM", "permlevel": 0, + "precision": "", "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "conversion_factor", + "fieldtype": "Float", + "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": "UOM Conversion Factor", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_16", + "fieldtype": "Section Break", + "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, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "price_list_rate", + "fieldtype": "Currency", + "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": "Price List Rate", + "length": 0, + "no_copy": 0, + "oldfieldname": "ref_rate", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 1, "remember_last_selected_value": 0, @@ -1069,6 +1156,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "stock_qty", + "fieldtype": "Float", + "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": "Qty as per Stock UOM", + "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, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1415,7 +1531,7 @@ "istable": 1, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-20 13:23:20.175080", + "modified": "2017-02-22 01:51:58.405422", "modified_by": "Administrator", "module": "Selling", "name": "Quotation Item", diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index ae59ae789a0..891f37cb282 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -29,7 +29,7 @@ frappe.ui.form.on("Sales Order", { // formatter for material request item frm.set_indicator_formatter('item_code', - function(doc) { return (doc.qty<=doc.delivered_qty) ? "green" : "orange" }) + function(doc) { return (doc.stock_qty<=doc.delivered_qty) ? "green" : "orange" }) erpnext.queries.setup_warehouse_query(frm); } diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 9aa9cadf23c..4b20ec8d811 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -33,6 +33,7 @@ class SalesOrder(SellingController): self.validate_proj_cust() self.validate_po() self.validate_uom_is_integer("stock_uom", "qty") + self.validate_uom_is_integer("uom", "qty") self.validate_for_items() self.validate_warehouse() self.validate_drop_ship() @@ -324,7 +325,7 @@ class SalesOrder(SellingController): item_code= i.item_code, bom = bom, warehouse = i.warehouse, - pending_qty= i.qty - flt(frappe.db.sql('''select sum(qty) from `tabProduction Order` + pending_qty= i.stock_qty - flt(frappe.db.sql('''select sum(qty) from `tabProduction Order` where production_item=%s and sales_order=%s''', (i.item_code, self.name))[0][0]) )) @@ -393,7 +394,8 @@ def make_material_request(source_name, target_doc=None): "doctype": "Material Request Item", "field_map": { "parent": "sales_order", - "stock_uom": "uom" + "stock_uom": "uom", + "stock_qty": "qty" }, "condition": lambda doc: not frappe.db.exists('Product Bundle', doc.item_code), "postprocess": update_item @@ -616,6 +618,7 @@ def make_purchase_order_for_drop_shipment(source_name, for_supplier, target_doc= def update_item(source, target, source_parent): target.schedule_date = source_parent.delivery_date target.qty = flt(source.qty) - flt(source.ordered_qty) + target.stock_qty = (flt(source.qty) - flt(source.ordered_qty)) * flt(source.conversion_factor) doclist = get_mapped_doc("Sales Order", source_name, { "Sales Order": { @@ -636,7 +639,9 @@ def make_purchase_order_for_drop_shipment(source_name, for_supplier, target_doc= "field_map": [ ["name", "sales_order_item"], ["parent", "sales_order"], - ["uom", "stock_uom"], + ["stock_uom", "stock_uom"], + ["uom", "uom"], + ["conversion_factor", "conversion_factor"], ["delivery_date", "schedule_date"] ], "field_no_map": [ diff --git a/erpnext/selling/doctype/sales_order/test_records.json b/erpnext/selling/doctype/sales_order/test_records.json index 9df66f45d01..12e953a1b63 100644 --- a/erpnext/selling/doctype/sales_order/test_records.json +++ b/erpnext/selling/doctype/sales_order/test_records.json @@ -26,7 +26,10 @@ "parentfield": "items", "qty": 10.0, "rate": 100.0, - "warehouse": "_Test Warehouse - _TC" + "warehouse": "_Test Warehouse - _TC", + "stock_uom": "_Test UOM", + "conversion_factor": 1.0, + "uom": "_Test UOM" } ], "selling_price_list": "_Test Price List", diff --git a/erpnext/selling/doctype/sales_order_item/sales_order_item.json b/erpnext/selling/doctype/sales_order_item/sales_order_item.json index ae30450bec4..b6d0bf19656 100644 --- a/erpnext/selling/doctype/sales_order_item/sales_order_item.json +++ b/erpnext/selling/doctype/sales_order_item/sales_order_item.json @@ -345,8 +345,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "price_list_rate", - "fieldtype": "Currency", + "fieldname": "stock_uom", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -354,14 +354,14 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Price List Rate", + "label": "Stock UOM", "length": 0, "no_copy": 0, - "oldfieldname": "ref_rate", - "oldfieldtype": "Currency", - "options": "currency", + "oldfieldname": "stock_uom", + "oldfieldtype": "Data", + "options": "UOM", "permlevel": 0, - "print_hide": 1, + "print_hide": 0, "print_hide_if_no_value": 0, "print_width": "70px", "read_only": 1, @@ -405,7 +405,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "stock_uom", + "fieldname": "uom", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -417,12 +417,99 @@ "label": "UOM", "length": 0, "no_copy": 0, - "oldfieldname": "stock_uom", - "oldfieldtype": "Data", "options": "UOM", "permlevel": 0, + "precision": "", "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "conversion_factor", + "fieldtype": "Float", + "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": "UOM Conversion Factor", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_16", + "fieldtype": "Section Break", + "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, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "price_list_rate", + "fieldtype": "Currency", + "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": "Price List Rate", + "length": 0, + "no_copy": 0, + "oldfieldname": "ref_rate", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, "print_width": "70px", "read_only": 1, "remember_last_selected_value": 0, @@ -1373,6 +1460,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "stock_qty", + "fieldtype": "Float", + "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": "Qty as per Stock UOM", + "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, + "unique": 0 + }, { "allow_on_submit": 1, "bold": 0, @@ -1754,7 +1870,7 @@ "istable": 1, "max_attachments": 0, "menu_index": 0, - "modified": "2017-02-20 13:23:31.696583", + "modified": "2017-02-22 01:47:17.147012", "modified_by": "Administrator", "module": "Selling", "name": "Sales Order Item", diff --git a/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py b/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py index c7baf0cc914..e57636c8f01 100644 --- a/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py +++ b/erpnext/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py @@ -92,7 +92,7 @@ def get_achieved_details(filters, sales_person, all_sales_persons, target_item_g item_details = frappe.db.sql(""" select - sum(soi.qty * (st.allocated_percentage/100)) as qty, + sum(soi.stock_qty * (st.allocated_percentage/100)) as qty, sum(soi.base_net_amount * (st.allocated_percentage/100)) as amount, st.sales_person, MONTHNAME(so.transaction_date) as month_name from diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py index 0c6914daced..558a9af0617 100644 --- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py +++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py @@ -20,7 +20,7 @@ def execute(filters=None): data.append([ d.name, d.customer, d.territory, d.posting_date, d.item_code, item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"), - d.qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt + d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt ]) if data: @@ -48,7 +48,7 @@ def get_entries(filters): entries = frappe.db.sql(""" select dt.name, dt.customer, dt.territory, dt.%s as posting_date, dt_item.item_code, - dt_item.qty, dt_item.base_net_amount, st.sales_person, st.allocated_percentage, + dt_item.stock_qty, dt_item.base_net_amount, st.sales_person, st.allocated_percentage, dt_item.base_net_amount*st.allocated_percentage/100 as contribution_amt from `tab%s` dt, `tab%s Item` dt_item, `tabSales Team` st diff --git a/erpnext/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py b/erpnext/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py index dd3433399ea..7caed9bc46a 100644 --- a/erpnext/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py +++ b/erpnext/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py @@ -92,7 +92,7 @@ def get_achieved_details(filters, territory, item_groups): item_details = frappe.db.sql(""" select - soi.item_code, sum(soi.qty) as qty, sum(soi.base_net_amount) as amount, + soi.item_code, sum(soi.stock_qty) as qty, sum(soi.base_net_amount) as amount, MONTHNAME(so.transaction_date) as month_name from `tabSales Order Item` soi, `tabSales Order` so diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 9d9511e7cbc..da9c771b05d 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -215,7 +215,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ args: { item_code: item.item_code, warehouse: item.warehouse, - qty: item.qty, + stock_qty: item.stock_qty, serial_no: item.serial_no || "" }, callback:function(r){ diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py index 6cdd889add6..e4bbd8744e4 100644 --- a/erpnext/startup/report_data_map.py +++ b/erpnext/startup/report_data_map.py @@ -121,7 +121,7 @@ data_map = { }, "Purchase Order Item": { "columns": ["item.name as name", "item_code", "warehouse", - "(qty - received_qty) as qty"], + "(qty - received_qty)*conversion_factor as qty"], "from": "`tabPurchase Order Item` item, `tabPurchase Order` main", "conditions": ["item.parent = main.name", "main.docstatus=1", "main.status != 'Stopped'", "ifnull(warehouse, '')!=''", "qty > received_qty"], @@ -132,7 +132,7 @@ data_map = { }, "Sales Order Item": { - "columns": ["item.name as name", "item_code", "(qty - delivered_qty) as qty", "warehouse"], + "columns": ["item.name as name", "item_code", "(qty - delivered_qty)*conversion_factor as qty", "warehouse"], "from": "`tabSales Order Item` item, `tabSales Order` main", "conditions": ["item.parent = main.name", "main.docstatus=1", "main.status != 'Stopped'", "ifnull(warehouse, '')!=''", "qty > delivered_qty"], @@ -173,7 +173,7 @@ data_map = { } }, "Sales Invoice Item": { - "columns": ["name", "parent", "item_code", "qty", "base_net_amount"], + "columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"], "conditions": ["docstatus=1", "ifnull(parent, '')!=''"], "order_by": "parent", "links": { @@ -191,7 +191,7 @@ data_map = { } }, "Sales Order Item[Sales Analytics]": { - "columns": ["name", "parent", "item_code", "qty", "base_net_amount"], + "columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"], "conditions": ["docstatus=1", "ifnull(parent, '')!=''"], "order_by": "parent", "links": { @@ -209,7 +209,7 @@ data_map = { } }, "Delivery Note Item[Sales Analytics]": { - "columns": ["name", "parent", "item_code", "qty", "base_net_amount"], + "columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"], "conditions": ["docstatus=1", "ifnull(parent, '')!=''"], "order_by": "parent", "links": { @@ -241,7 +241,7 @@ data_map = { } }, "Purchase Invoice Item": { - "columns": ["name", "parent", "item_code", "qty", "base_net_amount"], + "columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"], "conditions": ["docstatus=1", "ifnull(parent, '')!=''"], "order_by": "parent", "links": { @@ -259,7 +259,7 @@ data_map = { } }, "Purchase Order Item[Purchase Analytics]": { - "columns": ["name", "parent", "item_code", "qty", "base_net_amount"], + "columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"], "conditions": ["docstatus=1", "ifnull(parent, '')!=''"], "order_by": "parent", "links": { @@ -277,7 +277,7 @@ data_map = { } }, "Purchase Receipt Item[Purchase Analytics]": { - "columns": ["name", "parent", "item_code", "qty", "base_net_amount"], + "columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"], "conditions": ["docstatus=1", "ifnull(parent, '')!=''"], "order_by": "parent", "links": { diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js index 43bd6d42bf1..1f69ad1679b 100644 --- a/erpnext/stock/dashboard/item_dashboard.js +++ b/erpnext/stock/dashboard/item_dashboard.js @@ -176,6 +176,8 @@ erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callb row.f_warehouse = dialog.get_value('target'); row.t_warehouse = dialog.get_value('target'); row.qty = dialog.get_value('qty'); + row.conversion_factor = 1; + row.transfer_qty = dialog.get_value('qty'); row.basic_rate = dialog.get_value('rate'); frappe.set_route('Form', doc.doctype, doc.name); }) diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 5e31ac3098c..3b2c44c8b7b 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -102,6 +102,7 @@ class DeliveryNote(SellingController): self.validate_for_items() self.validate_warehouse() self.validate_uom_is_integer("stock_uom", "qty") + self.validate_uom_is_integer("uom", "qty") self.validate_with_previous_doc() from erpnext.stock.doctype.packed_item.packed_item import make_packing_list diff --git a/erpnext/stock/doctype/delivery_note/test_records.json b/erpnext/stock/doctype/delivery_note/test_records.json index 9c11286b0b4..c76bab2cce5 100644 --- a/erpnext/stock/doctype/delivery_note/test_records.json +++ b/erpnext/stock/doctype/delivery_note/test_records.json @@ -18,6 +18,8 @@ "parentfield": "items", "qty": 1.0, "rate": 100.0, + "uom": "_Test UOM", + "conversion_factor": 1, "stock_uom": "_Test UOM", "warehouse": "_Test Warehouse - _TC" } diff --git a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json index 679e31da82b..48aa6536918 100644 --- a/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json +++ b/erpnext/stock/doctype/delivery_note_item/delivery_note_item.json @@ -373,33 +373,33 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "price_list_rate", - "fieldtype": "Currency", + "fieldname": "stock_uom", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, - "label": "Price List Rate", + "label": "Stock UOM", "length": 0, "no_copy": 0, - "oldfieldname": "ref_rate", - "oldfieldtype": "Currency", - "options": "currency", + "oldfieldname": "stock_uom", + "oldfieldtype": "Data", + "options": "UOM", "permlevel": 0, - "print_hide": 1, + "print_hide": 0, "print_hide_if_no_value": 0, - "print_width": "100px", + "print_width": "50px", "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0, - "width": "100px" + "width": "50px" }, { "allow_on_submit": 0, @@ -433,33 +433,120 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "stock_uom", + "fieldname": "uom", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 0, "label": "UOM", "length": 0, "no_copy": 0, - "oldfieldname": "stock_uom", - "oldfieldtype": "Data", "options": "UOM", "permlevel": 0, + "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "print_width": "50px", - "read_only": 1, + "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "conversion_factor", + "fieldtype": "Float", + "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": "UOM Conversion Factor", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_17", + "fieldtype": "Section Break", + "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, + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "price_list_rate", + "fieldtype": "Currency", + "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": "Price List Rate", + "length": 0, + "no_copy": 0, + "oldfieldname": "ref_rate", + "oldfieldtype": "Currency", + "options": "currency", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": "100px", + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, "unique": 0, - "width": "50px" + "width": "100px" }, { "allow_on_submit": 0, @@ -1674,6 +1761,35 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "stock_qty", + "fieldtype": "Float", + "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": "Qty as per Stock UOM", + "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, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -1777,7 +1893,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2017-02-20 13:30:37.815725", + "modified": "2017-02-22 01:49:51.752713", "modified_by": "Administrator", "module": "Stock", "name": "Delivery Note Item", diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py index 4fb5f5d6392..244ac66ffb9 100644 --- a/erpnext/stock/doctype/material_request/material_request.py +++ b/erpnext/stock/doctype/material_request/material_request.py @@ -46,7 +46,7 @@ class MaterialRequest(BuyingController): docstatus = 1 and parent != %s""", (item, so_no, self.name)) already_indented = already_indented and flt(already_indented[0][0]) or 0 - actual_so_qty = frappe.db.sql("""select sum(qty) from `tabSales Order Item` + actual_so_qty = frappe.db.sql("""select sum(stock_qty) from `tabSales Order Item` where parent = %s and item_code = %s and docstatus = 1""", (so_no, item)) actual_so_qty = actual_so_qty and flt(actual_so_qty[0][0]) or 0 diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py index 09affe04943..582960de4df 100644 --- a/erpnext/stock/doctype/packed_item/packed_item.py +++ b/erpnext/stock/doctype/packed_item/packed_item.py @@ -67,7 +67,7 @@ def make_packing_list(doc): for d in doc.get("items"): if frappe.db.get_value("Product Bundle", {"new_item_code": d.item_code}): for i in get_product_bundle_items(d.item_code): - update_packing_list_item(doc, i.item_code, flt(i.qty)*flt(d.qty), d, i.description) + update_packing_list_item(doc, i.item_code, flt(i.qty)*flt(d.stock_qty), d, i.description) if [d.item_code, d.name] not in parent_items: parent_items.append([d.item_code, d.name]) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 1c0a3d1006e..8f6c592a451 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -86,7 +86,7 @@ frappe.ui.form.on('Stock Entry', { var args = { 'item_code' : d.item_code, 'warehouse' : cstr(d.s_warehouse), - 'qty' : d.qty + 'stock_qty' : d.transfer_qty }; frappe.call({ method: "erpnext.stock.get_item_details.get_serial_no", diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index b9b11a88557..be20a810c2b 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -73,7 +73,7 @@ def get_item_details(args): out.update(get_pricing_rule_for_item(args)) - if args.get("doctype") in ("Sales Invoice", "Delivery Note") and out.qty > 0: + if args.get("doctype") in ("Sales Invoice", "Delivery Note") and out.stock_qty > 0: out.serial_no = get_serial_no(out) if args.transaction_date and item.lead_time_days: @@ -345,7 +345,7 @@ def get_serial_nos_by_fifo(args): order by timestamp(purchase_date, purchase_time) asc limit %(qty)s""", { "item_code": args.item_code, "warehouse": args.warehouse, - "qty": abs(cint(args.qty)) + "qty": abs(cint(args.stock_qty)) })) def get_actual_batch_qty(batch_no,warehouse,item_code): @@ -378,17 +378,17 @@ def get_bin_details(item_code, warehouse): or {"projected_qty": 0, "actual_qty": 0} @frappe.whitelist() -def get_serial_no_details(item_code, warehouse, qty, serial_no): - args = frappe._dict({"item_code":item_code, "warehouse":warehouse, "qty":qty, "serial_no":serial_no}) +def get_serial_no_details(item_code, warehouse, stock_qty, serial_no): + args = frappe._dict({"item_code":item_code, "warehouse":warehouse, "stock_qty":stock_qty, "serial_no":serial_no}) serial_no = get_serial_no(args) return {'serial_no': serial_no} @frappe.whitelist() -def get_bin_details_and_serial_nos(item_code, warehouse, qty=None, serial_no=None): +def get_bin_details_and_serial_nos(item_code, warehouse, stock_qty=None, serial_no=None): bin_details_and_serial_nos = {} bin_details_and_serial_nos.update(get_bin_details(item_code, warehouse)) - if qty > 0: - bin_details_and_serial_nos.update(get_serial_no_details(item_code, warehouse, qty, serial_no)) + if stock_qty > 0: + bin_details_and_serial_nos.update(get_serial_no_details(item_code, warehouse, stock_qty, serial_no)) return bin_details_and_serial_nos @frappe.whitelist() @@ -510,7 +510,7 @@ def get_valuation_rate(item_code, warehouse=None): ["valuation_rate"], as_dict=True) or {"valuation_rate": 0} elif not item.is_stock_item: - valuation_rate =frappe.db.sql("""select sum(base_net_amount) / sum(qty) + valuation_rate =frappe.db.sql("""select sum(base_net_amount) / sum(qty*conversion_factor) from `tabPurchase Invoice Item` where item_code = %s and docstatus=1""", item_code) @@ -522,7 +522,7 @@ def get_valuation_rate(item_code, warehouse=None): def get_gross_profit(out): if out.valuation_rate: out.update({ - "gross_profit": ((out.base_rate - out.valuation_rate) * out.qty) + "gross_profit": ((out.base_rate - out.valuation_rate) * out.stock_qty) }) return out @@ -533,10 +533,10 @@ def get_serial_no(args): args = json.loads(args) args = frappe._dict(args) - if args.get('warehouse') and args.get('qty') and args.get('item_code'): + if args.get('warehouse') and args.get('stock_qty') and args.get('item_code'): if frappe.get_value('Item', {'item_code': args.item_code}, "has_serial_no") == 1: - args = json.dumps({"item_code": args.get('item_code'),"warehouse": args.get('warehouse'),"qty": args.get('qty')}) + args = json.dumps({"item_code": args.get('item_code'),"warehouse": args.get('warehouse'),"stock_qty": args.get('stock_qty')}) args = process_args(args) serial_no = get_serial_nos_by_fifo(args) return serial_no diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py index 096f6c07b6e..4c8cc262881 100644 --- a/erpnext/stock/stock_balance.py +++ b/erpnext/stock/stock_balance.py @@ -73,7 +73,7 @@ def get_reserved_qty(item_code, warehouse): (select qty as dnpi_qty, ( - select qty from `tabSales Order Item` + select stock_qty from `tabSales Order Item` where name = dnpi.parent_detail_docname and (delivered_by_supplier is null or delivered_by_supplier = 0) ) as so_item_qty, @@ -94,7 +94,7 @@ def get_reserved_qty(item_code, warehouse): where name = dnpi_in.parent and docstatus = 1 and status != 'Closed') ) dnpi) union - (select qty as dnpi_qty, qty as so_item_qty, + (select qty as dnpi_qty, stock_qty as so_item_qty, delivered_qty as so_item_delivered_qty, parent, name from `tabSales Order Item` so_item where item_code = %s and warehouse = %s