0
votes

I have added a new model (call it crm_lead_external) that is linked via a new one2many on crm_lead.

Thus, my module has two models defined: an updated crm_lead (with _name=crm_lead) and a new crm_lead_external.

This external model tracks a file and as such has a 'filename' field.

I also created a unique SQL index on this filename field.

This is part of my module:

def copy(self, cr, uid, id, default=None, context=None):
    if not default:
        default = {}
    default.update({
        'state': 'new',
        'filename': '',
    })
    ret = super(crm_lead_external, self).copy(cr, uid, id, default, context=context)
    #do file copy
    return ret

The intent here is to allow an external entity to be duplicated, but to retarget the file path.

Now, if I click duplicate on the Lead, I get an IntegrityError on my unique constraint. Is there a particular reason why copy() isn't being called?

Should I add this logic to copy_data()? Myst I really override copy() for the lead?

Thanks in advance.

3

3 Answers

3
votes

There are two osv class methods: copy and copy_data, which are accessible to all osv subclasses, such as your crm_lead_external class.

When you click Duplicate it calls osv.copy(). If your model contains any relational fields and those fields have any records linked then osv will call copy_data() on the linked records. In your case, when you call copy on model crm.lead, it calls copy_data() on crm_lead_external. You have a UNIQUE constraint on crm_lead_external, and that causes your error message.

There can be two fixes to this problem.

  1. If you don't want to copy crm_lead_external records, then override the copy method of the crm.lead model and disable copying of the crm_lead_external oem field values.

    def copy(self, cr, uid, id, default=None, context=None):
        if default is None:
            default = {}
        default['o2m_field'] = []
        return super(<calss_name>, self).copy(cr, uid, id, default, context)
    

    This will stop copying the o2m field record.

  2. We will override the copy method of your model crm_lead_extenal so every time copy_data is called, we will resolve the UNIQUE constraint stuff and and pass new values so you will not encounter any issues.

    def copy_data(self, cr, uid, id, default=None, context=None):
        if default is None:
            default = {}
        default['name'] = self.browse(cr, uid, id, context=context).name or ''
        if not context.get('copy',False):
            new_name = _("%s (copy)")%default.get('name','')
            default.update({'name':new_name})
        return super(<calss_bame>, self).copy_data(cr, uid, id, default, context)
    

    In this example, I have appended copy text at the end of the name so I will always get a new name, likewise you can avoid UNIQUE constraints like this, and you will have all the data copied perfectly.

0
votes

just change the value of the unique fields in copy method. like adding " COPY" after the original value.

you can have en example in addons/product/product.py line no 660

0
votes

Try this code :

def copy(self,cr,uid,id,default = None,context = None):
        print"---------Calling copy function----"
        print default

                return super(demo_courses, self).copy(cr, uid, id, default, context)