-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43709 from ruthra-kumar/ledger_for_advance_payment
feat: Ledger for advance payment
- Loading branch information
Showing
12 changed files
with
534 additions
and
17 deletions.
There are no files selected for viewing
Empty file.
8 changes: 8 additions & 0 deletions
8
erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors | ||
// For license information, please see license.txt | ||
|
||
// frappe.ui.form.on("Advance Payment Ledger Entry", { | ||
// refresh(frm) { | ||
|
||
// }, | ||
// }); |
97 changes: 97 additions & 0 deletions
97
erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
{ | ||
"actions": [], | ||
"allow_rename": 1, | ||
"creation": "2024-10-16 16:57:12.085072", | ||
"doctype": "DocType", | ||
"engine": "InnoDB", | ||
"field_order": [ | ||
"company", | ||
"voucher_type", | ||
"voucher_no", | ||
"against_voucher_type", | ||
"against_voucher_no", | ||
"amount", | ||
"currency", | ||
"event" | ||
], | ||
"fields": [ | ||
{ | ||
"fieldname": "voucher_type", | ||
"fieldtype": "Link", | ||
"label": "Voucher Type", | ||
"options": "DocType", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "voucher_no", | ||
"fieldtype": "Dynamic Link", | ||
"label": "Voucher No", | ||
"options": "voucher_type", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "against_voucher_type", | ||
"fieldtype": "Link", | ||
"label": "Against Voucher Type", | ||
"options": "DocType", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "against_voucher_no", | ||
"fieldtype": "Dynamic Link", | ||
"label": "Against Voucher No", | ||
"options": "against_voucher_type", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "amount", | ||
"fieldtype": "Currency", | ||
"label": "Amount", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "currency", | ||
"fieldtype": "Link", | ||
"label": "Currency", | ||
"options": "Currency", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "event", | ||
"fieldtype": "Data", | ||
"label": "Event", | ||
"read_only": 1 | ||
}, | ||
{ | ||
"fieldname": "company", | ||
"fieldtype": "Link", | ||
"label": "Company", | ||
"options": "Company", | ||
"read_only": 1 | ||
} | ||
], | ||
"index_web_pages_for_search": 1, | ||
"links": [], | ||
"modified": "2024-10-16 17:11:28.143979", | ||
"modified_by": "Administrator", | ||
"module": "Accounts", | ||
"name": "Advance Payment Ledger Entry", | ||
"owner": "Administrator", | ||
"permissions": [ | ||
{ | ||
"create": 1, | ||
"delete": 1, | ||
"email": 1, | ||
"export": 1, | ||
"print": 1, | ||
"read": 1, | ||
"report": 1, | ||
"role": "System Manager", | ||
"share": 1, | ||
"write": 1 | ||
} | ||
], | ||
"sort_field": "creation", | ||
"sort_order": "DESC", | ||
"states": [] | ||
} |
27 changes: 27 additions & 0 deletions
27
erpnext/accounts/doctype/advance_payment_ledger_entry/advance_payment_ledger_entry.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors | ||
# For license information, please see license.txt | ||
|
||
# import frappe | ||
from frappe.model.document import Document | ||
|
||
|
||
class AdvancePaymentLedgerEntry(Document): | ||
# begin: auto-generated types | ||
# This code is auto-generated. Do not modify anything in this block. | ||
|
||
from typing import TYPE_CHECKING | ||
|
||
if TYPE_CHECKING: | ||
from frappe.types import DF | ||
|
||
against_voucher_no: DF.DynamicLink | None | ||
against_voucher_type: DF.Link | None | ||
amount: DF.Currency | ||
company: DF.Link | None | ||
currency: DF.Link | None | ||
event: DF.Data | None | ||
voucher_no: DF.DynamicLink | None | ||
voucher_type: DF.Link | None | ||
# end: auto-generated types | ||
|
||
pass |
228 changes: 228 additions & 0 deletions
228
erpnext/accounts/doctype/advance_payment_ledger_entry/test_advance_payment_ledger_entry.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors | ||
# See license.txt | ||
|
||
import frappe | ||
from frappe.tests import IntegrationTestCase, UnitTestCase | ||
from frappe.utils import nowdate, today | ||
|
||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry | ||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin | ||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order | ||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order | ||
|
||
# On IntegrationTestCase, the doctype test records and all | ||
# link-field test record depdendencies are recursively loaded | ||
# Use these module variables to add/remove to/from that list | ||
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] | ||
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"] | ||
|
||
|
||
class TestAdvancePaymentLedgerEntry(AccountsTestMixin, IntegrationTestCase): | ||
""" | ||
Integration tests for AdvancePaymentLedgerEntry. | ||
Use this class for testing interactions between multiple components. | ||
""" | ||
|
||
def setUp(self): | ||
self.create_company() | ||
self.create_usd_receivable_account() | ||
self.create_usd_payable_account() | ||
self.create_item() | ||
self.clear_old_entries() | ||
|
||
def tearDown(self): | ||
frappe.db.rollback() | ||
|
||
def create_sales_order(self, qty=1, rate=100, currency="INR", do_not_submit=False): | ||
""" | ||
Helper method | ||
""" | ||
so = make_sales_order( | ||
company=self.company, | ||
customer=self.customer, | ||
currency=currency, | ||
item=self.item, | ||
qty=qty, | ||
rate=rate, | ||
transaction_date=today(), | ||
do_not_submit=do_not_submit, | ||
) | ||
return so | ||
|
||
def create_purchase_order(self, qty=1, rate=100, currency="INR", do_not_submit=False): | ||
""" | ||
Helper method | ||
""" | ||
po = create_purchase_order( | ||
company=self.company, | ||
customer=self.supplier, | ||
currency=currency, | ||
item=self.item, | ||
qty=qty, | ||
rate=rate, | ||
transaction_date=today(), | ||
do_not_submit=do_not_submit, | ||
) | ||
return po | ||
|
||
def test_so_advance_paid_and_currency_with_payment(self): | ||
self.create_customer("_Test USD Customer", "USD") | ||
|
||
so = self.create_sales_order(currency="USD", do_not_submit=True) | ||
so.conversion_rate = 80 | ||
so.submit() | ||
|
||
pe_exchange_rate = 85 | ||
pe = get_payment_entry(so.doctype, so.name, bank_account=self.cash) | ||
pe.reference_no = "1" | ||
pe.reference_date = nowdate() | ||
pe.paid_from = self.debtors_usd | ||
pe.paid_from_account_currency = "USD" | ||
pe.source_exchange_rate = pe_exchange_rate | ||
pe.paid_amount = so.grand_total | ||
pe.received_amount = pe_exchange_rate * pe.paid_amount | ||
pe.references[0].outstanding_amount = 100 | ||
pe.references[0].total_amount = 100 | ||
pe.references[0].allocated_amount = 100 | ||
pe.save().submit() | ||
|
||
so.reload() | ||
self.assertEqual(so.advance_paid, 100) | ||
self.assertEqual(so.party_account_currency, "USD") | ||
|
||
# cancel advance payment | ||
pe.reload() | ||
pe.cancel() | ||
|
||
so.reload() | ||
self.assertEqual(so.advance_paid, 0) | ||
self.assertEqual(so.party_account_currency, "USD") | ||
|
||
def test_so_advance_paid_and_currency_with_journal(self): | ||
self.create_customer("_Test USD Customer", "USD") | ||
|
||
so = self.create_sales_order(currency="USD", do_not_submit=True) | ||
so.conversion_rate = 80 | ||
so.submit() | ||
|
||
je_exchange_rate = 85 | ||
je = frappe.get_doc( | ||
{ | ||
"doctype": "Journal Entry", | ||
"company": self.company, | ||
"voucher_type": "Journal Entry", | ||
"posting_date": so.transaction_date, | ||
"multi_currency": True, | ||
"accounts": [ | ||
{ | ||
"account": self.debtors_usd, | ||
"party_type": "Customer", | ||
"party": so.customer, | ||
"credit": 8500, | ||
"credit_in_account_currency": 100, | ||
"is_advance": "Yes", | ||
"reference_type": so.doctype, | ||
"reference_name": so.name, | ||
"exchange_rate": je_exchange_rate, | ||
}, | ||
{ | ||
"account": self.cash, | ||
"debit": 8500, | ||
"debit_in_account_currency": 8500, | ||
}, | ||
], | ||
} | ||
) | ||
je.save().submit() | ||
so.reload() | ||
self.assertEqual(so.advance_paid, 100) | ||
self.assertEqual(so.party_account_currency, "USD") | ||
|
||
# cancel advance payment | ||
je.reload() | ||
je.cancel() | ||
|
||
so.reload() | ||
self.assertEqual(so.advance_paid, 0) | ||
self.assertEqual(so.party_account_currency, "USD") | ||
|
||
def test_po_advance_paid_and_currency_with_payment(self): | ||
self.create_supplier("_Test USD Supplier", "USD") | ||
|
||
po = self.create_purchase_order(currency="USD", do_not_submit=True) | ||
po.conversion_rate = 80 | ||
po.submit() | ||
|
||
pe_exchange_rate = 85 | ||
pe = get_payment_entry(po.doctype, po.name, bank_account=self.cash) | ||
pe.reference_no = "1" | ||
pe.reference_date = nowdate() | ||
pe.paid_to = self.creditors_usd | ||
pe.paid_to_account_currency = "USD" | ||
pe.target_exchange_rate = pe_exchange_rate | ||
pe.received_amount = po.grand_total | ||
pe.paid_amount = pe_exchange_rate * pe.received_amount | ||
pe.references[0].outstanding_amount = 100 | ||
pe.references[0].total_amount = 100 | ||
pe.references[0].allocated_amount = 100 | ||
pe.save().submit() | ||
|
||
po.reload() | ||
self.assertEqual(po.advance_paid, 100) | ||
self.assertEqual(po.party_account_currency, "USD") | ||
|
||
# cancel advance payment | ||
pe.reload() | ||
pe.cancel() | ||
|
||
po.reload() | ||
self.assertEqual(po.advance_paid, 0) | ||
self.assertEqual(po.party_account_currency, "USD") | ||
|
||
def test_po_advance_paid_and_currency_with_journal(self): | ||
self.create_supplier("_Test USD Supplier", "USD") | ||
|
||
po = self.create_purchase_order(currency="USD", do_not_submit=True) | ||
po.conversion_rate = 80 | ||
po.submit() | ||
|
||
je_exchange_rate = 85 | ||
je = frappe.get_doc( | ||
{ | ||
"doctype": "Journal Entry", | ||
"company": self.company, | ||
"voucher_type": "Journal Entry", | ||
"posting_date": po.transaction_date, | ||
"multi_currency": True, | ||
"accounts": [ | ||
{ | ||
"account": self.creditors_usd, | ||
"party_type": "Supplier", | ||
"party": po.supplier, | ||
"debit": 8500, | ||
"debit_in_account_currency": 100, | ||
"is_advance": "Yes", | ||
"reference_type": po.doctype, | ||
"reference_name": po.name, | ||
"exchange_rate": je_exchange_rate, | ||
}, | ||
{ | ||
"account": self.cash, | ||
"credit": 8500, | ||
"credit_in_account_currency": 8500, | ||
}, | ||
], | ||
} | ||
) | ||
je.save().submit() | ||
po.reload() | ||
self.assertEqual(po.advance_paid, 100) | ||
self.assertEqual(po.party_account_currency, "USD") | ||
|
||
# cancel advance payment | ||
je.reload() | ||
je.cancel() | ||
|
||
po.reload() | ||
self.assertEqual(po.advance_paid, 0) | ||
self.assertEqual(po.party_account_currency, "USD") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.