forked from ChelseaKR/ca-tariff-parse
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcredit.py
More file actions
85 lines (68 loc) · 2.76 KB
/
Copy pathcredit.py
File metadata and controls
85 lines (68 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""Parse a per-unit credit stated on its own line.
For example::
Credit applies to all electricity usage charges from midnight to 6:00 a.m. daily.
Electric Vehicle Credit.................................. -$0.0150/kWh
The credit carries no effective date of its own, so it inherits the schedule's
own effective date, cited to the footer that prints it rather than assumed.
"""
from __future__ import annotations
import re
from ..model import Charge, Cited, Money
from ..segment import Section
from .base import Citer, Emission
CREDIT_RE = re.compile(
r"\A(?P<label>.+?)\s+(?P<sign>-)\$(?P<num>\d+(?:\.\d+)?)\s*/\s*(?P<unit>[A-Za-z]+)\s*\Z"
)
APPLIES_RE = re.compile(r"\ACredit applies to\s+(?P<scope>.+?)\s*\Z", re.IGNORECASE)
WINDOW_RE = re.compile(r"\bfrom\s+(?P<window>.+?)\s*\.?\s*\Z", re.IGNORECASE)
def _credit_rows(section: Section) -> list[int]:
return [
position
for position, line in enumerate(section.content_lines)
if CREDIT_RE.match(line.text)
]
def claims(section: Section) -> bool:
return bool(_credit_rows(section))
def parse(section: Section, citer: Citer, effective: Cited[str] | None) -> Emission:
emission = Emission()
if effective is None:
# No document effective date was printed, so there is nothing to date
# the credit from and it is not emitted.
return emission
lines = section.content_lines
window: Cited[str] | None = None
for line in lines:
match = APPLIES_RE.match(line.text)
if not match:
continue
scope = match.group("scope")
window_match = WINDOW_RE.search(scope)
if window_match:
window = citer.text(line, section.section_id, window_match.group("window").strip())
emission.notes.append(citer.text(line, section.section_id, line.text))
emission.take(line)
for position in _credit_rows(section):
line = lines[position]
match = CREDIT_RE.match(line.text)
if not match:
continue
emission.charges.append(
Charge(
label=citer.text(line, section.section_id, match.group("label").strip()),
kind="credit",
price=Money(
amount=Cited(
value=f"-{match.group('num')}",
provenance=citer.cite(line, section.section_id),
),
currency="USD",
unit=citer.text(line, section.section_id, f"$/{match.group('unit')}"),
),
effective_from=effective,
tou_period=window,
)
)
emission.take(line)
if section.level > 0 and lines and not section.heading_inline:
emission.take(lines[0])
return emission