blob: c439d4b1904cc84225578552f87b49b9bd96d956 [file] [log] [blame]
tundebabzy40a02762017-10-25 07:54:34 +01001import unittest
Chillar Anand915b3432021-09-02 16:44:59 +05302
Ankush Menat700e8642022-04-19 13:24:29 +05303import frappe
tundebabzy40a02762017-10-25 07:54:34 +01004from frappe.test_runner import make_test_objects
5
Devin Slauenwhite98c39c42023-01-01 22:25:12 -05006from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
7from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
Chillar Anand915b3432021-09-02 16:44:59 +05308from erpnext.accounts.party import get_party_shipping_address
Ankush Menat700e8642022-04-19 13:24:29 +05309from erpnext.accounts.utils import (
10 get_future_stock_vouchers,
11 get_voucherwise_gl_entries,
12 sort_stock_vouchers_by_posting_date,
Devin Slauenwhite98c39c42023-01-01 22:25:12 -050013 update_reference_in_payment_entry,
Ankush Menat700e8642022-04-19 13:24:29 +053014)
15from erpnext.stock.doctype.item.test_item import make_item
rohitwaghchaure058d9832021-09-07 12:14:40 +053016from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
Ankush Menat700e8642022-04-19 13:24:29 +053017from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
Chillar Anand915b3432021-09-02 16:44:59 +053018
tundebabzy40a02762017-10-25 07:54:34 +010019
20class TestUtils(unittest.TestCase):
21 @classmethod
22 def setUpClass(cls):
23 super(TestUtils, cls).setUpClass()
rohitwaghchaure058d9832021-09-07 12:14:40 +053024 make_test_objects("Address", ADDRESS_RECORDS)
tundebabzy40a02762017-10-25 07:54:34 +010025
Gursheen Anand813b7a92024-01-11 12:22:08 +053026 @classmethod
27 def tearDownClass(cls):
Gursheen Anandbbdf98a2024-01-10 22:06:06 +053028 frappe.db.rollback()
29
tundebabzy40a02762017-10-25 07:54:34 +010030 def test_get_party_shipping_address(self):
rohitwaghchaure058d9832021-09-07 12:14:40 +053031 address = get_party_shipping_address("Customer", "_Test Customer 1")
32 self.assertEqual(address, "_Test Billing Address 2 Title-Billing")
tundebabzy40a02762017-10-25 07:54:34 +010033
34 def test_get_party_shipping_address2(self):
rohitwaghchaure058d9832021-09-07 12:14:40 +053035 address = get_party_shipping_address("Customer", "_Test Customer 2")
36 self.assertEqual(address, "_Test Shipping Address 2 Title-Shipping")
37
38 def test_get_voucher_wise_gl_entry(self):
39
40 pr = make_purchase_receipt(
41 item_code="_Test Item",
42 posting_date="2021-02-01",
43 rate=100,
44 qty=1,
45 warehouse="Stores - TCP1",
46 company="_Test Company with perpetual inventory",
47 )
48
49 future_vouchers = get_future_stock_vouchers("2021-01-01", "00:00:00", for_items=["_Test Item"])
50
51 voucher_type_and_no = ("Purchase Receipt", pr.name)
52 self.assertTrue(
53 voucher_type_and_no in future_vouchers,
54 msg="get_future_stock_vouchers not returning correct value",
55 )
56
57 posting_date = "2021-01-01"
58 gl_entries = get_voucherwise_gl_entries(future_vouchers, posting_date)
59 self.assertTrue(
Ankush Menat494bd9e2022-03-28 18:52:46 +053060 voucher_type_and_no in gl_entries,
61 msg="get_voucherwise_gl_entries not returning expected GLes",
rohitwaghchaure058d9832021-09-07 12:14:40 +053062 )
tundebabzy40a02762017-10-25 07:54:34 +010063
Ankush Menat700e8642022-04-19 13:24:29 +053064 def test_stock_voucher_sorting(self):
65 vouchers = []
66
67 item = make_item().name
68
69 stock_entry = {"item": item, "to_warehouse": "_Test Warehouse - _TC", "qty": 1, "rate": 10}
70
71 se1 = make_stock_entry(posting_date="2022-01-01", **stock_entry)
Ankush Menat700e8642022-04-19 13:24:29 +053072 se3 = make_stock_entry(posting_date="2022-03-01", **stock_entry)
Ankush Menat2535d5e2022-06-14 18:20:33 +053073 se2 = make_stock_entry(posting_date="2022-02-01", **stock_entry)
Ankush Menat700e8642022-04-19 13:24:29 +053074
75 for doc in (se1, se2, se3):
76 vouchers.append((doc.doctype, doc.name))
77
78 vouchers.append(("Stock Entry", "Wat"))
79
80 sorted_vouchers = sort_stock_vouchers_by_posting_date(list(reversed(vouchers)))
81 self.assertEqual(sorted_vouchers, vouchers)
82
Devin Slauenwhite98c39c42023-01-01 22:25:12 -050083 def test_update_reference_in_payment_entry(self):
84 item = make_item().name
85
86 purchase_invoice = make_purchase_invoice(
ruthra kumar72bc5b32023-06-27 16:11:03 +053087 item=item, supplier="_Test Supplier USD", currency="USD", conversion_rate=82.32, do_not_submit=1
Devin Slauenwhite98c39c42023-01-01 22:25:12 -050088 )
ruthra kumar72bc5b32023-06-27 16:11:03 +053089 purchase_invoice.credit_to = "_Test Payable USD - _TC"
Devin Slauenwhite98c39c42023-01-01 22:25:12 -050090 purchase_invoice.submit()
91
92 payment_entry = get_payment_entry(purchase_invoice.doctype, purchase_invoice.name)
Devin Slauenwhite98c39c42023-01-01 22:25:12 -050093 payment_entry.paid_amount = 15725
94 payment_entry.deductions = []
ruthra kumar72bc5b32023-06-27 16:11:03 +053095 payment_entry.save()
Devin Slauenwhite98c39c42023-01-01 22:25:12 -050096
ruthra kumar72bc5b32023-06-27 16:11:03 +053097 # below is the difference between base_received_amount and base_paid_amount
98 self.assertEqual(payment_entry.difference_amount, -4855.0)
99
100 payment_entry.target_exchange_rate = 62.9
101 payment_entry.save()
102
103 # below is due to change in exchange rate
104 self.assertEqual(payment_entry.references[0].exchange_gain_loss, -4855.0)
105
Devin Slauenwhite98c39c42023-01-01 22:25:12 -0500106 payment_entry.references = []
ruthra kumar72bc5b32023-06-27 16:11:03 +0530107 self.assertEqual(payment_entry.difference_amount, 0.0)
Devin Slauenwhite98c39c42023-01-01 22:25:12 -0500108 payment_entry.submit()
109
110 payment_reconciliation = frappe.new_doc("Payment Reconciliation")
111 payment_reconciliation.company = payment_entry.company
112 payment_reconciliation.party_type = "Supplier"
113 payment_reconciliation.party = purchase_invoice.supplier
114 payment_reconciliation.receivable_payable_account = payment_entry.paid_to
115 payment_reconciliation.get_unreconciled_entries()
116 payment_reconciliation.allocate_entries(
117 {
118 "payments": [d.__dict__ for d in payment_reconciliation.payments],
119 "invoices": [d.__dict__ for d in payment_reconciliation.invoices],
120 }
121 )
122 for d in payment_reconciliation.invoices:
123 # Reset invoice outstanding_amount because allocate_entries will zero this value out.
124 d.outstanding_amount = d.amount
125 for d in payment_reconciliation.allocation:
126 d.difference_account = "Exchange Gain/Loss - _TC"
127 payment_reconciliation.reconcile()
128
129 payment_entry.load_from_db()
130 self.assertEqual(len(payment_entry.references), 1)
131 self.assertEqual(payment_entry.difference_amount, 0)
132
Gursheen Anandbbdf98a2024-01-10 22:06:06 +0530133 def test_naming_series_variable_parsing(self):
134 """
135 Tests parsing utility used by Naming Series Variable hook for FY
136 """
137 from frappe.custom.doctype.property_setter.property_setter import make_property_setter
138 from frappe.utils import nowdate
139
140 from erpnext.accounts.utils import get_fiscal_year
141 from erpnext.buying.doctype.supplier.test_supplier import create_supplier
142
143 # Configure Supplier Naming in Buying Settings
144 frappe.db.set_default("supp_master_name", "Auto Name")
145
146 # Configure Autoname in Supplier DocType
147 make_property_setter(
148 "Supplier", None, "naming_rule", "Expression", "Data", for_doctype="Doctype"
149 )
150 make_property_setter(
151 "Supplier", None, "autoname", "SUP-.FY.-.#####", "Data", for_doctype="Doctype"
152 )
153
Gursheen Anandbbdf98a2024-01-10 22:06:06 +0530154 fiscal_year = get_fiscal_year(nowdate())[0]
155
156 # Create Supplier
157 supplier = create_supplier()
158
159 # Check Naming Series in generated Supplier ID
160 doc_name = supplier.name.split("-")
161 self.assertEqual(len(doc_name), 3)
162 self.assertSequenceEqual(doc_name[0:2], ("SUP", fiscal_year))
Gursheen Anand813b7a92024-01-11 12:22:08 +0530163 frappe.db.set_default("supp_master_name", "Supplier Name")
Gursheen Anandbbdf98a2024-01-10 22:06:06 +0530164
tundebabzy40a02762017-10-25 07:54:34 +0100165
166ADDRESS_RECORDS = [
167 {
168 "doctype": "Address",
169 "address_type": "Billing",
170 "address_line1": "Address line 1",
171 "address_title": "_Test Billing Address Title",
172 "city": "Lagos",
173 "country": "Nigeria",
174 "links": [
rohitwaghchaure058d9832021-09-07 12:14:40 +0530175 {"link_doctype": "Customer", "link_name": "_Test Customer 2", "doctype": "Dynamic Link"}
176 ],
tundebabzy40a02762017-10-25 07:54:34 +0100177 },
178 {
179 "doctype": "Address",
180 "address_type": "Shipping",
181 "address_line1": "Address line 2",
182 "address_title": "_Test Shipping Address 1 Title",
183 "city": "Lagos",
184 "country": "Nigeria",
185 "links": [
rohitwaghchaure058d9832021-09-07 12:14:40 +0530186 {"link_doctype": "Customer", "link_name": "_Test Customer 2", "doctype": "Dynamic Link"}
187 ],
tundebabzy40a02762017-10-25 07:54:34 +0100188 },
189 {
190 "doctype": "Address",
191 "address_type": "Shipping",
192 "address_line1": "Address line 3",
193 "address_title": "_Test Shipping Address 2 Title",
194 "city": "Lagos",
195 "country": "Nigeria",
196 "is_shipping_address": "1",
197 "links": [
rohitwaghchaure058d9832021-09-07 12:14:40 +0530198 {"link_doctype": "Customer", "link_name": "_Test Customer 2", "doctype": "Dynamic Link"}
199 ],
tundebabzy40a02762017-10-25 07:54:34 +0100200 },
201 {
202 "doctype": "Address",
203 "address_type": "Billing",
204 "address_line1": "Address line 4",
205 "address_title": "_Test Billing Address 2 Title",
206 "city": "Lagos",
207 "country": "Nigeria",
208 "is_shipping_address": "1",
209 "links": [
rohitwaghchaure058d9832021-09-07 12:14:40 +0530210 {"link_doctype": "Customer", "link_name": "_Test Customer 1", "doctype": "Dynamic Link"}
211 ],
212 },
tundebabzy40a02762017-10-25 07:54:34 +0100213]