Passed
Push — main ( 1909da...2ebff6 )
by Jochen
01:37
created

calculate_total_amount()   A

Complexity

Conditions 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
"""
2
byceps.services.shop.article.article_domain_service
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2014-2024 Jochen Kupperschmidt
6
:License: Revised BSD (see `LICENSE` file for details)
7
"""
8
9
from datetime import datetime
10
11
from moneyed import Money
12
13
from byceps.util.result import Err, Ok, Result
14
15
from .errors import SomeArticlesLackFixedQuantityError
16
from .models import Article, ArticleCompilation, ArticleWithQuantity
17
18
19
def is_article_available_now(article: Article) -> bool:
20
    """Return `True` if the article is available at this moment in time."""
21
    start = article.available_from
22
    end = article.available_until
23
24
    now = datetime.utcnow()
25
26
    return (start is None or start <= now) and (end is None or now < end)
27
28
29
def calculate_total_amount(
30
    articles_with_quantities: list[ArticleWithQuantity],
31
) -> Money:
32
    """Calculate total amount of articles with quantities."""
33
    if not articles_with_quantities:
34
        raise ValueError('No articles with quantity given')
35
36
    return sum(awq.amount for awq in articles_with_quantities)  # type: ignore[return-value]
37
38
39
def calculate_article_compilation_total_amount(
40
    compilation: ArticleCompilation,
41
) -> Result[Money, SomeArticlesLackFixedQuantityError]:
42
    """Calculate total amount of articles and their attached articles in
43
    the compilation.
44
    """
45
    if any(item.fixed_quantity is None for item in compilation):
46
        return Err(SomeArticlesLackFixedQuantityError())
47
48
    articles_with_quantities = [
49
        ArticleWithQuantity(item.article, item.fixed_quantity)
50
        for item in compilation
51
    ]
52
53
    total_amount = calculate_total_amount(articles_with_quantities)
54
55
    return Ok(total_amount)
56