Skip to content

Commit

Permalink
fix: internal transfer flow
Browse files Browse the repository at this point in the history
  • Loading branch information
rohitwaghchaure committed Sep 7, 2022
1 parent 404668f commit 4bac0da
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 23 deletions.
38 changes: 27 additions & 11 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ def validate_with_previous_doc(self):
if (
cint(frappe.db.get_single_value("Selling Settings", "maintain_same_sales_rate"))
and not self.is_return
and not self.is_internal_customer
):
self.validate_rate_with_reference_doc(
[["Sales Order", "sales_order", "so_detail"], ["Delivery Note", "delivery_note", "dn_detail"]]
Expand Down Expand Up @@ -2161,6 +2162,17 @@ def update_details(source_doc, target_doc, source_parent):

def update_item(source, target, source_parent):
target.qty = flt(source.qty) - received_items.get(source.name, 0.0)
if source.doctype == "Purchase Order Item" and target.doctype == "Sales Order Item":
target.purchase_order = source.parent
target.purchase_order_item = source.name

if (
source.get("purchase_order")
and source.get("purchase_order_item")
and target.doctype == "Purchase Invoice Item"
):
target.purchase_order = source.purchase_order
target.po_detail = source.purchase_order_item

item_field_map = {
"doctype": target_doctype + " Item",
Expand All @@ -2187,6 +2199,12 @@ def update_item(source, target, source_parent):
"serial_no": "serial_no",
}
)
elif target_doctype == "Sales Order":
item_field_map["field_map"].update(
{
source_document_warehouse_field: "warehouse",
}
)

doclist = get_mapped_doc(
doctype,
Expand Down Expand Up @@ -2231,6 +2249,7 @@ def get_received_items(reference_name, doctype, reference_fieldname):

def set_purchase_references(doc):
# add internal PO or PR links if any

if doc.is_internal_transfer():
if doc.doctype == "Purchase Receipt":
so_item_map = get_delivery_note_details(doc.inter_company_invoice_reference)
Expand Down Expand Up @@ -2260,15 +2279,6 @@ def set_purchase_references(doc):
warehouse_map,
)

if list(so_item_map.values()):
pd_item_map, parent_child_map, warehouse_map = get_pd_details(
"Purchase Order Item", so_item_map, "sales_order_item"
)

update_pi_items(
doc, "po_detail", "purchase_order", so_item_map, pd_item_map, parent_child_map, warehouse_map
)


def update_pi_items(
doc,
Expand All @@ -2284,13 +2294,19 @@ def update_pi_items(
item.set(parent_field, parent_child_map.get(sales_item_map.get(item.sales_invoice_item)))
if doc.update_stock:
item.warehouse = warehouse_map.get(sales_item_map.get(item.sales_invoice_item))
if not item.warehouse and item.get("purchase_order") and item.get("purchase_order_item"):
item.warehouse = frappe.db.get_value(
"Purchase Order Item", item.purchase_order_item, "warehouse"
)


def update_pr_items(doc, sales_item_map, purchase_item_map, parent_child_map, warehouse_map):
for item in doc.get("items"):
item.purchase_order_item = purchase_item_map.get(sales_item_map.get(item.delivery_note_item))
item.warehouse = warehouse_map.get(sales_item_map.get(item.delivery_note_item))
item.purchase_order = parent_child_map.get(sales_item_map.get(item.delivery_note_item))
if not item.warehouse and item.get("purchase_order") and item.get("purchase_order_item"):
item.warehouse = frappe.db.get_value(
"Purchase Order Item", item.purchase_order_item, "warehouse"
)


def get_delivery_note_details(internal_reference):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
"delivery_note",
"dn_detail",
"delivered_qty",
"internal_transfer_section",
"purchase_order",
"column_break_92",
"purchase_order_item",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
Expand Down Expand Up @@ -840,12 +844,38 @@
"fieldtype": "Check",
"label": "Grant Commission",
"read_only": 1
},
{
"collapsible": 1,
"depends_on": "eval:parent.is_internal_customer == 1",
"fieldname": "internal_transfer_section",
"fieldtype": "Section Break",
"label": "Internal Transfer"
},
{
"fieldname": "purchase_order",
"fieldtype": "Link",
"label": "Purchase Order",
"options": "Purchase Order",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "column_break_92",
"fieldtype": "Column Break"
},
{
"fieldname": "purchase_order_item",
"fieldtype": "Data",
"label": "Purchase Order Item",
"print_hide": 1,
"read_only": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2022-08-26 12:06:31.205417",
"modified": "2022-09-06 14:17:43.394309",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
Expand Down
10 changes: 9 additions & 1 deletion erpnext/buying/doctype/purchase_order/purchase_order.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"section_break_45",
"before_items_section",
"scan_barcode",
"set_from_warehouse",
"items_col_break",
"set_warehouse",
"items_section",
Expand Down Expand Up @@ -1166,13 +1167,20 @@
"hidden": 1,
"label": "Is Old Subcontracting Flow",
"read_only": 1
},
{
"depends_on": "is_internal_supplier",
"fieldname": "set_from_warehouse",
"fieldtype": "Link",
"label": "Set From Warehouse",
"options": "Warehouse"
}
],
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
"links": [],
"modified": "2022-06-15 15:40:58.527065",
"modified": "2022-09-07 11:06:46.035093",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ def get_data():
"items": ["Material Request", "Supplier Quotation", "Project", "Auto Repeat"],
},
{"label": _("Sub-contracting"), "items": ["Subcontracting Order", "Stock Entry"]},
{"label": _("Internal"), "items": ["Sales Order"]},
],
}
52 changes: 52 additions & 0 deletions erpnext/buying/doctype/purchase_order/test_purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from frappe.utils import add_days, flt, getdate, nowdate

from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.buying.doctype.purchase_order.purchase_order import make_inter_company_sales_order
from erpnext.buying.doctype.purchase_order.purchase_order import (
make_purchase_invoice as make_pi_from_po,
)
Expand Down Expand Up @@ -796,6 +797,56 @@ def test_payment_terms_are_fetched_when_creating_purchase_invoice(self):

automatically_fetch_payment_terms(enable=0)

def test_internal_transfer_flow(self):
from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note

prepare_data_for_internal_transfer()
supplier = "_Test Internal Supplier 2"
customer = "_Test Internal Customer 2"

po = create_purchase_order(
company="_Test Company with perpetual inventory",
supplier=supplier,
warehouse="Stores - TCP1",
from_warehouse="_Test Internal Warehouse New 1 - TCP1",
qty=2,
rate=1,
)

so = make_inter_company_sales_order(po.name)
so.submit()

dn = make_delivery_note(so.name)


def prepare_data_for_internal_transfer():
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse

create_internal_customer(
"_Test Internal Customer 2",
"_Test Company with perpetual inventory",
"_Test Company with perpetual inventory",
)

create_internal_supplier(
"_Test Internal Supplier 2",
"_Test Company with perpetual inventory",
"_Test Company with perpetual inventory",
)

warehouse = create_warehouse(
"_Test Internal Warehouse New 1", company="_Test Company with perpetual inventory"
)

make_purchase_receipt(
company="_Test Company with perpetual inventory",
warehouse=warehouse,
qty=2,
)


def make_pr_against_po(po, received_qty=0):
pr = make_purchase_receipt(po)
Expand Down Expand Up @@ -847,6 +898,7 @@ def create_purchase_order(**args):
{
"item_code": args.item or args.item_code or "_Test Item",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"from_warehouse": args.from_warehouse,
"qty": args.qty or 10,
"rate": args.rate or 500,
"schedule_date": add_days(nowdate(), 1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
"item_code",
"supplier_part_no",
"item_name",
"brand",
"product_bundle",
"fg_item",
"fg_item_qty",
"column_break_4",
"schedule_date",
"expected_delivery_date",
"item_group",
"section_break_5",
"description",
"col_break1",
Expand Down Expand Up @@ -58,9 +60,12 @@
"base_net_rate",
"base_net_amount",
"warehouse_and_reference",
"from_warehouse",
"warehouse",
"column_break_54",
"actual_qty",
"company_total_stock",
"references_section",
"material_request",
"material_request_item",
"sales_order",
Expand All @@ -73,8 +78,6 @@
"against_blanket_order",
"blanket_order",
"blanket_order_rate",
"item_group",
"brand",
"section_break_56",
"received_qty",
"returned_qty",
Expand Down Expand Up @@ -442,13 +445,13 @@
{
"fieldname": "warehouse_and_reference",
"fieldtype": "Section Break",
"label": "Warehouse and Reference"
"label": "Warehouse Settings"
},
{
"fieldname": "warehouse",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Warehouse",
"label": "Target Warehouse",
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
Expand Down Expand Up @@ -760,7 +763,7 @@
"allow_on_submit": 1,
"fieldname": "actual_qty",
"fieldtype": "Float",
"label": "Available Qty at Warehouse",
"label": "Available Qty at Target Warehouse",
"print_hide": 1,
"read_only": 1
},
Expand Down Expand Up @@ -868,13 +871,30 @@
"fieldtype": "Float",
"label": "Finished Good Item Qty",
"mandatory_depends_on": "eval:parent.is_subcontracted && !parent.is_old_subcontracting_flow"
},
{
"depends_on": "eval:parent.is_internal_supplier",
"fieldname": "from_warehouse",
"fieldtype": "Link",
"label": "From Warehouse",
"options": "Warehouse"
},
{
"collapsible": 1,
"fieldname": "references_section",
"fieldtype": "Section Break",
"label": "References"
},
{
"fieldname": "column_break_54",
"fieldtype": "Column Break"
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-06-17 05:29:40.602349",
"modified": "2022-09-07 11:12:38.634976",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
Expand Down
2 changes: 1 addition & 1 deletion erpnext/controllers/accounts_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def validate_party_accounts(self):
)

def validate_inter_company_reference(self):
if self.doctype not in ("Purchase Invoice", "Purchase Receipt", "Purchase Order"):
if self.doctype not in ("Purchase Invoice", "Purchase Receipt"):
return

if self.is_internal_transfer():
Expand Down
14 changes: 14 additions & 0 deletions erpnext/controllers/status_updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,20 @@ def check_overflow_with_allowance(self, item, args):

def limits_crossed_error(self, args, item, qty_or_amount):
"""Raise exception for limits crossed"""
if (
self.doctype in ["Sales Invoice", "Delivery Note"]
and qty_or_amount == "amount"
and self.is_internal_customer
):
return

elif (
self.doctype in ["Purchase Invoice", "Purchase Receipt"]
and qty_or_amount == "amount"
and self.is_internal_supplier
):
return

if qty_or_amount == "qty":
action_msg = _(
'To allow over receipt / delivery, update "Over Receipt/Delivery Allowance" in Stock Settings or the Item.'
Expand Down
Loading

0 comments on commit 4bac0da

Please sign in to comment.