Skip to content

Commit

Permalink
Merge branch 'develop' into payment_entry_total_taxes
Browse files Browse the repository at this point in the history
  • Loading branch information
deepeshgarg007 committed Feb 25, 2022
2 parents b1a46c8 + 25edc70 commit 550b245
Show file tree
Hide file tree
Showing 55 changed files with 905 additions and 354 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt

from erpnext import get_company_currency
Expand Down Expand Up @@ -275,6 +276,10 @@ def check_matching(bank_account, company, transaction, document_types):
}

matching_vouchers = []

matching_vouchers.extend(get_loan_vouchers(bank_account, transaction,
document_types, filters))

for query in subquery:
matching_vouchers.extend(
frappe.db.sql(query, filters,)
Expand Down Expand Up @@ -311,6 +316,114 @@ def get_queries(bank_account, company, transaction, document_types):

return queries

def get_loan_vouchers(bank_account, transaction, document_types, filters):
vouchers = []
amount_condition = True if "exact_match" in document_types else False

if transaction.withdrawal > 0 and "loan_disbursement" in document_types:
vouchers.extend(get_ld_matching_query(bank_account, amount_condition, filters))

if transaction.deposit > 0 and "loan_repayment" in document_types:
vouchers.extend(get_lr_matching_query(bank_account, amount_condition, filters))

return vouchers

def get_ld_matching_query(bank_account, amount_condition, filters):
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
matching_reference = loan_disbursement.reference_number == filters.get("reference_number")
matching_party = loan_disbursement.applicant_type == filters.get("party_type") and \
loan_disbursement.applicant == filters.get("party")

rank = (
frappe.qb.terms.Case()
.when(matching_reference, 1)
.else_(0)
)

rank1 = (
frappe.qb.terms.Case()
.when(matching_party, 1)
.else_(0)
)

query = frappe.qb.from_(loan_disbursement).select(
rank + rank1 + 1,
ConstantColumn("Loan Disbursement").as_("doctype"),
loan_disbursement.name,
loan_disbursement.disbursed_amount,
loan_disbursement.reference_number,
loan_disbursement.reference_date,
loan_disbursement.applicant_type,
loan_disbursement.disbursement_date
).where(
loan_disbursement.docstatus == 1
).where(
loan_disbursement.clearance_date.isnull()
).where(
loan_disbursement.disbursement_account == bank_account
)

if amount_condition:
query.where(
loan_disbursement.disbursed_amount == filters.get('amount')
)
else:
query.where(
loan_disbursement.disbursed_amount <= filters.get('amount')
)

vouchers = query.run(as_list=True)

return vouchers

def get_lr_matching_query(bank_account, amount_condition, filters):
loan_repayment = frappe.qb.DocType("Loan Repayment")
matching_reference = loan_repayment.reference_number == filters.get("reference_number")
matching_party = loan_repayment.applicant_type == filters.get("party_type") and \
loan_repayment.applicant == filters.get("party")

rank = (
frappe.qb.terms.Case()
.when(matching_reference, 1)
.else_(0)
)

rank1 = (
frappe.qb.terms.Case()
.when(matching_party, 1)
.else_(0)
)

query = frappe.qb.from_(loan_repayment).select(
rank + rank1 + 1,
ConstantColumn("Loan Repayment").as_("doctype"),
loan_repayment.name,
loan_repayment.amount_paid,
loan_repayment.reference_number,
loan_repayment.reference_date,
loan_repayment.applicant_type,
loan_repayment.posting_date
).where(
loan_repayment.docstatus == 1
).where(
loan_repayment.clearance_date.isnull()
).where(
loan_repayment.payment_account == bank_account
)

if amount_condition:
query.where(
loan_repayment.amount_paid == filters.get('amount')
)
else:
query.where(
loan_repayment.amount_paid <= filters.get('amount')
)

vouchers = query.run()

return vouchers

def get_pe_matching_query(amount_condition, account_from_to, transaction):
# get matching payment entries query
if transaction.deposit > 0:
Expand Down Expand Up @@ -348,7 +461,6 @@ def get_je_matching_query(amount_condition, transaction):
# We have mapping at the bank level
# So one bank could have both types of bank accounts like asset and liability
# So cr_or_dr should be judged only on basis of withdrawal and deposit and not account type
company_account = frappe.get_value("Bank Account", transaction.bank_account, "account")
cr_or_dr = "credit" if transaction.withdrawal > 0 else "debit"

return f"""
Expand Down
12 changes: 10 additions & 2 deletions erpnext/accounts/doctype/bank_transaction/bank_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def update_allocations(self):

def clear_linked_payment_entries(self, for_cancel=False):
for payment_entry in self.payment_entries:
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim", "Loan Repayment",
"Loan Disbursement"]:
self.clear_simple_entry(payment_entry, for_cancel=for_cancel)

elif payment_entry.payment_document == "Sales Invoice":
Expand Down Expand Up @@ -116,11 +117,18 @@ def get_paid_amount(payment_entry, currency, bank_account):
payment_entry.payment_entry, paid_amount_field)

elif payment_entry.payment_document == "Journal Entry":
return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account}, "sum(credit_in_account_currency)")
return frappe.db.get_value('Journal Entry Account', {'parent': payment_entry.payment_entry, 'account': bank_account},
"sum(credit_in_account_currency)")

elif payment_entry.payment_document == "Expense Claim":
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed")

elif payment_entry.payment_document == "Loan Disbursement":
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "disbursed_amount")

elif payment_entry.payment_document == "Loan Repayment":
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "amount_paid")

else:
frappe.throw("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
frappe.get_doc({
"doctype": "Bank",
"bank_name":bank_name,
}).insert()
}).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass

Expand All @@ -119,7 +119,7 @@ def create_bank_account(bank_name="Citi Bank", account_name="_Test Bank - _TC"):
"account_name":"Checking Account",
"bank": bank_name,
"account": account_name
}).insert()
}).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass

Expand Down Expand Up @@ -184,7 +184,7 @@ def add_vouchers():
"supplier_group":"All Supplier Groups",
"supplier_type": "Company",
"supplier_name": "Conrad Electronic"
}).insert()
}).insert(ignore_if_duplicate=True)

except frappe.DuplicateEntryError:
pass
Expand All @@ -203,7 +203,7 @@ def add_vouchers():
"supplier_group":"All Supplier Groups",
"supplier_type": "Company",
"supplier_name": "Mr G"
}).insert()
}).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass

Expand All @@ -227,7 +227,7 @@ def add_vouchers():
"supplier_group":"All Supplier Groups",
"supplier_type": "Company",
"supplier_name": "Poore Simon's"
}).insert()
}).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass

Expand All @@ -237,7 +237,7 @@ def add_vouchers():
"customer_group":"All Customer Groups",
"customer_type": "Company",
"customer_name": "Poore Simon's"
}).insert()
}).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass

Expand Down Expand Up @@ -266,7 +266,7 @@ def add_vouchers():
"customer_group":"All Customer Groups",
"customer_type": "Company",
"customer_name": "Fayva"
}).insert()
}).insert(ignore_if_duplicate=True)
except frappe.DuplicateEntryError:
pass

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def get_item_dict():
frappe.scrub(row.party_type): row.party,
"is_pos": 0,
"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice",
"update_stock": 0,
"update_stock": 0, # important: https://github.com/frappe/erpnext/pull/23559
"invoice_number": row.invoice_number,
"disable_rounded_total": 1
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt

import unittest

import frappe
from frappe.cache_manager import clear_doctype_cache
from frappe.custom.doctype.property_setter.property_setter import make_property_setter

from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
create_dimension,
Expand All @@ -14,14 +10,17 @@
from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_creation_tool import (
get_temporary_opening_account,
)
from erpnext.tests.utils import ERPNextTestCase

test_dependencies = ["Customer", "Supplier", "Accounting Dimension"]

class TestOpeningInvoiceCreationTool(unittest.TestCase):
def setUp(self):
class TestOpeningInvoiceCreationTool(ERPNextTestCase):
@classmethod
def setUpClass(self):
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
make_company()
create_dimension()
return super().setUpClass()

def make_invoices(self, invoice_type="Sales", company=None, party_1=None, party_2=None, invoice_number=None, department=None):
doc = frappe.get_single("Opening Invoice Creation Tool")
Expand All @@ -31,26 +30,20 @@ def make_invoices(self, invoice_type="Sales", company=None, party_1=None, party_
return doc.make_invoices()

def test_opening_sales_invoice_creation(self):
property_setter = make_property_setter("Sales Invoice", "update_stock", "default", 1, "Check")
try:
invoices = self.make_invoices(company="_Test Opening Invoice Company")

self.assertEqual(len(invoices), 2)
expected_value = {
"keys": ["customer", "outstanding_amount", "status"],
0: ["_Test Customer", 300, "Overdue"],
1: ["_Test Customer 1", 250, "Overdue"],
}
self.check_expected_values(invoices, expected_value)
invoices = self.make_invoices(company="_Test Opening Invoice Company")

si = frappe.get_doc("Sales Invoice", invoices[0])
self.assertEqual(len(invoices), 2)
expected_value = {
"keys": ["customer", "outstanding_amount", "status"],
0: ["_Test Customer", 300, "Overdue"],
1: ["_Test Customer 1", 250, "Overdue"],
}
self.check_expected_values(invoices, expected_value)

# Check if update stock is not enabled
self.assertEqual(si.update_stock, 0)
si = frappe.get_doc("Sales Invoice", invoices[0])

finally:
property_setter.delete()
clear_doctype_cache("Sales Invoice")
# Check if update stock is not enabled
self.assertEqual(si.update_stock, 0)

def check_expected_values(self, invoices, expected_value, invoice_type="Sales"):
doctype = "Sales Invoice" if invoice_type == "Sales" else "Purchase Invoice"
Expand Down
2 changes: 1 addition & 1 deletion erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ def get_outstanding_reference_documents(args):
if d.voucher_type in ("Purchase Invoice"):
d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no")

# Get all SO / PO which are not fully billed or aginst which full advance not paid
# Get all SO / PO which are not fully billed or against which full advance not paid
orders_to_be_billed = []
if (args.get("party_type") != "Student"):
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
Expand Down
1 change: 0 additions & 1 deletion erpnext/accounts/doctype/pos_invoice/pos_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,6 @@ def reset_mode_of_payments(self):
self.paid_amount = 0

def set_account_for_mode_of_payment(self):
self.payments = [d for d in self.payments if d.amount or d.base_amount or d.default]
for pay in self.payments:
if not pay.account:
pay.account = get_bank_cash_account(pay.mode_of_payment, self.company).get("account")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def valdiate_taxes_and_charges_template(doc):

for tax in doc.get("taxes"):
validate_taxes_and_charges(tax)
validate_account_head(tax, doc)
validate_account_head(tax.idx, tax.account_head, doc.company)
validate_cost_center(tax, doc)
validate_inclusive_tax(tax, doc)

Expand Down
5 changes: 4 additions & 1 deletion erpnext/accounts/party.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def validate_party_gle_currency(party_type, party, company, party_account_curren
.format(frappe.bold(party_type), frappe.bold(party), frappe.bold(existing_gle_currency), frappe.bold(company)), InvalidAccountCurrency)

def validate_party_accounts(doc):

from erpnext.controllers.accounts_controller import validate_account_head
companies = []

for account in doc.get("accounts"):
Expand All @@ -330,6 +330,9 @@ def validate_party_accounts(doc):
if doc.default_currency != party_account_currency and doc.default_currency != company_default_currency:
frappe.throw(_("Billing currency must be equal to either default company's currency or party account currency"))

# validate if account is mapped for same company
validate_account_head(account.idx, account.account, account.company)


@frappe.whitelist()
def get_due_date(posting_date, party_type, party, company=None, bill_date=None):
Expand Down

0 comments on commit 550b245

Please sign in to comment.