mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-03 12:19:12 +00:00
fix: merge conflicts
This commit is contained in:
@@ -183,16 +183,7 @@ class POSInvoice(SalesInvoice):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_delivered_serial_nos(self, item):
|
def validate_delivered_serial_nos(self, item):
|
||||||
<<<<<<< HEAD
|
|
||||||
serial_nos = get_serial_nos(item.serial_no)
|
|
||||||
delivered_serial_nos = frappe.db.get_list(
|
|
||||||
"Serial No",
|
|
||||||
{"item_code": item.item_code, "name": ["in", serial_nos], "sales_invoice": ["is", "set"]},
|
|
||||||
pluck="name",
|
|
||||||
)
|
|
||||||
=======
|
|
||||||
delivered_serial_nos = get_delivered_serial_nos(item.serial_no)
|
delivered_serial_nos = get_delivered_serial_nos(item.serial_no)
|
||||||
>>>>>>> f2ae63cbfd (fix(pos): remove returned sr. nos. from pos reserved sr. nos. list)
|
|
||||||
|
|
||||||
if delivered_serial_nos:
|
if delivered_serial_nos:
|
||||||
bold_delivered_serial_nos = frappe.bold(", ".join(delivered_serial_nos))
|
bold_delivered_serial_nos = frappe.bold(", ".join(delivered_serial_nos))
|
||||||
@@ -220,24 +211,18 @@ class POSInvoice(SalesInvoice):
|
|||||||
frappe.throw(error_msg, title=_("Invalid Item"), as_list=True)
|
frappe.throw(error_msg, title=_("Invalid Item"), as_list=True)
|
||||||
|
|
||||||
def validate_stock_availablility(self):
|
def validate_stock_availablility(self):
|
||||||
<<<<<<< HEAD
|
|
||||||
if self.is_return or self.docstatus != 1:
|
|
||||||
return
|
|
||||||
allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")
|
|
||||||
for d in self.get("items"):
|
|
||||||
is_service_item = not (frappe.db.get_value("Item", d.get("item_code"), "is_stock_item"))
|
|
||||||
=======
|
|
||||||
if self.is_return:
|
if self.is_return:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.docstatus.is_draft() and not frappe.db.get_value('POS Profile', self.pos_profile, 'validate_stock_on_save'):
|
if self.docstatus.is_draft() and not frappe.db.get_value(
|
||||||
|
"POS Profile", self.pos_profile, "validate_stock_on_save"
|
||||||
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
from erpnext.stock.stock_ledger import is_negative_stock_allowed
|
allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")
|
||||||
|
|
||||||
for d in self.get('items'):
|
for d in self.get("items"):
|
||||||
is_service_item = not (frappe.db.get_value('Item', d.get('item_code'), 'is_stock_item'))
|
is_service_item = not (frappe.db.get_value("Item", d.get("item_code"), "is_stock_item"))
|
||||||
>>>>>>> aff7408775 (fix(pos): allow validating stock on save)
|
|
||||||
if is_service_item:
|
if is_service_item:
|
||||||
return
|
return
|
||||||
if d.serial_no:
|
if d.serial_no:
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import six
|
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.core.page.background_jobs.background_jobs import get_info
|
from frappe.core.page.background_jobs.background_jobs import get_info
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
@@ -66,7 +65,9 @@ class POSInvoiceMergeLog(Document):
|
|||||||
frappe.throw(msg)
|
frappe.throw(msg)
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
pos_invoice_docs = [frappe.get_cached_doc("POS Invoice", d.pos_invoice) for d in self.pos_invoices]
|
pos_invoice_docs = [
|
||||||
|
frappe.get_cached_doc("POS Invoice", d.pos_invoice) for d in self.pos_invoices
|
||||||
|
]
|
||||||
|
|
||||||
returns = [d for d in pos_invoice_docs if d.get("is_return") == 1]
|
returns = [d for d in pos_invoice_docs if d.get("is_return") == 1]
|
||||||
sales = [d for d in pos_invoice_docs if d.get("is_return") == 0]
|
sales = [d for d in pos_invoice_docs if d.get("is_return") == 0]
|
||||||
@@ -83,7 +84,9 @@ class POSInvoiceMergeLog(Document):
|
|||||||
self.update_pos_invoices(pos_invoice_docs, sales_invoice, credit_note)
|
self.update_pos_invoices(pos_invoice_docs, sales_invoice, credit_note)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
pos_invoice_docs = [frappe.get_cached_doc("POS Invoice", d.pos_invoice) for d in self.pos_invoices]
|
pos_invoice_docs = [
|
||||||
|
frappe.get_cached_doc("POS Invoice", d.pos_invoice) for d in self.pos_invoices
|
||||||
|
]
|
||||||
|
|
||||||
self.update_pos_invoices(pos_invoice_docs)
|
self.update_pos_invoices(pos_invoice_docs)
|
||||||
self.cancel_linked_invoices()
|
self.cancel_linked_invoices()
|
||||||
@@ -279,16 +282,18 @@ def get_all_unconsolidated_invoices():
|
|||||||
"status": ["not in", ["Consolidated"]],
|
"status": ["not in", ["Consolidated"]],
|
||||||
"docstatus": 1,
|
"docstatus": 1,
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
pos_invoices = frappe.db.get_all(
|
pos_invoices = frappe.db.get_all(
|
||||||
"POS Invoice",
|
"POS Invoice",
|
||||||
filters=filters,
|
filters=filters,
|
||||||
fields=["name as pos_invoice", "posting_date", "grand_total", "customer"],
|
fields=[
|
||||||
|
"name as pos_invoice",
|
||||||
|
"posting_date",
|
||||||
|
"grand_total",
|
||||||
|
"customer",
|
||||||
|
"is_return",
|
||||||
|
"return_against",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
=======
|
|
||||||
pos_invoices = frappe.db.get_all('POS Invoice', filters=filters,
|
|
||||||
fields=["name as pos_invoice", 'posting_date', 'grand_total', 'customer', 'is_return', 'return_against'])
|
|
||||||
>>>>>>> cf51a0a1b8 (fix(pos): cannot close the pos if sr. no. is sold & returned)
|
|
||||||
|
|
||||||
return pos_invoices
|
return pos_invoices
|
||||||
|
|
||||||
@@ -331,29 +336,14 @@ def unconsolidate_pos_invoices(closing_entry):
|
|||||||
else:
|
else:
|
||||||
cancel_merge_logs(merge_logs, closing_entry)
|
cancel_merge_logs(merge_logs, closing_entry)
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
def create_merge_logs(invoice_by_customer, closing_entry=None):
|
|
||||||
try:
|
|
||||||
for customer, invoices in six.iteritems(invoice_by_customer):
|
|
||||||
merge_log = frappe.new_doc("POS Invoice Merge Log")
|
|
||||||
merge_log.posting_date = (
|
|
||||||
getdate(closing_entry.get("posting_date")) if closing_entry else nowdate()
|
|
||||||
)
|
|
||||||
merge_log.customer = customer
|
|
||||||
merge_log.pos_closing_entry = closing_entry.get("name") if closing_entry else None
|
|
||||||
|
|
||||||
merge_log.set("pos_invoices", invoices)
|
|
||||||
merge_log.save(ignore_permissions=True)
|
|
||||||
merge_log.submit()
|
|
||||||
=======
|
|
||||||
def split_invoices(invoices):
|
def split_invoices(invoices):
|
||||||
'''
|
"""
|
||||||
Splits invoices into multiple groups
|
Splits invoices into multiple groups
|
||||||
Use-case:
|
Use-case:
|
||||||
If a serial no is sold and later it is returned
|
If a serial no is sold and later it is returned
|
||||||
then split the invoices such that the selling entry is merged first and then the return entry
|
then split the invoices such that the selling entry is merged first and then the return entry
|
||||||
'''
|
"""
|
||||||
# Input
|
# Input
|
||||||
# invoices = [
|
# invoices = [
|
||||||
# {'pos_invoice': 'Invoice with SR#1 & SR#2', 'is_return': 0},
|
# {'pos_invoice': 'Invoice with SR#1 & SR#2', 'is_return': 0},
|
||||||
@@ -368,17 +358,26 @@ def split_invoices(invoices):
|
|||||||
|
|
||||||
_invoices = []
|
_invoices = []
|
||||||
special_invoices = []
|
special_invoices = []
|
||||||
pos_return_docs = [frappe.get_cached_doc("POS Invoice", d.pos_invoice) for d in invoices if d.is_return and d.return_against]
|
pos_return_docs = [
|
||||||
|
frappe.get_cached_doc("POS Invoice", d.pos_invoice)
|
||||||
|
for d in invoices
|
||||||
|
if d.is_return and d.return_against
|
||||||
|
]
|
||||||
for pos_invoice in pos_return_docs:
|
for pos_invoice in pos_return_docs:
|
||||||
for item in pos_invoice.items:
|
for item in pos_invoice.items:
|
||||||
if not item.serial_no:
|
if not item.serial_no:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return_against_is_added = any(d for d in _invoices if d.pos_invoice == pos_invoice.return_against)
|
return_against_is_added = any(
|
||||||
|
d for d in _invoices if d.pos_invoice == pos_invoice.return_against
|
||||||
|
)
|
||||||
if return_against_is_added:
|
if return_against_is_added:
|
||||||
break
|
break
|
||||||
|
|
||||||
return_against_is_consolidated = frappe.db.get_value('POS Invoice', pos_invoice.return_against, 'status', cache=True) == 'Consolidated'
|
return_against_is_consolidated = (
|
||||||
|
frappe.db.get_value("POS Invoice", pos_invoice.return_against, "status", cache=True)
|
||||||
|
== "Consolidated"
|
||||||
|
)
|
||||||
if return_against_is_consolidated:
|
if return_against_is_consolidated:
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -391,19 +390,21 @@ def split_invoices(invoices):
|
|||||||
|
|
||||||
return _invoices
|
return _invoices
|
||||||
|
|
||||||
|
|
||||||
def create_merge_logs(invoice_by_customer, closing_entry=None):
|
def create_merge_logs(invoice_by_customer, closing_entry=None):
|
||||||
try:
|
try:
|
||||||
for customer, invoices in invoice_by_customer.items():
|
for customer, invoices in invoice_by_customer.items():
|
||||||
for _invoices in split_invoices(invoices):
|
for _invoices in split_invoices(invoices):
|
||||||
merge_log = frappe.new_doc('POS Invoice Merge Log')
|
merge_log = frappe.new_doc("POS Invoice Merge Log")
|
||||||
merge_log.posting_date = getdate(closing_entry.get('posting_date')) if closing_entry else nowdate()
|
merge_log.posting_date = (
|
||||||
|
getdate(closing_entry.get("posting_date")) if closing_entry else nowdate()
|
||||||
|
)
|
||||||
merge_log.customer = customer
|
merge_log.customer = customer
|
||||||
merge_log.pos_closing_entry = closing_entry.get('name') if closing_entry else None
|
merge_log.pos_closing_entry = closing_entry.get("name") if closing_entry else None
|
||||||
|
|
||||||
merge_log.set('pos_invoices', _invoices)
|
merge_log.set("pos_invoices", _invoices)
|
||||||
merge_log.save(ignore_permissions=True)
|
merge_log.save(ignore_permissions=True)
|
||||||
merge_log.submit()
|
merge_log.submit()
|
||||||
>>>>>>> cf51a0a1b8 (fix(pos): cannot close the pos if sr. no. is sold & returned)
|
|
||||||
|
|
||||||
if closing_entry:
|
if closing_entry:
|
||||||
closing_entry.set_status(update=True, status="Submitted")
|
closing_entry.set_status(update=True, status="Submitted")
|
||||||
|
|||||||
@@ -391,11 +391,9 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
|
|||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
frappe.db.sql("delete from `tabPOS Profile`")
|
frappe.db.sql("delete from `tabPOS Profile`")
|
||||||
frappe.db.sql("delete from `tabPOS Invoice`")
|
frappe.db.sql("delete from `tabPOS Invoice`")
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
|
|
||||||
def test_serial_no_case_1(self):
|
def test_serial_no_case_1(self):
|
||||||
'''
|
"""
|
||||||
Create a POS Invoice with serial no
|
Create a POS Invoice with serial no
|
||||||
Create a Return Invoice with serial no
|
Create a Return Invoice with serial no
|
||||||
Create a POS Invoice with serial no again
|
Create a POS Invoice with serial no again
|
||||||
@@ -403,7 +401,7 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
|
|||||||
|
|
||||||
The first POS Invoice should be consolidated with a separate single Merge Log
|
The first POS Invoice should be consolidated with a separate single Merge Log
|
||||||
The second and third POS Invoice should be consolidated with a single Merge Log
|
The second and third POS Invoice should be consolidated with a single Merge Log
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from erpnext.stock.doctype.serial_no.test_serial_no import get_serial_nos
|
from erpnext.stock.doctype.serial_no.test_serial_no import get_serial_nos
|
||||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||||
@@ -417,15 +415,13 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
|
|||||||
init_user_and_profile()
|
init_user_and_profile()
|
||||||
|
|
||||||
pos_inv = create_pos_invoice(
|
pos_inv = create_pos_invoice(
|
||||||
item_code="_Test Serialized Item With Series",
|
item_code="_Test Serialized Item With Series",
|
||||||
serial_no=serial_no,
|
serial_no=serial_no,
|
||||||
qty=1,
|
qty=1,
|
||||||
rate=100,
|
rate=100,
|
||||||
do_not_submit=1
|
do_not_submit=1,
|
||||||
)
|
)
|
||||||
pos_inv.append('payments', {
|
pos_inv.append("payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 100})
|
||||||
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 100
|
|
||||||
})
|
|
||||||
pos_inv.submit()
|
pos_inv.submit()
|
||||||
|
|
||||||
pos_inv_cn = make_sales_return(pos_inv.name)
|
pos_inv_cn = make_sales_return(pos_inv.name)
|
||||||
@@ -433,15 +429,13 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
|
|||||||
pos_inv_cn.submit()
|
pos_inv_cn.submit()
|
||||||
|
|
||||||
pos_inv2 = create_pos_invoice(
|
pos_inv2 = create_pos_invoice(
|
||||||
item_code="_Test Serialized Item With Series",
|
item_code="_Test Serialized Item With Series",
|
||||||
serial_no=serial_no,
|
serial_no=serial_no,
|
||||||
qty=1,
|
qty=1,
|
||||||
rate=100,
|
rate=100,
|
||||||
do_not_submit=1
|
do_not_submit=1,
|
||||||
)
|
)
|
||||||
pos_inv2.append('payments', {
|
pos_inv2.append("payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 100})
|
||||||
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 100
|
|
||||||
})
|
|
||||||
pos_inv2.submit()
|
pos_inv2.submit()
|
||||||
|
|
||||||
consolidate_pos_invoices()
|
consolidate_pos_invoices()
|
||||||
@@ -455,4 +449,3 @@ class TestPOSInvoiceMergeLog(unittest.TestCase):
|
|||||||
frappe.set_user("Administrator")
|
frappe.set_user("Administrator")
|
||||||
frappe.db.sql("delete from `tabPOS Profile`")
|
frappe.db.sql("delete from `tabPOS Profile`")
|
||||||
frappe.db.sql("delete from `tabPOS Invoice`")
|
frappe.db.sql("delete from `tabPOS Invoice`")
|
||||||
>>>>>>> cf51a0a1b8 (fix(pos): cannot close the pos if sr. no. is sold & returned)
|
|
||||||
|
|||||||
@@ -352,17 +352,9 @@ erpnext.patches.v13_0.update_reserved_qty_closed_wo
|
|||||||
erpnext.patches.v13_0.amazon_mws_deprecation_warning
|
erpnext.patches.v13_0.amazon_mws_deprecation_warning
|
||||||
erpnext.patches.v13_0.set_work_order_qty_in_so_from_mr
|
erpnext.patches.v13_0.set_work_order_qty_in_so_from_mr
|
||||||
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
erpnext.patches.v13_0.update_accounts_in_loan_docs
|
||||||
<<<<<<< HEAD
|
|
||||||
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items # 24-03-2022
|
||||||
erpnext.patches.v13_0.rename_non_profit_fields
|
erpnext.patches.v13_0.rename_non_profit_fields
|
||||||
erpnext.patches.v13_0.enable_ksa_vat_docs #1
|
erpnext.patches.v13_0.enable_ksa_vat_docs #1
|
||||||
erpnext.patches.v13_0.create_gst_custom_fields_in_quotation
|
erpnext.patches.v13_0.create_gst_custom_fields_in_quotation
|
||||||
erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances
|
erpnext.patches.v13_0.update_expense_claim_status_for_paid_advances
|
||||||
=======
|
|
||||||
erpnext.patches.v14_0.update_batch_valuation_flag
|
|
||||||
erpnext.patches.v14_0.delete_non_profit_doctypes
|
|
||||||
erpnext.patches.v14_0.update_employee_advance_status
|
|
||||||
erpnext.patches.v13_0.add_cost_center_in_loans
|
|
||||||
erpnext.patches.v13_0.remove_unknown_links_to_prod_plan_items
|
|
||||||
erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
|
erpnext.patches.v13_0.set_return_against_in_pos_invoice_references
|
||||||
>>>>>>> 16253a2f72 (fix: set is_return & return_against in POS Invoice Reference table)
|
|
||||||
|
|||||||
@@ -821,16 +821,17 @@ def auto_fetch_serial_number(
|
|||||||
|
|
||||||
|
|
||||||
def get_delivered_serial_nos(serial_nos):
|
def get_delivered_serial_nos(serial_nos):
|
||||||
'''
|
"""
|
||||||
Returns serial numbers that delivered from the list of serial numbers
|
Returns serial numbers that delivered from the list of serial numbers
|
||||||
'''
|
"""
|
||||||
from frappe.query_builder.functions import Coalesce
|
from frappe.query_builder.functions import Coalesce
|
||||||
|
|
||||||
SerialNo = frappe.qb.DocType("Serial No")
|
SerialNo = frappe.qb.DocType("Serial No")
|
||||||
serial_nos = get_serial_nos(serial_nos)
|
serial_nos = get_serial_nos(serial_nos)
|
||||||
query = frappe.qb.select(SerialNo.name).from_(SerialNo).where(
|
query = (
|
||||||
(SerialNo.name.isin(serial_nos))
|
frappe.qb.select(SerialNo.name)
|
||||||
& (Coalesce(SerialNo.delivery_document_type, "") != "")
|
.from_(SerialNo)
|
||||||
|
.where((SerialNo.name.isin(serial_nos)) & (Coalesce(SerialNo.delivery_document_type, "") != ""))
|
||||||
)
|
)
|
||||||
|
|
||||||
result = query.run()
|
result = query.run()
|
||||||
@@ -838,48 +839,30 @@ def get_delivered_serial_nos(serial_nos):
|
|||||||
delivered_serial_nos = [row[0] for row in result]
|
delivered_serial_nos = [row[0] for row in result]
|
||||||
return delivered_serial_nos
|
return delivered_serial_nos
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_pos_reserved_serial_nos(filters):
|
def get_pos_reserved_serial_nos(filters):
|
||||||
if isinstance(filters, str):
|
if isinstance(filters, str):
|
||||||
filters = json.loads(filters)
|
filters = json.loads(filters)
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
pos_transacted_sr_nos = frappe.db.sql(
|
|
||||||
"""select item.serial_no as serial_no
|
|
||||||
from `tabPOS Invoice` p, `tabPOS Invoice Item` item
|
|
||||||
where p.name = item.parent
|
|
||||||
and p.consolidated_invoice is NULL
|
|
||||||
and p.docstatus = 1
|
|
||||||
and item.docstatus = 1
|
|
||||||
and item.item_code = %(item_code)s
|
|
||||||
and item.warehouse = %(warehouse)s
|
|
||||||
and item.serial_no is NOT NULL and item.serial_no != ''
|
|
||||||
""",
|
|
||||||
filters,
|
|
||||||
as_dict=1,
|
|
||||||
)
|
|
||||||
=======
|
|
||||||
POSInvoice = frappe.qb.DocType("POS Invoice")
|
POSInvoice = frappe.qb.DocType("POS Invoice")
|
||||||
POSInvoiceItem = frappe.qb.DocType("POS Invoice Item")
|
POSInvoiceItem = frappe.qb.DocType("POS Invoice Item")
|
||||||
query = frappe.qb.from_(
|
query = (
|
||||||
POSInvoice
|
frappe.qb.from_(POSInvoice)
|
||||||
).from_(
|
.from_(POSInvoiceItem)
|
||||||
POSInvoiceItem
|
.select(POSInvoice.is_return, POSInvoiceItem.serial_no)
|
||||||
).select(
|
.where(
|
||||||
POSInvoice.is_return,
|
(POSInvoice.name == POSInvoiceItem.parent)
|
||||||
POSInvoiceItem.serial_no
|
& (POSInvoice.docstatus == 1)
|
||||||
).where(
|
& (POSInvoiceItem.docstatus == 1)
|
||||||
(POSInvoice.name == POSInvoiceItem.parent)
|
& (POSInvoiceItem.item_code == filters.get("item_code"))
|
||||||
& (POSInvoice.docstatus == 1)
|
& (POSInvoiceItem.warehouse == filters.get("warehouse"))
|
||||||
& (POSInvoiceItem.docstatus == 1)
|
& (POSInvoiceItem.serial_no.isnotnull())
|
||||||
& (POSInvoiceItem.item_code == filters.get('item_code'))
|
& (POSInvoiceItem.serial_no != "")
|
||||||
& (POSInvoiceItem.warehouse == filters.get('warehouse'))
|
)
|
||||||
& (POSInvoiceItem.serial_no.isnotnull())
|
|
||||||
& (POSInvoiceItem.serial_no != '')
|
|
||||||
)
|
)
|
||||||
|
|
||||||
pos_transacted_sr_nos = query.run(as_dict=True)
|
pos_transacted_sr_nos = query.run(as_dict=True)
|
||||||
>>>>>>> f2ae63cbfd (fix(pos): remove returned sr. nos. from pos reserved sr. nos. list)
|
|
||||||
|
|
||||||
reserved_sr_nos = []
|
reserved_sr_nos = []
|
||||||
returned_sr_nos = []
|
returned_sr_nos = []
|
||||||
|
|||||||
Reference in New Issue
Block a user