diff --git a/check_run/check_run/doctype/check_run/check_run.js b/check_run/check_run/doctype/check_run/check_run.js
index aabfd4e8..0ba6cbc4 100644
--- a/check_run/check_run/doctype/check_run/check_run.js
+++ b/check_run/check_run/doctype/check_run/check_run.js
@@ -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(__('This Check Run has errors, click to view.'), '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)
@@ -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)
}
@@ -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)
@@ -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) {
diff --git a/check_run/check_run/doctype/check_run/check_run.py b/check_run/check_run/doctype/check_run/check_run.py
index a708e0a5..43fdca86 100644
--- a/check_run/check_run/doctype/check_run/check_run.py
+++ b/check_run/check_run/doctype/check_run/check_run.py
@@ -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()
@@ -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 {account_check_number} for {self.bank_account}')
@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")
@@ -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 []
@@ -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)
@@ -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'):
@@ -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
@@ -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':
@@ -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()
\ No newline at end of file
+ return cr.ach_only()
+
+
+@frappe.whitelist()
+def process_check_run(docname):
+ doc = frappe.get_doc('Check Run', docname)
+ doc.process_check_run()
diff --git a/check_run/test_setup.py b/check_run/test_setup.py
index f9311bef..e4c34384 100644
--- a/check_run/test_setup.py
+++ b/check_run/test_setup.py
@@ -97,105 +97,108 @@ def before_test():
}),
]
-employees = [('Wilmer Larson',
- 'Male',
- '1977-03-06',
- '2019-04-12',
- '20 Gaven Path',
- 'Spokane',
- 'NV',
- '66308'),
+employees = [
+ ('Wilmer Larson',
+ 'Male',
+ '1977-03-06',
+ '2019-04-12',
+ '20 Gaven Path',
+ 'Spokane',
+ 'NV',
+ '66308'),
('Shanel Finley',
- 'Female',
- '1984-04-23',
- '2019-07-04',
- '1070 Ulloa Green',
- 'DeKalb',
- 'PA',
- '30474'),
+ 'Female',
+ '1984-04-23',
+ '2019-07-04',
+ '1070 Ulloa Green',
+ 'DeKalb',
+ 'PA',
+ '30474'),
('Camellia Phelps',
- 'Female',
- '1980-07-06',
- '2019-07-28',
- '787 Sotelo Arcade',
- 'Stockton',
- 'CO',
- '14860'),
+ 'Female',
+ '1980-07-06',
+ '2019-07-28',
+ '787 Sotelo Arcade',
+ 'Stockton',
+ 'CO',
+ '14860'),
('Michale Mitchell',
- 'Male',
- '1984-06-29',
- '2020-01-12',
- '773 Icehouse Road',
- 'West Sacramento',
- 'VT',
- '24355'),
+ 'Male',
+ '1984-06-29',
+ '2020-01-12',
+ '773 Icehouse Road',
+ 'West Sacramento',
+ 'VT',
+ '24355'),
('Sharilyn Romero',
- 'Female',
- '1998-04-22',
- '2020-03-20',
- '432 Dudley Ranch',
- 'Clovis',
- 'WA',
- '97159'),
+ 'Female',
+ '1998-04-22',
+ '2020-03-20',
+ '432 Dudley Ranch',
+ 'Clovis',
+ 'WA',
+ '97159'),
('Doug Buckley',
- 'Male',
- '1979-06-18',
- '2020-09-08',
- '771 Battery Caulfield Motorway',
- 'Yonkers',
- 'VT',
- '38125'),
+ 'Male',
+ '1979-06-18',
+ '2020-09-08',
+ '771 Battery Caulfield Motorway',
+ 'Yonkers',
+ 'VT',
+ '38125'),
('Margarito Wallace',
- 'Male',
- '1991-08-17',
- '2020-11-01',
- '639 Brook Park',
- 'Terre Haute',
- 'OR',
- '41704'),
+ 'Male',
+ '1991-08-17',
+ '2020-11-01',
+ '639 Brook Park',
+ 'Terre Haute',
+ 'OR',
+ '41704'),
('Mckenzie Ashley',
- 'Female',
- '1997-09-13',
- '2021-02-22',
- '1119 Hunter Glen',
- 'Ormond Beach',
- 'MD',
- '30864'),
+ 'Female',
+ '1997-09-13',
+ '2021-02-22',
+ '1119 Hunter Glen',
+ 'Ormond Beach',
+ 'MD',
+ '30864'),
('Merrie Oliver',
- 'Other',
- '1979-11-08',
- '2021-03-11',
- '267 Vega Freeway',
- 'West Palm Beach',
- 'FL',
- '24411'),
+ 'Other',
+ '1979-11-08',
+ '2021-03-11',
+ '267 Vega Freeway',
+ 'West Palm Beach',
+ 'FL',
+ '24411'),
('Naoma Blake',
- 'Female',
- '1987-07-10',
- '2021-06-21',
- '649 Conrad Road',
- 'Thousand Oaks',
- 'CT',
- '97929'),
+ 'Female',
+ '1987-07-10',
+ '2021-06-21',
+ '649 Conrad Road',
+ 'Thousand Oaks',
+ 'CT',
+ '97929'),
('Donnell Fry',
- 'Male',
- '1994-07-27',
- '2021-06-24',
- '504 Starr King Canyon',
- 'Norwalk',
- 'OR',
- '46845'),
+ 'Male',
+ '1994-07-27',
+ '2021-06-24',
+ '504 Starr King Canyon',
+ 'Norwalk',
+ 'OR',
+ '46845'),
('Shalanda Peterson',
- 'Female',
- '1999-10-04',
- '2021-08-01',
- '109 Seventh Parkway',
- 'Urbana',
- 'DE',
- '55975')]
+ 'Female',
+ '1999-10-04',
+ '2021-08-01',
+ '109 Seventh Parkway',
+ 'Urbana',
+ 'DE',
+ '55975')
+]
def create_test_data():
+ setup_accounts()
settings = frappe._dict({
'day': datetime.date(int(frappe.defaults.get_defaults().get('fiscal_year')), 1 ,1),
'company': frappe.defaults.get_defaults().get('company'),
@@ -203,14 +206,12 @@ def create_test_data():
{"account_type": "Bank", "company": frappe.defaults.get_defaults().get('company'), "is_group": 0}),
})
create_bank_and_bank_account(settings)
- set_up_accounts(settings)
create_payment_terms_templates(settings)
create_suppliers(settings)
create_items(settings)
create_invoices(settings)
config_expense_claim(settings)
create_employees(settings)
- create_expense_claim(settings)
for month in range(1,13):
create_payroll_journal_entry(settings)
settings.day = settings.day.replace(month=month)
@@ -225,9 +226,25 @@ def create_bank_and_bank_account(settings):
mop.append('accounts', {'company': settings.company, 'default_account': settings.company_account})
mop.save()
- frappe.db.set_value('Mode of Payment', 'Wire Transfer', 'type', 'General')
- frappe.db.set_value('Mode of Payment', 'Credit Card', 'type', 'General')
- frappe.db.set_value('Mode of Payment', 'Bank Draft', 'type', 'General')
+ wire_transfer = frappe.get_doc('Mode of Payment', 'Wire Transfer')
+ wire_transfer.type = 'General'
+ wire_transfer.append('accounts', {'company': settings.company, 'default_account': settings.company_account})
+ wire_transfer.save()
+
+ credit_card = frappe.get_doc('Mode of Payment', 'Credit Card')
+ credit_card.type = 'General'
+ credit_card.append('accounts', {'company': settings.company, 'default_account': settings.company_account})
+ credit_card.save()
+
+ bank_draft = frappe.get_doc('Mode of Payment', 'Bank Draft')
+ bank_draft.type = 'General'
+ bank_draft.append('accounts', {'company': settings.company, 'default_account': settings.company_account})
+ bank_draft.save()
+
+ check_mop = frappe.get_doc('Mode of Payment', 'Check')
+ check_mop.type = 'Bank'
+ check_mop.append('accounts', {'company': settings.company, 'default_account': settings.company_account})
+ check_mop.save()
if not frappe.db.exists('Bank', 'Local Bank'):
bank = frappe.new_doc('Bank')
@@ -260,11 +277,13 @@ def create_bank_and_bank_account(settings):
doc.save()
doc.submit()
-def set_up_accounts(settings):
+def setup_accounts():
frappe.rename_doc('Account', '1000 - Application of Funds (Assets) - CFC', '1000 - Assets - CFC', force=True)
frappe.rename_doc('Account', '2000 - Source of Funds (Liabilities) - CFC', '2000 - Liabilities - CFC', force=True)
frappe.rename_doc('Account', '1310 - Debtors - CFC', '1310 - Accounts Payable - CFC', force=True)
frappe.rename_doc('Account', '2110 - Creditors - CFC', '2110 - Accounts Receivable - CFC', force=True)
+ update_account_number('1110 - Cash - CFC', 'Petty Cash', account_number='1110')
+ update_account_number('Primary Checking - CFC', 'Primary Checking', account_number='1201')
def create_payment_terms_templates(settings):
@@ -296,6 +315,7 @@ def create_payment_terms_templates(settings):
"credit_days": 14})
doc.save()
+
def create_suppliers(settings):
addresses = frappe._dict({})
for supplier in suppliers + tax_authority:
@@ -488,6 +508,7 @@ def config_expense_claim(settings):
pta.parent_account = frappe.get_value('Account', {'account_name': 'Indirect Expenses', 'company': settings.company})
pta.save()
+
def create_employees(settings):
for employee_number, employee in enumerate(employees, start=10):
emp = frappe.new_doc('Employee')
@@ -507,6 +528,7 @@ def create_employees(settings):
emp.bank_account = f'{employee_number}12345'
emp.save()
+
def create_expense_claim(settings):
cost_center = frappe.get_value('Company', settings.company, 'cost_center')
payable_acct = frappe.get_value('Company', settings.company, 'default_payable_account')
@@ -564,6 +586,7 @@ def create_expense_claim(settings):
ec.save()
ec.submit()
+
def create_payroll_journal_entry(settings):
emps = frappe.get_list('Employee', {'company': settings.company})
cost_center = frappe.get_value('Company', settings.company, 'cost_center')