Merge branch 'dev_odex25_hr' into bakry_hr3

This commit is contained in:
bakry 2025-06-23 15:37:57 +03:00 committed by GitHub
commit c68079ccd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 1157 additions and 654 deletions

View File

@ -15,6 +15,7 @@ on:
- Twahod-Project
- Ekram-Project
- Sahli-Project
- Sahli-Stage-Project
jobs:
# Cyber Project
@ -116,4 +117,18 @@ jobs:
sudo chmod +x ${{ secrets.SAHLI_STANDARD_FOLDER_PATH }}/scripts/pull_code.sh
sudo ${{ secrets.SAHLI_STANDARD_FOLDER_PATH }}/scripts/pull_code.sh ${{ secrets.SAHLI_PROJECT_USER }} ${{ secrets.SAHLI_STANDARD_FOLDER_PATH }} ${{ secrets.SAHLI_PROD_MASTER_SERVICE }} master ${GITHUB_REF#refs/heads/master_} ${GITHUB_REF#refs/heads/} ${{ secrets.GH_TOKEN }}
sahli_stage_master_server:
name: Deploy to Sahli Stage Master
runs-on: sahli-client-project-runner
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'Sahli-Stage-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: |
echo "** [INFO] Running on branch --> ${GITHUB_REF#refs/heads/}"
mkdir -p ~/master_branch_sha
echo "$(date '+%Y-%m-%d %H:%M:%S') - ${{ github.sha }}" >> ~/master_branch_sha/${GITHUB_REF#refs/heads/}-stage
sudo chmod +x ${{ secrets.SAHLI_STANDARD_FOLDER_PATH }}/scripts/pull_code.sh
sudo ${{ secrets.SAHLI_STANDARD_FOLDER_PATH }}/scripts/pull_code.sh ${{ secrets.SAHLI_PROJECT_USER }} ${{ secrets.SAHLI_STANDARD_FOLDER_PATH }} ${{ secrets.SAHLI_STAGE_MASTER_SERVICE }} master ${GITHUB_REF#refs/heads/master_} ${GITHUB_REF#refs/heads/} ${{ secrets.GH_TOKEN }}

View File

@ -8,7 +8,8 @@
'website': 'http://exp-sa.com',
'license': 'GPL-3',
'author': 'Expert Co. Ltd.' ,
'depends': ['base', 'hr_attendance', 'report_xlsx','hr_base','exp_payroll_custom'],
'depends': ['base', 'hr_attendance', 'report_xlsx','hr_base','exp_payroll_custom',],
# hr_holidays_public
'data': [
'security/attendance_security.xml',
'security/ir.model.access.csv',

View File

@ -126,11 +126,15 @@ class HrAttendanceReport(models.Model):
working_hours = office_hours + permission_hours + mission_hours + mission_by_days_hours + leave_hours
missed_hours = planed_hours - working_hours
missing_punch_transactions = transactions.filtered(
lambda t: (
(t.sign_in and not t.sign_out) or
(not t.sign_in and t.sign_out) or
(not t.sign_in and not t.sign_out and t.office_hours > 0)
not t.public_holiday and
not t.normal_leave and
(
(t.sign_in and not t.sign_out) or
(not t.sign_in and t.sign_out)
)
)
)
@ -286,9 +290,20 @@ class HrAttendanceReport(models.Model):
hours += attendance.official_hours
extra_break_duration += attendance.break_duration
additional_hours += attendance.additional_hours
if (attendance.sign_in and not attendance.sign_out) or (
not attendance.sign_in and attendance.sign_out):
missing_punch_hours = attendance.plan_hours - attendance.official_hours
if (
not attendance.public_holiday and
not attendance.normal_leave and
(
(attendance.sign_in and not attendance.sign_out) or
(not attendance.sign_in and attendance.sign_out)
)
):
missing_punch_hours = (
attendance.plan_hours - attendance.official_hours
if attendance.plan_hours > attendance.official_hours
else 0.0
)
if attendance.is_absent:
actual_absent_hours +=attendance.plan_hours

View File

@ -41,6 +41,9 @@ class HrAttendanceTransactions(models.Model):
has_sign_in = fields.Boolean(readonly=True)
has_sign_out = fields.Boolean(readonly=True)
total_mission_hours = fields.Float()
total_permission_hours = fields.Float()
'''to_date = fields.Boolean(string='Today',compute='_attendance_today', store=True)

View File

@ -396,6 +396,71 @@ msgstr "بند الصرف"
msgid "Accounting"
msgstr "الحسابات"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__name
#: model_terms:ir.ui.view,arch_db:employee_requests.view_hr_classification_form
msgid "Name"
msgstr "الاسم "
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__active
#: model_terms:ir.ui.view,arch_db:employee_requests.view_hr_classification_form
msgid "Active"
msgstr "نشط "
#. module: employee_requests
#: model_terms:ir.ui.view,arch_db:employee_requests.view_hr_classification_form
msgid "HR Classification"
msgstr "التصنيف"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__name
msgid "Classification"
msgstr "التصنيف"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__name
msgid "Name"
msgstr "الاسم "
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__active
msgid "Active"
msgstr "نشط "
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__name
msgid "Classification"
msgstr "التصنيف"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__name
msgid "Name"
msgstr "الاسم "
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_hr_classification__active
msgid "Active"
msgstr "نشط "
#. module: employee_requests
#: model:ir.actions.act_window,name:employee_requests.employee_hr_classification_actionn
#: model:ir.ui.menu,name:employee_requests.hr_classification_menu_item
msgid "HR Classifications"
msgstr "إعداد التصنيف"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_employee_department_jobs__message_needaction
#: model:ir.model.fields,field_description:employee_requests.field_employee_effective_form__message_needaction
@ -964,6 +1029,11 @@ msgstr "المعالين"
msgid "Destination"
msgstr "الجهــــه"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_employee_other_request__classification_id
msgid "Classification"
msgstr "التصنيف"
#. module: employee_requests
#: model:ir.model.fields,field_description:employee_requests.field_salary_destination__english_name
msgid "English Name"
@ -3989,3 +4059,7 @@ msgstr "يجب إدخال إسم دفتر اليومية لإعدادات الع
msgid "Employee %s, has no Overtime Account Setting Base On Employee Type."
msgstr "الموظف %s, ليس لديه إعدادات حساب بند صرف للأجر الإضافي حسب نوع الموظف."

View File

@ -9,6 +9,7 @@ class EmployeeOtherRequest(models.Model):
_rec_name = 'employee_id'
_description = 'Other Request'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'date desc'
from_hr = fields.Boolean()
date = fields.Date(default=lambda self: fields.Date.today())
@ -52,6 +53,7 @@ class EmployeeOtherRequest(models.Model):
is_branch = fields.Many2one(related='department_id.branch_name', store=True, readonly=True)
classification_id = fields.Many2one('hr.classification',string ='Classification')
def print_with_details(self):
return self.env.ref('employee_requests.action_report_employee_identification').report_action(self)
@ -91,36 +93,40 @@ class EmployeeOtherRequest(models.Model):
if item.request_type == 'dependent':
if not item.employee_dependant:
raise exceptions.Warning(_('Please The dependents were not Included'))
#if item.employee_id.contract_id.contract_status == 'single':
#raise exceptions.Warning(_('You can not Add Fimaly record Because Employee is Single'))
else:
for rec in item.employee_dependant:
if not rec.attachment:
raise exceptions.Warning(_('Please Insert dependents Attachments Files Below!'))
item.state = "submit"
if item.request_type == 'qualification':
if not item.qualification_employee:
raise exceptions.Warning(_('Please The qualification or certification were not Insert Below!'))
for rec in item.qualification_employee:
if not rec.attachment:
raise exceptions.Warning(_('Please Insert Attachments Files Below!'))
else:
item.state = "submit"
if item.request_type == 'certification':
if not item.certification_employee:
raise exceptions.Warning(_('Please The qualification or certification were not Insert Below!'))
for rec in item.certification_employee:
if not rec.attachment:
raise exceptions.Warning(_('Please Insert Attachments Files Below!'))
else:
item.state = "submit"
else:
item.state = "submit"
if item.request_type in ['suggestion', 'complaint']:
item.state = "submit"
else:
item.state = "confirm"
def confirm(self):
#self.state = 'confirm'
@ -252,7 +258,14 @@ class Qualification(models.Model):
# Hr_Employee_Certification
class HrCertification(models.Model):
class HrCerti(models.Model):
_inherit = 'hr.certification'
request_id = fields.Many2one('employee.other.request')
class HrCclassification(models.Model):
_name = 'hr.classification'
_rec_name = 'name'
name = fields.Char(string='Name') # Translatable
active = fields.Boolean(default=True, string='Active')

View File

@ -19,3 +19,5 @@ access_degree_medical_issuance_hr,degree_medical_issuance_hr,model_degree_medica
access_degree_medical_issuance_emp,degree_medical_issuance_emp,model_degree_medical_issuance,base.group_user,1,0,0,0
access_salary_destination_hr,salary_destination_hr,model_salary_destination,hr.group_hr_user,1,1,1,1
access_salary_destination_emp,salary_destination_emp,model_salary_destination,base.group_user,1,0,0,0
access_hr_classification,hr_classification,model_hr_classification,base.group_user,1,1,1,1

1 id name model_id:id group_id/id perm_read perm_write perm_create perm_unlink
19 access_degree_medical_issuance_emp degree_medical_issuance_emp model_degree_medical_issuance base.group_user 1 0 0 0
20 access_salary_destination_hr salary_destination_hr model_salary_destination hr.group_hr_user 1 1 1 1
21 access_salary_destination_emp salary_destination_emp model_salary_destination base.group_user 1 0 0 0
22 access_hr_classification hr_classification model_hr_classification base.group_user 1 1 1 1
23

View File

@ -49,6 +49,7 @@
<button name="draft_state" string="RE-Draft" class="oe_highlight" type="object"
states="refused,done"
groups="hr.group_hr_user" confirm="Are you sure to Reset To Draft This Record?"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>

View File

@ -6,7 +6,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">employee.other.request</field>
<field name="view_mode">tree,form,calendar</field>
<field name= "context">{"search_default_my_request":1}</field>
<field name= "context">{"search_default_my_request":1}</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Employee Other Request
@ -68,7 +68,9 @@
id="with_details2"
attrs="{'invisible': ['|',('request_type', '!=', 'salary_fixing'),('state', '!=', 'approved')]}"
class="oe_highlight" groups="base.group_user"/>
<field name="state" widget="statusbar" statusbar_colors="{'KEY_IS_STATE':'VALUE_IS_COLOR'}"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,confirm,approved,refuse"
statusbar_colors="{'KEY_IS_STATE':'VALUE_IS_COLOR'}"/>
</header>
<sheet>
<group>
@ -100,7 +102,15 @@
<field name="parent_request_id" attrs="{'invisible':['|',('parent_request_id','=','False'),
('request_type','!=','insurance')]}" readonly="1"/>
<field name="destination" attrs="{'invisible': [('request_type', 'not in', ('salary_define','salary_fixing'))],
'required': [('request_type', 'in', ('salary_define','salary_fixing'))],'readonly': [('state', '!=', 'draft')]}"/>
'required': [('request_type', 'in', ('salary_define','salary_fixing'))],
'readonly': [('state', '!=', 'draft')]}"/>
<!-- <field name="classification_id" string="Classification" required="1"/>-->
<field name="classification_id" string="التصنيف"
attrs="{'invisible': [('request_type', 'not in', ('suggestion','complaint'))],'required': [('request_type', 'in', ('suggestion','complaint'))],
}"/>
@ -237,9 +247,9 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search>
<field name="employee_id"/>
<field name="employee_no"/>
<field name="department_id" />
<field name="employee_id"/>
<field name="employee_no"/>
<field name="department_id" />
<group expand="0" string="Group By">
<filter name="group_employee" string="Employee" domain="[]" context="{'group_by': 'employee_id'}"/>
<filter name="group_department" string="Department" domain="[]" context="{'group_by': 'department_id'}"/>
@ -247,11 +257,41 @@
<filter name="group_state" string="State" domain="[]" context="{'group_by': 'state'}"/>
</group>
<separator/>
<filter string="My Requests" name="my_request" domain="[('employee_id.user_id', '=', uid)]"/>
<filter string="My Requests" name="my_request" domain="[('employee_id.user_id', '=', uid)]"/>
<separator/>
</search>
</field>
</record>
<record id="view_hr_classification_form" model="ir.ui.view">
<field name="name">hr.classification.form</field>
<field name="model">hr.classification</field>
<field name="arch" type="xml">
<form string="HR Classification">
<sheet>
<group>
<field name="name" string="الاسم"/>
<field name="active" string="الحالة"/>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="employee_hr_classification_actionn">
<field name="name">HR Classifications</field>
<field name="res_model">hr.classification</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem name="التصنيف " id="hr_classification_menu_item"
parent="hr.hr_menu_configuration"
action="employee_hr_classification_actionn"
/>
</data>
</odoo>

View File

@ -550,6 +550,13 @@ msgstr "الدرجة الكاملة"
msgid "Greed"
msgstr "الدرجة المحققة"
#. module: exp_hr_appraisal
#: model:ir.model.fields,field_description:exp_hr_appraisal.field_standard_appraisal_line__priority
#: model_terms:ir.ui.view,arch_db:exp_hr_appraisal.hr_appraisal_form_view
msgid "priority"
msgstr " التقييم "
#. module: exp_hr_appraisal
#: code:addons/exp_hr_appraisal/models/employees_appraisal.py:0
#: model:ir.model.fields.selection,name:exp_hr_appraisal.selection__hr_group_employee_appraisal__state__gm_approval

View File

@ -262,9 +262,52 @@ class StandardAppraisalLines(models.Model):
accrued_greed = fields.Float()
question = fields.Char()
great_level = fields.Float()
priority = fields.Selection(
[
('1', '1'),
('2', '2'),
('3', '3'),
('4', '4'),
('5', '5'),
('6', '6'),
],
string='Priority',
compute='_compute_priority',
inverse='_inverse_priority',
store=True
)
# Relational fields
standard_appraisal_employee_line = fields.Many2one('hr.employee.appraisal') # inverse field
standard_appraisal_employee_line = fields.Many2one('hr.employee.appraisal')
@api.depends('greed', 'great_level')
def _compute_priority(self):
for rec in self:
if rec.great_level:
value = rec.greed / (rec.great_level / 5)
# 3.5
if 1 <= value <= 2:
rec.priority = '1'
elif 2 < value <= 3:
rec.priority = '2'
# 3.5
elif 3 < value <= 4:
rec.priority = '3'
# 4
elif 4 < value <= 5:
rec.priority = '4'
elif value > 5:
rec.priority = '5'
else:
rec.priority = '0' # fallback
else:
rec.priority = '0'
def _inverse_priority(self):
for rec in self:
if rec.great_level and rec.priority:
# 3*2
# 2*4
rec.greed = int(rec.priority) * (rec.great_level / 5)
@api.constrains('greed', 'great_level')
def greed_constrains(self):

View File

@ -49,7 +49,10 @@
attrs="{'invisible':[('is_manager','=',True)],'readonly':[('state', 'not in', ['draft', 'employee_confirmation'])] }">
<tree editable="bottom">
<field name="question" string="Question" readonly="1" force_save="1"/>
<field name="priority" string="priority" widget="priority"/>
<field name="greed" string="Greed" required="1" force_save="1" store="1" />
<field name="accrued_greed" attrs="{
'invisible': [('parent.employee_protest', '!=', True)],
'column_invisible': [('parent.employee_protest', '!=', True)]

View File

@ -25,7 +25,7 @@
'views/ticket_view.xml',
'views/course_view.xml',
'views/appraisal_view.xml',
# 'views/res_partner_form_view.xml',
'views/res_partner_form_view.xml',
'views/training_menus.xml',
'wizard/employee_selection_wizard.xml',
'wizard/training_appraisal.xml',

View File

@ -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
@ -683,6 +692,8 @@ 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_training_form_view
#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_training_tree_view
msgid "Total Hours"
msgstr "مجموع الساعات"
@ -1797,7 +1808,9 @@ msgstr "نوع طلب التذكرة"
#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_especially_line_form_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
#: model_terms:ir.ui.view,arch_db:exp_official_mission.hr_employees_training_lines_form
#: model_terms:ir.ui.view,arch_db:exp_official_mission.employee_training_tree_view
msgid "Total Hours"
msgstr "مجموع الساعات"
@ -2662,6 +2675,12 @@ msgstr "خطة التقييم"
msgid "Training Course"
msgstr "الدورة التدريبية"
#. module: exp_official_mission
#: model:ir.model.fields,field_description:exp_official_mission.field_hr_employee_appraisal__course_name
msgid "Course Name"
msgstr " اسم الدورة التدريبية"
#. module: exp_official_mission
#: model:ir.model,name:exp_official_mission.model_appraisal_result
#: model:ir.model.fields,field_description:exp_official_mission.field_appraisal_plan__appraisal_result_ids
@ -2805,3 +2824,7 @@ msgid "If there are no attendance, this day will be absent."
msgstr "في حالة عدم وجود حضور، سيتم اعتبار اليوم غياب"
#. module: exp_official_mission
#: model:ir.model.fields,field_description:exp_official_mission.field_res_partner_training
msgid "Training"
msgstr "تدريب"

View File

@ -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=False)

View File

@ -7,6 +7,7 @@ class EmployeeAppraisal(models.Model):
_inherit= 'hr.employee.appraisal'
mission_id = fields.Many2one('hr.official.mission', string="Training Course",domain=[("mission_type.work_state", "=", "training")])
course_name = fields.Many2one(related='mission_id.course_name',string="Course Name")
@api.onchange('department_id', 'mission_id', 'appraisal_type')
def employee_ids_domain(self):

View File

@ -24,7 +24,7 @@ class HrOfficialMission(models.Model):
hour_to = fields.Float(default=16)
date_duration = fields.Float()
hour_duration = fields.Float(default=8)
total_hours = fields.Float()
total_hours = fields.Float(compute='compute_number_of_hours',store=True,)
balance = fields.Float()
early_exit = fields.Boolean()
mission_purpose = fields.Text()
@ -104,11 +104,10 @@ class HrOfficialMission(models.Model):
hr_nomination = fields.Boolean(string="HR Nomination")
@api.onchange('hour_duration', 'date_duration')
@api.constrains('hour_duration', 'date_duration')
@api.depends('hour_duration', 'date_duration')
def compute_number_of_hours(self):
for item in self:
# if item.hour_duration and item.date_duration:
item.total_hours = item.hour_duration * item.date_duration
@ -277,6 +276,7 @@ class HrOfficialMission(models.Model):
end_mission_date = datetime.strptime(str(item.date_to), "%Y-%m-%d")
if not item.table_ids:
print("khgggggg")
if end_mission_date >= start_mission_date:
if not item.table_ids:
days = (end_mission_date - start_mission_date).days
@ -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:
@ -308,6 +309,7 @@ class HrOfficialMission(models.Model):
raise exceptions.Warning(
_('mission duration must be less than "%s" maximum days in mission type "%s" ') % (
item.mission_type.maximum_days, item.mission_type.name))
else:
unique_dates = set(item.table_ids.mapped('date'))
item.date_duration = len(unique_dates)
@ -362,7 +364,14 @@ 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:
print("55555555556")
line.days = len(date_range)
else:
unique_dates = set(item.table_ids.mapped('date'))
line.days = len(unique_dates)
print("555ooooo")
print(line.days)
if item.mission_type.related_with_financial is True:
if item.mission_type.type_of_payment == 'fixed':
if item.mission_type.day_price:
@ -397,6 +406,7 @@ class HrOfficialMission(models.Model):
else:
line.hours = (line.hour_to - line.hour_from)
line.total_hours = line.hours * line.days
print("11111111111")
if item.mission_type.related_with_financial is True:
if item.mission_type.type_of_payment == 'fixed':
if item.mission_type.hour_price:
@ -416,7 +426,8 @@ class HrOfficialMission(models.Model):
def re_compute(self):
self.employee_ids.compute_Training_cost_emp()
self.employee_ids.compute_day_price()
self.employee_ids.compute_number_of_days()
if not self.table_ids:
self.employee_ids.compute_number_of_days()
self.employee_ids.compute_number_of_hours()
return True
@ -1355,7 +1366,17 @@ class HrOfficialMissionEmployee(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.days = len(date_range)
if not item.official_mission_id.table_ids:
item.days = len(date_range)
else:
unique_dates = set(item.official_mission_id.table_ids.mapped('date'))
item.days = len(unique_dates)
print(item.days)
print(item.days)
# item.days = len(date_range)
else:
raise exceptions.Warning(_('Date Form Must Be Less than Date To'))
else:
@ -1376,7 +1397,18 @@ class HrOfficialMissionEmployee(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.days = len(date_range)
print("pppppppp00")
print(date_range)
if not item.official_mission_id.table_ids:
print("55555555556")
item.days = len(date_range)
else:
print("kkkffld")
unique_dates = set(item.official_mission_id.table_ids.mapped('date'))
item.days = len(unique_dates)
print(item.days)
print(item.days)
else:
raise exceptions.Warning(_('Date Form Must Be Less than Date To'))
@ -1395,6 +1427,8 @@ class HrOfficialMissionEmployee(models.Model):
else:
item.hours = (item.hour_to - item.hour_from)
item.total_hours = item.hours * item.days
print("22222222222")
else:
item.hour_from = item.official_mission_id.hour_from
item.hour_to = item.official_mission_id.hour_to
@ -1406,6 +1440,7 @@ class HrOfficialMissionEmployee(models.Model):
item.hours = (item.hour_to - item.hour_from)
item.total_hours = item.hours * item.days
# compute day_price , hour_price and amount
@api.onchange('hour_from', 'hour_to', 'hours', 'date_from', 'date_to', 'days', 'employee_id', 'day_price',
@ -1723,11 +1758,22 @@ class MissionTable(models.Model):
date = fields.Date()
hour_from = fields.Float(default=8)
hour_to = fields.Float(default=16)
hour_from = fields.Float()
hour_to = fields.Float()
trainer_id = fields.Many2one('res.partner', string="Trainer")
destination_id = fields.Many2one('hr.official.mission', string="Destination ")
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
parent_id = self.env.context.get('default_destination_id')
if parent_id:
parent = self.env['hr.official.mission'].browse(parent_id)
if parent and parent.hour_from:
res['hour_from'] = parent.hour_from
res['hour_to'] = parent.hour_to
return res
@api.constrains('date', 'destination_id')
def _check_date_within_destination(self):
for rec in self:

View File

@ -20,6 +20,8 @@
<xpath expr="//field[@name='appraisal_type']" position="after">
<field name="mission_id" attrs="{'invisible':[('appraisal_type','!=', 'training')]}"/>
<field name="course_name" attrs="{'invisible':[('appraisal_type','!=', 'training')]}"/>
</xpath>
</field>

View File

@ -167,24 +167,24 @@
</group>
<group>
<!-- <field name="ticket_insurance" string="Ticket Insurance"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="ticket_insurance" string="Ticket Insurance"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<field name="self_car" string="Self Car"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="visa" string="Visa" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="note" string="Other"
attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
<!-- <group>-->
<!-- <field name="car_insurance" string="Car Insurance"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="car_type" string="Car Type"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="rent_days" string="Rent Days"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="max_rent" string="Max Rent"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- </group>-->
<!-- <group>-->
<!-- <field name="car_insurance" string="Car Insurance"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="car_type" string="Car Type"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="rent_days" string="Rent Days"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- <field name="max_rent" string="Max Rent"-->
<!-- attrs="{'readonly':[('state','!=','draft')]}"/>-->
<!-- </group>-->
</group>
</page>
<page string="Attachments" name="attachments">
@ -243,11 +243,11 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search>
<field name="mission_type"/>
<field name="employee_id"/>
<field name="employee_no"/>
<field name="destination"/>
<field name="state"/>
<field name="mission_type"/>
<field name="employee_id"/>
<field name="employee_no"/>
<field name="destination"/>
<field name="state"/>
<group expand="0" string="Group By">
<filter name="group_employee" string="Responsible" domain="[]" context="{'group_by': 'employee_id'}"/>
<filter name="group_type" string="Mission Type" domain="[]" context="{'group_by': 'mission_type'}"/>
@ -256,7 +256,7 @@
<filter name="group_state" string="State" domain="[]" context="{'group_by': 'state'}"/>
</group>
<separator/>
<filter string="My Requests" name="my_request" domain="[('employee_id.user_id', '=', uid)]"/>
<filter string="My Requests" name="my_request" domain="[('employee_id.user_id', '=', uid)]"/>
<separator/>
</search>
</field>
@ -342,6 +342,7 @@
<field name="hour_from" widget="float_time"/>
<field name="hour_to" widget="float_time"/>
<field name="hours" widget="float_time"/>
<field name="total_hours" string="Total Hours"/>
<field name="state" string="Status" invisible="1"/>
<field name="state" string="Status"/>
</tree>

View File

@ -8,6 +8,7 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='category_id']" position="after">
<field name="training" />
</xpath>
</field>
</record>

File diff suppressed because it is too large Load Diff

View File

@ -294,30 +294,59 @@ 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):
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')

View File

@ -251,8 +251,11 @@ class EmployeeMissionTrainingReportXlsx(models.AbstractModel):
sheet.write(row, clm + 14, (rec.day_price + rec.train_cost_emp), format1)
sheet.write(row, clm + 15, rec.date_from, date_format)
sheet.write(row, clm + 16, rec.date_to, date_format)
sheet.write(row, clm + 17, str(rec.hours))
sheet.write(row, clm + 18, str(rec.days))
# sheet.write(row, clm + 17, str(rec.hours))
sheet.write(row, clm + 17, str(rec.days))
# sheet.write(row, clm + 18, str(rec.days))
sheet.write(row, clm + 18, str(rec.total_hours))
if self.env.user.lang != 'en_US':
sheet.write(row, clm + 19, stages[rec.official_mission_id.state], format1)
else:

View File

@ -244,7 +244,8 @@
<td>
<t>
<span t-esc="o.hours"/>
<!-- <span t-esc="o.hours"/>-->
<span t-esc="o.total_hours"/>
Hour
</t>

View File

@ -139,6 +139,7 @@
attrs="{'invisible': [('show_leaves','=', False)]}"
groups="base.group_user"
help="Remaining leaves">
<field string="Leaves Left" name="leaves_count" widget="statinfo"/>
</button>
</xpath>

View File

@ -10,59 +10,47 @@
<field name="search_view_id" ref="hr_holidays_community.view_hr_holidays_filter"/>
</record>
<record id="view_hr_holidays_tree_no_delete" model="ir.ui.view">
<field name="name">hr.holidays.tree.no.delete</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays_public.leaves_balance_tree_view"/>
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="delete">false</attribute>
<attribute name="edit">false</attribute>
<attribute name="create">false</attribute>
</tree>
</field>
</record>
<record id="view_hr_holidays_form_no_delete" model="ir.ui.view">
<field name="name">hr.holidays.form.no.delete</field>
<field name="model">hr.holidays</field>
<field name="inherit_id" ref="hr_holidays_community.edit_holiday_new"/>
<field name="arch" type="xml">
<form position="attributes">
<attribute name="delete">false</attribute>
<attribute name="edit">false</attribute>
<attribute name="create">false</attribute>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="leaves_balancee_action">
<field name="name">Leaves Balance</field>
<field name="res_model">hr.holidays</field>
<field name="view_mode">tree,form</field>
<field name="view_ids" eval="[
(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('view_hr_holidays_tree_no_delete')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('hr_holidays_public.leaves_balance_form_view')})
]"/>
<field name="domain">[('type','=','add'),('check_allocation_view','=','balance')]</field>
<field name="context">{'search_default_employee_id': [active_id], 'default_employee_id': active_id, 'search_default_group_type': 1,
'search_default_year': 1}</field>
<field name="context">{'default_type':'add', 'default_check_allocation_view': 'balance'}</field>
<field name="search_view_id" ref="hr_holidays_community.view_hr_holidays_filter"/>
</record>
<record id="view_employee_form_leave_inherit_custom" model="ir.ui.view">
<!-- <record id="view_employee_form_leave_inherit_custome" model="ir.ui.view">-->
<!-- <field name="name">hr.employee.leave.form.inherit.custom</field>-->
<!-- <field name="model">hr.employee</field>-->
<!-- <field name="inherit_id" ref="hr_holidays_community.view_employee_form_leave_inherit"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//button[@name='%(hr_holidays_community.act_hr_employee_holiday_request)d']" position="attributes">-->
<!-- <attribute name="name">%(hr_holidays_public.leaves_balancee_action)d</attribute>-->
<!--&lt;!&ndash; <attribute name="name">%(hr_holidays_public.leaves_balance_action)d</attribute>&ndash;&gt;-->
<!--&lt;!&ndash; <attribute name="context">{'search_default_employee_id': active_id}</attribute>&ndash;&gt;-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<record id="view_employee_form_leave_inherit_actionn" model="ir.ui.view">
<field name="name">hr.employee.leave.form.inherit.custom</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr_holidays_community.view_employee_form_leave_inherit"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='%(hr_holidays_community.act_hr_employee_holiday_request)d']" position="attributes">
<attribute name="name">%(hr_holidays_public.leaves_balancee_action)d</attribute>
</xpath>
<xpath expr="//button[child::field[@name='leaves_count']]" position="attributes">
<attribute name="name">%(hr_holidays_public.leaves_balance_action)d</attribute>
<attribute name="context">{'search_default_employee_id': active_id}</attribute>
</xpath>
</field>
</record>
@ -74,6 +62,11 @@
<record model="ir.ui.view" id="leaves_balance_form_view">
<field name="name">Leaves Balance</field>
<field name="model">hr.holidays</field>