Skip to content

Commit

Permalink
feat: auto create PR on SCR submission (backport #38290) (#38428)
Browse files Browse the repository at this point in the history
* feat: add field `Action on Purchase Order Submission`

(cherry picked from commit 628ea42)

# Conflicts:
#	erpnext/buying/doctype/buying_settings/buying_settings.json

* feat: auto create SCO on PO submission

(cherry picked from commit 9ec6f1e)

# Conflicts:
#	erpnext/buying/doctype/buying_settings/buying_settings.json

* feat: add field `Action on Subcontracting Receipt Submission`

(cherry picked from commit 762906f)

# Conflicts:
#	erpnext/buying/doctype/buying_settings/buying_settings.json

* chore: notify user on SCO creation

(cherry picked from commit 745e3bf)

* feat: add field `Purchase Order Item` in SCO Service Item

(cherry picked from commit 45d5cff)

* fix: hold PO item ref in SCO Service Item

(cherry picked from commit 7e4dd33)

* feat: add field `Purchase Order Item` in SCO Item

(cherry picked from commit a2ede7d)

* fix: maintain PO and PO Item ref in SCR Item

(cherry picked from commit e1cea25)

* feat: auto create PR on SCR submission

(cherry picked from commit 040cc8d)

* feat: add `Purchase Order` link in SCR connections

(cherry picked from commit ca8a5b4)

* feat: add `Subcontracting Receipt` link in PO connections

(cherry picked from commit 98cba5e)

* fix: dont show `View` button on cancelled SCR

(cherry picked from commit dd80d3b)

* fix: use checkbox instead of select field

(cherry picked from commit d366a91)

# Conflicts:
#	erpnext/buying/doctype/buying_settings/buying_settings.json

* feat: Subcontracting Receipt ref in Purchase Receipt

(cherry picked from commit d891bd7)

* feat: SCR Item ref in PR Item

(cherry picked from commit 37b3ac7)

* feat: provision to create PR from SCR

(cherry picked from commit 8052103)

* chore: PR ref in SCR connections

(cherry picked from commit 096a2c8)

* fix: map warehouses in return SCR

(cherry picked from commit 874766a)

* fix(ux): hide `Create Purchase Receipt` button for Subcontract Return

(cherry picked from commit 7145b04)

* chore: `linter`

(cherry picked from commit 857f2b5)

* test: auto create SCO on PO submit

(cherry picked from commit 68585f6)

* test: auto create PR on SCR submit

(cherry picked from commit 7b0cd03)

* fix(test): `test_auto_create_purchase_receipt`

(cherry picked from commit 3da0aa6)

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
  • Loading branch information
mergify[bot] and s-aga-r authored Nov 30, 2023
1 parent 277e81c commit 7005d51
Show file tree
Hide file tree
Showing 16 changed files with 531 additions and 200 deletions.
30 changes: 28 additions & 2 deletions erpnext/buying/doctype/buying_settings/buying_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
"subcontract",
"backflush_raw_materials_of_subcontract_based_on",
"column_break_11",
"over_transfer_allowance"
"over_transfer_allowance",
"section_break_xcug",
"auto_create_subcontracting_order",
"column_break_izrr",
"auto_create_purchase_receipt"
],
"fields": [
{
Expand Down Expand Up @@ -174,6 +178,28 @@
"fieldtype": "Float",
"label": "Blanket Order Allowance (%)"
},
{
"fieldname": "section_break_xcug",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_izrr",
"fieldtype": "Column Break"
},
{
"default": "0",
"description": "Subcontracting Order (Draft) will be auto-created on submission of Purchase Order.",
"fieldname": "auto_create_subcontracting_order",
"fieldtype": "Check",
"label": "Auto Create Subcontracting Order"
},
{
"default": "0",
"description": "Purchase Receipt (Draft) will be auto-created on submission of Subcontracting Receipt.",
"fieldname": "auto_create_purchase_receipt",
"fieldtype": "Check",
"label": "Auto Create Purchase Receipt"
},
{
"default": "Each Transaction",
"description": "How often should Project be updated of Total Purchase Cost ?",
Expand All @@ -188,7 +214,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-24 10:55:51.287327",
"modified": "2023-11-28 13:01:18.403492",
"modified_by": "Administrator",
"module": "Buying",
"name": "Buying Settings",
Expand Down
39 changes: 35 additions & 4 deletions erpnext/buying/doctype/purchase_order/purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from frappe import _, msgprint
from frappe.desk.notifications import clear_doctype_notifications
from frappe.model.mapper import get_mapped_doc
from frappe.utils import cint, cstr, flt
from frappe.utils import cint, cstr, flt, get_link_to_form

from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
unlink_inter_company_doc,
Expand Down Expand Up @@ -357,6 +357,8 @@ def on_submit(self):

update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)

self.auto_create_subcontracting_order()

def on_cancel(self):
self.ignore_linked_doctypes = ("GL Entry", "Payment Ledger Entry")
super(PurchaseOrder, self).on_cancel()
Expand Down Expand Up @@ -484,6 +486,11 @@ def can_update_items(self) -> bool:

return result

def auto_create_subcontracting_order(self):
if self.is_subcontracted and not self.is_old_subcontracting_flow:
if frappe.db.get_single_value("Buying Settings", "auto_create_subcontracting_order"):
make_subcontracting_order(self.name, save=True, notify=True)


def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor=1.0):
"""get last purchase rate for an item"""
Expand Down Expand Up @@ -686,8 +693,30 @@ def make_inter_company_sales_order(source_name, target_doc=None):


@frappe.whitelist()
def make_subcontracting_order(source_name, target_doc=None):
return get_mapped_subcontracting_order(source_name, target_doc)
def make_subcontracting_order(
source_name, target_doc=None, save=False, submit=False, notify=False
):
target_doc = get_mapped_subcontracting_order(source_name, target_doc)

if (save or submit) and frappe.has_permission(target_doc.doctype, "create"):
target_doc.save()

if submit and frappe.has_permission(target_doc.doctype, "submit", target_doc):
try:
target_doc.submit()
except Exception as e:
target_doc.add_comment("Comment", _("Submit Action Failed") + "<br><br>" + str(e))

if notify:
frappe.msgprint(
_("Subcontracting Order {0} created.").format(
get_link_to_form(target_doc.doctype, target_doc.name)
),
indicator="green",
alert=True,
)

return target_doc


def get_mapped_subcontracting_order(source_name, target_doc=None):
Expand All @@ -713,7 +742,9 @@ def get_mapped_subcontracting_order(source_name, target_doc=None):
},
"Purchase Order Item": {
"doctype": "Subcontracting Order Service Item",
"field_map": {},
"field_map": {
"name": "purchase_order_item",
},
"field_no_map": [],
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ def get_data():
"label": _("Reference"),
"items": ["Material Request", "Supplier Quotation", "Project", "Auto Repeat"],
},
{"label": _("Sub-contracting"), "items": ["Subcontracting Order", "Stock Entry"]},
{
"label": _("Sub-contracting"),
"items": ["Subcontracting Order", "Subcontracting Receipt", "Stock Entry"],
},
{"label": _("Internal"), "items": ["Sales Order"]},
],
}
32 changes: 32 additions & 0 deletions erpnext/buying/doctype/purchase_order/test_purchase_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,38 @@ def update_items(po, qty):
self.assertEqual(po.items[0].qty, 30)
self.assertEqual(po.items[0].fg_item_qty, 30)

@change_settings("Buying Settings", {"auto_create_subcontracting_order": 1})
def test_auto_create_subcontracting_order(self):
from erpnext.controllers.tests.test_subcontracting_controller import (
make_bom_for_subcontracted_items,
make_raw_materials,
make_service_items,
make_subcontracted_items,
)

make_subcontracted_items()
make_raw_materials()
make_service_items()
make_bom_for_subcontracted_items()

service_items = [
{
"warehouse": "_Test Warehouse - _TC",
"item_code": "Subcontracted Service Item 7",
"qty": 10,
"rate": 100,
"fg_item": "Subcontracted Item SA7",
"fg_item_qty": 10,
},
]
po = create_purchase_order(
rm_items=service_items,
is_subcontracted=1,
supplier_warehouse="_Test Warehouse 1 - _TC",
)

self.assertTrue(frappe.db.get_value("Subcontracting Order", {"purchase_order": po.name}))


def prepare_data_for_internal_transfer():
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
Expand Down
5 changes: 4 additions & 1 deletion erpnext/controllers/sales_and_purchase_return.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,10 @@ def set_missing_values(source, target):
if doc.get("discount_amount"):
doc.discount_amount = -1 * source.discount_amount

if doctype != "Subcontracting Receipt":
if doctype == "Subcontracting Receipt":
doc.set_warehouse = source.set_warehouse
doc.supplier_warehouse = source.supplier_warehouse
else:
doc.run_method("calculate_taxes_and_totals")

def update_item(source_doc, target_doc, source_parent):
Expand Down
22 changes: 22 additions & 0 deletions erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ frappe.ui.form.on("Purchase Receipt", {
}
});

frm.set_query("subcontracting_receipt", function() {
return {
filters: {
'docstatus': 1,
'supplier': frm.doc.supplier,
}
}
});
},
onload: function(frm) {
erpnext.queries.setup_queries(frm, "Warehouse", function() {
Expand Down Expand Up @@ -114,6 +122,20 @@ frappe.ui.form.on("Purchase Receipt", {
erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
},

subcontracting_receipt: (frm) => {
if (frm.doc.is_subcontracted === 1 && frm.doc.is_old_subcontracting_flow === 0 && frm.doc.subcontracting_receipt) {
frm.set_value('items', null);

erpnext.utils.map_current_doc({
method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_purchase_receipt',
source_name: frm.doc.subcontracting_receipt,
target_doc: frm,
freeze: true,
freeze_message: __('Mapping Purchase Receipt ...'),
});
}
},

toggle_display_account_head: function(frm) {
var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company)
frm.fields_dict["items"].grid.set_column_disp(["cost_center"], enabled);
Expand Down
11 changes: 10 additions & 1 deletion erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"supplier",
"supplier_name",
"supplier_delivery_note",
"subcontracting_receipt",
"column_break1",
"posting_date",
"posting_time",
Expand Down Expand Up @@ -1236,13 +1237,21 @@
"fieldname": "named_place",
"fieldtype": "Data",
"label": "Named Place"
},
{
"depends_on": "eval: (doc.is_subcontracted && !doc.is_old_subcontracting_flow)",
"fieldname": "subcontracting_receipt",
"fieldtype": "Link",
"label": "Subcontracting Receipt",
"options": "Subcontracting Receipt",
"search_index": 1
}
],
"icon": "fa fa-truck",
"idx": 261,
"is_submittable": 1,
"links": [],
"modified": "2023-10-01 21:00:44.556816",
"modified": "2023-11-28 13:14:15.243474",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@
"section_break_80",
"page_break",
"sales_order",
"sales_order_item"
"sales_order_item",
"subcontracting_receipt_item"
],
"fields": [
{
Expand Down Expand Up @@ -1086,12 +1087,23 @@
"print_hide": 1,
"read_only": 1,
"search_index": 1
},
{
"fieldname": "subcontracting_receipt_item",
"fieldtype": "Data",
"hidden": 1,
"label": "Subcontracting Receipt Item",
"no_copy": 1,
"print_hide": 1,
"read_only": 1,
"report_hide": 1,
"search_index": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-11-14 18:38:15.251994",
"modified": "2023-11-28 13:37:29.245204",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def populate_items_table(self):
)
or item.default_bom
)

items.append(
{
"item_code": item.item_code,
Expand All @@ -168,19 +169,21 @@ def populate_items_table(self):
"qty": si.fg_item_qty,
"stock_uom": item.stock_uom,
"bom": bom,
},
"purchase_order_item": si.purchase_order_item,
}
)
else:
frappe.throw(
_("Please select Finished Good Item for Service Item {0}").format(
si.item_name or si.item_code
)
)
else:

if items:
for item in items:
self.append("items", item)
else:
self.set_missing_values()

self.set_missing_values()

def update_status(self, status=None, update_modified=True):
if self.docstatus >= 1 and not status:
Expand Down Expand Up @@ -222,9 +225,11 @@ def make_subcontracting_receipt(source_name, target_doc=None):


def get_mapped_subcontracting_receipt(source_name, target_doc=None):
def update_item(obj, target, source_parent):
target.qty = flt(obj.qty) - flt(obj.received_qty)
target.amount = (flt(obj.qty) - flt(obj.received_qty)) * flt(obj.rate)
def update_item(source, target, source_parent):
target.purchase_order = source_parent.purchase_order
target.purchase_order_item = source.purchase_order_item
target.qty = flt(source.qty) - flt(source.received_qty)
target.amount = (flt(source.qty) - flt(source.received_qty)) * flt(source.rate)

target_doc = get_mapped_doc(
"Subcontracting Order",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"dimension_col_break",
"project",
"section_break_34",
"page_break"
"page_break",
"purchase_order_item"
],
"fields": [
{
Expand Down Expand Up @@ -332,13 +333,22 @@
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"fieldname": "purchase_order_item",
"fieldtype": "Data",
"hidden": 1,
"label": "Purchase Order Item",
"no_copy": 1,
"read_only": 1,
"search_index": 1
}
],
"idx": 1,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-11-14 18:38:37.640677",
"modified": "2023-11-23 16:56:22.182698",
"modified_by": "Administrator",
"module": "Subcontracting",
"name": "Subcontracting Order Item",
Expand Down
Loading

0 comments on commit 7005d51

Please sign in to comment.