Completed
Push — master ( 0943a5...c65a32 )
by Jochen
04:29
created

check_in_user()   A

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nop 2
dl 0
loc 15
rs 9.95
c 0
b 0
f 0
1
"""
2
byceps.services.ticketing.ticket_user_checkin_service
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2019 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9
from ...database import db
10
from ...typing import UserID
11
12
from ..user import service as user_service
13
from ..user.transfer.models import User
14
15
from . import event_service
16
from .exceptions import (
17
    TicketIsRevoked,
18
    TicketLacksUser,
19
    UserAccountDeleted,
20
    UserAccountSuspended,
21
    UserAlreadyCheckedIn,
22
    UserIdUnknown,
23
)
24
from .models.ticket import Ticket as DbTicket
25
from . import ticket_service
26
from .transfer.models import TicketID
27
28
29
def check_in_user(ticket_id: TicketID, initiator_id: UserID) -> None:
30
    """Record that the ticket was used to check in its user."""
31
    ticket = _get_ticket_for_checkin(ticket_id)
32
33
    user = _get_user_for_checkin(ticket.used_by_id)
34
35
    ticket.user_checked_in = True
36
37
    event = event_service.build_event('user-checked-in', ticket.id, {
38
        'checked_in_user_id': str(ticket.used_by_id),
39
        'initiator_id': str(initiator_id),
40
    })
41
    db.session.add(event)
42
43
    db.session.commit()
44
45
46
def _get_ticket_for_checkin(ticket_id: TicketID) -> DbTicket:
47
    ticket = ticket_service.find_ticket(ticket_id)
48
49
    if ticket is None:
50
        raise ValueError(f"Unknown ticket ID '{ticket_id}'")
51
52
    if ticket.revoked:
53
        raise TicketIsRevoked(f'Ticket {ticket_id} has been revoked.')
54
55
    if ticket.used_by_id is None:
56
        raise TicketLacksUser(f'Ticket {ticket_id} has no user assigned.')
57
58
    if ticket.user_checked_in:
59
        raise UserAlreadyCheckedIn(
60
            f'Ticket {ticket_id} has already been used to check in a user.'
61
        )
62
63
    return ticket
64
65
66
def _get_user_for_checkin(user_id: UserID) -> User:
67
    user = user_service.find_user(user_id)
68
69
    if user is None:
70
        raise UserIdUnknown(f"Unknown user ID '{user_id}'")
71
72
    if user.deleted:
73
        raise UserAccountDeleted(
74
            f'User account {user.screen_name} has been deleted.'
75
        )
76
77
    if user.suspended:
78
        raise UserAccountSuspended(
79
            f'User account {user.screen_name} is suspended.'
80
        )
81
82
    return user
83
84
85
def revert_user_check_in(ticket_id: TicketID, initiator_id: UserID) -> None:
86
    """Revert a user check-in that was done by mistake."""
87
    ticket = ticket_service.find_ticket(ticket_id)
88
89
    if not ticket.user_checked_in:
90
        raise ValueError(f'User of ticket {ticket_id} has not been checked in.')
91
92
    ticket.user_checked_in = False
93
94
    event = event_service.build_event('user-check-in-reverted', ticket.id, {
95
        'checked_in_user_id': str(ticket.used_by_id),
96
        'initiator_id': str(initiator_id),
97
    })
98
    db.session.add(event)
99
100
    db.session.commit()
101