EnCoach Odoo 19 custom modules
Full backend implementation with custom Odoo modules: - encoach_api: Core API, user management, JWT auth - encoach_exam: Exam generation (reading, writing, listening, speaking) - encoach_evaluate: AI-powered evaluation (writing, speaking) - encoach_training: Training tips and walkthrough - encoach_storage: File storage management - encoach_payment: Stripe, PayPal, Paymob integration - encoach_mail: Email notifications Made-with: Cursor
This commit is contained in:
1
encoach_evaluation/__init__.py
Normal file
1
encoach_evaluation/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
16
encoach_evaluation/__manifest__.py
Normal file
16
encoach_evaluation/__manifest__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "EnCoach Evaluation",
|
||||
"version": "19.0.1.0.0",
|
||||
"category": "Education",
|
||||
"summary": "Evaluation records and AI job tracking for EnCoach",
|
||||
"description": "Stores writing/speaking evaluations and background AI job state.",
|
||||
"depends": ["encoach_core", "encoach_exam", "encoach_ai"],
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"security/rules.xml",
|
||||
"views/evaluation_views.xml",
|
||||
"views/ai_job_views.xml",
|
||||
],
|
||||
"installable": True,
|
||||
"license": "LGPL-3",
|
||||
}
|
||||
2
encoach_evaluation/models/__init__.py
Normal file
2
encoach_evaluation/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import evaluation
|
||||
from . import ai_job
|
||||
34
encoach_evaluation/models/ai_job.py
Normal file
34
encoach_evaluation/models/ai_job.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class EncoachAIJob(models.Model):
|
||||
_name = "encoach.ai.job"
|
||||
_description = "EnCoach AI Background Job"
|
||||
|
||||
job_type = fields.Selection(
|
||||
[
|
||||
("writing_grading", "Writing Grading"),
|
||||
("speaking_grading", "Speaking Grading"),
|
||||
("video_generation", "Video Generation"),
|
||||
],
|
||||
string="Job Type",
|
||||
)
|
||||
status = fields.Selection(
|
||||
[
|
||||
("pending", "Pending"),
|
||||
("in_progress", "In Progress"),
|
||||
("completed", "Completed"),
|
||||
("error", "Error"),
|
||||
],
|
||||
default="pending",
|
||||
)
|
||||
user_id = fields.Many2one("res.users", string="User", ondelete="set null")
|
||||
evaluation_id = fields.Many2one(
|
||||
"encoach.evaluation", string="Evaluation", ondelete="cascade",
|
||||
)
|
||||
input_data = fields.Json()
|
||||
result_data = fields.Json()
|
||||
error_message = fields.Text()
|
||||
created_at = fields.Datetime(default=fields.Datetime.now)
|
||||
completed_at = fields.Datetime()
|
||||
retry_count = fields.Integer(default=0)
|
||||
45
encoach_evaluation/models/evaluation.py
Normal file
45
encoach_evaluation/models/evaluation.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class EncoachEvaluation(models.Model):
|
||||
_name = "encoach.evaluation"
|
||||
_description = "EnCoach Evaluation Record"
|
||||
|
||||
user_id = fields.Many2one("res.users", string="User", ondelete="cascade")
|
||||
session_id = fields.Integer(string="Session Reference")
|
||||
exercise_id = fields.Char(string="Exercise ID")
|
||||
exercise_type = fields.Selection(
|
||||
[("writing", "Writing"), ("speaking", "Speaking")],
|
||||
string="Exercise Type",
|
||||
)
|
||||
status = fields.Selection(
|
||||
[
|
||||
("pending", "Pending"),
|
||||
("in_progress", "In Progress"),
|
||||
("completed", "Completed"),
|
||||
("error", "Error"),
|
||||
],
|
||||
default="pending",
|
||||
)
|
||||
result = fields.Json()
|
||||
created_at = fields.Datetime(default=fields.Datetime.now)
|
||||
completed_at = fields.Datetime()
|
||||
legacy_id = fields.Char(index=True)
|
||||
|
||||
def to_encoach_dict(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
"id": self.id,
|
||||
"userId": self.user_id.id if self.user_id else None,
|
||||
"sessionId": self.session_id,
|
||||
"exerciseId": self.exercise_id or "",
|
||||
"exerciseType": self.exercise_type or "",
|
||||
"status": self.status,
|
||||
"result": self.result,
|
||||
"createdAt": (
|
||||
self.created_at.isoformat() if self.created_at else None
|
||||
),
|
||||
"completedAt": (
|
||||
self.completed_at.isoformat() if self.completed_at else None
|
||||
),
|
||||
}
|
||||
6
encoach_evaluation/security/ir.model.access.csv
Normal file
6
encoach_evaluation/security/ir.model.access.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_encoach_evaluation_student,encoach.evaluation.student,model_encoach_evaluation,encoach_core.group_encoach_student,1,0,0,0
|
||||
access_encoach_evaluation_admin,encoach.evaluation.admin,model_encoach_evaluation,encoach_core.group_encoach_admin,1,1,1,1
|
||||
access_encoach_ai_job_admin,encoach.ai.job.admin,model_encoach_ai_job,encoach_core.group_encoach_admin,1,1,1,1
|
||||
access_encoach_evaluation_sysadmin,encoach.evaluation.sysadmin,model_encoach_evaluation,base.group_system,1,1,1,1
|
||||
access_encoach_ai_job_sysadmin,encoach.ai.job.sysadmin,model_encoach_ai_job,base.group_system,1,1,1,1
|
||||
|
23
encoach_evaluation/security/rules.xml
Normal file
23
encoach_evaluation/security/rules.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="rule_evaluation_student_own" model="ir.rule">
|
||||
<field name="name">Students see own evaluations</field>
|
||||
<field name="model_id" ref="model_encoach_evaluation"/>
|
||||
<field name="groups" eval="[(4, ref('encoach_core.group_encoach_student'))]"/>
|
||||
<field name="domain_force">[('user_id', '=', user.id)]</field>
|
||||
</record>
|
||||
<record id="rule_evaluation_admin" model="ir.rule">
|
||||
<field name="name">Admins see all evaluations</field>
|
||||
<field name="model_id" ref="model_encoach_evaluation"/>
|
||||
<field name="groups" eval="[(4, ref('encoach_core.group_encoach_admin'))]"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
</record>
|
||||
<record id="rule_ai_job_admin" model="ir.rule">
|
||||
<field name="name">Admins see all AI jobs</field>
|
||||
<field name="model_id" ref="model_encoach_ai_job"/>
|
||||
<field name="groups" eval="[(4, ref('encoach_core.group_encoach_admin'))]"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
55
encoach_evaluation/views/ai_job_views.xml
Normal file
55
encoach_evaluation/views/ai_job_views.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="view_encoach_ai_job_list" model="ir.ui.view">
|
||||
<field name="name">encoach.ai.job.list</field>
|
||||
<field name="model">encoach.ai.job</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="AI Jobs">
|
||||
<field name="job_type"/>
|
||||
<field name="status"/>
|
||||
<field name="user_id"/>
|
||||
<field name="retry_count"/>
|
||||
<field name="created_at"/>
|
||||
<field name="completed_at"/>
|
||||
<field name="error_message"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_encoach_ai_job_form" model="ir.ui.view">
|
||||
<field name="name">encoach.ai.job.form</field>
|
||||
<field name="model">encoach.ai.job</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="AI Job">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="job_type"/>
|
||||
<field name="status"/>
|
||||
<field name="user_id"/>
|
||||
<field name="evaluation_id"/>
|
||||
<field name="retry_count"/>
|
||||
<field name="created_at"/>
|
||||
<field name="completed_at"/>
|
||||
<field name="error_message"/>
|
||||
</group>
|
||||
<group string="Data">
|
||||
<field name="input_data" widget="json"/>
|
||||
<field name="result_data" widget="json"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_encoach_ai_job" model="ir.actions.act_window">
|
||||
<field name="name">AI Jobs</field>
|
||||
<field name="res_model">encoach.ai.job</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_encoach_ai_job"
|
||||
name="AI Jobs"
|
||||
parent="encoach_core.menu_encoach_ai"
|
||||
action="action_encoach_ai_job"
|
||||
sequence="20"/>
|
||||
</odoo>
|
||||
50
encoach_evaluation/views/evaluation_views.xml
Normal file
50
encoach_evaluation/views/evaluation_views.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="view_encoach_evaluation_list" model="ir.ui.view">
|
||||
<field name="name">encoach.evaluation.list</field>
|
||||
<field name="model">encoach.evaluation</field>
|
||||
<field name="arch" type="xml">
|
||||
<list string="Evaluations">
|
||||
<field name="user_id"/>
|
||||
<field name="exercise_type"/>
|
||||
<field name="exercise_id"/>
|
||||
<field name="status"/>
|
||||
<field name="created_at"/>
|
||||
<field name="completed_at"/>
|
||||
</list>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_encoach_evaluation_form" model="ir.ui.view">
|
||||
<field name="name">encoach.evaluation.form</field>
|
||||
<field name="model">encoach.evaluation</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Evaluation">
|
||||
<sheet>
|
||||
<field name="status" widget="statusbar" statusbar_visible="pending,in_progress,completed,error"/>
|
||||
<group>
|
||||
<field name="user_id"/>
|
||||
<field name="exercise_type"/>
|
||||
<field name="exercise_id"/>
|
||||
<field name="session_id"/>
|
||||
<field name="created_at"/>
|
||||
<field name="completed_at"/>
|
||||
<field name="result" widget="json"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_encoach_evaluation" model="ir.actions.act_window">
|
||||
<field name="name">Evaluations</field>
|
||||
<field name="res_model">encoach.evaluation</field>
|
||||
<field name="view_mode">list,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_encoach_evaluation"
|
||||
name="Evaluations"
|
||||
parent="encoach_core.menu_encoach_ai"
|
||||
action="action_encoach_evaluation"
|
||||
sequence="10"/>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user