Merge pull request #38290 from s-aga-r/FIX-36704
feat: auto create PR on SCR submission
This commit is contained in:
commit
2e8739fff7
@ -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": [
|
||||
{
|
||||
@ -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 ?",
|
||||
@ -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",
|
||||
|
@ -8,7 +8,7 @@ import frappe
|
||||
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,
|
||||
@ -357,6 +357,8 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
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()
|
||||
@ -484,6 +486,11 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
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"""
|
||||
@ -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):
|
||||
@ -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": [],
|
||||
},
|
||||
},
|
||||
|
@ -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"]},
|
||||
],
|
||||
}
|
||||
|
@ -981,6 +981,38 @@ class TestPurchaseOrder(FrappeTestCase):
|
||||
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
|
||||
|
@ -391,7 +391,10 @@ def make_return_doc(
|
||||
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):
|
||||
|
@ -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() {
|
||||
@ -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);
|
||||
|
@ -16,6 +16,7 @@
|
||||
"supplier",
|
||||
"supplier_name",
|
||||
"supplier_delivery_note",
|
||||
"subcontracting_receipt",
|
||||
"column_break1",
|
||||
"posting_date",
|
||||
"posting_time",
|
||||
@ -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",
|
||||
|
@ -127,7 +127,8 @@
|
||||
"section_break_80",
|
||||
"page_break",
|
||||
"sales_order",
|
||||
"sales_order_item"
|
||||
"sales_order_item",
|
||||
"subcontracting_receipt_item"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -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",
|
||||
|
@ -159,6 +159,7 @@ class SubcontractingOrder(SubcontractingController):
|
||||
)
|
||||
or item.default_bom
|
||||
)
|
||||
|
||||
items.append(
|
||||
{
|
||||
"item_code": item.item_code,
|
||||
@ -168,7 +169,8 @@ class SubcontractingOrder(SubcontractingController):
|
||||
"qty": si.fg_item_qty,
|
||||
"stock_uom": item.stock_uom,
|
||||
"bom": bom,
|
||||
},
|
||||
"purchase_order_item": si.purchase_order_item,
|
||||
}
|
||||
)
|
||||
else:
|
||||
frappe.throw(
|
||||
@ -176,11 +178,12 @@ class SubcontractingOrder(SubcontractingController):
|
||||
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:
|
||||
@ -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",
|
||||
|
@ -45,7 +45,8 @@
|
||||
"dimension_col_break",
|
||||
"project",
|
||||
"section_break_34",
|
||||
"page_break"
|
||||
"page_break",
|
||||
"purchase_order_item"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -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",
|
||||
|
@ -1,131 +1,141 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "hash",
|
||||
"creation": "2022-04-01 19:23:05.728354",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"item_code",
|
||||
"column_break_2",
|
||||
"item_name",
|
||||
"section_break_4",
|
||||
"qty",
|
||||
"column_break_6",
|
||||
"rate",
|
||||
"column_break_8",
|
||||
"amount",
|
||||
"section_break_10",
|
||||
"fg_item",
|
||||
"column_break_12",
|
||||
"fg_item_qty"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 2,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"options": "Item",
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.item_name",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item Name",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 1,
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Quantity",
|
||||
"print_width": "60px",
|
||||
"reqd": 1,
|
||||
"width": "60px"
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 2,
|
||||
"fetch_from": "item_code.standard_rate",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "fg_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Finished Good Item",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "fg_item_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Finished Good Item Quantity",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_8",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-04-07 11:43:43.094867",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Subcontracting",
|
||||
"name": "Subcontracting Order Service Item",
|
||||
"naming_rule": "Random",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"search_fields": "item_name",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
"actions": [],
|
||||
"autoname": "hash",
|
||||
"creation": "2022-04-01 19:23:05.728354",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"item_code",
|
||||
"column_break_2",
|
||||
"item_name",
|
||||
"section_break_4",
|
||||
"qty",
|
||||
"column_break_6",
|
||||
"rate",
|
||||
"column_break_8",
|
||||
"amount",
|
||||
"section_break_10",
|
||||
"fg_item",
|
||||
"column_break_12",
|
||||
"fg_item_qty",
|
||||
"purchase_order_item"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 2,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"options": "Item",
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "item_code.item_name",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item Name",
|
||||
"print_hide": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 1,
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Quantity",
|
||||
"print_width": "60px",
|
||||
"reqd": 1,
|
||||
"width": "60px"
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"columns": 2,
|
||||
"fetch_from": "item_code.standard_rate",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"options": "currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"in_list_view": 1,
|
||||
"label": "Amount",
|
||||
"options": "currency",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "fg_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Finished Good Item",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "fg_item_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Finished Good Item Quantity",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_4",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_8",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "purchase_order_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Purchase Order Item",
|
||||
"no_copy": 1,
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-11-23 17:05:04.561948",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Subcontracting",
|
||||
"name": "Subcontracting Order Service Item",
|
||||
"naming_rule": "Random",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"search_fields": "item_name",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
}
|
@ -11,6 +11,10 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
||||
frm.get_field('supplied_items').grid.cannot_add_rows = true;
|
||||
frm.get_field('supplied_items').grid.only_sortable();
|
||||
frm.trigger('set_queries');
|
||||
|
||||
frm.custom_make_buttons = {
|
||||
'Purchase Receipt': 'Purchase Receipt',
|
||||
}
|
||||
},
|
||||
|
||||
on_submit(frm) {
|
||||
@ -24,64 +28,75 @@ frappe.ui.form.on('Subcontracting Receipt', {
|
||||
},
|
||||
|
||||
refresh: (frm) => {
|
||||
if (frm.doc.docstatus > 0) {
|
||||
if (frm.doc.docstatus === 1) {
|
||||
frm.add_custom_button(__('Stock Ledger'), () => {
|
||||
frappe.route_options = {
|
||||
voucher_no: frm.doc.name,
|
||||
from_date: frm.doc.posting_date,
|
||||
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
||||
company: frm.doc.company,
|
||||
show_cancelled_entries: frm.doc.docstatus === 2
|
||||
}
|
||||
frappe.set_route('query-report', 'Stock Ledger');
|
||||
}, __('View'));
|
||||
frappe.route_options = {
|
||||
voucher_no: frm.doc.name,
|
||||
from_date: frm.doc.posting_date,
|
||||
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
||||
company: frm.doc.company,
|
||||
show_cancelled_entries: frm.doc.docstatus === 2
|
||||
}
|
||||
frappe.set_route('query-report', 'Stock Ledger');
|
||||
}, __('View'));
|
||||
|
||||
frm.add_custom_button(__('Accounting Ledger'), () => {
|
||||
frappe.route_options = {
|
||||
voucher_no: frm.doc.name,
|
||||
from_date: frm.doc.posting_date,
|
||||
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
||||
company: frm.doc.company,
|
||||
group_by: 'Group by Voucher (Consolidated)',
|
||||
show_cancelled_entries: frm.doc.docstatus === 2
|
||||
}
|
||||
frappe.set_route('query-report', 'General Ledger');
|
||||
}, __('View'));
|
||||
frappe.route_options = {
|
||||
voucher_no: frm.doc.name,
|
||||
from_date: frm.doc.posting_date,
|
||||
to_date: moment(frm.doc.modified).format('YYYY-MM-DD'),
|
||||
company: frm.doc.company,
|
||||
group_by: 'Group by Voucher (Consolidated)',
|
||||
show_cancelled_entries: frm.doc.docstatus === 2
|
||||
}
|
||||
frappe.set_route('query-report', 'General Ledger');
|
||||
}, __('View'));
|
||||
|
||||
if (frm.doc.is_return === 0) {
|
||||
frm.add_custom_button(__('Purchase Receipt'), () => {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_purchase_receipt',
|
||||
frm: frm,
|
||||
freeze: true,
|
||||
freeze_message: __('Creating Purchase Receipt ...')
|
||||
});
|
||||
}, __('Create'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!frm.doc.is_return && frm.doc.docstatus === 1 && frm.doc.per_returned < 100) {
|
||||
frm.add_custom_button(__('Subcontract Return'), () => {
|
||||
frappe.model.open_mapped_doc({
|
||||
method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_subcontract_return',
|
||||
frm: frm
|
||||
});
|
||||
}, __('Create'));
|
||||
frappe.model.open_mapped_doc({
|
||||
method: 'erpnext.subcontracting.doctype.subcontracting_receipt.subcontracting_receipt.make_subcontract_return',
|
||||
frm: frm
|
||||
});
|
||||
}, __('Create'));
|
||||
frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||
}
|
||||
|
||||
if (frm.doc.docstatus === 0) {
|
||||
frm.add_custom_button(__('Subcontracting Order'), () => {
|
||||
if (!frm.doc.supplier) {
|
||||
frappe.throw({
|
||||
title: __('Mandatory'),
|
||||
message: __('Please Select a Supplier')
|
||||
});
|
||||
}
|
||||
|
||||
erpnext.utils.map_current_doc({
|
||||
method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
|
||||
source_doctype: 'Subcontracting Order',
|
||||
target: frm,
|
||||
setters: {
|
||||
supplier: frm.doc.supplier,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
per_received: ['<', 100],
|
||||
company: frm.doc.company
|
||||
}
|
||||
if (!frm.doc.supplier) {
|
||||
frappe.throw({
|
||||
title: __('Mandatory'),
|
||||
message: __('Please Select a Supplier')
|
||||
});
|
||||
}, __('Get Items From'));
|
||||
}
|
||||
|
||||
erpnext.utils.map_current_doc({
|
||||
method: 'erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order.make_subcontracting_receipt',
|
||||
source_doctype: 'Subcontracting Order',
|
||||
target: frm,
|
||||
setters: {
|
||||
supplier: frm.doc.supplier,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
per_received: ['<', 100],
|
||||
company: frm.doc.company
|
||||
}
|
||||
});
|
||||
}, __('Get Items From'));
|
||||
|
||||
frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty', 'read_only', frm.doc.__onload && frm.doc.__onload.backflush_based_on === 'BOM');
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cint, flt, getdate, nowdate
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.utils import cint, flt, get_link_to_form, getdate, nowdate
|
||||
|
||||
import erpnext
|
||||
from erpnext.accounts.utils import get_account_currency
|
||||
@ -80,6 +81,7 @@ class SubcontractingReceipt(SubcontractingController):
|
||||
self.make_gl_entries()
|
||||
self.repost_future_sle_and_gle()
|
||||
self.update_status()
|
||||
self.auto_create_purchase_receipt()
|
||||
|
||||
def on_update(self):
|
||||
for table_field in ["items", "supplied_items"]:
|
||||
@ -528,9 +530,102 @@ class SubcontractingReceipt(SubcontractingController):
|
||||
+ "\n".join(warehouse_with_no_account)
|
||||
)
|
||||
|
||||
def auto_create_purchase_receipt(self):
|
||||
if frappe.db.get_single_value("Buying Settings", "auto_create_purchase_receipt"):
|
||||
make_purchase_receipt(self, save=True, notify=True)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_subcontract_return(source_name, target_doc=None):
|
||||
from erpnext.controllers.sales_and_purchase_return import make_return_doc
|
||||
|
||||
return make_return_doc("Subcontracting Receipt", source_name, target_doc)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_purchase_receipt(source_name, target_doc=None, save=False, submit=False, notify=False):
|
||||
if isinstance(source_name, str):
|
||||
source_doc = frappe.get_doc("Subcontracting Receipt", source_name)
|
||||
else:
|
||||
source_doc = source_name
|
||||
|
||||
if not source_doc.is_return:
|
||||
if not target_doc:
|
||||
target_doc = frappe.new_doc("Purchase Receipt")
|
||||
target_doc.is_subcontracted = 1
|
||||
target_doc.is_old_subcontracting_flow = 0
|
||||
|
||||
target_doc = get_mapped_doc(
|
||||
"Subcontracting Receipt",
|
||||
source_doc.name,
|
||||
{
|
||||
"Subcontracting Receipt": {
|
||||
"doctype": "Purchase Receipt",
|
||||
"field_map": {
|
||||
"posting_date": "posting_date",
|
||||
"posting_time": "posting_time",
|
||||
"name": "subcontracting_receipt",
|
||||
"supplier_warehouse": "supplier_warehouse",
|
||||
},
|
||||
"field_no_map": ["total_qty", "total"],
|
||||
},
|
||||
},
|
||||
target_doc,
|
||||
ignore_child_tables=True,
|
||||
)
|
||||
|
||||
target_doc.currency = frappe.get_cached_value("Company", target_doc.company, "default_currency")
|
||||
|
||||
po_items_details = {}
|
||||
for item in source_doc.items:
|
||||
if item.purchase_order and item.purchase_order_item:
|
||||
if item.purchase_order not in po_items_details:
|
||||
po_doc = frappe.get_doc("Purchase Order", item.purchase_order)
|
||||
po_items_details[item.purchase_order] = {po_item.name: po_item for po_item in po_doc.items}
|
||||
|
||||
if po_item := po_items_details[item.purchase_order].get(item.purchase_order_item):
|
||||
conversion_factor = flt(po_item.qty) / flt(po_item.fg_item_qty)
|
||||
item_row = {
|
||||
"item_code": po_item.item_code,
|
||||
"item_name": po_item.item_name,
|
||||
"conversion_factor": conversion_factor,
|
||||
"qty": flt(item.qty) * conversion_factor,
|
||||
"rejected_qty": flt(item.rejected_qty) * conversion_factor,
|
||||
"uom": po_item.uom,
|
||||
"rate": po_item.rate,
|
||||
"warehouse": item.warehouse,
|
||||
"rejected_warehouse": item.rejected_warehouse,
|
||||
"purchase_order": item.purchase_order,
|
||||
"purchase_order_item": item.purchase_order_item,
|
||||
"subcontracting_receipt_item": item.name,
|
||||
}
|
||||
target_doc.append("items", item_row)
|
||||
|
||||
if not target_doc.items:
|
||||
frappe.throw(
|
||||
_("Purchase Order Item reference is missing in Subcontracting Receipt {0}").format(
|
||||
source_doc.name
|
||||
)
|
||||
)
|
||||
|
||||
target_doc.set_missing_values()
|
||||
|
||||
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(
|
||||
_("Purchase Receipt {0} created.").format(
|
||||
get_link_to_form(target_doc.doctype, target_doc.name)
|
||||
),
|
||||
indicator="green",
|
||||
alert=True,
|
||||
)
|
||||
|
||||
return target_doc
|
||||
|
@ -3,17 +3,27 @@ from frappe import _
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
"fieldname": "subcontracting_receipt_no",
|
||||
"fieldname": "subcontracting_receipt",
|
||||
"non_standard_fieldnames": {
|
||||
"Subcontracting Receipt": "return_against",
|
||||
},
|
||||
"internal_links": {
|
||||
"Subcontracting Order": ["items", "subcontracting_order"],
|
||||
"Purchase Order": ["items", "purchase_order"],
|
||||
"Project": ["items", "project"],
|
||||
"Quality Inspection": ["items", "quality_inspection"],
|
||||
},
|
||||
"transactions": [
|
||||
{"label": _("Reference"), "items": ["Subcontracting Order", "Quality Inspection", "Project"]},
|
||||
{
|
||||
"label": _("Reference"),
|
||||
"items": [
|
||||
"Purchase Order",
|
||||
"Purchase Receipt",
|
||||
"Subcontracting Order",
|
||||
"Quality Inspection",
|
||||
"Project",
|
||||
],
|
||||
},
|
||||
{"label": _("Returns"), "items": ["Subcontracting Receipt"]},
|
||||
],
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
import copy
|
||||
|
||||
import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import add_days, cint, cstr, flt, nowtime, today
|
||||
|
||||
import erpnext
|
||||
@ -953,6 +953,33 @@ class TestSubcontractingReceipt(FrappeTestCase):
|
||||
|
||||
scr.submit()
|
||||
|
||||
@change_settings("Buying Settings", {"auto_create_purchase_receipt": 1})
|
||||
def test_auto_create_purchase_receipt(self):
|
||||
fg_item = "Subcontracted Item SA1"
|
||||
service_items = [
|
||||
{
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"item_code": "Subcontracted Service Item 1",
|
||||
"qty": 5,
|
||||
"rate": 100,
|
||||
"fg_item": fg_item,
|
||||
"fg_item_qty": 5,
|
||||
},
|
||||
]
|
||||
sco = get_subcontracting_order(service_items=service_items)
|
||||
rm_items = get_rm_items(sco.supplied_items)
|
||||
itemwise_details = make_stock_in_entry(rm_items=rm_items)
|
||||
make_stock_transfer_entry(
|
||||
sco_no=sco.name,
|
||||
rm_items=rm_items,
|
||||
itemwise_details=copy.deepcopy(itemwise_details),
|
||||
)
|
||||
scr = make_subcontracting_receipt(sco.name)
|
||||
scr.save()
|
||||
scr.submit()
|
||||
|
||||
self.assertTrue(frappe.db.get_value("Purchase Receipt", {"subcontracting_receipt": scr.name}))
|
||||
|
||||
|
||||
def make_return_subcontracting_receipt(**args):
|
||||
args = frappe._dict(args)
|
||||
|
@ -63,7 +63,9 @@
|
||||
"dimension_col_break",
|
||||
"project",
|
||||
"section_break_80",
|
||||
"page_break"
|
||||
"page_break",
|
||||
"purchase_order",
|
||||
"purchase_order_item"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -517,12 +519,31 @@
|
||||
"label": "Reference Name",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "purchase_order_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Purchase Order Item",
|
||||
"no_copy": 1,
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "purchase_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Purchase Order",
|
||||
"no_copy": 1,
|
||||
"options": "Purchase Order",
|
||||
"read_only": 1,
|
||||
"search_index": 1
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-11-14 18:38:26.459669",
|
||||
"modified": "2023-11-23 17:38:55.134685",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Subcontracting",
|
||||
"name": "Subcontracting Receipt Item",
|
||||
|
Loading…
x
Reference in New Issue
Block a user