Title: Error while upgrading my module in odoo to add a ir_cron
Tags: python,json,postgresql,module,odoo

Question: I'm getting this error when trying to 'UPDATE' my module through odoo interface to try to install the ir.cron
Traceback (most recent call last):
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/cache.py", line 85, in lookup
    r = d[key]
  File "<decorator-gen-6>", line 2, in __getitem__
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/lru.py", line 34, in __getitem__
    a = self.d[obj]
KeyError: ('ir.model.data', <function IrModelData._xmlid_lookup at 0x7fc9240dc3a0>, 'iopSaleOrder.model_iop_handler')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 698, in _tag_root
    f(rec)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 568, in _tag_record
    f_val = self.id_get(f_ref, raise_if_not_found=nodeattr2bool(rec, 'forcecreate', True))
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 681, in id_get
    res = self.model_id_get(id_str, raise_if_not_found)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 687, in model_id_get
    return self.env['ir.model.data']._xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/addons/base/models/ir_model.py", line 2023, in _xmlid_to_res_model_res_id
    return self._xmlid_lookup(xmlid)[1:3]
  File "<decorator-gen-40>", line 2, in _xmlid_lookup
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/cache.py", line 90, in lookup
    value = d[key] = self.method(*args, **kwargs)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/addons/base/models/ir_model.py", line 2016, in _xmlid_lookup
    raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: iopSaleOrder.model_iop_handler

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/http.py", line 1584, in _serve_db
    return service_model.retrying(self._serve_ir_http, self.env)
 
    load_data(cr, idref, mode, kind='data', package=package)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/modules/loading.py", line 71, in load_data
    tools.convert_file(cr, package.name, filename, idref, mode, noupdate, kind)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 763, in convert_file
    convert_xml_import(cr, module, fp, idref, mode, noupdate)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 829, in convert_xml_import
    obj.parse(doc.getroot())
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 749, in parse
    self._tag_root(de)
  File "/home/odoo-it1/odoo/versions/16.0/odoo/odoo/tools/convert.py", line 711, in _tag_root
    raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing /home/odoo-it1/odoo/dev/OdooCourse/iopSaleOrder/data/ir_cron_data.xml:2, somewhere inside
<record id="ir_cron_create_sale_order" model="ir.cron">
    <field name="name">Create Sale Order from JSON Data</field>
    <field name="model_id" ref="iopSaleOrder.model_iop_handler"/>
    <field name="state">code</field>
    <field name="code">model.cron_create_sale_order()</field>
    <field name="interval_number">1</field>
    <field name="interval_type">hours</field>
    <field name="numbercall">-1</field>
    <field name="user_id" ref="base.user_root"/>
</record>

The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
    RPCError@http

where should be my problem, I was expecting cron to add since I follow every step and added all fields and seems that he cannot find the eID, what could be wrong?
This is my models/iop_api.py that's been already installed before handling cron.
import logging
import json 
from odoo import api, models, fields, Command

_logger = logging.getLogger(__name__)

class JsonHandler(models.Model):
    _name = 'iop.handler'
    
    data = fields.Char('IOP JSON Data')

    @api.model
    def create_sale_order(self):
        data = json.loads(self.data) 
        Sale = data['Sale']
        for sale in Sale:
            partner = self.env['res.partner'].search([('vat', '=', sale['Clients'][0]['Vat'])], limit=1)
            if not partner:
                # Create partner if not found and loop through all the clients 
                partner = self.env['res.partner'].create({
                    'name': sale['Clients'][0]['Name'] + ' ' + sale['Clients'][0]['Last_name'],
                    'vat': sale['Clients'][0]['Vat'],
                    'email': sale['Clients'][0]['Email'],
                    'street': sale['Clients'][0]['Street'],
                    'street2': sale['Clients'][0]['Street2'],
                    'country_id': self.env['res.country'].search([('code', '=', sale['Clients'][0]['Country_id'].split('/')[0])], limit=1).id,
                    'state_id': self.env['res.country.state'].search([('code', '=', sale['Clients'][0]['State_id'].split('/')[1])], limit=1).id,
                    'zip': sale['Clients'][0]['zip'],
                })      

            order_values = {
                'name': sale['Customer_ref'],
                'partner_id': partner.id,
                'order_line': [],
            }

            for product in sale['Product']:
                product_id = self.env['product.product'].search([('barcode', '=', str(product['Barcode']))], limit=1)
                if product_id:
                    order_values['order_line'].append(Command.create({
                        'product_id': product_id.id,
                        'product_uom_qty': product['Quantity'],
                        'price_unit': product['Price'],
                    }))

            self.env['sale.order'].create(order_values)

    @api.model
    def cron_create_sale_order(self):
        pass
        # handlers = self.search([])
        # for handler in handlers:
        #     handler.create_sale_order()

this is data/ir_cron_data.xml
<odoo>
<record id="ir_cron_create_sale_order" model="ir.cron">
    <field name="name">Create Sale Order from JSON Data</field>
    <field name="model_id" ref="iopSaleOrder.model_iop_handler"/>
    <field name="state">code</field>
    <field name="code">model.cron_create_sale_order()</field>
    <field name="interval_number">1</field>
    <field name="interval_type">hours</field>
    <field name="numbercall">-1</field>
    <field name="user_id" ref="base.user_root"/>
</record>

</odoo>

{
    'name': "IOP Sales",
    'summary': "IOP import orders from Prestashop to Odoo",
    'version': '16.0.1.0.0',
    'depends': [
        'sale',
        
    ],
    'data': [
      'data/ir_cron_data.xml',
      
    ],
}

This is for Odoo 16

Answer: iopSaleOrder.model_iop_handler doesn't exist, data/ir_cron_data.xml is trying to reference this. iopSaleOrder.model_iop_handler needs ti be defined in your module.