-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy path__init__.py
170 lines (152 loc) · 6.11 KB
/
__init__.py
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# Part of OpenG2P. See LICENSE file for full copyright and licensing details.
from . import models
from odoo import _
from odoo.exceptions import MissingError
import logging
_logger = logging.getLogger(__name__)
def init_materialized_view(env):
"""
Initializes or refreshes the materialized views for the res_partner_dashboard_data.
"""
cr = env.cr
matviews_to_check = [
"g2p_gender_count_view",
"g2p_age_distribution_view",
"g2p_total_registrants_view",
"g2p_sr_dashboard_data",
]
try:
cr.execute(
"""
SELECT matviewname
FROM pg_matviews
WHERE matviewname IN %s;
""",
(tuple(matviews_to_check),),
)
existing_views = set([row[0] for row in cr.fetchall()])
if "g2p_gender_count_view" not in existing_views:
gender_query = """
CREATE MATERIALIZED VIEW g2p_gender_count_view AS
SELECT
rp.company_id,
gt.code AS gender,
COUNT(rp.id) AS gender_count
FROM
res_partner rp
LEFT JOIN
gender_type gt ON rp.gender = gt.value
WHERE
rp.is_registrant = True
AND rp.active = True
AND rp.is_group = False
GROUP BY
rp.company_id, gt.code;
"""
cr.execute(gender_query)
_logger.info("Created materialized view: g2p_gender_count_view")
if "g2p_age_distribution_view" not in existing_views:
age_distribution_query = """
CREATE MATERIALIZED VIEW g2p_age_distribution_view AS
SELECT
rp.company_id,
jsonb_build_object(
'below_18', COUNT(rp.id) FILTER (
WHERE EXTRACT(YEAR FROM AGE(rp.birthdate)) < 18
),
'18_to_30', COUNT(rp.id) FILTER (
WHERE EXTRACT(YEAR FROM AGE(rp.birthdate)) BETWEEN 18 AND 30
),
'31_to_40', COUNT(rp.id) FILTER (
WHERE EXTRACT(YEAR FROM AGE(rp.birthdate)) BETWEEN 31 AND 40
),
'41_to_50', COUNT(rp.id) FILTER (
WHERE EXTRACT(YEAR FROM AGE(rp.birthdate)) BETWEEN 41 AND 50
),
'above_50', COUNT(rp.id) FILTER (
WHERE EXTRACT(YEAR FROM AGE(rp.birthdate)) > 50
)
) AS age_distribution
FROM
res_partner rp
WHERE
rp.is_registrant = True
AND rp.active = True
AND rp.is_group = False
GROUP BY
rp.company_id;
"""
cr.execute(age_distribution_query)
_logger.info("Created materialized view: g2p_age_distribution_view")
if "g2p_total_registrants_view" not in existing_views:
total_registrants_query = """
CREATE MATERIALIZED VIEW g2p_total_registrants_view AS
SELECT
rp.company_id,
jsonb_build_object(
'total_individuals', COUNT(rp.id) FILTER (WHERE rp.is_group = False),
'total_groups', COUNT(rp.id) FILTER (WHERE rp.is_group = True)
) AS total_registrants
FROM
res_partner rp
WHERE
rp.is_registrant = True
AND rp.active = True
GROUP BY
rp.company_id;
"""
cr.execute(total_registrants_query)
_logger.info("Created materialized view: g2p_total_registrants_view")
if "g2p_sr_dashboard_data" not in existing_views:
dashboard_query = """
CREATE MATERIALIZED VIEW g2p_sr_dashboard_data AS
SELECT
trv.company_id,
trv.total_registrants,
COALESCE(
jsonb_object_agg(gc.gender, gc.gender_count) FILTER (WHERE gc.gender IS NOT NULL),
'{}'
) AS gender_spec,
adv.age_distribution
FROM
g2p_total_registrants_view trv
LEFT JOIN
g2p_gender_count_view gc ON trv.company_id = gc.company_id
LEFT JOIN
g2p_age_distribution_view adv ON trv.company_id = adv.company_id
GROUP BY
trv.company_id, trv.total_registrants, adv.age_distribution;
"""
cr.execute(dashboard_query)
_logger.info("Created materialized view: g2p_sr_dashboard_data")
except Exception as exc:
_logger.error("Error while creating materialized views: %s", str(exc))
raise MissingError(
_(
"Failed to create the materialized views."
"Please check the logs for details or Manually create it."
)
) from exc
def drop_materialized_view(env):
"""
Drop all the materialized views related to the dashboard.
"""
cr = env.cr
matviews_to_drop = [
"g2p_sr_dashboard_data",
"g2p_gender_count_view",
"g2p_age_distribution_view",
"g2p_total_registrants_view",
]
try:
for matview in matviews_to_drop:
cr.execute(f"DROP MATERIALIZED VIEW IF EXISTS {matview} CASCADE;") # pylint: disable=sql-injection
_logger.info("Dropped materialized view: %s", matview)
except Exception as exc:
_logger.error("Error while dropping materialized views: %s", str(exc))
raise MissingError(
_(
"Failed to drop the materialized views."
"Please check the logs for details or manually delete the view."
)
) from exc