Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion __manifest__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
'name': 'APEX - Academic Progress and Excellence',
'version': '18.0.1.0.44',
'version': '18.0.1.0.45',
'icon': '/aps_sis/static/description/icon.png',
'category': 'Tools',
'summary': 'Allow the assigning and tracking of academic tasks such as homework, exams etc.',
Expand Down Expand Up @@ -78,6 +78,8 @@
'aps_sis/static/src/js/recent_submissions_widget.js',
'aps_sis/static/src/js/confetti.browser.min.js',
'aps_sis/static/src/js/float_sentinel_widget.js',
'aps_sis/static/src/js/alpha_numeric_widget.js',
'aps_sis/static/src/css/alpha_numeric_widget.css',
'aps_sis/static/src/js/resource_links_widget.js',
# 'aps_sis/static/src/js/form_notebook_default_page.js',
'aps_sis/static/src/js/submission_list_score_refresh.js',
Expand Down
48 changes: 48 additions & 0 deletions migrations/18.0.1.0.45/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from odoo import SUPERUSER_ID, api
import logging

_logger = logging.getLogger(__name__)

SENTINEL = -0.01


def migrate(cr, version):
"""Back-fill score_alpha and out_of_marks_alpha from existing numeric fields.

For records that already have a meaningful numeric score (i.e. not the
sentinel -0.01), populate the new alpha Char fields so the new widget
displays the correct value without requiring a manual re-entry.
"""
# score → score_alpha
cr.execute(
"""
UPDATE aps_resource_submission
SET score_alpha = CASE
WHEN score IS NULL OR ABS(score - %s) < 0.000001 THEN NULL
WHEN score = FLOOR(score) THEN TRIM(TO_CHAR(score, 'FM999999999999990'))
ELSE TRIM(TO_CHAR(score, 'FM999999999999990.099999'))
END
WHERE score_alpha IS NULL
""",
(SENTINEL,),
)
rows = cr.rowcount
_logger.info("Migration 18.0.1.0.45: backfilled score_alpha for %d submission(s).", rows)

# out_of_marks → out_of_marks_alpha
cr.execute(
"""
UPDATE aps_resource_submission
SET out_of_marks_alpha = CASE
WHEN out_of_marks IS NULL OR ABS(out_of_marks - %s) < 0.000001 THEN NULL
WHEN out_of_marks = FLOOR(out_of_marks) THEN TRIM(TO_CHAR(out_of_marks, 'FM999999999999990'))
ELSE TRIM(TO_CHAR(out_of_marks, 'FM999999999999990.099999'))
END
WHERE out_of_marks_alpha IS NULL
""",
(SENTINEL,),
)
rows = cr.rowcount
_logger.info(
"Migration 18.0.1.0.45: backfilled out_of_marks_alpha for %d submission(s).", rows
)
41 changes: 41 additions & 0 deletions models/submissions/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@
_logger = logging.getLogger(__name__)
sentinel_zero = -0.01


def alpha_to_float(alpha_val, sentinel=sentinel_zero):
"""Parse an alpha score string to its numeric equivalent.

Returns the parsed float when *alpha_val* is a valid number, or *sentinel*
when it is empty, ``False``, or a non-numeric special code (e.g. "A", "-").
"""
if not alpha_val or not str(alpha_val).strip():
return sentinel
cleaned = str(alpha_val).replace(',', '').strip()
try:
return float(cleaned)
except ValueError:
return sentinel

class APSResourceSubmission(models.Model):
_name = 'aps.resource.submission'
_description = 'APEX Submission'
Expand Down Expand Up @@ -76,7 +91,19 @@ class APSResourceSubmission(models.Model):
tracking=True)
date_due = fields.Date(string='Due Date', tracking=True)
score = fields.Float(string='Score', digits=(16, 2), tracking=True, default=sentinel_zero)
score_alpha = fields.Char(
string='Score',
tracking=True,
help='Score as text. Accepts a number or a special code such as A (Absent), C (Cheating), or - (Excluded). '
'Changing this field automatically updates the numeric Score field.',
)
out_of_marks = fields.Float(string='Out of Marks', digits=(16, 1), store=True, tracking=True)
out_of_marks_alpha = fields.Char(
string='Out of Marks',
tracking=True,
help='Out-of-marks as text. Accepts a number or a special code. '
'Changing this field automatically updates the numeric Out of Marks field.',
)
result_percent = fields.Integer(string='Result %', compute='_compute_result_percent', store=True, tracking=True)
due_status = fields.Selection([
('late', 'Late'),
Expand Down Expand Up @@ -455,6 +482,20 @@ def _compute_display_name(self):

# endregion - Computed Fields

# region - Alpha-Numeric Score Helpers

@api.onchange('score_alpha')
def _onchange_score_alpha(self):
"""Keep the numeric score field in sync with score_alpha."""
self.score = alpha_to_float(self.score_alpha)

@api.onchange('out_of_marks_alpha')
def _onchange_out_of_marks_alpha(self):
"""Keep the numeric out_of_marks field in sync with out_of_marks_alpha."""
self.out_of_marks = alpha_to_float(self.out_of_marks_alpha)

# endregion - Alpha-Numeric Score Helpers

def _get_faculty_for_current_user(self):
"""Get the faculty record for the current user"""
employee = self.env['hr.employee'].search([('user_id', '=', self.env.user.id)], limit=1)
Expand Down
10 changes: 9 additions & 1 deletion models/submissions/overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import ast

from odoo import models, fields, api, _
from .model import sentinel_zero
from .model import sentinel_zero, alpha_to_float
import logging
from lxml import etree

Expand All @@ -16,6 +16,14 @@ class APSResourceSubmissionOverrides(models.Model):

def write(self, vals):

# Sync alpha fields → numeric fields when only the alpha field is provided
# (e.g. when saved programmatically without the onchange firing).
# Do this before the auto_score check so that 'score in vals' is correct.
if 'score_alpha' in vals and 'score' not in vals:
vals['score'] = alpha_to_float(vals['score_alpha'])
if 'out_of_marks_alpha' in vals and 'out_of_marks' not in vals:
vals['out_of_marks'] = alpha_to_float(vals['out_of_marks_alpha'])

# Mark score and answer as manually set when either is changed without explicitly
# passing auto_score=True. Our auto-calculation code always passes auto_score=True
# explicitly, so this only triggers for user-initiated changes.
Expand Down
29 changes: 29 additions & 0 deletions static/src/css/alpha_numeric_widget.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* Alpha-Numeric Field Widget */

.o_field_alpha_numeric_wrap {
display: flex;
flex-direction: column;
}

.o_alpha_numeric_input {
text-align: right;
}

/* Readonly display */
.o_alpha_numeric_value {
display: inline-block;
}

.o_alpha_numeric_value.o_alpha_number {
text-align: right;
min-width: 3em;
}

.o_alpha_numeric_value.o_alpha_code {
text-align: center;
}

/* Validation error message */
.o_alpha_numeric_error {
font-size: 0.75rem;
}
Loading