Merge pull request #24651 from ankush/ignore_gl_while_cancelling_so
fix(selling): cancel sales order with cancelled PE
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index d011689..76f3c50 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -222,7 +222,7 @@
set_gl_entries_by_account(start_date,
end_date, root.lft, root.rgt, filters,
- gl_entries_by_account, accounts_by_name, ignore_closing_entries=False)
+ gl_entries_by_account, accounts_by_name, accounts, ignore_closing_entries=False)
calculate_values(accounts_by_name, gl_entries_by_account, companies, start_date, filters)
accumulate_values_into_parents(accounts, accounts_by_name, companies)
@@ -339,7 +339,7 @@
return data
def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, gl_entries_by_account,
- accounts_by_name, ignore_closing_entries=False):
+ accounts_by_name, accounts, ignore_closing_entries=False):
"""Returns a dict like { "account": [gl entries], ... }"""
company_lft, company_rgt = frappe.get_cached_value('Company',
@@ -382,15 +382,31 @@
for entry in gl_entries:
key = entry.account_number or entry.account_name
- validate_entries(key, entry, accounts_by_name)
+ validate_entries(key, entry, accounts_by_name, accounts)
gl_entries_by_account.setdefault(key, []).append(entry)
return gl_entries_by_account
-def validate_entries(key, entry, accounts_by_name):
+def get_account_details(account):
+ return frappe.get_cached_value('Account', account, ['name', 'report_type', 'root_type', 'company',
+ 'is_group', 'account_name', 'account_number', 'parent_account', 'lft', 'rgt'], as_dict=1)
+
+def validate_entries(key, entry, accounts_by_name, accounts):
if key not in accounts_by_name:
- field = "Account number" if entry.account_number else "Account name"
- frappe.throw(_("{0} {1} is not present in the parent company").format(field, key))
+ args = get_account_details(entry.account)
+
+ if args.parent_account:
+ parent_args = get_account_details(args.parent_account)
+
+ args.update({
+ 'lft': parent_args.lft + 1,
+ 'rgt': parent_args.rgt - 1,
+ 'root_type': parent_args.root_type,
+ 'report_type': parent_args.report_type
+ })
+
+ accounts_by_name.setdefault(key, args)
+ accounts.append(args)
def get_additional_conditions(from_date, ignore_closing_entries, filters):
additional_conditions = []
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 8031905..60d1e20 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -888,18 +888,22 @@
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
warehouse_account=None, company=None):
+ stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items, company)
+ repost_gle_for_stock_vouchers(stock_vouchers, posting_date, company, warehouse_account)
+
+
+def repost_gle_for_stock_vouchers(stock_vouchers, posting_date, company=None, warehouse_account=None):
def _delete_gl_entries(voucher_type, voucher_no):
frappe.db.sql("""delete from `tabGL Entry`
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
+
if not warehouse_account:
warehouse_account = get_warehouse_account_map(company)
- future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time,
- for_warehouses, for_items, company)
- gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
+ gle = get_voucherwise_gl_entries(stock_vouchers, posting_date)
- for voucher_type, voucher_no in future_stock_vouchers:
+ for voucher_type, voucher_no in stock_vouchers:
existing_gle = gle.get((voucher_type, voucher_no), [])
voucher_obj = frappe.get_doc(voucher_type, voucher_no)
expected_gle = voucher_obj.get_gl_entries(warehouse_account)
@@ -924,7 +928,7 @@
values += for_warehouses
if company:
- condition += " and company = %s "
+ condition += " and company = %s"
values.append(company)
for d in frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 991eef1..12a81c7 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -1309,45 +1309,28 @@
})
tax_row.db_insert()
-def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
+def set_order_defaults(parent_doctype, parent_doctype_name, child_doctype, child_docname, trans_item):
"""
- Returns a Sales Order Item child item containing the default values
+ Returns a Sales/Purchase Order Item child item containing the default values
"""
p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
- child_item = frappe.new_doc('Sales Order Item', p_doc, child_docname)
+ child_item = frappe.new_doc(child_doctype, p_doc, child_docname)
item = frappe.get_doc("Item", trans_item.get('item_code'))
- child_item.item_code = item.item_code
- child_item.item_name = item.item_name
- child_item.description = item.description
- child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
+ for field in ("item_code", "item_name", "description", "item_group"):
+ child_item.update({field: item.get(field)})
+ date_fieldname = "delivery_date" if child_doctype == "Sales Order Item" else "schedule_date"
+ child_item.update({date_fieldname: trans_item.get(date_fieldname) or p_doc.get(date_fieldname)})
child_item.uom = trans_item.get("uom") or item.stock_uom
conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
- set_child_tax_template_and_map(item, child_item, p_doc)
- add_taxes_from_tax_template(child_item, p_doc)
- child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
- if not child_item.warehouse:
- frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
- .format(frappe.bold("default warehouse"), frappe.bold(item.item_code)))
- return child_item
-
-
-def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, trans_item):
- """
- Returns a Purchase Order Item child item containing the default values
- """
- p_doc = frappe.get_doc(parent_doctype, parent_doctype_name)
- child_item = frappe.new_doc('Purchase Order Item', p_doc, child_docname)
- item = frappe.get_doc("Item", trans_item.get('item_code'))
- child_item.item_code = item.item_code
- child_item.item_name = item.item_name
- child_item.description = item.description
- child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
- child_item.uom = trans_item.get("uom") or item.stock_uom
- conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
- child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
- child_item.base_rate = 1 # Initiallize value will update in parent validation
- child_item.base_amount = 1 # Initiallize value will update in parent validation
+ if child_doctype == "Purchase Order Item":
+ child_item.base_rate = 1 # Initiallize value will update in parent validation
+ child_item.base_amount = 1 # Initiallize value will update in parent validation
+ if child_doctype == "Sales Order Item":
+ child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
+ if not child_item.warehouse:
+ frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
+ .format(frappe.bold("default warehouse"), frappe.bold(item.item_code)))
set_child_tax_template_and_map(item, child_item, p_doc)
add_taxes_from_tax_template(child_item, p_doc)
return child_item
@@ -1411,8 +1394,8 @@
)
def get_new_child_item(item_row):
- new_child_function = set_sales_order_defaults if parent_doctype == "Sales Order" else set_purchase_order_defaults
- return new_child_function(parent_doctype, parent_doctype_name, child_docname, item_row)
+ child_doctype = "Sales Order Item" if parent_doctype == "Sales Order" else "Purchase Order Item"
+ return set_order_defaults(parent_doctype, parent_doctype_name, child_doctype, child_docname, item_row)
def validate_quantity(child_item, d):
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 70e8d8c..ea9659c 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -488,13 +488,12 @@
"voucher_no": self.name,
"company": self.company
})
-
if check_if_future_sle_exists(args):
create_repost_item_valuation_entry(args)
elif not is_reposting_pending():
check_if_stock_and_account_balance_synced(self.posting_date,
self.company, self.doctype, self.name)
-
+
def is_reposting_pending():
return frappe.db.exists("Repost Item Valuation",
{'docstatus': 1, 'status': ['in', ['Queued','In Progress']]})
diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
index c324228..325c209 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py
@@ -121,6 +121,7 @@
stock_entry.stock_entry_type = 'Material Receipt'
stock_entry.to_warehouse = self.warehouse
+ stock_entry.company = self.company
expense_account = get_account(None, 'expense_account', 'Healthcare Settings', self.company)
for item in self.items:
if item.qty > item.actual_qty:
diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
index 4ee5f6b..fb72073 100644
--- a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
+++ b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+ # -*- coding: utf-8 -*-
# Copyright (c) 2017, ESS LLP and Contributors
# See license.txt
from __future__ import unicode_literals
@@ -60,6 +60,7 @@
procedure.practitioner = practitioner
procedure.consume_stock = procedure_template.allow_stock_consumption
procedure.items = procedure_template.items
- procedure.warehouse = frappe.db.get_single_value('Stock Settings', 'default_warehouse')
+ procedure.company = "_Test Company"
+ procedure.warehouse = "_Test Warehouse - _TC"
procedure.submit()
return procedure
\ No newline at end of file
diff --git a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py
index eff0ae4..f60e0d3 100644
--- a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py
+++ b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py
@@ -3,7 +3,6 @@
from erpnext.stock.stock_ledger import update_entries_after
from erpnext.accounts.utils import update_gl_entries_after
-
def execute():
data = frappe.db.sql(''' SELECT name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time
from `tabStock Ledger Entry` where creation > '2020-12-26 12:58:55.903836' and is_cancelled = 0
diff --git a/erpnext/public/less/hub.less b/erpnext/public/less/hub.less
index 8cb7a9c..29deada 100644
--- a/erpnext/public/less/hub.less
+++ b/erpnext/public/less/hub.less
@@ -32,7 +32,12 @@
}
.hub-image-loading, .hub-image-broken {
- .img-background();
+ content: " ";
+ position: absolute;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ background-color: var(--bg-light-gray);
display: flex;
align-items: center;
justify-content: center;
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 3c9f849..681d161 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -462,6 +462,9 @@
return customer
def get_debtors_account(cart_settings):
+ if not cart_settings.payment_gateway_account:
+ frappe.throw(_("Payment Gateway Account not set"), _("Mandatory"))
+
payment_gateway_account_currency = \
frappe.get_doc("Payment Gateway Account", cart_settings.payment_gateway_account).currency
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
index 702583a..3691721 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
@@ -26,10 +26,10 @@
"quotation_series",
"section_break_8",
"enable_checkout",
- "payment_success_url",
- "column_break_11",
"save_quotations_as_draft",
- "payment_gateway_account"
+ "column_break_11",
+ "payment_gateway_account",
+ "payment_success_url"
],
"fields": [
{
@@ -143,10 +143,12 @@
},
{
"default": "Orders",
+ "depends_on": "enable_checkout",
"description": "After payment completion redirect user to selected page.",
"fieldname": "payment_success_url",
"fieldtype": "Select",
"label": "Payment Success Url",
+ "mandatory_depends_on": "enable_checkout",
"options": "\nOrders\nInvoices\nMy Account"
},
{
@@ -154,9 +156,11 @@
"fieldtype": "Column Break"
},
{
+ "depends_on": "enable_checkout",
"fieldname": "payment_gateway_account",
"fieldtype": "Link",
"label": "Payment Gateway Account",
+ "mandatory_depends_on": "enable_checkout",
"options": "Payment Gateway Account"
},
{
@@ -186,7 +190,7 @@
"idx": 1,
"issingle": 1,
"links": [],
- "modified": "2021-02-01 18:18:54.606535",
+ "modified": "2021-02-11 18:48:30.433058",
"modified_by": "Administrator",
"module": "Shopping Cart",
"name": "Shopping Cart Settings",
diff --git a/erpnext/stock/__init__.py b/erpnext/stock/__init__.py
index 8d64efe..b3ae804 100644
--- a/erpnext/stock/__init__.py
+++ b/erpnext/stock/__init__.py
@@ -64,7 +64,7 @@
if not account and warehouse.company:
account = get_company_default_inventory_account(warehouse.company)
- if not account and warehouse.company:
+ if not account and warehouse.company and not warehouse.is_group:
frappe.throw(_("Please set Account in Warehouse {0} or Default Inventory Account in Company {1}")
.format(warehouse.name, warehouse.company))
return account
diff --git a/erpnext/stock/doctype/batch/test_batch.py b/erpnext/stock/doctype/batch/test_batch.py
index 97f85ba..cbd272d 100644
--- a/erpnext/stock/doctype/batch/test_batch.py
+++ b/erpnext/stock/doctype/batch/test_batch.py
@@ -298,9 +298,9 @@
self.assertEqual(details.get('price_list_rate'), 400)
def create_batch(item_code, rate, create_item_price_for_batch):
- pi = make_purchase_invoice(company="_Test Company with perpetual inventory",
- warehouse= "Stores - TCP1", cost_center = "Main - TCP1", update_stock=1,
- expense_account ="_Test Account Cost for Goods Sold - TCP1", item_code=item_code)
+ pi = make_purchase_invoice(company="_Test Company",
+ warehouse= "Stores - _TC", cost_center = "Main - _TC", update_stock=1,
+ expense_account ="_Test Account Cost for Goods Sold - _TC", item_code=item_code)
batch = frappe.db.get_value('Batch', {'item': item_code, 'reference_name': pi.name})
diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
index 144101c..984ae46 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py
@@ -148,7 +148,6 @@
def test_landed_cost_voucher_for_odd_numbers (self):
-
pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", do_not_save=True)
pr.items[0].cost_center = "Main - TCP1"
for x in range(2):
@@ -208,6 +207,10 @@
self.assertEqual(pr.items[1].landed_cost_voucher_amount, 100)
def test_multi_currency_lcv(self):
+ from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records
+
+ save_new_records(test_records)
+
## Create USD Shipping charges_account
usd_shipping = create_account(account_name="Shipping Charges USD",
parent_account="Duties and Taxes - TCP1", company="_Test Company with perpetual inventory",
diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
index ba2c2c6..f22c601 100644
--- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py
@@ -64,7 +64,7 @@
message += "<br>" + "Traceback: <br>" + traceback
frappe.db.set_value(doc.doctype, doc.name, 'error_log', message)
- notify_error_to_stock_managers(doc)
+ notify_error_to_stock_managers(doc, message)
doc.set_status('Failed')
raise
finally:
diff --git a/erpnext/stock/doctype/shipment/test_shipment.py b/erpnext/stock/doctype/shipment/test_shipment.py
index e1fa207..9c3e22f 100644
--- a/erpnext/stock/doctype/shipment/test_shipment.py
+++ b/erpnext/stock/doctype/shipment/test_shipment.py
@@ -190,6 +190,7 @@
company.abbr = abbr
company.default_currency = 'EUR'
company.country = 'Germany'
+ company.enable_perpetual_inventory = 0
company.insert()
return company
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 8c9c172..21860b6 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -204,7 +204,8 @@
where
item_code = %(item_code)s
and warehouse = %(warehouse)s
- and timestamp(posting_date, time_format(posting_time, %(time_format)s)) = timestamp(%(posting_date)s, time_format(%(posting_time)s, %(time_format)s))
+ and voucher_type = %(voucher_type)s
+ and voucher_no = %(voucher_no)s
order by
creation ASC
for update