In OpenERP7, the core module account has a declaration for account.invoice which has, at some point, the following declaration:
addons/account/account_invoice.py:343
_sql_constraints = [
('number_uniq', 'unique(number, company_id, journal_id, type)', 'Invoice Number must be unique per Company!'),
]
In a module which redefined account.invoice I wanted to remove the constraint with two different approaches:
Removing it in init (account_invoice::init(self, pool, cr))
def __init__(self, pool, cr):
super(account_invoice, self).__init__(pool, cr)
try:
cr.execute('ALTER TABLE account_invoice DROP CONSTRAINT IF EXISTS account_invoice_number_uniq')
finally:
pass
Replacing the constraint
_sql_constraints = [
('number_uniq', 'check(1=1)', 'Dummy check, always true, used to replace the previous constraint'),
]
However, when I reinstall the module in which those two declarations were made, I get an error (in the PG logs) telling me that the constraint account_invoice_number_uniq could not be craeted for a unique key since there's repeated data.
How can I prevent having such error? How can I prevent the system attempting to create (first; then... replace/delete) the constraint?
Check the Below Reference Link to remove the SQL Constraint Of Parent Class in Odoo
Click To See the Reference For Remove the SQL Constraint In Odoo(formally OpenERP)
Related
I have used as
_sql_constraints = [
('bpv_uniq', 'unique (branch_id,product_id,product_tmpl_id)', "There are Other Reference Purchase Price in same branch, please change branch"),
]
I have removed this code and upgrade module. But on data entry still gives the following error;
duplicate key value violates unique constraint "reference_price_uniq"
DETAIL: Key (branch_id,product_id,product_tmpl_id)=(2,31,27) already exists.
Please guide.
One way is to override the constraint to check nothing instead.
_sql_constraints = [('bpv_uniq', 'CHECK(1==1)', "There are Other Reference Purchase Price in same branch, please change branch"),]
Is it possible to change(edit) default ondelete message in Many2one field?
My field is:
parent_id = fields.Many2one("pgp.organizational.classifications", string="Parent classification", select=True, ondelete='restrict')
Default message is like this, but I won't to add my message:
"Odoo Server Error - Greška kod provjere
The operation cannot be completed, probably due to the following:
- deletion: you may be trying to delete a record while other records still reference it
- creation/update: a mandatory field is not correctly set
[objekt s referencom: pgp.organizational.classifications - pgp.organizational.classifications] "
You cannot change it in the Many2one field's declaration.
Code which generates this message is there: https://github.com/odoo/odoo/blob/12.0/odoo/service/model.py#L120-L154
Seems to be tricky to overload
Restricting and cascading deletes are the two most common options. RESTRICT prevents deletion of a referenced row. NO ACTION means that if any referencing rows still exist when the constraint is checked, an error is raised; this is the default behavior if you do not specify anything. (The essential difference between these two choices is that NO ACTION allows the check to be deferred until later in the transaction, whereas RESTRICT does not.) CASCADE specifies that when a referenced row is deleted, row(s) referencing it should be automatically deleted as well. There are two other options: SET NULL and SET DEFAULT. These cause the referencing columns to be set to nulls or default values, respectively, when the referenced row is deleted. Note that these do not excuse you from observing any constraints. For example, if an action specifies SET DEFAULT but the default value would not satisfy the foreign key, the operation will fail.
I solved it by overloading unlink method.
Here is the code if it helps someone:
> #api.multi
> def unlink(self):
> for field in self:
> if field.parent_id:
> raise UserError(_('It is not possible to delete a record that is already used in transactions!'))
> return super(YourClass, self).unlink()
We have some custom objects modelled through EDL which have foreign keys to system Intershop objects (ISPRODUCT and ISORDER). We need our objects to get deleted when referenced order or product is deleted.
This is the extract from the EDL file:
/**
* Relation to product PO (tariff item)
*/
dependency tariff: ProductPO
{
foreign key(tariffID);
}
/*
* Order relation
*/
dependency order: OrderPO
{
foreign key(orderID);
}
As I can see, it is possible to add delete actions on EDL relations but it is not possible to add delete actions on dependencies.
What we are doing at the moment is modifying the statements in the generated dbconstraints.oracle.ddl files like this:
EXEC staging_ddl.add_constraint('A1APPLICATIONFORM', 'A1APPLICATIONFORM_CO_003', 'FOREIGN KEY (TARIFFID) REFERENCES PRODUCT (UUID) ON DELETE SET NULL INITIALLY DEFERRED DEFERRABLE DISABLE NOVALIDATE');
EXEC staging_ddl.add_constraint('A1APPLICATIONFORM', 'A1APPLICATIONFORM_CO_004', 'FOREIGN KEY (ORDERID) REFERENCES ISORDER (UUID) ON DELETE CASCADE INITIALLY DEFERRED DEFERRABLE DISABLE NOVALIDATE');
But it is only the temporary workaround because these files will get overwritten each time we restart the code generator on the EDL.
On relationship it is possible to define the on delete action like this:
relation promotionBenefitPOs : A1PromotionBenefitPO[0..n] inverse promotionPO implements promotionBenefits delete default;
Is it possible to achieve the same thing on the dependency with the system objects?
I didn't know that was possible with EDL, good to know. My problem with this approach is that the orm cache does not know that these objects are being removed by oracle, so it might have phantom object floating around in the orm cache.
I would use this register listener solution to remove these objects so that everything is updated and flushed out of the cache.
I do wonder how the code generator deals with this delete property on the relation.
I'm afraid you need to do that by hand. Meaning once an instance of the types involved is removed, you need to query for your custom glue object and remove that one a subsequent action by your own. As dependency is merely a weak (unidirectional) relation that orm cannot automatically remove.
See here for documentation about EDL-dependency: https://support.intershop.com/kb/index.php/Display/247P28
For example, I checked ProcessPagelet-Delete pipline. In there we first unassign (i.e. remove the assignment) Label objects from the Pagelet to be deleted. The PageletLabelAssingmentPO contains a dependency to Pagelet as you can see here:
orm class PageletLabelAssignmentPO extends LabelAssignmentPO
{
attribute pageletUUID : uuid;
dependency pagelet : PageletPO
{
foreign key(pageletUUID);
}
}
I use delegation to inherit fields from sale_order in a custom module:
class EXAMPLE(osv.osv):
_name = 'EXAMPLECLASS'
_inherits = {
'sale.order': 'sale_order_id'}
I'm using the standard view for sale_order. Everything works fine, I can add and update order_lines within the sale_order. However, when I try to delete an order_line from the sale_order I get the following error:
Integrity Error
The operation cannot be completed, probably due to the following:
- deletion: you may be trying to delete a record while other records still reference it
- creation/update: a mandatory field is not correctly set
[object with reference: order_id - order.id]
What am I missing? I think it has something to do with the fact that '_inherits' only inherits fields and not methods.
Any help on this matter would be greatly appreciated.
I am learning about optional parameter regarding fields for ondelete parameter.
These are the predefined values: "cascade", "set null", "restrict", "no action", "set default"
Can anyone explain in detail about the
difference between RESTRICT and NO ACTION.
how SET DEFAULT is used in OpenERP 7?
where to set default value for the field ?
how to define set default value in python code itself?
Take for example a Course with Students. On Students is a foreign key to Course. The ondelete determines what happens with the student_id column (on Course) when the Student is deleted.
CASCADE: Delete the Course record with matching student_id when Student is deleted
RESTRICT: Cannot delete the Student as long as it is related to a Course.
NO ACTION: similar, but is a deferred check: You can delete the Student but you have to make sure that the integrity is OK when the transaction is committed.
SET DEFAULT: uses openerp default definition (see _defaults dict in the python model definition)
SET NULL: when a Student gets deleted, the student_id becomes NULL in the DB.
In Python you can find these in _columns defintion:
_columns = {
'student_id': fields.many2one(
'my.student',
'Student',
ondelete='set null',
),