Skip to content

Commit

Permalink
Merge pull request #44209 from frappe/version-15-hotfix
Browse files Browse the repository at this point in the history
chore: release v15
  • Loading branch information
ruthra-kumar authored Nov 20, 2024
2 parents 7c78e00 + d0e2b7c commit 9b690e9
Show file tree
Hide file tree
Showing 61 changed files with 1,784 additions and 212 deletions.
4 changes: 2 additions & 2 deletions erpnext/accounts/doctype/account/account.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
"label": "Account Type",
"oldfieldname": "account_type",
"oldfieldtype": "Select",
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nCurrent Asset\nCurrent Liability\nDepreciation\nDirect Expense\nDirect Income\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nIndirect Expense\nIndirect Income\nLiability\nPayable\nReceivable\nRound Off\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
"options": "\nAccumulated Depreciation\nAsset Received But Not Billed\nBank\nCash\nChargeable\nCapital Work in Progress\nCost of Goods Sold\nCurrent Asset\nCurrent Liability\nDepreciation\nDirect Expense\nDirect Income\nEquity\nExpense Account\nExpenses Included In Asset Valuation\nExpenses Included In Valuation\nFixed Asset\nIncome Account\nIndirect Expense\nIndirect Income\nLiability\nPayable\nReceivable\nRound Off\nRound Off for Opening\nStock\nStock Adjustment\nStock Received But Not Billed\nService Received But Not Billed\nTax\nTemporary",
"search_index": 1
},
{
Expand Down Expand Up @@ -191,7 +191,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2024-06-27 16:23:04.444354",
"modified": "2024-08-19 15:19:11.095045",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Account",
Expand Down
1 change: 1 addition & 0 deletions erpnext/accounts/doctype/account/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Account(NestedSet):
"Payable",
"Receivable",
"Round Off",
"Round Off for Opening",
"Stock",
"Stock Adjustment",
"Stock Received But Not Billed",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@ def validate_mandatory(self):
if not (self.company and self.posting_date):
frappe.throw(_("Please select Company and Posting Date to getting entries"))

def before_submit(self):
self.remove_accounts_without_gain_loss()

def remove_accounts_without_gain_loss(self):
self.accounts = [account for account in self.accounts if account.gain_loss]

if not self.accounts:
frappe.throw(_("At least one account with exchange gain or loss is required"))

frappe.msgprint(
_("Removing rows without exchange gain or loss"),
alert=True,
indicator="yellow",
)

def on_cancel(self):
self.ignore_linked_doctypes = "GL Entry"

Expand Down Expand Up @@ -248,23 +263,23 @@ def calculate_new_account_balance(company, posting_date, account_details):
new_exchange_rate = get_exchange_rate(d.account_currency, company_currency, posting_date)
new_balance_in_base_currency = flt(d.balance_in_account_currency * new_exchange_rate)
gain_loss = flt(new_balance_in_base_currency, precision) - flt(d.balance, precision)
if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": d.balance_in_account_currency,
"gain_loss": gain_loss,
}
)

accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": d.balance_in_account_currency,
"gain_loss": gain_loss,
}
)

# Handle Accounts with '0' balance in Account/Base Currency
for d in [x for x in account_details if x.zero_balance]:
Expand All @@ -288,23 +303,22 @@ def calculate_new_account_balance(company, posting_date, account_details):
current_exchange_rate * d.balance_in_account_currency
)

if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": new_balance_in_account_currency,
"gain_loss": gain_loss,
}
)
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": new_balance_in_account_currency,
"gain_loss": gain_loss,
}
)

return accounts

Expand Down
4 changes: 2 additions & 2 deletions erpnext/accounts/doctype/fiscal_year/fiscal_year.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@
},
{
"default": "0",
"description": "Less than 12 months.",
"description": "More/Less than 12 months.",
"fieldname": "is_short_year",
"fieldtype": "Check",
"label": "Is Short Year",
"label": "Is Short/Long Year",
"set_only_once": 1
}
],
Expand Down
19 changes: 19 additions & 0 deletions erpnext/accounts/doctype/payment_entry/payment_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ frappe.ui.form.on("Payment Entry", {
}

erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);

if (frm.is_new()) {
set_default_party_type(frm);
}
},

setup: function (frm) {
Expand Down Expand Up @@ -403,6 +407,8 @@ frappe.ui.form.on("Payment Entry", {
},

payment_type: function (frm) {
set_default_party_type(frm);

if (frm.doc.payment_type == "Internal Transfer") {
$.each(
[
Expand Down Expand Up @@ -1776,3 +1782,16 @@ frappe.ui.form.on("Payment Entry Deduction", {
frm.events.set_unallocated_amount(frm);
},
});

function set_default_party_type(frm) {
if (frm.doc.party) return;

let party_type;
if (frm.doc.payment_type == "Receive") {
party_type = "Customer";
} else if (frm.doc.payment_type == "Pay") {
party_type = "Supplier";
}

if (party_type) frm.set_value("party_type", party_type);
}
25 changes: 20 additions & 5 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,12 @@ def build_gl_map(self):
if self.payment_type in ("Receive", "Pay") and not self.get("party_account_field"):
self.setup_party_account_field()

company_currency = erpnext.get_company_currency(self.company)
if self.paid_from_account_currency != company_currency:
self.currency = self.paid_from_account_currency
elif self.paid_to_account_currency != company_currency:
self.currency = self.paid_to_account_currency

gl_entries = []
self.add_party_gl_entries(gl_entries)
self.add_bank_gl_entries(gl_entries)
Expand Down Expand Up @@ -1248,13 +1254,22 @@ def add_party_gl_entries(self, gl_entries):
base_unallocated_amount = self.unallocated_amount * exchange_rate

gle = party_gl_dict.copy()

gle.update(
{
dr_or_cr + "_in_account_currency": self.unallocated_amount,
dr_or_cr: base_unallocated_amount,
}
self.get_gl_dict(
{
"account": self.party_account,
"party_type": self.party_type,
"party": self.party,
"against": against_account,
"account_currency": self.party_account_currency,
"cost_center": self.cost_center,
dr_or_cr + "_in_account_currency": self.unallocated_amount,
dr_or_cr: base_unallocated_amount,
},
item=self,
)
)

if self.book_advance_payments_in_separate_party_account:
gle.update(
{
Expand Down
47 changes: 47 additions & 0 deletions erpnext/accounts/doctype/payment_entry/test_payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,53 @@ def test_payment_entry_account_and_party_balance_with_cost_center(self):
self.assertEqual(flt(expected_party_balance), party_balance)
self.assertEqual(flt(expected_party_account_balance, 2), flt(party_account_balance, 2))

def test_gl_of_multi_currency_payment_transaction(self):
from erpnext.setup.doctype.currency_exchange.test_currency_exchange import (
save_new_records,
test_records,
)

save_new_records(test_records)
paid_from = create_account(
parent_account="Current Liabilities - _TC",
account_name="_Test Cash USD",
company="_Test Company",
account_type="Cash",
account_currency="USD",
)
payment_entry = create_payment_entry(
party="_Test Supplier USD",
paid_from=paid_from,
paid_to="_Test Payable USD - _TC",
paid_amount=100,
save=True,
)
payment_entry.source_exchange_rate = 84.4
payment_entry.target_exchange_rate = 84.4
payment_entry.save()
payment_entry = payment_entry.submit()
gle = qb.DocType("GL Entry")
gl_entries = (
qb.from_(gle)
.select(
gle.account,
gle.debit,
gle.credit,
gle.debit_in_account_currency,
gle.credit_in_account_currency,
gle.debit_in_transaction_currency,
gle.credit_in_transaction_currency,
)
.orderby(gle.account)
.where(gle.voucher_no == payment_entry.name)
.run()
)
expected_gl_entries = (
(paid_from, 0.0, 8440.0, 0.0, 100.0, 0.0, 100.0),
("_Test Payable USD - _TC", 8440.0, 0.0, 100.0, 0.0, 100.0, 0.0),
)
self.assertEqual(gl_entries, expected_gl_entries)

def test_multi_currency_payment_entry_with_taxes(self):
payment_entry = create_payment_entry(
party="_Test Supplier USD", paid_to="_Test Payable USD - _TC", save=True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,14 @@ def get_jv_entries(self):
if self.get("cost_center"):
conditions.append(jea.cost_center == self.cost_center)

dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
else "debit_in_account_currency"
)
conditions.append(jea[dr_or_cr].gt(0))
account_type = erpnext.get_party_account_type(self.party_type)

if account_type == "Receivable":
dr_or_cr = jea.credit_in_account_currency - jea.debit_in_account_currency
elif account_type == "Payable":
dr_or_cr = jea.debit_in_account_currency - jea.credit_in_account_currency

conditions.append(dr_or_cr.gt(0))

if self.bank_cash_account:
conditions.append(jea.against_account.like(f"%%{self.bank_cash_account}%%"))
Expand All @@ -231,7 +233,7 @@ def get_jv_entries(self):
je.posting_date,
je.remark.as_("remarks"),
jea.name.as_("reference_row"),
jea[dr_or_cr].as_("amount"),
dr_or_cr.as_("amount"),
jea.is_advance,
jea.exchange_rate,
jea.account_currency.as_("currency"),
Expand Down Expand Up @@ -371,6 +373,10 @@ def get_invoice_entries(self):
if self.invoice_limit:
non_reconciled_invoices = non_reconciled_invoices[: self.invoice_limit]

non_reconciled_invoices = sorted(
non_reconciled_invoices, key=lambda k: k["posting_date"] or getdate(nowdate())
)

self.add_invoice_entries(non_reconciled_invoices)

def add_invoice_entries(self, non_reconciled_invoices):
Expand Down
Loading

0 comments on commit 9b690e9

Please sign in to comment.