Control possible concurrency moving the search of the emails to create

the activity in side the queued function, to do the search in the moment
is needed.

Add a costraint to only have one mail per activity.

Update translations.
This commit is contained in:
Bernat Brunet 2023-12-07 07:14:04 +01:00
parent c57d407c5f
commit c115b7b7b8
5 changed files with 63 additions and 32 deletions

View File

@ -1,7 +1,7 @@
# The COPYRIGHT file at the top level of this repository contains the full # The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms. # copyright notices and license terms.
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.model import fields, ModelView from trytond.model import fields, ModelView, Unique
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.wizard import Wizard, StateAction from trytond.wizard import Wizard, StateAction
from trytond.pyson import Eval, Bool from trytond.pyson import Eval, Bool
@ -46,7 +46,14 @@ class Activity(metaclass=PoolMeta):
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(Activity, cls).__setup__() super().__setup__()
t = cls.__table__()
cls._sql_constraints = [
('mail_unique', Unique(t, t.mail),
'electronic_mail_activity.msg_electronic_mail_unique'),
]
cls._buttons.update({ cls._buttons.update({
'new': { 'new': {
'icon': 'tryton-email', 'icon': 'tryton-email',
@ -305,18 +312,10 @@ class Activity(metaclass=PoolMeta):
@classmethod @classmethod
def create_activity(cls): def create_activity(cls):
pool = Pool() pool = Pool()
ActivityConfiguration = pool.get('activity.configuration')
ElectronicMail = pool.get('electronic.mail') ElectronicMail = pool.get('electronic.mail')
config = ActivityConfiguration(1)
pending_mailbox = config.pending_mailbox
mails = ElectronicMail.search([
('mailbox', '=', pending_mailbox)
], order=[('date', 'ASC'), ('id', 'ASC')])
with Transaction().set_context(queue_name=QUEUE_NAME): with Transaction().set_context(queue_name=QUEUE_NAME):
ElectronicMail.__queue__._create_activity(mails) ElectronicMail.__queue__._create_activity()
def get_previous_activity(self): def get_previous_activity(self):
ElectronicMail = Pool().get('electronic.mail') ElectronicMail = Pool().get('electronic.mail')

View File

@ -19,7 +19,7 @@ class ElectronicMail(metaclass=PoolMeta):
__name__ = 'electronic.mail' __name__ = 'electronic.mail'
@classmethod @classmethod
def _create_activity(cls, mails): def _create_activity(cls):
pool = Pool() pool = Pool()
ModelData = pool.get('ir.model.data') ModelData = pool.get('ir.model.data')
Activity = pool.get('activity.activity') Activity = pool.get('activity.activity')
@ -29,11 +29,16 @@ class ElectronicMail(metaclass=PoolMeta):
config = ActivityConfiguration(1) config = ActivityConfiguration(1)
employee = config.employee employee = config.employee
pending_mailbox = config.pending_mailbox
processed_mailbox = config.processed_mailbox processed_mailbox = config.processed_mailbox
activity_type = ActivityType(ModelData.get_id('activity', activity_type = ActivityType(ModelData.get_id('activity',
'incoming_email_type')) 'incoming_email_type'))
mails = ElectronicMail.search([
('mailbox', '=', pending_mailbox)
], order=[('date', 'ASC'), ('id', 'ASC')])
activities = [] activities = []
activity_attachments = [] activity_attachments = []
for mail in mails: for mail in mails:

View File

@ -2,6 +2,10 @@
msgid "" msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n" msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:activity.activity,filename:"
msgid "File Name"
msgstr "Nom del fitxer"
msgctxt "field:activity.activity,have_mail:" msgctxt "field:activity.activity,have_mail:"
msgid "Have mail" msgid "Have mail"
msgstr "Es un correu" msgstr "Es un correu"
@ -10,10 +14,18 @@ msgctxt "field:activity.activity,mail:"
msgid "Related Mail" msgid "Related Mail"
msgstr "Correu relacionat" msgstr "Correu relacionat"
msgctxt "field:activity.activity,mail_content:"
msgid "Mail Content"
msgstr "Contingut del correu"
msgctxt "field:activity.activity,related_activity:" msgctxt "field:activity.activity,related_activity:"
msgid "Related activity" msgid "Related activity"
msgstr "Activitat relacionada" msgstr "Activitat relacionada"
msgctxt "field:activity.configuration,employee:"
msgid "Employee"
msgstr "Empleat"
msgctxt "field:activity.configuration,pending_mailbox:" msgctxt "field:activity.configuration,pending_mailbox:"
msgid "Pending Mailbox" msgid "Pending Mailbox"
msgstr "Bústia de correu Pendents" msgstr "Bústia de correu Pendents"
@ -22,10 +34,6 @@ msgctxt "field:activity.configuration,processed_mailbox:"
msgid "Processed Mailbox" msgid "Processed Mailbox"
msgstr "Bústia de correu Processats" msgstr "Bústia de correu Processats"
msgctxt "field:imap.server,employee:"
msgid "Default Employee"
msgstr "Empleat per defecte"
msgctxt "field:res.user,add_signature:" msgctxt "field:res.user,add_signature:"
msgid "Use Signature" msgid "Use Signature"
msgstr "Utilitza la signatura" msgstr "Utilitza la signatura"
@ -55,6 +63,10 @@ msgctxt "model:ir.message,text:mail_received"
msgid "The activity (id: \"%(activity)s\") is a mail received so you ca not send." msgid "The activity (id: \"%(activity)s\") is a mail received so you ca not send."
msgstr "Aquesta activitat (id: \"%s\") es un correu rebut i no el pot enviar." msgstr "Aquesta activitat (id: \"%s\") es un correu rebut i no el pot enviar."
msgctxt "model:ir.message,text:msg_electronic_mail_unique"
msgid "A electronic mail can be linked to only one activity."
msgstr "Un correu electrònic només es pot enllaçar a una activitat."
msgctxt "model:ir.message,text:no_mailbox" msgctxt "model:ir.message,text:no_mailbox"
msgid "" msgid ""
"The user \"%(user)s\", do not have the mailbox server deffined. Without it, " "The user \"%(user)s\", do not have the mailbox server deffined. Without it, "

View File

@ -2,6 +2,10 @@
msgid "" msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n" msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:activity.activity,filename:"
msgid "File Name"
msgstr "Nombre del archivo"
msgctxt "field:activity.activity,have_mail:" msgctxt "field:activity.activity,have_mail:"
msgid "Have mail" msgid "Have mail"
msgstr "Es un correo" msgstr "Es un correo"
@ -10,10 +14,18 @@ msgctxt "field:activity.activity,mail:"
msgid "Related Mail" msgid "Related Mail"
msgstr "Correo relacionado" msgstr "Correo relacionado"
msgctxt "field:activity.activity,mail_content:"
msgid "Mail Content"
msgstr "Contenido del correo"
msgctxt "field:activity.activity,related_activity:" msgctxt "field:activity.activity,related_activity:"
msgid "Related activity" msgid "Related activity"
msgstr "Actividad relacionada" msgstr "Actividad relacionada"
msgctxt "field:activity.configuration,employee:"
msgid "Employee"
msgstr "Empleado"
msgctxt "field:activity.configuration,pending_mailbox:" msgctxt "field:activity.configuration,pending_mailbox:"
msgid "Pending Mailbox" msgid "Pending Mailbox"
msgstr "Buzón Pendientes" msgstr "Buzón Pendientes"
@ -22,10 +34,6 @@ msgctxt "field:activity.configuration,processed_mailbox:"
msgid "Processed Mailbox" msgid "Processed Mailbox"
msgstr "Buzón Procesados" msgstr "Buzón Procesados"
msgctxt "field:imap.server,employee:"
msgid "Default Employee"
msgstr "Empleado por defecto"
msgctxt "field:res.user,add_signature:" msgctxt "field:res.user,add_signature:"
msgid "Use Signature" msgid "Use Signature"
msgstr "Añade firma" msgstr "Añade firma"
@ -57,6 +65,10 @@ msgid "The activity (id: \"%(activity)s\") is a mail received so you ca not send
msgstr "" msgstr ""
"Este correo (id: \"%(activity)s\") es un correo recibido y no puede enviar." "Este correo (id: \"%(activity)s\") es un correo recibido y no puede enviar."
msgctxt "model:ir.message,text:msg_electronic_mail_unique"
msgid "A electronic mail can be linked to only one activity."
msgstr "Un correo electrónico sólo puede estar vinculado a una actividad."
msgctxt "model:ir.message,text:no_mailbox" msgctxt "model:ir.message,text:no_mailbox"
msgid "" msgid ""
"The user \"%(user)s\", do not have the mailbox server deffined. Without it, " "The user \"%(user)s\", do not have the mailbox server deffined. Without it, "

View File

@ -3,17 +3,20 @@
this repository contains the full copyright notices and license terms. --> this repository contains the full copyright notices and license terms. -->
<tryton> <tryton>
<data grouped="1"> <data grouped="1">
<record model="ir.message" id="mail_received"> <record model="ir.message" id="mail_received">
<field name="text">The activity (id: "%(activity)s") is a mail received so you ca not send.</field> <field name="text">The activity (id: "%(activity)s") is a mail received so you ca not send.</field>
</record> </record>
<record model="ir.message" id="no_smtp_server"> <record model="ir.message" id="no_smtp_server">
<field name="text">The user "%(user)s", do not have the SMTP server deffined. Without it, it is no possible to send mails.</field> <field name="text">The user "%(user)s", do not have the SMTP server deffined. Without it, it is no possible to send mails.</field>
</record> </record>
<record model="ir.message" id="no_mailbox"> <record model="ir.message" id="no_mailbox">
<field name="text">The user "%(user)s", do not have the mailbox server deffined. Without it, it is no possible to send mails.</field> <field name="text">The user "%(user)s", do not have the mailbox server deffined. Without it, it is no possible to send mails.</field>
</record> </record>
<record model="ir.message" id="no_valid_mail"> <record model="ir.message" id="no_valid_mail">
<field name="text">The "%(mail)s" of the party "%(party)s" it is not correct.</field> <field name="text">The "%(mail)s" of the party "%(party)s" it is not correct.</field>
</record> </record>
<record model="ir.message" id="msg_electronic_mail_unique">
<field name="text">A electronic mail can be linked to only one activity.</field>
</record>
</data> </data>
</tryton> </tryton>