mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-27 08:54:45 +00:00
[Fix] POS Closing Voucher, on save collected amount becomes zero issue and added test cases (#14649)
* [Fix] POS Closing Voucher, on save collected amount becomes zero * Added test cases for the POS Closing Voucher
This commit is contained in:
committed by
Nabin Hait
parent
648728f330
commit
3a595d07d0
@@ -51,4 +51,6 @@ def make_pos_profile():
|
|||||||
})
|
})
|
||||||
|
|
||||||
if not frappe.db.exists("POS Profile", "_Test POS Profile"):
|
if not frappe.db.exists("POS Profile", "_Test POS Profile"):
|
||||||
pos_profile.insert()
|
pos_profile.insert()
|
||||||
|
|
||||||
|
return pos_profile
|
||||||
|
|||||||
@@ -691,6 +691,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
item = make_item("_Test POS Item")
|
item = make_item("_Test POS Item")
|
||||||
pos = copy.deepcopy(test_records[1])
|
pos = copy.deepcopy(test_records[1])
|
||||||
pos['items'][0]['item_code'] = item.name
|
pos['items'][0]['item_code'] = item.name
|
||||||
|
pos['items'][0]['warehouse'] = "_Test Warehouse - _TC"
|
||||||
pos["is_pos"] = 1
|
pos["is_pos"] = 1
|
||||||
pos["offline_pos_name"] = timestamp
|
pos["offline_pos_name"] = timestamp
|
||||||
pos["update_stock"] = 1
|
pos["update_stock"] = 1
|
||||||
|
|||||||
@@ -363,4 +363,4 @@ def check_active_sales_items(obj):
|
|||||||
"company": obj.company,
|
"company": obj.company,
|
||||||
"income_account": d.income_account
|
"income_account": d.income_account
|
||||||
})
|
})
|
||||||
doc.save()
|
doc.save(ignore_permissions=True)
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
def calculate_net_total(self):
|
def calculate_net_total(self):
|
||||||
self.doc.total_qty = self.doc.total = self.doc.base_total = self.doc.net_total = self.doc.base_net_total = 0.0
|
self.doc.total_qty = self.doc.total = self.doc.base_total = self.doc.net_total = self.doc.base_net_total = 0.0
|
||||||
|
|
||||||
for item in self.doc.get("items"):
|
for item in self.doc.get("items"):
|
||||||
self.doc.total += item.amount
|
self.doc.total += item.amount
|
||||||
self.doc.total_qty += item.qty
|
self.doc.total_qty += item.qty
|
||||||
@@ -175,6 +176,9 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
|
self.doc.round_floats_in(self.doc, ["total", "base_total", "net_total", "base_net_total"])
|
||||||
|
|
||||||
|
if self.doc.doctype == 'Sales Invoice' and self.doc.is_pos:
|
||||||
|
self.doc.pos_total_qty = self.doc.total_qty
|
||||||
|
|
||||||
def calculate_taxes(self):
|
def calculate_taxes(self):
|
||||||
self.doc.rounding_adjustment = 0
|
self.doc.rounding_adjustment = 0
|
||||||
# maintain actual tax rate based on idx
|
# maintain actual tax rate based on idx
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from collections import defaultdict
|
|||||||
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
|
from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
class POSClosingVoucher(Document):
|
class POSClosingVoucher(Document):
|
||||||
def get_closing_voucher_details(self):
|
def get_closing_voucher_details(self):
|
||||||
filters = {
|
filters = {
|
||||||
@@ -21,7 +20,6 @@ class POSClosingVoucher(Document):
|
|||||||
'user': self.user,
|
'user': self.user,
|
||||||
'is_pos': 1
|
'is_pos': 1
|
||||||
}
|
}
|
||||||
frappe.log_error(filters)
|
|
||||||
|
|
||||||
invoice_list = get_invoices(filters)
|
invoice_list = get_invoices(filters)
|
||||||
self.set_invoice_list(invoice_list)
|
self.set_invoice_list(invoice_list)
|
||||||
@@ -29,8 +27,9 @@ class POSClosingVoucher(Document):
|
|||||||
sales_summary = get_sales_summary(invoice_list)
|
sales_summary = get_sales_summary(invoice_list)
|
||||||
self.set_sales_summary_values(sales_summary)
|
self.set_sales_summary_values(sales_summary)
|
||||||
|
|
||||||
mop = get_mode_of_payment_details(invoice_list)
|
if not self.get('payment_reconciliation'):
|
||||||
self.set_mode_of_payments(mop)
|
mop = get_mode_of_payment_details(invoice_list)
|
||||||
|
self.set_mode_of_payments(mop)
|
||||||
|
|
||||||
taxes = get_tax_details(invoice_list)
|
taxes = get_tax_details(invoice_list)
|
||||||
self.set_taxes(taxes)
|
self.set_taxes(taxes)
|
||||||
@@ -67,11 +66,10 @@ class POSClosingVoucher(Document):
|
|||||||
'amount': tax['amount']
|
'amount': tax['amount']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def get_payment_reconciliation_details(self):
|
def get_payment_reconciliation_details(self):
|
||||||
currency = get_company_currency(self)
|
currency = get_company_currency(self)
|
||||||
return frappe.render_template("erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html", {"data": self, "currency": currency})
|
return frappe.render_template("erpnext/selling/doctype/pos_closing_voucher/closing_voucher_details.html",
|
||||||
|
{"data": self, "currency": currency})
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_cashiers(doctype, txt, searchfield, start, page_len, filters):
|
def get_cashiers(doctype, txt, searchfield, start, page_len, filters):
|
||||||
@@ -151,7 +149,6 @@ def get_tax_details(invoice_list):
|
|||||||
|
|
||||||
return tax_breakup
|
return tax_breakup
|
||||||
|
|
||||||
|
|
||||||
def get_sales_summary(invoice_list):
|
def get_sales_summary(invoice_list):
|
||||||
net_total = sum(item['net_total'] for item in invoice_list)
|
net_total = sum(item['net_total'] for item in invoice_list)
|
||||||
grand_total = sum(item['grand_total'] for item in invoice_list)
|
grand_total = sum(item['grand_total'] for item in invoice_list)
|
||||||
@@ -163,7 +160,6 @@ def get_company_currency(doc):
|
|||||||
currency = frappe.db.get_value("Company", doc.company, "default_currency")
|
currency = frappe.db.get_value("Company", doc.company, "default_currency")
|
||||||
return frappe.get_doc('Currency', currency)
|
return frappe.get_doc('Currency', currency)
|
||||||
|
|
||||||
|
|
||||||
def get_invoices(filters):
|
def get_invoices(filters):
|
||||||
return frappe.db.sql("""select a.name, a.base_grand_total as grand_total,
|
return frappe.db.sql("""select a.name, a.base_grand_total as grand_total,
|
||||||
a.base_net_total as net_total, a.pos_total_qty
|
a.base_net_total as net_total, a.pos_total_qty
|
||||||
|
|||||||
@@ -2,8 +2,82 @@
|
|||||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# See license.txt
|
# See license.txt
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
|
||||||
|
|
||||||
class TestPOSClosingVoucher(unittest.TestCase):
|
class TestPOSClosingVoucher(unittest.TestCase):
|
||||||
pass
|
def test_pos_closing_voucher(self):
|
||||||
|
old_user = frappe.session.user
|
||||||
|
user = 'test@example.com'
|
||||||
|
test_user = frappe.get_doc('User', user)
|
||||||
|
|
||||||
|
roles = ("Accounts Manager", "Accounts User", "Sales Manager")
|
||||||
|
test_user.add_roles(*roles)
|
||||||
|
frappe.set_user(user)
|
||||||
|
|
||||||
|
pos_profile = make_pos_profile()
|
||||||
|
pos_profile.append('applicable_for_users', {
|
||||||
|
'default': 1,
|
||||||
|
'user': user
|
||||||
|
})
|
||||||
|
|
||||||
|
pos_profile.save()
|
||||||
|
|
||||||
|
si1 = create_sales_invoice(is_pos=1, rate=3500, do_not_submit=1)
|
||||||
|
si1.append('payments', {
|
||||||
|
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3500
|
||||||
|
})
|
||||||
|
si1.submit()
|
||||||
|
|
||||||
|
si2 = create_sales_invoice(is_pos=1, rate=3200, do_not_submit=1)
|
||||||
|
si2.append('payments', {
|
||||||
|
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 3200
|
||||||
|
})
|
||||||
|
si2.submit()
|
||||||
|
|
||||||
|
pcv_doc = create_pos_closing_voucher(user=user,
|
||||||
|
pos_profile=pos_profile.name, collected_amount=6700)
|
||||||
|
|
||||||
|
pcv_doc.get_closing_voucher_details()
|
||||||
|
|
||||||
|
self.assertEqual(pcv_doc.total_quantity, 2)
|
||||||
|
self.assertEqual(pcv_doc.net_total, 6700)
|
||||||
|
|
||||||
|
payment = pcv_doc.payment_reconciliation[0]
|
||||||
|
self.assertEqual(payment.mode_of_payment, 'Cash')
|
||||||
|
|
||||||
|
si1.load_from_db()
|
||||||
|
si1.cancel()
|
||||||
|
|
||||||
|
si2.load_from_db()
|
||||||
|
si2.cancel()
|
||||||
|
|
||||||
|
test_user.load_from_db()
|
||||||
|
test_user.remove_roles(*roles)
|
||||||
|
|
||||||
|
frappe.set_user(old_user)
|
||||||
|
frappe.db.sql("delete from `tabPOS Profile`")
|
||||||
|
|
||||||
|
def create_pos_closing_voucher(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
'doctype': 'POS Closing Voucher',
|
||||||
|
'period_start_date': args.period_start_date or nowdate(),
|
||||||
|
'period_end_date': args.period_end_date or nowdate(),
|
||||||
|
'posting_date': args.posting_date or nowdate(),
|
||||||
|
'company': args.company or "_Test Company",
|
||||||
|
'pos_profile': args.pos_profile,
|
||||||
|
'user': args.user or "Administrator",
|
||||||
|
})
|
||||||
|
|
||||||
|
doc.get_closing_voucher_details()
|
||||||
|
if doc.get('payment_reconciliation'):
|
||||||
|
doc.payment_reconciliation[0].collected_amount = (args.collected_amount or
|
||||||
|
doc.payment_reconciliation[0].expected_amount)
|
||||||
|
|
||||||
|
doc.save()
|
||||||
|
return doc
|
||||||
Reference in New Issue
Block a user