Commit fafd18bd370776369f506f62bc86ffa09deb82ac
1 parent
ef35b851
Exists in
dev
add quota related methods
Showing
4 changed files
with
126 additions
and
57 deletions
Show diff stats
src/core/pyros_django/dashboard/templates/dashboard/observation_index.html
@@ -102,6 +102,24 @@ | @@ -102,6 +102,24 @@ | ||
102 | </a> | 102 | </a> |
103 | </div> | 103 | </div> |
104 | </li> | 104 | </li> |
105 | + <li> | ||
106 | + {% comment %} | ||
107 | + Old version to be remastered : | ||
108 | + <a href="{% url "proposal" %}"> | ||
109 | + <div class="all-info"> | ||
110 | + | ||
111 | + <h3>Proposal</h3> | ||
112 | + {% load static %} <img src="{% static "media/proposal.png" %}" alt="html5" height="180" width="180" /> | ||
113 | + </div></a> | ||
114 | + {% endcomment %} | ||
115 | + <div class="all-info"> | ||
116 | + <a href="{% url "quota_sp" %}"> | ||
117 | + | ||
118 | + <h3>Quota Scientific programs</h3> | ||
119 | + {% load static %} <img src="{% static "media/proposal.png" %}" alt="html5" /> | ||
120 | + </a> | ||
121 | + </div> | ||
122 | + </li> | ||
105 | {% endif %} | 123 | {% endif %} |
106 | {# TBD #} | 124 | {# TBD #} |
107 | {% if USER_LEVEL|ifinlist:"Admin,Operator,Unit-PI,Management board member,Observer,TAC" %} | 125 | {% if USER_LEVEL|ifinlist:"Admin,Operator,Unit-PI,Management board member,Observer,TAC" %} |
src/core/pyros_django/scp_mgmt/A_SCP_Manager.py
@@ -19,6 +19,7 @@ for short_path in short_paths: | @@ -19,6 +19,7 @@ for short_path in short_paths: | ||
19 | from majordome.agent.Agent import Agent, build_agent | 19 | from majordome.agent.Agent import Agent, build_agent |
20 | from user_mgmt.models import PyrosUser, Institute, SP_Period, Period, SP_Period, SP_Period_Guest, SP_PeriodWorkflow | 20 | from user_mgmt.models import PyrosUser, Institute, SP_Period, Period, SP_Period, SP_Period_Guest, SP_PeriodWorkflow |
21 | import vendor.guitastro.src.guitastro as guitastro | 21 | import vendor.guitastro.src.guitastro as guitastro |
22 | +from scp_mgmt.models import Quota | ||
22 | 23 | ||
23 | # Django imports | 24 | # Django imports |
24 | from django.shortcuts import reverse | 25 | from django.shortcuts import reverse |
@@ -47,6 +48,9 @@ class A_SCP_Manager(Agent): | @@ -47,6 +48,9 @@ class A_SCP_Manager(Agent): | ||
47 | # Format : “cmd_name” : (timeout, exec_mode, tooltip) | 48 | # Format : “cmd_name” : (timeout, exec_mode, tooltip) |
48 | 49 | ||
49 | "do_generate_ephem_moon_and_sun_for_period": (3, Agent.EXEC_MODE.SEQUENTIAL, 'generate ephem of moon & sun for a period'), | 50 | "do_generate_ephem_moon_and_sun_for_period": (3, Agent.EXEC_MODE.SEQUENTIAL, 'generate ephem of moon & sun for a period'), |
51 | + "do_set_quota_for_SP": (60, Agent.EXEC_MODE.SEQUENTIAL, 'set quota for scientific programs for id period'), | ||
52 | + "do_set_quota_for_institutes": (60, Agent.EXEC_MODE.SEQUENTIAL, 'set quota for institutes for id period'), | ||
53 | + "do_run_quota_workflow": (60, Agent.EXEC_MODE.SEQUENTIAL, 'set quota for a period'), | ||
50 | } | 54 | } |
51 | 55 | ||
52 | # new init with obsconfig | 56 | # new init with obsconfig |
@@ -229,8 +233,8 @@ class A_SCP_Manager(Agent): | @@ -229,8 +233,8 @@ class A_SCP_Manager(Agent): | ||
229 | self.send_mail_to_observers_for_notification(next_sp_to_be_notified) | 233 | self.send_mail_to_observers_for_notification(next_sp_to_be_notified) |
230 | SP_PeriodWorkflow.objects.create(period=self.period,action=SP_PeriodWorkflow.NOTIFICATION) | 234 | SP_PeriodWorkflow.objects.create(period=self.period,action=SP_PeriodWorkflow.NOTIFICATION) |
231 | self.update_sun_moon_ephems() | 235 | self.update_sun_moon_ephems() |
232 | - self.set_quota_for_institutes(self.period.id) | ||
233 | - self.set_quota_for_sp(self.period.id) | 236 | + self.do_set_quota_for_institutes(self.period.id) |
237 | + self.do_set_quota_for_SP(self.period.id) | ||
234 | 238 | ||
235 | def routine_process_body(self): | 239 | def routine_process_body(self): |
236 | print("routine automatic period workflow") | 240 | print("routine automatic period workflow") |
@@ -245,27 +249,49 @@ class A_SCP_Manager(Agent): | @@ -245,27 +249,49 @@ class A_SCP_Manager(Agent): | ||
245 | for n in range(int((end_date - start_date).days)): | 249 | for n in range(int((end_date - start_date).days)): |
246 | yield start_date + timedelta(n) | 250 | yield start_date + timedelta(n) |
247 | 251 | ||
248 | - def set_quota_for_institutes(self, id_period): | ||
249 | - for institute in Institute.objects.all(): | ||
250 | - quota_f = institute.quota_f | ||
251 | - # the lowest id of quota table for this period should be the first night of the period | ||
252 | - period_quota = Period.objects.get(id=id_period).quota | ||
253 | - institute_quota = period_quota.convert_to_quota(quota_f) | ||
254 | - new_quota = Quota() | ||
255 | - new_quota.set_attributes_and_save(institute_quota) | ||
256 | - institute.quota = new_quota | ||
257 | - institute.save() | 252 | + def do_run_quota_workflow(self, id_period:int): |
253 | + try: | ||
254 | + self.update_sun_moon_ephems() | ||
255 | + except Exception as e: | ||
256 | + print(e) | ||
257 | + self.do_set_quota_for_institutes(id_period) | ||
258 | + self.do_set_quota_for_SP(id_period) | ||
259 | + | ||
260 | + def do_set_quota_for_institutes(self, id_period:int): | ||
261 | + try: | ||
262 | + for institute in Institute.objects.all(): | ||
263 | + quota_f = institute.quota_f | ||
264 | + # the lowest id of quota table for this period should be the first night of the period | ||
265 | + period_quota = Period.objects.get(id=id_period).quota | ||
266 | + institute_quota = period_quota.convert_to_quota(quota_f) | ||
267 | + institute_quota["night_id"] = 0 | ||
268 | + institute_quota["id_period"] = id_period | ||
269 | + new_quota = Quota() | ||
270 | + new_quota.set_attributes_and_save(institute_quota) | ||
271 | + institute.quota = new_quota | ||
272 | + institute.save() | ||
273 | + except Exception as e: | ||
274 | + print(e) | ||
275 | + raise e | ||
258 | 276 | ||
259 | - def set_quota_for_SP(self, id_period): | ||
260 | - period = Period.objects.get(id=id_period) | ||
261 | - for sp_period in SP_Period.objects.filter(period=period): | ||
262 | - sp = sp_period.scientific_program | ||
263 | - institute = sp.institute | ||
264 | - institute_quota = institute.quota | ||
265 | - new_quota = Quota() | ||
266 | - quota_attributes = institute_quota.convert_to_quota(sp.quota_f) | ||
267 | - new_quota.set_attributes_and_save(quota_attributes) | ||
268 | - | 277 | + def do_set_quota_for_SP(self, id_period:int): |
278 | + try: | ||
279 | + period = Period.objects.get(id=id_period) | ||
280 | + for sp_period in SP_Period.objects.filter(period=period): | ||
281 | + sp = sp_period.scientific_program | ||
282 | + institute = sp.institute | ||
283 | + institute_quota = institute.quota | ||
284 | + new_quota = Quota() | ||
285 | + quota_attributes = institute_quota.convert_to_quota(sp.quota_f) | ||
286 | + quota_attributes["night_id"] = 1 | ||
287 | + quota_attributes["id_period"] = id_period | ||
288 | + new_quota.set_attributes_and_save(quota_attributes) | ||
289 | + sp.quota = new_quota | ||
290 | + sp.save() | ||
291 | + | ||
292 | + except Exception as e: | ||
293 | + print(e) | ||
294 | + raise e | ||
269 | 295 | ||
270 | if __name__ == "__main__": | 296 | if __name__ == "__main__": |
271 | 297 |
src/core/pyros_django/scp_mgmt/models.py
@@ -4,90 +4,114 @@ from django.db import models | @@ -4,90 +4,114 @@ from django.db import models | ||
4 | class Quota(models.Model): | 4 | class Quota(models.Model): |
5 | id_period = models.BigIntegerField(blank=True, null=True) | 5 | id_period = models.BigIntegerField(blank=True, null=True) |
6 | night_id = models.CharField(max_length=8, null=True, blank=True, db_index=True) | 6 | night_id = models.CharField(max_length=8, null=True, blank=True, db_index=True) |
7 | + d_total = models.BigIntegerField(default=0, blank=True, null=True) | ||
7 | d_totalq = models.BigIntegerField(default=0, blank=True, null=True) | 8 | d_totalq = models.BigIntegerField(default=0, blank=True, null=True) |
8 | d_totalx = models.BigIntegerField(default=0, blank=True, null=True) | 9 | d_totalx = models.BigIntegerField(default=0, blank=True, null=True) |
9 | 10 | ||
11 | + d_previous = models.BigIntegerField(default=0, blank=True, null=True) | ||
10 | d_previousq = models.BigIntegerField(default=0, blank=True, null=True) | 12 | d_previousq = models.BigIntegerField(default=0, blank=True, null=True) |
11 | d_previousx = models.BigIntegerField(default=0, blank=True, null=True) | 13 | d_previousx = models.BigIntegerField(default=0, blank=True, null=True) |
12 | 14 | ||
15 | + d_current = models.BigIntegerField(default=0, blank=True, null=True) | ||
13 | d_currentq = models.BigIntegerField(default=0, blank=True, null=True) | 16 | d_currentq = models.BigIntegerField(default=0, blank=True, null=True) |
14 | d_currentx = models.BigIntegerField(default=0, blank=True, null=True) | 17 | d_currentx = models.BigIntegerField(default=0, blank=True, null=True) |
15 | 18 | ||
19 | + d_passed = models.BigIntegerField(default=0, blank=True, null=True) | ||
16 | d_passedq = models.BigIntegerField(default=0, blank=True, null=True) | 20 | d_passedq = models.BigIntegerField(default=0, blank=True, null=True) |
17 | d_passedx = models.BigIntegerField(default=0, blank=True, null=True) | 21 | d_passedx = models.BigIntegerField(default=0, blank=True, null=True) |
18 | 22 | ||
23 | + d_schedule = models.BigIntegerField(default=0, blank=True, null=True) | ||
19 | d_scheduleq = models.BigIntegerField(default=0, blank=True, null=True) | 24 | d_scheduleq = models.BigIntegerField(default=0, blank=True, null=True) |
20 | d_schedulex = models.BigIntegerField(default=0, blank=True, null=True) | 25 | d_schedulex = models.BigIntegerField(default=0, blank=True, null=True) |
21 | 26 | ||
27 | + d_next = models.BigIntegerField(default=0, blank=True, null=True) | ||
22 | d_nextq = models.BigIntegerField(default=0, blank=True, null=True) | 28 | d_nextq = models.BigIntegerField(default=0, blank=True, null=True) |
23 | d_nextx = models.BigIntegerField(default=0, blank=True, null=True) | 29 | d_nextx = models.BigIntegerField(default=0, blank=True, null=True) |
24 | 30 | ||
25 | - @property | ||
26 | - def d_total(self): | ||
27 | - return self.d_totalq + self.d_totalx | 31 | + # @property |
32 | + # def d_total(self): | ||
33 | + # return self.d_totalq + self.d_totalx | ||
28 | 34 | ||
29 | - @property | ||
30 | - def d_previous(self): | ||
31 | - return self.d_previousq + self.d_previousx | 35 | + # @property |
36 | + # def d_previous(self): | ||
37 | + # return self.d_previousq + self.d_previousx | ||
32 | 38 | ||
33 | - @property | ||
34 | - def d_current(self): | ||
35 | - return self.d_currentq + self.d_currentx | 39 | + # @property |
40 | + # def d_current(self): | ||
41 | + # return self.d_currentq + self.d_currentx | ||
36 | 42 | ||
37 | - @property | ||
38 | - def d_passed(self): | ||
39 | - return self.d_passedq + self.d_passedx | 43 | + # @property |
44 | + # def d_passed(self): | ||
45 | + # return self.d_passedq + self.d_passedx | ||
40 | 46 | ||
41 | - @property | ||
42 | - def d_schedule(self): | ||
43 | - return self.d_scheduleq + self.d_schedulex | 47 | + # @property |
48 | + # def d_schedule(self): | ||
49 | + # return self.d_scheduleq + self.d_schedulex | ||
44 | 50 | ||
45 | - @property | ||
46 | - def d_next(self): | ||
47 | - return self.d_nextq + self.d_nextx | 51 | + # @property |
52 | + # def d_next(self): | ||
53 | + # return self.d_nextq + self.d_nextx | ||
48 | 54 | ||
49 | def set_attributes_and_save(self, quota_attributes:dict): | 55 | def set_attributes_and_save(self, quota_attributes:dict): |
50 | - | ||
51 | if quota_attributes.get("id_period") != None: | 56 | if quota_attributes.get("id_period") != None: |
52 | self.id_period = quota_attributes["id_period"] | 57 | self.id_period = quota_attributes["id_period"] |
53 | if quota_attributes.get("night_id") != None: | 58 | if quota_attributes.get("night_id") != None: |
54 | self.night_id = quota_attributes["night_id"] | 59 | self.night_id = quota_attributes["night_id"] |
60 | + | ||
55 | if quota_attributes.get("d_totalq") != None: | 61 | if quota_attributes.get("d_totalq") != None: |
56 | self.d_totalq = quota_attributes["d_totalq"] | 62 | self.d_totalq = quota_attributes["d_totalq"] |
57 | if quota_attributes.get("d_totalx") != None: | 63 | if quota_attributes.get("d_totalx") != None: |
58 | self.d_totalx = quota_attributes["d_totalx"] | 64 | self.d_totalx = quota_attributes["d_totalx"] |
65 | + | ||
59 | if quota_attributes.get("d_previousq") != None: | 66 | if quota_attributes.get("d_previousq") != None: |
60 | self.d_previousq = quota_attributes["d_previousq"] | 67 | self.d_previousq = quota_attributes["d_previousq"] |
61 | if quota_attributes.get("d_previousx") != None: | 68 | if quota_attributes.get("d_previousx") != None: |
62 | self.d_previousx = quota_attributes["d_previousx"] | 69 | self.d_previousx = quota_attributes["d_previousx"] |
70 | + | ||
63 | if quota_attributes.get("d_currentq") != None: | 71 | if quota_attributes.get("d_currentq") != None: |
64 | self.d_currentq = quota_attributes["d_currentq"] | 72 | self.d_currentq = quota_attributes["d_currentq"] |
65 | if quota_attributes.get("d_currentx") != None: | 73 | if quota_attributes.get("d_currentx") != None: |
66 | self.d_currentx = quota_attributes["d_currentx"] | 74 | self.d_currentx = quota_attributes["d_currentx"] |
75 | + | ||
76 | + if quota_attributes.get("d_passedq") != None: | ||
77 | + self.d_passedq = quota_attributes["d_passedq"] | ||
78 | + if quota_attributes.get("d_passedx") != None: | ||
79 | + self.d_passedx = quota_attributes["d_passedx"] | ||
80 | + | ||
81 | + | ||
67 | if quota_attributes.get("d_scheduleq") != None: | 82 | if quota_attributes.get("d_scheduleq") != None: |
68 | self.d_scheduleq = quota_attributes["d_scheduleq"] | 83 | self.d_scheduleq = quota_attributes["d_scheduleq"] |
69 | if quota_attributes.get("d_schedulex") != None: | 84 | if quota_attributes.get("d_schedulex") != None: |
70 | - self.d_schedule = quota_attributes["d_schedulex"] | 85 | + self.d_schedulex = quota_attributes["d_schedulex"] |
86 | + | ||
87 | + if quota_attributes.get("d_nextx") != None: | ||
88 | + self.d_nextq = quota_attributes["d_nextx"] | ||
71 | if quota_attributes.get("d_nextq") != None: | 89 | if quota_attributes.get("d_nextq") != None: |
72 | self.d_nextq = quota_attributes["d_nextq"] | 90 | self.d_nextq = quota_attributes["d_nextq"] |
73 | - if quota_attributes.get("d_nextx") != None: | ||
74 | - self.d_nextx = quota_attributes["d_nextx"] | 91 | + |
92 | + | ||
93 | + if quota_attributes.get("d_total") != None: | ||
94 | + self.d_total = quota_attributes["d_total"] | ||
95 | + if quota_attributes.get("d_previous") != None: | ||
96 | + self.d_previous = quota_attributes["d_previous"] | ||
97 | + if quota_attributes.get("d_current") != None: | ||
98 | + self.d_current = quota_attributes["d_current"] | ||
99 | + if quota_attributes.get("d_passed") != None: | ||
100 | + self.d_passed = quota_attributes["d_passed"] | ||
101 | + if quota_attributes.get("d_schedule") != None: | ||
102 | + self.d_schedule = quota_attributes["d_schedule"] | ||
103 | + if quota_attributes.get("d_next") != None: | ||
104 | + self.d_next = quota_attributes["d_next"] | ||
75 | self.save() | 105 | self.save() |
76 | 106 | ||
77 | def convert_to_quota(self, quota_f): | 107 | def convert_to_quota(self, quota_f): |
78 | quota_institute = {} | 108 | quota_institute = {} |
79 | 109 | ||
80 | - quota_institute["d_totalq"] = self.d_totalq * quota_f | ||
81 | - quota_institute["d_totalx"] = self.d_totalx * quota_f | ||
82 | - quota_institute["d_previousq"] = self.d_previousq * quota_f | ||
83 | - quota_institute["d_previousx"] = self.d_previousx * quota_f | ||
84 | - quota_institute["d_currentq"] = self.d_currentq * quota_f | ||
85 | - quota_institute["d_currentx"] = self.d_currentx * quota_f | ||
86 | - quota_institute["d_passedq"] = self.d_passedq * quota_f | ||
87 | - quota_institute["d_passedx"] = self.d_passedx * quota_f | ||
88 | - quota_institute["d_scheduleq"] = self.d_scheduleq * quota_f | ||
89 | - quota_institute["d_schedulex"] = self.d_schedulex * quota_f | ||
90 | - quota_institute["d_nextq"] = self.d_nextq * quota_f | ||
91 | - quota_institute["d_nextx"] = self.d_nextx * quota_f | 110 | + quota_institute["d_total"] = self.d_total * quota_f |
111 | + quota_institute["d_previous"] = self.d_previous * quota_f | ||
112 | + quota_institute["d_current"] = self.d_current * quota_f | ||
113 | + quota_institute["d_passed"] = self.d_passed * quota_f | ||
114 | + quota_institute["d_schedule"] = self.d_schedule * quota_f | ||
115 | + quota_institute["d_next"] = self.d_next * quota_f | ||
92 | 116 | ||
93 | return quota_institute | 117 | return quota_institute |
src/core/pyros_django/scp_mgmt/views.py
@@ -815,7 +815,8 @@ def quota_sp(request): | @@ -815,7 +815,8 @@ def quota_sp(request): | ||
815 | config = OBSConfig(os.environ["PATH_TO_OBSCONF_FILE"],os.environ["unit_name"]) | 815 | config = OBSConfig(os.environ["PATH_TO_OBSCONF_FILE"],os.environ["unit_name"]) |
816 | current_night = config.fn.date2night("now") | 816 | current_night = config.fn.date2night("now") |
817 | current_period = Period.objects.exploitation_period() | 817 | current_period = Period.objects.exploitation_period() |
818 | - quota_current_night = Quota.objects.get(id_period=current_period.id, night_id=current_night) | 818 | + # lowest id is period line |
819 | + quota_current_night = Quota.objects.filter(id_period=current_period.id, night_id=current_night).order_by("id").first() | ||
819 | return render(request, 'scp_mgmt/quota_sp.html', locals()) | 820 | return render(request, 'scp_mgmt/quota_sp.html', locals()) |
820 | 821 | ||
821 | 822 |