Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADD] 14.0 cancel and redraft sale endpoint #907

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions shopinvader/services/sale.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Copyright 2017 Akretion (http://www.akretion.com).
# @author Sébastien BEAU <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.exceptions import UserError
from odoo.osv import expression
from odoo.tools.float_utils import float_is_zero
from odoo.tools.translate import _

from odoo.addons.base_rest.components.service import to_int
from odoo.addons.component.core import Component
Expand Down Expand Up @@ -49,6 +52,21 @@ def ask_email_invoice(self, _id):
self._ask_email_invoice = True
return self.ask_email(_id)

def cancel(self, _id):
order = self._get(_id)
self._cancel(order)
return self._to_json(order)[0]

def reset_to_cart(self, _id):
order = self._get(_id)
self._cancel(order, reset_to_cart=True)
res = self._to_json(order)[0]
return {
"data": res,
"set_session": {"cart_id": res["id"]},
"store_cache": {"cart": res},
}

# Validator
def _validator_search(self):
default_search_validator = self._default_validator_search()
Expand All @@ -59,6 +77,12 @@ def _validator_search(self):
def _validator_ask_email_invoice(self):
return self._validator_ask_email()

def _validator_cancel(self):
return {}

def _validator_reset_to_cart(self):
return {}

# The following method are 'private' and should be never never NEVER call
# from the controller.
# All params are trusted as they have been checked before
Expand Down Expand Up @@ -102,6 +126,28 @@ def _get_invoices(self, sale):
domain_state = invoice_service._get_domain_state()
return invoices.filtered_domain(domain_state)

def _is_cancel_allowed(self, sale):
precision = self.env["decimal.precision"].precision_get(
"Product Unit of Measure"
)
for line in sale.order_line:
if not float_is_zero(
line.qty_delivered, precision_digits=precision
) or not float_is_zero(line.qty_invoiced, precision_digits=precision):
raise UserError(
_("Orders that have been delivered or invoiced cannot be edited.")
)
return True

def _cancel(self, sale, reset_to_cart=False):
if not self._is_cancel_allowed(sale):
raise UserError(_("This order cannot be cancelled"))
sale.action_cancel()
if reset_to_cart:
sale.action_draft()
sale.typology = "cart"
return sale

def _convert_invoices(self, invoices):
return [self._convert_one_invoice(invoice) for invoice in invoices]

Expand Down
1 change: 1 addition & 0 deletions shopinvader/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from . import test_product
from . import test_product_filter
from . import test_sale
from . import test_sale_cancel
from . import test_shopinvader_category
from . import test_shopinvader_variant_binding_wizard
from . import test_shopinvader_category_binding_wizard
Expand Down
6 changes: 4 additions & 2 deletions shopinvader/tests/test_sale.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .common import CommonCase, CommonTestDownload


class SaleCase(CommonCase, CommonTestDownload):
class CommonSaleCase(CommonCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
Expand All @@ -25,10 +25,12 @@ def setUpClass(cls):
)

def setUp(self, *args, **kwargs):
super(SaleCase, self).setUp(*args, **kwargs)
super().setUp(*args, **kwargs)
with self.work_on_services(partner=self.partner) as work:
self.service = work.component(usage="sales")


class SaleCase(CommonSaleCase, CommonTestDownload):
def _confirm_and_invoice_sale(self):
self.sale.action_confirm()
for line in self.sale.order_line:
Expand Down
41 changes: 41 additions & 0 deletions shopinvader/tests/test_sale_cancel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2021 Akretion (https://www.akretion.com).
# @author Pierrick Brun <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.exceptions import UserError

from .test_sale import CommonSaleCase


class TestSaleCancel(CommonSaleCase):
def test_sale_cancel(self):
self.sale.action_confirm()
self.assertEqual("sale", self.sale.typology)
self.assertEqual("sale", self.sale.state)

self.service.dispatch("cancel", self.sale.id)

self.assertEqual("cancel", self.sale.state)

def test_sale_cancel_fail_if_delivered(self):
self.sale.action_confirm()
# deliver only 1 line
self.sale.order_line[0].write({"qty_delivered": 1})
self.env["sale.order.line"].flush(records=self.sale.order_line)
with self.assertRaises(UserError):
self.service.dispatch("cancel", self.sale.id)
self.assertEqual("sale", self.sale.typology)
self.assertEqual("sale", self.sale.state)

def test_sale_cancel_to_cart(self):
self.sale.action_confirm()
self.assertEqual("sale", self.sale.typology)
self.assertEqual("sale", self.sale.state)

result = self.service.dispatch("reset_to_cart", self.sale.id)

session = result.get("set_session")
self.assertEqual("draft", self.sale.state)
self.assertEqual("cart", self.sale.typology)
self.assertIsInstance(session, dict)
self.assertEqual(session.get("cart_id"), self.sale.id)