Skip to content

Commit

Permalink
[v14] handle errors in background queue (#72)
Browse files Browse the repository at this point in the history
* feat: handle errors in background queue

* style: prettify code

* feat: use process_checks instead of submit triggers to manage submission and errors

* style: prettify code

---------

Co-authored-by: agritheory <[email protected]>
  • Loading branch information
agritheory and agritheory authored Mar 6, 2023
1 parent 7f940f3 commit 1b9b592
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 117 deletions.
32 changes: 31 additions & 1 deletion check_run/check_run/doctype/check_run/check_run.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ frappe.ui.form.on('Check Run', {
},
refresh: frm => {
frm.layout.show_message('')
frm.trigger('update_primary_action')
if (frm.doc.__onload && frm.doc.__onload.errors) {
frm.set_intro(__('<a href="" style="color: var(--red)" id="check-run-error">This Check Run has errors, click to view.</a>'), 'red')
$('#check-run-error')
.off()
.on('click', e => {
frappe.route_options = { method: ['like', `%${frm.doc.name}%`] }
frappe.set_route('list', 'Error Log')
e.stopPropagation()
})
}
settings_button(frm)
permit_first_user(frm)
get_defaults(frm)
Expand All @@ -29,7 +40,6 @@ frappe.ui.form.on('Check Run', {
frappe.realtime.on('reload', message => {
frm.reload_doc()
})

if (frm.is_new()) {
get_balance(frm)
}
Expand All @@ -45,6 +55,10 @@ frappe.ui.form.on('Check Run', {
onload_post_render: frm => {
frm.page.wrapper.find('.layout-side-section').hide()
permit_first_user(frm)
frm.trigger('update_primary_action')
$(frm.wrapper).on('dirty', () => {
frm.trigger('update_primary_action')
})
},
end_date: frm => {
get_entries(frm)
Expand Down Expand Up @@ -75,6 +89,22 @@ frappe.ui.form.on('Check Run', {
bank_account: frm => {
get_balance(frm)
},
process_check_run: frm => {
frm.layout.show_message('')
frm.doc.status = 'Submitting'
frm.page.set_indicator(__('Submitting'), 'orange')
frm.disable_form()
$(frm.$check_run).css({ 'pointer-events': 'none' })
frappe.xcall('check_run.check_run.doctype.check_run.check_run.process_check_run', { docname: frm.doc.name })
},
update_primary_action: frm => {
frm.disable_save()
if (frm.is_dirty()) {
frm.enable_save()
} else if (frm.doc.status === 'Draft') {
frm.page.set_primary_action(__('Process Check Run'), () => frm.trigger('process_check_run'))
}
},
})

function get_balance(frm) {
Expand Down
62 changes: 37 additions & 25 deletions check_run/check_run/doctype/check_run/check_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def onload(self):
settings = get_check_run_settings(self)
if not settings:
self.set_onload('settings_missing', True)
errors = frappe.get_all('Error Log', {'method': ['like', f"%{self.name}%"]})
if errors and self.docstatus == 0:
self.set_onload('errors', True)

def validate(self):
self.set_status()
Expand Down Expand Up @@ -125,37 +128,37 @@ def validate_last_check_number(self, check_number=None):
frappe.throw(f'Initial Check Number cannot be lower than the last used check number <b>{account_check_number}</b> for <b>{self.bank_account}</b>')

@frappe.whitelist()
def before_submit(self):
def process_check_run(self):
self.status = 'Submitting'
transactions = self.transactions
transactions = json.loads(transactions)
if len(transactions) < 1:
frappe.throw("You must select at least one Invoice to pay.")
frappe.throw(frappe._("You must select at least one Invoice to pay."))
self.print_count = 0
if self.ach_only().ach_only:
self.initial_check_number = ""
self.final_check_number = ""
frappe.enqueue_doc(self.doctype, self.name, "_process_check_run", save=True, queue="short", timeout=3600)

if len(transactions) < 25:
self._before_submit()
else:
self.status = 'Submitting'
frappe.enqueue_doc(self.doctype, self.name, "_before_submit", save=True, queue="short", timeout=3600)

def _before_submit(self, save=False):
def _process_check_run(self, save=False):
savepoint = "process_check_run"
frappe.db.savepoint(savepoint)
try:
transactions = self.transactions
transactions = json.loads(transactions)
transactions = sorted([frappe._dict(item) for item in transactions if item.get("pay")], key=lambda x: x.party)
_transactions = self.create_payment_entries(transactions)

self.db_set('transactions', json.dumps(_transactions))
self.db_set('status', 'Submitted')
if self.final_check_number:
frappe.db.set_value('Bank Account', self.bank_account, 'check_number', self.final_check_number)
frappe.db.commit()
frappe.publish_realtime('reload', '{}', doctype=self.doctype, docname=self.name)
except Exception as e:
frappe.log_error(title=f"{self.name} Check Run Error", message=e)
frappe.db.rollback(savepoint="process_check_run")
raise e

self.transactions = json.dumps(_transactions)
self.set_status('Submitted')
self.save()
self.submit()
if self.final_check_number:
frappe.db.set_value('Bank Account', self.bank_account, 'check_number', self.final_check_number)
frappe.publish_realtime('reload', '{}', doctype=self.doctype, docname=self.name)

def build_nacha_file(self, settings=None):
electronic_mop = frappe.get_all('Mode of Payment', {'type': 'Electronic', 'enabled': 1}, 'name', pluck="name")
Expand All @@ -168,7 +171,6 @@ def build_nacha_file(self, settings=None):
ach_file.seek(0)
return ach_file


@frappe.whitelist()
def ach_only(self):
transactions = json.loads(self.transactions) if self.transactions else []
Expand Down Expand Up @@ -263,8 +265,14 @@ def create_payment_entries(self, transactions):
pe.paid_amount = total_amount
pe.base_paid_amount = total_amount
pe.base_grand_total = total_amount
pe.save()
pe.submit()
try:
pe.save()
pe.submit()
except Exception as e:
frappe.db.rollback()
frappe.log_error(title=f"{self.name} Check Run Error", message=e)
frappe.publish_realtime('reload', '{}', doctype=self.doctype, docname=self.name)
raise e
for reference in _references:
reference.payment_entry = pe.name
_transactions.append(reference)
Expand All @@ -273,13 +281,12 @@ def create_payment_entries(self, transactions):

@frappe.whitelist()
def increment_print_count(self, reprint_check_number=None):
self.load_from_db()
print('render checks')
frappe.enqueue_doc(self.doctype, self.name, 'render_check_pdf', reprint_check_number=reprint_check_number, queue='short', now=True)


@frappe.whitelist()
def render_check_pdf(self, reprint_check_number=None):
self.load_from_db()
self.print_count = self.print_count + 1
self.set_status('Submitted')
if not frappe.db.exists('File', 'Home/Check Run'):
Expand Down Expand Up @@ -404,7 +411,7 @@ def get_entries(doc):
.where(purchase_invoices.docstatus == 1)
.where(purchase_invoices.credit_to == pay_to_account)
.where(purchase_invoices.due_date <= end_date)
.where(Coalesce(purchase_invoices.release_date, datetime.date(1900, 1, 1)) <= end_date)
.where(Coalesce(purchase_invoices.release_date, datetime.date(1900, 1, 1)) < end_date)
)

# Build expense claims query
Expand Down Expand Up @@ -492,7 +499,6 @@ def get_entries(doc):
}, as_dict=True)
for transaction in transactions:
if settings and settings.pre_check_overdue_items:
print(transaction.due_date, doc.posting_date)
if transaction.due_date < doc.posting_date:
transaction.pay = 1
if transaction.doctype == 'Journal Entry':
Expand Down Expand Up @@ -644,4 +650,10 @@ def ach_only(docname):
if not frappe.db.exists('Check Run', docname):
return {'ach_only': False, 'checks_only': False}
cr = frappe.get_doc('Check Run', docname)
return cr.ach_only()
return cr.ach_only()


@frappe.whitelist()
def process_check_run(docname):
doc = frappe.get_doc('Check Run', docname)
doc.process_check_run()
Loading

0 comments on commit 1b9b592

Please sign in to comment.