mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-23 15:09:20 +00:00
Merge pull request #37655 from frappe/version-13-hotfix
chore: release v13
This commit is contained in:
@@ -1626,6 +1626,30 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
|
|||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_default_cost_center_for_purchase(self):
|
||||||
|
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
|
||||||
|
|
||||||
|
for c_center in ["_Test Cost Center Selling", "_Test Cost Center Buying"]:
|
||||||
|
create_cost_center(cost_center_name=c_center)
|
||||||
|
|
||||||
|
item = create_item(
|
||||||
|
"_Test Cost Center Item For Purchase",
|
||||||
|
is_stock_item=1,
|
||||||
|
buying_cost_center="_Test Cost Center Buying - _TC",
|
||||||
|
selling_cost_center="_Test Cost Center Selling - _TC",
|
||||||
|
)
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(
|
||||||
|
item=item.name, qty=1, rate=1000, update_stock=True, do_not_submit=True, cost_center=""
|
||||||
|
)
|
||||||
|
|
||||||
|
pi.items[0].cost_center = ""
|
||||||
|
pi.set_missing_values()
|
||||||
|
pi.calculate_taxes_and_totals()
|
||||||
|
pi.save()
|
||||||
|
|
||||||
|
self.assertEqual(pi.items[0].cost_center, "_Test Cost Center Buying - _TC")
|
||||||
|
|
||||||
|
|
||||||
def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
|
def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
|
||||||
gl_entries = frappe.db.sql(
|
gl_entries = frappe.db.sql(
|
||||||
|
|||||||
@@ -2472,36 +2472,6 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(target_doc.company, "_Test Company 1")
|
self.assertEqual(target_doc.company, "_Test Company 1")
|
||||||
self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
|
self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
|
||||||
|
|
||||||
def test_sle_for_target_warehouse(self):
|
|
||||||
se = make_stock_entry(
|
|
||||||
item_code="138-CMS Shoe",
|
|
||||||
target="Finished Goods - _TC",
|
|
||||||
company="_Test Company",
|
|
||||||
qty=1,
|
|
||||||
basic_rate=500,
|
|
||||||
)
|
|
||||||
|
|
||||||
si = frappe.copy_doc(test_records[0])
|
|
||||||
si.update_stock = 1
|
|
||||||
si.set_warehouse = "Finished Goods - _TC"
|
|
||||||
si.set_target_warehouse = "Stores - _TC"
|
|
||||||
si.get("items")[0].warehouse = "Finished Goods - _TC"
|
|
||||||
si.get("items")[0].target_warehouse = "Stores - _TC"
|
|
||||||
si.insert()
|
|
||||||
si.submit()
|
|
||||||
|
|
||||||
sles = frappe.get_all(
|
|
||||||
"Stock Ledger Entry", filters={"voucher_no": si.name}, fields=["name", "actual_qty"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# check if both SLEs are created
|
|
||||||
self.assertEqual(len(sles), 2)
|
|
||||||
self.assertEqual(sum(d.actual_qty for d in sles), 0.0)
|
|
||||||
|
|
||||||
# tear down
|
|
||||||
si.cancel()
|
|
||||||
se.cancel()
|
|
||||||
|
|
||||||
def test_internal_transfer_gl_entry(self):
|
def test_internal_transfer_gl_entry(self):
|
||||||
si = create_sales_invoice(
|
si = create_sales_invoice(
|
||||||
company="_Test Company with perpetual inventory",
|
company="_Test Company with perpetual inventory",
|
||||||
|
|||||||
@@ -582,13 +582,21 @@ class StockController(AccountsController):
|
|||||||
d.stock_uom_rate = d.rate / (d.conversion_factor or 1)
|
d.stock_uom_rate = d.rate / (d.conversion_factor or 1)
|
||||||
|
|
||||||
def validate_internal_transfer(self):
|
def validate_internal_transfer(self):
|
||||||
if (
|
if self.doctype in ("Sales Invoice", "Delivery Note", "Purchase Invoice", "Purchase Receipt"):
|
||||||
self.doctype in ("Sales Invoice", "Delivery Note", "Purchase Invoice", "Purchase Receipt")
|
if self.is_internal_transfer():
|
||||||
and self.is_internal_transfer()
|
self.validate_in_transit_warehouses()
|
||||||
):
|
self.validate_multi_currency()
|
||||||
self.validate_in_transit_warehouses()
|
self.validate_packed_items()
|
||||||
self.validate_multi_currency()
|
else:
|
||||||
self.validate_packed_items()
|
self.validate_internal_transfer_warehouse()
|
||||||
|
|
||||||
|
def validate_internal_transfer_warehouse(self):
|
||||||
|
for row in self.items:
|
||||||
|
if row.get("target_warehouse"):
|
||||||
|
row.target_warehouse = None
|
||||||
|
|
||||||
|
if row.get("from_warehouse"):
|
||||||
|
row.from_warehouse = None
|
||||||
|
|
||||||
def validate_in_transit_warehouses(self):
|
def validate_in_transit_warehouses(self):
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1184,6 +1184,21 @@ class TestDeliveryNote(FrappeTestCase):
|
|||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
||||||
|
|
||||||
|
def non_internal_transfer_delivery_note(self):
|
||||||
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
|
|
||||||
|
dn = create_delivery_note(do_not_submit=True)
|
||||||
|
warehouse = create_warehouse("Internal Transfer Warehouse", dn.company)
|
||||||
|
dn.items[0].db_set("target_warehouse", "warehouse")
|
||||||
|
|
||||||
|
dn.reload()
|
||||||
|
|
||||||
|
self.assertEqual(dn.items[0].target_warehouse, warehouse.name)
|
||||||
|
|
||||||
|
dn.save()
|
||||||
|
dn.reload()
|
||||||
|
self.assertFalse(dn.items[0].target_warehouse)
|
||||||
|
|
||||||
|
|
||||||
def create_delivery_note(**args):
|
def create_delivery_note(**args):
|
||||||
dn = frappe.new_doc("Delivery Note")
|
dn = frappe.new_doc("Delivery Note")
|
||||||
|
|||||||
@@ -742,6 +742,8 @@ def create_item(
|
|||||||
opening_stock=0,
|
opening_stock=0,
|
||||||
is_fixed_asset=0,
|
is_fixed_asset=0,
|
||||||
asset_category=None,
|
asset_category=None,
|
||||||
|
buying_cost_center=None,
|
||||||
|
selling_cost_center=None,
|
||||||
company="_Test Company",
|
company="_Test Company",
|
||||||
):
|
):
|
||||||
if not frappe.db.exists("Item", item_code):
|
if not frappe.db.exists("Item", item_code):
|
||||||
@@ -759,7 +761,15 @@ def create_item(
|
|||||||
item.is_purchase_item = is_purchase_item
|
item.is_purchase_item = is_purchase_item
|
||||||
item.is_customer_provided_item = is_customer_provided_item
|
item.is_customer_provided_item = is_customer_provided_item
|
||||||
item.customer = customer or ""
|
item.customer = customer or ""
|
||||||
item.append("item_defaults", {"default_warehouse": warehouse, "company": company})
|
item.append(
|
||||||
|
"item_defaults",
|
||||||
|
{
|
||||||
|
"default_warehouse": warehouse,
|
||||||
|
"company": company,
|
||||||
|
"selling_cost_center": selling_cost_center,
|
||||||
|
"buying_cost_center": buying_cost_center,
|
||||||
|
},
|
||||||
|
)
|
||||||
item.save()
|
item.save()
|
||||||
else:
|
else:
|
||||||
item = frappe.get_doc("Item", item_code)
|
item = frappe.get_doc("Item", item_code)
|
||||||
|
|||||||
@@ -1069,88 +1069,6 @@ class TestPurchaseReceipt(FrappeTestCase):
|
|||||||
pr1.reload()
|
pr1.reload()
|
||||||
pr1.cancel()
|
pr1.cancel()
|
||||||
|
|
||||||
def test_stock_transfer_from_purchase_receipt(self):
|
|
||||||
pr1 = make_purchase_receipt(
|
|
||||||
warehouse="Work In Progress - TCP1", company="_Test Company with perpetual inventory"
|
|
||||||
)
|
|
||||||
|
|
||||||
pr = make_purchase_receipt(
|
|
||||||
company="_Test Company with perpetual inventory", warehouse="Stores - TCP1", do_not_save=1
|
|
||||||
)
|
|
||||||
|
|
||||||
pr.supplier_warehouse = ""
|
|
||||||
pr.items[0].from_warehouse = "Work In Progress - TCP1"
|
|
||||||
|
|
||||||
pr.submit()
|
|
||||||
|
|
||||||
gl_entries = get_gl_entries("Purchase Receipt", pr.name)
|
|
||||||
sl_entries = get_sl_entries("Purchase Receipt", pr.name)
|
|
||||||
|
|
||||||
self.assertFalse(gl_entries)
|
|
||||||
|
|
||||||
expected_sle = {"Work In Progress - TCP1": -5, "Stores - TCP1": 5}
|
|
||||||
|
|
||||||
for sle in sl_entries:
|
|
||||||
self.assertEqual(expected_sle[sle.warehouse], sle.actual_qty)
|
|
||||||
|
|
||||||
pr.cancel()
|
|
||||||
pr1.cancel()
|
|
||||||
|
|
||||||
def test_stock_transfer_from_purchase_receipt_with_valuation(self):
|
|
||||||
create_warehouse(
|
|
||||||
"_Test Warehouse for Valuation",
|
|
||||||
company="_Test Company with perpetual inventory",
|
|
||||||
properties={"account": "_Test Account Stock In Hand - TCP1"},
|
|
||||||
)
|
|
||||||
|
|
||||||
pr1 = make_purchase_receipt(
|
|
||||||
warehouse="_Test Warehouse for Valuation - TCP1",
|
|
||||||
company="_Test Company with perpetual inventory",
|
|
||||||
)
|
|
||||||
|
|
||||||
pr = make_purchase_receipt(
|
|
||||||
company="_Test Company with perpetual inventory", warehouse="Stores - TCP1", do_not_save=1
|
|
||||||
)
|
|
||||||
|
|
||||||
pr.items[0].from_warehouse = "_Test Warehouse for Valuation - TCP1"
|
|
||||||
pr.supplier_warehouse = ""
|
|
||||||
|
|
||||||
pr.append(
|
|
||||||
"taxes",
|
|
||||||
{
|
|
||||||
"charge_type": "On Net Total",
|
|
||||||
"account_head": "_Test Account Shipping Charges - TCP1",
|
|
||||||
"category": "Valuation and Total",
|
|
||||||
"cost_center": "Main - TCP1",
|
|
||||||
"description": "Test",
|
|
||||||
"rate": 9,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
pr.submit()
|
|
||||||
|
|
||||||
gl_entries = get_gl_entries("Purchase Receipt", pr.name)
|
|
||||||
sl_entries = get_sl_entries("Purchase Receipt", pr.name)
|
|
||||||
|
|
||||||
expected_gle = [
|
|
||||||
["Stock In Hand - TCP1", 272.5, 0.0],
|
|
||||||
["_Test Account Stock In Hand - TCP1", 0.0, 250.0],
|
|
||||||
["_Test Account Shipping Charges - TCP1", 0.0, 22.5],
|
|
||||||
]
|
|
||||||
|
|
||||||
expected_sle = {"_Test Warehouse for Valuation - TCP1": -5, "Stores - TCP1": 5}
|
|
||||||
|
|
||||||
for sle in sl_entries:
|
|
||||||
self.assertEqual(expected_sle[sle.warehouse], sle.actual_qty)
|
|
||||||
|
|
||||||
for i, gle in enumerate(gl_entries):
|
|
||||||
self.assertEqual(gle.account, expected_gle[i][0])
|
|
||||||
self.assertEqual(gle.debit, expected_gle[i][1])
|
|
||||||
self.assertEqual(gle.credit, expected_gle[i][2])
|
|
||||||
|
|
||||||
pr.cancel()
|
|
||||||
pr1.cancel()
|
|
||||||
|
|
||||||
def test_subcontracted_pr_for_multi_transfer_batches(self):
|
def test_subcontracted_pr_for_multi_transfer_batches(self):
|
||||||
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
from erpnext.buying.doctype.purchase_order.purchase_order import (
|
||||||
make_purchase_receipt,
|
make_purchase_receipt,
|
||||||
@@ -2050,6 +1968,21 @@ class TestPurchaseReceipt(FrappeTestCase):
|
|||||||
# Test - 2: Valuation Rate should be equal to Previous SLE Valuation Rate
|
# Test - 2: Valuation Rate should be equal to Previous SLE Valuation Rate
|
||||||
self.assertEqual(flt(sle.valuation_rate, 2), flt(previous_sle_valuation_rate, 2))
|
self.assertEqual(flt(sle.valuation_rate, 2), flt(previous_sle_valuation_rate, 2))
|
||||||
|
|
||||||
|
def non_internal_transfer_purchase_receipt(self):
|
||||||
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
|
|
||||||
|
pr_doc = make_purchase_receipt(do_not_submit=True)
|
||||||
|
warehouse = create_warehouse("Internal Transfer Warehouse", pr_doc.company)
|
||||||
|
pr_doc.items[0].db_set("target_warehouse", "warehouse")
|
||||||
|
|
||||||
|
pr_doc.reload()
|
||||||
|
|
||||||
|
self.assertEqual(pr_doc.items[0].from_warehouse, warehouse.name)
|
||||||
|
|
||||||
|
pr_doc.save()
|
||||||
|
pr_doc.reload()
|
||||||
|
self.assertFalse(pr_doc.items[0].from_warehouse)
|
||||||
|
|
||||||
|
|
||||||
def prepare_data_for_internal_transfer():
|
def prepare_data_for_internal_transfer():
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
||||||
|
|||||||
@@ -751,6 +751,12 @@ def get_default_cost_center(args, item=None, item_group=None, brand=None, compan
|
|||||||
data = frappe.get_attr(path)(args.get("item_code"), company)
|
data = frappe.get_attr(path)(args.get("item_code"), company)
|
||||||
|
|
||||||
if data and (data.selling_cost_center or data.buying_cost_center):
|
if data and (data.selling_cost_center or data.buying_cost_center):
|
||||||
|
if args.get("customer") and data.selling_cost_center:
|
||||||
|
return data.selling_cost_center
|
||||||
|
|
||||||
|
elif args.get("supplier") and data.buying_cost_center:
|
||||||
|
return data.buying_cost_center
|
||||||
|
|
||||||
return data.selling_cost_center or data.buying_cost_center
|
return data.selling_cost_center or data.buying_cost_center
|
||||||
|
|
||||||
if not cost_center and args.get("cost_center"):
|
if not cost_center and args.get("cost_center"):
|
||||||
|
|||||||
Reference in New Issue
Block a user