예제 #1
0
    def test_pos_closing_entry(self):
        test_user, pos_profile = init_user_and_profile()
        opening_entry = create_opening_entry(pos_profile, test_user.name)

        pos_inv1 = create_pos_invoice(rate=3500, do_not_submit=1)
        pos_inv1.append('payments', {
            'mode_of_payment': 'Cash',
            'account': 'Cash - _TC',
            'amount': 3500
        })
        pos_inv1.submit()

        pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
        pos_inv2.append('payments', {
            'mode_of_payment': 'Cash',
            'account': 'Cash - _TC',
            'amount': 3200
        })
        pos_inv2.submit()

        pcv_doc = make_closing_entry_from_opening(opening_entry)
        payment = pcv_doc.payment_reconciliation[0]

        self.assertEqual(payment.mode_of_payment, 'Cash')

        for d in pcv_doc.payment_reconciliation:
            if d.mode_of_payment == 'Cash':
                d.closing_amount = 6700

        pcv_doc.submit()

        self.assertEqual(pcv_doc.total_quantity, 2)
        self.assertEqual(pcv_doc.net_total, 6700)

        frappe.set_user("Administrator")
        frappe.db.sql("delete from `tabPOS Profile`")
예제 #2
0
    def test_processing_of_callback_payload(self):
        create_mpesa_settings(payment_gateway_name="Payment")
        mpesa_account = frappe.db.get_value(
            "Payment Gateway Account", {"payment_gateway": 'Mpesa-Payment'},
            "payment_account")
        frappe.db.set_value("Account", mpesa_account, "account_currency",
                            "KES")
        frappe.db.set_value("Customer", "_Test Customer", "default_currency",
                            "KES")

        pos_invoice = create_pos_invoice(do_not_submit=1)
        pos_invoice.append(
            "payments", {
                'mode_of_payment': 'Mpesa-Payment',
                'account': mpesa_account,
                'amount': 500
            })
        pos_invoice.contact_mobile = "093456543894"
        pos_invoice.currency = "KES"
        pos_invoice.save()

        pr = pos_invoice.create_payment_request()
        # test payment request creation
        self.assertEquals(pr.payment_gateway, "Mpesa-Payment")

        callback_response = get_payment_callback_payload()
        verify_transaction(**callback_response)
        # test creation of integration request
        integration_request = frappe.get_doc("Integration Request",
                                             "ws_CO_061020201133231972")

        # test integration request creation and successful update of the status on receiving callback response
        self.assertTrue(integration_request)
        self.assertEquals(integration_request.status, "Completed")

        pos_invoice.reload()
        integration_request.reload()
        self.assertEquals(pos_invoice.mpesa_receipt_number, "LGR7OWQX0R")
        self.assertEquals(integration_request.status, "Completed")

        frappe.db.set_value("Customer", "_Test Customer", "default_currency",
                            "")
    def test_consolidated_credit_note_creation(self):
        frappe.db.sql("delete from `tabPOS Invoice`")

        test_user, pos_profile = init_user_and_profile()

        pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
        pos_inv.append('payments', {
            'mode_of_payment': 'Cash',
            'account': 'Cash - _TC',
            'amount': 300
        })
        pos_inv.submit()

        pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
        pos_inv2.append('payments', {
            'mode_of_payment': 'Cash',
            'account': 'Cash - _TC',
            'amount': 3200
        })
        pos_inv2.submit()

        pos_inv3 = create_pos_invoice(customer="_Test Customer 2",
                                      rate=2300,
                                      do_not_submit=1)
        pos_inv3.append('payments', {
            'mode_of_payment': 'Cash',
            'account': 'Cash - _TC',
            'amount': 2300
        })
        pos_inv3.submit()

        pos_inv_cn = make_sales_return(pos_inv.name)
        pos_inv_cn.set("payments", [])
        pos_inv_cn.append('payments', {
            'mode_of_payment': 'Cash',
            'account': 'Cash - _TC',
            'amount': -300
        })
        pos_inv_cn.paid_amount = -300
        pos_inv_cn.submit()

        consolidate_pos_invoices()

        pos_inv.load_from_db()
        self.assertTrue(
            frappe.db.exists("Sales Invoice", pos_inv.consolidated_invoice))

        pos_inv3.load_from_db()
        self.assertTrue(
            frappe.db.exists("Sales Invoice", pos_inv3.consolidated_invoice))

        pos_inv_cn.load_from_db()
        self.assertTrue(
            frappe.db.exists("Sales Invoice", pos_inv_cn.consolidated_invoice))
        self.assertTrue(
            frappe.db.get_value("Sales Invoice",
                                pos_inv_cn.consolidated_invoice, "is_return"))

        frappe.set_user("Administrator")
        frappe.db.sql("delete from `tabPOS Profile`")
        frappe.db.sql("delete from `tabPOS Invoice`")
예제 #4
0
    def test_consolidated_credit_note_creation(self):
        frappe.db.sql("delete from `tabPOS Invoice`")

        try:
            test_user, pos_profile = init_user_and_profile()

            pos_inv = create_pos_invoice(rate=300, do_not_submit=1)
            pos_inv.append("payments", {
                "mode_of_payment": "Cash",
                "account": "Cash - _TC",
                "amount": 300
            })
            pos_inv.submit()

            pos_inv2 = create_pos_invoice(rate=3200, do_not_submit=1)
            pos_inv2.append("payments", {
                "mode_of_payment": "Cash",
                "account": "Cash - _TC",
                "amount": 3200
            })
            pos_inv2.submit()

            pos_inv3 = create_pos_invoice(customer="_Test Customer 2",
                                          rate=2300,
                                          do_not_submit=1)
            pos_inv3.append("payments", {
                "mode_of_payment": "Cash",
                "account": "Cash - _TC",
                "amount": 2300
            })
            pos_inv3.submit()

            pos_inv_cn = make_sales_return(pos_inv.name)
            pos_inv_cn.set("payments", [])
            pos_inv_cn.append("payments", {
                "mode_of_payment": "Cash",
                "account": "Cash - _TC",
                "amount": -100
            })
            pos_inv_cn.append(
                "payments", {
                    "mode_of_payment": "Bank Draft",
                    "account": "_Test Bank - _TC",
                    "amount": -200
                })
            pos_inv_cn.paid_amount = -300
            pos_inv_cn.submit()

            consolidate_pos_invoices()

            pos_inv.load_from_db()
            self.assertTrue(
                frappe.db.exists("Sales Invoice",
                                 pos_inv.consolidated_invoice))

            pos_inv3.load_from_db()
            self.assertTrue(
                frappe.db.exists("Sales Invoice",
                                 pos_inv3.consolidated_invoice))

            pos_inv_cn.load_from_db()
            self.assertTrue(
                frappe.db.exists("Sales Invoice",
                                 pos_inv_cn.consolidated_invoice))
            consolidated_credit_note = frappe.get_doc(
                "Sales Invoice", pos_inv_cn.consolidated_invoice)
            self.assertEqual(consolidated_credit_note.is_return, 1)
            self.assertEqual(
                consolidated_credit_note.payments[0].mode_of_payment, "Cash")
            self.assertEqual(consolidated_credit_note.payments[0].amount, -100)
            self.assertEqual(
                consolidated_credit_note.payments[1].mode_of_payment,
                "Bank Draft")
            self.assertEqual(consolidated_credit_note.payments[1].amount, -200)

        finally:
            frappe.set_user("Administrator")
            frappe.db.sql("delete from `tabPOS Profile`")
            frappe.db.sql("delete from `tabPOS Invoice`")
예제 #5
0
    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_inv2.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`")
예제 #6
0
    def test_consolidation_round_off_error_3(self):
        frappe.db.sql("delete from `tabPOS Invoice`")

        try:
            make_stock_entry(
                to_warehouse="_Test Warehouse - _TC",
                item_code="_Test Item",
                rate=8000,
                qty=10,
            )
            init_user_and_profile()

            item_rates = [69, 59, 29]
            for i in [1, 2]:
                inv = create_pos_invoice(is_return=1, do_not_save=1)
                inv.items = []
                for rate in item_rates:
                    inv.append(
                        "items",
                        {
                            "item_code": "_Test Item",
                            "warehouse": "_Test Warehouse - _TC",
                            "qty": -1,
                            "rate": rate,
                            "income_account": "Sales - _TC",
                            "expense_account": "Cost of Goods Sold - _TC",
                            "cost_center": "_Test Cost Center - _TC",
                        },
                    )
                inv.append(
                    "taxes",
                    {
                        "account_head": "_Test Account VAT - _TC",
                        "charge_type": "On Net Total",
                        "cost_center": "_Test Cost Center - _TC",
                        "description": "VAT",
                        "doctype": "Sales Taxes and Charges",
                        "rate": 15,
                        "included_in_print_rate": 1,
                    },
                )
                inv.payments = []
                inv.append(
                    "payments", {
                        "mode_of_payment": "Cash",
                        "account": "Cash - _TC",
                        "amount": -157
                    })
                inv.paid_amount = -157
                inv.save()
                inv.submit()

            consolidate_pos_invoices()

            inv.load_from_db()
            consolidated_invoice = frappe.get_doc("Sales Invoice",
                                                  inv.consolidated_invoice)
            self.assertEqual(consolidated_invoice.status, "Return")
            self.assertEqual(consolidated_invoice.rounding_adjustment, -0.001)

        finally:
            frappe.set_user("Administrator")
            frappe.db.sql("delete from `tabPOS Profile`")
            frappe.db.sql("delete from `tabPOS Invoice`")
예제 #7
0
    def test_consolidation_round_off_error_2(self):
        """
		Test the same case as above but with an Unpaid POS Invoice
		"""
        frappe.db.sql("delete from `tabPOS Invoice`")

        try:
            make_stock_entry(
                to_warehouse="_Test Warehouse - _TC",
                item_code="_Test Item",
                rate=8000,
                qty=10,
            )

            init_user_and_profile()

            inv = create_pos_invoice(qty=6, rate=10000, do_not_save=True)
            inv.append(
                "taxes",
                {
                    "account_head": "_Test Account VAT - _TC",
                    "charge_type": "On Net Total",
                    "cost_center": "_Test Cost Center - _TC",
                    "description": "VAT",
                    "doctype": "Sales Taxes and Charges",
                    "rate": 7.5,
                    "included_in_print_rate": 1,
                },
            )
            inv.append(
                "payments", {
                    "mode_of_payment": "Cash",
                    "account": "Cash - _TC",
                    "amount": 60000
                })
            inv.insert()
            inv.submit()

            inv2 = create_pos_invoice(qty=6, rate=10000, do_not_save=True)
            inv2.append(
                "taxes",
                {
                    "account_head": "_Test Account VAT - _TC",
                    "charge_type": "On Net Total",
                    "cost_center": "_Test Cost Center - _TC",
                    "description": "VAT",
                    "doctype": "Sales Taxes and Charges",
                    "rate": 7.5,
                    "included_in_print_rate": 1,
                },
            )
            inv2.append(
                "payments", {
                    "mode_of_payment": "Cash",
                    "account": "Cash - _TC",
                    "amount": 60000
                })
            inv2.insert()
            inv2.submit()

            inv3 = create_pos_invoice(qty=3, rate=600, do_not_save=True)
            inv3.append("payments", {
                "mode_of_payment": "Cash",
                "account": "Cash - _TC",
                "amount": 1000
            })
            inv3.insert()
            inv3.submit()

            consolidate_pos_invoices()

            inv.load_from_db()
            consolidated_invoice = frappe.get_doc("Sales Invoice",
                                                  inv.consolidated_invoice)
            self.assertEqual(consolidated_invoice.outstanding_amount, 800)
            self.assertNotEqual(consolidated_invoice.status, "Paid")

        finally:
            frappe.set_user("Administrator")
            frappe.db.sql("delete from `tabPOS Profile`")
            frappe.db.sql("delete from `tabPOS Invoice`")
예제 #8
0
    def test_processing_of_only_one_succes_callback_payload(self):
        mpesa_account = frappe.db.get_value(
            "Payment Gateway Account", {"payment_gateway": "Mpesa-Payment"},
            "payment_account")
        frappe.db.set_value("Account", mpesa_account, "account_currency",
                            "KES")
        frappe.db.set_value("Mpesa Settings", "Payment", "transaction_limit",
                            "500")
        frappe.db.set_value("Customer", "_Test Customer", "default_currency",
                            "KES")

        pos_invoice = create_pos_invoice(do_not_submit=1)
        pos_invoice.append(
            "payments", {
                "mode_of_payment": "Mpesa-Payment",
                "account": mpesa_account,
                "amount": 1000
            })
        pos_invoice.contact_mobile = "093456543894"
        pos_invoice.currency = "KES"
        pos_invoice.save()

        pr = pos_invoice.create_payment_request()
        # test payment request creation
        self.assertEqual(pr.payment_gateway, "Mpesa-Payment")

        # submitting payment request creates integration requests with random id
        integration_req_ids = frappe.get_all(
            "Integration Request",
            filters={
                "reference_doctype": pr.doctype,
                "reference_docname": pr.name,
            },
            pluck="name",
        )

        # create random receipt nos and send it as response to callback handler
        mpesa_receipt_numbers = [
            frappe.utils.random_string(5) for d in integration_req_ids
        ]

        callback_response = get_payment_callback_payload(
            Amount=500,
            CheckoutRequestID=integration_req_ids[0],
            MpesaReceiptNumber=mpesa_receipt_numbers[0],
        )
        # handle response manually
        verify_transaction(**callback_response)
        # test completion of integration request
        integration_request = frappe.get_doc("Integration Request",
                                             integration_req_ids[0])
        self.assertEqual(integration_request.status, "Completed")

        # now one request is completed
        # second integration request fails
        # now retrying payment request should make only one integration request again
        pr = pos_invoice.create_payment_request()
        new_integration_req_ids = frappe.get_all(
            "Integration Request",
            filters={
                "reference_doctype": pr.doctype,
                "reference_docname": pr.name,
                "name": ["not in", integration_req_ids],
            },
            pluck="name",
        )

        self.assertEqual(len(new_integration_req_ids), 1)

        frappe.db.set_value("Customer", "_Test Customer", "default_currency",
                            "")
        frappe.db.sql(
            "delete from `tabIntegration Request` where integration_request_service = 'Mpesa'"
        )
        pr.reload()
        pr.cancel()
        pr.delete()
        pos_invoice.delete()
예제 #9
0
    def test_processing_of_multiple_callback_payload(self):
        mpesa_account = frappe.db.get_value(
            "Payment Gateway Account", {"payment_gateway": "Mpesa-Payment"},
            "payment_account")
        frappe.db.set_value("Account", mpesa_account, "account_currency",
                            "KES")
        frappe.db.set_value("Mpesa Settings", "Payment", "transaction_limit",
                            "500")
        frappe.db.set_value("Customer", "_Test Customer", "default_currency",
                            "KES")

        pos_invoice = create_pos_invoice(do_not_submit=1)
        pos_invoice.append(
            "payments", {
                "mode_of_payment": "Mpesa-Payment",
                "account": mpesa_account,
                "amount": 1000
            })
        pos_invoice.contact_mobile = "093456543894"
        pos_invoice.currency = "KES"
        pos_invoice.save()

        pr = pos_invoice.create_payment_request()
        # test payment request creation
        self.assertEqual(pr.payment_gateway, "Mpesa-Payment")

        # submitting payment request creates integration requests with random id
        integration_req_ids = frappe.get_all(
            "Integration Request",
            filters={
                "reference_doctype": pr.doctype,
                "reference_docname": pr.name,
            },
            pluck="name",
        )

        # create random receipt nos and send it as response to callback handler
        mpesa_receipt_numbers = [
            frappe.utils.random_string(5) for d in integration_req_ids
        ]

        integration_requests = []
        for i in range(len(integration_req_ids)):
            callback_response = get_payment_callback_payload(
                Amount=500,
                CheckoutRequestID=integration_req_ids[i],
                MpesaReceiptNumber=mpesa_receipt_numbers[i],
            )
            # handle response manually
            verify_transaction(**callback_response)
            # test completion of integration request
            integration_request = frappe.get_doc("Integration Request",
                                                 integration_req_ids[i])
            self.assertEqual(integration_request.status, "Completed")
            integration_requests.append(integration_request)

        # check receipt number once all the integration requests are completed
        pos_invoice.reload()
        self.assertEqual(pos_invoice.mpesa_receipt_number,
                         ", ".join(mpesa_receipt_numbers))

        frappe.db.set_value("Customer", "_Test Customer", "default_currency",
                            "")
        [d.delete() for d in integration_requests]
        pr.reload()
        pr.cancel()
        pr.delete()
        pos_invoice.delete()