diff --git a/addons/mail/static/src/model/model_manager.js b/addons/mail/static/src/model/model_manager.js index 3c44839ede6..24594acae96 100644 --- a/addons/mail/static/src/model/model_manager.js +++ b/addons/mail/static/src/model/model_manager.js @@ -638,6 +638,9 @@ export class ModelManager { ) { throw new Error(`Mismatched relation types: ${field} on ${Model} (${field.relationType}) and ${inverseField} on ${RelatedModel} (${inverseField.relationType}).`); } + if (field.required && !inverseField.isCausal) { + throw new Error(`${field} on ${Model} is required but its inverse ${inverseField} on ${RelatedModel} is not causal.`); + } } for (const identifyingField of Model.__identifyingFieldsFlattened) { const field = Model.__fieldMap[identifyingField]; @@ -1070,7 +1073,10 @@ export class ModelManager { relFunc(Model.name, { inverse: field.fieldName }), { fieldName: `_inverse_${Model}/${field.fieldName}`, - } + // Note that an identifying field is not necessarily defined as + // `required` (example: identifyingFields with an OR). + isCausal: field.required || Model.__identifyingFieldsFlattened.has(field.fieldName), + }, )); return inverseField; } diff --git a/addons/mail/static/src/models/attachment/attachment.js b/addons/mail/static/src/models/attachment/attachment.js index 2c94f255300..16efacb45c9 100644 --- a/addons/mail/static/src/models/attachment/attachment.js +++ b/addons/mail/static/src/models/attachment/attachment.js @@ -279,29 +279,12 @@ registerModel({ activities: many2many('Activity', { inverse: 'attachments', }), - /** - * States the attachment cards that are displaying this attachment. - */ - attachmentCards: one2many('AttachmentCard', { - inverse: 'attachment', - isCausal: true, - }), - /** - * States the attachment images that are displaying this attachment. - */ - attachmentImages: one2many('AttachmentImage', { - inverse: 'attachment', - isCausal: true, - }), /** * States the attachment lists that are displaying this attachment. */ attachmentLists: many2many('AttachmentList', { inverse: 'attachments', }), - attachmentViewers: many2many('AttachmentViewer', { - inverse: 'attachments', - }), checksum: attr(), /** * States on which composer this attachment is currently being created. diff --git a/addons/mail/static/src/models/attachment_card/attachment_card.js b/addons/mail/static/src/models/attachment_card/attachment_card.js index c71c39f9d84..770e723263e 100644 --- a/addons/mail/static/src/models/attachment_card/attachment_card.js +++ b/addons/mail/static/src/models/attachment_card/attachment_card.js @@ -66,7 +66,6 @@ registerModel({ * Determines the attachment of this card. */ attachment: many2one('Attachment', { - inverse: 'attachmentCards', readonly: true, required: true, }), diff --git a/addons/mail/static/src/models/attachment_image/attachment_image.js b/addons/mail/static/src/models/attachment_image/attachment_image.js index 8a4c58d3353..9c4c9d57035 100644 --- a/addons/mail/static/src/models/attachment_image/attachment_image.js +++ b/addons/mail/static/src/models/attachment_image/attachment_image.js @@ -108,7 +108,6 @@ registerModel({ * Determines the attachment of this attachment image.. */ attachment: many2one('Attachment', { - inverse: 'attachmentImages', readonly: true, required: true, }), diff --git a/addons/mail/static/src/models/attachment_list/attachment_list.js b/addons/mail/static/src/models/attachment_list/attachment_list.js index 81025830caa..a18b1bb9ce2 100644 --- a/addons/mail/static/src/models/attachment_list/attachment_list.js +++ b/addons/mail/static/src/models/attachment_list/attachment_list.js @@ -80,13 +80,6 @@ registerModel({ inverse: 'attachmentList', isCausal: true, }), - /** - * Determines the attachment viewers displaying this attachment list (if any). - */ - attachmentViewers: one2many('AttachmentViewer', { - inverse: 'attachmentList', - isCausal: true, - }), /** * Link with a chatter to handle attachments. */ diff --git a/addons/mail/static/src/models/attachment_viewer/attachment_viewer.js b/addons/mail/static/src/models/attachment_viewer/attachment_viewer.js index 58a05bc9170..6e485d3b408 100644 --- a/addons/mail/static/src/models/attachment_viewer/attachment_viewer.js +++ b/addons/mail/static/src/models/attachment_viewer/attachment_viewer.js @@ -40,12 +40,10 @@ registerModel({ }), attachment: many2one('Attachment'), attachmentList: many2one('AttachmentList', { - inverse: 'attachmentViewers', readonly: true, required: true, }), attachments: many2many('Attachment', { - inverse: 'attachmentViewers', related: 'attachmentList.viewableAttachments', }), /** diff --git a/addons/mail/static/src/models/channel_invitation_form/channel_invitation_form.js b/addons/mail/static/src/models/channel_invitation_form/channel_invitation_form.js index 6ada1d1b0b7..7bf92edaf0c 100644 --- a/addons/mail/static/src/models/channel_invitation_form/channel_invitation_form.js +++ b/addons/mail/static/src/models/channel_invitation_form/channel_invitation_form.js @@ -210,10 +210,6 @@ registerModel({ inviteButtonText: attr({ compute: '_computeInviteButtonText', }), - popoverView: one2one('PopoverView', { - inverse: 'channelInvitationForm', - isCausal: true, - }), /** * States the OWL ref of the "search" input of this channel invitation * form. Useful to be able to focus it. diff --git a/addons/mail/static/src/models/composer/composer.js b/addons/mail/static/src/models/composer/composer.js index cdfadd21013..2641e8cc710 100644 --- a/addons/mail/static/src/models/composer/composer.js +++ b/addons/mail/static/src/models/composer/composer.js @@ -135,10 +135,6 @@ registerModel({ compute: '_computeCanPostMessage', default: false, }), - composerViews: one2many('ComposerView', { - inverse: 'composer', - isCausal: true, - }), /** * This field determines whether some attachments linked to this * composer are being uploaded. diff --git a/addons/mail/static/src/models/composer_view/composer_view.js b/addons/mail/static/src/models/composer_view/composer_view.js index 1c1f4a88c07..6415b376b6c 100644 --- a/addons/mail/static/src/models/composer_view/composer_view.js +++ b/addons/mail/static/src/models/composer_view/composer_view.js @@ -871,7 +871,6 @@ registerModel({ */ composer: many2one('Composer', { compute: '_computeComposer', - inverse: 'composerViews', required: true, }), /** diff --git a/addons/mail/static/src/models/message/message.js b/addons/mail/static/src/models/message/message.js index b02cb739c20..8019b901fcf 100644 --- a/addons/mail/static/src/models/message/message.js +++ b/addons/mail/static/src/models/message/message.js @@ -701,10 +701,6 @@ registerModel({ isCausal: true, }), message_type: attr(), - messageSeenIndicators: one2many('MessageSeenIndicator', { - inverse: 'message', - isCausal: true, - }), /** * States the views that are displaying this message. */ diff --git a/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js b/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js index 223cb57d52a..1bdd55c680d 100644 --- a/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js +++ b/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js @@ -226,7 +226,6 @@ registerModel({ * The message concerned by this seen indicator. */ message: many2one('Message', { - inverse: 'messageSeenIndicators', readonly: true, required: true, }), diff --git a/addons/mail/static/src/models/partner/partner.js b/addons/mail/static/src/models/partner/partner.js index 539a50cd502..3f506898fca 100644 --- a/addons/mail/static/src/models/partner/partner.js +++ b/addons/mail/static/src/models/partner/partner.js @@ -446,10 +446,6 @@ registerModel({ nameOrDisplayName: attr({ compute: '_computeNameOrDisplayName', }), - partnerSeenInfos: one2many('ThreadPartnerSeenInfo', { - inverse: 'partner', - isCausal: true, - }), rtcSessions: one2many('RtcSession', { inverse: 'partner', }), diff --git a/addons/mail/static/src/models/popover_view/popover_view.js b/addons/mail/static/src/models/popover_view/popover_view.js index 2aba54e19ae..e7ee9028698 100644 --- a/addons/mail/static/src/models/popover_view/popover_view.js +++ b/addons/mail/static/src/models/popover_view/popover_view.js @@ -68,7 +68,6 @@ registerModel({ * The record that represents the content inside the popover view. */ channelInvitationForm: one2one('ChannelInvitationForm', { - inverse: 'popoverView', isCausal: true, readonly: true, required: true, diff --git a/addons/mail/static/src/models/rtc_call_viewer/rtc_call_viewer.js b/addons/mail/static/src/models/rtc_call_viewer/rtc_call_viewer.js index e21604dd61a..5068a35362f 100644 --- a/addons/mail/static/src/models/rtc_call_viewer/rtc_call_viewer.js +++ b/addons/mail/static/src/models/rtc_call_viewer/rtc_call_viewer.js @@ -366,7 +366,6 @@ registerModel({ rtcController: one2one('RtcController', { default: insertAndReplace(), readonly: true, - required: true, inverse: 'callViewer', isCausal: true, }), diff --git a/addons/mail/static/src/models/rtc_configuration_menu/rtc_configuration_menu.js b/addons/mail/static/src/models/rtc_configuration_menu/rtc_configuration_menu.js index 5c54c59d82f..49003931721 100644 --- a/addons/mail/static/src/models/rtc_configuration_menu/rtc_configuration_menu.js +++ b/addons/mail/static/src/models/rtc_configuration_menu/rtc_configuration_menu.js @@ -87,7 +87,6 @@ registerModel({ userSetting: one2one('UserSetting', { inverse: 'rtcConfigurationMenu', readonly: true, - required: true, }), }, }); diff --git a/addons/mail/static/src/models/rtc_controller/rtc_controller.js b/addons/mail/static/src/models/rtc_controller/rtc_controller.js index ece522ec7c8..5a9c7dbaa0e 100644 --- a/addons/mail/static/src/models/rtc_controller/rtc_controller.js +++ b/addons/mail/static/src/models/rtc_controller/rtc_controller.js @@ -92,7 +92,6 @@ registerModel({ default: insertAndReplace(), inverse: 'rtcController', isCausal: true, - required: true, }), }, }); diff --git a/addons/mail/static/src/models/thread_cache/thread_cache.js b/addons/mail/static/src/models/thread_cache/thread_cache.js index 8f0b782a78e..917dc19aaca 100644 --- a/addons/mail/static/src/models/thread_cache/thread_cache.js +++ b/addons/mail/static/src/models/thread_cache/thread_cache.js @@ -403,6 +403,7 @@ registerModel({ }), thread: one2one('Thread', { inverse: 'cache', + isCausal: true, readonly: true, required: true, }), diff --git a/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js b/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js index 2a17da48d0f..aa9e8161e9e 100644 --- a/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js +++ b/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js @@ -13,7 +13,6 @@ registerModel({ * Partner that this seen info is related to. */ partner: many2one('Partner', { - inverse: 'partnerSeenInfos', readonly: true, required: true, }), diff --git a/addons/mail/static/src/models/thread_view/thread_viewer.js b/addons/mail/static/src/models/thread_view/thread_viewer.js index 83303619b52..035a7d37537 100644 --- a/addons/mail/static/src/models/thread_view/thread_viewer.js +++ b/addons/mail/static/src/models/thread_view/thread_viewer.js @@ -61,10 +61,12 @@ registerModel({ fields: { chatter: one2one('Chatter', { inverse: 'threadViewer', + isCausal: true, readonly: true, }), chatWindow: one2one('ChatWindow', { inverse: 'threadViewer', + isCausal: true, readonly: true, }), /** @@ -75,6 +77,7 @@ registerModel({ }), discuss: one2one('Discuss', { inverse: 'threadViewer', + isCausal: true, readonly: true, }), discussPublicView: one2one('DiscussPublicView', { diff --git a/addons/mail/static/src/models/user_setting/user_setting.js b/addons/mail/static/src/models/user_setting/user_setting.js index 02deeabf938..a857945e3aa 100644 --- a/addons/mail/static/src/models/user_setting/user_setting.js +++ b/addons/mail/static/src/models/user_setting/user_setting.js @@ -255,7 +255,6 @@ registerModel({ default: insertAndReplace(), inverse: 'userSetting', isCausal: true, - required: true, }), /** * layout of the rtc session display chosen by the user @@ -282,12 +281,5 @@ registerModel({ voiceActiveDuration: attr({ default: 0, }), - /** - * Models that represent the volume chosen by the user for each partner. - */ - volumeSettings: one2many('VolumeSetting', { - inverse: 'userSetting', - isCausal: true, - }), }, }); diff --git a/addons/mail/static/src/models/volume_setting/volume_setting.js b/addons/mail/static/src/models/volume_setting/volume_setting.js index fef540b79b8..fd4512042cc 100644 --- a/addons/mail/static/src/models/volume_setting/volume_setting.js +++ b/addons/mail/static/src/models/volume_setting/volume_setting.js @@ -39,7 +39,6 @@ registerModel({ inverse: 'volumeSetting', }), userSetting: many2one('UserSetting', { - inverse: 'volumeSettings', required: true, }), volume: attr({