diff --git a/erpnext/__version__.py b/erpnext/__version__.py index 01b41d293a8..4cc1ceced9d 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1,2 +1,2 @@ from __future__ import unicode_literals -__version__ = '6.27.16' +__version__ = '6.27.17' diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js index 941aa8714b0..bad826ed148 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js @@ -34,6 +34,12 @@ frappe.query_reports["Item-wise Purchase Register"] = { "fieldtype": "Link", "options": "Company", "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname":"mode_of_payment", + "label": __("Mode of Payment"), + "fieldtype": "Link", + "options": "Mode of Payment" } ] } diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py index 9e7cdb65d03..d6bbee5bb92 100644 --- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py +++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -35,7 +35,7 @@ def execute(filters=None): expense_account = d.expense_account or aii_account_map.get(d.company) row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier, - d.supplier_name, d.credit_to, d.project, d.company, d.purchase_order, + d.supplier_name, d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order, purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount] for tax in tax_accounts: @@ -53,7 +53,8 @@ def get_columns(): return [_("Item Code") + ":Link/Item:120", _("Item Name") + "::120", _("Item Group") + ":Link/Item Group:100", _("Invoice") + ":Link/Purchase Invoice:120", _("Posting Date") + ":Date:80", _("Supplier") + ":Link/Supplier:120", - "Supplier Name::120", "Payable Account:Link/Account:120", _("Project") + ":Link/Project:80", + "Supplier Name::120", "Payable Account:Link/Account:120", + _("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100", _("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140", _("Qty") + ":Float:120", _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120" @@ -66,7 +67,8 @@ def get_conditions(filters): ("supplier", " and pi.supplier = %(supplier)s"), ("item_code", " and pi_item.item_code = %(item_code)s"), ("from_date", " and pi.posting_date>=%(from_date)s"), - ("to_date", " and pi.posting_date<=%(to_date)s")): + ("to_date", " and pi.posting_date<=%(to_date)s"), + ("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s")): if filters.get(opts[0]): conditions += opts[1] @@ -82,7 +84,7 @@ def get_items(filters): pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name, pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt, pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate, - pi_item.base_net_amount, pi.supplier_name + pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item where pi.name = pi_item.parent and pi.docstatus = 1 %s %s order by pi.posting_date desc, pi_item.item_code desc diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js index d3224060fdf..142a55f3c5b 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -28,6 +28,12 @@ frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales R "fieldtype": "Link", "options": "Company", "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname":"mode_of_payment", + "label": __("Mode of Payment"), + "fieldtype": "Link", + "options": "Mode of Payment" } ] } diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index beca96e7f6a..6fc7349bb84 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -32,7 +32,7 @@ def execute(filters=None): from `tabDelivery Note Item` where docstatus=1 and so_detail=%s""", d.so_detail)) row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.customer, d.customer_name, - d.customer_group, d.debit_to, d.territory, d.project, d.company, d.sales_order, + d.customer_group, d.debit_to, d.mode_of_payment, d.territory, d.project, d.company, d.sales_order, delivery_note, d.income_account, d.qty, d.base_net_rate, d.base_net_amount] for tax in tax_accounts: @@ -51,7 +51,8 @@ def get_columns(): _("Item Group") + ":Link/Item Group:100", _("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80", _("Customer") + ":Link/Customer:120", _("Customer Name") + "::120", _("Customer Group") + ":Link/Customer Group:120", - _("Receivable Account") + ":Link/Account:120", _("Territory") + ":Link/Territory:80", + _("Receivable Account") + ":Link/Account:120", + _("Mode of Payment") + ":Link/Mode of Payment:80", _("Territory") + ":Link/Territory:80", _("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100", _("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100", _("Income Account") + ":Link/Account:140", _("Qty") + ":Float:120", @@ -65,7 +66,8 @@ def get_conditions(filters): ("customer", " and si.customer = %(customer)s"), ("item_code", " and si_item.item_code = %(item_code)s"), ("from_date", " and si.posting_date>=%(from_date)s"), - ("to_date", " and si.posting_date<=%(to_date)s")): + ("to_date", " and si.posting_date<=%(to_date)s"), + ("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s")): if filters.get(opts[0]): conditions += opts[1] @@ -80,7 +82,7 @@ def get_items(filters): si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order, si_item.delivery_note, si_item.income_account, si_item.qty, si_item.base_net_rate, si_item.base_net_amount, si.customer_name, - si.customer_group, si_item.so_detail + si.customer_group, si_item.so_detail, si.mode_of_payment from `tabSales Invoice` si, `tabSales Invoice Item` si_item where si.name = si_item.parent and si.docstatus = 1 %s order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1) diff --git a/erpnext/accounts/report/purchase_register/purchase_register.js b/erpnext/accounts/report/purchase_register/purchase_register.js index 15300c30a79..d32f7b64c08 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.js +++ b/erpnext/accounts/report/purchase_register/purchase_register.js @@ -28,6 +28,12 @@ frappe.query_reports["Purchase Register"] = { "fieldtype": "Link", "options": "Company", "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname":"mode_of_payment", + "label": __("Mode of Payment"), + "fieldtype": "Link", + "options": "Mode of Payment" } ] } diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py index 53cb7af6631..9a90f2f2354 100644 --- a/erpnext/accounts/report/purchase_register/purchase_register.py +++ b/erpnext/accounts/report/purchase_register/purchase_register.py @@ -33,7 +33,7 @@ def execute(filters=None): row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name, supplier_details.get(inv.supplier), - inv.credit_to, ", ".join(project), inv.bill_no, inv.bill_date, inv.remarks, + inv.credit_to, inv.mode_of_payment, ", ".join(project), inv.bill_no, inv.bill_date, inv.remarks, ", ".join(purchase_order), ", ".join(purchase_receipt), company_currency] # map expense values @@ -64,10 +64,10 @@ def execute(filters=None): def get_columns(invoice_list): """return columns based on filters""" columns = [ - _("Invoice") + ":Link/Purchase Invoice:120", - _("Posting Date") + ":Date:80", _("Supplier Id") + "::120", - _("Supplier Name") + "::120", _("Supplier Type") + ":Link/Supplier Type:120", - _("Payable Account") + ":Link/Account:120", _("Project") + ":Link/Project:80", + _("Invoice") + ":Link/Purchase Invoice:120", _("Posting Date") + ":Date:80", + _("Supplier Id") + "::120", _("Supplier Name") + "::120", + _("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120", + _("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80", _("Bill No") + "::120", _("Bill Date") + ":Date:80", _("Remarks") + "::150", _("Purchase Order") + ":Link/Purchase Order:100", _("Purchase Receipt") + ":Link/Purchase Receipt:100", @@ -114,6 +114,8 @@ def get_conditions(filters): if filters.get("from_date"): conditions += " and posting_date>=%(from_date)s" if filters.get("to_date"): conditions += " and posting_date<=%(to_date)s" + + if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s" return conditions @@ -121,8 +123,8 @@ def get_invoices(filters): conditions = get_conditions(filters) return frappe.db.sql(""" select - name, posting_date, credit_to, supplier, supplier_name, - bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount + name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date, remarks, + base_net_total, base_grand_total, outstanding_amount, mode_of_payment from `tabPurchase Invoice` where docstatus = 1 %s order by posting_date desc, name desc""" % conditions, filters, as_dict=1) diff --git a/erpnext/accounts/report/sales_register/sales_register.js b/erpnext/accounts/report/sales_register/sales_register.js index 4764255a471..d7aac5a83d7 100644 --- a/erpnext/accounts/report/sales_register/sales_register.js +++ b/erpnext/accounts/report/sales_register/sales_register.js @@ -28,6 +28,12 @@ frappe.query_reports["Sales Register"] = { "fieldtype": "Link", "options": "Company", "default": frappe.defaults.get_user_default("Company") + }, + { + "fieldname":"mode_of_payment", + "label": __("Mode of Payment"), + "fieldtype": "Link", + "options": "Mode of Payment" } ] } diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py index d09cfc1924d..663c5c95ccd 100644 --- a/erpnext/accounts/report/sales_register/sales_register.py +++ b/erpnext/accounts/report/sales_register/sales_register.py @@ -33,7 +33,7 @@ def execute(filters=None): row = [inv.name, inv.posting_date, inv.customer, inv.customer_name, customer_map.get(inv.customer, {}).get("customer_group"), customer_map.get(inv.customer, {}).get("territory"), - inv.debit_to, inv.project, inv.remarks, + inv.debit_to, inv.mode_of_payment, inv.project, inv.remarks, ", ".join(sales_order), ", ".join(delivery_note), company_currency] # map income values @@ -65,9 +65,11 @@ def execute(filters=None): def get_columns(invoice_list): """return columns based on filters""" columns = [ - _("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80", _("Customer Id") + "::120", - _("Customer Name") + "::120", _("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80", - _("Receivable Account") + ":Link/Account:120", _("Project") +":Link/Project:80", _("Remarks") + "::150", + _("Invoice") + ":Link/Sales Invoice:120", _("Posting Date") + ":Date:80", + _("Customer Id") + "::120", _("Customer Name") + "::120", + _("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80", + _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + ":Link/Mode of Payment:80", + _("Project") +":Link/Project:80", _("Remarks") + "::150", _("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100", { "fieldname": "currency", @@ -110,13 +112,15 @@ def get_conditions(filters): if filters.get("from_date"): conditions += " and posting_date >= %(from_date)s" if filters.get("to_date"): conditions += " and posting_date <= %(to_date)s" + + if filters.get("mode_of_payment"): conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s" return conditions def get_invoices(filters): conditions = get_conditions(filters) - return frappe.db.sql("""select name, posting_date, debit_to, project, customer, - customer_name, remarks, base_net_total, base_grand_total, base_rounded_total, outstanding_amount + return frappe.db.sql("""select name, posting_date, debit_to, project, customer, customer_name, remarks, + base_net_total, base_grand_total, base_rounded_total, outstanding_amount, mode_of_payment from `tabSales Invoice` where docstatus = 1 %s order by posting_date desc, name desc""" % conditions, filters, as_dict=1) diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 74a3d696e0d..8f687d19ae2 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -330,19 +330,23 @@ class BuyingController(StockController): pr_qty = flt(d.qty) * flt(d.conversion_factor) if pr_qty: - val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9 - rate = flt(d.valuation_rate, val_rate_db_precision) sle = self.get_sl_entries(d, { "actual_qty": flt(pr_qty), "serial_no": cstr(d.serial_no).strip() }) if self.is_return: + original_incoming_rate = frappe.db.get_value("Stock Ledger Entry", + {"voucher_type": "Purchase Receipt", "voucher_no": self.return_against, + "item_code": d.item_code}, "incoming_rate") + sle.update({ - "outgoing_rate": rate + "outgoing_rate": original_incoming_rate }) else: + val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9 + incoming_rate = flt(d.valuation_rate, val_rate_db_precision) sle.update({ - "incoming_rate": rate + "incoming_rate": incoming_rate }) sl_entries.append(sle) diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py index d5c677c7d0d..37b13c3e2de 100644 --- a/erpnext/controllers/sales_and_purchase_return.py +++ b/erpnext/controllers/sales_and_purchase_return.py @@ -62,8 +62,8 @@ def validate_returned_items(doc): if doc.doctype in ("Delivery Note", "Sales Invoice"): - for d in frappe.db.sql("""select item_code, sum(qty) as qty, serial_no, batch_no from `tabPacked Item` - where parent = %s group by item_code""".format(doc.doctype), doc.return_against, as_dict=1): + for d in frappe.db.sql("""select item_code, qty, serial_no, batch_no from `tabPacked Item` + where parent = %s""".format(doc.doctype), doc.return_against, as_dict=1): valid_items = get_ref_item_dict(valid_items, d) already_returned_items = get_already_returned_items(doc) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 1e16c89405d..aef612b755c 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -7,7 +7,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd." app_description = """ERP made simple""" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "6.27.16" +app_version = "6.27.17" app_email = "info@erpnext.com" app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json index 8817f65ef91..37b643db895 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json @@ -422,6 +422,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, + "description": "Enter items and planned qty for which you want to raise production orders or download raw materials for analysis.", "fieldname": "items_for_production", "fieldtype": "Section Break", "hidden": 0, @@ -524,7 +525,7 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "description": "Enter items and planned qty for which you want to raise production orders or download raw materials for analysis.", + "description": "", "fieldname": "create_production_orders", "fieldtype": "Section Break", "hidden": 0, @@ -625,7 +626,32 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "description": "Items to be requested which are \"Out of Stock\" considering all warehouses based on projected qty and minimum order qty", + "fieldname": "create_material_requests_for_all_required_qty", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Create Material Requests for All Required Qty", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "description": "Items to be requested which are \"Out of Stock\" considering all warehouses based on projected qty and minimum order qty, if \"Create Material Requests for All Required Qty\" is unchecked.", "fieldname": "create_material_requests", "fieldtype": "Button", "hidden": 0, @@ -683,7 +709,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2016-03-16 06:18:50.179089", + "modified": "2016-05-10 12:55:45.647374", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Planning Tool", 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 199a5a4f148..f45708a7952 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -386,19 +386,24 @@ class ProductionPlanningTool(Document): self.create_material_request() def get_requested_items(self): - item_projected_qty = self.get_projected_qty() items_to_be_requested = frappe._dict() + if not self.create_material_requests_for_all_required_qty: + item_projected_qty = self.get_projected_qty() + for item, so_item_qty in self.item_dict.items(): - requested_qty = 0 total_qty = sum([flt(d[0]) for d in so_item_qty]) - if total_qty > item_projected_qty.get(item, 0): + requested_qty = 0 + + if self.create_material_requests_for_all_required_qty: + requested_qty = total_qty + elif total_qty > item_projected_qty.get(item, 0): # shortage requested_qty = total_qty - flt(item_projected_qty.get(item)) # consider minimum order qty - if requested_qty < flt(so_item_qty[0][3]): - requested_qty = flt(so_item_qty[0][3]) + if requested_qty and requested_qty < flt(so_item_qty[0][3]): + requested_qty = flt(so_item_qty[0][3]) # distribute requested qty SO wise for item_details in so_item_qty: diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 1babf2ea439..a173ae86dc4 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -189,12 +189,9 @@ class PurchaseReceipt(BuyingController): for d in self.get("items"): if d.item_code in stock_items and flt(d.valuation_rate) and flt(d.qty): if warehouse_account.get(d.warehouse): - - val_rate_db_precision = 6 if cint(d.precision("valuation_rate")) <= 6 else 9 - - # warehouse account - stock_value_diff = flt(flt(d.valuation_rate, val_rate_db_precision) * flt(d.qty) - * flt(d.conversion_factor), d.precision("base_net_amount")) + stock_value_diff = frappe.db.get_value("Stock Ledger Entry", + {"voucher_type": "Purchase Receipt", "voucher_no": self.name, + "voucher_detail_no": d.name}, "stock_value_difference") gl_entries.append(self.get_gl_dict({ "account": warehouse_account[d.warehouse]["name"], @@ -239,14 +236,20 @@ class PurchaseReceipt(BuyingController): }, warehouse_account[self.supplier_warehouse]["account_currency"])) # divisional loss adjustment - distributed_amount = flt(flt(d.base_net_amount, d.precision("base_net_amount"))) + \ + valuation_amount_as_per_doc = flt(d.base_net_amount, d.precision("base_net_amount")) + \ flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.item_tax_amount) - divisional_loss = flt(distributed_amount - stock_value_diff, + divisional_loss = flt(valuation_amount_as_per_doc - stock_value_diff, d.precision("base_net_amount")) + if divisional_loss: + if self.is_return or flt(d.item_tax_amount): + loss_account = expenses_included_in_valuation + else: + loss_account = stock_rbnb + gl_entries.append(self.get_gl_dict({ - "account": stock_rbnb, + "account": loss_account, "against": warehouse_account[d.warehouse]["name"], "cost_center": d.cost_center, "remarks": self.get("remarks") or _("Accounting Entry for Stock"), diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index ed6732227a9..d3fa4823cd1 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -215,8 +215,6 @@ class update_entries_after(object): stock_value_change = 0 if incoming_rate: stock_value_change = actual_qty * incoming_rate - elif flt(sle.outgoing_rate): - stock_value_change = actual_qty * flt(sle.outgoing_rate) elif actual_qty < 0: # In case of delivery/stock issue, get average purchase rate # of serial nos of current entry diff --git a/setup.py b/setup.py index ce447d5e465..9ced1743954 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages from pip.req import parse_requirements -version = "6.27.16" +version = "6.27.17" requirements = parse_requirements("requirements.txt", session="") setup(