Merge branch 'develop' into item-tax-update-items

This commit is contained in:
Marica 2020-09-15 11:30:22 +05:30 committed by GitHub
commit baedc627ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 17 deletions

View File

@ -1084,7 +1084,7 @@
"idx": 105, "idx": 105,
"is_submittable": 1, "is_submittable": 1,
"links": [], "links": [],
"modified": "2020-07-31 14:13:44.610190", "modified": "2020-09-14 14:36:12.418690",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Buying", "module": "Buying",
"name": "Purchase Order", "name": "Purchase Order",
@ -1135,5 +1135,6 @@
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"timeline_field": "supplier", "timeline_field": "supplier",
"title_field": "supplier" "title_field": "supplier",
"track_changes": 1
} }

View File

@ -89,7 +89,7 @@ class TestPurchaseOrder(unittest.TestCase):
frappe.db.set_value("Accounts Settings", None, "over_billing_allowance", 0) frappe.db.set_value("Accounts Settings", None, "over_billing_allowance", 0)
def test_update_child_qty_rate(self): def test_update_child(self):
mr = make_material_request(qty=10) mr = make_material_request(qty=10)
po = make_purchase_order(mr.name) po = make_purchase_order(mr.name)
po.supplier = "_Test Supplier" po.supplier = "_Test Supplier"
@ -119,7 +119,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3) self.assertEqual(get_ordered_qty(), existing_ordered_qty + 3)
def test_add_new_item_in_update_child_qty_rate(self): def test_update_child_adding_new_item(self):
po = create_purchase_order(do_not_save=1) po = create_purchase_order(do_not_save=1)
po.items[0].qty = 4 po.items[0].qty = 4
po.save() po.save()
@ -145,7 +145,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(po.status, 'To Receive and Bill') self.assertEqual(po.status, 'To Receive and Bill')
def test_remove_item_in_update_child_qty_rate(self): def test_update_child_removing_item(self):
po = create_purchase_order(do_not_save=1) po = create_purchase_order(do_not_save=1)
po.items[0].qty = 4 po.items[0].qty = 4
po.save() po.save()
@ -185,7 +185,7 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(len(po.get('items')), 1) self.assertEquals(len(po.get('items')), 1)
self.assertEqual(po.status, 'To Receive and Bill') self.assertEqual(po.status, 'To Receive and Bill')
def test_update_child_qty_rate_perm(self): def test_update_child_perm(self):
po = create_purchase_order(item_code= "_Test Item", qty=4) po = create_purchase_order(item_code= "_Test Item", qty=4)
user = 'test@example.com' user = 'test@example.com'
@ -245,6 +245,25 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(po.taxes[0].tax_amount, 60) self.assertEqual(po.taxes[0].tax_amount, 60)
self.assertEqual(po.taxes[0].total, 660) self.assertEqual(po.taxes[0].total, 660)
def test_update_child_uom_conv_factor_change(self):
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
total_reqd_qty = sum([d.get("required_qty") for d in po.as_dict().get("supplied_items")])
trans_item = json.dumps([{
'item_code': po.get("items")[0].item_code,
'rate': po.get("items")[0].rate,
'qty': po.get("items")[0].qty,
'uom': "_Test UOM 1",
'conversion_factor': 2,
'docname': po.get("items")[0].name
}])
update_child_qty_rate('Purchase Order', trans_item, po.name)
po.reload()
total_reqd_qty_after_change = sum([d.get("required_qty") for d in po.as_dict().get("supplied_items")])
self.assertEqual(total_reqd_qty_after_change, 2 * total_reqd_qty)
def test_update_qty(self): def test_update_qty(self):
po = create_purchase_order() po = create_purchase_order()

View File

@ -1181,9 +1181,9 @@ def set_sales_order_defaults(parent_doctype, parent_doctype_name, child_docname,
child_item.item_name = item.item_name child_item.item_name = item.item_name
child_item.description = item.description child_item.description = item.description
child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date child_item.delivery_date = trans_item.get('delivery_date') or p_doc.delivery_date
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0 child_item.uom = trans_item.get("uom") or item.stock_uom
child_item.uom = item.stock_uom conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
set_child_tax_template_and_map(item, child_item, p_doc) child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True) child_item.warehouse = get_item_warehouse(item, p_doc, overwrite_warehouse=True)
if not child_item.warehouse: if not child_item.warehouse:
frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.") frappe.throw(_("Cannot find {} for item {}. Please set the same in Item Master or Stock Settings.")
@ -1202,8 +1202,9 @@ def set_purchase_order_defaults(parent_doctype, parent_doctype_name, child_docna
child_item.item_name = item.item_name child_item.item_name = item.item_name
child_item.description = item.description child_item.description = item.description
child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date child_item.schedule_date = trans_item.get('schedule_date') or p_doc.schedule_date
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or get_conversion_factor(item.item_code, item.stock_uom).get("conversion_factor") or 1.0 child_item.uom = trans_item.get("uom") or item.stock_uom
child_item.uom = item.stock_uom conversion_factor = flt(get_conversion_factor(item.item_code, child_item.uom).get("conversion_factor"))
child_item.conversion_factor = flt(trans_item.get('conversion_factor')) or conversion_factor
child_item.base_rate = 1 # Initiallize value will update in parent validation child_item.base_rate = 1 # Initiallize value will update in parent validation
child_item.base_amount = 1 # Initiallize value will update in parent validation child_item.base_amount = 1 # Initiallize value will update in parent validation
set_child_tax_template_and_map(item, child_item, p_doc) set_child_tax_template_and_map(item, child_item, p_doc)
@ -1296,6 +1297,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate")) prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate"))
prev_qty, new_qty = flt(child_item.get("qty")), flt(d.get("qty")) prev_qty, new_qty = flt(child_item.get("qty")), flt(d.get("qty"))
prev_con_fac, new_con_fac = flt(child_item.get("conversion_factor")), flt(d.get("conversion_factor")) prev_con_fac, new_con_fac = flt(child_item.get("conversion_factor")), flt(d.get("conversion_factor"))
prev_uom, new_uom = child_item.get("uom"), d.get("uom")
if parent_doctype == 'Sales Order': if parent_doctype == 'Sales Order':
prev_date, new_date = child_item.get("delivery_date"), d.get("delivery_date") prev_date, new_date = child_item.get("delivery_date"), d.get("delivery_date")
@ -1304,9 +1306,10 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
rate_unchanged = prev_rate == new_rate rate_unchanged = prev_rate == new_rate
qty_unchanged = prev_qty == new_qty qty_unchanged = prev_qty == new_qty
uom_unchanged = prev_uom == new_uom
conversion_factor_unchanged = prev_con_fac == new_con_fac conversion_factor_unchanged = prev_con_fac == new_con_fac
date_unchanged = prev_date == new_date if prev_date and new_date else False # in case of delivery note etc date_unchanged = prev_date == new_date if prev_date and new_date else False # in case of delivery note etc
if rate_unchanged and qty_unchanged and conversion_factor_unchanged and date_unchanged: if rate_unchanged and qty_unchanged and conversion_factor_unchanged and uom_unchanged and date_unchanged:
continue continue
validate_quantity(child_item, d) validate_quantity(child_item, d)
@ -1325,6 +1328,11 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
child_item.conversion_factor = 1 child_item.conversion_factor = 1
else: else:
child_item.conversion_factor = flt(d.get('conversion_factor')) child_item.conversion_factor = flt(d.get('conversion_factor'))
if d.get("uom"):
child_item.uom = d.get("uom")
conversion_factor = flt(get_conversion_factor(child_item.item_code, child_item.uom).get("conversion_factor"))
child_item.conversion_factor = flt(d.get('conversion_factor')) or conversion_factor
if d.get("delivery_date") and parent_doctype == 'Sales Order': if d.get("delivery_date") and parent_doctype == 'Sales Order':
child_item.delivery_date = d.get('delivery_date') child_item.delivery_date = d.get('delivery_date')
@ -1391,6 +1399,8 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
parent.update_receiving_percentage() parent.update_receiving_percentage()
if parent.is_subcontracted == "Yes": if parent.is_subcontracted == "Yes":
parent.update_reserved_qty_for_subcontract() parent.update_reserved_qty_for_subcontract()
parent.create_raw_materials_supplied("supplied_items")
parent.save()
else: else:
parent.update_reserved_qty() parent.update_reserved_qty()
parent.update_project() parent.update_project()

View File

@ -466,6 +466,33 @@ erpnext.utils.update_child_items = function(opts) {
read_only: 0, read_only: 0,
disabled: 0, disabled: 0,
label: __('Item Code') label: __('Item Code')
}, {
fieldtype:'Link',
fieldname:'uom',
options: 'UOM',
read_only: 0,
label: __('UOM'),
reqd: 1,
onchange: function () {
frappe.call({
method: "erpnext.stock.get_item_details.get_conversion_factor",
args: { item_code: this.doc.item_code, uom: this.value },
callback: r => {
if(!r.exc) {
if (this.doc.conversion_factor == r.message.conversion_factor) return;
const docname = this.doc.docname;
dialog.fields_dict.trans_items.df.data.some(doc => {
if (doc.docname == docname) {
doc.conversion_factor = r.message.conversion_factor;
dialog.fields_dict.trans_items.grid.refresh();
return true;
}
})
}
}
});
}
}, { }, {
fieldtype:'Float', fieldtype:'Float',
fieldname:"qty", fieldname:"qty",
@ -546,6 +573,7 @@ erpnext.utils.update_child_items = function(opts) {
"conversion_factor": d.conversion_factor, "conversion_factor": d.conversion_factor,
"qty": d.qty, "qty": d.qty,
"rate": d.rate, "rate": d.rate,
"uom": d.uom
}); });
this.data = dialog.fields_dict.trans_items.df.data; this.data = dialog.fields_dict.trans_items.df.data;
dialog.fields_dict.trans_items.grid.refresh(); dialog.fields_dict.trans_items.grid.refresh();

View File

@ -318,7 +318,7 @@ class TestSalesOrder(unittest.TestCase):
self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"), self.assertEqual(get_reserved_qty("_Test Item Home Desktop 100"),
existing_reserved_qty_item2 + 20) existing_reserved_qty_item2 + 20)
def test_add_new_item_in_update_child_qty_rate(self): def test_update_child_adding_new_item(self):
so = make_sales_order(item_code= "_Test Item", qty=4) so = make_sales_order(item_code= "_Test Item", qty=4)
create_dn_against_so(so.name, 4) create_dn_against_so(so.name, 4)
make_sales_invoice(so.name) make_sales_invoice(so.name)
@ -338,7 +338,7 @@ class TestSalesOrder(unittest.TestCase):
self.assertEqual(so.get("items")[-1].amount, 1400) self.assertEqual(so.get("items")[-1].amount, 1400)
self.assertEqual(so.status, 'To Deliver and Bill') self.assertEqual(so.status, 'To Deliver and Bill')
def test_remove_item_in_update_child_qty_rate(self): def test_update_child_removing_item(self):
so = make_sales_order(**{ so = make_sales_order(**{
"item_list": [{ "item_list": [{
"item_code": '_Test Item', "item_code": '_Test Item',
@ -381,7 +381,7 @@ class TestSalesOrder(unittest.TestCase):
self.assertEqual(so.status, 'To Deliver and Bill') self.assertEqual(so.status, 'To Deliver and Bill')
def test_update_child_qty_rate(self): def test_update_child(self):
so = make_sales_order(item_code= "_Test Item", qty=4) so = make_sales_order(item_code= "_Test Item", qty=4)
create_dn_against_so(so.name, 4) create_dn_against_so(so.name, 4)
make_sales_invoice(so.name) make_sales_invoice(so.name)
@ -402,7 +402,7 @@ class TestSalesOrder(unittest.TestCase):
trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 2, 'docname': so.items[0].name}]) trans_item = json.dumps([{'item_code' : '_Test Item', 'rate' : 200, 'qty' : 2, 'docname': so.items[0].name}])
self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Sales Order', trans_item, so.name) self.assertRaises(frappe.ValidationError, update_child_qty_rate,'Sales Order', trans_item, so.name)
def test_update_child_qty_rate_perm(self): def test_update_child_perm(self):
so = make_sales_order(item_code= "_Test Item", qty=4) so = make_sales_order(item_code= "_Test Item", qty=4)
user = 'test@example.com' user = 'test@example.com'
@ -454,7 +454,7 @@ class TestSalesOrder(unittest.TestCase):
workflow.is_active = 0 workflow.is_active = 0
workflow.save() workflow.save()
def test_update_child_qty_rate_product_bundle(self): def test_update_child_product_bundle(self):
# test Update Items with product bundle # test Update Items with product bundle
if not frappe.db.exists("Item", "_Product Bundle Item"): if not frappe.db.exists("Item", "_Product Bundle Item"):
bundle_item = make_item("_Product Bundle Item", {"is_stock_item": 0}) bundle_item = make_item("_Product Bundle Item", {"is_stock_item": 0})
@ -474,6 +474,20 @@ class TestSalesOrder(unittest.TestCase):
so.reload() so.reload()
self.assertEqual(so.packed_items[0].qty, 4) self.assertEqual(so.packed_items[0].qty, 4)
# test uom and conversion factor change
update_uom_conv_factor = json.dumps([{
'item_code': so.get("items")[0].item_code,
'rate': so.get("items")[0].rate,
'qty': so.get("items")[0].qty,
'uom': "_Test UOM 1",
'conversion_factor': 2,
'docname': so.get("items")[0].name
}])
update_child_qty_rate('Sales Order', update_uom_conv_factor, so.name)
so.reload()
self.assertEqual(so.packed_items[0].qty, 8)
def test_warehouse_user(self): def test_warehouse_user(self):
frappe.permissions.add_user_permission("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com") frappe.permissions.add_user_permission("Warehouse", "_Test Warehouse 1 - _TC", "test@example.com")
frappe.permissions.add_user_permission("Warehouse", "_Test Warehouse 2 - _TC1", "test2@example.com") frappe.permissions.add_user_permission("Warehouse", "_Test Warehouse 2 - _TC1", "test2@example.com")