Compare commits

...

28 Commits

Author SHA1 Message Date
administrator 05d145c5cd pull commit 2025-06-02 16:25:55 +05:30
administrator 9c6feae512 Initial commit 2025-06-02 16:25:55 +05:30
Pranay 71293ad8ef TimeOff Fix 2025-06-02 16:25:55 +05:30
Pranay fc053eca72 time-off FIX 2025-06-02 16:25:55 +05:30
Pranay 40020cf23c Recruitment Changes 2025-06-02 16:25:55 +05:30
Pranay edc151bb1e fix whatsapp 2025-06-02 16:25:55 +05:30
Pranay 2908134931 update whatsapp code 2025-06-02 16:25:55 +05:30
administrator 212900a1d3 Initial commit 2025-06-02 16:25:55 +05:30
administrator bd382f6d20 Initial commit 2025-06-02 16:25:55 +05:30
administrator 5f23d59213 Initial commit 2025-06-02 16:25:55 +05:30
administrator db1906ce4c Initial commit 2025-06-02 16:25:55 +05:30
administrator 1befd50b28 Initial commit 2025-06-02 16:25:55 +05:30
administrator 9c1ebc720c Initial commit 2025-06-02 16:25:55 +05:30
administrator b88c388b75 Initial commit 2025-06-02 16:25:55 +05:30
administrator 52641f4514 Initial commit 2025-06-02 16:25:55 +05:30
administrator 9b751e29d5 Initial commit 2025-06-02 16:25:55 +05:30
administrator a588370258 Initial commit 2025-06-02 16:25:55 +05:30
administrator 2498d1010b Initial commit 2025-06-02 16:25:54 +05:30
administrator ab560ad6d6 Initial commit 2025-06-02 16:25:54 +05:30
administrator daf31782fd Initial commit 2025-06-02 16:25:54 +05:30
administrator f88623168f Initial commit 2025-06-02 16:25:54 +05:30
administrator 0537dc1979 Initial commit 2025-06-02 16:25:54 +05:30
administrator e5972f0f92 Initial commit 2025-06-02 16:25:54 +05:30
administrator 902813c978 Initial commit 2025-06-02 16:25:54 +05:30
administrator eb4ccbfa22 Initial commit 2025-06-02 16:25:54 +05:30
administrator 01f5d4c74e Initial commit 2025-06-02 16:25:54 +05:30
administrator f07ae8eb99 Initial commit 2025-06-02 16:25:54 +05:30
raman 19bdf92f67 fix Time zone 2025-06-02 16:13:09 +05:30
3 changed files with 21 additions and 9 deletions

View File

@ -18,8 +18,12 @@
'version': '0.1', 'version': '0.1',
# any module necessary for this one to work correctly # any module necessary for this one to work correctly
'depends': ['base','hr','account','mail','hr_skills', 'hr_contract'], 'depends': ['base','hr','account','mail','hr_skills', 'hr_contract'],
# always loaded # always loaded
'data': [ 'data': [
'security/security.xml', 'security/security.xml',

View File

@ -256,6 +256,8 @@ class HRJobRecruitment(models.Model):
rec.submission_status = 'zero' rec.submission_status = 'zero'
experience = fields.Many2one('candidate.experience', string="Experience")
@api.depends('application_ids.submitted_to_client') @api.depends('application_ids.submitted_to_client')
def _compute_no_of_submissions(self): def _compute_no_of_submissions(self):
counts = dict(self.env['hr.applicant']._read_group( counts = dict(self.env['hr.applicant']._read_group(

View File

@ -2,7 +2,7 @@ from odoo import models, fields, api
from datetime import timedelta from datetime import timedelta
import json import json
from collections import defaultdict from collections import defaultdict
from datetime import datetime from pytz import timezone, UTC
class AttendanceWeeklyReport(models.Model): class AttendanceWeeklyReport(models.Model):
@ -22,32 +22,39 @@ class AttendanceWeeklyReport(models.Model):
last_monday = today - timedelta(days=today.weekday() + 7) last_monday = today - timedelta(days=today.weekday() + 7)
last_sunday = last_monday + timedelta(days=6) last_sunday = last_monday + timedelta(days=6)
user_tz = self.env.user.tz or 'UTC'
tz = timezone(user_tz)
# Search for attendance in UTC (Odoo stores in UTC)
attendances = self.env['hr.attendance'].search([ attendances = self.env['hr.attendance'].search([
('check_in', '>=', str(last_monday)), ('check_in', '>=', str(last_monday)),
('check_out', '<=', str(last_sunday + timedelta(days=1))) ('check_out', '<=', str(last_sunday + timedelta(days=1)))
]) ])
employee_data = {}
employee_data = defaultdict(list) employee_data = defaultdict(list)
grouped_attendance = defaultdict(lambda: defaultdict(list)) # {emp: {date: [attendances]}} grouped_attendance = defaultdict(lambda: defaultdict(list)) # {emp: {date: [attendances]}}
# Group attendances by employee and local date
for att in attendances: for att in attendances:
emp = att.employee_id.name emp = att.employee_id.name
date = att.check_in.date() check_in_local = att.check_in.astimezone(tz)
grouped_attendance[emp][date].append(att) date_local = check_in_local.date()
grouped_attendance[emp][date_local].append(att)
# Process each employee's attendance
for emp_name, dates in grouped_attendance.items(): for emp_name, dates in grouped_attendance.items():
for date, records in dates.items(): for date, records in dates.items():
records = sorted(records, key=lambda a: a.check_in) records = sorted(records, key=lambda a: a.check_in)
total_seconds = 0 total_seconds = 0
first_in = records[0].check_in.time().strftime('%H:%M') first_in = records[0].check_in.astimezone(tz).strftime('%H:%M')
last_out = 'N/A' last_out = 'N/A'
for rec in records: for rec in records:
if rec.check_in and rec.check_out: if rec.check_in and rec.check_out:
total_seconds += (rec.check_out - rec.check_in).total_seconds() check_in_local = rec.check_in.astimezone(tz)
last_out = rec.check_out.time().strftime('%H:%M') check_out_local = rec.check_out.astimezone(tz)
total_seconds += (check_out_local - check_in_local).total_seconds()
last_out = check_out_local.strftime('%H:%M')
employee_data[emp_name].append({ employee_data[emp_name].append({
'date': date.strftime('%Y-%m-%d'), 'date': date.strftime('%Y-%m-%d'),
@ -55,7 +62,6 @@ class AttendanceWeeklyReport(models.Model):
'out': last_out, 'out': last_out,
'hours': f'{total_seconds / 3600:.2f}', 'hours': f'{total_seconds / 3600:.2f}',
}) })
# Inline QWeb-compatible HTML template (must be in a real view in production) # Inline QWeb-compatible HTML template (must be in a real view in production)
html_template = """ html_template = """
<div style="max-width:800px;margin:auto;background-color:#fff;padding:20px;border:1px solid #ddd;border-radius:8px;"> <div style="max-width:800px;margin:auto;background-color:#fff;padding:20px;border:1px solid #ddd;border-radius:8px;">