diff --git a/src/budy/models/__init__.py b/src/budy/models/__init__.py
index 24ed2b35..4366dba2 100644
--- a/src/budy/models/__init__.py
+++ b/src/budy/models/__init__.py
@@ -61,6 +61,8 @@
from . import store
from . import subscription
from . import voucher
+from . import wishlist_line
+from . import wishlist
from .account import BudyAccount
from .address import Address
@@ -89,3 +91,5 @@
from .store import Store
from .subscription import Subscription
from .voucher import Voucher
+from .wishlist_line import WishlistLine
+from .wishlist import Wishlist
diff --git a/src/budy/models/wishlist.py b/src/budy/models/wishlist.py
new file mode 100644
index 00000000..56fbeda0
--- /dev/null
+++ b/src/budy/models/wishlist.py
@@ -0,0 +1,137 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Hive Budy
+# Copyright (c) 2008-2016 Hive Solutions Lda.
+#
+# This file is part of Hive Budy.
+#
+# Hive Budy is free software: you can redistribute it and/or modify
+# it under the terms of the Apache License as published by the Apache
+# Foundation, either version 2.0 of the License, or (at your option) any
+# later version.
+#
+# Hive Budy is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# Apache License for more details.
+#
+# You should have received a copy of the Apache License along with
+# Hive Budy. If not, see .
+
+__author__ = "João Magalhães "
+""" The author(s) of the module """
+
+__version__ = "1.0.0"
+""" The version of the module """
+
+__revision__ = "$LastChangedRevision$"
+""" The revision number of the module """
+
+__date__ = "$LastChangedDate$"
+""" The last change date of the module """
+
+__copyright__ = "Copyright (c) 2008-2016 Hive Solutions Lda."
+""" The copyright for the module """
+
+__license__ = "Apache License, Version 2.0"
+""" The license for the module """
+
+import appier
+import appier_extras
+
+from . import bundle
+from . import wishlist_line
+
+class Wishlist(bundle.Bundle):
+
+ lines = appier.field(
+ type = appier.references(
+ "WishlistLine",
+ name = "id"
+ ),
+ eager = True
+ )
+
+ account = appier.field(
+ type = appier.reference(
+ "BudyAccount",
+ name = "id"
+ ),
+ eager = True
+ )
+
+ @classmethod
+ def list_names(cls):
+ return ["id", "key", "total", "currency", "account"]
+
+ @classmethod
+ def line_cls(cls):
+ return wishlist_line.WishlistLine
+
+ @classmethod
+ def from_session(cls, ensure = True, raise_e = False):
+ from . import BudyAccount
+ account = BudyAccount.from_session(raise_e = raise_e)
+ if account: return account.ensure_wishlist_s()
+ session = appier.get_session()
+ key = session.get("wishlist", None)
+ wishlist = cls.get(key = key, raise_e = raise_e) if key else None
+ if wishlist: return wishlist
+ if not ensure: return None
+ wishlist = cls()
+ wishlist.save()
+ session["wishlist"] = wishlist.key
+ return wishlist
+
+ @classmethod
+ def ensure_s(cls, key = None):
+ from . import BudyAccount
+ account = BudyAccount.from_session(raise_e = False)
+ if account: return account.ensure_wishlist_s(key = key)
+ wishlist = cls(key = key)
+ wishlist.save()
+ return wishlist
+
+ def pre_validate(self):
+ bundle.Bundle.pre_validate(self)
+ self.try_valid()
+
+ def pre_delete(self):
+ bundle.Bundle.pre_delete(self)
+ for line in self.lines: line.delete()
+
+ def add_line_s(self, line):
+ line.wishlist = self
+ return bundle.Bundle.add_line_s(self, line)
+
+ @appier.operation(name = "Garbage Collect")
+ def collect_s(self):
+ self.delete()
+
+ @appier.operation(name = "Fix Orphans")
+ def fix_orphans_s(self):
+ for line in self.lines:
+ line.wishlist = self
+ line.save()
+
+ @appier.operation(name = "Notify")
+ def notify(self, name = None):
+ name = name or "wishlist.new"
+ wishlist = self.reload(map = True)
+ account = wishlist.get("account", {})
+ receiver = account.get("email", None)
+ appier_extras.admin.Event.notify_g(
+ name,
+ arguments = dict(
+ params = dict(
+ payload = wishlist,
+ wishlist = wishlist,
+ receiver = receiver
+ )
+ )
+ )
+
+ @appier.operation(name = "Remind")
+ def remind(self):
+ self.notify("wishlist.remind")
diff --git a/src/budy/models/wishlist_line.py b/src/budy/models/wishlist_line.py
new file mode 100644
index 00000000..e7c7c439
--- /dev/null
+++ b/src/budy/models/wishlist_line.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Hive Budy
+# Copyright (c) 2008-2016 Hive Solutions Lda.
+#
+# This file is part of Hive Budy.
+#
+# Hive Budy is free software: you can redistribute it and/or modify
+# it under the terms of the Apache License as published by the Apache
+# Foundation, either version 2.0 of the License, or (at your option) any
+# later version.
+#
+# Hive Budy is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# Apache License for more details.
+#
+# You should have received a copy of the Apache License along with
+# Hive Budy. If not, see .
+
+__author__ = "João Magalhães "
+""" The author(s) of the module """
+
+__version__ = "1.0.0"
+""" The version of the module """
+
+__revision__ = "$LastChangedRevision$"
+""" The revision number of the module """
+
+__date__ = "$LastChangedDate$"
+""" The last change date of the module """
+
+__copyright__ = "Copyright (c) 2008-2016 Hive Solutions Lda."
+""" The copyright for the module """
+
+__license__ = "Apache License, Version 2.0"
+""" The license for the module """
+
+import appier
+
+from . import bundle_line
+
+class WishlistLine(bundle_line.BundleLine):
+
+ wishlist = appier.field(
+ type = appier.reference(
+ "Wishlist",
+ name = "id"
+ )
+ )
+
+ @classmethod
+ def list_names(cls):
+ return ["id", "quantity", "total", "currency", "product", "wishlist"]
+
+ def pre_validate(self):
+ bundle_line.BundleLine.pre_validate(self)
+ self.try_valid()
+
+ @appier.operation(name = "Garbage Collect")
+ def collect_s(self):
+ if self.wishlist: return
+ self.delete()
diff --git a/src/budy/test/wishlist.py b/src/budy/test/wishlist.py
new file mode 100644
index 00000000..88033921
--- /dev/null
+++ b/src/budy/test/wishlist.py
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Hive Budy
+# Copyright (c) 2008-2016 Hive Solutions Lda.
+#
+# This file is part of Hive Budy.
+#
+# Hive Budy is free software: you can redistribute it and/or modify
+# it under the terms of the Apache License as published by the Apache
+# Foundation, either version 2.0 of the License, or (at your option) any
+# later version.
+#
+# Hive Budy is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# Apache License for more details.
+#
+# You should have received a copy of the Apache License along with
+# Hive Budy. If not, see .
+
+__author__ = "João Magalhães "
+""" The author(s) of the module """
+
+__version__ = "1.0.0"
+""" The version of the module """
+
+__revision__ = "$LastChangedRevision$"
+""" The revision number of the module """
+
+__date__ = "$LastChangedDate$"
+""" The last change date of the module """
+
+__copyright__ = "Copyright (c) 2008-2016 Hive Solutions Lda."
+""" The copyright for the module """
+
+__license__ = "Apache License, Version 2.0"
+""" The license for the module """
+
+import commons
+import logging
+import unittest
+
+import appier
+
+import budy
+
+class WishlistTest(unittest.TestCase):
+
+ def setUp(self):
+ self.app = budy.BudyApp(level = logging.ERROR)
+
+ def tearDown(self):
+ self.app.unload()
+ adapter = appier.get_adapter()
+ adapter.drop_db()
+
+ def test_basic(self):
+ product = budy.Product(
+ short_description = "product",
+ gender = "Male",
+ price = 10.0
+ )
+ product.save()
+
+ self.assertEqual(product.short_description, "product")
+ self.assertEqual(product.gender, "Male")
+ self.assertEqual(product.price, 10.0)
+
+ wishlist = budy.Wishlist()
+ wishlist.save()
+
+ self.assertEqual(type(wishlist.key), appier.legacy.UNICODE)
+ self.assertEqual(type(wishlist.total), commons.Decimal)
+ self.assertEqual(len(wishlist.lines), 0)
+ self.assertEqual(wishlist.currency, None)
+ self.assertEqual(wishlist.total >= 0.0, True)
+
+ wishlist_line = budy.WishlistLine(
+ quantity = 2.0
+ )
+ wishlist_line.product = product
+ wishlist_line.save()
+ wishlist.add_line_s(wishlist_line)
+
+ self.assertEqual(wishlist_line.quantity, 2.0)
+ self.assertEqual(wishlist_line.total, 20.0)
+ self.assertEqual(wishlist.total, 20.0)
+ self.assertEqual(len(wishlist.lines), 1)
+
+ wishlist.add_product_s(product, 3.0)
+
+ self.assertEqual(wishlist.total, 50.0)
+ self.assertEqual(len(wishlist.lines), 1)
+
+ product_expensive = budy.Product(
+ short_description = "product_expensive",
+ gender = "Female",
+ price = 100.0
+ )
+ product_expensive.save()
+
+ self.assertEqual(product_expensive.short_description, "product_expensive")
+ self.assertEqual(product_expensive.gender, "Female")
+ self.assertEqual(product_expensive.price, 100.0)
+
+ wishlist.add_product_s(product_expensive, 1.0)
+
+ self.assertEqual(wishlist.total, 150.0)
+ self.assertEqual(len(wishlist.lines), 2)
+
+ wishlist.empty_s()
+
+ self.assertEqual(wishlist.total, 0.0)
+ self.assertEqual(len(wishlist.lines), 0)