Skip to content

Commit dbc6921

Browse files
authored
Voucher improvements (#43)
- Expanded voucher attributes and operations
1 parent 4cb39d9 commit dbc6921

5 files changed

Lines changed: 296 additions & 19 deletions

File tree

src/budy/controllers/api/voucher.py

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ def create(self):
5151
voucher = voucher.map()
5252
return voucher
5353

54-
@appier.route("/api/vouchers/<int:id>", "GET", json=True)
54+
@appier.route("/api/vouchers/<str:key>", "GET", json=True)
5555
@appier.ensure(token="admin")
56-
def show(self, id):
57-
voucher = budy.Voucher.get_e(id=id, map=True)
56+
def show(self, key):
57+
voucher = budy.Voucher.get_e(key=key, map=True)
5858
return voucher
5959

6060
@appier.route("/api/vouchers/value", "POST", json=True)
@@ -64,12 +64,22 @@ def create_value(self):
6464
key = object.get("key", None)
6565
amount = object.get("amount", None)
6666
currency = object.get("currency", None)
67-
unlimited = object.get("unlimited", None)
68-
key = self.field("key", key)
67+
usage_limit = object.get("usage_limit", 0)
68+
unlimited = object.get("unlimited", False)
69+
start = object.get("start", None)
70+
expiration = object.get("expiration", None)
71+
meta = object.get("meta", {})
72+
key = self.field("key", key, cast=str)
6973
amount = self.field("amount", amount, cast=float)
7074
currency = self.field("currency", currency, cast=str)
75+
usage_limit = self.field("usage_limit", usage_limit, cast=int)
7176
unlimited = self.field("unlimited", unlimited, cast=bool)
72-
voucher = budy.Voucher.create_value_s(key, amount, currency, unlimited)
77+
start = self.field("start", start, cast=int)
78+
expiration = self.field("expiration", expiration, cast=int)
79+
meta = self.field("meta", meta, cast=dict)
80+
voucher = budy.Voucher.create_value_s(
81+
key, amount, currency, usage_limit, unlimited, start, expiration, meta
82+
)
7383
voucher = voucher.map()
7484
return voucher
7585

@@ -79,8 +89,45 @@ def create_percentage(self):
7989
object = appier.get_object()
8090
key = object.get("key", None)
8191
percentage = object.get("percentage", None)
82-
key = self.field("key", key)
92+
usage_limit = object.get("usage_limit", 0)
93+
start = object.get("start", None)
94+
expiration = object.get("expiration", None)
95+
meta = object.get("meta", {})
96+
unlimited = object.get("unlimited", None)
97+
key = self.field("key", key, cast=str)
8398
percentage = self.field("percentage", percentage, cast=float)
84-
voucher = budy.Voucher.create_percentage_s(key, percentage)
99+
usage_limit = self.field("usage_limit", usage_limit, cast=int)
100+
start = self.field("start", start, cast=int)
101+
expiration = self.field("expiration", expiration, cast=int)
102+
meta = self.field("meta", meta, cast=dict)
103+
unlimited = self.field("unlimited", unlimited, cast=bool)
104+
voucher = budy.Voucher.create_percentage_s(
105+
key, percentage, usage_limit, start, expiration, meta
106+
)
107+
voucher = voucher.map()
108+
return voucher
109+
110+
@appier.route("/api/vouchers/<str:key>/use", "POST", json=True)
111+
@appier.ensure(token="admin")
112+
def use(self, key):
113+
object = appier.get_object()
114+
amount = object.get("amount", None)
115+
currency = object.get("currency", None)
116+
justification = object.get("justification", None)
117+
save_use = object.get("save_use", True)
118+
voucher = budy.Voucher.get_e(key=key)
119+
voucher_use = voucher.use_s(
120+
amount, currency=currency, justification=justification, save_use=save_use
121+
)
122+
voucher = voucher.map()
123+
if voucher_use:
124+
voucher["use"] = voucher_use.map()
125+
return voucher
126+
127+
@appier.route("/api/vouchers/<str:key>/disuse", "POST", json=True)
128+
@appier.ensure(token="admin")
129+
def disuse(self, key):
130+
voucher = budy.Voucher.get_e(key=key)
131+
voucher.disuse_s()
85132
voucher = voucher.map()
86133
return voucher

src/budy/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,6 @@
8484
from .store import Store
8585
from .subscription import Subscription
8686
from .voucher import Voucher
87+
from .voucher_use import VoucherUse
8788
from .wishlist_line import WishlistLine
8889
from .wishlist import Wishlist

src/budy/models/voucher.py

Lines changed: 105 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,41 @@
3535
import appier_extras
3636

3737
from . import base
38+
from . import voucher_use
3839

3940

4041
class Voucher(base.BudyBase):
41-
key = appier.field(index=True, safe=True, immutable=True)
42+
key = appier.field(
43+
index=True,
44+
safe=True,
45+
immutable=True,
46+
observations="""The (secret) key of the voucher, considered to be
47+
the unique identifier of the voucher, this is the key that will
48+
be used to identify the voucher when it is used""",
49+
)
4250

4351
amount = appier.field(
4452
type=commons.Decimal,
4553
index=True,
4654
initial=commons.Decimal(0.0),
4755
safe=True,
4856
immutable=True,
57+
observations="""The amount of the voucher, meaning the total
58+
amount of the voucher that can be used, this is the amount
59+
that will be deducted from the order total when the voucher
60+
is used, if this value is set to zero the voucher is considered
61+
to be a percentage based voucher""",
4962
)
5063

5164
used_amount = appier.field(
52-
type=commons.Decimal, initial=commons.Decimal(0.0), index=True, safe=True
65+
type=commons.Decimal,
66+
initial=commons.Decimal(0.0),
67+
index=True,
68+
safe=True,
69+
observations="""The amount of the voucher that has been used,
70+
meaning that the remaining amount of the voucher that can be
71+
used can be calculated by subtracting the used amount from the
72+
amount""",
5373
)
5474

5575
percentage = appier.field(
@@ -58,6 +78,8 @@ class Voucher(base.BudyBase):
5878
index=True,
5979
safe=True,
6080
immutable=True,
81+
observations="""The percentage of discount to be applied when
82+
using the voucher, meaning the voucher is percentage based""",
6183
)
6284

6385
currency = appier.field(
@@ -175,12 +197,27 @@ def is_snapshot(cls):
175197
("Key", "key", str),
176198
("Amount", "amount", commons.Decimal),
177199
("Currency", "currency", str),
200+
("Usage Limit", "usage_limit", int, 0),
178201
("Unlimited", "unlimited", bool, False),
202+
("Start", "start", int, None),
203+
("Expiration", "expiration", int, None),
204+
("Metadata", "meta", dict, {}),
179205
),
180206
factory=True,
181207
)
182-
def create_value_s(cls, key, amount, currency, unlimited):
183-
voucher = cls(key=key, amount=amount, currency=currency, unlimited=unlimited)
208+
def create_value_s(
209+
cls, key, amount, currency, usage_limit, unlimited, start, expiration, meta
210+
):
211+
voucher = cls(
212+
key=key,
213+
amount=amount,
214+
currency=currency,
215+
usage_limit=usage_limit,
216+
unlimited=unlimited,
217+
start=start,
218+
expiration=expiration,
219+
meta=meta,
220+
)
184221
voucher.save()
185222
return voucher
186223

@@ -191,29 +228,62 @@ def create_value_s(cls, key, amount, currency, unlimited):
191228
("Key", "key", str),
192229
("Amount", "amount", commons.Decimal),
193230
("Currency", "currency", str),
231+
("Usage Limit", "usage_limit", int, 0),
194232
("Unlimited", "unlimited", bool, False),
233+
("Start", "start", int, None),
234+
("Expiration", "expiration", int, None),
235+
("Metadata", "meta", dict, {}),
195236
("Count", "count", int, 1),
196237
),
197238
)
198-
def create_value_multiple_s(cls, key, amount, currency, unlimited, count):
239+
def create_value_multiple_s(
240+
cls,
241+
key,
242+
amount,
243+
currency,
244+
usage_limit,
245+
unlimited,
246+
start,
247+
expiration,
248+
meta,
249+
count,
250+
):
199251
key = key or cls.secret_g()
200252
for index in appier.legacy.xrange(count):
201253
voucher = cls(
202254
key=key + "-" + str(index),
203255
amount=amount,
204256
currency=currency,
257+
usage_limit=usage_limit,
205258
unlimited=unlimited,
259+
start=start,
260+
expiration=expiration,
261+
meta=meta,
206262
)
207263
voucher.save()
208264

209265
@classmethod
210266
@appier.operation(
211267
name="Create Percentage",
212-
parameters=(("Key", "key", str), ("Percentage", "percentage", commons.Decimal)),
268+
parameters=(
269+
("Key", "key", str),
270+
("Percentage", "percentage", commons.Decimal),
271+
("Usage Limit", "usage_limit", int, 0),
272+
("Start", "start", int, None),
273+
("Expiration", "expiration", int, None),
274+
("Metadata", "meta", dict, {}),
275+
),
213276
factory=True,
214277
)
215-
def create_percentage_s(cls, key, percentage):
216-
voucher = cls(key=key, percentage=percentage)
278+
def create_percentage_s(cls, key, percentage, usage_limit, start, expiration, meta):
279+
voucher = cls(
280+
key=key,
281+
percentage=percentage,
282+
usage_limit=usage_limit,
283+
start=start,
284+
expiration=expiration,
285+
meta=meta,
286+
)
217287
voucher.save()
218288
return voucher
219289

@@ -223,13 +293,26 @@ def create_percentage_s(cls, key, percentage):
223293
parameters=(
224294
("Key", "key", str),
225295
("Percentage", "percentage", commons.Decimal),
296+
("Usage Limit", "usage_limit", int, 0),
297+
("Start", "start", int, None),
298+
("Expiration", "expiration", int, None),
299+
("Metadata", "meta", dict, {}),
226300
("Count", "count", int, 1),
227301
),
228302
)
229-
def create_percentage_multiple_s(cls, key, percentage, count):
303+
def create_percentage_multiple_s(
304+
cls, key, percentage, usage_limit, start, expiration, meta, count
305+
):
230306
key = key or cls.secret_g()
231307
for index in appier.legacy.xrange(count):
232-
voucher = cls(key=key + "-" + str(index), percentage=percentage)
308+
voucher = cls(
309+
key=key + "-" + str(index),
310+
percentage=percentage,
311+
usage_limit=usage_limit,
312+
start=start,
313+
expiration=expiration,
314+
meta=meta,
315+
)
233316
voucher.save()
234317

235318
def pre_create(self):
@@ -245,13 +328,24 @@ def pre_update(self):
245328
if self.used and not self.is_used():
246329
self.used = False
247330

248-
def use_s(self, amount, currency=None):
331+
def use_s(self, amount, currency=None, justification=None, save_use=True):
249332
amount_l = self.to_local(amount, currency)
250333
appier.verify(self.is_valid(amount=amount, currency=currency))
251334
if self.is_value and not self.unlimited:
252335
self.used_amount += commons.Decimal(amount_l)
253336
self.usage_count += 1
254337
self.save()
338+
if save_use:
339+
usage_type = "value" if self.is_value else "percentage"
340+
voucher_use_ = voucher_use.VoucherUse(
341+
usage_type=usage_type,
342+
amount=amount,
343+
currency=currency,
344+
justification=justification,
345+
voucher=self,
346+
)
347+
voucher_use_.save()
348+
return voucher_use_
255349

256350
def disuse_s(self, amount, currency=None):
257351
appier.verify(self.usage_count > 0)

0 commit comments

Comments
 (0)