From 6484e74975f41b5827a3e0a119c190ed8d1e507e Mon Sep 17 00:00:00 2001
From: Jose Zambudio Bernabeu <zamberjo@gmail.com>
Date: Tue, 23 Jul 2024 12:02:13 +0200
Subject: [PATCH] [IMP] Added the possibility to indicate a server action to be
 executed for the matching record.

---
 .../models/fetchmail_server_folder.py         | 24 ++++++++
 .../tests/test_match_algorithms.py            | 55 ++++++++++++++++++-
 .../views/fetchmail_server.xml                |  2 +
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/fetchmail_attach_from_folder/models/fetchmail_server_folder.py b/fetchmail_attach_from_folder/models/fetchmail_server_folder.py
index 6f6e64d04..3e351fb36 100644
--- a/fetchmail_attach_from_folder/models/fetchmail_server_folder.py
+++ b/fetchmail_attach_from_folder/models/fetchmail_server_folder.py
@@ -91,6 +91,12 @@ class FetchmailServerFolder(models.Model):
         help="The state messages fetched from this folder should be assigned in Odoo",
     )
     active = fields.Boolean(default=True)
+    action_id = fields.Many2one(
+        comodel_name="ir.actions.server",
+        name="Server action",
+        help="Optional custom server action to trigger for each incoming "
+        "mail, on the record that was created or updated by this mail",
+    )
 
     def button_confirm_folder(self):
         self.write({"state": "draft"})
@@ -227,11 +233,29 @@ class FetchmailServerFolder(models.Model):
                     thread_id = match.id
                     self.attach_mail(match, message_dict)
         matched = True if thread_id else False
+        if matched:
+            self.run_server_action(thread_id)
         self.update_msg(connection, msgid, matched=matched)
         if self.archive_path:
             self._archive_msg(connection, msgid)
         return thread_id  # Can be None if no match found.
 
+    def run_server_action(self, matched_object_ids):
+        action = self.action_id
+        if not action:
+            return
+        records = self.env[self.model_id.model].browse(matched_object_ids)
+        for record in records:
+            if not record.exists():
+                continue
+            action.with_context(
+                **{
+                    "active_id": record.id,
+                    "active_ids": record.ids,
+                    "active_model": self.model_id.model,
+                }
+            ).run()
+
     def fetch_msg(self, connection, msgid):
         """Select a single message from a folder."""
         self.ensure_one()
diff --git a/fetchmail_attach_from_folder/tests/test_match_algorithms.py b/fetchmail_attach_from_folder/tests/test_match_algorithms.py
index 04018f42b..bdd406c37 100644
--- a/fetchmail_attach_from_folder/tests/test_match_algorithms.py
+++ b/fetchmail_attach_from_folder/tests/test_match_algorithms.py
@@ -56,7 +56,14 @@ class TestMatchAlgorithms(TransactionCase):
 
         cls.partner_model = cls.env["res.partner"]
         cls.test_partner = cls.partner_model.with_context(tracking_disable=True).create(
-            {"name": "Reynaert de Vos", "email": TEST_EMAIL, "is_company": False}
+            {
+                "name": "Reynaert de Vos",
+                "email": TEST_EMAIL,
+                "is_company": False,
+                "category_id": [
+                    (6, 0, []),
+                ],
+            }
         )
         cls.server_model = cls.env["fetchmail.server"]
         cls.folder_model = cls.env["fetchmail.server.folder"]
@@ -81,6 +88,40 @@ class TestMatchAlgorithms(TransactionCase):
                 "mail_field": "from",
             }
         )
+        cls.partner_ir_model = cls.env["ir.model"].search(
+            [
+                ("model", "=", cls.partner_model._name),
+            ],
+            limit=1,
+        )
+        cls.partner_category = cls.env.ref("base.res_partner_category_12")
+        cls.server_action = cls.env["ir.actions.server"].create(
+            {
+                "name": "Action Set Active Partner",
+                "model_id": cls.partner_ir_model.id,
+                "state": "object_write",
+                "code": False,
+                "fields_lines": [
+                    (
+                        0,
+                        0,
+                        {
+                            "col1": cls.env["ir.model.fields"]
+                            .search(
+                                [
+                                    ("name", "=", "category_id"),
+                                    ("model_id", "=", cls.partner_ir_model.id),
+                                ],
+                                limit=1,
+                            )
+                            .id,
+                            "evaluation_type": "equation",
+                            "value": str([cls.partner_category.id]),
+                        },
+                    ),
+                ],
+            }
+        )
 
     def test_email_exact(self):
         """A message to ronald@acme.com should be linked to partner with that email."""
@@ -122,3 +163,15 @@ class TestMatchAlgorithms(TransactionCase):
         folder.match_algorithm = "email_domain"
         connection = MockConnection()
         folder.retrieve_imap_folder(connection)
+
+    def test_non_action(self):
+        connection = MockConnection()
+        self.folder.action_id = False
+        self.folder.apply_matching(connection, "1")
+        self.assertFalse(self.test_partner.category_id)
+
+    def test_action(self):
+        connection = MockConnection()
+        self.folder.action_id = self.server_action
+        self.folder.apply_matching(connection, "1")
+        self.assertEqual(self.partner_category, self.test_partner.category_id)
diff --git a/fetchmail_attach_from_folder/views/fetchmail_server.xml b/fetchmail_attach_from_folder/views/fetchmail_server.xml
index 9cf93de4b..459a15f10 100644
--- a/fetchmail_attach_from_folder/views/fetchmail_server.xml
+++ b/fetchmail_attach_from_folder/views/fetchmail_server.xml
@@ -26,6 +26,7 @@
                             <field name="path" />
                             <field name="archive_path" />
                             <field name="model_id" />
+                            <field name="action_id" />
                             <field name="match_algorithm" />
                             <field name="model_field" />
                             <field name="mail_field" />
@@ -63,6 +64,7 @@
                                 <group>
                                     <field name="path" placeholder="INBOX.subfolder1" />
                                     <field name="model_id" />
+                                    <field name="action_id" />
                                     <field name="match_algorithm" />
                                 </group>
                                 <group