2022-02-08 01:00:37 +05:30
|
|
|
import json
|
|
|
|
from datetime import date, datetime
|
|
|
|
|
|
|
|
import frappe
|
|
|
|
from frappe import _
|
2023-11-10 13:45:52 +05:30
|
|
|
from frappe.utils import get_link_to_form, today
|
2022-02-08 01:00:37 +05:30
|
|
|
|
|
|
|
|
|
|
|
@frappe.whitelist()
|
|
|
|
def transaction_processing(data, from_doctype, to_doctype):
|
|
|
|
if isinstance(data, str):
|
|
|
|
deserialized_data = json.loads(data)
|
|
|
|
else:
|
|
|
|
deserialized_data = data
|
|
|
|
|
|
|
|
length_of_data = len(deserialized_data)
|
|
|
|
|
|
|
|
if length_of_data > 10:
|
|
|
|
frappe.msgprint(
|
|
|
|
_("Started a background job to create {1} {0}").format(to_doctype, length_of_data)
|
|
|
|
)
|
|
|
|
frappe.enqueue(
|
|
|
|
job,
|
|
|
|
deserialized_data=deserialized_data,
|
|
|
|
from_doctype=from_doctype,
|
|
|
|
to_doctype=to_doctype,
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
job(deserialized_data, from_doctype, to_doctype)
|
|
|
|
|
|
|
|
|
2023-11-10 12:20:30 +05:30
|
|
|
@frappe.whitelist()
|
2023-11-10 13:45:52 +05:30
|
|
|
def retry(date: str | None):
|
2023-11-10 12:20:30 +05:30
|
|
|
if date:
|
|
|
|
failed_docs = frappe.db.get_all(
|
|
|
|
"Bulk Transaction Log Detail",
|
|
|
|
filters={"date": date, "transaction_status": "Failed", "retried": 0},
|
|
|
|
fields=["name", "transaction_name", "from_doctype", "to_doctype"],
|
|
|
|
)
|
|
|
|
if not failed_docs:
|
2023-11-10 13:45:52 +05:30
|
|
|
frappe.msgprint(_("There are no Failed transactions"))
|
|
|
|
else:
|
|
|
|
job = frappe.enqueue(
|
|
|
|
retry_failed_transactions,
|
|
|
|
failed_docs=failed_docs,
|
|
|
|
)
|
|
|
|
frappe.msgprint(
|
|
|
|
_("Job: {0} has been triggered for processing failed transactions").format(
|
|
|
|
get_link_to_form("RQ Job", job.id)
|
|
|
|
)
|
|
|
|
)
|
2023-11-10 12:20:30 +05:30
|
|
|
|
2023-11-10 13:45:52 +05:30
|
|
|
|
|
|
|
def retry_failed_transactions(failed_docs: list | None):
|
|
|
|
if failed_docs:
|
2023-11-10 12:20:30 +05:30
|
|
|
for log in failed_docs:
|
|
|
|
try:
|
|
|
|
frappe.db.savepoint("before_creation_state")
|
|
|
|
task(log.transaction_name, log.from_doctype, log.to_doctype)
|
|
|
|
except Exception as e:
|
|
|
|
frappe.db.rollback(save_point="before_creation_state")
|
2023-11-11 05:20:27 +05:30
|
|
|
update_log(log.name, "Failed", 1, str(frappe.get_traceback()))
|
2023-11-10 12:20:30 +05:30
|
|
|
else:
|
|
|
|
update_log(log.name, "Success", 1)
|
|
|
|
|
|
|
|
|
2023-11-11 05:20:27 +05:30
|
|
|
def update_log(log_name, status, retried, err=None):
|
2023-11-10 12:20:30 +05:30
|
|
|
frappe.db.set_value("Bulk Transaction Log Detail", log_name, "transaction_status", status)
|
|
|
|
frappe.db.set_value("Bulk Transaction Log Detail", log_name, "retried", retried)
|
2023-11-11 05:20:27 +05:30
|
|
|
if err:
|
|
|
|
frappe.db.set_value("Bulk Transaction Log Detail", log_name, "error_description", err)
|
2023-11-10 12:20:30 +05:30
|
|
|
|
|
|
|
|
2022-02-08 01:00:37 +05:30
|
|
|
def job(deserialized_data, from_doctype, to_doctype):
|
2022-10-03 10:59:53 +05:30
|
|
|
fail_count = 0
|
2022-02-08 01:00:37 +05:30
|
|
|
for d in deserialized_data:
|
|
|
|
try:
|
|
|
|
doc_name = d.get("name")
|
|
|
|
frappe.db.savepoint("before_creation_state")
|
|
|
|
task(doc_name, from_doctype, to_doctype)
|
|
|
|
except Exception as e:
|
|
|
|
frappe.db.rollback(save_point="before_creation_state")
|
2022-10-03 10:59:53 +05:30
|
|
|
fail_count += 1
|
2023-11-09 16:38:34 +05:30
|
|
|
create_log(
|
2022-10-03 10:59:53 +05:30
|
|
|
doc_name,
|
|
|
|
str(frappe.get_traceback()),
|
|
|
|
from_doctype,
|
|
|
|
to_doctype,
|
|
|
|
status="Failed",
|
|
|
|
log_date=str(date.today()),
|
2022-03-28 18:52:46 +05:30
|
|
|
)
|
2022-10-03 10:59:53 +05:30
|
|
|
else:
|
2023-11-09 16:38:34 +05:30
|
|
|
create_log(
|
2022-02-08 01:00:37 +05:30
|
|
|
doc_name, None, from_doctype, to_doctype, status="Success", log_date=str(date.today())
|
2022-03-28 18:52:46 +05:30
|
|
|
)
|
2022-02-08 01:00:37 +05:30
|
|
|
|
2022-10-03 10:59:53 +05:30
|
|
|
show_job_status(fail_count, len(deserialized_data), to_doctype)
|
2022-02-08 01:00:37 +05:30
|
|
|
|
|
|
|
|
|
|
|
def task(doc_name, from_doctype, to_doctype):
|
|
|
|
from erpnext.accounts.doctype.payment_entry import payment_entry
|
|
|
|
from erpnext.accounts.doctype.purchase_invoice import purchase_invoice
|
|
|
|
from erpnext.accounts.doctype.sales_invoice import sales_invoice
|
|
|
|
from erpnext.buying.doctype.purchase_order import purchase_order
|
|
|
|
from erpnext.buying.doctype.supplier_quotation import supplier_quotation
|
|
|
|
from erpnext.selling.doctype.quotation import quotation
|
|
|
|
from erpnext.selling.doctype.sales_order import sales_order
|
|
|
|
from erpnext.stock.doctype.delivery_note import delivery_note
|
|
|
|
from erpnext.stock.doctype.purchase_receipt import purchase_receipt
|
|
|
|
|
|
|
|
mapper = {
|
|
|
|
"Sales Order": {
|
|
|
|
"Sales Invoice": sales_order.make_sales_invoice,
|
|
|
|
"Delivery Note": sales_order.make_delivery_note,
|
2023-04-25 19:16:30 +05:30
|
|
|
"Payment Entry": payment_entry.get_payment_entry,
|
2022-02-08 01:00:37 +05:30
|
|
|
},
|
|
|
|
"Sales Invoice": {
|
|
|
|
"Delivery Note": sales_invoice.make_delivery_note,
|
2022-11-17 15:53:56 +05:30
|
|
|
"Payment Entry": payment_entry.get_payment_entry,
|
2022-02-08 01:00:37 +05:30
|
|
|
},
|
|
|
|
"Delivery Note": {
|
|
|
|
"Sales Invoice": delivery_note.make_sales_invoice,
|
|
|
|
"Packing Slip": delivery_note.make_packing_slip,
|
|
|
|
},
|
|
|
|
"Quotation": {
|
|
|
|
"Sales Order": quotation.make_sales_order,
|
|
|
|
"Sales Invoice": quotation.make_sales_invoice,
|
|
|
|
},
|
|
|
|
"Supplier Quotation": {
|
|
|
|
"Purchase Order": supplier_quotation.make_purchase_order,
|
|
|
|
"Purchase Invoice": supplier_quotation.make_purchase_invoice,
|
|
|
|
},
|
|
|
|
"Purchase Order": {
|
|
|
|
"Purchase Invoice": purchase_order.make_purchase_invoice,
|
|
|
|
"Purchase Receipt": purchase_order.make_purchase_receipt,
|
2023-04-25 19:16:30 +05:30
|
|
|
"Payment Entry": payment_entry.get_payment_entry,
|
2022-02-08 01:00:37 +05:30
|
|
|
},
|
2022-10-03 10:59:53 +05:30
|
|
|
"Purchase Invoice": {
|
2022-02-08 01:00:37 +05:30
|
|
|
"Purchase Receipt": purchase_invoice.make_purchase_receipt,
|
2022-11-17 15:53:56 +05:30
|
|
|
"Payment Entry": payment_entry.get_payment_entry,
|
2022-02-08 01:00:37 +05:30
|
|
|
},
|
|
|
|
"Purchase Receipt": {"Purchase Invoice": purchase_receipt.make_purchase_invoice},
|
|
|
|
}
|
2023-04-25 19:16:30 +05:30
|
|
|
if to_doctype in ["Payment Entry"]:
|
2022-02-08 01:00:37 +05:30
|
|
|
obj = mapper[from_doctype][to_doctype](from_doctype, doc_name)
|
|
|
|
else:
|
|
|
|
obj = mapper[from_doctype][to_doctype](doc_name)
|
|
|
|
|
|
|
|
obj.flags.ignore_validate = True
|
2023-04-25 10:43:53 -03:00
|
|
|
obj.set_title_field()
|
2022-02-08 01:00:37 +05:30
|
|
|
obj.insert(ignore_mandatory=True)
|
|
|
|
|
|
|
|
|
2023-11-09 16:38:34 +05:30
|
|
|
def create_log(doc_name, e, from_doctype, to_doctype, status, log_date=None, restarted=0):
|
|
|
|
transaction_log = frappe.new_doc("Bulk Transaction Log Detail")
|
|
|
|
transaction_log.transaction_name = doc_name
|
|
|
|
transaction_log.date = today()
|
2022-02-08 01:00:37 +05:30
|
|
|
now = datetime.now()
|
2023-11-09 16:38:34 +05:30
|
|
|
transaction_log.time = now.strftime("%H:%M:%S")
|
|
|
|
transaction_log.transaction_status = status
|
|
|
|
transaction_log.error_description = str(e)
|
|
|
|
transaction_log.from_doctype = from_doctype
|
|
|
|
transaction_log.to_doctype = to_doctype
|
|
|
|
transaction_log.retried = restarted
|
|
|
|
transaction_log.save()
|
2022-02-08 01:00:37 +05:30
|
|
|
|
|
|
|
|
2022-10-03 10:59:53 +05:30
|
|
|
def show_job_status(fail_count, deserialized_data_count, to_doctype):
|
|
|
|
if not fail_count:
|
2022-02-08 01:00:37 +05:30
|
|
|
frappe.msgprint(
|
2022-11-17 15:53:56 +05:30
|
|
|
_("Creation of <b><a href='/app/{0}'>{1}(s)</a></b> successful").format(
|
|
|
|
to_doctype.lower().replace(" ", "-"), to_doctype
|
|
|
|
),
|
2022-02-08 01:00:37 +05:30
|
|
|
title="Successful",
|
|
|
|
indicator="green",
|
|
|
|
)
|
2022-10-03 10:59:53 +05:30
|
|
|
elif fail_count != 0 and fail_count < deserialized_data_count:
|
2022-02-08 01:00:37 +05:30
|
|
|
frappe.msgprint(
|
|
|
|
_(
|
|
|
|
"""Creation of {0} partially successful.
|
|
|
|
Check <b><a href="/app/bulk-transaction-log">Bulk Transaction Log</a></b>"""
|
|
|
|
).format(to_doctype),
|
|
|
|
title="Partially successful",
|
|
|
|
indicator="orange",
|
|
|
|
)
|
2022-10-03 10:59:53 +05:30
|
|
|
else:
|
2022-02-08 01:00:37 +05:30
|
|
|
frappe.msgprint(
|
|
|
|
_(
|
|
|
|
"""Creation of {0} failed.
|
|
|
|
Check <b><a href="/app/bulk-transaction-log">Bulk Transaction Log</a></b>"""
|
|
|
|
).format(to_doctype),
|
|
|
|
title="Failed",
|
|
|
|
indicator="red",
|
|
|
|
)
|