def reconcile(self): """ Links booking and payment voucher 1. cancel payment voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit payment voucher """ if not self.voucher_no or not frappe.db.sql( """select name from `tab%s` where name = %s""" % (self.voucher_type, '%s'), self.voucher_no): frappe.throw(_("Please select valid Voucher No to proceed")) lst = [] for d in self.get('ir_payment_details'): if flt(d.amt_to_be_reconciled) > 0: args = { 'voucher_no': d.voucher_no, 'voucher_detail_no': d.voucher_detail_no, 'against_voucher_type': self.voucher_type, 'against_voucher': self.voucher_no, 'account': self.account, 'is_advance': 'No', # 'dr_or_cr' : self.account_type=='debit' and 'credit' or 'debit', 'unadjusted_amt': flt(d.amt_due), 'allocated_amt': flt(d.amt_to_be_reconciled) } lst.append(args) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) msgprint(_("Successfully allocated")) else: msgprint(_("No amount allocated"), raise_exception=1)
def reconcile(self): self.validate_allocation() dr_or_cr = ("credit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency") entry_list = [] dr_or_cr_notes = [] for row in self.get('allocation'): reconciled_entry = [] if row.invoice_number and row.allocated_amount: if row.reference_type in ['Sales Invoice', 'Purchase Invoice']: reconciled_entry = dr_or_cr_notes else: reconciled_entry = entry_list reconciled_entry.append(self.get_payment_details( row, dr_or_cr)) if entry_list: reconcile_against_document(entry_list) if dr_or_cr_notes: reconcile_dr_cr_note(dr_or_cr_notes, self.company) msgprint(_("Successfully Reconciled")) self.get_unreconciled_entries()
def update_payment_entry(self, payment): lst = [] invoices = payment.invoices.strip().split(',') if (len(invoices) == 0): return amount = float(abs(payment.amount)) for invoice_entry in invoices: if (not invoice_entry.strip()): continue invs = invoice_entry.split('|') invoice_type, invoice = invs[0], invs[1] outstanding_amount = frappe.get_value(invoice_type, invoice, 'outstanding_amount') lst.append(frappe._dict({ 'voucher_type': payment.reference_type, 'voucher_no' : payment.reference_name, 'against_voucher_type' : invoice_type, 'against_voucher' : invoice, 'account' : payment.account, 'party_type': payment.party_type, 'party': frappe.get_value("Payment Entry", payment.reference_name, "party"), 'unadjusted_amount' : float(amount), 'allocated_amount' : min(outstanding_amount, amount) })) amount -= outstanding_amount if lst: from erpnext.accounts.utils import reconcile_against_document try: reconcile_against_document(lst) except: frappe.throw(_("Exception occurred while reconciling {0}".format(payment.reference_name)))
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ if self.doctype == "Sales Invoice": party_type = "Customer" party = self.customer party_account = self.debit_to dr_or_cr = "credit_in_account_currency" elif self.doctype == "Purchase Invoice": party_type = "Letter of Credit" if self.letter_of_credit else "Supplier" party = self.letter_of_credit if self.letter_of_credit else self.supplier party_account = self.credit_to dr_or_cr = "debit_in_account_currency" else: party_type = self.party_type party = self.party party_account = self.credit_to dr_or_cr = "debit_in_account_currency" if self.doctype in ["Sales Invoice", "Purchase Invoice"]: invoice_amounts = { 'exchange_rate': (self.conversion_rate if self.party_account_currency != self.company_currency else 1), 'grand_total': (self.base_grand_total if self.party_account_currency == self.company_currency else self.grand_total) } else: invoice_amounts = { 'exchange_rate': 1, 'grand_total': self.grand_total } lst = [] for d in self.get('advances'): if flt(d.allocated_amount) > 0: args = frappe._dict({ 'voucher_type': d.reference_type, 'voucher_no': d.reference_name, 'voucher_detail_no': d.reference_row, 'against_voucher_type': self.doctype, 'against_voucher': self.name, 'account': party_account, 'party_type': party_type, 'party': party, 'dr_or_cr': dr_or_cr, 'unadjusted_amount': flt(d.advance_amount), 'allocated_amount': flt(d.allocated_amount), 'outstanding_amount': self.outstanding_amount }) args.update(invoice_amounts) lst.append(args) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst)
def reconcile(self): for e in self.get('payments'): e.invoice_type = None if e.invoice_number and " | " in e.invoice_number: e.invoice_type, e.invoice_number = e.invoice_number.split(" | ") self.get_invoice_entries() self.validate_invoice() dr_or_cr = ("credit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency") lst = [] for e in self.get('payments'): if e.invoice_number and e.allocated_amount: lst.append(frappe._dict({ 'voucher_type': e.reference_type, 'voucher_no' : e.reference_name, 'voucher_detail_no' : e.reference_row, 'against_voucher_type' : e.invoice_type, 'against_voucher' : e.invoice_number, 'account' : self.receivable_payable_account, 'party_type': self.party_type, 'party': self.party, 'dr_or_cr' : dr_or_cr, 'unadjusted_amount' : flt(e.amount), 'allocated_amount' : flt(e.allocated_amount) })) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) msgprint(_("Successfully Reconciled")) self.get_unreconciled_entries()
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ lst = [] for d in self.get('advances'): if flt(d.allocated_amount) > 0: args = { 'voucher_no' : d.journal_entry, 'voucher_detail_no' : d.jv_detail_no, 'against_voucher_type' : 'Purchase Invoice', 'against_voucher' : self.name, 'account' : self.credit_to, 'party_type': 'Supplier', 'party': self.supplier, 'is_advance' : 'Yes', 'dr_or_cr' : 'debit', 'unadjusted_amt' : flt(d.advance_amount), 'allocated_amt' : flt(d.allocated_amount) } lst.append(args) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst)
def reconcile(self, args): self.get_invoice_entries() self.validate_invoice() dr_or_cr = "credit" if self.party_type == "Customer" else "debit" lst = [] for e in self.get('payments'): if e.invoice_type and e.invoice_number and e.allocated_amount: lst.append({ 'voucher_no' : e.journal_entry, 'voucher_detail_no' : e.voucher_detail_number, 'against_voucher_type' : e.invoice_type, 'against_voucher' : e.invoice_number, 'account' : self.receivable_payable_account, 'party_type': self.party_type, 'party': self.party, 'is_advance' : e.is_advance, 'dr_or_cr' : dr_or_cr, 'unadjusted_amt' : flt(e.amount), 'allocated_amt' : flt(e.allocated_amount) }) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) msgprint(_("Successfully Reconciled")) self.get_unreconciled_entries()
def update_payment_entry(self, payment): lst = [] invoices = payment.invoices.strip().split(',') if (len(invoices) == 0): return amount = float(abs(payment.amount)) for invoice_entry in invoices: if (not invoice_entry.strip()): continue invs = invoice_entry.split('|') invoice_type, invoice = invs[0], invs[1] outstanding_amount = frappe.get_value(invoice_type, invoice, 'outstanding_amount') lst.append(frappe._dict({ 'voucher_type': payment.reference_type, 'voucher_no' : payment.reference_name, 'against_voucher_type' : invoice_type, 'against_voucher' : invoice, 'account' : payment.account, 'party_type': payment.party_type, 'party': frappe.get_value("Payment Entry", payment.reference_name, "party"), 'unadjusted_amount' : float(amount), 'allocated_amount' : min(outstanding_amount, amount) })) amount -= outstanding_amount if lst: from erpnext.accounts.utils import reconcile_against_document try: reconcile_against_document(lst) except: frappe.throw("Exception occurred while reconciling {0}".format(payment.reference_name))
def reconcile(self, args): for e in self.get('payments'): e.invoice_type = None if e.invoice_number and " | " in e.invoice_number: e.invoice_type, e.invoice_number = e.invoice_number.split(" | ") self.get_invoice_entries() self.validate_invoice() dr_or_cr = ("credit_in_account_currency" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency") lst = [] dr_or_cr_notes = [] for e in self.get('payments'): reconciled_entry = [] if e.invoice_number and e.allocated_amount: if e.reference_type in ['Sales Invoice', 'Purchase Invoice']: reconciled_entry = dr_or_cr_notes else: reconciled_entry = lst reconciled_entry.append(self.get_payment_details(e, dr_or_cr)) if lst: reconcile_against_document(lst) if dr_or_cr_notes: reconcile_dr_cr_note(dr_or_cr_notes, self.company) msgprint(_("Successfully Reconciled")) self.get_unreconciled_entries()
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ lst = [] for d in self.get('advances'): if flt(d.allocated_amount) > 0: args = { 'voucher_no' : d.journal_entry, 'voucher_detail_no' : d.jv_detail_no, 'against_voucher_type' : 'Purchase Invoice', 'against_voucher' : self.name, 'account' : self.credit_to, 'party_type': 'Supplier', 'party': self.supplier, 'is_advance' : 'Yes', 'dr_or_cr' : 'debit_in_account_currency', 'unadjusted_amt' : flt(d.advance_amount), 'allocated_amt' : flt(d.allocated_amount) } lst.append(args) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst)
def reconcile(self, args): self.get_invoice_entries() self.validate_invoice() dr_or_cr = "credit" if self.party_type == "Customer" else "debit" lst = [] for e in self.get("payments"): if e.invoice_type and e.invoice_number and e.allocated_amount: lst.append( { "voucher_no": e.journal_entry, "voucher_detail_no": e.voucher_detail_number, "against_voucher_type": e.invoice_type, "against_voucher": e.invoice_number, "account": self.receivable_payable_account, "party_type": self.party_type, "party": self.party, "is_advance": e.is_advance, "dr_or_cr": dr_or_cr, "unadjusted_amt": flt(e.amount), "allocated_amt": flt(e.allocated_amount), } ) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) msgprint(_("Successfully Reconciled")) self.get_unreconciled_entries()
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ lst = [] for d in self.get("advances"): if flt(d.allocated_amount) > 0: args = { "voucher_no": d.journal_entry, "voucher_detail_no": d.jv_detail_no, "against_voucher_type": "Sales Invoice", "against_voucher": self.name, "account": self.debit_to, "party_type": "Customer", "party": self.customer, "is_advance": "Yes", "dr_or_cr": "credit_in_account_currency", "unadjusted_amt": flt(d.advance_amount), "allocated_amt": flt(d.allocated_amount), } lst.append(args) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst)
def reconcile(self, args): for e in self.get('payments'): e.invoice_type = None if e.invoice_number and " | " in e.invoice_number: e.invoice_type, e.invoice_number = e.invoice_number.split(" | ") self.get_invoice_entries() self.validate_invoice() dr_or_cr = "credit_in_account_currency" \ if self.party_type == "Customer" else "debit_in_account_currency" lst = [] for e in self.get('payments'): if e.invoice_number and e.allocated_amount: lst.append(frappe._dict({ 'voucher_type': e.reference_type, 'voucher_no' : e.reference_name, 'voucher_detail_no' : e.reference_row, 'against_voucher_type' : e.invoice_type, 'against_voucher' : e.invoice_number, 'account' : self.receivable_payable_account, 'party_type': self.party_type, 'party': self.party, 'is_advance' : e.is_advance, 'dr_or_cr' : dr_or_cr, 'unadjusted_amount' : flt(e.amount), 'allocated_amount' : flt(e.allocated_amount) })) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) msgprint(_("Successfully Reconciled")) self.get_unreconciled_entries()
def reconcile(self): self.validate_mandatory() self.validate_allocated_amount() dr_or_cr = "credit" if self.total_amount > 0 else "debit" lst = [] for d in self.get('against_entries'): if flt(d.allocated_amount) > 0: lst.append({ 'voucher_no' : d.voucher_no, 'voucher_detail_no' : d.voucher_detail_no, 'against_voucher_type' : self.voucher_type, 'against_voucher' : self.voucher_no, 'account' : self.account, 'is_advance' : d.is_advance, 'dr_or_cr' : dr_or_cr, 'unadjusted_amt' : flt(d.original_amount), 'allocated_amt' : flt(d.allocated_amount) }) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) self.get_voucher_details() self.get_against_entries() msgprint(_("Successfully allocated"))
def update_against_document_in_jv(self): """ Links invoice and advance voucher: 1. cancel advance voucher 2. split into multiple rows if partially adjusted, assign against voucher 3. submit advance voucher """ if self.doctype == "Sales Invoice": party_type = "Customer" party = self.customer party_account = self.debit_to dr_or_cr = "credit_in_account_currency" else: party_type = "Supplier" party = self.supplier party_account = self.credit_to dr_or_cr = "debit_in_account_currency" lst = [] for d in self.get("advances"): if flt(d.allocated_amount) > 0: args = frappe._dict( { "voucher_type": d.reference_type, "voucher_no": d.reference_name, "voucher_detail_no": d.reference_row, "against_voucher_type": self.doctype, "against_voucher": self.name, "account": party_account, "party_type": party_type, "party": party, "is_advance": "Yes", "dr_or_cr": dr_or_cr, "unadjusted_amount": flt(d.advance_amount), "allocated_amount": flt(d.allocated_amount), "exchange_rate": ( self.conversion_rate if self.party_account_currency != self.company_currency else 1 ), "grand_total": ( self.base_grand_total if self.party_account_currency == self.company_currency else self.grand_total ), "outstanding_amount": self.outstanding_amount, } ) lst.append(args) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst)
def adjust_je_against_dn(payments): """ Adjust Journal Entries against Debit Note """ try: for pi, value in payments.iteritems(): if len(value['vendor_credit']) == 1: for dn in value['vendor_credit']: lst = [] quickbooks_journal_entry_id = dn.get('vendor_credit_id') args = get_jv_voucher_detail_no( quickbooks_journal_entry_id) pi_name = frappe.db.get_value( "Purchase Invoice", { "quickbooks_purchase_invoice_id": value.get('qb_pi_id'), "outstanding_amount": ['!=', 0] }, "name") if args.get('voucher_detail_no') and args.get( 'unadjusted_amount') and pi_name: invoice = frappe.get_doc("Purchase Invoice", pi_name) lst.append( frappe._dict( reconcile_entry( args, "Purchase Invoice", pi_name, invoice, paid_amt=value.get('paid_amount')))) if lst: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst) frappe.db.commit() elif len(value['vendor_credit']) > 1: for dn in value['vendor_credit']: lst1 = [] quickbooks_journal_entry_id = dn.get('vendor_credit_id') args = get_jv_voucher_detail_no( quickbooks_journal_entry_id) pi_name = frappe.db.get_value( "Purchase Invoice", { "quickbooks_purchase_invoice_id": value.get('qb_pi_id'), "outstanding_amount": ['!=', 0] }, "name") if args.get('voucher_detail_no') and args.get( 'unadjusted_amount') and pi_name: invoice = frappe.get_doc("Purchase Invoice", pi_name) lst1.append( frappe._dict( reconcile_entry( args, "Purchase Invoice", pi_name, invoice, paid_amt=dn.get('paid_amount')))) if lst1: from erpnext.accounts.utils import reconcile_against_document reconcile_against_document(lst1) frappe.db.commit() except Exception, e: make_quickbooks_log(title=e.message, status="Error", method="adjust_je_against_dn", message=frappe.get_traceback(), request_data=payments, exception=True)
def test_reconcile_advance_journal_entries(self): self.assertFalse( get_advance_journal_entries(self.customer.doctype, self.customer.name, "_Test Receivable - _TC", "Sales Order", against_all_orders=True)) # Test records jv_simple = make_payment_jv(self.customer, 100) jv_multiple_rows = make_payment_jv(self.customer, 300, unallocated_rows=3) jv_half_returned = make_payment_jv(self.customer, 200) _jv_return = make_payment_jv(self.customer, 0, jv_half_returned.doctype, jv_half_returned.name, -100) _jv_receivable = make_payment_jv(self.customer, -100) jv_half_allocated = make_payment_jv(self.customer, 100, _jv_receivable.doctype, _jv_receivable.name, 100) so = make_sales_order(self.customer) jv_against_so = make_payment_jv(self.customer, 100, so.doctype, so.name, 100) # Test get_advance_journal_entries advances = get_advance_journal_entries(self.customer.doctype, self.customer.name, "_Test Receivable - _TC", "Sales Order", against_all_orders=True) advance_vouchers = {} for d in advances: advance_vouchers.setdefault(d.reference_name, []) advance_vouchers[d.reference_name].append(d) self.assertEqual(len(advance_vouchers[jv_simple.name]), 1) self.assertEqual(advance_vouchers[jv_simple.name][0].amount, 100) self.assertEqual(len(advance_vouchers[jv_multiple_rows.name]), 1) self.assertEqual(advance_vouchers[jv_multiple_rows.name][0].amount, 300) self.assertEqual(len(advance_vouchers[jv_half_returned.name]), 1) self.assertEqual(advance_vouchers[jv_half_returned.name][0].amount, 100) self.assertEqual(len(advance_vouchers[jv_half_allocated.name]), 1) self.assertEqual(advance_vouchers[jv_half_allocated.name][0].amount, 100) self.assertEqual(len(advance_vouchers[jv_against_so.name]), 2) self.assertEqual(advance_vouchers[jv_against_so.name][0].amount, 100) self.assertEqual(advance_vouchers[jv_against_so.name][0].reference_row, jv_against_so.accounts[2].name) self.assertEqual(advance_vouchers[jv_against_so.name][1].amount, 100) # Test reconcile_against_document jv_receivable = make_payment_jv(self.customer, -5000) # Full allocation lst = [ frappe._dict({ 'voucher_type': jv_simple.doctype, 'voucher_no': jv_simple.name, 'voucher_detail_no': None, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 100, 'allocated_amount': 100 }) ] reconcile_against_document(lst) self.assertEqual( get_balance_on_voucher(jv_receivable.doctype, jv_receivable.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 4900) self.assertTrue( frappe.db.sql( """select name from `tabJournal Entry Account` where name=%s and reference_name=%s and credit_in_account_currency=%s and docstatus=1 """, [jv_simple.accounts[1].name, jv_receivable.name, 100])) # Multiple row partial allocation lst = [ frappe._dict({ 'voucher_type': jv_multiple_rows.doctype, 'voucher_no': jv_multiple_rows.name, 'voucher_detail_no': None, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 300, 'allocated_amount': 230 }) ] reconcile_against_document(lst) self.assertEqual( get_balance_on_voucher(jv_receivable.doctype, jv_receivable.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 4670) self.assertTrue( frappe.db.sql( """select count(*) from `tabJournal Entry Account` where parent=%s and reference_name=%s and party_type='Customer' and party=%s and account='_Test Receivable - _TC' and credit_in_account_currency=%s and docstatus=1 having count(*) = 2 """, [jv_multiple_rows.name, jv_receivable.name, self.customer.name, 100])) self.assertTrue( frappe.db.sql( """select name from `tabJournal Entry Account` where parent=%s and reference_name=%s and party_type='Customer' and party=%s and account='_Test Receivable - _TC' and credit_in_account_currency=%s and docstatus=1 """, [jv_multiple_rows.name, jv_receivable.name, self.customer.name, 30])) self.assertTrue( frappe.db.sql( """select name from `tabJournal Entry Account` where parent=%s and party_type='Customer' and party=%s and ifnull(reference_name, '') = '' and account='_Test Receivable - _TC' and credit_in_account_currency=%s and docstatus=1 """, [jv_multiple_rows.name, self.customer.name, 70])) # Attempt to over allocate a partially returned/knocked-off jv lst = [ frappe._dict({ 'voucher_type': jv_half_returned.doctype, 'voucher_no': jv_half_returned.name, 'voucher_detail_no': None, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 200, 'allocated_amount': 200 }) ] self.assertRaises(frappe.ValidationError, reconcile_against_document, lst) # Attempt to over allocate a partially allocated jv lst = [ frappe._dict({ 'voucher_type': jv_half_allocated.doctype, 'voucher_no': jv_half_allocated.name, 'voucher_detail_no': None, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 200, 'allocated_amount': 200 }) ] self.assertRaises(frappe.ValidationError, reconcile_against_document, lst) # Sales Order advance reallocation lst = [ frappe._dict({ 'voucher_type': jv_against_so.doctype, 'voucher_no': jv_against_so.name, 'voucher_detail_no': jv_against_so.accounts[2].name, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 100, 'allocated_amount': 100 }) ] reconcile_against_document(lst) self.assertEqual( get_balance_on_voucher(jv_receivable.doctype, jv_receivable.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 4570) self.assertEqual( get_balance_on_voucher(so.doctype, so.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 0) self.assertEqual( frappe.db.get_value("Sales Order", so.name, "advance_paid"), 0) self.assertTrue( frappe.db.sql( """select name from `tabJournal Entry Account` where name=%s and reference_name=%s and credit_in_account_currency=%s and docstatus=1 """, [jv_against_so.accounts[2].name, jv_receivable.name, 100])) # Test get_advance_payment_entries after reconciliation advances = get_advance_journal_entries(self.customer.doctype, self.customer.name, "_Test Receivable - _TC", "Sales Order", against_all_orders=True) advance_vouchers = {} for d in advances: advance_vouchers.setdefault(d.reference_name, []) advance_vouchers[d.reference_name].append(d) self.assertFalse(advance_vouchers.get(jv_simple.name)) self.assertEqual(len(advance_vouchers[jv_multiple_rows.name]), 1) self.assertEqual(advance_vouchers[jv_multiple_rows.name][0].amount, 70) self.assertEqual(len(advance_vouchers[jv_against_so.name]), 1) self.assertEqual(advance_vouchers[jv_against_so.name][0].amount, 100)
def test_reconcile_advance_payment_entries(self): self.assertFalse( get_advance_payment_entries(self.customer.doctype, self.customer.name, "_Test Receivable - _TC", "Sales Order", against_all_orders=True)) # Test records _jv_receivable = make_payment_jv(self.customer, -100) so = make_sales_order(self.customer) pe_against_so = make_payment_entry(self.customer, 100, so.doctype, so.name, 100) pe_unallocated = make_payment_entry(self.customer, 100) pe_half_allocated = make_payment_entry(self.customer, 100, _jv_receivable.doctype, _jv_receivable.name, 100) # Test get_advance_payment_entries advances = get_advance_payment_entries(self.customer.doctype, self.customer.name, "_Test Receivable - _TC", "Sales Order", against_all_orders=True) advance_vouchers = {} for d in advances: advance_vouchers.setdefault(d.reference_name, []) advance_vouchers[d.reference_name].append(d) self.assertEqual(len(advance_vouchers[pe_against_so.name]), 2) self.assertEqual(advance_vouchers[pe_against_so.name][0].reference_row, pe_against_so.references[0].name) self.assertEqual(advance_vouchers[pe_against_so.name][0].amount, 100) self.assertEqual(advance_vouchers[pe_against_so.name][1].amount, 100) self.assertEqual(len(advance_vouchers[pe_unallocated.name]), 1) self.assertEqual(advance_vouchers[pe_unallocated.name][0].amount, 100) self.assertEqual(len(advance_vouchers[pe_half_allocated.name]), 1) self.assertEqual(advance_vouchers[pe_half_allocated.name][0].amount, 100) # Test reconcile_against_document jv_receivable = make_payment_jv(self.customer, -5000) # Full allocation lst = [ frappe._dict({ 'voucher_type': pe_unallocated.doctype, 'voucher_no': pe_unallocated.name, 'voucher_detail_no': None, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 100, 'allocated_amount': 100 }) ] reconcile_against_document(lst) self.assertEqual( get_balance_on_voucher(jv_receivable.doctype, jv_receivable.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 4900) self.assertTrue( frappe.db.sql( """select name from `tabPayment Entry Reference` where parent=%s and reference_name=%s and allocated_amount=%s and docstatus=1 """, [pe_unallocated.name, jv_receivable.name, 100])) self.assertEqual( frappe.get_value("Payment Entry", pe_unallocated.name, "unallocated_amount"), 0) # Attempt to over allocate a partially allocated pe lst = [ frappe._dict({ 'voucher_type': pe_half_allocated.doctype, 'voucher_no': pe_half_allocated.name, 'voucher_detail_no': None, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 200, 'allocated_amount': 200 }) ] self.assertRaises(frappe.ValidationError, reconcile_against_document, lst) # Sales Order advance reallocation lst = [ frappe._dict({ 'voucher_type': pe_against_so.doctype, 'voucher_no': pe_against_so.name, 'voucher_detail_no': pe_against_so.references[0].name, 'against_voucher_type': jv_receivable.doctype, 'against_voucher': jv_receivable.name, 'account': "_Test Receivable - _TC", 'party_type': "Customer", 'party': self.customer.name, 'dr_or_cr': "credit_in_account_currency", 'unadjusted_amount': 100, 'allocated_amount': 100 }) ] reconcile_against_document(lst) self.assertEqual( get_balance_on_voucher(jv_receivable.doctype, jv_receivable.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 4800) self.assertEqual( get_balance_on_voucher(so.doctype, so.name, "Customer", self.customer.name, "_Test Receivable - _TC"), 0) self.assertEqual( frappe.db.get_value("Sales Order", so.name, "advance_paid"), 0) self.assertTrue( frappe.db.sql( """select name from `tabPayment Entry Reference` where parent=%s and reference_name=%s and allocated_amount=%s and docstatus=1 """, [pe_unallocated.name, jv_receivable.name, 100])) self.assertEqual( frappe.get_value("Payment Entry", pe_against_so.name, "unallocated_amount"), 100) # Test get_advance_payment_entries after reconciliation advances = get_advance_payment_entries(self.customer.doctype, self.customer.name, "_Test Receivable - _TC", "Sales Order", against_all_orders=True) advance_vouchers = {} for d in advances: advance_vouchers.setdefault(d.reference_name, []) advance_vouchers[d.reference_name].append(d) self.assertFalse(advance_vouchers.get(pe_unallocated.name)) self.assertEqual(len(advance_vouchers[pe_against_so.name]), 1) self.assertEqual(advance_vouchers[pe_against_so.name][0].amount, 100)