blob: bff83f9e0d305df9590700995572eb0cbd60a09e [file] [log] [blame]
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +05301import json
2from datetime import date, datetime
3
4import frappe
5from frappe import _
ruthra kumarc3202882023-11-10 13:45:52 +05306from frappe.utils import get_link_to_form, today
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +05307
8
9@frappe.whitelist()
David Arnoldffd38362024-01-23 17:42:56 +010010def transaction_processing(data, from_doctype, to_doctype, args=None):
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053011 if isinstance(data, str):
12 deserialized_data = json.loads(data)
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053013 else:
14 deserialized_data = data
15
David Arnoldffd38362024-01-23 17:42:56 +010016 if isinstance(args, str):
17 args = frappe._dict(json.loads(args))
18
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053019 length_of_data = len(deserialized_data)
20
Akhil Narang3effaf22024-03-27 11:37:26 +053021 frappe.msgprint(_("Started a background job to create {1} {0}").format(to_doctype, length_of_data))
ruthra kumar15dc5c72024-01-05 14:32:05 +053022 frappe.enqueue(
23 job,
24 deserialized_data=deserialized_data,
25 from_doctype=from_doctype,
26 to_doctype=to_doctype,
David Arnoldffd38362024-01-23 17:42:56 +010027 args=args,
ruthra kumar15dc5c72024-01-05 14:32:05 +053028 )
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053029
30
ruthra kumar0aa16362023-11-10 12:20:30 +053031@frappe.whitelist()
ruthra kumarfb06ad72023-11-20 13:26:02 +053032def retry(date: str | None = None):
33 if not date:
34 date = today()
35
ruthra kumar0aa16362023-11-10 12:20:30 +053036 if date:
37 failed_docs = frappe.db.get_all(
38 "Bulk Transaction Log Detail",
39 filters={"date": date, "transaction_status": "Failed", "retried": 0},
40 fields=["name", "transaction_name", "from_doctype", "to_doctype"],
41 )
42 if not failed_docs:
ruthra kumarc3202882023-11-10 13:45:52 +053043 frappe.msgprint(_("There are no Failed transactions"))
44 else:
45 job = frappe.enqueue(
46 retry_failed_transactions,
47 failed_docs=failed_docs,
48 )
49 frappe.msgprint(
50 _("Job: {0} has been triggered for processing failed transactions").format(
51 get_link_to_form("RQ Job", job.id)
52 )
53 )
ruthra kumar0aa16362023-11-10 12:20:30 +053054
ruthra kumarc3202882023-11-10 13:45:52 +053055
56def retry_failed_transactions(failed_docs: list | None):
57 if failed_docs:
ruthra kumar0aa16362023-11-10 12:20:30 +053058 for log in failed_docs:
59 try:
60 frappe.db.savepoint("before_creation_state")
61 task(log.transaction_name, log.from_doctype, log.to_doctype)
Akhil Narang3effaf22024-03-27 11:37:26 +053062 except Exception:
ruthra kumar0aa16362023-11-10 12:20:30 +053063 frappe.db.rollback(save_point="before_creation_state")
Ankush Menat510fdf72024-01-01 13:10:03 +053064 update_log(log.name, "Failed", 1, str(frappe.get_traceback(with_context=True)))
ruthra kumar0aa16362023-11-10 12:20:30 +053065 else:
66 update_log(log.name, "Success", 1)
67
68
ruthra kumara52a1b42023-11-11 05:20:27 +053069def update_log(log_name, status, retried, err=None):
ruthra kumar0aa16362023-11-10 12:20:30 +053070 frappe.db.set_value("Bulk Transaction Log Detail", log_name, "transaction_status", status)
71 frappe.db.set_value("Bulk Transaction Log Detail", log_name, "retried", retried)
ruthra kumara52a1b42023-11-11 05:20:27 +053072 if err:
73 frappe.db.set_value("Bulk Transaction Log Detail", log_name, "error_description", err)
ruthra kumar0aa16362023-11-10 12:20:30 +053074
75
David Arnoldffd38362024-01-23 17:42:56 +010076def job(deserialized_data, from_doctype, to_doctype, args):
Dany Robert91055152022-10-03 10:59:53 +053077 fail_count = 0
David Arnoldffd38362024-01-23 17:42:56 +010078
79 if args:
80 # currently: flag-based transport to `task`
81 frappe.flags.args = args
82
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053083 for d in deserialized_data:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053084 try:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053085 doc_name = d.get("name")
86 frappe.db.savepoint("before_creation_state")
87 task(doc_name, from_doctype, to_doctype)
Akhil Narang3effaf22024-03-27 11:37:26 +053088 except Exception:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +053089 frappe.db.rollback(save_point="before_creation_state")
Dany Robert91055152022-10-03 10:59:53 +053090 fail_count += 1
ruthra kumarebd74a42023-11-09 16:38:34 +053091 create_log(
Dany Robert91055152022-10-03 10:59:53 +053092 doc_name,
Ankush Menat510fdf72024-01-01 13:10:03 +053093 str(frappe.get_traceback(with_context=True)),
Dany Robert91055152022-10-03 10:59:53 +053094 from_doctype,
95 to_doctype,
96 status="Failed",
97 log_date=str(date.today()),
Ankush Menat494bd9e2022-03-28 18:52:46 +053098 )
Dany Robert91055152022-10-03 10:59:53 +053099 else:
Akhil Narang3effaf22024-03-27 11:37:26 +0530100 create_log(doc_name, None, from_doctype, to_doctype, status="Success", log_date=str(date.today()))
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530101
Dany Robert91055152022-10-03 10:59:53 +0530102 show_job_status(fail_count, len(deserialized_data), to_doctype)
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530103
104
105def task(doc_name, from_doctype, to_doctype):
106 from erpnext.accounts.doctype.payment_entry import payment_entry
107 from erpnext.accounts.doctype.purchase_invoice import purchase_invoice
108 from erpnext.accounts.doctype.sales_invoice import sales_invoice
109 from erpnext.buying.doctype.purchase_order import purchase_order
110 from erpnext.buying.doctype.supplier_quotation import supplier_quotation
111 from erpnext.selling.doctype.quotation import quotation
112 from erpnext.selling.doctype.sales_order import sales_order
113 from erpnext.stock.doctype.delivery_note import delivery_note
114 from erpnext.stock.doctype.purchase_receipt import purchase_receipt
115
116 mapper = {
117 "Sales Order": {
118 "Sales Invoice": sales_order.make_sales_invoice,
119 "Delivery Note": sales_order.make_delivery_note,
Solufy Solutionf1acc5f2023-04-25 19:16:30 +0530120 "Payment Entry": payment_entry.get_payment_entry,
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530121 },
122 "Sales Invoice": {
123 "Delivery Note": sales_invoice.make_delivery_note,
Deepesh Garg2dfe8492022-11-17 15:53:56 +0530124 "Payment Entry": payment_entry.get_payment_entry,
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530125 },
126 "Delivery Note": {
127 "Sales Invoice": delivery_note.make_sales_invoice,
128 "Packing Slip": delivery_note.make_packing_slip,
129 },
130 "Quotation": {
131 "Sales Order": quotation.make_sales_order,
132 "Sales Invoice": quotation.make_sales_invoice,
133 },
134 "Supplier Quotation": {
135 "Purchase Order": supplier_quotation.make_purchase_order,
136 "Purchase Invoice": supplier_quotation.make_purchase_invoice,
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530137 },
138 "Purchase Order": {
139 "Purchase Invoice": purchase_order.make_purchase_invoice,
140 "Purchase Receipt": purchase_order.make_purchase_receipt,
Solufy Solutionf1acc5f2023-04-25 19:16:30 +0530141 "Payment Entry": payment_entry.get_payment_entry,
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530142 },
Dany Robert91055152022-10-03 10:59:53 +0530143 "Purchase Invoice": {
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530144 "Purchase Receipt": purchase_invoice.make_purchase_receipt,
Deepesh Garg2dfe8492022-11-17 15:53:56 +0530145 "Payment Entry": payment_entry.get_payment_entry,
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530146 },
147 "Purchase Receipt": {"Purchase Invoice": purchase_receipt.make_purchase_invoice},
148 }
David Arnold426c2452023-11-14 11:13:05 +0100149 frappe.flags.bulk_transaction = True
Solufy Solutionf1acc5f2023-04-25 19:16:30 +0530150 if to_doctype in ["Payment Entry"]:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530151 obj = mapper[from_doctype][to_doctype](from_doctype, doc_name)
152 else:
153 obj = mapper[from_doctype][to_doctype](doc_name)
154
David Arnold9a705162024-01-30 12:59:26 +0100155 if obj:
156 obj.flags.ignore_validate = True
157 obj.set_title_field()
158 obj.insert(ignore_mandatory=True)
159
160 del obj
David Arnold426c2452023-11-14 11:13:05 +0100161 del frappe.flags.bulk_transaction
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530162
163
ruthra kumarebd74a42023-11-09 16:38:34 +0530164def create_log(doc_name, e, from_doctype, to_doctype, status, log_date=None, restarted=0):
165 transaction_log = frappe.new_doc("Bulk Transaction Log Detail")
166 transaction_log.transaction_name = doc_name
167 transaction_log.date = today()
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530168 now = datetime.now()
ruthra kumarebd74a42023-11-09 16:38:34 +0530169 transaction_log.time = now.strftime("%H:%M:%S")
170 transaction_log.transaction_status = status
171 transaction_log.error_description = str(e)
172 transaction_log.from_doctype = from_doctype
173 transaction_log.to_doctype = to_doctype
174 transaction_log.retried = restarted
David49dd4c12024-03-18 23:05:58 +0100175 transaction_log.save(ignore_permissions=True)
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530176
177
Dany Robert91055152022-10-03 10:59:53 +0530178def show_job_status(fail_count, deserialized_data_count, to_doctype):
179 if not fail_count:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530180 frappe.msgprint(
Deepesh Garg2dfe8492022-11-17 15:53:56 +0530181 _("Creation of <b><a href='/app/{0}'>{1}(s)</a></b> successful").format(
182 to_doctype.lower().replace(" ", "-"), to_doctype
183 ),
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530184 title="Successful",
185 indicator="green",
186 )
Dany Robert91055152022-10-03 10:59:53 +0530187 elif fail_count != 0 and fail_count < deserialized_data_count:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530188 frappe.msgprint(
Ankush Menat494bd9e2022-03-28 18:52:46 +0530189 _(
190 """Creation of {0} partially successful.
191 Check <b><a href="/app/bulk-transaction-log">Bulk Transaction Log</a></b>"""
192 ).format(to_doctype),
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530193 title="Partially successful",
194 indicator="orange",
195 )
Dany Robert91055152022-10-03 10:59:53 +0530196 else:
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530197 frappe.msgprint(
Ankush Menat494bd9e2022-03-28 18:52:46 +0530198 _(
199 """Creation of {0} failed.
200 Check <b><a href="/app/bulk-transaction-log">Bulk Transaction Log</a></b>"""
201 ).format(to_doctype),
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +0530202 title="Failed",
203 indicator="red",
204 )