blob: 64e2ff42184505d7bc954758767954d237653b3a [file] [log] [blame]
Mohammed Yusuf Shaikha3e69cf2022-02-08 01:00:37 +05301import json
2from datetime import date, datetime
3
4import frappe
5from frappe import _
6
7
8@frappe.whitelist()
9def transaction_processing(data, from_doctype, to_doctype):
10 if isinstance(data, str):
11 deserialized_data = json.loads(data)
12
13 else:
14 deserialized_data = data
15
16 length_of_data = len(deserialized_data)
17
18 if length_of_data > 10:
19 frappe.msgprint(
20 _("Started a background job to create {1} {0}").format(to_doctype, length_of_data)
21 )
22 frappe.enqueue(
23 job,
24 deserialized_data=deserialized_data,
25 from_doctype=from_doctype,
26 to_doctype=to_doctype,
27 )
28 else:
29 job(deserialized_data, from_doctype, to_doctype)
30
31
32def job(deserialized_data, from_doctype, to_doctype):
33 failed_history = []
34 i = 0
35 for d in deserialized_data:
36 failed = []
37
38 try:
39 i += 1
40 doc_name = d.get("name")
41 frappe.db.savepoint("before_creation_state")
42 task(doc_name, from_doctype, to_doctype)
43
44 except Exception as e:
45 frappe.db.rollback(save_point="before_creation_state")
46 failed_history.append(e)
47 failed.append(e)
48 update_logger(doc_name, e, from_doctype, to_doctype, status="Failed", log_date=str(date.today()))
49 if not failed:
50 update_logger(doc_name, None, from_doctype, to_doctype, status="Success", log_date=str(date.today()))
51
52 show_job_status(failed_history, deserialized_data, to_doctype)
53
54
55def task(doc_name, from_doctype, to_doctype):
56 from erpnext.accounts.doctype.payment_entry import payment_entry
57 from erpnext.accounts.doctype.purchase_invoice import purchase_invoice
58 from erpnext.accounts.doctype.sales_invoice import sales_invoice
59 from erpnext.buying.doctype.purchase_order import purchase_order
60 from erpnext.buying.doctype.supplier_quotation import supplier_quotation
61 from erpnext.selling.doctype.quotation import quotation
62 from erpnext.selling.doctype.sales_order import sales_order
63 from erpnext.stock.doctype.delivery_note import delivery_note
64 from erpnext.stock.doctype.purchase_receipt import purchase_receipt
65
66 mapper = {
67 "Sales Order": {
68 "Sales Invoice": sales_order.make_sales_invoice,
69 "Delivery Note": sales_order.make_delivery_note,
70 "Advance Payment": payment_entry.get_payment_entry,
71 },
72 "Sales Invoice": {
73 "Delivery Note": sales_invoice.make_delivery_note,
74 "Payment": payment_entry.get_payment_entry,
75 },
76 "Delivery Note": {
77 "Sales Invoice": delivery_note.make_sales_invoice,
78 "Packing Slip": delivery_note.make_packing_slip,
79 },
80 "Quotation": {
81 "Sales Order": quotation.make_sales_order,
82 "Sales Invoice": quotation.make_sales_invoice,
83 },
84 "Supplier Quotation": {
85 "Purchase Order": supplier_quotation.make_purchase_order,
86 "Purchase Invoice": supplier_quotation.make_purchase_invoice,
87 "Advance Payment": payment_entry.get_payment_entry,
88 },
89 "Purchase Order": {
90 "Purchase Invoice": purchase_order.make_purchase_invoice,
91 "Purchase Receipt": purchase_order.make_purchase_receipt,
92 },
93 "Purhcase Invoice": {
94 "Purchase Receipt": purchase_invoice.make_purchase_receipt,
95 "Payment": payment_entry.get_payment_entry,
96 },
97 "Purchase Receipt": {"Purchase Invoice": purchase_receipt.make_purchase_invoice},
98 }
99 if to_doctype in ['Advance Payment', 'Payment']:
100 obj = mapper[from_doctype][to_doctype](from_doctype, doc_name)
101 else:
102 obj = mapper[from_doctype][to_doctype](doc_name)
103
104 obj.flags.ignore_validate = True
105 obj.insert(ignore_mandatory=True)
106
107
108def check_logger_doc_exists(log_date):
109 return frappe.db.exists("Bulk Transaction Log", log_date)
110
111
112def get_logger_doc(log_date):
113 return frappe.get_doc("Bulk Transaction Log", log_date)
114
115
116def create_logger_doc():
117 log_doc = frappe.new_doc("Bulk Transaction Log")
118 log_doc.set_new_name(set_name=str(date.today()))
119 log_doc.log_date = date.today()
120
121 return log_doc
122
123
124def append_data_to_logger(log_doc, doc_name, error, from_doctype, to_doctype, status, restarted):
125 row = log_doc.append("logger_data", {})
126 row.transaction_name = doc_name
127 row.date = date.today()
128 now = datetime.now()
129 row.time = now.strftime("%H:%M:%S")
130 row.transaction_status = status
131 row.error_description = str(error)
132 row.from_doctype = from_doctype
133 row.to_doctype = to_doctype
134 row.retried = restarted
135
136
137def update_logger(doc_name, e, from_doctype, to_doctype, status, log_date=None, restarted=0):
138 if not check_logger_doc_exists(log_date):
139 log_doc = create_logger_doc()
140 append_data_to_logger(log_doc, doc_name, e, from_doctype, to_doctype, status, restarted)
141 log_doc.insert()
142 else:
143 log_doc = get_logger_doc(log_date)
144 if record_exists(log_doc, doc_name, status):
145 append_data_to_logger(
146 log_doc, doc_name, e, from_doctype, to_doctype, status, restarted
147 )
148 log_doc.save()
149
150
151def show_job_status(failed_history, deserialized_data, to_doctype):
152 if not failed_history:
153 frappe.msgprint(
154 _("Creation of {0} successful").format(to_doctype),
155 title="Successful",
156 indicator="green",
157 )
158
159 if len(failed_history) != 0 and len(failed_history) < len(deserialized_data):
160 frappe.msgprint(
161 _("""Creation of {0} partially successful.
162 Check <b><a href="/app/bulk-transaction-log">Bulk Transaction Log</a></b>""").format(
163 to_doctype
164 ),
165 title="Partially successful",
166 indicator="orange",
167 )
168
169 if len(failed_history) == len(deserialized_data):
170 frappe.msgprint(
171 _("""Creation of {0} failed.
172 Check <b><a href="/app/bulk-transaction-log">Bulk Transaction Log</a></b>""").format(
173 to_doctype
174 ),
175 title="Failed",
176 indicator="red",
177 )
178
179
180def record_exists(log_doc, doc_name, status):
181
182 record = mark_retrired_transaction(log_doc, doc_name)
183
184 if record and status == "Failed":
185 return False
186 elif record and status == "Success":
187 return True
188 else:
189 return True
190
191
192def mark_retrired_transaction(log_doc, doc_name):
193 record = 0
194 for d in log_doc.get("logger_data"):
195 if d.transaction_name == doc_name and d.transaction_status == "Failed":
196 d.retried = 1
197 record = record + 1
198
199 log_doc.save()
200
201 return record