Skip to content

Commit

Permalink
Merge pull request #36961 from frappe/develop
Browse files Browse the repository at this point in the history
chore: release v15 beta
  • Loading branch information
ankush authored Sep 5, 2023
2 parents 1ac5656 + d2f03c8 commit acbc12d
Show file tree
Hide file tree
Showing 92 changed files with 4,032 additions and 1,042 deletions.
9 changes: 5 additions & 4 deletions erpnext/accounts/doctype/bank_transaction/bank_transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ frappe.ui.form.on("Bank Transaction", {
});
},
refresh(frm) {
frm.add_custom_button(__('Unreconcile Transaction'), () => {
frm.call('remove_payment_entries')
.then( () => frm.refresh() );
});
if (!frm.is_dirty() && frm.doc.payment_entries.length > 0) {
frm.add_custom_button(__("Unreconcile Transaction"), () => {
frm.call("remove_payment_entries").then(() => frm.refresh());
});
}
},
bank_account: function (frm) {
set_bank_statement_filter(frm);
Expand Down
24 changes: 21 additions & 3 deletions erpnext/accounts/doctype/payment_entry/payment_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,15 +535,21 @@ frappe.ui.form.on('Payment Entry', {
},

source_exchange_rate: function(frm) {
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
if (frm.doc.paid_amount) {
frm.set_value("base_paid_amount", flt(frm.doc.paid_amount) * flt(frm.doc.source_exchange_rate));
// target exchange rate should always be same as source if both account currencies is same
if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
frm.set_value("base_received_amount", frm.doc.base_paid_amount);
} else if (company_currency == frm.doc.paid_to_account_currency) {
frm.set_value("received_amount", frm.doc.base_paid_amount);
frm.set_value("base_received_amount", frm.doc.base_paid_amount);
}

frm.events.set_unallocated_amount(frm);
// set_unallocated_amount is called by below method,
// no need trigger separately
frm.events.set_total_allocated_amount(frm);
}

// Make read only if Accounts Settings doesn't allow stale rates
Expand All @@ -552,6 +558,7 @@ frappe.ui.form.on('Payment Entry', {

target_exchange_rate: function(frm) {
frm.set_paid_amount_based_on_received_amount = true;
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;

if (frm.doc.received_amount) {
frm.set_value("base_received_amount",
Expand All @@ -561,9 +568,14 @@ frappe.ui.form.on('Payment Entry', {
(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate);
frm.set_value("base_paid_amount", frm.doc.base_received_amount);
} else if (company_currency == frm.doc.paid_from_account_currency) {
frm.set_value("paid_amount", frm.doc.base_received_amount);
frm.set_value("base_paid_amount", frm.doc.base_received_amount);
}

frm.events.set_unallocated_amount(frm);
// set_unallocated_amount is called by below method,
// no need trigger separately
frm.events.set_total_allocated_amount(frm);
}
frm.set_paid_amount_based_on_received_amount = false;

Expand Down Expand Up @@ -879,12 +891,18 @@ frappe.ui.form.on('Payment Entry', {
},

set_total_allocated_amount: function(frm) {
let exchange_rate = 1;
if (frm.doc.payment_type == "Receive") {
exchange_rate = frm.doc.source_exchange_rate;
} else if (frm.doc.payment_type == "Pay") {
exchange_rate = frm.doc.target_exchange_rate;
}
var total_allocated_amount = 0.0;
var base_total_allocated_amount = 0.0;
$.each(frm.doc.references || [], function(i, row) {
if (row.allocated_amount) {
total_allocated_amount += flt(row.allocated_amount);
base_total_allocated_amount += flt(flt(row.allocated_amount)*flt(row.exchange_rate),
base_total_allocated_amount += flt(flt(row.allocated_amount)*flt(exchange_rate),
precision("base_paid_amount"));
}
});
Expand Down
9 changes: 7 additions & 2 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,11 @@ def calculate_base_allocated_amount_for_reference(self, d) -> float:
flt(d.allocated_amount) * flt(exchange_rate), self.precision("base_paid_amount")
)

# on rare case, when `exchange_rate` is unset, gain/loss amount is incorrectly calculated
# for base currency transactions
if d.exchange_rate is None:
d.exchange_rate = 1

allocated_amount_in_pe_exchange_rate = flt(
flt(d.allocated_amount) * flt(d.exchange_rate), self.precision("base_paid_amount")
)
Expand Down Expand Up @@ -2300,7 +2305,7 @@ def set_paid_amount_and_received_amount(
if bank_amount:
received_amount = bank_amount
else:
if company_currency != bank.account_currency:
if bank and company_currency != bank.account_currency:
received_amount = paid_amount / doc.get("conversion_rate", 1)
else:
received_amount = paid_amount * doc.get("conversion_rate", 1)
Expand All @@ -2309,7 +2314,7 @@ def set_paid_amount_and_received_amount(
if bank_amount:
paid_amount = bank_amount
else:
if company_currency != bank.account_currency:
if bank and company_currency != bank.account_currency:
paid_amount = received_amount / doc.get("conversion_rate", 1)
else:
# if party account currency and bank currency is different then populate paid amount as well
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def get_jv_entries(self):
"Journal Entry" as reference_type, t1.name as reference_name,
t1.posting_date, t1.remark as remarks, t2.name as reference_row,
{dr_or_cr} as amount, t2.is_advance, t2.exchange_rate,
t2.account_currency as currency
t2.account_currency as currency, t2.cost_center as cost_center
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
Expand Down Expand Up @@ -209,6 +209,7 @@ def get_dr_or_cr_notes(self):
"amount": -(inv.outstanding_in_account_currency),
"posting_date": inv.posting_date,
"currency": inv.currency,
"cost_center": inv.cost_center,
}
)
)
Expand Down Expand Up @@ -357,6 +358,7 @@ def get_allocated_entry(self, pay, inv, allocated_amount):
"allocated_amount": allocated_amount,
"difference_amount": pay.get("difference_amount"),
"currency": inv.get("currency"),
"cost_center": pay.get("cost_center"),
}
)

Expand Down Expand Up @@ -431,6 +433,7 @@ def get_payment_details(self, row, dr_or_cr):
"allocated_amount": flt(row.get("allocated_amount")),
"difference_amount": flt(row.get("difference_amount")),
"difference_account": row.get("difference_account"),
"cost_center": row.get("cost_center"),
}
)

Expand Down Expand Up @@ -603,7 +606,7 @@ def reconcile_dr_cr_note(dr_cr_notes, company):
inv.dr_or_cr: abs(inv.allocated_amount),
"reference_type": inv.against_voucher_type,
"reference_name": inv.against_voucher,
"cost_center": erpnext.get_default_cost_center(company),
"cost_center": inv.cost_center or erpnext.get_default_cost_center(company),
"exchange_rate": inv.exchange_rate,
"user_remark": f"{fmt_money(flt(inv.allocated_amount), currency=company_currency)} against {inv.against_voucher}",
},
Expand All @@ -618,7 +621,7 @@ def reconcile_dr_cr_note(dr_cr_notes, company):
),
"reference_type": inv.voucher_type,
"reference_name": inv.voucher_no,
"cost_center": erpnext.get_default_cost_center(company),
"cost_center": inv.cost_center or erpnext.get_default_cost_center(company),
"exchange_rate": inv.exchange_rate,
"user_remark": f"{fmt_money(flt(inv.allocated_amount), currency=company_currency)} from {inv.voucher_no}",
},
Expand All @@ -644,6 +647,7 @@ def reconcile_dr_cr_note(dr_cr_notes, company):

create_gain_loss_journal(
company,
today(),
inv.party_type,
inv.party,
inv.account,
Expand All @@ -657,4 +661,5 @@ def reconcile_dr_cr_note(dr_cr_notes, company):
inv.against_voucher_type,
inv.against_voucher,
None,
inv.cost_center,
)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"column_break_7",
"difference_account",
"exchange_rate",
"currency"
"currency",
"cost_center"
],
"fields": [
{
Expand Down Expand Up @@ -144,11 +145,17 @@
"fieldtype": "Float",
"label": "Exchange Rate",
"read_only": 1
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
}
],
"istable": 1,
"links": [],
"modified": "2022-12-24 21:01:14.882747",
"modified": "2023-09-03 07:52:33.684217",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Allocation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"sec_break1",
"remark",
"currency",
"exchange_rate"
"exchange_rate",
"cost_center"
],
"fields": [
{
Expand Down Expand Up @@ -98,11 +99,17 @@
"fieldtype": "Float",
"hidden": 1,
"label": "Exchange Rate"
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
}
],
"istable": 1,
"links": [],
"modified": "2022-11-08 18:18:36.268760",
"modified": "2023-09-03 07:43:29.965353",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Payment",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def check_if_previous_year_closed(self):
def make_gl_entries(self, get_opening_entries=False):
gl_entries = self.get_gl_entries()
closing_entries = self.get_grouped_gl_entries(get_opening_entries=get_opening_entries)
if len(gl_entries) > 5000:
if len(gl_entries + closing_entries) > 3000:
frappe.enqueue(
process_gl_entries,
gl_entries=gl_entries,
Expand Down
2 changes: 1 addition & 1 deletion erpnext/accounts/party.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ def get_party_account(party_type, party=None, company=None, include_advance=Fals
if (account and account_currency != existing_gle_currency) or not account:
account = get_party_gle_account(party_type, party, company)

if include_advance and party_type in ["Customer", "Supplier"]:
if include_advance and party_type in ["Customer", "Supplier", "Student"]:
advance_account = get_party_advance_account(party_type, party, company)
if advance_account:
return [account, advance_account]
Expand Down
53 changes: 28 additions & 25 deletions erpnext/accounts/report/accounts_payable/accounts_payable.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,6 @@ frappe.query_reports["Accounts Payable"] = {
}
}
},
{
"fieldname": "supplier",
"label": __("Supplier"),
"fieldtype": "Link",
"options": "Supplier",
on_change: () => {
var supplier = frappe.query_report.get_filter_value('supplier');
if (supplier) {
frappe.db.get_value('Supplier', supplier, "tax_id", function(value) {
frappe.query_report.set_filter_value('tax_id', value["tax_id"]);
});
} else {
frappe.query_report.set_filter_value('tax_id', "");
}

frappe.query_report.refresh();
}
},
{
"fieldname": "party_account",
"label": __("Payable Account"),
Expand Down Expand Up @@ -112,11 +94,38 @@ frappe.query_reports["Accounts Payable"] = {
"fieldtype": "Link",
"options": "Payment Terms Template"
},
{
"fieldname": "party_type",
"label": __("Party Type"),
"fieldtype": "Link",
"options": "Party Type",
get_query: () => {
return {
filters: {
'account_type': 'Payable'
}
};
},
on_change: () => {
frappe.query_report.set_filter_value('party', "");
let party_type = frappe.query_report.get_filter_value('party_type');
frappe.query_report.toggle_filter_display('supplier_group', frappe.query_report.get_filter_value('party_type') !== "Supplier");

}

},
{
"fieldname":"party",
"label": __("Party"),
"fieldtype": "Dynamic Link",
"options": "party_type",
},
{
"fieldname": "supplier_group",
"label": __("Supplier Group"),
"fieldtype": "Link",
"options": "Supplier Group"
"options": "Supplier Group",
"hidden": 1
},
{
"fieldname": "group_by_party",
Expand All @@ -133,12 +142,6 @@ frappe.query_reports["Accounts Payable"] = {
"label": __("Show Remarks"),
"fieldtype": "Check",
},
{
"fieldname": "tax_id",
"label": __("Tax Id"),
"fieldtype": "Data",
"hidden": 1
},
{
"fieldname": "show_future_payments",
"label": __("Show Future Payments"),
Expand Down
67 changes: 67 additions & 0 deletions erpnext/accounts/report/accounts_payable/test_accounts_payable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import unittest

import frappe
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, flt, getdate, today

from erpnext import get_default_cost_center
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.accounts.report.accounts_payable.accounts_payable import execute
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order


class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
def setUp(self):
self.create_company()
self.create_customer()
self.create_item()
self.create_supplier(currency="USD", supplier_name="Test Supplier2")
self.create_usd_payable_account()

def tearDown(self):
frappe.db.rollback()

def test_accounts_receivable_with_supplier(self):
pi = self.create_purchase_invoice(do_not_submit=True)
pi.currency = "USD"
pi.conversion_rate = 80
pi.credit_to = self.creditors_usd
pi = pi.save().submit()

filters = {
"company": self.company,
"party_type": "Supplier",
"party": self.supplier,
"report_date": today(),
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
}

data = execute(filters)
self.assertEqual(data[1][0].get("outstanding"), 300)
self.assertEqual(data[1][0].get("currency"), "USD")

def create_purchase_invoice(self, do_not_submit=False):
frappe.set_user("Administrator")
pi = make_purchase_invoice(
item=self.item,
company=self.company,
supplier=self.supplier,
is_return=False,
update_stock=False,
posting_date=frappe.utils.datetime.date(2021, 5, 1),
do_not_save=1,
rate=300,
price_list_rate=300,
qty=1,
)

pi = pi.save()
if not do_not_submit:
pi = pi.submit()
return pi
Loading

0 comments on commit acbc12d

Please sign in to comment.