fix(pos): cannot close the pos if sr. no. is sold & returned
This commit is contained in:
parent
4aabe97565
commit
cf51a0a1b8
@ -53,7 +53,7 @@ class POSInvoiceMergeLog(Document):
|
|||||||
frappe.throw(msg)
|
frappe.throw(msg)
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
pos_invoice_docs = [frappe.get_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]
|
||||||
@ -70,7 +70,7 @@ 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_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()
|
||||||
@ -254,7 +254,7 @@ def get_all_unconsolidated_invoices():
|
|||||||
'docstatus': 1
|
'docstatus': 1
|
||||||
}
|
}
|
||||||
pos_invoices = frappe.db.get_all('POS Invoice', filters=filters,
|
pos_invoices = frappe.db.get_all('POS Invoice', 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'])
|
||||||
|
|
||||||
return pos_invoices
|
return pos_invoices
|
||||||
|
|
||||||
@ -294,15 +294,57 @@ def unconsolidate_pos_invoices(closing_entry):
|
|||||||
else:
|
else:
|
||||||
cancel_merge_logs(merge_logs, closing_entry)
|
cancel_merge_logs(merge_logs, closing_entry)
|
||||||
|
|
||||||
|
def split_invoices(invoices):
|
||||||
|
'''
|
||||||
|
Splits invoices into multiple groups
|
||||||
|
Use-case:
|
||||||
|
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
|
||||||
|
'''
|
||||||
|
# Input
|
||||||
|
# invoices = [
|
||||||
|
# {'pos_invoice': 'Invoice with SR#1 & SR#2', 'is_return': 0},
|
||||||
|
# {'pos_invoice': 'Invoice with SR#1', 'is_return': 1},
|
||||||
|
# {'pos_invoice': 'Invoice with SR#2', 'is_return': 0}
|
||||||
|
# ]
|
||||||
|
# Output
|
||||||
|
# _invoices = [
|
||||||
|
# [{'pos_invoice': 'Invoice with SR#1 & SR#2', 'is_return': 0}],
|
||||||
|
# [{'pos_invoice': 'Invoice with SR#1', 'is_return': 1}, {'pos_invoice': 'Invoice with SR#2', 'is_return': 0}],
|
||||||
|
# ]
|
||||||
|
|
||||||
|
_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]
|
||||||
|
for pos_invoice in pos_return_docs:
|
||||||
|
for item in pos_invoice.items:
|
||||||
|
if not item.serial_no: continue
|
||||||
|
|
||||||
|
return_against_is_added = any(d for d in _invoices if d.pos_invoice == pos_invoice.return_against)
|
||||||
|
if return_against_is_added: break
|
||||||
|
|
||||||
|
return_against_is_consolidated = frappe.db.get_value('POS Invoice', pos_invoice.return_against, 'status', cache=True) == 'Consolidated'
|
||||||
|
if return_against_is_consolidated: break
|
||||||
|
|
||||||
|
pos_invoice_row = [d for d in invoices if d.pos_invoice == pos_invoice.return_against]
|
||||||
|
_invoices.append(pos_invoice_row)
|
||||||
|
special_invoices.append(pos_invoice.return_against)
|
||||||
|
break
|
||||||
|
|
||||||
|
_invoices.append([d for d in invoices if d.pos_invoice not in special_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):
|
||||||
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()
|
||||||
|
|
||||||
|
@ -386,3 +386,65 @@ 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`")
|
||||||
|
|
||||||
|
def test_serial_no_case_1(self):
|
||||||
|
'''
|
||||||
|
Create a POS Invoice with serial no
|
||||||
|
Create a Return Invoice with serial no
|
||||||
|
Create a POS Invoice with serial no again
|
||||||
|
Consolidate the invoices
|
||||||
|
|
||||||
|
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
|
||||||
|
'''
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
frappe.db.sql("delete from `tabPOS Invoice`")
|
||||||
|
|
||||||
|
try:
|
||||||
|
se = make_serialized_item()
|
||||||
|
serial_no = get_serial_nos(se.get("items")[0].serial_no)[0]
|
||||||
|
|
||||||
|
init_user_and_profile()
|
||||||
|
|
||||||
|
pos_inv = create_pos_invoice(
|
||||||
|
item_code="_Test Serialized Item With Series",
|
||||||
|
serial_no=serial_no,
|
||||||
|
qty=1,
|
||||||
|
rate=100,
|
||||||
|
do_not_submit=1
|
||||||
|
)
|
||||||
|
pos_inv.append('payments', {
|
||||||
|
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 100
|
||||||
|
})
|
||||||
|
pos_inv.submit()
|
||||||
|
|
||||||
|
pos_inv_cn = make_sales_return(pos_inv.name)
|
||||||
|
pos_inv_cn.paid_amount = -100
|
||||||
|
pos_inv_cn.submit()
|
||||||
|
|
||||||
|
pos_inv2 = create_pos_invoice(
|
||||||
|
item_code="_Test Serialized Item With Series",
|
||||||
|
serial_no=serial_no,
|
||||||
|
qty=1,
|
||||||
|
rate=100,
|
||||||
|
do_not_submit=1
|
||||||
|
)
|
||||||
|
pos_inv2.append('payments', {
|
||||||
|
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 100
|
||||||
|
})
|
||||||
|
pos_inv.submit()
|
||||||
|
|
||||||
|
consolidate_pos_invoices()
|
||||||
|
|
||||||
|
pos_inv.load_from_db()
|
||||||
|
pos_inv2.load_from_db()
|
||||||
|
|
||||||
|
self.assertNotEqual(pos_inv.consolidated_invoice, pos_inv2.consolidated_invoice)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
frappe.db.sql("delete from `tabPOS Profile`")
|
||||||
|
frappe.db.sql("delete from `tabPOS Invoice`")
|
@ -9,7 +9,9 @@
|
|||||||
"posting_date",
|
"posting_date",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"customer",
|
"customer",
|
||||||
"grand_total"
|
"grand_total",
|
||||||
|
"is_return",
|
||||||
|
"return_against"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -48,11 +50,27 @@
|
|||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Amount",
|
"label": "Amount",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fetch_from": "pos_invoice.is_return",
|
||||||
|
"fieldname": "is_return",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Return",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "pos_invoice.return_against",
|
||||||
|
"fieldname": "return_against",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Return Against",
|
||||||
|
"options": "POS Invoice",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-05-29 15:08:42.194979",
|
"modified": "2022-03-24 13:32:02.366257",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "POS Invoice Reference",
|
"name": "POS Invoice Reference",
|
||||||
@ -61,5 +79,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user