Test cases for sales return

This commit is contained in:
Nabin Hait 2015-07-20 18:39:44 +05:30
parent 6b25708b7a
commit 246ed3f122
7 changed files with 177 additions and 274 deletions

View File

@ -493,7 +493,7 @@ class SalesInvoice(SellingController):
"against": self.against_income_account,
"debit": self.base_grand_total,
"remarks": self.remarks,
"against_voucher": self.against_invoice if cint(self.is_return) else self.name,
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype
})
)
@ -541,7 +541,7 @@ class SalesInvoice(SellingController):
"against": self.cash_bank_account,
"credit": self.paid_amount,
"remarks": self.remarks,
"against_voucher": self.against_invoice if cint(self.is_return) else self.name,
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype,
})
)
@ -565,7 +565,7 @@ class SalesInvoice(SellingController):
"against": self.write_off_account,
"credit": self.write_off_amount,
"remarks": self.remarks,
"against_voucher": self.against_invoice if cint(self.is_return) else self.name,
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype,
})
)

View File

@ -4,11 +4,10 @@ from __future__ import unicode_literals
import frappe
import unittest, copy
import time
from frappe.utils import nowdate, add_days
from erpnext.accounts.utils import get_stock_and_account_difference
from frappe.utils import nowdate, add_days, flt
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
class TestSalesInvoice(unittest.TestCase):
@ -772,6 +771,53 @@ class TestSalesInvoice(unittest.TestCase):
si1 = create_sales_invoice(posting_date="2015-07-05")
self.assertEqual(si1.due_date, "2015-08-31")
def test_return_sales_invoice(self):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
actual_qty_0 = get_qty_after_transaction()
si = create_sales_invoice(qty=5, rate=500, update_stock=1)
actual_qty_1 = get_qty_after_transaction()
self.assertEquals(actual_qty_0 - 5, actual_qty_1)
# outgoing_rate
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si.name}, "stock_value_difference") / 5
# return entry
si1 = create_sales_invoice(is_return=1, return_against=si.name, qty=-2, rate=500, update_stock=1)
actual_qty_2 = get_qty_after_transaction()
self.assertEquals(actual_qty_1 + 2, actual_qty_2)
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Sales Invoice", "voucher_no": si1.name},
["incoming_rate", "stock_value_difference"])
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
# Check gl entry
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "_Test Warehouse - _TC"}, "debit")
self.assertEquals(gle_warehouse_amount, stock_value_difference)
party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice",
"voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit")
self.assertEqual(party_credited, 1000)
# Check outstanding amount
self.assertFalse(si1.outstanding_amount)
self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500)
set_perpetual_inventory(0)
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
@ -784,6 +830,10 @@ def create_sales_invoice(**args):
si.debit_to = args.debit_to or "Debtors - _TC"
si.update_stock = args.update_stock
si.is_pos = args.is_pos
si.is_return = args.is_return
si.return_against = args.return_against
si.currency="INR"
si.conversion_rate = 1
si.append("items", {
"item_code": args.item or args.item_code or "_Test Item",

View File

@ -86,8 +86,7 @@ class AccountsController(TransactionBase):
ref_posting_datetime = "%s %s" % (ref_doc.posting_date, ref_doc.get("posting_time") or "00:00:00")
if get_datetime(return_posting_datetime) < get_datetime(ref_posting_datetime):
frappe.throw(_("Posting timestamp must be after {0}")
.format(datetime_in_user_format(ref_posting_datetime)))
frappe.throw(_("Posting timestamp must be after {0}").format(format_datetime(ref_posting_datetime)))
# validate same exchange rate
if self.conversion_rate != ref_doc.conversion_rate:
@ -105,6 +104,11 @@ class AccountsController(TransactionBase):
for d in frappe.db.sql("""select item_code, sum(qty) as qty, rate from `tab{0} Item`
where parent = %s group by item_code""".format(self.doctype), self.return_against, as_dict=1):
valid_items.setdefault(d.item_code, d)
if self.doctype in ("Delivery Note", "Sales Invoice"):
for d in frappe.db.sql("""select item_code, sum(qty) as qty from `tabPacked Item`
where parent = %s group by item_code""".format(self.doctype), self.return_against, as_dict=1):
valid_items.setdefault(d.item_code, d)
already_returned_items = self.get_already_returned_items()
@ -124,7 +128,7 @@ class AccountsController(TransactionBase):
elif abs(d.qty) > max_return_qty:
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
.format(d.idx, ref.qty, d.item_code), StockOverReturnError)
elif flt(d.rate) != ref.rate:
elif ref.rate and flt(d.rate) != ref.rate:
frappe.throw(_("Row # {0}: Rate must be same as {1} {2}")
.format(d.idx, self.doctype, self.return_against))

View File

@ -257,7 +257,7 @@ class DeliveryNote(SellingController):
sl_entries.append(self.get_sl_entries(d, {
"actual_qty": -1*flt(d['qty']),
incoming_rate: incoming_rate
"incoming_rate": incoming_rate
}))
self.make_sl_entries(sl_entries)

View File

@ -13,8 +13,10 @@ from erpnext.accounts.utils import get_balance_on
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
import get_gl_entries, set_perpetual_inventory
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, make_serialized_item
from erpnext.stock.doctype.stock_entry.test_stock_entry \
import make_stock_entry, make_serialized_item, get_qty_after_transaction
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, SerialNoStatusError
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
class TestDeliveryNote(unittest.TestCase):
def test_over_billing_against_dn(self):
@ -177,7 +179,113 @@ class TestDeliveryNote(unittest.TestCase):
def check_serial_no_values(self, serial_no, field_values):
for field, value in field_values.items():
self.assertEquals(cstr(frappe.db.get_value("Serial No", serial_no, field)), value)
def test_sales_return_for_non_bundled_items(self):
set_perpetual_inventory()
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
actual_qty_0 = get_qty_after_transaction()
dn = create_delivery_note(qty=5, rate=500)
actual_qty_1 = get_qty_after_transaction()
self.assertEquals(actual_qty_0 - 5, actual_qty_1)
# outgoing_rate
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note",
"voucher_no": dn.name}, "stock_value_difference") / 5
# return entry
dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-2, rate=500)
actual_qty_2 = get_qty_after_transaction()
self.assertEquals(actual_qty_1 + 2, actual_qty_2)
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Delivery Note", "voucher_no": dn1.name},
["incoming_rate", "stock_value_difference"])
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Delivery Note",
"voucher_no": dn1.name, "account": "_Test Warehouse - _TC"}, "debit")
self.assertEquals(gle_warehouse_amount, stock_value_difference)
set_perpetual_inventory(0)
def test_return_single_item_from_bundled_items(self):
set_perpetual_inventory()
create_stock_reconciliation(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, rate=100)
create_stock_reconciliation(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
qty=50, rate=100)
dn = create_delivery_note(item_code="_Test Product Bundle Item", qty=5, rate=500)
# Qty after delivery
actual_qty_1 = get_qty_after_transaction()
self.assertEquals(actual_qty_1, 25)
# outgoing_rate
outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note",
"voucher_no": dn.name, "item_code": "_Test Item"}, "stock_value_difference") / 25
# return 'test item' from packed items
dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-10, rate=500)
# qty after return
actual_qty_2 = get_qty_after_transaction()
self.assertEquals(actual_qty_2, 35)
# Check incoming rate for return entry
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Delivery Note", "voucher_no": dn1.name},
["incoming_rate", "stock_value_difference"])
self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3)))
# Check gl entry for warehouse
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Delivery Note",
"voucher_no": dn1.name, "account": "_Test Warehouse - _TC"}, "debit")
self.assertEquals(gle_warehouse_amount, stock_value_difference)
set_perpetual_inventory(0)
def test_return_entire_bundled_items(self):
set_perpetual_inventory()
create_stock_reconciliation(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, rate=100)
create_stock_reconciliation(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
qty=50, rate=100)
dn = create_delivery_note(item_code="_Test Product Bundle Item", qty=5, rate=500)
# return bundled item
dn1 = create_delivery_note(item_code='_Test Product Bundle Item', is_return=1,
return_against=dn.name, qty=-2, rate=500)
# qty after return
actual_qty = get_qty_after_transaction()
self.assertEquals(actual_qty, 35)
# Check incoming rate for return entry
incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Delivery Note", "voucher_no": dn1.name},
["incoming_rate", "stock_value_difference"])
self.assertEquals(incoming_rate, 100)
# Check gl entry for warehouse
gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Delivery Note",
"voucher_no": dn1.name, "account": "_Test Warehouse - _TC"}, "debit")
self.assertEquals(gle_warehouse_amount, 1400)
set_perpetual_inventory(0)
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")
@ -190,6 +298,8 @@ def create_delivery_note(**args):
dn.company = args.company or "_Test Company"
dn.customer = args.customer or "_Test Customer"
dn.currency = args.currency or "INR"
dn.is_return = args.is_return
dn.return_against = args.return_against
dn.append("items", {
"item_code": args.item or args.item_code or "_Test Item",

View File

@ -13,7 +13,6 @@ from erpnext.stock.get_item_details import get_available_qty, get_default_cost_c
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
from erpnext.accounts.utils import validate_fiscal_year
class NotUpdateStockError(frappe.ValidationError): pass
class IncorrectValuationRateError(frappe.ValidationError): pass
class DuplicateEntryForProductionOrderError(frappe.ValidationError): pass
class OperationsNotCompleteError(frappe.ValidationError): pass

View File

@ -4,15 +4,12 @@
from __future__ import unicode_literals
import frappe, unittest
import frappe.defaults
from frappe.utils import flt, nowdate, nowtime, getdate
from frappe.utils import flt, nowdate, nowtime
from erpnext.stock.doctype.serial_no.serial_no import *
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt \
import set_perpetual_inventory, make_purchase_receipt
import set_perpetual_inventory
from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
from erpnext.stock.stock_ledger import get_previous_sle
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order, create_dn_against_so
from erpnext.stock.doctype.stock_entry.stock_entry import NotUpdateStockError
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
def get_sle(**args):
@ -303,263 +300,6 @@ class TestStockEntry(unittest.TestCase):
self.assertEquals(expected_gl_entries[i][1], gle[1])
self.assertEquals(expected_gl_entries[i][2], gle[2])
# def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty):
# from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
#
# si = create_sales_invoice(item_code=item_code, qty=delivered_qty)
#
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=returned_qty,
# purpose="Sales Return", sales_invoice_no=si.name, do_not_save=True)
# self.assertRaises(NotUpdateStockError, se.insert)
#
# make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=200, incoming_rate=100)
#
# # check currency available qty in bin
# actual_qty_0 = get_qty_after_transaction()
#
# # insert a pos invoice with update stock
# si = create_sales_invoice(update_stock=1, item_code=item_code, qty=5)
#
# # check available bin qty after invoice submission
# actual_qty_1 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
#
# # check if item is validated
# se = make_stock_entry(item_code="_Test Item Home Desktop 200", target="_Test Warehouse - _TC",
# qty=returned_qty, purpose="Sales Return", sales_invoice_no=si.name, do_not_save=True)
#
# self.assertRaises(frappe.DoesNotExistError, se.insert)
#
# # try again
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
# qty=returned_qty, purpose="Sales Return", sales_invoice_no=si.name)
#
# # check if available qty is increased
# actual_qty_2 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
#
# return se
#
# def test_sales_invoice_return_of_non_packing_item(self):
# self._test_sales_invoice_return("_Test Item", 5, 2)
#
# def test_sales_invoice_return_of_packing_item(self):
# self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
#
# def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty):
# from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
#
# from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
#
# make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
#
# actual_qty_0 = get_qty_after_transaction()
# # make a delivery note based on this invoice
# dn = create_delivery_note(item_code="_Test Item",
# warehouse="_Test Warehouse - _TC", qty=delivered_qty)
#
# actual_qty_1 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
#
# si = make_sales_invoice(dn.name)
# si.insert()
# si.submit()
#
# # insert and submit stock entry for sales return
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
# qty=returned_qty, purpose="Sales Return", delivery_note_no=dn.name)
#
# actual_qty_2 = get_qty_after_transaction()
# self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
#
# return se
#
# def test_delivery_note_return_of_non_packing_item(self):
# self._test_delivery_note_return("_Test Item", 5, 2)
#
# def test_delivery_note_return_of_packing_item(self):
# self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
#
# def _test_sales_return_jv(self, se):
# jv = make_return_jv(se.name)
#
# self.assertEqual(len(jv.get("accounts")), 2)
# self.assertEqual(jv.get("voucher_type"), "Credit Note")
# self.assertEqual(jv.get("posting_date"), getdate(se.posting_date))
# self.assertEqual(jv.get("accounts")[0].get("account"), "Debtors - _TC")
# self.assertEqual(jv.get("accounts")[0].get("party_type"), "Customer")
# self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Customer")
# self.assertEqual(jv.get("accounts")[1].get("account"), "Sales - _TC")
#
# def test_make_return_jv_for_sales_invoice_non_packing_item(self):
# se = self._test_sales_invoice_return("_Test Item", 5, 2)
# self._test_sales_return_jv(se)
#
# def test_make_return_jv_for_sales_invoice_packing_item(self):
# se = self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
# self._test_sales_return_jv(se)
#
# def test_make_return_jv_for_delivery_note_non_packing_item(self):
# se = self._test_delivery_note_return("_Test Item", 5, 2)
# self._test_sales_return_jv(se)
#
# se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2)
# self._test_sales_return_jv(se)
#
# def test_make_return_jv_for_delivery_note_packing_item(self):
# se = self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
# self._test_sales_return_jv(se)
#
# se = self._test_delivery_note_return_against_sales_order("_Test Product Bundle Item", 25, 20)
# self._test_sales_return_jv(se)
#
# def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty):
# from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
#
# actual_qty_0 = get_qty_after_transaction()
#
# so = make_sales_order(qty=50)
#
# dn = create_dn_against_so(so.name, delivered_qty)
#
# actual_qty_1 = get_qty_after_transaction()
# self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
#
# si = make_sales_invoice(so.name)
# si.insert()
# si.submit()
#
# # insert and submit stock entry for sales return
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
# qty=returned_qty, purpose="Sales Return", delivery_note_no=dn.name)
#
# actual_qty_2 = get_qty_after_transaction()
# self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
#
# return se
#
# def test_purchase_receipt_return(self):
# actual_qty_0 = get_qty_after_transaction()
#
# # submit purchase receipt
# pr = make_purchase_receipt(item_code="_Test Item", warehouse="_Test Warehouse - _TC", qty=5)
#
# actual_qty_1 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_0 + 5, actual_qty_1)
#
# pi_doc = make_purchase_invoice(pr.name)
#
# pi = frappe.get_doc(pi_doc)
# pi.posting_date = pr.posting_date
# pi.credit_to = "_Test Payable - _TC"
# for d in pi.get("items"):
# d.expense_account = "_Test Account Cost for Goods Sold - _TC"
# d.cost_center = "_Test Cost Center - _TC"
#
# for d in pi.get("taxes"):
# d.cost_center = "_Test Cost Center - _TC"
#
# pi.insert()
# pi.submit()
#
# # submit purchase return
# se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
# qty=5, purpose="Purchase Return", purchase_receipt_no=pr.name)
#
# actual_qty_2 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_1 - 5, actual_qty_2)
#
# return se, pr.name
#
# def test_over_stock_return(self):
# from erpnext.stock.doctype.stock_entry.stock_entry import StockOverReturnError
#
# # out of 10, 5 gets returned
# prev_se, pr_docname = self.test_purchase_receipt_return()
#
# se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
# qty=6, purpose="Purchase Return", purchase_receipt_no=pr_docname, do_not_save=True)
#
# self.assertRaises(StockOverReturnError, se.insert)
#
# def _test_purchase_return_jv(self, se):
# jv = make_return_jv(se.name)
#
# self.assertEqual(len(jv.get("accounts")), 2)
# self.assertEqual(jv.get("voucher_type"), "Debit Note")
# self.assertEqual(jv.get("posting_date"), getdate(se.posting_date))
# self.assertEqual(jv.get("accounts")[0].get("account"), "_Test Payable - _TC")
# self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Supplier")
# self.assertEqual(jv.get("accounts")[1].get("account"), "_Test Account Cost for Goods Sold - _TC")
#
# def test_make_return_jv_for_purchase_receipt(self):
# se, pr_name = self.test_purchase_receipt_return()
# self._test_purchase_return_jv(se)
#
# se, pr_name = self._test_purchase_return_return_against_purchase_order()
# self._test_purchase_return_jv(se)
#
# def _test_purchase_return_return_against_purchase_order(self):
#
# actual_qty_0 = get_qty_after_transaction()
#
# from erpnext.buying.doctype.purchase_order.test_purchase_order \
# import test_records as purchase_order_test_records
#
# from erpnext.buying.doctype.purchase_order.purchase_order import \
# make_purchase_receipt, make_purchase_invoice
#
# # submit purchase receipt
# po = frappe.copy_doc(purchase_order_test_records[0])
# po.transaction_date = nowdate()
# po.is_subcontracted = None
# po.get("items")[0].item_code = "_Test Item"
# po.get("items")[0].rate = 50
# po.insert()
# po.submit()
#
# pr_doc = make_purchase_receipt(po.name)
#
# pr = frappe.get_doc(pr_doc)
# pr.posting_date = po.transaction_date
# pr.insert()
# pr.submit()
#
# actual_qty_1 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_0 + 10, actual_qty_1)
#
# pi_doc = make_purchase_invoice(po.name)
#
# pi = frappe.get_doc(pi_doc)
# pi.posting_date = pr.posting_date
# pi.credit_to = "_Test Payable - _TC"
# for d in pi.get("items"):
# d.expense_account = "_Test Account Cost for Goods Sold - _TC"
# d.cost_center = "_Test Cost Center - _TC"
# for d in pi.get("taxes"):
# d.cost_center = "_Test Cost Center - _TC"
#
# pi.run_method("calculate_taxes_and_totals")
# pi.bill_no = "NA"
# pi.insert()
# pi.submit()
#
# # submit purchase return
# se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
# qty=5, purpose="Purchase Return", purchase_receipt_no=pr.name)
#
# actual_qty_2 = get_qty_after_transaction()
#
# self.assertEquals(actual_qty_1 - 5, actual_qty_2)
#
# return se, pr.name
def test_serial_no_not_reqd(self):
se = frappe.copy_doc(test_records[0])
se.get("items")[0].serial_no = "ABCD"