Update Items in Submit state can add new row (#15644)
* Update Items in Sumbit state can add new row In Sales Order and Purchase Order when docstatus is submitted user can use Update Item btn to add new child Items * Remove unused code line * Remove blocking db save thread line * Remove Company as not standard Field in Purchase Order Item * Minor indentation fix * Add Unit Test, add new row in update_child_qty_rate * Codacy fix
This commit is contained in:
parent
7c2a5bddb1
commit
3d82b74ea4
@ -42,6 +42,7 @@ frappe.ui.form.on("Purchase Order", {
|
||||
frm: frm,
|
||||
child_docname: "items",
|
||||
child_doctype: "Purchase Order Detail",
|
||||
cannot_add_row: false,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import frappe, erpnext
|
||||
import json
|
||||
from frappe import _, throw
|
||||
from frappe.utils import today, flt, cint, fmt_money, formatdate, getdate, add_days, add_months, get_last_day, nowdate
|
||||
from erpnext.stock.get_item_details import get_conversion_factor
|
||||
from erpnext.setup.utils import get_exchange_rate
|
||||
from erpnext.accounts.utils import get_fiscal_years, validate_fiscal_year, get_account_currency
|
||||
from erpnext.utilities.transaction_base import TransactionBase
|
||||
@ -1067,24 +1068,68 @@ def get_supplier_block_status(party_name):
|
||||
}
|
||||
return info
|
||||
|
||||
def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
|
||||
"""
|
||||
Returns a Sales Order Item child item containing the default values
|
||||
"""
|
||||
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||
child_item = frappe.new_doc('Sales Order Item', p_doctype, child_docname)
|
||||
item = frappe.get_doc("Item", item_code)
|
||||
child_item.item_code = item.item_code
|
||||
child_item.item_name = item.item_name
|
||||
child_item.description = item.description
|
||||
child_item.reqd_by_date = p_doctype.delivery_date
|
||||
child_item.uom = item.stock_uom
|
||||
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||
return child_item
|
||||
|
||||
|
||||
def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, item_code):
|
||||
"""
|
||||
Returns a Purchase Order Item child item containing the default values
|
||||
"""
|
||||
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||
child_item = frappe.new_doc('Purchase Order Item', p_doctype, child_docname)
|
||||
item = frappe.get_doc("Item", item_code)
|
||||
child_item.item_code = item.item_code
|
||||
child_item.item_name = item.item_name
|
||||
child_item.description = item.description
|
||||
child_item.schedule_date = p_doctype.schedule_date
|
||||
child_item.uom = item.stock_uom
|
||||
child_item.conversion_factor = get_conversion_factor(item_code, item.stock_uom).get("conversion_factor") or 1.0
|
||||
child_item.base_rate = 1 # Initiallize value will update in parent validation
|
||||
child_item.base_amount = 1 # Initiallize value will update in parent validation
|
||||
return child_item
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name):
|
||||
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
|
||||
data = json.loads(trans_items)
|
||||
for d in data:
|
||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||
child_item.qty = flt(d.get("qty"))
|
||||
|
||||
for d in data:
|
||||
new_child_flag = False
|
||||
if not d.get("docname"):
|
||||
new_child_flag = True
|
||||
if parent_doctype == "Sales Order":
|
||||
child_item = set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
|
||||
if parent_doctype == "Purchase Order":
|
||||
child_item = set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docname, d.get("item_code"))
|
||||
else:
|
||||
child_item = frappe.get_doc(parent_doctype + ' Item', d.get("docname"))
|
||||
|
||||
child_item.qty = flt(d.get("qty"))
|
||||
if child_item.billed_amt > (flt(d.get("rate")) * flt(d.get("qty"))):
|
||||
frappe.throw(_("Row #{0}: Cannot set Rate if amount is greater than billed amount for Item {1}.")
|
||||
.format(child_item.idx, child_item.item_code))
|
||||
else:
|
||||
child_item.rate = flt(d.get("rate"))
|
||||
child_item.flags.ignore_validate_update_after_submit = True
|
||||
child_item.save()
|
||||
if new_child_flag:
|
||||
child_item.insert()
|
||||
else:
|
||||
child_item.save()
|
||||
|
||||
p_doctype = frappe.get_doc(parent_doctype, parent_doctype_name)
|
||||
|
||||
p_doctype.flags.ignore_validate_update_after_submit = True
|
||||
p_doctype.set_qty_as_per_stock_uom()
|
||||
p_doctype.calculate_taxes_and_totals()
|
||||
|
@ -406,15 +406,19 @@ erpnext.utils.select_alternate_items = function(opts) {
|
||||
|
||||
erpnext.utils.update_child_items = function(opts) {
|
||||
const frm = opts.frm;
|
||||
|
||||
const cannot_add_row = (typeof opts.cannot_add_row === 'undefined') ? true : opts.cannot_add_row;
|
||||
const child_docname = (typeof opts.cannot_add_row === 'undefined') ? "items" : opts.child_docname;
|
||||
this.data = [];
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: __("Update Items"),
|
||||
fields: [
|
||||
{fieldtype:'Section Break', label: __('Items')},
|
||||
{
|
||||
fieldname: "trans_items", fieldtype: "Table", cannot_add_rows: true,
|
||||
in_place_edit: true, data: this.data,
|
||||
fieldname: "trans_items",
|
||||
fieldtype: "Table",
|
||||
cannot_add_rows: cannot_add_row,
|
||||
in_place_edit: true,
|
||||
data: this.data,
|
||||
get_data: () => {
|
||||
return this.data;
|
||||
},
|
||||
@ -450,10 +454,12 @@ erpnext.utils.update_child_items = function(opts) {
|
||||
const trans_items = this.get_values()["trans_items"];
|
||||
frappe.call({
|
||||
method: 'erpnext.controllers.accounts_controller.update_child_qty_rate',
|
||||
freeze: true,
|
||||
args: {
|
||||
'parent_doctype': frm.doc.doctype,
|
||||
'trans_items': trans_items,
|
||||
'parent_doctype_name': frm.doc.name
|
||||
'parent_doctype_name': frm.doc.name,
|
||||
'child_docname': child_docname
|
||||
},
|
||||
callback: function() {
|
||||
frm.reload_doc();
|
||||
|
@ -25,6 +25,7 @@ frappe.ui.form.on("Sales Order", {
|
||||
frm: frm,
|
||||
child_docname: "items",
|
||||
child_doctype: "Sales Order Detail",
|
||||
cannot_add_row: false,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ from erpnext.selling.doctype.sales_order.sales_order import make_work_orders
|
||||
from erpnext.controllers.accounts_controller import update_child_qty_rate
|
||||
import json
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_raw_material_request
|
||||
|
||||
|
||||
class TestSalesOrder(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
frappe.set_user("Administrator")
|
||||
@ -268,6 +270,22 @@ class TestSalesOrder(unittest.TestCase):
|
||||
self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"),
|
||||
existing_reserved_qty_item2 + 20)
|
||||
|
||||
def test_add_new_item_in_update_child_qty_rate(self):
|
||||
so = make_sales_order(item_code= "_Test Item", qty=4)
|
||||
create_dn_against_so(so.name, 4)
|
||||
make_sales_invoice(so.name)
|
||||
|
||||
trans_item = json.dumps([{'item_code' : '_Test Item 2', 'rate' : 200, 'qty' : 7}])
|
||||
update_child_qty_rate('Sales Order', trans_item, so.name)
|
||||
|
||||
so.reload()
|
||||
self.assertEqual(so.get("items")[-1].item_code, '_Test Item 2')
|
||||
self.assertEqual(so.get("items")[-1].rate, 200)
|
||||
self.assertEqual(so.get("items")[-1].qty, 7)
|
||||
self.assertEqual(so.get("items")[-1].amount, 1400)
|
||||
self.assertEqual(so.status, 'To Deliver and Bill')
|
||||
|
||||
|
||||
def test_update_child_qty_rate(self):
|
||||
so = make_sales_order(item_code= "_Test Item", qty=4)
|
||||
create_dn_against_so(so.name, 4)
|
||||
@ -760,7 +778,7 @@ def make_sales_order(**args):
|
||||
})
|
||||
|
||||
so.delivery_date = add_days(so.transaction_date, 10)
|
||||
|
||||
|
||||
if not args.do_not_save:
|
||||
so.insert()
|
||||
if not args.do_not_submit:
|
||||
|
Loading…
x
Reference in New Issue
Block a user