Merge branch 'develop' into item-tax-update-items
This commit is contained in:
commit
baedc627ee
@ -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
|
||||||
}
|
}
|
@ -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()
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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();
|
||||||
|
@ -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")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user