diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index ce26a258fb6..f2eeb327b42 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1105,7 +1105,10 @@ class SalesInvoice(SellingController): expiry_date=self.posting_date, include_expired_entry=True) if lp_details and getdate(lp_details.from_date) <= getdate(self.posting_date) and \ (not lp_details.to_date or getdate(lp_details.to_date) >= getdate(self.posting_date)): - points_earned = cint(eligible_amount/lp_details.collection_factor) + + collection_factor = lp_details.collection_factor if lp_details.collection_factor else 1.0 + points_earned = cint(eligible_amount/collection_factor) + doc = frappe.get_doc({ "doctype": "Loyalty Point Entry", "company": self.company, diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 34ab80f2fff..e4a58482bd9 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -653,6 +653,11 @@ def get_gst_accounts(company, account_wise=False): return gst_accounts def update_grand_total_for_rcm(doc, method): + country = frappe.get_cached_value('Company', doc.company, 'country') + + if country != 'India': + return + if doc.reverse_charge == 'Y': gst_accounts = get_gst_accounts(doc.company) gst_account_list = gst_accounts.get('cgst_account') + gst_accounts.get('sgst_account') \ diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py index a091ac7fae9..c8424f13e12 100644 --- a/erpnext/stock/doctype/batch/batch.py +++ b/erpnext/stock/doctype/batch/batch.py @@ -143,7 +143,7 @@ class Batch(Document): @frappe.whitelist() -def get_batch_qty(batch_no=None, warehouse=None, item_code=None): +def get_batch_qty(batch_no=None, warehouse=None, item_code=None, posting_date=None, posting_time=None): """Returns batch actual qty if warehouse is passed, or returns dict of qty by warehouse if warehouse is None @@ -155,9 +155,14 @@ def get_batch_qty(batch_no=None, warehouse=None, item_code=None): out = 0 if batch_no and warehouse: + cond = "" + if posting_date and posting_time: + cond = " and timestamp(posting_date, posting_time) <= timestamp('{0}', '{1}')".format(posting_date, + posting_time) + out = float(frappe.db.sql("""select sum(actual_qty) from `tabStock Ledger Entry` - where warehouse=%s and batch_no=%s""", + where warehouse=%s and batch_no=%s {0}""".format(cond), (warehouse, batch_no))[0][0] or 0) if batch_no and not warehouse: diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index 1791978a068..0475ea7a2ec 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -74,6 +74,20 @@ frappe.ui.form.on("Stock Reconciliation", { , __("Get Items"), __("Update")); }, + posting_date: function(frm) { + frm.trigger("set_valuation_rate_and_qty_for_all_items"); + }, + + posting_time: function(frm) { + frm.trigger("set_valuation_rate_and_qty_for_all_items"); + }, + + set_valuation_rate_and_qty_for_all_items: function(frm) { + frm.doc.items.forEach(row => { + frm.events.set_valuation_rate_and_qty(frm, row.doctype, row.name); + }); + }, + set_valuation_rate_and_qty: function(frm, cdt, cdn) { var d = frappe.model.get_doc(cdt, cdn); diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 0a49c26b629..36f309c1a6e 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -184,8 +184,12 @@ class StockReconciliation(StockController): sl_entries = [] has_serial_no = False + has_batch_no = False for row in self.items: item = frappe.get_doc("Item", row.item_code) + if item.has_batch_no: + has_batch_no = True + if item.has_serial_no or item.has_batch_no: has_serial_no = True self.get_sle_for_serialized_items(row, sl_entries) @@ -221,7 +225,11 @@ class StockReconciliation(StockController): if has_serial_no: sl_entries = self.merge_similar_item_serial_nos(sl_entries) - self.make_sl_entries(sl_entries) + allow_negative_stock = False + if has_batch_no: + allow_negative_stock = True + + self.make_sl_entries(sl_entries, allow_negative_stock=allow_negative_stock) if has_serial_no and sl_entries: self.update_valuation_rate_for_serial_no() @@ -498,7 +506,7 @@ def get_stock_balance_for(item_code, warehouse, qty, rate = data if item_dict.get("has_batch_no"): - qty = get_batch_qty(batch_no, warehouse) or 0 + qty = get_batch_qty(batch_no, warehouse, posting_date=posting_date, posting_time=posting_time) or 0 return { 'qty': qty, diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py index 74a4f6ef142..042087a4a77 100644 --- a/erpnext/stock/report/stock_balance/stock_balance.py +++ b/erpnext/stock/report/stock_balance/stock_balance.py @@ -2,7 +2,7 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals -import frappe +import frappe, erpnext from frappe import _ from frappe.utils import flt, cint, getdate, now, date_diff from erpnext.stock.utils import add_additional_uom_columns @@ -20,6 +20,11 @@ def execute(filters=None): from_date = filters.get('from_date') to_date = filters.get('to_date') + if filters.get("company"): + company_currency = erpnext.get_company_currency(filters.get("company")) + else: + company_currency = frappe.db.get_single_value("Global Defaults", "default_currency") + include_uom = filters.get("include_uom") columns = get_columns(filters) items = get_items(filters) @@ -52,6 +57,7 @@ def execute(filters=None): item_reorder_qty = item_reorder_detail_map[item + warehouse]["warehouse_reorder_qty"] report_data = { + 'currency': company_currency, 'item_code': item, 'warehouse': warehouse, 'company': company, @@ -89,7 +95,6 @@ def execute(filters=None): def get_columns(filters): """return columns""" - columns = [ {"label": _("Item"), "fieldname": "item_code", "fieldtype": "Link", "options": "Item", "width": 100}, {"label": _("Item Name"), "fieldname": "item_name", "width": 150}, @@ -97,14 +102,14 @@ def get_columns(filters): {"label": _("Warehouse"), "fieldname": "warehouse", "fieldtype": "Link", "options": "Warehouse", "width": 100}, {"label": _("Stock UOM"), "fieldname": "stock_uom", "fieldtype": "Link", "options": "UOM", "width": 90}, {"label": _("Balance Qty"), "fieldname": "bal_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, - {"label": _("Balance Value"), "fieldname": "bal_val", "fieldtype": "Currency", "width": 100}, + {"label": _("Balance Value"), "fieldname": "bal_val", "fieldtype": "Currency", "width": 100, "options": "currency"}, {"label": _("Opening Qty"), "fieldname": "opening_qty", "fieldtype": "Float", "width": 100, "convertible": "qty"}, - {"label": _("Opening Value"), "fieldname": "opening_val", "fieldtype": "Float", "width": 110}, + {"label": _("Opening Value"), "fieldname": "opening_val", "fieldtype": "Currency", "width": 110, "options": "currency"}, {"label": _("In Qty"), "fieldname": "in_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("In Value"), "fieldname": "in_val", "fieldtype": "Float", "width": 80}, {"label": _("Out Qty"), "fieldname": "out_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Out Value"), "fieldname": "out_val", "fieldtype": "Float", "width": 80}, - {"label": _("Valuation Rate"), "fieldname": "val_rate", "fieldtype": "Currency", "width": 90, "convertible": "rate"}, + {"label": _("Valuation Rate"), "fieldname": "val_rate", "fieldtype": "Currency", "width": 90, "convertible": "rate", "options": "currency"}, {"label": _("Reorder Level"), "fieldname": "reorder_level", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Reorder Qty"), "fieldname": "reorder_qty", "fieldtype": "Float", "width": 80, "convertible": "qty"}, {"label": _("Company"), "fieldname": "company", "fieldtype": "Link", "options": "Company", "width": 100} diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py index 884356ee779..6a265ec4cc5 100644 --- a/erpnext/stock/report/stock_ledger/stock_ledger.py +++ b/erpnext/stock/report/stock_ledger/stock_ledger.py @@ -32,7 +32,7 @@ def execute(filters=None): actual_qty += flt(sle.actual_qty, precision) stock_value += sle.stock_value_difference - if sle.voucher_type == 'Stock Reconciliation': + if sle.voucher_type == 'Stock Reconciliation' and not sle.actual_qty: actual_qty = sle.qty_after_transaction stock_value = sle.stock_value