From f367ddc443b0af9c0c1a1cfd56b46565b3b4aa66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B4=D8=B1=D9=83=D8=A9=20=D8=AE=D8=A8=D9=8A=D8=B1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D8=AD=D8=AF=D9=88=D8=AF=D8=A9?= Date: Mon, 16 Jun 2025 22:22:48 +0300 Subject: [PATCH 01/53] Update production_pull_code.yml --- .github/workflows/production_pull_code.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/production_pull_code.yml b/.github/workflows/production_pull_code.yml index 3aa0018b1..686243128 100644 --- a/.github/workflows/production_pull_code.yml +++ b/.github/workflows/production_pull_code.yml @@ -106,7 +106,7 @@ jobs: sahli_prod_master_server: name: Deploy to Sahli Prod Master runs-on: sahli-client-project-runner - if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Sahli-Project' && (github.ref == 'refs/heads/master_odex25_accounting' || github.ref == 'refs/heads/master_odex25_base' || github.ref == 'refs/heads/master_odex25_dms' || github.ref == 'refs/heads/master_odex25_hr' || github.ref == 'refs/heads/master_odex25_inventory' || github.ref == 'refs/heads/master_odex25_purchase' || github.ref == 'refs/heads/master_odex25_sales' || github.ref == 'refs/heads/master_odex25_project') + if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Sahli-Project' && (github.ref == 'refs/heads/master_odex25_accounting' || github.ref == 'refs/heads/master_odex25_helpdesk' || github.ref == 'refs/heads/master_odex25_base' || github.ref == 'refs/heads/master_odex25_dms' || github.ref == 'refs/heads/master_odex25_hr' || github.ref == 'refs/heads/master_odex25_inventory' || github.ref == 'refs/heads/master_odex25_purchase' || github.ref == 'refs/heads/master_odex25_sales' || github.ref == 'refs/heads/master_odex25_project') steps: - name: Checkout And Restart Project run: | From 1862f3e41da452b50bbd256c130dd2b16ac23e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B4=D8=B1=D9=83=D8=A9=20=D8=AE=D8=A8=D9=8A=D8=B1=20?= =?UTF-8?q?=D8=A7=D9=84=D9=85=D8=AD=D8=AF=D9=88=D8=AF=D8=A9?= Date: Tue, 17 Jun 2025 07:14:30 +0300 Subject: [PATCH 02/53] Update github action file --- .github/workflows/production_pull_code.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/production_pull_code.yml b/.github/workflows/production_pull_code.yml index 686243128..3aa0018b1 100644 --- a/.github/workflows/production_pull_code.yml +++ b/.github/workflows/production_pull_code.yml @@ -106,7 +106,7 @@ jobs: sahli_prod_master_server: name: Deploy to Sahli Prod Master runs-on: sahli-client-project-runner - if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Sahli-Project' && (github.ref == 'refs/heads/master_odex25_accounting' || github.ref == 'refs/heads/master_odex25_helpdesk' || github.ref == 'refs/heads/master_odex25_base' || github.ref == 'refs/heads/master_odex25_dms' || github.ref == 'refs/heads/master_odex25_hr' || github.ref == 'refs/heads/master_odex25_inventory' || github.ref == 'refs/heads/master_odex25_purchase' || github.ref == 'refs/heads/master_odex25_sales' || github.ref == 'refs/heads/master_odex25_project') + if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Sahli-Project' && (github.ref == 'refs/heads/master_odex25_accounting' || github.ref == 'refs/heads/master_odex25_base' || github.ref == 'refs/heads/master_odex25_dms' || github.ref == 'refs/heads/master_odex25_hr' || github.ref == 'refs/heads/master_odex25_inventory' || github.ref == 'refs/heads/master_odex25_purchase' || github.ref == 'refs/heads/master_odex25_sales' || github.ref == 'refs/heads/master_odex25_project') steps: - name: Checkout And Restart Project run: | From ee5b55a361b65fb43f6a4b2420cebceba5a06bc4 Mon Sep 17 00:00:00 2001 From: blackbelts <74664702+eslamtalaat74@users.noreply.github.com> Date: Tue, 17 Jun 2025 10:11:50 +0300 Subject: [PATCH 03/53] delete can delete ,edite false from balance view --- .../hr_holidays_public/views/leaves_balance.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/odex25_hr/hr_holidays_public/views/leaves_balance.xml b/odex25_hr/hr_holidays_public/views/leaves_balance.xml index 8eab9a45a..a5b8f288b 100644 --- a/odex25_hr/hr_holidays_public/views/leaves_balance.xml +++ b/odex25_hr/hr_holidays_public/views/leaves_balance.xml @@ -16,9 +16,9 @@ - false - false - false + + True + True @@ -29,9 +29,9 @@
- false - false - false + + +
From e1bea016cdc83c8fd89dfc1ad19c3b8967312301 Mon Sep 17 00:00:00 2001 From: younes Date: Tue, 17 Jun 2025 10:30:07 +0100 Subject: [PATCH 04/53] fix bug --- odex25_hr/hr_base/models/hr_base.py | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/odex25_hr/hr_base/models/hr_base.py b/odex25_hr/hr_base/models/hr_base.py index 99731446e..da7465c70 100644 --- a/odex25_hr/hr_base/models/hr_base.py +++ b/odex25_hr/hr_base/models/hr_base.py @@ -316,8 +316,37 @@ class HrEmployee(models.Model): @api.onchange('department_id') def _onchange_department(self): - self.sudo().parent_id = self.sudo().department_id.manager_id - self.sudo().coach_id = self.sudo().department_id.parent_id.manager_id + # self.sudo().parent_id = self.sudo().department_id.manager_id + # self.sudo().coach_id = self.sudo().department_id.parent_id.manager_id + for emp in self: + dept = emp.department_id + manager = dept.manager_id + if manager == emp: + cur = dept.parent_id + while cur: + if cur.manager_id and cur.manager_id != emp: + manager = cur.manager_id + break + cur = cur.parent_id + else: + manager = emp + + emp.sudo().parent_id = manager or False + + coach = False + cur = dept.parent_id + while cur: + # if cur.manager_id: + if cur.manager_id and cur.manager_id not in (emp): + coach = cur.manager_id + break + cur = cur.parent_id + + # emp.coach_id = coach or dept.manager_id or False + if not coach and dept.manager_id not in (emp): + coach = dept.manager_id + + emp.sudo().coach_id = coach or False # to Calculate duration service Period @api.onchange('first_hiring_date', 'leaving_date') From 3765ba5dd2dd8d6aaa89d4b42991f75e00ed5081 Mon Sep 17 00:00:00 2001 From: blackbelts <74664702+eslamtalaat74@users.noreply.github.com> Date: Tue, 17 Jun 2025 12:45:12 +0300 Subject: [PATCH 05/53] on publicleaves_balance_action --- .../views/leaves_balance.xml | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/odex25_hr/hr_holidays_public/views/leaves_balance.xml b/odex25_hr/hr_holidays_public/views/leaves_balance.xml index a5b8f288b..1bd21bfd1 100644 --- a/odex25_hr/hr_holidays_public/views/leaves_balance.xml +++ b/odex25_hr/hr_holidays_public/views/leaves_balance.xml @@ -10,46 +10,46 @@ - - hr.holidays.tree.no.delete - hr.holidays - - - - - True - True - - - + + + + + + + + + + + + - - hr.holidays.form.no.delete - hr.holidays - - -
- - - -
-
-
+ + + + + + + + + + + + - - Leaves Balance - hr.holidays - tree,form - - [('type','=','add'),('check_allocation_view','=','balance')] - {'search_default_employee_id': [active_id], 'default_employee_id': active_id, 'search_default_group_type': 1, - 'search_default_year': 1} - - + + + + + + + + + + + + + + @@ -60,7 +60,8 @@ - %(hr_holidays_public.leaves_balancee_action)d + + %(hr_holidays_public.leaves_balance_action)d From b43f8d1b0341b0ff54f93b595dbe7089b2fedd01 Mon Sep 17 00:00:00 2001 From: younes Date: Tue, 17 Jun 2025 11:45:20 +0100 Subject: [PATCH 06/53] fix bug --- odex25_hr/hr_base/models/hr_base.py | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/odex25_hr/hr_base/models/hr_base.py b/odex25_hr/hr_base/models/hr_base.py index da7465c70..ca59cbd26 100644 --- a/odex25_hr/hr_base/models/hr_base.py +++ b/odex25_hr/hr_base/models/hr_base.py @@ -294,25 +294,25 @@ class HrEmployee(models.Model): age = today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day)) emp.sudo().employee_age = age - @api.constrains('parent_id') - def _check_parent_id(self): - for employee in self: - if not employee._check_recursion(): - parent_id = employee.sudo().department_id.parent_id.manager_id - if parent_id: - employee.parent_id = parent_id - else: - employee.parent_id = False - - @api.constrains('coach_id') - def _check_coach_id(self): - for employee in self: - if not employee._check_recursion(): - parent_id = employee.sudo().department_id.parent_id.manager_id - if parent_id: - employee.parent_id = parent_id - else: - employee.coach_id = False + # @api.constrains('parent_id') + # def _check_parent_id(self): + # for employee in self: + # if not employee._check_recursion(): + # parent_id = employee.sudo().department_id.parent_id.manager_id + # if parent_id: + # employee.parent_id = parent_id + # else: + # employee.parent_id = False + # + # @api.constrains('coach_id') + # def _check_coach_id(self): + # for employee in self: + # if not employee._check_recursion(): + # parent_id = employee.sudo().department_id.parent_id.manager_id + # if parent_id: + # employee.parent_id = parent_id + # else: + # employee.coach_id = False @api.onchange('department_id') def _onchange_department(self): From b68ee7ea4ef7cb48e7fd97088658b324ab638119 Mon Sep 17 00:00:00 2001 From: blackbelts <74664702+eslamtalaat74@users.noreply.github.com> Date: Tue, 17 Jun 2025 17:19:14 +0300 Subject: [PATCH 07/53] modify on official_mission_id --- odex25_hr/exp_official_mission/i18n/ar_001.po | 9 ++++ .../models/hr_official_mission.py | 7 ++- .../views/hr_official_mission.xml | 44 +++++++++++-------- .../exp_official_mission/views/training.xml | 7 +-- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/odex25_hr/exp_official_mission/i18n/ar_001.po b/odex25_hr/exp_official_mission/i18n/ar_001.po index abe7212e7..9978c0fee 100644 --- a/odex25_hr/exp_official_mission/i18n/ar_001.po +++ b/odex25_hr/exp_official_mission/i18n/ar_001.po @@ -515,6 +515,15 @@ msgstr "تاريخ البداية" msgid "Date Request" msgstr "تاريخ الطلب" +#. module: exp_official_mission +#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_especially_hours_form_view +#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_especially_hours_tree_view +#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_official_mission_form_view +#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_training_form_view +#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_training_tree_view +msgid "Date Requestt" +msgstr "التاريخ " + #. module: exp_official_mission #: model:ir.model.fields,field_description:exp_official_mission.field_hr_official_mission__date_to #: model:ir.model.fields,field_description:exp_official_mission.field_hr_official_mission_employee__date_to diff --git a/odex25_hr/exp_official_mission/models/hr_official_mission.py b/odex25_hr/exp_official_mission/models/hr_official_mission.py index ea78d1399..769e908b8 100644 --- a/odex25_hr/exp_official_mission/models/hr_official_mission.py +++ b/odex25_hr/exp_official_mission/models/hr_official_mission.py @@ -297,6 +297,7 @@ class HrOfficialMission(models.Model): weekend_names = [d.name.lower() for d in weekend_days] date_range = [d for d in date_range if d.strftime('%A').lower() not in weekend_names] + item.date_duration = len(date_range) else: @@ -362,7 +363,11 @@ class HrOfficialMission(models.Model): date_range = [d for d in date_range if d.strftime('%A').lower() not in weekend_names] - line.days = len(date_range) + if not item.table_ids: + line.days = len(date_range) + else: + unique_dates = set(item.table_ids.mapped('date')) + item.days = len(unique_dates) if item.mission_type.related_with_financial is True: if item.mission_type.type_of_payment == 'fixed': if item.mission_type.day_price: diff --git a/odex25_hr/exp_official_mission/views/hr_official_mission.xml b/odex25_hr/exp_official_mission/views/hr_official_mission.xml index 849da4d4a..8e37aa605 100644 --- a/odex25_hr/exp_official_mission/views/hr_official_mission.xml +++ b/odex25_hr/exp_official_mission/views/hr_official_mission.xml @@ -167,24 +167,24 @@ - - + + - - - - - - - - - - + + + + + + + + + + @@ -243,11 +243,11 @@ search - - - - - + + + + + @@ -256,7 +256,7 @@ - + @@ -287,7 +287,12 @@ - + + + @@ -342,6 +347,7 @@ + diff --git a/odex25_hr/exp_official_mission/views/training.xml b/odex25_hr/exp_official_mission/views/training.xml index 01662e423..7ed7b7262 100644 --- a/odex25_hr/exp_official_mission/views/training.xml +++ b/odex25_hr/exp_official_mission/views/training.xml @@ -369,11 +369,11 @@ - + + required="1" widget="float_time"/> + required="1" widget="float_time"/> @@ -430,6 +430,7 @@ + + attrs="{'readonly': [('state', '!=', 'draft')]}" + groups="hr.group_hr_user" /> + domain="[('work_state', '=', 'training'),('special_hours', '!=', True)]" + attrs="{'readonly':[('state','not in',('draft','direct_manager','depart_manager','send'))] }" /> + attrs="{'readonly':[('state','not in',('draft','direct_manager','depart_manager','send'))] }" /> + attrs="{'readonly':[('state','not in',('draft','direct_manager','depart_manager','send'))] }" /> + attrs="{'readonly':[('state','not in',('draft','direct_manager','depart_manager','send'))] }" /> + attrs="{'readonly':[('state','not in',('draft','direct_manager','depart_manager','send'))] }" /> + force_save="1" + widget="float_time" + attrs="{'required':[('duration_type','=','hours')]}" /> + force_save="1" + attrs="{'required':[('duration_type','=','days')]}" /> + /> + readonly="1" /> + attrs="{'readonly':[('state','!=','draft')]}" /> + attrs="{'readonly':[('state','!=','draft')]}" + required="1" /> + widget="many2many_tags" + attrs="{'readonly':[('state','=','approve')]}" /> + attrs="{'readonly':[('state','!=','draft')]}" /> + domain="[('country_id','=',country_id),('destination_type','in',('training','all'))]" + attrs="{'readonly':[('state','not in',('draft','direct_manager','depart_manager','send'))] }" /> + attrs="{'readonly':[('state','=','approve')]}" /> + domain="[('is_company','=',False)]" + attrs="{'readonly':[('state','=','approve')]}" /> + attrs="{'readonly':[('state','!=','depart_manager')], 'required': [('state', '=', 'depart_manager')],'invisible':[('related_with_financial','=',False)]}" /> + attrs="{'readonly':[('state','=','approve')]}" + groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager" /> + attrs="{'invisible':['|',('state','!=','approve'),('Tra_cost_invo_id','=',False)]}" + groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager" /> + attrs="{'readonly':[('state','=','approve')]}" + groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager" /> + attrs="{'readonly':[('state','=','approve')]}" + groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager" /> @@ -183,15 +183,15 @@
+ attrs="{'readonly':[('state','not in',('depart_manager','direct_manager','send','draft'))]}"> @@ -199,54 +199,54 @@ + readonly="1" force_save="1" /> + widget="float_time" /> + widget="float_time" /> + readonly="1" force_save="1" /> + attrs="{'column_invisible':[('parent.related_with_financial','=',False)]}" + readonly="0" /> + groups="hr_base.group_account_manager,hr.group_hr_user,hr_base.group_division_manager" /> + force_save="1" invisible="1" /> + readonly="1" + force_save="1" + attrs="{'column_invisible':[('parent.appraisal_check','=',False)]}" /> + groups="hr_base.group_account_manager,hr.group_hr_user" + attrs="{'column_invisible':[('parent.related_with_financial','=',False)]}" + readonly="1" force_save="1" /> - + + @@ -551,16 +556,16 @@ + attrs="{'invisible':[('appraisal_id','=',False)]}" /> + attrs="{'invisible':[('appraisal_id','=',False)]}" /> + widget="float_time" /> @@ -584,7 +589,7 @@ hr.official.mission.employee + decoration-danger="status == 'refused'" decoration-success="status=='approved'"> @@ -594,15 +599,16 @@ + + attrs="{'invisible':[('appraisal_id','=',False)]}" /> diff --git a/odex25_hr/hr_holidays_public/views/leaves_balance.xml b/odex25_hr/hr_holidays_public/views/leaves_balance.xml index 85ecbf474..8510517ae 100644 --- a/odex25_hr/hr_holidays_public/views/leaves_balance.xml +++ b/odex25_hr/hr_holidays_public/views/leaves_balance.xml @@ -10,37 +10,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - Leaves Balance hr.holidays tree,form - [('type','=','add'),('check_allocation_view','=','balance')] + [('type','=','add'),('check_allocation_view','=','balance')] {'default_type':'add', 'default_check_allocation_view': 'balance'} @@ -49,17 +24,43 @@ - - - - - + + + + + + + + + + + + + + + + + hr.employee.leave.form.inherit.custom + hr.employee + + - - + + - - + + %(hr_holidays_public.leaves_balancee_action)d + {'search_default_employee_id': active_id} + + + + + + + + + + From 7b1ea86913486ed3194746d47633f38ab3557755 Mon Sep 17 00:00:00 2001 From: ahmed-nouri051 Date: Thu, 12 Jun 2025 16:20:00 +0200 Subject: [PATCH 27/53] add space # Conflicts: # odex25_hr/exp_official_mission/models/attendance.py --- odex25_hr/exp_official_mission/models/attendance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odex25_hr/exp_official_mission/models/attendance.py b/odex25_hr/exp_official_mission/models/attendance.py index a18eb4bb9..c22523909 100644 --- a/odex25_hr/exp_official_mission/models/attendance.py +++ b/odex25_hr/exp_official_mission/models/attendance.py @@ -14,4 +14,4 @@ class AttendanceTransactions(models.Model): # class ResPartner(models.Model): # _inherit = 'res.partner' # -# training = fields.Boolean(string="Training",default=True) \ No newline at end of file +# training = fields.Boolean(string="Training",default=True) From 9d6fb64419bda3fabd1e074018dd3388f87e6f66 Mon Sep 17 00:00:00 2001 From: ahmed-nouri051 Date: Sun, 15 Jun 2025 08:59:57 +0200 Subject: [PATCH 28/53] modification in hr # Conflicts: # odex25_hr/exp_official_mission/views/training.xml --- odex25_hr/exp_official_mission/i18n/ar_001.po | 8 +++++++- odex25_hr/exp_official_mission/models/attendance.py | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/odex25_hr/exp_official_mission/i18n/ar_001.po b/odex25_hr/exp_official_mission/i18n/ar_001.po index 7548f531d..ab134042b 100644 --- a/odex25_hr/exp_official_mission/i18n/ar_001.po +++ b/odex25_hr/exp_official_mission/i18n/ar_001.po @@ -2803,4 +2803,10 @@ msgstr "الموارد البشرية" #: model:ir.model.fields,field_description:exp_official_mission.field_hr_official_mission_type__analytic_account_id #: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_official_mission_type_form_view msgid "Analytic Account" -msgstr "الحساب التحليلي" \ No newline at end of file +msgstr "الحساب التحليلي" + + +#. module: exp_official_missionAdd commentMore actions +#: model:ir.model.fields,field_description:exp_official_mission.field_res_partner_training +msgid "Training" +msgstr "تدريب" \ No newline at end of file diff --git a/odex25_hr/exp_official_mission/models/attendance.py b/odex25_hr/exp_official_mission/models/attendance.py index c22523909..264f68e2d 100644 --- a/odex25_hr/exp_official_mission/models/attendance.py +++ b/odex25_hr/exp_official_mission/models/attendance.py @@ -11,7 +11,7 @@ class AttendanceTransactions(models.Model): -# class ResPartner(models.Model): -# _inherit = 'res.partner' -# -# training = fields.Boolean(string="Training",default=True) +class ResPartner(models.Model): + _inherit = 'res.partner' + + training = fields.Boolean(string="Training",default=True) From c63622a241963df389e7a1d6489b00c6ea70ac58 Mon Sep 17 00:00:00 2001 From: blackbelts <74664702+eslamtalaat74@users.noreply.github.com> Date: Thu, 19 Jun 2025 10:20:45 +0300 Subject: [PATCH 29/53] view_employee_form_leave_inherit_action --- odex25_hr/hr_holidays_public/views/leaves_balance.xml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/odex25_hr/hr_holidays_public/views/leaves_balance.xml b/odex25_hr/hr_holidays_public/views/leaves_balance.xml index 8510517ae..da5141efc 100644 --- a/odex25_hr/hr_holidays_public/views/leaves_balance.xml +++ b/odex25_hr/hr_holidays_public/views/leaves_balance.xml @@ -39,17 +39,13 @@ - + hr.employee.leave.form.inherit.custom hr.employee - - - - - %(hr_holidays_public.leaves_balancee_action)d + %(hr_holidays_public.leaves_balance_action)d {'search_default_employee_id': active_id} From 9c66aeb54e910d2eabd97ceb503dde02932b0f91 Mon Sep 17 00:00:00 2001 From: ahmed-nouri051 Date: Thu, 19 Jun 2025 09:26:03 +0200 Subject: [PATCH 30/53] modification related to training --- .../exp_official_mission/views/training.xml | 1266 ++++++++++------- 1 file changed, 719 insertions(+), 547 deletions(-) diff --git a/odex25_hr/exp_official_mission/views/training.xml b/odex25_hr/exp_official_mission/views/training.xml index 9608eb95f..57ea4e625 100644 --- a/odex25_hr/exp_official_mission/views/training.xml +++ b/odex25_hr/exp_official_mission/views/training.xml @@ -1,399 +1,553 @@ - - - Employee Training - hr.official.mission - tree,form - [('process_type','=','training')] - {'default_process_type':'training'} - + + + Employee Training + hr.official.mission + tree,form + [('process_type','=','training')] + {'default_process_type':'training'} + - + - + - Employee Training - hr.official.mission - - -
-
- -
- + - -
- - - - - - - - - - - - - - - - + + - + - - - - - - - - - - + + + + + + + + + + - - + - - + + + - + - + - + - - - + + + - - - - - - -
-
- - - - - - + + + +
+
+ + + + + + - - - - - + readonly="1" + force_save="1" /> + + + + - + readonly="1" + force_save="1" /> - + - - - + + + - - + - - - - - - - - - - - - - + +
+ +
+ + + + + + + + + - - - - + + + + - - - - - - + + + + + + - + -
+
-
-
-
- - - -
- - - + +
+
+ + + +
+ + + - - Employee Training Course - hr.official.mission.employee - - - - - - - - - - - - - - - - - -