from odoo import api, fields, models from datetime import date, timedelta class WeekTimesheet(models.Model): _name = 'week.timesheet' _description = 'Week Timesheet' _rec_name = 'year' year = fields.Char( string="Year", required=True, default=lambda self: date.today().year ) week_line_ids = fields.One2many( 'week.timesheet.line', 'week_timesheet_id', string="Weeks" ) def action_generate_weeks(self): for rec in self: self.week_line_ids = [(5, 0, 0)] if not self.year: return selected_year = int(self.year) lines = [] # START DATE jan_first = date(selected_year, 1, 1) # If year starts in middle of week, # move to next Monday if jan_first.weekday() != 0: days_to_monday = 7 - jan_first.weekday() current_date = jan_first + timedelta(days=days_to_monday) else: current_date = jan_first # PREVIOUS YEAR LAST WEEK prev_year_end = date(selected_year - 1, 12, 31) prev_week_start = prev_year_end - timedelta( days=prev_year_end.weekday() ) prev_week_end = prev_week_start + timedelta(days=6) # If previous week overlaps current year, # start after it if prev_week_end.year == selected_year: current_date = prev_week_end + timedelta(days=1) week_number = 1 while current_date.year <= selected_year: week_start = current_date week_end = current_date + timedelta(days=6) lines.append((0, 0, { 'week_name': f"Week {week_number:02d}", 'date_from': week_start, 'date_to': week_end, })) week_number += 1 current_date = week_end + timedelta(days=1) # Stop when next week completely outside year if current_date.year > selected_year and current_date.month > 1: break self.week_line_ids = lines class WeekTimesheetLine(models.Model): _name = 'week.timesheet.line' _description = 'Week timesheet Line' _rec_name = 'display_name' week_timesheet_id = fields.Many2one( 'week.timesheet', string="Week Timesheet" ) week_name = fields.Char(string="Week") date_from = fields.Date(string="Start Date") date_to = fields.Date(string="End Date") display_name = fields.Char( compute="_compute_display_name", store=True ) @api.depends('week_name', 'date_from', 'date_to') def _compute_display_name(self): for rec in self: rec.display_name = ( f"{rec.week_name} " f"({rec.date_from} To {rec.date_to})" )