diff --git a/shopinvader_invoice/services/invoice.py b/shopinvader_invoice/services/invoice.py index 6edb34f833..c28de0aea6 100644 --- a/shopinvader_invoice/services/invoice.py +++ b/shopinvader_invoice/services/invoice.py @@ -43,19 +43,7 @@ def _validator_return_get(self): Output validator for the search :return: dict """ - invoice_schema = { - "invoice_id": {"type": "integer"}, - "number": {"type": "string"}, - "date_invoice": {"type": "string"}, - "amount_total": {"type": "float"}, - "amount_tax": {"type": "float"}, - "amount_untaxed": {"type": "float"}, - "amount_due": {"type": "float"}, - "type": {"type": "string"}, - "type_label": {"type": "string"}, - "state": {"type": "string"}, - "state_label": {"type": "string"}, - } + invoice_schema = self._get_return_invoice_schema() schema = {"data": {"type": "dict", "schema": invoice_schema}} return schema @@ -64,6 +52,22 @@ def _validator_return_search(self): Output validator for the search :return: dict """ + invoice_schema = self._get_return_invoice_schema() + schema = { + "size": {"type": "integer"}, + "data": { + "type": "list", + "schema": {"type": "dict", "schema": invoice_schema}, + }, + } + return schema + + def _get_return_invoice_schema(self): + """ + Get details about invoice to return + (used into validator_return) + :return: dict + """ invoice_schema = { "invoice_id": {"type": "integer"}, "number": {"type": "string"}, @@ -77,14 +81,7 @@ def _validator_return_search(self): "type_label": {"type": "string"}, "state_label": {"type": "string"}, } - schema = { - "size": {"type": "integer"}, - "data": { - "type": "list", - "schema": {"type": "dict", "schema": invoice_schema}, - }, - } - return schema + return invoice_schema def _get_parser_invoice(self): """ @@ -98,9 +95,9 @@ def _get_parser_invoice(self): "amount_total", "amount_tax", "amount_untaxed", - "residual:amount_due", - "type", "state", + "type", + "residual:amount_due", ] return to_parse diff --git a/shopinvader_invoice/tests/common.py b/shopinvader_invoice/tests/common.py new file mode 100644 index 0000000000..99a4037190 --- /dev/null +++ b/shopinvader_invoice/tests/common.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import fields +from odoo.addons.shopinvader.tests.common import CommonCase + + +class CommonInvoiceCase(CommonCase): + """ + Common for invoice service + """ + + def setUp(self, *args, **kwargs): + super(CommonInvoiceCase, self).setUp(*args, **kwargs) + self.invoice_obj = self.env["account.invoice"] + self.journal_obj = self.env["account.journal"] + self.register_payments_obj = self.env["account.register.payments"] + self.sale = self.env.ref("shopinvader.sale_order_2") + self.partner = self.env.ref("shopinvader.partner_1") + self.partner2 = self.env.ref("shopinvader.partner_2") + self.product = self.env.ref("product.product_product_4") + self.bank_journal_euro = self.journal_obj.create( + {"name": "Bank", "type": "bank", "code": "BNK67"} + ) + self.payment_method_manual_in = self.env.ref( + "account.account_payment_method_manual_in" + ) + self.precision = 2 + with self.work_on_services(partner=self.partner) as work: + self.service = work.component(usage="invoice") + with self.work_on_services( + partner=self.backend.anonymous_partner_id + ) as work: + self.service_guest = work.component(usage="invoice") + + def _check_data_content(self, data, invoices): + """ + Check data based on given invoices + :param data: list + :param invoices: account.invoice recordset + :return: bool + """ + # To have them into correct order + invoices = invoices.search([("id", "in", invoices.ids)]) + self.assertEquals(len(data), len(invoices)) + for current_data, invoice in zip(data, invoices): + state_label = self._get_selection_label(invoice, "state") + type_label = self._get_selection_label(invoice, "type") + self.assertEquals(current_data.get("invoice_id"), invoice.id) + self.assertEquals(current_data.get("number"), invoice.number) + self.assertEquals( + current_data.get("date_invoice"), invoice.date_invoice + ) + self.assertEquals(current_data.get("state"), invoice.state) + self.assertEquals(current_data.get("type"), invoice.type) + self.assertEquals(current_data.get("state_label"), state_label) + self.assertEquals(current_data.get("type_label"), type_label) + self.assertEquals( + current_data.get("amount_total"), invoice.amount_total + ) + self.assertEquals( + current_data.get("amount_tax"), invoice.amount_tax + ) + self.assertEquals( + current_data.get("amount_untaxed"), invoice.amount_untaxed + ) + self.assertEquals(current_data.get("amount_due"), invoice.residual) + return True + + def _confirm_and_invoice_sale(self, sale, validate=True, payment=True): + """ + Confirm the given SO and create an invoice. + Can also make the payment if payment parameter is True + :param sale: sale.order recordset + :param validate: bool + :param payment: bool + :return: account.invoice + """ + sale.action_confirm() + for line in sale.order_line: + line.write({"qty_delivered": line.product_uom_qty}) + invoice_id = sale.action_invoice_create() + invoice = self.env["account.invoice"].browse(invoice_id) + if validate: + invoice.action_invoice_open() + invoice.action_move_create() + if payment: + self._make_payment(invoice) + return invoice + + def _make_payment(self, invoice, journal=False, amount=False): + """ + Make payment for given invoice + :param invoice: account.invoice recordset + :param amount: float + :return: bool + """ + ctx = {"active_model": invoice._name, "active_ids": invoice.ids} + wizard_obj = self.register_payments_obj.with_context(ctx) + register_payments = wizard_obj.create( + { + "payment_date": fields.Date.today(), + "journal_id": self.bank_journal_euro.id, + "payment_method_id": self.payment_method_manual_in.id, + } + ) + if journal: + register_payments.write({"journal_id": journal.id}) + if amount: + register_payments.write({"amount": amount}) + register_payments.create_payment() + + def _create_invoice( + self, partner=False, inv_type="out_invoice", validate=False + ): + """ + Create a new invoice + :param partner: res.partner + :param inv_type: str + :param validate: bool + :return: stock.invoice recordset + """ + partner = partner or self.partner + account = self.product.categ_id.property_account_expense_categ_id + values = { + "partner_id": partner.id, + "partner_shipping_id": partner.id, + "shopinvader_backend_id": self.backend.id, + "date_invoice": fields.Date.today(), + "type": inv_type, + "invoice_line_ids": [ + ( + 0, + False, + { + "product_id": self.product.id, + "quantity": 10, + "price_unit": 1250, + "account_id": account.id, + "name": self.product.display_name, + }, + ) + ], + } + invoice = self.invoice_obj.create(values) + if validate: + invoice.action_invoice_open() + return invoice + + def _get_selection_label(self, invoice, field): + """ + Get the translated label of the invoice selection field + :param invoice: account.invoice recordset + :param field: str + :return: str + """ + technical_type = invoice[field] + type_dict = dict( + invoice._fields.get(field)._description_selection(invoice.env) + ) + return type_dict.get(technical_type, technical_type) diff --git a/shopinvader_invoice/tests/test_invoice_service.py b/shopinvader_invoice/tests/test_invoice_service.py index 43924ff1e5..cb3348f571 100644 --- a/shopinvader_invoice/tests/test_invoice_service.py +++ b/shopinvader_invoice/tests/test_invoice_service.py @@ -1,90 +1,39 @@ # -*- coding: utf-8 -*- # Copyright 2019 ACSONE SA/NV () # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from odoo import exceptions, fields -from odoo.addons.shopinvader.tests.common import CommonCase +from .common import CommonInvoiceCase -class TestInvoiceService(CommonCase): - """ - Tests for - """ +class TestInvoiceServiceAnonymous(CommonInvoiceCase): def setUp(self, *args, **kwargs): - super(TestInvoiceService, self).setUp(*args, **kwargs) - self.invoice_obj = self.env["account.invoice"] - self.journal_obj = self.env["account.journal"] - self.register_payments_obj = self.env["account.register.payments"] - self.sale = self.env.ref("shopinvader.sale_order_2") - self.partner = self.env.ref("shopinvader.partner_1") - self.partner2 = self.env.ref("shopinvader.partner_2") - self.product = self.env.ref("product.product_product_4") - self.bank_journal_euro = self.journal_obj.create( - {"name": "Bank", "type": "bank", "code": "BNK67"} - ) - self.payment_method_manual_in = self.env.ref( - "account.account_payment_method_manual_in" - ) - self.precision = 2 - with self.work_on_services(partner=self.partner) as work: - self.service = work.component(usage="invoice") - with self.work_on_services( - partner=self.backend.anonymous_partner_id - ) as work: - self.service_guest = work.component(usage="invoice") + super(TestInvoiceServiceAnonymous, self).setUp(*args, **kwargs) + self.partner = self.env.ref("base.res_partner_2").copy() - def _check_data_content(self, data, invoices): + def test_get_invoice_anonymous(self): """ - Check data based on given invoices - :param data: list - :param invoices: account.invoice recordset - :return: bool - """ - # To have them into correct order - invoices = invoices.search([("id", "in", invoices.ids)]) - self.assertEquals(len(data), len(invoices)) - for current_data, invoice in zip(data, invoices): - state_label = self._get_selection_label(invoice, "state") - type_label = self._get_selection_label(invoice, "type") - self.assertEquals(current_data.get("invoice_id"), invoice.id) - self.assertEquals(current_data.get("number"), invoice.number) - self.assertEquals( - current_data.get("date_invoice"), invoice.date_invoice - ) - self.assertEquals(current_data.get("state"), invoice.state) - self.assertEquals(current_data.get("type"), invoice.type) - self.assertEquals(current_data.get("state_label"), state_label) - self.assertEquals(current_data.get("type_label"), type_label) - self.assertEquals( - current_data.get("amount_total"), invoice.amount_total - ) - self.assertEquals( - current_data.get("amount_tax"), invoice.amount_tax - ) - self.assertEquals( - current_data.get("amount_untaxed"), invoice.amount_untaxed - ) - self.assertEquals(current_data.get("amount_due"), invoice.residual) - return True - - def _confirm_and_invoice_sale(self, sale, payment=True): - """ - Confirm the given SO and create an invoice. - Can also make the payment if payment parameter is True - :param sale: sale.order recordset - :param payment: bool - :return: account.invoice + Test the get on guest mode (using anonymous user). + It should not return any result, even if the anonymous user has some + invoices + :return: """ - sale.action_confirm() - for line in sale.order_line: - line.write({"qty_delivered": line.product_uom_qty}) - invoice_id = sale.action_invoice_create() - invoice = self.env["account.invoice"].browse(invoice_id) - invoice.action_invoice_open() - invoice.action_move_create() - if payment: - self._make_payment(invoice) - return invoice + # Check first without invoice related to the anonymous user + result = self.service_guest.dispatch("search") + data = result.get("data", []) + self.assertFalse(data) + # Then create a invoice related to the anonymous user + invoice = self._create_invoice( + partner=self.backend.anonymous_partner_id, validate=True + ) + self.assertEquals( + invoice.partner_id, self.backend.anonymous_partner_id + ) + result = self.service_guest.dispatch("search") + data = result.get("data", []) + self.assertFalse(data) + return def _make_payment(self, invoice, journal=False, amount=False): """ @@ -111,6 +60,8 @@ def _make_payment(self, invoice, journal=False, amount=False): register_payments.write(values) register_payments.create_payment() + +class TestInvoiceService(CommonInvoiceCase): def test_get_invoice_logged(self): """ Test the get on a logged user.