mirror of
https://github.com/frappe/erpnext.git
synced 2026-02-21 10:26:30 +00:00
fix: Merge conflicts
This commit is contained in:
@@ -236,11 +236,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
<<<<<<< HEAD
|
|
||||||
"modified": "2024-01-31 13:34:18.101256",
|
|
||||||
=======
|
|
||||||
"modified": "2025-03-03 17:32:25.939482",
|
"modified": "2025-03-03 17:32:25.939482",
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Buying Settings",
|
"name": "Buying Settings",
|
||||||
@@ -286,12 +282,7 @@
|
|||||||
"role": "Purchase User"
|
"role": "Purchase User"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
<<<<<<< HEAD
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
=======
|
|
||||||
"row_format": "Dynamic",
|
|
||||||
"sort_field": "creation",
|
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
|
|||||||
@@ -1281,20 +1281,19 @@
|
|||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
"fieldname": "dispatch_address_display",
|
"fieldname": "dispatch_address_display",
|
||||||
"fieldtype": "Text Editor",
|
"fieldtype": "Text Editor",
|
||||||
"label": "Dispatch Address Details",
|
"label": "Dispatch Address Details",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
=======
|
},
|
||||||
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "has_unit_price_items",
|
"fieldname": "has_unit_price_items",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Has Unit Price Items",
|
"label": "Has Unit Price Items",
|
||||||
"no_copy": 1
|
"no_copy": 1
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
@@ -1302,11 +1301,7 @@
|
|||||||
"idx": 105,
|
"idx": 105,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
<<<<<<< HEAD
|
|
||||||
"modified": "2025-04-09 16:54:08.836106",
|
"modified": "2025-04-09 16:54:08.836106",
|
||||||
=======
|
|
||||||
"modified": "2025-03-03 16:48:08.697520",
|
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
|||||||
@@ -5,11 +5,7 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
<<<<<<< HEAD
|
|
||||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
=======
|
|
||||||
from frappe.tests import IntegrationTestCase, UnitTestCase, change_settings
|
|
||||||
>>>>>>> eea758f5b2 (test: Purchase Order with Unit Price Items)
|
|
||||||
from frappe.utils import add_days, flt, getdate, nowdate
|
from frappe.utils import add_days, flt, getdate, nowdate
|
||||||
from frappe.utils.data import today
|
from frappe.utils.data import today
|
||||||
|
|
||||||
@@ -48,13 +44,6 @@ class TestPurchaseOrder(FrappeTestCase):
|
|||||||
po.items[1].qty = 0
|
po.items[1].qty = 0
|
||||||
self.assertRaises(InvalidQtyError, po.save)
|
self.assertRaises(InvalidQtyError, po.save)
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
# No error with qty=1
|
|
||||||
po.items[1].qty = 1
|
|
||||||
po.save()
|
|
||||||
self.assertEqual(po.items[1].qty, 1)
|
|
||||||
|
|
||||||
def test_purchase_order_zero_qty(self):
|
def test_purchase_order_zero_qty(self):
|
||||||
po = create_purchase_order(qty=0, do_not_save=True)
|
po = create_purchase_order(qty=0, do_not_save=True)
|
||||||
|
|
||||||
@@ -62,7 +51,6 @@ class TestPurchaseOrder(FrappeTestCase):
|
|||||||
po.save()
|
po.save()
|
||||||
self.assertEqual(po.items[0].qty, 0)
|
self.assertEqual(po.items[0].qty, 0)
|
||||||
|
|
||||||
>>>>>>> eea758f5b2 (test: Purchase Order with Unit Price Items)
|
|
||||||
def test_make_purchase_receipt(self):
|
def test_make_purchase_receipt(self):
|
||||||
po = create_purchase_order(do_not_submit=True)
|
po = create_purchase_order(do_not_submit=True)
|
||||||
self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
|
self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name)
|
||||||
@@ -812,8 +800,6 @@ class TestPurchaseOrder(FrappeTestCase):
|
|||||||
po_doc.reload()
|
po_doc.reload()
|
||||||
self.assertEqual(po_doc.advance_paid, 5000)
|
self.assertEqual(po_doc.advance_paid, 5000)
|
||||||
|
|
||||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
|
|
||||||
|
|
||||||
company_doc.book_advance_payments_in_separate_party_account = False
|
company_doc.book_advance_payments_in_separate_party_account = False
|
||||||
company_doc.save()
|
company_doc.save()
|
||||||
|
|
||||||
@@ -1218,7 +1204,7 @@ class TestPurchaseOrder(FrappeTestCase):
|
|||||||
po.reload()
|
po.reload()
|
||||||
self.assertEqual(po.per_billed, 100)
|
self.assertEqual(po.per_billed, 100)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Buying Settings", {"allow_zero_qty_in_purchase_order": 1})
|
@change_settings("Buying Settings", {"allow_zero_qty_in_purchase_order": 1})
|
||||||
def test_receive_zero_qty_purchase_order(self):
|
def test_receive_zero_qty_purchase_order(self):
|
||||||
"""
|
"""
|
||||||
Test the flow of a Unit Price PO and PR creation against it until completion.
|
Test the flow of a Unit Price PO and PR creation against it until completion.
|
||||||
@@ -1267,7 +1253,7 @@ class TestPurchaseOrder(FrappeTestCase):
|
|||||||
self.assertEqual(po.per_received, 100.0)
|
self.assertEqual(po.per_received, 100.0)
|
||||||
self.assertEqual(po.status, "To Bill")
|
self.assertEqual(po.status, "To Bill")
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Buying Settings", {"allow_zero_qty_in_purchase_order": 1})
|
@change_settings("Buying Settings", {"allow_zero_qty_in_purchase_order": 1})
|
||||||
def test_bill_zero_qty_purchase_order(self):
|
def test_bill_zero_qty_purchase_order(self):
|
||||||
po = create_purchase_order(qty=0)
|
po = create_purchase_order(qty=0)
|
||||||
|
|
||||||
|
|||||||
@@ -322,11 +322,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
<<<<<<< HEAD
|
|
||||||
"modified": "2023-11-06 12:45:28.898706",
|
|
||||||
=======
|
|
||||||
"modified": "2025-03-03 16:48:39.856779",
|
"modified": "2025-03-03 16:48:39.856779",
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Request for Quotation",
|
"name": "Request for Quotation",
|
||||||
|
|||||||
@@ -5,11 +5,7 @@
|
|||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
<<<<<<< HEAD
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
from frappe.tests.utils import FrappeTestCase
|
|
||||||
=======
|
|
||||||
from frappe.tests import IntegrationTestCase, UnitTestCase, change_settings
|
|
||||||
>>>>>>> 8f96c0b546 (test: Zero Qty in RFQ and Supplier Quotation)
|
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
|
|
||||||
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
from erpnext.buying.doctype.request_for_quotation.request_for_quotation import (
|
||||||
@@ -24,29 +20,7 @@ from erpnext.stock.doctype.item.test_item import make_item
|
|||||||
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
from erpnext.templates.pages.rfq import check_supplier_has_docname_access
|
||||||
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
class TestRequestforQuotation(FrappeTestCase):
|
class TestRequestforQuotation(FrappeTestCase):
|
||||||
=======
|
|
||||||
class UnitTestRequestForQuotation(UnitTestCase):
|
|
||||||
"""
|
|
||||||
Unit tests for RequestForQuotation.
|
|
||||||
Use this class for testing individual functions and methods.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TestRequestforQuotation(IntegrationTestCase):
|
|
||||||
def test_rfq_qty(self):
|
|
||||||
rfq = make_request_for_quotation(qty=0, do_not_save=True)
|
|
||||||
with self.assertRaises(InvalidQtyError):
|
|
||||||
rfq.save()
|
|
||||||
|
|
||||||
# No error with qty=1
|
|
||||||
rfq.items[0].qty = 1
|
|
||||||
rfq.save()
|
|
||||||
self.assertEqual(rfq.items[0].qty, 1)
|
|
||||||
|
|
||||||
def test_rfq_zero_qty(self):
|
def test_rfq_zero_qty(self):
|
||||||
"""
|
"""
|
||||||
Test if RFQ with zero qty (Unit Price Item) is conditionally allowed.
|
Test if RFQ with zero qty (Unit Price Item) is conditionally allowed.
|
||||||
@@ -57,7 +31,6 @@ class TestRequestforQuotation(IntegrationTestCase):
|
|||||||
rfq.save()
|
rfq.save()
|
||||||
self.assertEqual(rfq.items[0].qty, 0)
|
self.assertEqual(rfq.items[0].qty, 0)
|
||||||
|
|
||||||
>>>>>>> 8f96c0b546 (test: Zero Qty in RFQ and Supplier Quotation)
|
|
||||||
def test_quote_status(self):
|
def test_quote_status(self):
|
||||||
rfq = make_request_for_quotation()
|
rfq = make_request_for_quotation()
|
||||||
|
|
||||||
@@ -198,7 +171,7 @@ class TestRequestforQuotation(IntegrationTestCase):
|
|||||||
supplier_doc.reload()
|
supplier_doc.reload()
|
||||||
self.assertTrue(supplier_doc.portal_users[0].user)
|
self.assertTrue(supplier_doc.portal_users[0].user)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Buying Settings", {"allow_zero_qty_in_request_for_quotation": 1})
|
@change_settings("Buying Settings", {"allow_zero_qty_in_request_for_quotation": 1})
|
||||||
def test_supplier_quotation_from_zero_qty_rfq(self):
|
def test_supplier_quotation_from_zero_qty_rfq(self):
|
||||||
rfq = make_request_for_quotation(qty=0)
|
rfq = make_request_for_quotation(qty=0)
|
||||||
sq = make_supplier_quotation_from_rfq(rfq.name, for_supplier=rfq.get("suppliers")[0].supplier)
|
sq = make_supplier_quotation_from_rfq(rfq.name, for_supplier=rfq.get("suppliers")[0].supplier)
|
||||||
|
|||||||
@@ -3,58 +3,15 @@
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
<<<<<<< HEAD
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
from frappe.tests.utils import FrappeTestCase
|
|
||||||
from frappe.utils import add_days, today
|
from frappe.utils import add_days, today
|
||||||
|
|
||||||
|
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order
|
||||||
|
|
||||||
|
|
||||||
class TestPurchaseOrder(FrappeTestCase):
|
class TestPurchaseOrder(FrappeTestCase):
|
||||||
def test_make_purchase_order(self):
|
def test_make_purchase_order(self):
|
||||||
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order
|
|
||||||
|
|
||||||
sq = frappe.copy_doc(test_records[0]).insert()
|
sq = frappe.copy_doc(test_records[0]).insert()
|
||||||
=======
|
|
||||||
from frappe.tests import IntegrationTestCase, UnitTestCase, change_settings
|
|
||||||
|
|
||||||
from erpnext.buying.doctype.supplier_quotation.supplier_quotation import make_purchase_order
|
|
||||||
from erpnext.controllers.accounts_controller import InvalidQtyError
|
|
||||||
|
|
||||||
|
|
||||||
class UnitTestSupplierQuotation(UnitTestCase):
|
|
||||||
"""
|
|
||||||
Unit tests for SupplierQuotation.
|
|
||||||
Use this class for testing individual functions and methods.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TestPurchaseOrder(IntegrationTestCase):
|
|
||||||
def test_supplier_quotation_qty(self):
|
|
||||||
sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0])
|
|
||||||
sq.items[0].qty = 0
|
|
||||||
with self.assertRaises(InvalidQtyError):
|
|
||||||
sq.save()
|
|
||||||
|
|
||||||
# No error with qty=1
|
|
||||||
sq.items[0].qty = 1
|
|
||||||
sq.save()
|
|
||||||
self.assertEqual(sq.items[0].qty, 1)
|
|
||||||
|
|
||||||
def test_supplier_quotation_zero_qty(self):
|
|
||||||
"""
|
|
||||||
Test if RFQ with zero qty (Unit Price Item) is conditionally allowed.
|
|
||||||
"""
|
|
||||||
sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0])
|
|
||||||
sq.items[0].qty = 0
|
|
||||||
|
|
||||||
with change_settings("Buying Settings", {"allow_zero_qty_in_supplier_quotation": 1}):
|
|
||||||
sq.save()
|
|
||||||
self.assertEqual(sq.items[0].qty, 0)
|
|
||||||
|
|
||||||
def test_make_purchase_order(self):
|
|
||||||
sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0]).insert()
|
|
||||||
>>>>>>> 8f96c0b546 (test: Zero Qty in RFQ and Supplier Quotation)
|
|
||||||
|
|
||||||
self.assertRaises(frappe.ValidationError, make_purchase_order, sq.name)
|
self.assertRaises(frappe.ValidationError, make_purchase_order, sq.name)
|
||||||
|
|
||||||
@@ -73,17 +30,9 @@ class TestPurchaseOrder(IntegrationTestCase):
|
|||||||
|
|
||||||
po.insert()
|
po.insert()
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
test_records = frappe.get_test_records("Supplier Quotation")
|
|
||||||
=======
|
|
||||||
@change_settings("Buying Settings", {"allow_zero_qty_in_supplier_quotation": 1})
|
@change_settings("Buying Settings", {"allow_zero_qty_in_supplier_quotation": 1})
|
||||||
=======
|
|
||||||
@IntegrationTestCase.change_settings("Buying Settings", {"allow_zero_qty_in_supplier_quotation": 1})
|
|
||||||
>>>>>>> eea758f5b2 (test: Purchase Order with Unit Price Items)
|
|
||||||
def test_map_purchase_order_from_zero_qty_supplier_quotation(self):
|
def test_map_purchase_order_from_zero_qty_supplier_quotation(self):
|
||||||
sq = frappe.copy_doc(self.globalTestRecords["Supplier Quotation"][0])
|
sq = frappe.copy_doc(test_records[0]).insert()
|
||||||
sq.items[0].qty = 0
|
sq.items[0].qty = 0
|
||||||
sq.submit()
|
sq.submit()
|
||||||
|
|
||||||
@@ -91,4 +40,6 @@ test_records = frappe.get_test_records("Supplier Quotation")
|
|||||||
self.assertEqual(len(po.get("items")), 1)
|
self.assertEqual(len(po.get("items")), 1)
|
||||||
self.assertEqual(po.get("items")[0].qty, 0)
|
self.assertEqual(po.get("items")[0].qty, 0)
|
||||||
self.assertEqual(po.get("items")[0].item_code, sq.get("items")[0].item_code)
|
self.assertEqual(po.get("items")[0].item_code, sq.get("items")[0].item_code)
|
||||||
>>>>>>> 8f96c0b546 (test: Zero Qty in RFQ and Supplier Quotation)
|
|
||||||
|
|
||||||
|
test_records = frappe.get_test_records("Supplier Quotation")
|
||||||
|
|||||||
@@ -1259,17 +1259,8 @@ class AccountsController(TransactionBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_qty_is_not_zero(self):
|
def validate_qty_is_not_zero(self):
|
||||||
<<<<<<< HEAD
|
if self.doctype == "Purchase Receipt" or self.flags.allow_zero_qty:
|
||||||
if self.doctype == "Purchase Receipt":
|
|
||||||
return
|
return
|
||||||
=======
|
|
||||||
if self.flags.allow_zero_qty:
|
|
||||||
return
|
|
||||||
|
|
||||||
for item in self.items:
|
|
||||||
if self.doctype == "Purchase Receipt" and item.rejected_qty:
|
|
||||||
continue
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
|
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if not flt(item.qty):
|
if not flt(item.qty):
|
||||||
|
|||||||
@@ -1099,15 +1099,7 @@
|
|||||||
"idx": 82,
|
"idx": 82,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
<<<<<<< HEAD
|
|
||||||
<<<<<<< HEAD
|
|
||||||
"modified": "2024-11-26 12:43:29.293637",
|
|
||||||
=======
|
|
||||||
"modified": "2025-02-28 18:52:44.063265",
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
=======
|
|
||||||
"modified": "2025-03-03 16:49:20.050303",
|
"modified": "2025-03-03 16:49:20.050303",
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation",
|
"name": "Quotation",
|
||||||
|
|||||||
@@ -2,39 +2,13 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
<<<<<<< HEAD
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
from frappe.tests.utils import FrappeTestCase
|
|
||||||
=======
|
|
||||||
from frappe.tests import IntegrationTestCase, UnitTestCase, change_settings
|
|
||||||
>>>>>>> 0447c7be0a (fix: Treat rows as Unit Price rows only until the qty is 0)
|
|
||||||
from frappe.utils import add_days, add_months, flt, getdate, nowdate
|
from frappe.utils import add_days, add_months, flt, getdate, nowdate
|
||||||
|
|
||||||
test_dependencies = ["Product Bundle"]
|
test_dependencies = ["Product Bundle"]
|
||||||
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
class TestQuotation(FrappeTestCase):
|
class TestQuotation(FrappeTestCase):
|
||||||
=======
|
|
||||||
class UnitTestQuotation(UnitTestCase):
|
|
||||||
"""
|
|
||||||
Unit tests for Quotation.
|
|
||||||
Use this class for testing individual functions and methods.
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TestQuotation(IntegrationTestCase):
|
|
||||||
def test_quotation_qty(self):
|
|
||||||
qo = make_quotation(qty=0, do_not_save=True)
|
|
||||||
with self.assertRaises(InvalidQtyError):
|
|
||||||
qo.save()
|
|
||||||
|
|
||||||
# No error with qty=1
|
|
||||||
qo.items[0].qty = 1
|
|
||||||
qo.save()
|
|
||||||
self.assertEqual(qo.items[0].qty, 1)
|
|
||||||
|
|
||||||
def test_quotation_zero_qty(self):
|
def test_quotation_zero_qty(self):
|
||||||
"""
|
"""
|
||||||
Test if Quote with zero qty (Unit Price Item) is conditionally allowed.
|
Test if Quote with zero qty (Unit Price Item) is conditionally allowed.
|
||||||
@@ -44,7 +18,6 @@ class TestQuotation(IntegrationTestCase):
|
|||||||
qo.save()
|
qo.save()
|
||||||
self.assertEqual(qo.items[0].qty, 0)
|
self.assertEqual(qo.items[0].qty, 0)
|
||||||
|
|
||||||
>>>>>>> 0447c7be0a (fix: Treat rows as Unit Price rows only until the qty is 0)
|
|
||||||
def test_make_quotation_without_terms(self):
|
def test_make_quotation_without_terms(self):
|
||||||
quotation = make_quotation(do_not_save=1)
|
quotation = make_quotation(do_not_save=1)
|
||||||
self.assertFalse(quotation.get("payment_schedule"))
|
self.assertFalse(quotation.get("payment_schedule"))
|
||||||
@@ -797,7 +770,7 @@ class TestQuotation(IntegrationTestCase):
|
|||||||
self.assertEqual(quotation.rounding_adjustment, 0)
|
self.assertEqual(quotation.rounding_adjustment, 0)
|
||||||
self.assertEqual(quotation.rounded_total, 0)
|
self.assertEqual(quotation.rounded_total, 0)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Selling Settings", {"allow_zero_qty_in_quotation": 1})
|
@change_settings("Selling Settings", {"allow_zero_qty_in_quotation": 1})
|
||||||
def test_so_from_zero_qty_quotation(self):
|
def test_so_from_zero_qty_quotation(self):
|
||||||
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
from erpnext.selling.doctype.quotation.quotation import make_sales_order
|
||||||
from erpnext.stock.doctype.item.test_item import make_item
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
|||||||
@@ -153,11 +153,7 @@ class SalesOrder(SellingController):
|
|||||||
shipping_address_name: DF.Link | None
|
shipping_address_name: DF.Link | None
|
||||||
shipping_rule: DF.Link | None
|
shipping_rule: DF.Link | None
|
||||||
skip_delivery_note: DF.Check
|
skip_delivery_note: DF.Check
|
||||||
<<<<<<< HEAD
|
|
||||||
<<<<<<< HEAD
|
|
||||||
source: DF.Link | None
|
source: DF.Link | None
|
||||||
=======
|
|
||||||
>>>>>>> 71f65bab5e (fix: Linters)
|
|
||||||
status: DF.Literal[
|
status: DF.Literal[
|
||||||
"",
|
"",
|
||||||
"Draft",
|
"Draft",
|
||||||
@@ -170,12 +166,6 @@ class SalesOrder(SellingController):
|
|||||||
"Cancelled",
|
"Cancelled",
|
||||||
"Closed",
|
"Closed",
|
||||||
]
|
]
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
status: DF.Literal["", "Draft", "On Hold", "To Pay", "To Deliver and Bill", "To Bill", "To Deliver", "Completed", "Cancelled", "Closed"]
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
=======
|
|
||||||
>>>>>>> 71f65bab5e (fix: Linters)
|
|
||||||
tax_category: DF.Link | None
|
tax_category: DF.Link | None
|
||||||
tax_id: DF.Data | None
|
tax_id: DF.Data | None
|
||||||
taxes: DF.Table[SalesTaxesandCharges]
|
taxes: DF.Table[SalesTaxesandCharges]
|
||||||
|
|||||||
@@ -6,11 +6,7 @@ import json
|
|||||||
import frappe
|
import frappe
|
||||||
import frappe.permissions
|
import frappe.permissions
|
||||||
from frappe.core.doctype.user_permission.test_user_permission import create_user
|
from frappe.core.doctype.user_permission.test_user_permission import create_user
|
||||||
<<<<<<< HEAD
|
|
||||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||||
=======
|
|
||||||
from frappe.tests import IntegrationTestCase, change_settings
|
|
||||||
>>>>>>> 55981c8358 (test: Sales Order + fix: Mapping of Items from Quotation & SO)
|
|
||||||
from frappe.utils import add_days, flt, getdate, nowdate, today
|
from frappe.utils import add_days, flt, getdate, nowdate, today
|
||||||
|
|
||||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
@@ -90,31 +86,6 @@ class TestSalesOrder(AccountsTestMixin, FrappeTestCase):
|
|||||||
)
|
)
|
||||||
update_child_qty_rate("Sales Order", trans_item, so.name)
|
update_child_qty_rate("Sales Order", trans_item, so.name)
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
def test_sales_order_qty(self):
|
|
||||||
so = make_sales_order(qty=1, do_not_save=True)
|
|
||||||
|
|
||||||
# NonNegativeError with qty=-1
|
|
||||||
so.append(
|
|
||||||
"items",
|
|
||||||
{
|
|
||||||
"item_code": "_Test Item",
|
|
||||||
"qty": -1,
|
|
||||||
"rate": 10,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
self.assertRaises(frappe.NonNegativeError, so.save)
|
|
||||||
|
|
||||||
# InvalidQtyError with qty=0
|
|
||||||
so.items[1].qty = 0
|
|
||||||
self.assertRaises(InvalidQtyError, so.save)
|
|
||||||
|
|
||||||
# No error with qty=1
|
|
||||||
so.items[1].qty = 1
|
|
||||||
so.save()
|
|
||||||
self.assertEqual(so.items[0].qty, 1)
|
|
||||||
|
|
||||||
def test_sales_order_zero_qty(self):
|
def test_sales_order_zero_qty(self):
|
||||||
po = make_sales_order(qty=0, do_not_save=True)
|
po = make_sales_order(qty=0, do_not_save=True)
|
||||||
|
|
||||||
@@ -122,7 +93,6 @@ class TestSalesOrder(AccountsTestMixin, FrappeTestCase):
|
|||||||
po.save()
|
po.save()
|
||||||
self.assertEqual(po.items[0].qty, 0)
|
self.assertEqual(po.items[0].qty, 0)
|
||||||
|
|
||||||
>>>>>>> 55981c8358 (test: Sales Order + fix: Mapping of Items from Quotation & SO)
|
|
||||||
def test_make_material_request(self):
|
def test_make_material_request(self):
|
||||||
so = make_sales_order(do_not_submit=True)
|
so = make_sales_order(do_not_submit=True)
|
||||||
|
|
||||||
@@ -1983,79 +1953,6 @@ class TestSalesOrder(AccountsTestMixin, FrappeTestCase):
|
|||||||
self.assertEqual(so.items[0].rate, scenario.get("expected_rate"))
|
self.assertEqual(so.items[0].rate, scenario.get("expected_rate"))
|
||||||
self.assertEqual(so.packed_items[0].rate, scenario.get("expected_rate"))
|
self.assertEqual(so.packed_items[0].rate, scenario.get("expected_rate"))
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
@patch(
|
|
||||||
# this also shadows one (1) call to _get_payment_gateway_controller
|
|
||||||
"erpnext.accounts.doctype.payment_request.payment_request.PaymentRequest.get_payment_url",
|
|
||||||
return_value=None,
|
|
||||||
)
|
|
||||||
def test_sales_order_advance_payment_status(self, mocked_get_payment_url):
|
|
||||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
|
||||||
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
|
|
||||||
|
|
||||||
# Flow progressing to SI with payment entries "moved" from SO to SI
|
|
||||||
so = make_sales_order(qty=1, rate=100, do_not_submit=True)
|
|
||||||
# no-op; for optical consistency with how a webshop SO would look like
|
|
||||||
so.order_type = "Shopping Cart"
|
|
||||||
so.submit()
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Not Requested")
|
|
||||||
|
|
||||||
pr = make_payment_request(
|
|
||||||
dt=so.doctype,
|
|
||||||
dn=so.name,
|
|
||||||
order_type="Shopping Cart",
|
|
||||||
submit_doc=True,
|
|
||||||
return_doc=True,
|
|
||||||
mute_email=True,
|
|
||||||
)
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Requested")
|
|
||||||
|
|
||||||
pe = pr.set_as_paid()
|
|
||||||
pr.reload() # status updated
|
|
||||||
pe.reload() # references moved to Sales Invoice
|
|
||||||
self.assertEqual(pr.status, "Paid")
|
|
||||||
self.assertEqual(pe.references[0].reference_doctype, "Sales Invoice")
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Fully Paid")
|
|
||||||
|
|
||||||
pe.cancel()
|
|
||||||
pr.reload()
|
|
||||||
self.assertEqual(pr.status, "Paid") # TODO: this might be a bug
|
|
||||||
so.reload() # reload
|
|
||||||
# regardless, since the references have already "handed-over" to SI,
|
|
||||||
# the SO keeps its historical state at the time of hand over
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Fully Paid")
|
|
||||||
|
|
||||||
pr.cancel()
|
|
||||||
self.assertEqual(
|
|
||||||
frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Not Requested"
|
|
||||||
) # TODO: this might be a bug; handover has happened
|
|
||||||
|
|
||||||
# Flow NOT progressing to SI with payment entries NOT "moved"
|
|
||||||
so = make_sales_order(qty=1, rate=100)
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Not Requested")
|
|
||||||
|
|
||||||
pr = make_payment_request(
|
|
||||||
dt=so.doctype, dn=so.name, submit_doc=True, return_doc=True, mute_email=True
|
|
||||||
)
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Requested")
|
|
||||||
|
|
||||||
pe = get_payment_entry(so.doctype, so.name).save().submit()
|
|
||||||
self.assertEqual(frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Fully Paid")
|
|
||||||
|
|
||||||
pe.reload()
|
|
||||||
pe.cancel()
|
|
||||||
self.assertEqual(
|
|
||||||
frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Requested"
|
|
||||||
) # here: reset
|
|
||||||
|
|
||||||
pr.reload()
|
|
||||||
pr.cancel()
|
|
||||||
self.assertEqual(
|
|
||||||
frappe.db.get_value(so.doctype, so.name, "advance_payment_status"), "Not Requested"
|
|
||||||
) # here: reset
|
|
||||||
|
|
||||||
>>>>>>> 0447c7be0a (fix: Treat rows as Unit Price rows only until the qty is 0)
|
|
||||||
def test_pick_list_without_rejected_materials(self):
|
def test_pick_list_without_rejected_materials(self):
|
||||||
serial_and_batch_item = make_item(
|
serial_and_batch_item = make_item(
|
||||||
"_Test Serial and Batch Item for Rejected Materials",
|
"_Test Serial and Batch Item for Rejected Materials",
|
||||||
@@ -2302,7 +2199,7 @@ class TestSalesOrder(AccountsTestMixin, FrappeTestCase):
|
|||||||
po.submit()
|
po.submit()
|
||||||
self.assertEqual(po.taxes[0].tax_amount, 2)
|
self.assertEqual(po.taxes[0].tax_amount, 2)
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Selling Settings", {"allow_zero_qty_in_sales_order": 1})
|
@change_settings("Selling Settings", {"allow_zero_qty_in_sales_order": 1})
|
||||||
def test_deliver_zero_qty_purchase_order(self):
|
def test_deliver_zero_qty_purchase_order(self):
|
||||||
"""
|
"""
|
||||||
Test the flow of a Unit Price SO and DN creation against it until completion.
|
Test the flow of a Unit Price SO and DN creation against it until completion.
|
||||||
@@ -2350,7 +2247,7 @@ class TestSalesOrder(AccountsTestMixin, FrappeTestCase):
|
|||||||
self.assertEqual(so.per_delivered, 100.0)
|
self.assertEqual(so.per_delivered, 100.0)
|
||||||
self.assertEqual(so.status, "To Bill")
|
self.assertEqual(so.status, "To Bill")
|
||||||
|
|
||||||
@IntegrationTestCase.change_settings("Selling Settings", {"allow_zero_qty_in_sales_order": 1})
|
@change_settings("Selling Settings", {"allow_zero_qty_in_sales_order": 1})
|
||||||
def test_bill_zero_qty_sales_order(self):
|
def test_bill_zero_qty_sales_order(self):
|
||||||
so = make_sales_order(qty=0)
|
so = make_sales_order(qty=0)
|
||||||
|
|
||||||
|
|||||||
@@ -32,16 +32,9 @@
|
|||||||
"allow_sales_order_creation_for_expired_quotation",
|
"allow_sales_order_creation_for_expired_quotation",
|
||||||
"dont_reserve_sales_order_qty_on_sales_return",
|
"dont_reserve_sales_order_qty_on_sales_return",
|
||||||
"hide_tax_id",
|
"hide_tax_id",
|
||||||
<<<<<<< HEAD
|
|
||||||
"enable_discount_accounting"
|
|
||||||
=======
|
|
||||||
"enable_discount_accounting",
|
"enable_discount_accounting",
|
||||||
"enable_cutoff_date_on_bulk_delivery_note_creation",
|
|
||||||
"allow_zero_qty_in_quotation",
|
"allow_zero_qty_in_quotation",
|
||||||
"allow_zero_qty_in_sales_order",
|
"allow_zero_qty_in_sales_order"
|
||||||
"experimental_section",
|
|
||||||
"use_server_side_reactivity"
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -209,25 +202,6 @@
|
|||||||
"fieldname": "blanket_order_allowance",
|
"fieldname": "blanket_order_allowance",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Blanket Order Allowance (%)"
|
"label": "Blanket Order Allowance (%)"
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "enable_cutoff_date_on_bulk_delivery_note_creation",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Enable Cut-Off Date on Bulk Delivery Note Creation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "experimental_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Experimental"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "1",
|
|
||||||
"fieldname": "use_server_side_reactivity",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Use Server Side Reactivity"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@@ -239,12 +213,7 @@
|
|||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "allow_zero_qty_in_quotation",
|
"fieldname": "allow_zero_qty_in_quotation",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
<<<<<<< HEAD
|
|
||||||
"label": "Allow 0 Qty in Quotation (Unit Price Contract)"
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
=======
|
|
||||||
"label": "Allow 0 Qty in Quotation (Unit Price Items)"
|
"label": "Allow 0 Qty in Quotation (Unit Price Items)"
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
@@ -253,15 +222,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
<<<<<<< HEAD
|
|
||||||
<<<<<<< HEAD
|
|
||||||
"modified": "2023-10-25 14:03:03.966701",
|
|
||||||
=======
|
|
||||||
"modified": "2025-02-28 18:19:46.436595",
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
=======
|
|
||||||
"modified": "2025-03-03 16:39:16.360823",
|
"modified": "2025-03-03 16:39:16.360823",
|
||||||
>>>>>>> e403d3f153 (feat: Unit Price Items in Buying (RFQ, SQ, PO))
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Selling Settings",
|
"name": "Selling Settings",
|
||||||
@@ -286,12 +247,7 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
<<<<<<< HEAD
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
=======
|
|
||||||
"row_format": "Dynamic",
|
|
||||||
"sort_field": "creation",
|
|
||||||
>>>>>>> c1e4e7af28 (feat: Unit Price Contract)
|
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
|
|||||||
Reference in New Issue
Block a user