mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-14 07:01:56 +00:00
Merge pull request #56630 from mihir-kandoi/pg-convergence-fixes
fix: Postgres transaction-abort savepoints + div0/tiebreaker convergence fixes
This commit is contained in:
@@ -582,6 +582,7 @@ def make_gl_entries(
|
||||
frappe.db.commit()
|
||||
except Exception as e:
|
||||
if frappe.in_test:
|
||||
frappe.db.rollback()
|
||||
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
||||
raise e
|
||||
else:
|
||||
|
||||
@@ -47,6 +47,7 @@ def create_bank_entries(columns: str, data: str | list, bank_account: str):
|
||||
for key, value in header_map.items():
|
||||
fields.update({key: d[int(value) - 1]})
|
||||
|
||||
frappe.db.savepoint("bank_entry")
|
||||
try:
|
||||
bank_transaction = frappe.get_doc({"doctype": "Bank Transaction"})
|
||||
bank_transaction.update(fields)
|
||||
@@ -56,7 +57,8 @@ def create_bank_entries(columns: str, data: str | list, bank_account: str):
|
||||
bank_transaction.submit()
|
||||
success += 1
|
||||
except Exception:
|
||||
bank_transaction.log_error("Bank entry creation failed")
|
||||
frappe.db.rollback(save_point="bank_entry")
|
||||
frappe.log_error(title="Bank entry creation failed")
|
||||
errors += 1
|
||||
|
||||
return {"success": success, "errors": errors}
|
||||
|
||||
@@ -65,6 +65,7 @@ def start_merge(docname):
|
||||
total = len(ledger_merge.merge_accounts)
|
||||
for row in ledger_merge.merge_accounts:
|
||||
if not row.merged:
|
||||
frappe.db.savepoint("ledger_merge_row")
|
||||
try:
|
||||
merge_account(
|
||||
row.account,
|
||||
@@ -79,8 +80,7 @@ def start_merge(docname):
|
||||
{"ledger_merge": ledger_merge.name, "current": successful_merges, "total": total},
|
||||
)
|
||||
except Exception:
|
||||
if not frappe.in_test:
|
||||
frappe.db.rollback()
|
||||
frappe.db.rollback(save_point="ledger_merge_row")
|
||||
ledger_merge.log_error("Ledger merge failed")
|
||||
finally:
|
||||
if successful_merges == total:
|
||||
|
||||
@@ -514,10 +514,12 @@ class PaymentEntry(AccountsController):
|
||||
invoice_names.add((ref.reference_doctype, ref.reference_name))
|
||||
|
||||
for doctype, name in invoice_names:
|
||||
frappe.db.savepoint("subscription_update")
|
||||
try:
|
||||
doc = frappe.get_doc(doctype, name)
|
||||
doc.refresh_subscription_status()
|
||||
except Exception:
|
||||
frappe.db.rollback(save_point="subscription_update")
|
||||
frappe.log_error(_("Failed to update subscription status for {0} {1}").format(doctype, name))
|
||||
|
||||
def set_missing_values(self):
|
||||
|
||||
@@ -187,6 +187,7 @@ def make_depreciation_entry(
|
||||
for d in depr_schedule_doc.get("depreciation_schedule")[
|
||||
(sch_start_idx or 0) : (sch_end_idx or len(depr_schedule_doc.get("depreciation_schedule")))
|
||||
]:
|
||||
frappe.db.savepoint("depr_entry")
|
||||
try:
|
||||
_make_journal_entry_for_depreciation(
|
||||
depr_schedule_doc,
|
||||
@@ -202,6 +203,7 @@ def make_depreciation_entry(
|
||||
accounting_dimensions,
|
||||
)
|
||||
except Exception as e:
|
||||
frappe.db.rollback(save_point="depr_entry")
|
||||
depr_posting_error = e
|
||||
|
||||
asset.reload()
|
||||
|
||||
@@ -405,16 +405,10 @@ def get_default_scorecard_standing():
|
||||
def make_default_records():
|
||||
install_variable_docs = get_default_scorecard_variables()
|
||||
for d in install_variable_docs:
|
||||
try:
|
||||
d["doctype"] = "Supplier Scorecard Variable"
|
||||
frappe.get_doc(d).insert()
|
||||
except frappe.NameError:
|
||||
pass
|
||||
d["doctype"] = "Supplier Scorecard Variable"
|
||||
frappe.get_doc(d).insert(ignore_if_duplicate=True)
|
||||
|
||||
install_standing_docs = get_default_scorecard_standing()
|
||||
for d in install_standing_docs:
|
||||
try:
|
||||
d["doctype"] = "Supplier Scorecard Standing"
|
||||
frappe.get_doc(d).insert()
|
||||
except frappe.NameError:
|
||||
pass
|
||||
d["doctype"] = "Supplier Scorecard Standing"
|
||||
frappe.get_doc(d).insert(ignore_if_duplicate=True)
|
||||
|
||||
@@ -7,7 +7,7 @@ import frappe
|
||||
from frappe import _, bold
|
||||
from frappe.model.meta import get_field_precision
|
||||
from frappe.query_builder import DocType
|
||||
from frappe.query_builder.functions import Abs, Sum
|
||||
from frappe.query_builder.functions import Abs, NullIf, Sum
|
||||
from frappe.utils import cint, flt, format_datetime, get_datetime
|
||||
|
||||
import erpnext
|
||||
@@ -766,7 +766,7 @@ def get_rate_for_return(
|
||||
select_field = "incoming_rate"
|
||||
else:
|
||||
StockLedgerEntry = frappe.qb.DocType("Stock Ledger Entry")
|
||||
select_field = Abs(StockLedgerEntry.stock_value_difference / StockLedgerEntry.actual_qty)
|
||||
select_field = Abs(StockLedgerEntry.stock_value_difference / NullIf(StockLedgerEntry.actual_qty, 0))
|
||||
|
||||
item_details = frappe.get_cached_value("Item", item_code, ["has_batch_no", "has_expiry_date"], as_dict=1)
|
||||
set_zero_rate_for_expired_batch = frappe.db.get_single_value(
|
||||
|
||||
@@ -174,6 +174,7 @@ def send_mail(entry, email_campaign):
|
||||
subject = frappe.render_template(email_template.get("subject"), context)
|
||||
content = frappe.render_template(email_template.response_, context)
|
||||
|
||||
frappe.db.savepoint("email_campaign_send")
|
||||
try:
|
||||
comm = make(
|
||||
doctype="Email Campaign",
|
||||
@@ -197,6 +198,7 @@ def send_mail(entry, email_campaign):
|
||||
queue_separately=True,
|
||||
)
|
||||
except Exception:
|
||||
frappe.db.rollback(save_point="email_campaign_send")
|
||||
frappe.log_error(title="Email Campaign Failed.")
|
||||
|
||||
return comm
|
||||
|
||||
@@ -26,6 +26,7 @@ def create_prospect_against_crm_deal():
|
||||
prospect.insert()
|
||||
prospect_name = prospect.name
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(
|
||||
frappe.get_traceback(),
|
||||
f"Error while creating prospect against CRM Deal: {frappe.form_dict.get('crm_deal_id')}",
|
||||
@@ -70,6 +71,7 @@ def create_address(doctype, docname, address):
|
||||
if not address:
|
||||
return
|
||||
address = frappe.parse_json(address)
|
||||
frappe.db.savepoint("crm_create_address")
|
||||
try:
|
||||
_address = frappe.db.exists("Address", address.get("name"))
|
||||
if not _address:
|
||||
@@ -97,6 +99,7 @@ def create_address(doctype, docname, address):
|
||||
address.save(ignore_permissions=True)
|
||||
return address.name
|
||||
except Exception:
|
||||
frappe.db.rollback(save_point="crm_create_address")
|
||||
frappe.log_error(frappe.get_traceback(), f"Error while creating address for {docname}")
|
||||
|
||||
|
||||
@@ -157,6 +160,7 @@ def create_customer(customer_data: dict | None = None):
|
||||
create_address("Customer", customer_name, customer_data.get("address"))
|
||||
return customer_name
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(frappe.get_traceback(), "Error while creating customer against Frappe CRM Deal")
|
||||
pass
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ def add_institution(token: str, response: str | dict):
|
||||
)
|
||||
bank.insert()
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error("Plaid Link Error")
|
||||
else:
|
||||
bank = frappe.get_doc("Bank", response["institution"]["name"])
|
||||
@@ -154,6 +155,7 @@ def add_bank_accounts(response: str | dict, bank: str | dict, company: str):
|
||||
)
|
||||
|
||||
else:
|
||||
frappe.db.savepoint("plaid_update_account")
|
||||
try:
|
||||
existing_account = frappe.get_doc("Bank Account", existing_bank_account)
|
||||
existing_account.update(
|
||||
@@ -169,6 +171,7 @@ def add_bank_accounts(response: str | dict, bank: str | dict, company: str):
|
||||
existing_account.save()
|
||||
result.append(existing_bank_account)
|
||||
except Exception:
|
||||
frappe.db.rollback(save_point="plaid_update_account")
|
||||
frappe.log_error("Plaid Link Error")
|
||||
frappe.throw(
|
||||
_("There was an error updating Bank Account {0} while linking with Plaid.").format(
|
||||
|
||||
@@ -313,6 +313,7 @@ class BOMCreator(Document):
|
||||
|
||||
frappe.msgprint(_("BOMs created successfully"))
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
traceback = frappe.get_traceback(with_context=True)
|
||||
self.db_set(
|
||||
{
|
||||
|
||||
@@ -856,6 +856,7 @@ def install_country_fixtures(company, country):
|
||||
except ImportError:
|
||||
pass
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error("Unable to set country fixtures")
|
||||
frappe.throw(
|
||||
_("Failed to setup defaults for country {0}. Please contact support.").format(
|
||||
|
||||
@@ -120,6 +120,7 @@ def from_detailed_data(company_name, data):
|
||||
def update_regional_tax_settings(country, company):
|
||||
path = frappe.get_app_path("erpnext", "regional", frappe.scrub(country))
|
||||
if os.path.exists(path.encode("utf-8")):
|
||||
frappe.db.savepoint("regional_tax_settings")
|
||||
try:
|
||||
module_name = f"erpnext.regional.{frappe.scrub(country)}.setup.update_regional_tax_settings"
|
||||
frappe.get_attr(module_name)(country, company)
|
||||
@@ -127,6 +128,7 @@ def update_regional_tax_settings(country, company):
|
||||
pass
|
||||
except Exception:
|
||||
# Log error and ignore if failed to setup regional tax settings
|
||||
frappe.db.rollback(save_point="regional_tax_settings")
|
||||
frappe.log_error("Unable to setup regional tax settings")
|
||||
|
||||
|
||||
|
||||
@@ -95,7 +95,11 @@ def get_exchange_rate(
|
||||
|
||||
# cksgb 19/09/2016: get last entry in Currency Exchange with from_currency and to_currency.
|
||||
entries = frappe.get_all(
|
||||
"Currency Exchange", fields=["exchange_rate"], filters=filters, order_by="date desc", limit=1
|
||||
"Currency Exchange",
|
||||
fields=["exchange_rate"],
|
||||
filters=filters,
|
||||
order_by="date desc, name desc",
|
||||
limit=1,
|
||||
)
|
||||
if entries:
|
||||
return flt(entries[0].exchange_rate)
|
||||
|
||||
@@ -152,6 +152,7 @@ def prepare_closing_stock_balance(name):
|
||||
doc.create_stock_closing_balance_entries()
|
||||
doc.db_set("status", "Completed")
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
doc.db_set("status", "Failed")
|
||||
doc.log_error(title="Stock Closing Entry Failed")
|
||||
|
||||
|
||||
@@ -216,6 +216,7 @@ def create_material_request(material_requests):
|
||||
company_wise_mr = frappe._dict({})
|
||||
for request_type in material_requests:
|
||||
for company in material_requests[request_type]:
|
||||
frappe.db.savepoint("reorder_mr")
|
||||
try:
|
||||
items = material_requests[request_type][company]
|
||||
if not items:
|
||||
@@ -287,8 +288,9 @@ def create_material_request(material_requests):
|
||||
company_wise_mr.setdefault(company, []).append(mr)
|
||||
|
||||
except Exception as exception:
|
||||
frappe.db.rollback(save_point="reorder_mr")
|
||||
exceptions_list.append(exception)
|
||||
mr.log_error("Unable to create material request")
|
||||
frappe.log_error(title="Unable to create material request")
|
||||
|
||||
if company_wise_mr:
|
||||
if getattr(frappe.local, "reorder_email_notify", None) is None:
|
||||
|
||||
@@ -202,6 +202,7 @@ def create_reposting_entries(rows: str | list, company: str):
|
||||
|
||||
for key, sle in item_wh.items():
|
||||
item_code, warehouse = key
|
||||
frappe.db.savepoint("repost_value_comparison")
|
||||
try:
|
||||
doc = frappe.get_doc(
|
||||
{
|
||||
@@ -219,7 +220,7 @@ def create_reposting_entries(rows: str | list, company: str):
|
||||
|
||||
entries.append(get_link_to_form("Repost Item Valuation", doc.name))
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
frappe.db.rollback(save_point="repost_value_comparison")
|
||||
|
||||
if entries:
|
||||
entries = ", ".join(entries)
|
||||
|
||||
@@ -304,6 +304,7 @@ def create_reposting_entries(rows: str | list, item_code: str | None = None, war
|
||||
for row in rows:
|
||||
row = frappe._dict(row)
|
||||
|
||||
frappe.db.savepoint("repost_invariant_check")
|
||||
try:
|
||||
doc = frappe.get_doc(
|
||||
{
|
||||
@@ -320,6 +321,7 @@ def create_reposting_entries(rows: str | list, item_code: str | None = None, war
|
||||
|
||||
entries.append(get_link_to_form("Repost Item Valuation", doc.name))
|
||||
except frappe.DuplicateEntryError:
|
||||
frappe.db.rollback(save_point="repost_invariant_check")
|
||||
continue
|
||||
|
||||
if entries:
|
||||
|
||||
@@ -163,6 +163,7 @@ def link_existing_conversations(doc, state):
|
||||
return
|
||||
if doc.doctype != "Contact":
|
||||
return
|
||||
frappe.db.savepoint("link_call_logs")
|
||||
try:
|
||||
numbers = [d.phone for d in doc.phone_nos]
|
||||
|
||||
@@ -196,6 +197,7 @@ def link_existing_conversations(doc, state):
|
||||
if not frappe.in_test:
|
||||
frappe.db.commit()
|
||||
except Exception:
|
||||
frappe.db.rollback(save_point="link_call_logs")
|
||||
frappe.log_error(title=_("Error during caller information update"))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user