odoo13-addon-shopinvader-wishlist 13.0.3.4.2.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. odoo/addons/shopinvader_wishlist/README.rst +69 -0
  2. odoo/addons/shopinvader_wishlist/__init__.py +4 -0
  3. odoo/addons/shopinvader_wishlist/__manifest__.py +15 -0
  4. odoo/addons/shopinvader_wishlist/components/__init__.py +1 -0
  5. odoo/addons/shopinvader_wishlist/components/access_info.py +20 -0
  6. odoo/addons/shopinvader_wishlist/demo/product_set.xml +17 -0
  7. odoo/addons/shopinvader_wishlist/i18n/shopinvader_wishlist.pot +66 -0
  8. odoo/addons/shopinvader_wishlist/models/__init__.py +1 -0
  9. odoo/addons/shopinvader_wishlist/models/product_set.py +80 -0
  10. odoo/addons/shopinvader_wishlist/readme/CONTRIBUTORS.rst +2 -0
  11. odoo/addons/shopinvader_wishlist/readme/CREDITS.rst +4 -0
  12. odoo/addons/shopinvader_wishlist/readme/DESCRIPTION.rst +1 -0
  13. odoo/addons/shopinvader_wishlist/services/__init__.py +1 -0
  14. odoo/addons/shopinvader_wishlist/services/wishlist.py +550 -0
  15. odoo/addons/shopinvader_wishlist/static/description/icon.png +0 -0
  16. odoo/addons/shopinvader_wishlist/static/description/index.html +426 -0
  17. odoo/addons/shopinvader_wishlist/tests/__init__.py +2 -0
  18. odoo/addons/shopinvader_wishlist/tests/test_product_set.py +119 -0
  19. odoo/addons/shopinvader_wishlist/tests/test_wishlist.py +368 -0
  20. odoo/addons/shopinvader_wishlist/views/product_set.xml +15 -0
  21. odoo/addons/shopinvader_wishlist/wizard/__init__.py +1 -0
  22. odoo/addons/shopinvader_wishlist/wizard/product_set_add.py +24 -0
  23. odoo/addons/shopinvader_wishlist/wizard/product_set_add.xml +13 -0
  24. odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/METADATA +86 -0
  25. odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/RECORD +27 -0
  26. odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/WHEEL +5 -0
  27. odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,368 @@
1
+ # Copyright 2019 Camptocamp (http://www.camptocamp.com).
2
+ # @author Simone Orsi <simone.orsi@camptocamp.com>
3
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
4
+
5
+ import mock
6
+ from werkzeug.exceptions import NotFound
7
+
8
+ from odoo import exceptions
9
+
10
+ from odoo.addons.shopinvader.tests.common import CommonCase
11
+
12
+
13
+ class CommonWishlistCase(CommonCase):
14
+ @classmethod
15
+ def setUpClass(cls):
16
+ super(CommonWishlistCase, cls).setUpClass()
17
+ cls.partner = cls.env.ref("shopinvader.partner_1")
18
+ cls.prod1 = cls.env.ref("product.product_product_11")
19
+ cls.prod2 = cls.env.ref("product.product_product_13")
20
+ cls.prod3 = cls.env.ref("product.product_product_10")
21
+ cls.prod4 = cls.env.ref("product.product_product_9")
22
+ cls.prod5 = cls.env.ref("product.product_product_20")
23
+ cls.wl_params = {
24
+ "name": "My new wishlist :)",
25
+ "ref": "MY_NEW",
26
+ "partner_id": cls.partner.id,
27
+ "lines": [
28
+ {"product_id": cls.prod1.id, "quantity": 1.0},
29
+ {"product_id": cls.prod2.id, "quantity": 5.0},
30
+ ],
31
+ }
32
+
33
+ def setUp(self, *args, **kwargs):
34
+ super(CommonWishlistCase, self).setUp(*args, **kwargs)
35
+ with self.work_on_services(partner=self.partner) as work:
36
+ self.wishlist_service = work.component(usage="wishlist")
37
+
38
+ def _check_data(self, record, data):
39
+ data_lines = data.pop("lines", [])
40
+ rec_data = record._convert_to_write(record._cache)
41
+ rec_lines = record.set_line_ids
42
+ for key in data:
43
+ self.assertEqual(rec_data[key], data[key])
44
+ for dline in data_lines:
45
+ list_line = rec_lines.filtered(
46
+ lambda x: x.product_id.id == dline["product_id"]
47
+ )
48
+ self.assertTrue(list_line)
49
+ for key in ("quantity", "sequence"):
50
+ if key in dline:
51
+ self.assertEqual(list_line[key], dline.get(key))
52
+
53
+
54
+ class WishlistCase(CommonWishlistCase):
55
+ @classmethod
56
+ def setUpClass(cls):
57
+ super(WishlistCase, cls).setUpClass()
58
+ cls.prod_set = cls.env.ref("shopinvader_wishlist.wishlist_1")
59
+ cls.prod_set.shopinvader_backend_id = cls.backend
60
+
61
+ def test_create(self):
62
+ params = dict(self.wl_params)
63
+ res = self.wishlist_service.dispatch("create", params=params)["data"]
64
+ record = self.env["product.set"].browse(res["id"])
65
+ self.assertEqual(record.partner_id, self.partner)
66
+ self._check_data(record, params)
67
+
68
+ def test_update(self):
69
+ params = {"name": "Baz"}
70
+ self.assertEqual(self.prod_set.name, "Wishlist 1")
71
+ self.wishlist_service.dispatch(
72
+ "update", self.prod_set.id, params=params
73
+ )
74
+ self.assertEqual(self.prod_set.name, "Baz")
75
+
76
+ def test_move_items(self):
77
+ for line in self.wl_params["lines"]:
78
+ self.prod_set.set_line_ids.create(
79
+ dict(line, product_set_id=self.prod_set.id)
80
+ )
81
+ prod1 = self.prod_set.set_line_ids[0].product_id
82
+ prod2 = self.prod_set.set_line_ids[1].product_id
83
+ prod3 = self.prod_set.set_line_ids[2].product_id
84
+ move_to_set1 = self.prod_set.copy(default={"set_line_ids": False})
85
+ move_to_set2 = self.prod_set.copy(default={"set_line_ids": False})
86
+ self.assertFalse(move_to_set1.set_line_ids)
87
+ self.assertFalse(move_to_set2.set_line_ids)
88
+ self.wishlist_service.dispatch(
89
+ "move_items",
90
+ self.prod_set.id,
91
+ params={
92
+ "lines": [
93
+ {
94
+ "move_to_wishlist_id": move_to_set1.id,
95
+ "product_id": prod1.id,
96
+ },
97
+ {
98
+ "move_to_wishlist_id": move_to_set1.id,
99
+ "product_id": prod2.id,
100
+ },
101
+ {
102
+ "move_to_wishlist_id": move_to_set2.id,
103
+ "product_id": prod3.id,
104
+ },
105
+ ]
106
+ },
107
+ )
108
+ self.assertFalse(self.prod_set.set_line_ids)
109
+ self.assertEqual(len(move_to_set1.set_line_ids), 2)
110
+ self.assertEqual(len(move_to_set2.set_line_ids), 1)
111
+ self.assertIn(prod1, move_to_set1.mapped("set_line_ids.product_id"))
112
+ self.assertIn(prod2, move_to_set1.mapped("set_line_ids.product_id"))
113
+ self.assertIn(prod3, move_to_set2.mapped("set_line_ids.product_id"))
114
+
115
+ def test_replace_items(self):
116
+ for line in self.wl_params["lines"]:
117
+ self.prod_set.set_line_ids.create(
118
+ dict(line, product_set_id=self.prod_set.id)
119
+ )
120
+ prod1 = self.prod_set.set_line_ids[0].product_id
121
+ prod2 = self.prod_set.set_line_ids[1].product_id
122
+ prod3 = self.prod_set.set_line_ids[2].product_id
123
+ self.wishlist_service.dispatch(
124
+ "replace_items",
125
+ self.prod_set.id,
126
+ params={
127
+ "lines": [
128
+ {
129
+ "product_id": prod1.id,
130
+ "replacement_product_id": self.prod3.id,
131
+ },
132
+ {
133
+ "product_id": prod2.id,
134
+ "replacement_product_id": self.prod4.id,
135
+ },
136
+ {
137
+ "product_id": prod3.id,
138
+ "replacement_product_id": self.prod5.id,
139
+ },
140
+ ]
141
+ },
142
+ )
143
+ set_products = self.prod_set.mapped("set_line_ids.product_id")
144
+ self.assertNotIn(prod1, set_products)
145
+ self.assertNotIn(prod2, set_products)
146
+ self.assertNotIn(prod3, set_products)
147
+ self.assertIn(self.prod3, set_products)
148
+ self.assertIn(self.prod4, set_products)
149
+ self.assertIn(self.prod5, set_products)
150
+
151
+ def test_search(self):
152
+ res = self.wishlist_service.dispatch(
153
+ "search", params={"scope": {"typology": "foo"}}
154
+ )
155
+ self.assertEqual(res["size"], 0)
156
+ res = self.wishlist_service.dispatch(
157
+ "search", params={"scope": {"ref": "WISH_1"}}
158
+ )
159
+ self.assertEqual(res["size"], 1)
160
+ self.assertEqual(res["data"][0]["ref"], "WISH_1")
161
+
162
+ def test_get(self):
163
+ res = self.wishlist_service.dispatch("get", self.prod_set.id)
164
+ self.assertEqual(res["ref"], "WISH_1")
165
+
166
+ def test_delete(self):
167
+ self.wishlist_service.delete(self.prod_set.id)
168
+ self.assertFalse(self.prod_set.exists())
169
+
170
+ def test_add_to_cart(self):
171
+ prod = self.env.ref("product.product_product_4b")
172
+ # make sure no binding exists
173
+ prod.shopinvader_bind_ids.unlink()
174
+
175
+ with self.work_on_services(partner=self.partner) as work:
176
+ cart_service = work.component(usage="cart")
177
+ cart = cart_service._get()
178
+ # no line yet
179
+ self.assertFalse(cart.order_line)
180
+
181
+ # make sure the wishlist service use the same cart
182
+ with mock.patch.object(type(cart_service), "_get") as mocked:
183
+ mocked.return_value = cart
184
+ self.wishlist_service.add_to_cart(self.prod_set.id)
185
+ # no binding for the product -> no line added
186
+ self.assertFalse(cart.order_line)
187
+ # bind the product and try again
188
+ self._bind_products(prod)
189
+ self.wishlist_service.add_to_cart(self.prod_set.id)
190
+ self.assertEqual(cart.order_line[0].product_id, prod)
191
+
192
+ def test_add_items_to_cart(self):
193
+ for line in self.wl_params["lines"]:
194
+ self.prod_set.set_line_ids.create(
195
+ dict(line, product_set_id=self.prod_set.id)
196
+ )
197
+ self.assertEqual(len(self.prod_set.set_line_ids), 3)
198
+ with self.work_on_services(partner=self.partner) as work:
199
+ cart_service = work.component(usage="cart")
200
+ cart = cart_service._get()
201
+ # no line yet
202
+ self.assertFalse(cart.order_line)
203
+
204
+ # add only to products to cart
205
+ prods = self.prod_set.set_line_ids[:2].mapped("product_id")
206
+ params = {"lines": [{"product_id": x.id} for x in prods]}
207
+ with mock.patch.object(type(cart_service), "_get") as mocked:
208
+ mocked.return_value = cart
209
+ self.wishlist_service.add_items_to_cart(self.prod_set.id, **params)
210
+ self.assertEqual(cart.mapped("order_line.product_id"), prods)
211
+
212
+ def test_add_items(self):
213
+ prod1 = self.env.ref("product.product_product_4d")
214
+ prod2 = self.env.ref("product.product_product_11")
215
+ self.assertNotIn(
216
+ prod1, self.prod_set.mapped("set_line_ids.product_id")
217
+ )
218
+ self.assertNotIn(
219
+ prod2, self.prod_set.mapped("set_line_ids.product_id")
220
+ )
221
+ self._bind_products(prod1 + prod2)
222
+ params = {
223
+ "lines": [{"product_id": prod1.id}, {"product_id": prod2.id}]
224
+ }
225
+ self.wishlist_service.dispatch(
226
+ "add_items", self.prod_set.id, params=params
227
+ )
228
+ self.assertIn(prod1, self.prod_set.mapped("set_line_ids.product_id"))
229
+ self.assertIn(prod2, self.prod_set.mapped("set_line_ids.product_id"))
230
+
231
+ def _test_update_items(self, prods, lines_data):
232
+ self._bind_products(prods)
233
+ params = {"lines": lines_data}
234
+ self.wishlist_service.dispatch(
235
+ "update_items", self.prod_set.id, params=params
236
+ )
237
+ for line in lines_data:
238
+ line = self.prod_set.get_lines_by_products(
239
+ product_ids=[line["product_id"]]
240
+ )
241
+ self.assertEqual(line.quantity, line["quantity"])
242
+
243
+ def test_update_items(self):
244
+ with self.assertRaises(NotFound):
245
+ self.wishlist_service.dispatch(
246
+ "update_items",
247
+ self.prod_set.id,
248
+ params={"lines": [{"product_id": 9999}]},
249
+ )
250
+ for line in self.wl_params["lines"]:
251
+ self.prod_set.set_line_ids.create(
252
+ dict(line, product_set_id=self.prod_set.id)
253
+ )
254
+ prod1 = self.env.ref("product.product_product_4b")
255
+ prod2 = self.env.ref("product.product_product_11")
256
+ prod3 = self.env.ref("product.product_product_13")
257
+ lines = [
258
+ {"product_id": prod1.id, "quantity": 10},
259
+ {"product_id": prod2.id, "quantity": 15},
260
+ {"product_id": prod3.id, "quantity": 20},
261
+ ]
262
+ self._test_update_items(prod1 + prod2 + prod3, lines)
263
+
264
+ def test_update_item_order(self):
265
+ prod1 = self.env.ref("product.product_product_4b")
266
+ self._test_update_items(
267
+ prod1, [{"product_id": prod1.id, "quantity": 1}]
268
+ )
269
+ line1 = self.prod_set.get_lines_by_products(product_ids=prod1.ids)
270
+ line1.sequence = 10
271
+ # Add another line and change order
272
+ prod2 = self.env.ref("product.product_product_4d")
273
+ self.assertNotIn(
274
+ prod2, self.prod_set.mapped("set_line_ids.product_id")
275
+ )
276
+ self._bind_products(prod2)
277
+ params = {"lines": [{"product_id": prod2.id}]}
278
+ before = self.wishlist_service.dispatch(
279
+ "add_items", self.prod_set.id, params=params
280
+ )
281
+ line2 = self.prod_set.get_lines_by_products(product_ids=prod2.ids)
282
+ self.assertEqual(line1.sequence, 10)
283
+ self.assertEqual(line2.sequence, 0)
284
+ self.assertEqual(
285
+ [x["id"] for x in before["lines"]], [line2.id, line1.id]
286
+ )
287
+ params = {"lines": [{"product_id": prod2.id, "sequence": 20}]}
288
+ after = self.wishlist_service.dispatch(
289
+ "update_items", self.prod_set.id, params=params
290
+ )
291
+ self.prod_set.invalidate_cache()
292
+ self.assertEqual(line1.sequence, 10)
293
+ self.assertEqual(line2.sequence, 20)
294
+ self.assertEqual(
295
+ [x["id"] for x in after["lines"]], [line1.id, line2.id]
296
+ )
297
+
298
+ def test_delete_items(self):
299
+ prod = self.env.ref("product.product_product_4b")
300
+ self._bind_products(prod)
301
+ self.assertIn(prod, self.prod_set.mapped("set_line_ids.product_id"))
302
+ line = self.prod_set.get_lines_by_products(product_ids=prod.ids)
303
+ self.assertEqual(line.quantity, 1)
304
+ params = {"lines": [{"product_id": prod.id}]}
305
+ self.wishlist_service.dispatch(
306
+ "delete_items", self.prod_set.id, params=params
307
+ )
308
+ self.assertFalse(line.exists())
309
+
310
+ def test_jsonify(self):
311
+ res = self.wishlist_service._to_json_one(self.prod_set)
312
+ self.assertEqual(res["ref"], "WISH_1")
313
+ self.assertEqual(res["name"], "Wishlist 1")
314
+ self.assertEqual(res["typology"], "wishlist")
315
+ self.assertEqual(
316
+ res["access"], {"read": True, "update": True, "delete": True}
317
+ )
318
+ self.assertEqual(
319
+ res["partner"], {"id": self.partner.id, "name": self.partner.name}
320
+ )
321
+ prod = self.env.ref("product.product_product_4b")
322
+ variant = prod.shopinvader_bind_ids[0]
323
+ res_line = res["lines"][0]
324
+ self.assertEqual(res_line["id"], self.prod_set.set_line_ids[0].id)
325
+ self.assertEqual(res_line["quantity"], 1)
326
+ self.assertEqual(res_line["sequence"], 10)
327
+ self.assertEqual(
328
+ res_line["product"], dict(variant.get_shop_data(), available=True)
329
+ )
330
+
331
+ def test_jsonify_variant_archived(self):
332
+ prod = self.env.ref("product.product_product_4b")
333
+ variant = prod.shopinvader_bind_ids[0]
334
+ variant.active = False
335
+ res = self.wishlist_service._to_json_one(self.prod_set)
336
+ res_line = res["lines"][0]
337
+ self.assertEqual(
338
+ res_line["product"], dict(variant.get_shop_data(), available=False)
339
+ )
340
+
341
+ def test_jsonify_missing_variant_binding(self):
342
+ prod = self.env.ref("product.product_product_4b")
343
+ prod.shopinvader_bind_ids.unlink()
344
+ res = self.wishlist_service._to_json_one(self.prod_set)
345
+ res_line = res["lines"][0]
346
+ self.assertEqual(
347
+ res_line["product"],
348
+ {"id": prod.id, "name": prod.name, "available": False},
349
+ )
350
+
351
+ def test_jsonify_data_mode(self):
352
+ res = self.wishlist_service._to_json_one(
353
+ self.prod_set, data_mode="light"
354
+ )
355
+ self.assertEqual(
356
+ res,
357
+ {
358
+ "id": self.prod_set.id,
359
+ "name": self.prod_set.name,
360
+ "access": {"read": True, "update": True, "delete": True},
361
+ "partner": {"id": self.partner.id, "name": self.partner.name},
362
+ },
363
+ )
364
+ msg = "JSON data mode `fancy` not found."
365
+ with self.assertRaisesRegex(exceptions.UserError, msg):
366
+ self.wishlist_service._to_json_one(
367
+ self.prod_set, data_mode="fancy"
368
+ )
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <odoo>
3
+
4
+ <record id="view_product_set_variant_form" model="ir.ui.view">
5
+ <field name="name">product.set.form shopinvader_wishlist</field>
6
+ <field name="model">product.set</field>
7
+ <field name="inherit_id" ref="sale_product_set.view_product_set_form"/>
8
+ <field name="arch" type="xml">
9
+ <field name="name" position="before">
10
+ <field name="shopinvader_backend_id"/>
11
+ </field>
12
+ </field>
13
+ </record>
14
+
15
+ </odoo>
@@ -0,0 +1 @@
1
+ from . import product_set_add
@@ -0,0 +1,24 @@
1
+ # Copyright 2019 Camptocamp (http://www.camptocamp.com).
2
+ # @author Simone Orsi <simone.orsi@camptocamp.com>
3
+ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
4
+
5
+ from odoo import fields, models
6
+
7
+
8
+ class ProductSetAdd(models.TransientModel):
9
+ _inherit = "product.set.add"
10
+
11
+ shopinvader_backend_id = fields.Many2one(
12
+ related="product_set_id.shopinvader_backend_id"
13
+ )
14
+
15
+ def _get_lines(self):
16
+ lines = super()._get_lines()
17
+ if self.shopinvader_backend_id:
18
+ # consider only product lines that are allowed
19
+ # for current backend and partner
20
+ for line in lines:
21
+ if line.product_id._add_to_cart_allowed(
22
+ self.shopinvader_backend_id, partner=self.partner_id
23
+ ):
24
+ yield line
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <odoo>
3
+ <record id="product_set_add_form_view" model="ir.ui.view">
4
+ <field name="name">product.set.add.form.view shopinvader wishlist</field>
5
+ <field name="model">product.set.add</field>
6
+ <field name="inherit_id" ref="sale_product_set.product_set_add_form_view"/>
7
+ <field name="arch" type="xml">
8
+ <field name="product_set_id" position="before">
9
+ <field name="shopinvader_backend_id"/>
10
+ </field>
11
+ </field>
12
+ </record>
13
+ </odoo>
@@ -0,0 +1,86 @@
1
+ Metadata-Version: 2.1
2
+ Name: odoo13-addon-shopinvader_wishlist
3
+ Version: 13.0.3.4.2.dev1
4
+ Summary: Handle shop wishlist
5
+ Home-page: https://github.com/shopinvader/odoo-shopinvader
6
+ Author: Camptocamp,Odoo Community Association (OCA)
7
+ Author-email: support@odoo-community.org
8
+ License: AGPL-3
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Framework :: Odoo
11
+ Classifier: Framework :: Odoo :: 13.0
12
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3
13
+ Requires-Python: >=3.5
14
+ Requires-Dist: odoo13-addon-sale-wishlist
15
+ Requires-Dist: odoo13-addon-shopinvader
16
+ Requires-Dist: odoo<13.1dev,>=13.0a
17
+
18
+ ====================
19
+ Shopinvader Wishlist
20
+ ====================
21
+
22
+ ..
23
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
24
+ !! This file is generated by oca-gen-addon-readme !!
25
+ !! changes will be overwritten. !!
26
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27
+ !! source digest: sha256:659f1a86278f41835a64306a7c85a95392ac9cf2852287596fdcd52019c888ea
28
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
29
+
30
+ .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
31
+ :target: https://odoo-community.org/page/development-status
32
+ :alt: Beta
33
+ .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
34
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
35
+ :alt: License: AGPL-3
36
+ .. |badge3| image:: https://img.shields.io/badge/github-shopinvader%2Fodoo--shopinvader-lightgray.png?logo=github
37
+ :target: https://github.com/shopinvader/odoo-shopinvader/tree/13.0/shopinvader_wishlist
38
+ :alt: shopinvader/odoo-shopinvader
39
+
40
+ |badge1| |badge2| |badge3|
41
+
42
+ Expose wishlist features for Shopinvader websites.
43
+
44
+ **Table of contents**
45
+
46
+ .. contents::
47
+ :local:
48
+
49
+ Bug Tracker
50
+ ===========
51
+
52
+ Bugs are tracked on `GitHub Issues <https://github.com/shopinvader/odoo-shopinvader/issues>`_.
53
+ In case of trouble, please check there if your issue has already been reported.
54
+ If you spotted it first, help us to smash it by providing a detailed and welcomed
55
+ `feedback <https://github.com/shopinvader/odoo-shopinvader/issues/new?body=module:%20shopinvader_wishlist%0Aversion:%2013.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
56
+
57
+ Do not contact contributors directly about support or help with technical issues.
58
+
59
+ Credits
60
+ =======
61
+
62
+ Authors
63
+ ~~~~~~~
64
+
65
+ * Camptocamp
66
+
67
+ Contributors
68
+ ~~~~~~~~~~~~
69
+
70
+ * Simone Orsi <simone.orsi@camptocamp.com>
71
+ * Laurent Mignon <laurent.mignon@acsone.com>
72
+
73
+ Other credits
74
+ ~~~~~~~~~~~~~
75
+
76
+ The development of this module has been financially supported by:
77
+
78
+ * Camptocamp
79
+ * Cosanum
80
+
81
+ Maintainers
82
+ ~~~~~~~~~~~
83
+
84
+ This module is part of the `shopinvader/odoo-shopinvader <https://github.com/shopinvader/odoo-shopinvader/tree/13.0/shopinvader_wishlist>`_ project on GitHub.
85
+
86
+ You are welcome to contribute.
@@ -0,0 +1,27 @@
1
+ odoo/addons/shopinvader_wishlist/README.rst,sha256=GJMZUXc0_0Bji82Ji8q6I9WGDs2cqr7DckuETElKbyU,2229
2
+ odoo/addons/shopinvader_wishlist/__init__.py,sha256=ND64XbQE62LEt8umUkKedqmFbVnWZ81EwlRfnzCvUF0,90
3
+ odoo/addons/shopinvader_wishlist/__manifest__.py,sha256=-3AcynlRPxoSne-yd6tce_jmKncKy4xs5_5e8sVRcHE,525
4
+ odoo/addons/shopinvader_wishlist/components/__init__.py,sha256=Vl6GrhTg-EYredvnBO0eZfHkE7A-bnqoR4K07hn3qZ4,26
5
+ odoo/addons/shopinvader_wishlist/components/access_info.py,sha256=z-jlYn_sQ47kHOS53X-hm-7JqQHiOXZEDGt4Tu-bsnI,636
6
+ odoo/addons/shopinvader_wishlist/demo/product_set.xml,sha256=40Ys3UVOI-2VlhzedaZXx42hg6RpdVAYhUGLI6HF-Mo,559
7
+ odoo/addons/shopinvader_wishlist/i18n/shopinvader_wishlist.pot,sha256=6Xsi78Glh7FJQnN9D60Y0xAOStY9o_7aOn3PxwkztGw,2089
8
+ odoo/addons/shopinvader_wishlist/models/__init__.py,sha256=-eK0PQgPiingrDkPSjl7Va-qbxEiJP9Q9TPwLdaPPcA,26
9
+ odoo/addons/shopinvader_wishlist/models/product_set.py,sha256=YYUlQ7GIVx8_5XtW4v9OzxKN-4idSvDybJwu8c6ble8,2784
10
+ odoo/addons/shopinvader_wishlist/readme/CONTRIBUTORS.rst,sha256=WVWnMarLQfkwIEZs7iVVmBUbiuIaZVhyaxAGKqtv3bE,88
11
+ odoo/addons/shopinvader_wishlist/readme/CREDITS.rst,sha256=ZAK1Hn1oanVuW1XWIUkJBuloudzmHeu1U1JNkBEaun8,90
12
+ odoo/addons/shopinvader_wishlist/readme/DESCRIPTION.rst,sha256=Ey--fWLZ2tOwOv3uWWmoK0fE7hT4S3PT-lK27MQ09yE,51
13
+ odoo/addons/shopinvader_wishlist/services/__init__.py,sha256=0zrA78yXKcR3mfGnTXD7U17UTEdxJq5pZ-Cig1oALEE,23
14
+ odoo/addons/shopinvader_wishlist/services/wishlist.py,sha256=Xpmjeh67QwM2v9JYNHtth1q4gbV_vEXiJogHgLQe5r0,18254
15
+ odoo/addons/shopinvader_wishlist/static/description/icon.png,sha256=6xBPJauaFOF0KDHfHgQopSc28kKvxMaeoQFQWZtfZDo,9455
16
+ odoo/addons/shopinvader_wishlist/static/description/index.html,sha256=Va8I43sP3ZLyf6Q4i6i4zaZ7c4XuyjDcU7V2Rl1vjz8,11674
17
+ odoo/addons/shopinvader_wishlist/tests/__init__.py,sha256=-Xa8yeSzC5UZ2CZ-i2nEQdrS_295YzwMe1mxNm1PoVk,59
18
+ odoo/addons/shopinvader_wishlist/tests/test_product_set.py,sha256=LM7dQoT0rDWQ8PrP3g2Hra-B8mwu4BYRxprNBSbzAsw,4474
19
+ odoo/addons/shopinvader_wishlist/tests/test_wishlist.py,sha256=C3bpts9GyAfNHyumcmWbz9UcXPNJU5ak0vGviIixe1M,14806
20
+ odoo/addons/shopinvader_wishlist/views/product_set.xml,sha256=hFAqCiWjjQ-zHGGgjLN32N3a6XbNlrcy4MJy5ub8d0s,476
21
+ odoo/addons/shopinvader_wishlist/wizard/__init__.py,sha256=0I_cOZStU0w-tzPh31rdSqAcv0RA_O1vX_78GDUg9FI,30
22
+ odoo/addons/shopinvader_wishlist/wizard/product_set_add.py,sha256=Lhc-Inho-Pxb3AW7RQfT4ZM8-T8-zUhVFxFKUwT_5cU,813
23
+ odoo/addons/shopinvader_wishlist/wizard/product_set_add.xml,sha256=WbdDXLb_iGLIwGsBTS9n3ci9syM6R6E8ROsyxLJjlpg,497
24
+ odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/METADATA,sha256=sYVr0qs0cZXM7CCMza26p3Cu44w6c48jHLSWT7NBQXo,2843
25
+ odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
26
+ odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/top_level.txt,sha256=qBj40grFkGOfDZ2WDSw3y1RnDlgG0u8rP8pvGNdbz4w,5
27
+ odoo13_addon_shopinvader_wishlist-13.0.3.4.2.dev1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.45.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+