Error on Updating Record (write)

I have this model:

class UserTimesheetRecord(ModelSQL, ModelView):
    "Timesheet Record"
    __name__ = 'afx.user.timesheet.record'

    unique_id = fields.Char("Uuid")
    timesheet = fields.Many2One('afx.user.timesheet', "Timesheet")
    date = fields.Date("Date", required=True)
    day = fields.Char("Day")
    task = fields.Selection([], "Status", sort=False)
    project = fields.Many2One('afx.project', "Project", domain=[
        ('so_no', '!=', None)
    ])
    detail = fields.Text("Detail")
    so_no = fields.Char(
        "S/O Number",
        help="Automatically filled based on the selected project.",
        on_change_with=['project']  # Trigger computation when project changes
    )
    time_in = fields.Time(
        "Time In", 
        help="Format: HH:MM"
    )
    time_out = fields.Time(
        'Time Out', 
        help='Format: HH:MM'
    )
    total = fields.Float(
        'Total Hours',
        digits=(16, 2),  # Two decimal places
        help="Calculated total hours spent from Time In to Time Out."
    )

I can create this model with no failure, but when I want to Update it I got error:

Traceback (most recent call last):
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/protocols/dispatcher.py", line 216, in _dispatch
    result = rpc.result(meth(*c_args, **c_kwargs))
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 275, in wrapper
    return func(cls, *args, **kwargs)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1472, in write
    cls._validate(sub_records, field_names=all_field_names)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/transaction.py", line 50, in wrapper
    return func(*args, **kwargs)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelstorage.py", line 1408, in _validate
    validate_domain(field)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelstorage.py", line 1311, in validate_domain
    validate_relation_domain(
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelstorage.py", line 1333, in validate_relation_domain
    finds = Relation.search(['AND',
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1850, in search
    tables, expression, union_orderings = cls.__search_query(
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1798, in __search_query
    tables, expression = cls.search_domain(domain)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1962, in search_domain
    expression = convert(domain)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1958, in convert
    return And((convert(d) for d in (
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1958, in <genexpr>
    return And((convert(d) for d in (
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/modelsql.py", line 1949, in convert
    expression = field.convert_domain(domain, tables, cls)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/fields/field.py", line 217, in wrapper
    return func(self, domain, tables, Model)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/fields/field.py", line 456, in convert_domain
    expression = Operator(column, self._domain_value(operator, value))
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/fields/field.py", line 436, in _domain_value
    return self.sql_format(value)
  File "/home/tryton/afx_project/.env/lib/python3.10/site-packages/trytond/model/fields/date.py", line 36, in sql_format
    value = datetime.date.fromisoformat(value)
ValueError: Invalid isoformat string: '4'

Sample data in my db on a record (related to date or time) of this model are below

I tried many ways to find which part of my code is wrong, I also use AI to get answer… I couldn’t find it.. please need help

Regards
Bromo

You seem to have a domain defined based on a field of type Date but the value of it is not a date.
I do not see it in the code you paste but I suspect it is a record rule on afx.project because the traceback shows that it is during the validation of a relational field with a domain.

@ced

Yes u are 100% correct, I integrate with afx.project.member & afx.project.task in UserTimesheetRecord’s write method as below, but I already comment-out the whole write code block and still the error appears. Does commenting-out the whole block should make the error disappears?

    # -------- OVERRIDE METHODS --------
    @classmethod
    def write(cls, records, values, *args):
        """
        Override the write method to handle creation of ProjectMember and ProjectTask records.
        """
        pool = Pool()
        ProjectMember = pool.get('afx.project.member')
        ProjectTask = pool.get('afx.project.task')

        # Call the super method to ensure the write operation is performed
        super(UserTimesheetRecord, cls).write(records, values, *args)

        for record in records:
            if record.unique_id:
                # Check if the 'project' field has been updated and has a value
                if record.project:
                    project_id = record.project

                    Project = pool.get('afx.project')
                    project = Project.search([
                        ('id', '=', project_id)
                    ])
                    if project:
                        # Get the user from the timesheet field
                        user = record.timesheet.user if record.timesheet else None
                        if not user:
                            logger.warning("No user found for timesheet record")
                            continue

                        # Step 1: Check if a ProjectMember record already exists for the user and project
                        existing_project_member = ProjectMember.search([
                            ('project', '=', project_id),
                            ('member', '=', user.id),
                        ])
                        if existing_project_member:
                            # Use the existing ProjectMember record
                            project_member = existing_project_member[0]
                        else:
                            # Create a new ProjectMember record
                            start_date = project[0].start_date
                            end_date = project[0].end_date
                            project_member_values = {
                                'project': project_id,
                                'member': user.id,
                                'role': 'Default Role',  # You can adjust this as needed
                                'rate': 0,  # Default rate, adjust as needed
                                # Default start/end date for project member is uquals to project's start/end date
                                'est_start_date': None,  # Use the date from the project
                                'est_end_date': None,  # Use the date from the project
                            }
                            project_member, = ProjectMember.create([project_member_values])

                        # Step 2: Check if a ProjectTask record with the same unique_id already exists
                        try:
                            project_task = None
                            existing_project_task = ProjectTask.search([
                                ('unique_id', '=', record.unique_id)
                            ])
                            if existing_project_task:
                                # Update the existing ProjectTask record
                                project_task = existing_project_task[0]  # Assign the existing record to project_task
                                project_task_values = {
                                    'project': project_id,
                                    'activity': record.detail,
                                    'pic': project_member.id,
                                    'start_time': record.time_in,
                                    'end_time': record.time_out,
                                    'total_hours': record.total,
                                    'priority': 'medium',
                                    'status': 'to_do',
                                }
                                ProjectTask.write([project_task], project_task_values)
                            if not existing_project_task:
                                # Create a new ProjectTask record
                                project_task_values = {
                                    'unique_id': record.unique_id,
                                    'project': project_id,
                                    'activity': record.detail,
                                    'pic': project_member.id,
                                    'start_time': record.time_in,
                                    'end_time': record.time_out,
                                    'total_hours': record.total,
                                    'priority': 'medium',
                                    'status': 'to_do',
                                }
                                project_task, = ProjectTask.create([project_task_values])  # Assign the newly created record to project_task
                                # Ensure project_task is always defined before proceeding
                                if 'project_task' not in locals():
                                    logger.error(f"Failed to create or update ProjectTask for record {record.id}")
                                    continue
                        except Exception as e:
                            # Log the exception and continue processing other records
                            logger.error(f"An error occurred while processing record {record.id}: {str(e)}")
                            continue
                else:
                    existing_project_task = ProjectTask.search([
                        ('unique_id', '=', record.unique_id)
                    ])
                    if existing_project_task:
                        ProjectTask.delete(existing_project_task)

        return True

@ced

Resolved already… I made mistake on parent object of UserTimesheetRecord, which at UserTimesheet.
The culprit is the domain at records field.. I take it out and all works well..
Thanks @ced

class UserTimesheet(ModelSQL, ModelView):
    "User Timesheet"
    __name__ = 'afx.user.timesheet'

    # Hardcoded
    MAIN_COMPANY = 1
    UUID_PREFIX = "tsr_"
    ADMIN = "Timesheet Administration"

    year = fields.Selection([], "Year", help='Format: YYYY', required=True, states={
        'readonly': Eval('id', -1) > 0
    }, depends=['id'])
    month = fields.Selection([], "Month", sort=False, required=True, states={
        'readonly': Eval('id', -1) > 0
    }, depends=['id'])
    user = fields.Many2One('company.employee', "User", required=True, domain=[
        ('company', '=', MAIN_COMPANY)
    ])
    unique_id = fields.Char("Uuid", required=True)

    records = fields.One2Many('afx.user.timesheet.record', 'timesheet', "Records", required=False, domain=[
        ('date.month', '=', Eval('month')) <---- THIS IS THE CULPRIT
    ])

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.