• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hivesolutions / budy / 1308

pending completion
1308

push

travis-ci-com

joamag
feat: added default unset of store

6 of 6 new or added lines in 1 file covered. (100.0%)

4209 of 5946 relevant lines covered (70.79%)

5.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

20.9
/src/budy/controllers/api/order.py
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3

4
# Hive Budy
5
# Copyright (c) 2008-2020 Hive Solutions Lda.
6
#
7
# This file is part of Hive Budy.
8
#
9
# Hive Budy is free software: you can redistribute it and/or modify
10
# it under the terms of the Apache License as published by the Apache
11
# Foundation, either version 2.0 of the License, or (at your option) any
12
# later version.
13
#
14
# Hive Budy is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# Apache License for more details.
18
#
19
# You should have received a copy of the Apache License along with
20
# Hive Budy. If not, see <http://www.apache.org/licenses/>.
21

22
__author__ = "João Magalhães <joamag@hive.pt>"
8✔
23
""" The author(s) of the module """
24

25
__version__ = "1.0.0"
8✔
26
""" The version of the module """
27

28
__revision__ = "$LastChangedRevision$"
8✔
29
""" The revision number of the module """
30

31
__date__ = "$LastChangedDate$"
8✔
32
""" The last change date of the module """
33

34
__copyright__ = "Copyright (c) 2008-2020 Hive Solutions Lda."
8✔
35
""" The copyright for the module """
36

37
__license__ = "Apache License, Version 2.0"
8✔
38
""" The license for the module """
39

40
import appier
8✔
41

42
import budy
8✔
43

44
from . import root
8✔
45

46
class OrderAPIController(root.RootAPIController):
8✔
47

48
    @appier.route("/api/orders", "GET", json = True)
8✔
49
    @appier.ensure(token = "admin")
8✔
50
    def list(self):
51
        object = appier.get_object(alias = True, find = True, sort = [("id", -1)])
×
52
        orders = budy.Order.find(eager_l = True, map = True, **object)
×
53
        return orders
×
54

55
    @appier.route("/api/orders/complex.csv", "GET")
8✔
56
    @appier.ensure(token = "admin")
8✔
57
    def complex_csv(self):
58
        start = self.field("start", cast = int)
×
59
        end = self.field("end", cast = int)
×
60
        paid = self.field("paid", True, cast = bool)
×
61
        object = appier.get_object(
×
62
            alias = True,
63
            find = True,
64
            limit = 0,
65
            sort = [("id", -1)]
66
        )
67
        id = object.get("id", {})
×
68
        if start: id["$gte"] = start
×
69
        if end: id["$lte"] = end
×
70
        if start or end: object["id"] = id
×
71
        if paid: object["paid"] = True
×
72
        orders = budy.Order.find(**object)
×
73
        orders_s = [(
×
74
            "id",
75
            "reference",
76
            "date",
77
            "status",
78
            "email",
79
            "account",
80
            "store",
81
            "product",
82
            "gender",
83
            "size",
84
            "quantity",
85
            "total",
86
            "taxes",
87
            "currency",
88
            "first_name",
89
            "last_name",
90
            "billing_address",
91
            "billing_city",
92
            "billing_state",
93
            "billing_postal_code",
94
            "billing_country",
95
            "billing_phone",
96
            "shipping_address",
97
            "shipping_city",
98
            "shipping_state",
99
            "shipping_postal_code",
100
            "shipping_country",
101
            "shipping_phone",
102
            "shipping_cost"
103
        )]
104
        for order in orders:
×
105
            for line in order.lines:
×
106
                if not line.product: continue
×
107
                account = order.account
×
108
                shipping_address = order.shipping_address
×
109
                billing_address = order.billing_address
×
110
                shipping_cost = order.shipping_cost
×
111
                order_s = (
×
112
                    order.id,
113
                    order.reference,
114
                    order.created_d.strftime("%d/%m/%Y"),
115
                    order.status,
116
                    order.email,
117
                    account.username,
118
                    order.store and order.store.name,
119
                    line.product.short_description,
120
                    line.product.gender,
121
                    line.size,
122
                    line.quantity,
123
                    line.total,
124
                    line.taxes,
125
                    line.currency,
126
                    billing_address.first_name,
127
                    billing_address.last_name,
128
                    billing_address.address,
129
                    billing_address.city,
130
                    billing_address.state,
131
                    billing_address.postal_code,
132
                    billing_address.country,
133
                    billing_address.phone_number,
134
                    shipping_address and shipping_address.address,
135
                    shipping_address and shipping_address.city,
136
                    shipping_address and shipping_address.state,
137
                    shipping_address and shipping_address.postal_code,
138
                    shipping_address and shipping_address.country,
139
                    shipping_address and shipping_address.phone_number,
140
                    shipping_cost
141
                )
142
                orders_s.append(order_s)
×
143
        result = appier.serialize_csv(orders_s, delimiter = ",")
×
144
        self.content_type("text/csv")
×
145
        return result
×
146

147
    @appier.route("/api/orders/ctt.csv", "GET")
8✔
148
    @appier.ensure(token = "admin")
8✔
149
    def ctt_csv(self):
150
        start = self.field("start", cast = int)
×
151
        end = self.field("end", cast = int)
×
152
        paid = self.field("paid", True, cast = bool)
×
153
        sms = self.field("sms", False, cast = bool)
×
154
        quantity = self.field("quantity", 1, cast = int)
×
155
        weight = self.field("weight", 100, cast = int)
×
156
        object = appier.get_object(
×
157
            alias = True,
158
            find = True,
159
            limit = 0,
160
            sort = [("id", -1)]
161
        )
162
        id = object.get("id", {})
×
163
        if start: id["$gte"] = start
×
164
        if end: id["$lte"] = end
×
165
        if start or end: object["id"] = id
×
166
        if paid: object["paid"] = True
×
167
        orders = self.admin_part._find_view(budy.Order, **object)
×
168
        orders_s = []
×
169
        for order in orders:
×
170
            shipping_address = order.shipping_address
×
171
            postal_code = shipping_address.postal_code or ""
×
172
            if not "-" in postal_code: postal_code += "-"
×
173
            weight_s = "%.2f" % (order.quantity * weight)
×
174
            weight_s = weight_s.replace(".", ",")
×
175
            line = dict(
×
176
                reference = order.reference,
177
                quantity = int(order.quantity) if quantity == None else quantity,
178
                weight = weight_s,
179
                price = "0ue",
180
                destiny = shipping_address.full_name[:60],
181
                title = order.account.title[:20],
182
                name = shipping_address.full_name[:60],
183
                address = shipping_address.address[:60],
184
                town = shipping_address.city[:50],
185
                zip_code_4 = postal_code.split("-", 1)[0][:4],
186
                zip_code_3 = postal_code.split("-", 1)[1][:3],
187
                not_applicable_1 = "",
188
                observations = "",
189
                back = 0,
190
                document_code = "",
191
                phone_number = (shipping_address.phone_number or "").replace("+", "00")[:15],
192
                saturday = 0,
193
                email = (order.email or "")[:200],
194
                country = order.country,
195
                fragile = 0,
196
                not_applicable_2 = "",
197
                document_collection = "",
198
                code_email = "",
199
                mobile_phone = (shipping_address.phone_number or "").replace("+", "00")[:15],
200
                second_delivery = 0,
201
                delivery_date = "",
202
                return_signed_document = 0,
203
                expeditor_instructions = 0,
204
                sms = 1 if sms else 0,
205
                not_applicable_3 = "",
206
                printer = "",
207
                ticket_machine = "",
208
                at_code = ""
209
            )
210
            order_s = (
×
211
                line["reference"],
212
                str(line["quantity"]),
213
                line["weight"],
214
                line["price"],
215
                line["destiny"],
216
                line["title"],
217
                line["name"],
218
                line["address"],
219
                line["town"],
220
                line["zip_code_4"],
221
                line["zip_code_3"],
222
                line["not_applicable_1"],
223
                line["observations"],
224
                str(line["back"]),
225
                line["document_code"],
226
                line["phone_number"],
227
                str(line["saturday"]),
228
                line["email"],
229
                line["country"],
230
                str(line["fragile"]),
231
                line["not_applicable_2"],
232
                line["document_collection"],
233
                line["code_email"],
234
                line["mobile_phone"],
235
                str(line["second_delivery"]),
236
                line["delivery_date"],
237
                str(line["return_signed_document"]),
238
                str(line["expeditor_instructions"]),
239
                str(line["sms"]),
240
                line["not_applicable_3"],
241
                line["printer"],
242
                line["ticket_machine"],
243
                line["at_code"]
244
            )
245
            orders_s.append(order_s)
×
246
        result = appier.serialize_csv(
×
247
            orders_s,
248
            encoding = "Cp1252",
249
            errors = "ignore",
250
            delimiter = "+"
251
        )
252
        result = appier.legacy.bytes(
×
253
            result,
254
            encoding = "Cp1252",
255
            errors = "ignore"
256
        )
257
        self.content_type("text/csv")
×
258
        return result
×
259

260
    @appier.route("/api/orders/<str:key>", "GET", json = True)
8✔
261
    def show(self, key):
262
        order = budy.Order.get(key = key)
×
263
        order.refresh_s(
×
264
            currency = order.payment_currency or self.currency,
265
            country = order.shipping_country or self.country
266
        )
267
        order = order.reload(
×
268
            eager = (
269
                "lines.product.images",
270
                "lines.product.brand"
271
            ),
272
            map = True
273
        )
274
        return order
×
275

276
    @appier.route("/api/orders/<str:key>/store", "PUT", json = True)
8✔
277
    @appier.ensure(token = "user")
8✔
278
    def set_store(self, key):
279
        data = appier.request_json()
×
280
        store_id = data["store_id"]
×
281
        store = budy.Store.get(id = store_id)
×
282
        order = budy.Order.get(key = key, rules = False)
×
283
        order.store = store
×
284
        order.save()
×
285
        order = order.reload(map = True)
×
286
        return order
×
287

288
    @appier.route("/api/orders/<str:key>/shipping_address", "PUT", json = True)
8✔
289
    @appier.ensure(token = "user")
8✔
290
    def set_shipping_address(self, key):
291
        data = appier.request_json()
×
292
        unset_store = data.get("unset_store", True)
×
293
        address = budy.Address.new()
×
294
        address.save()
×
295
        order = budy.Order.get(key = key, rules = False)
×
296
        order.shipping_address = address
×
297
        if unset_store: order.store = None
×
298
        order.save()
×
299
        order = order.reload(map = True)
×
300
        return order
×
301

302
    @appier.route("/api/orders/<str:key>/billing_address", "PUT", json = True)
8✔
303
    @appier.ensure(token = "user")
8✔
304
    def set_billing_address(self, key):
305
        data = appier.request_json()
×
306
        unset_store = data.get("unset_store", False)
×
307
        address = budy.Address.new()
×
308
        address.save()
×
309
        order = budy.Order.get(key = key, rules = False)
×
310
        order.billing_address = address
×
311
        if unset_store: order.store = None
×
312
        order.save()
×
313
        order = order.reload(map = True)
×
314
        return order
×
315

316
    @appier.route("/api/orders/<str:key>/store_shipping", "PUT", json = True)
8✔
317
    @appier.ensure(token = "user")
8✔
318
    def set_store_shipping(self, key):
319
        order = budy.Order.get(key = key, rules = False)
×
320
        order.verify_store()
×
321
        store = order.store
×
322
        address = store.address.clone()
×
323
        address.save()
×
324
        order.shipping_address = address
×
325
        order.save()
×
326
        order = order.reload(map = True)
×
327
        return order
×
328

329
    @appier.route("/api/orders/<str:key>/store_billing", "PUT", json = True)
8✔
330
    @appier.ensure(token = "user")
8✔
331
    def set_store_billing(self, key):
332
        order = budy.Order.get(key = key, rules = False)
×
333
        order.verify_store()
×
334
        store = order.store
×
335
        address = store.address.clone()
×
336
        address.save()
×
337
        order.billing_address = address
×
338
        order.save()
×
339
        order = order.reload(map = True)
×
340
        return order
×
341

342
    @appier.route("/api/orders/<str:key>/ip_address", "PUT", json = True)
8✔
343
    @appier.ensure(token = "user")
8✔
344
    def set_ip_address(self, key):
345
        data = appier.request_json()
×
346
        ip_address = data["ip_address"]
×
347
        order = budy.Order.get(key = key, rules = False)
×
348
        order.set_ip_address_s(ip_address)
×
349
        order = order.reload(map = True)
×
350
        return order
×
351

352
    @appier.route("/api/orders/<str:key>/email", "PUT", json = True)
8✔
353
    @appier.ensure(token = "user")
8✔
354
    def set_email(self, key):
355
        data = appier.request_json()
×
356
        email = data["email"]
×
357
        order = budy.Order.get(key = key, rules = False)
×
358
        order.email = email
×
359
        order.save()
×
360
        order = order.reload(map = True)
×
361
        return order
×
362

363
    @appier.route("/api/orders/<str:key>/gift_wrap", "PUT", json = True)
8✔
364
    @appier.ensure(token = "user")
8✔
365
    def set_gift_wrap(self, key):
366
        data = appier.request_json()
×
367
        gift_wrap = data["gift_wrap"]
×
368
        order = budy.Order.get(key = key, rules = False)
×
369
        order.gift_wrap = gift_wrap
×
370
        order.save()
×
371
        order = order.reload(map = True)
×
372
        return order
×
373

374
    @appier.route("/api/orders/<str:key>/referral", "PUT", json = True)
8✔
375
    @appier.ensure(token = "user")
8✔
376
    def set_referral(self, key):
377
        data = appier.request_json()
×
378
        referral_name = data["name"]
×
379
        order = budy.Order.get(key = key, rules = False)
×
380
        referral = budy.Referral.get(name = referral_name)
×
381
        order.set_referral_s(referral)
×
382
        order = order.reload(map = True)
×
383
        return order
×
384

385
    @appier.route("/api/orders/<str:key>/voucher", "PUT", json = True)
8✔
386
    @appier.ensure(token = "user")
8✔
387
    def set_voucher(self, key):
388
        strict = self.field("strict", False, cast = bool)
×
389
        empty_vouchers = self.field("empty_vouchers", True, cast = bool)
×
390
        data = appier.request_json()
×
391
        voucher_key = data["key"]
×
392
        order = budy.Order.get(key = key, rules = False)
×
393
        if empty_vouchers: order.empty_vouchers_s()
×
394
        voucher = budy.Voucher.get(
×
395
            key = voucher_key,
396
            raise_e = strict
397
        )
398
        if not voucher: return
×
399
        order.set_voucher_s(voucher)
×
400
        order = order.reload(map = True)
×
401
        return order
×
402

403
    @appier.route("/api/orders/<str:key>/meta", "PUT", json = True)
8✔
404
    @appier.ensure(token = "user")
8✔
405
    def set_meta(self, key):
406
        name = self.field("name", mandatory = True, not_empty = True)
×
407
        value = self.field("value", mandatory = True)
×
408
        order = budy.Order.get(key = key, rules = False)
×
409
        order.set_meta_s(name, value)
×
410
        order = order.reload(map = True)
×
411
        return order
×
412

413
    @appier.route("/api/orders/<str:key>/account", "PUT", json = True)
8✔
414
    @appier.ensure(token = "user")
8✔
415
    def set_account(self, key):
416
        order = budy.Order.get(key = key, rules = False)
×
417
        account = budy.BudyAccount.from_session()
×
418
        order.set_account_s(account)
×
419
        order = order.reload(map = True)
×
420
        return order
×
421

422
    @appier.route("/api/orders/<str:key>/wait_payment", "PUT", json = True)
8✔
423
    @appier.ensure(token = "user")
8✔
424
    def wait_payment(self, key):
425
        empty_bag = self.field("empty_bag", True, cast = bool)
×
426
        order = budy.Order.get(key = key, rules = False)
×
427
        result = order.wait_payment_s(notify = True)
×
428
        bag = budy.Bag.from_session()
×
429
        if empty_bag and bag: bag.empty_s()
×
430
        order = order.reload(map = True)
×
431
        redirect_url = result if appier.legacy.is_string(result) else None
×
432
        return dict(
×
433
            redirect_url = redirect_url,
434
            order = order
435
        )
436

437
    @appier.route("/api/orders/<str:key>/pay", "PUT", json = True)
8✔
438
    @appier.ensure(token = "user")
8✔
439
    def pay(self, key):
440
        data = appier.request_json()
×
441
        empty_bag = self.field("empty_bag", True, cast = bool)
×
442
        order = budy.Order.get(key = key, rules = False)
×
443
        result = order.pay_s(payment_data = data, notify = True)
×
444
        bag = budy.Bag.from_session()
×
445
        if empty_bag and bag: bag.empty_s()
×
446
        order = order.reload(map = True)
×
447
        redirect_url = result if appier.legacy.is_string(result) else None
×
448
        return dict(
×
449
            redirect_url = redirect_url,
450
            order = order
451
        )
452

453
    @appier.route("/api/orders/<str:key>/end_pay", "PUT", json = True)
8✔
454
    @appier.ensure(token = "user")
8✔
455
    def end_pay(self, key):
456
        data = appier.request_json()
×
457
        empty_bag = self.field("empty_bag", True, cast = bool)
×
458
        order = budy.Order.get(key = key, rules = False)
×
459
        result = order.end_pay_s(payment_data = data, strict = True, notify = True)
×
460
        bag = budy.Bag.from_session()
×
461
        if empty_bag and bag: bag.empty_s()
×
462
        order = order.reload(map = True)
×
463
        redirect_url = result if appier.legacy.is_string(result) else None
×
464
        return dict(
×
465
            redirect_url = redirect_url,
466
            order = order
467
        )
468

469
    @appier.route("/api/orders/<str:key>/cancel", "PUT", json = True)
8✔
470
    @appier.ensure(token = "user")
8✔
471
    def cancel(self, key):
472
        data = appier.request_json()
×
473
        order = budy.Order.get(key = key, rules = False)
×
474
        result = order.cancel_s(data, notify = True)
×
475
        order = order.reload(map = True)
×
476
        redirect_url = result if appier.legacy.is_string(result) else None
×
477
        return dict(
×
478
            redirect_url = redirect_url,
479
            order = order
480
        )
481

482
    @appier.route("/api/orders/<str:key>/lines.csv", "GET")
8✔
483
    @appier.ensure(token = "admin")
8✔
484
    def lines_csv(self, key):
485
        order = budy.Order.get(key = key)
×
486
        lines_s = [(
×
487
            "id",
488
            "product",
489
            "product_id",
490
            "quantity",
491
            "size",
492
            "scale",
493
            "gender",
494
            "line_total",
495
            "currency",
496
            "order_id",
497
            "order_reference",
498
            "order_total",
499
            "order_status",
500
            "account",
501
            "date",
502
        )]
503
        for line in order.lines:
×
504
            if not line.product: continue
×
505
            line_s = (
×
506
                line.id,
507
                line.product.id,
508
                line.product.product_id,
509
                line.quantity,
510
                line.size,
511
                line.scale,
512
                line.product.gender,
513
                line.total,
514
                line.currency,
515
                order.id,
516
                order.reference,
517
                order.total,
518
                order.status,
519
                order.account.username,
520
                order.created_d.strftime("%d/%m/%Y"),
521
            )
522
            lines_s.append(line_s)
×
523

524
        result = appier.serialize_csv(lines_s, delimiter = ",")
×
525
        self.content_type("text/csv")
×
526
        return result
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc