If have two entities "payment" and "bill". With each payment the user must be able to pay one or more "biils" That is done by adding a One2Many field (of type bill) in the payment model. How can I add a constrain to ensure that a payment should have at least one bill ? (ensure that the One2Many list is not empty). I have tried this code but it is not working cause the user can create one payment without having to add "bill" to the One2Many Bills attibute.
class PaymentCenter(models.Model):
_name = 'center.payment'
_description = 'Payment'
_inherit = ['mail.thread', 'mail.activity.mixin']
bill_ids = fields.One2many('center.bill',
"payment_id",
string=" Bills", required=True)
@api.constrains('bill_ids')
def _constrains_bill_ids(self):
if not self.bill_ids or len(self.bill_ids)==0:
raise ValidationError("You must add at least one bill to the payment")
class BillCenter(models.Model):
_name = 'center.bill'
_inherits = {'ir.attachment': 'attachment_id'}
payment_id = fields.Many2one('center.payment', string="Payment")
@constrains
will be triggered only if the declared fields in the
decorated method are included in the create
or write
call.
It implies that fields not present in a view will not trigger a call
during record creation.
A override of create
is necessary to make
sure a constraint will always be triggered (e.g. to test the absence of
value).
Try to override create
method and check if bill_ids
is present:
@api.model
def create(self, values):
if 'bill_ids' not in values:
values['bill_ids'] = False
return super(PaymentCenter, self).create(values)
When You add the code above the constrains should work and If you try to delete bills and save It raises a validation error (it is because of bill_ids
is present in values
argument of write method. Example of one bill deleted {'bill_ids': [[2, id, False]]}
).
You can also raise the error in the create method.
You can let users create payments without filling bill_ids
and raise a user error when they try to validate a payment without a bill.
def validate_payment(self):
for payment in self:
if not payment.bill_ids:
raise UserError(_("You must add at least one bill to the payment."))