Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions edi_oca/models/edi_exchange_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ def notify_action_complete(self, action, message=None):
Implementers can hook to this method to do something after any action ends.
"""
if message:
self._notify_related_record(message)
self._notify_related_record(message, action=action)

# Trigger generic action complete event on exchange record
event_name = f"{action}_complete"
Expand All @@ -497,8 +497,14 @@ def notify_action_complete(self, action, message=None):
# Trigger specific event on related record
self._trigger_edi_event(event_name, target=self.record)

def _notify_related_record(self, message, level="info"):
"""Post notification on the original records."""
def _notify_related_record(self, message, level="info", action=None):
"""Post notification on the original records.

When `action` is given, the related-record note is gated by the exchange
type's `notify_related_record_on_<action>` toggle; `action=None` always posts.
"""
if action and not self.type_id._notify_related_record_on(action):
return
for rec in self.related_record_ids:
rec._notify_related_record(message, level)

Expand All @@ -515,13 +521,16 @@ def _trigger_edi_event(self, name, suffix=None, target=None, **kw):
target._event(name).notify(self, **kw)

def _notify_done(self):
self._notify_related_record(self._exchange_status_message("process_ok"))
self._notify_related_record(
self._exchange_status_message("process_ok"), action="process"
)
self._trigger_edi_event("done")

def _notify_error(self, message_key):
self._notify_related_record(
self._exchange_status_message(message_key),
level="error",
action="process",
)
self._trigger_edi_event("error")

Expand Down
32 changes: 32 additions & 0 deletions edi_oca/models/edi_exchange_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,26 @@ class EDIExchangeType(models.Model):
"(default is always 'Raise Error').",
)
allow_empty_files_on_receive = fields.Boolean(string="Allow Empty Files")
notify_related_record_on_generate = fields.Boolean(
string="Notify related record on generate",
default=True,
help="Post a note on the related record when the exchange is generated.",
)
notify_related_record_on_send = fields.Boolean(
string="Notify related record on send",
default=True,
help="Post a note on the related record when the exchange is sent.",
)
notify_related_record_on_process = fields.Boolean(
string="Notify related record on process",
default=True,
help="Post a note on the related record when the exchange is processed.",
)
notify_related_record_on_receive = fields.Boolean(
string="Notify related record on receive",
default=True,
help="Post a note on the related record when the exchange is received.",
)

_sql_constraints = [
(
Expand Down Expand Up @@ -286,6 +306,18 @@ def _get_record_name(self, exchange_record):
return exchange_record.record._get_edi_exchange_record_name(exchange_record)
return slugify(exchange_record.record.display_name)

def _notify_related_record_on(self, action):
"""Whether a chatter note should be posted on the related record.

Gated per stage via the `notify_related_record_on_*` toggles. Actions without a
dedicated toggle (e.g. `ack`) keep notifying to preserve legacy behavior.
"""
self.ensure_one()
field_name = "notify_related_record_on_%s" % action
if field_name not in self._fields:
return True
return self[field_name]

def is_partner_enabled(self, partner):
"""Check if given partner record is allowed for the current type.

Expand Down
19 changes: 19 additions & 0 deletions edi_oca/tests/test_backend_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,25 @@ def test_send_not_generated_record(self):
)
mocked.assert_not_called()

def test_notify_related_record_on_generate_default(self):
before = len(self.partner.message_ids)
self.record.with_context(fake_output="yeah!").action_exchange_generate()
messages = self.partner.message_ids
self.assertEqual(len(messages) - before, 1)
self.assertIn("Exchange data generated", messages[:1].body)

def test_notify_related_record_on_generate_disabled(self):
self.record.type_id.notify_related_record_on_generate = False
before = len(self.partner.message_ids)
self.record.with_context(fake_output="yeah!").action_exchange_generate()
# Generate no longer posts a note on the related record...
self.assertEqual(len(self.partner.message_ids), before)
# ...but send still does.
self.record.action_exchange_send()
messages = self.partner.message_ids
self.assertEqual(len(messages) - before, 1)
self.assertIn("Exchange sent", messages[:1].body)


class EDIBackendTestOutputJobsCase(EDIBackendCommonComponentRegistryTestCase):
@classmethod
Expand Down
82 changes: 58 additions & 24 deletions edi_oca/views/edi_exchange_type_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,66 @@
<field name="code" />
<field name="direction" />
</group>
<group name="config">
<field name="exchange_filename_pattern" />
<field name="exchange_filename_sequence_id" />
<field name="exchange_file_ext" />
<field name="exchange_file_auto_generate" />
<field name="ack_type_id" />
<field name="ack_for_type_ids" widget="many2many_tags" />
<field name="partner_ids" widget="many2many_tags" />
<field name="job_channel_id" />
<field name="quick_exec" />
<field name="encoding" />
<field
name="encoding_out_error_handler"
invisible="direction == 'input'"
/>
<field
name="encoding_in_error_handler"
invisible="direction == 'output'"
/>
<field
name="allow_empty_files_on_receive"
invisible="direction == 'output'"
/>
</group>
Comment on lines -42 to -65

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't do this: this architecture might be inherited and customized by third-party modules, and this change might break the view's inheritance mechanism (even though I personally agree a page in the notebook yields to a better UX).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for pointing out. what I've done now is still keep the name="config" attribute on the main group in the view. I understand there's still a chance that will can break current installations. do you think we should perhaps note this to be done in the next migration?

</group>
<notebook>
<page name="config" string="Configuration">
<group name="config">
<group name="file" string="File">
<field name="exchange_filename_pattern" />
<field name="exchange_filename_sequence_id" />
<field name="exchange_file_ext" />
<field name="encoding" />
<field
name="encoding_out_error_handler"
invisible="direction == 'input'"
/>
<field
name="encoding_in_error_handler"
invisible="direction == 'output'"
/>
</group>
<group name="automation" string="Automation">
<field name="exchange_file_auto_generate" />
<field name="quick_exec" />
<field name="job_channel_id" />
<field
name="allow_empty_files_on_receive"
invisible="direction == 'output'"
/>
</group>
<group name="ack" string="Acknowledgement">
<field name="ack_type_id" />
<field
name="ack_for_type_ids"
widget="many2many_tags"
/>
</group>
<group
name="notifications"
string="Related-record notifications"
>
<field
name="notify_related_record_on_generate"
invisible="direction == 'input'"
/>
<field
name="notify_related_record_on_send"
invisible="direction == 'input'"
/>
<field
name="notify_related_record_on_process"
invisible="direction == 'output'"
/>
<field
name="notify_related_record_on_receive"
invisible="direction == 'output'"
/>
</group>
<group name="scope" string="Scope">
<field name="partner_ids" widget="many2many_tags" />
</group>
</group>
</page>
<page
name="adv_settings"
string="Advanced settings"
Expand Down
Loading