From 76c30420694e810d4eaf80bc8bca331ff5bbb37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Pigeon?= Date: Fri, 20 Mar 2020 21:25:45 +0100 Subject: [PATCH] [10.0][CHG] being able to make the difference between an update done by the customer and update done internally in Odoo --- shopinvader/models/__init__.py | 1 + shopinvader/models/sale.py | 3 +- shopinvader/models/track_external_mixin.py | 26 +++++++++++++++ shopinvader/services/service.py | 7 ++++ shopinvader/tests/common.py | 12 +++++++ shopinvader/tests/test_cart.py | 10 ++++-- shopinvader/tests/test_cart_item.py | 32 +++++++++++++++++++ .../models/shopinvader_backend.py | 2 +- .../tests/test_cart_expiry.py | 8 +++-- .../models/sale_order.py | 2 +- .../tests/test_sale_order.py | 1 + 11 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 shopinvader/models/track_external_mixin.py diff --git a/shopinvader/models/__init__.py b/shopinvader/models/__init__.py index 1dd38c161c..d3d7a8e49c 100644 --- a/shopinvader/models/__init__.py +++ b/shopinvader/models/__init__.py @@ -4,6 +4,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import seo_title_mixin +from . import track_external_mixin from . import product_filter from . import product_product from . import product_template diff --git a/shopinvader/models/sale.py b/shopinvader/models/sale.py index 5981d753ae..f2bcd35601 100644 --- a/shopinvader/models/sale.py +++ b/shopinvader/models/sale.py @@ -21,7 +21,8 @@ class ShopinvaderCartStep(models.Model): class SaleOrder(models.Model): - _inherit = "sale.order" + _name = "sale.order" + _inherit = ["sale.order", "track.external.mixin"] typology = fields.Selection( [("sale", "Sale"), ("cart", "Cart")], default="sale" diff --git a/shopinvader/models/track_external_mixin.py b/shopinvader/models/track_external_mixin.py new file mode 100644 index 0000000000..15ec754d72 --- /dev/null +++ b/shopinvader/models/track_external_mixin.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models + + +class TrackExternalMixin(models.AbstractModel): + _name = "track.external.mixin" + _description = "Track external update" + + last_external_update_date = fields.Datetime() + + def is_rest_request(self): + return self.env.context.get("shopinvader_request", False) + + @api.multi + def _write(self, vals): + if self.is_rest_request(): + vals["last_external_update_date"] = fields.Datetime.now() + return super(TrackExternalMixin, self)._write(vals) + + @api.model + def create(self, vals): + if self.is_rest_request(): + vals["last_external_update_date"] = fields.Datetime.now() + return super(TrackExternalMixin, self).create(vals) diff --git a/shopinvader/services/service.py b/shopinvader/services/service.py index cbd5121428..8b8a6db141 100644 --- a/shopinvader/services/service.py +++ b/shopinvader/services/service.py @@ -9,6 +9,7 @@ from odoo.addons.component.core import AbstractComponent from odoo.exceptions import MissingError, UserError from odoo.osv import expression +from odoo.tools import frozendict from .. import shopinvader_response @@ -19,6 +20,12 @@ class BaseShopinvaderService(AbstractComponent): _collection = "shopinvader.backend" _expose_model = None + @property + def env(self): + env = self.work.env + env.context = frozendict(dict(env.context, shopinvader_request=True)) + return env + @property def partner(self): return self.work.partner diff --git a/shopinvader/tests/common.py b/shopinvader/tests/common.py index 6d955b98a0..843d045036 100644 --- a/shopinvader/tests/common.py +++ b/shopinvader/tests/common.py @@ -12,6 +12,9 @@ from odoo.addons.component.tests.common import ComponentMixin from odoo.addons.queue_job.job import Job from odoo.addons.server_environment import serv_config +from odoo.addons.shopinvader.models.track_external_mixin import ( + TrackExternalMixin, +) from odoo.exceptions import MissingError from odoo.tests import SavepointCase @@ -89,6 +92,15 @@ def _get_selection_label(self, record, field): record[field], record ) + def _get_last_external_update_date(self, record): + if isinstance(record, TrackExternalMixin): + return record.last_external_update_date + return False + + def _check_last_external_update_date(self, record, previous_date): + if isinstance(record, TrackExternalMixin): + self.assertTrue(record.last_external_update_date > previous_date) + class ProductCommonCase(CommonCase): def setUp(self): diff --git a/shopinvader/tests/test_cart.py b/shopinvader/tests/test_cart.py index 30433e436b..271a8e157a 100644 --- a/shopinvader/tests/test_cart.py +++ b/shopinvader/tests/test_cart.py @@ -151,7 +151,9 @@ def _sign_with(self, partner): def test_anonymous_cart_then_sign(self): cart = self.cart partner = self.env.ref("shopinvader.partner_1") + last_external_update_date = self._get_last_external_update_date(cart) self._sign_with(partner) + self._check_last_external_update_date(cart, last_external_update_date) self.assertEqual(cart.partner_id, partner) self.assertEqual(cart.partner_shipping_id, partner) self.assertEqual(cart.partner_invoice_id, partner) @@ -450,21 +452,25 @@ def test_cart_line_lang_logged(self): class ConnectedCartCase(CommonConnectedCartCase, CartClearTest): def test_set_shipping_address(self): + cart = self.cart + last_external_update_date = self._get_last_external_update_date(cart) self.service.dispatch( "update", params={"shipping": {"address": {"id": self.address.id}}} ) - cart = self.cart + self._check_last_external_update_date(cart, last_external_update_date) self.assertEqual(cart.partner_id, self.partner) self.assertEqual(cart.partner_shipping_id, self.address) self.assertEqual(cart.partner_invoice_id, self.address) def test_set_invoice_address(self): + cart = self.cart + last_external_update_date = self._get_last_external_update_date(cart) self.service.dispatch( "update", params={"invoicing": {"address": {"id": self.address.id}}}, ) + self._check_last_external_update_date(cart, last_external_update_date) - cart = self.cart self.assertEqual(cart.partner_id, self.partner) self.assertEqual(cart.partner_shipping_id, self.partner) self.assertEqual(cart.partner_invoice_id, self.address) diff --git a/shopinvader/tests/test_cart_item.py b/shopinvader/tests/test_cart_item.py index e10edd4faa..1051cba340 100644 --- a/shopinvader/tests/test_cart_item.py +++ b/shopinvader/tests/test_cart_item.py @@ -3,6 +3,8 @@ # @author Sébastien BEAU # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import time + from odoo.tools import float_round from .common import CommonCase @@ -249,6 +251,36 @@ def test_pricelist_product_price_unit_with_discount(self): # same for the total self.assertEqual(amount["total"], 14.85) + def test_upgrade_last_update_date(self): + last_external_update_date = self._get_last_external_update_date( + self.cart + ) + self.add_item(self.product_1.id, 2) + self._check_last_external_update_date( + self.cart, last_external_update_date + ) + + time.sleep(1) + + last_external_update_date = self._get_last_external_update_date( + self.cart + ) + line_id = self.cart.order_line[0].id + self.update_item(line_id, 5) + self._check_last_external_update_date( + self.cart, last_external_update_date + ) + + time.sleep(1) + + last_external_update_date = self._get_last_external_update_date( + self.cart + ) + self.delete_item(line_id) + self._check_last_external_update_date( + self.cart, last_external_update_date + ) + class AnonymousItemCase(AbstractItemCase, CommonCase): def setUp(self, *args, **kwargs): diff --git a/shopinvader_cart_expiry/models/shopinvader_backend.py b/shopinvader_cart_expiry/models/shopinvader_backend.py index 5323c9bc2b..ab1ce22c81 100644 --- a/shopinvader_cart_expiry/models/shopinvader_backend.py +++ b/shopinvader_cart_expiry/models/shopinvader_backend.py @@ -47,7 +47,7 @@ def manage_cart_expiry(self): ("shopinvader_backend_id", "=", self.id), ("typology", "=", "cart"), ("state", "=", "draft"), - ("write_date", "<=", expiry_date), + ("last_external_update_date", "<=", expiry_date), ] cart_expired = self.env["sale.order"].search(domain) if cart_expired: diff --git a/shopinvader_cart_expiry/tests/test_cart_expiry.py b/shopinvader_cart_expiry/tests/test_cart_expiry.py index 62e0845e3f..2709d00e1b 100644 --- a/shopinvader_cart_expiry/tests/test_cart_expiry.py +++ b/shopinvader_cart_expiry/tests/test_cart_expiry.py @@ -17,6 +17,8 @@ def setUp(self): super(TestCartExpiry, self).setUp() self.sale_obj = self.env["sale.order"] self.sale = self.env.ref("shopinvader.sale_order_2") + self.sale.write({"last_external_update_date": fields.Datetime.now()}) + self.so_date = self.sale.last_external_update_date def test_cart_expiry_scheduler(self): """ @@ -34,7 +36,7 @@ def test_cart_expiry_scheduler(self): return def test_cart_expiry_cancel(self): - so_date = fields.Datetime.from_string(self.sale.write_date) + so_date = fields.Datetime.from_string(self.so_date) today = fields.Datetime.to_string(so_date + timedelta(hours=5)) self.backend.write( {"cart_expiry_delay": 1, "cart_expiry_policy": "cancel"} @@ -52,7 +54,7 @@ def test_cart_expiry_cancel(self): self.assertEqual(self.sale.state, "cancel") def test_cart_expiry_delete(self): - so_date = fields.Datetime.from_string(self.sale.write_date) + so_date = fields.Datetime.from_string(self.so_date) today = fields.Datetime.to_string(so_date + timedelta(hours=5)) self.backend.write( {"cart_expiry_delay": 1, "cart_expiry_policy": "delete"} @@ -74,7 +76,7 @@ def test_cart_expiry_not_draft(self): Ensure the cart is not deleted/canceled when the state is not draft. :return: """ - so_date = fields.Datetime.from_string(self.sale.write_date) + so_date = fields.Datetime.from_string(self.so_date) today = fields.Datetime.to_string(so_date + timedelta(hours=5)) self.sale.write({"state": "sent"}) self.backend.write( diff --git a/shopinvader_pending_cart_reminder/models/sale_order.py b/shopinvader_pending_cart_reminder/models/sale_order.py index 5a6df60418..bf661bb418 100644 --- a/shopinvader_pending_cart_reminder/models/sale_order.py +++ b/shopinvader_pending_cart_reminder/models/sale_order.py @@ -27,7 +27,7 @@ def _get_sale_order_domain_for_reminder(self, backend, reminder_date): ("shopinvader_backend_id", "=", backend.id), ("typology", "=", "cart"), ("pending_cart_reminder_sent_dt", "=", False), - ("write_date", "<=", reminder_date), + ("last_external_update_date", "<=", reminder_date), ("create_date", ">=", backend.reminder_start_date), ] return domain diff --git a/shopinvader_pending_cart_reminder/tests/test_sale_order.py b/shopinvader_pending_cart_reminder/tests/test_sale_order.py index 263fa83d86..18fa71d449 100644 --- a/shopinvader_pending_cart_reminder/tests/test_sale_order.py +++ b/shopinvader_pending_cart_reminder/tests/test_sale_order.py @@ -16,6 +16,7 @@ def setUp(self): super(TestSaleOrder, self).setUp() self.sale_obj = self.env["sale.order"] self.sale = self.env.ref("shopinvader.sale_order_2") + self.sale.write({"last_external_update_date": fields.Datetime.now()}) self.template = self.env.ref( "shopinvader_pending_cart_reminder." "mail_template_shopinvader_sale_reminder"