Compare commits

...

2 Commits

Author SHA1 Message Date
Adrián Bernardi 29d020aa96 lims: open notebook lines: do not show party name 2023-11-16 19:06:40 -03:00
Adrián Bernardi 7a52f2a87d lims, lims_email, lims_account_invoice, lims_administrative_task, lims_sale: Add SMTP Server 2023-11-16 11:04:39 -03:00
22 changed files with 522 additions and 55 deletions

View File

@ -40,6 +40,7 @@ def register():
configuration.LabWorkYearHoliday,
configuration.Cron,
configuration.Sequence,
configuration.SmtpServer,
laboratory.LaboratoryProfessional,
laboratory.Laboratory,
laboratory.LabMethod,

View File

@ -5,8 +5,11 @@
from datetime import datetime
from dateutil import rrule
from sql import Null
import logging
import smtplib
from trytond.model import ModelSingleton, ModelView, ModelSQL, fields, Index
from trytond.model import ModelSingleton, ModelView, ModelSQL, Workflow, \
fields, Index
from trytond.pyson import Eval, Id
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
@ -15,6 +18,8 @@ from trytond.modules.company.model import (
from trytond.exceptions import UserError
from trytond.i18n import gettext
logger = logging.getLogger(__name__)
sequence_names = [
'entry_sequence', 'sample_sequence', 'service_sequence',
'results_report_sequence']
@ -201,6 +206,9 @@ class Configuration(ModelSingleton, ModelSQL, ModelView,
mail_ack_body = fields.Text('Email body of Acknowledgment of Samples'
' Receipt')
mail_ack_hide_recipients = fields.Boolean('Hide recipients')
mail_ack_smtp = fields.Many2One('lims.smtp.server', 'SMTP for '
'Acknowledgment of Samples Receipt',
domain=[('state', '=', 'done')])
microbiology_laboratories = fields.Many2Many(
'lims.configuration-laboratory', 'configuration',
'laboratory', 'Microbiology Laboratories')
@ -280,6 +288,9 @@ class Configuration(ModelSingleton, ModelSQL, ModelView,
mail_referral_subject = fields.Char('Email subject of Referral of Samples',
help="A suffix with the referral number will be added to the text")
mail_referral_body = fields.Text('Email body of Referral of Samples')
mail_referral_smtp = fields.Many2One('lims.smtp.server', 'SMTP for '
'Referral of Samples',
domain=[('state', '=', 'done')])
sample_fast_copy = fields.Boolean('Fast Sample Creation (Experimental)')
@staticmethod
@ -692,3 +703,134 @@ class Sequence(metaclass=PoolMeta):
date = Date.today()
res['year2'] = date.strftime('%y')
return res
class SmtpServer(Workflow, ModelSQL, ModelView):
'SMTP Server'
__name__ = 'lims.smtp.server'
_states = {'readonly': (Eval('state') != 'draft')}
name = fields.Char('Name', required=True)
smtp_server = fields.Char('Server', required=True, states=_states)
smtp_port = fields.Integer('Port', required=True, states=_states)
smtp_timeout = fields.Integer('Timeout', required=True, states=_states,
help='Time in seconds')
smtp_ssl = fields.Boolean('SSL', states=_states)
smtp_tls = fields.Boolean('TLS', states=_states)
smtp_user = fields.Char('User', states=_states)
smtp_password = fields.Char('Password', strip=False, states=_states)
smtp_email = fields.Char('Email', required=True, states=_states,
help='Default From and Reply Email')
state = fields.Selection([
('draft', 'Draft'),
('done', 'Done'),
], 'State', readonly=True, required=True)
del _states
@classmethod
def __setup__(cls):
super().__setup__()
cls._transitions |= set((
('draft', 'done'),
('done', 'draft'),
))
cls._buttons.update({
'test_smtp_server': {},
'draft': {
'invisible': Eval('state') == 'draft',
'depends': ['state'],
},
'done': {
'invisible': Eval('state') == 'done',
'depends': ['state'],
},
})
@staticmethod
def default_smtp_timeout():
return 60
@staticmethod
def default_smtp_ssl():
return True
@staticmethod
def default_smtp_port():
return 465
@staticmethod
def default_state():
return 'draft'
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, servers):
pass
@classmethod
@ModelView.button
@Workflow.transition('done')
def done(cls, servers):
pass
@classmethod
@ModelView.button
def test_smtp_server(cls, servers):
for server in servers:
try:
server.get_smtp_server()
except Exception as message:
logger.error('Exception getting SMTP Server: %s', message)
raise UserError(gettext('lims.smtp_test_failed',
error=message))
raise UserError(gettext('lims.smtp_test_successful'))
def get_smtp_server(self):
"""
Instanciate, configure and return a SMTP or SMTP_SSL instance from
smtplib.
:return: A SMTP instance. The quit() method must be call when all
the calls to sendmail() have been made.
"""
if self.smtp_ssl:
smtp_server = smtplib.SMTP_SSL(self.smtp_server, self.smtp_port,
timeout=self.smtp_timeout)
else:
smtp_server = smtplib.SMTP(self.smtp_server, self.smtp_port,
timeout=self.smtp_timeout)
if self.smtp_tls:
smtp_server.starttls()
if self.smtp_user and self.smtp_password:
smtp_server.login(self.smtp_user, self.smtp_password)
return smtp_server
def send_mail(self, from_addr, to_addrs, msg):
success = False
server = None
try:
smtp_server = self.get_smtp_server()
smtp_server.sendmail(from_addr, to_addrs, msg)
smtp_server.quit()
success = True
except smtplib.SMTPException as error:
logger.error('SMTPException: %s', error)
if server is not None:
server.quit()
raise UserError(gettext('lims.smtp_exception', error=error))
except smtplib.socket.error as error:
logger.error('socket.error: %s', error)
if server is not None:
server.quit()
raise UserError(gettext('lims.smtp_server_error', error=error))
except smtplib.SMTPRecipientsRefused as error:
logger.error('socket.error: %s', error)
if server is not None:
server.quit()
raise UserError(gettext('lims.smtp_server_error', error=error))
return success

View File

@ -219,5 +219,68 @@
<field name="name">sequence_form</field>
</record>
<!-- SMTP Servers -->
<record model="ir.ui.view" id="smtp_server_view_form">
<field name="model">lims.smtp.server</field>
<field name="type">form</field>
<field name="name">smtp_server_form</field>
</record>
<record model="ir.ui.view" id="smtp_server_view_list">
<field name="model">lims.smtp.server</field>
<field name="type">tree</field>
<field name="name">smtp_server_list</field>
</record>
<record model="ir.action.act_window" id="act_smtp_server">
<field name="name">SMTP Servers</field>
<field name="res_model">lims.smtp.server</field>
</record>
<record model="ir.action.act_window.view" id="act_smtp_server_view_list">
<field name="sequence" eval="10"/>
<field name="view" ref="smtp_server_view_list"/>
<field name="act_window" ref="act_smtp_server"/>
</record>
<record model="ir.action.act_window.view" id="act_smtp_server_view_form">
<field name="sequence" eval="20"/>
<field name="view" ref="smtp_server_view_form"/>
<field name="act_window" ref="act_smtp_server"/>
</record>
<menuitem action="act_smtp_server" id="act_smtp_server_menu"
parent="lims_config_base" sequence="40"/>
<record model="ir.model.button" id="smtp_server_test_smtp_server_button">
<field name="name">test_smtp_server</field>
<field name="string">Test Connection</field>
<field name="model" search="[('model', '=', 'lims.smtp.server')]"/>
</record>
<record model="ir.model.button" id="smtp_server_draft_button">
<field name="name">draft</field>
<field name="string">Draft</field>
<field name="model" search="[('model', '=', 'lims.smtp.server')]"/>
</record>
<record model="ir.model.button" id="smtp_server_done_button">
<field name="name">done</field>
<field name="string">Confirm</field>
<field name="model" search="[('model', '=', 'lims.smtp.server')]"/>
</record>
<record model="ir.model.access" id="access_smtp_server">
<field name="model" search="[('model', '=', 'lims.smtp.server')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_smtp_server_group_smtp_server">
<field name="model" search="[('model', '=', 'lims.smtp.server')]"/>
<field name="group" ref="group_lims_smtp_server"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
</data>
</tryton>

View File

@ -662,19 +662,21 @@ class Entry(Workflow, ModelSQL, ModelView):
if not self.ack_report_cache:
return
from_addr = tconfig.get('email', 'from')
config_ = Config(1)
smtp_server = config_.mail_ack_smtp
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
to_addrs = [c.contact.email for c in self.acknowledgment_contacts]
if not (from_addr and to_addrs):
return
config = Config(1)
hide_recipients = config.mail_ack_hide_recipients
hide_recipients = config_.mail_ack_hide_recipients
subject, body = self.subject_body()
attachment_data = self.attachment()
msg = self.create_msg(from_addr, to_addrs, subject,
body, hide_recipients, attachment_data)
return self.send_msg(from_addr, to_addrs, msg)
return self.send_msg(smtp_server, from_addr, to_addrs, msg)
def subject_body(self):
pool = Pool()
@ -734,17 +736,20 @@ class Entry(Workflow, ModelSQL, ModelView):
msg.attach(attachment)
return msg
def send_msg(self, from_addr, to_addrs, msg):
def send_msg(self, smtp_server, from_addr, to_addrs, msg):
to_addrs = list(set(to_addrs))
success = False
server = None
try:
server = get_smtp_server()
if smtp_server:
server = smtp_server.get_smtp_server()
else:
server = get_smtp_server()
server.sendmail(from_addr, to_addrs, msg.as_string())
server.quit()
success = True
except Exception as e:
logger.error('Unable to deliver mail for entry %s' % (self.number))
logger.error('Unable to deliver mail for entry %s' % self.number)
logger.error(str(e))
if server is not None:
server.quit()

View File

@ -447,6 +447,10 @@ msgctxt "field:lims.configuration,mail_ack_hide_recipients:"
msgid "Hide recipients"
msgstr "Ocultar destinatarios"
msgctxt "field:lims.configuration,mail_ack_smtp:"
msgid "SMTP for Acknowledgment of Samples Receipt"
msgstr "SMTP para Acuse de recibo de muestras"
msgctxt "field:lims.configuration,mail_ack_subject:"
msgid "Email subject of Acknowledgment of Samples Receipt"
msgstr "Asunto del correo de Acuse de recibo de muestras"
@ -455,6 +459,10 @@ msgctxt "field:lims.configuration,mail_referral_body:"
msgid "Email body of Referral of Samples"
msgstr "Cuerpo del correo de Derivación de muestras"
msgctxt "field:lims.configuration,mail_referral_smtp:"
msgid "SMTP for Referral of Samples"
msgstr "SMTP para Derivación de muestras"
msgctxt "field:lims.configuration,mail_referral_subject:"
msgid "Email subject of Referral of Samples"
msgstr "Asunto del correo de Derivación de muestras"
@ -6315,6 +6323,46 @@ msgctxt "field:lims.service.additional_origin,service:"
msgid "Service"
msgstr "Servicio"
msgctxt "field:lims.smtp.server,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:lims.smtp.server,smtp_email:"
msgid "Email"
msgstr "Correo electrónico"
msgctxt "field:lims.smtp.server,smtp_password:"
msgid "Password"
msgstr "Contraseña"
msgctxt "field:lims.smtp.server,smtp_port:"
msgid "Port"
msgstr "Puerto"
msgctxt "field:lims.smtp.server,smtp_server:"
msgid "Server"
msgstr "Servidor"
msgctxt "field:lims.smtp.server,smtp_ssl:"
msgid "SSL"
msgstr "SSL"
msgctxt "field:lims.smtp.server,smtp_timeout:"
msgid "Timeout"
msgstr "Timeout"
msgctxt "field:lims.smtp.server,smtp_tls:"
msgid "TLS"
msgstr "TLS"
msgctxt "field:lims.smtp.server,smtp_user:"
msgid "User"
msgstr "Usuario"
msgctxt "field:lims.smtp.server,state:"
msgid "State"
msgstr "Estado"
msgctxt "field:lims.technical.scope,certification_type:"
msgid "Certification type"
msgstr "Tipo de certificación"
@ -7273,6 +7321,14 @@ msgstr ""
"Para las condiciones \"En\" y \"No en\", utilice una lista de valores "
"separados por comas (Ej.: AB, CD, 12, 34)"
msgctxt "help:lims.smtp.server,smtp_email:"
msgid "Default From and Reply Email"
msgstr "Correo electrónico predeterminado para remitente y respuesta"
msgctxt "help:lims.smtp.server,smtp_timeout:"
msgid "Time in seconds"
msgstr "Tiempo en segundos"
msgctxt "help:lims.trend.chart,active:"
msgid "Check to include in future use"
msgstr "Marcar para usar en el futuro."
@ -7641,6 +7697,10 @@ msgctxt "model:ir.action,name:act_service_referred_pending_result_list"
msgid "Referred Services Pending Result"
msgstr "Servicios derivados pendientes de resultado"
msgctxt "model:ir.action,name:act_smtp_server"
msgid "SMTP Servers"
msgstr "Servidores SMTP"
msgctxt "model:ir.action,name:act_trend_chart_data"
msgid "Trend Chart"
msgstr "Gráfico de tendencia"
@ -9169,6 +9229,30 @@ msgctxt "model:ir.message,text:msg_zone_code_unique_id"
msgid "Zone code must be unique"
msgstr "El código de la zona debe ser único"
msgctxt "model:ir.message,text:smtp_exception"
msgid ""
"SMTP Server exception (Email not sent):\n"
"%(error)s"
msgstr ""
"Excepción de Servidor SMTP (Correo no enviado):\n"
"%(error)s"
msgctxt "model:ir.message,text:smtp_server_error"
msgid "Error: could not connect to server. (Email not sent)"
msgstr "Error: no se pudo conectar al servidor. (Correo no enviado)"
msgctxt "model:ir.message,text:smtp_test_failed"
msgid ""
"SMTP test connection failed:\n"
"%(error)s"
msgstr ""
"La conexión SMTP de prueba falló:\n"
"%(error)s"
msgctxt "model:ir.message,text:smtp_test_successful"
msgid "SMTP test connection was successful"
msgstr "La conexión SMTP de prueba fue exitosa"
msgctxt "model:ir.model.button,confirm:entry_confirm_button"
msgid "Are you sure you want to confirm the entry?"
msgstr "¿Está seguro que desea confirmar el ingreso?"
@ -9185,6 +9269,18 @@ msgctxt "model:ir.model.button,string:means_deviations_calc_select_all_button"
msgid "Select All"
msgstr "Seleccionar todo"
msgctxt "model:ir.model.button,string:smtp_server_done_button"
msgid "Confirm"
msgstr "Confirmar"
msgctxt "model:ir.model.button,string:smtp_server_draft_button"
msgid "Draft"
msgstr "Borrador"
msgctxt "model:ir.model.button,string:smtp_server_test_smtp_server_button"
msgid "Test Connection"
msgstr "Probar conexión"
msgctxt "model:ir.rule.group,name:rule_group_analysis_device"
msgid "User in laboratory"
msgstr ""
@ -9273,6 +9369,10 @@ msgctxt "model:ir.ui.menu,name:"
msgid "Laboratory Notebook"
msgstr "Cuaderno de laboratorio"
msgctxt "model:ir.ui.menu,name:act_smtp_server_menu"
msgid "SMTP Servers"
msgstr "Servidores SMTP"
msgctxt "model:ir.ui.menu,name:company_department_menu"
msgid "Departments"
msgstr "Departamentos"
@ -10662,6 +10762,10 @@ msgctxt "model:lims.service.additional_origin,name:"
msgid "Service Origin"
msgstr "Origen de Servicio adicional"
msgctxt "model:lims.smtp.server,name:"
msgid "SMTP Server"
msgstr "Servidor SMTP"
msgctxt "model:lims.technical.scope,name:"
msgid "Technical Scope"
msgstr "Alcance técnico"
@ -10898,6 +11002,10 @@ msgctxt "model:res.group,name:group_lims_planification_readonly"
msgid "Lims Planification Read Only"
msgstr "Lims Planificación Sólo lectura"
msgctxt "model:res.group,name:group_lims_smtp_server"
msgid "Lims SMTP Server"
msgstr "Lims Servidor SMTP"
msgctxt "model:res.group,name:group_lims_trend_chart"
msgid "Lims Trend Charts"
msgstr "Lims Gráficos de tendencia"
@ -13945,6 +14053,14 @@ msgctxt "selection:lims.service,analysis_type:"
msgid "Set"
msgstr "Set"
msgctxt "selection:lims.smtp.server,state:"
msgid "Done"
msgstr "Confirmado"
msgctxt "selection:lims.smtp.server,state:"
msgid "Draft"
msgstr "Borrador"
msgctxt "selection:lims.trend.chart,filter:"
msgid "Any Sample"
msgstr "Cualquier muestra"
@ -15312,6 +15428,10 @@ msgctxt "view:lims.service:"
msgid "Time"
msgstr "Hora"
msgctxt "view:lims.smtp.server:"
msgid "Server"
msgstr "Servidor"
msgctxt "view:lims.technical.scope.version.line:"
msgid "Technical Scope Version Line"
msgstr "Línea de versión de alcance técnico"

View File

@ -589,5 +589,19 @@ Rule 4: 1 value above or below the mean +/- 3 deviations.</field>
<record model="ir.message" id="msg_invalid_email">
<field name="text">Invalid email address</field>
</record>
<record model="ir.message" id="smtp_test_successful">
<field name="text">SMTP test connection was successful</field>
</record>
<record model="ir.message" id="smtp_test_failed">
<field name="text">SMTP test connection failed:
%(error)s</field>
</record>
<record model="ir.message" id="smtp_exception">
<field name="text">SMTP Server exception (Email not sent):
%(error)s</field>
</record>
<record model="ir.message" id="smtp_server_error">
<field name="text">Error: could not connect to server. (Email not sent)</field>
</record>
</data>
</tryton>

View File

@ -6328,7 +6328,7 @@ class OpenNotebookLines(Wizard):
action['name'] = \
'%s - %s - %s - %s - %s' % (notebook.fraction.number,
notebook.party.name, notebook.product_type.description,
notebook.party.code, notebook.product_type.description,
notebook.matrix.description, notebook.label)
return action, {}

View File

@ -7732,9 +7732,12 @@ class Referral(ModelSQL, ModelView):
@classmethod
def send_email_laboratory(cls, referrals):
Warning = Pool().get('res.user.warning')
pool = Pool()
Warning = pool.get('res.user.warning')
from_addr = tconfig.get('email', 'from')
smtp_server = None
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
if not from_addr:
logger.error("Missing configuration to send emails")
return
@ -7751,9 +7754,11 @@ class Referral(ModelSQL, ModelView):
subject, body = referral._get_mail_subject_body()
attachment_data = referral._get_mail_attachment()
msg = cls.create_msg(from_addr, to_addrs, subject,
body, attachment_data)
cls.send_msg(from_addr, to_addrs, msg, referral.number)
cls.send_msg(smtp_server, from_addr, to_addrs, msg,
referral.number)
def _get_mail_recipients(self):
pool = Pool()
@ -7821,17 +7826,23 @@ class Referral(ModelSQL, ModelView):
return msg
@staticmethod
def send_msg(from_addr, to_addrs, msg, referral_number):
def send_msg(smtp_server, from_addr, to_addrs, msg, referral_number):
to_addrs = list(set(to_addrs))
success = False
server = None
try:
server = get_smtp_server()
if smtp_server:
server = smtp_server.get_smtp_server()
else:
server = get_smtp_server()
server.sendmail(from_addr, to_addrs, msg.as_string())
server.quit()
success = True
except Exception:
logger.error(
"Unable to deliver mail for referral '%s'" % (referral_number))
"Unable to deliver mail for referral '%s'" % referral_number)
if server is not None:
server.quit()
return success

View File

@ -203,6 +203,14 @@
<field name="group" ref="group_lims_planification"/>
</record>
<record model="res.group" id="group_lims_smtp_server">
<field name="name">Lims SMTP Server</field>
</record>
<record model="res.user-res.group" id="user_admin_group_lims_smtp_server">
<field name="user" ref="res.user_admin"/>
<field name="group" ref="group_lims_smtp_server"/>
</record>
<!-- Icons -->
<record model="ir.ui.icon" id="laboratory_icon">

View File

@ -69,6 +69,8 @@
</page>
<page string="Mail Acknowledgment of Samples Receipt"
id="mail_ack_samples">
<label name="mail_ack_smtp"/>
<field name="mail_ack_smtp"/>
<label name="mail_ack_hide_recipients"/>
<field name="mail_ack_hide_recipients"/>
<separator string="Email body of Acknowledgment of Samples Receipt"
@ -77,6 +79,8 @@
<field name="mail_ack_body" colspan="4"/>
</page>
<page string="Mail Referral of Samples" id="mail_referral" col="6">
<label name="mail_referral_smtp"/>
<field name="mail_referral_smtp"/>
<separator string="Email subject of Referral of Samples"
colspan="4" id="mail_referral_subject"/>
<field name="mail_referral_subject" colspan="4"/>

View File

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<form col="4">
<label name="name"/>
<field name="name"/>
<notebook colspan="4">
<page id="server" string="Server">
<label name="smtp_server"/>
<field name="smtp_server"/>
<group id="smtp_header" col="4" colspan="2">
<label name="smtp_port"/>
<field name="smtp_port"/>
<label name="smtp_timeout"/>
<field name="smtp_timeout"/>
</group>
<label name="smtp_ssl"/>
<field name="smtp_ssl"/>
<label name="smtp_tls"/>
<field name="smtp_tls"/>
<label name="smtp_user"/>
<field name="smtp_user"/>
<label name="smtp_password"/>
<field name="smtp_password" widget="password"/>
<label name="smtp_email"/>
<field name="smtp_email"/>
<group id="server_buttons" col="6" colspan="6">
<label name="state"/>
<field name="state"/>
<button name="draft" icon="tryton-clear"/>
<button name="done" icon="tryton-forward"/>
<button name="test_smtp_server" icon="tryton-ok"/>
</group>
</page>
</notebook>
</form>

View File

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<tree>
<field name="name"/>
<field name="smtp_server"/>
<field name="smtp_user"/>
<field name="state"/>
</tree>

View File

@ -13,6 +13,9 @@ class Configuration(metaclass=PoolMeta):
mail_send_invoice_subject = fields.Char('Email subject of Invoice report',
help="In the text will be added suffix with the invoice report number")
mail_send_invoice_body = fields.Text('Email body of Invoice report')
mail_send_invoice_smtp = fields.Many2One('lims.smtp.server', 'SMTP for '
'Invoice report',
domain=[('state', '=', 'done')])
class Cron(metaclass=PoolMeta):

View File

@ -18,7 +18,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, Bool, Or, If
from trytond.transaction import Transaction
from trytond.tools import get_smtp_server
from trytond.config import config
from trytond.config import config as tconfig
from trytond.exceptions import UserError
from trytond.i18n import gettext
@ -114,10 +114,16 @@ class Invoice(metaclass=PoolMeta):
tt)
def mail_send_invoice(self):
pool = Pool()
Config = pool.get('lims.configuration')
if not self.invoice_report_cache:
return
from_addr = config.get('email', 'from')
config_ = Config(1)
smtp_server = config_.mail_send_invoice_smtp
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
to_addrs = [c.contact.email for c in self.invoice_contacts]
if not (from_addr and to_addrs):
logger.warn('mail_send_invoice():Factura %s:Envio omitido '
@ -128,9 +134,10 @@ class Invoice(metaclass=PoolMeta):
subject, body = self.subject_body()
attachments_data = self.attachment()
msg = self.create_msg(from_addr, to_addrs, subject,
body, attachments_data)
return self.send_msg(from_addr, to_addrs, msg)
return self.send_msg(smtp_server, from_addr, to_addrs, msg)
def subject_body(self):
pool = Pool()
@ -138,7 +145,7 @@ class Invoice(metaclass=PoolMeta):
User = pool.get('res.user')
Lang = pool.get('ir.lang')
config = Config(1)
config_ = Config(1)
lang = User(Transaction().user).language
if not lang:
@ -147,9 +154,9 @@ class Invoice(metaclass=PoolMeta):
], limit=1)
with Transaction().set_context(language=lang.code):
subject = str('%s %s' % (config.mail_send_invoice_subject,
subject = str('%s %s' % (config_.mail_send_invoice_subject,
self.number)).strip()
body = str(config.mail_send_invoice_body)
body = str(config_.mail_send_invoice_body)
return subject, body
@ -204,16 +211,23 @@ class Invoice(metaclass=PoolMeta):
msg.attach(attachment)
return msg
def send_msg(self, from_addr, to_addrs, msg):
def send_msg(self, smtp_server, from_addr, to_addrs, msg):
to_addrs = list(set(to_addrs))
success = False
server = None
try:
server = get_smtp_server()
if smtp_server:
server = smtp_server.get_smtp_server()
else:
server = get_smtp_server()
server.sendmail(from_addr, to_addrs, msg.as_string())
server.quit()
success = True
except Exception:
except Exception as e:
logger.error('Unable to deliver mail for invoice %s', self.number)
logger.error(str(e))
if server is not None:
server.quit()
return success

View File

@ -54,6 +54,10 @@ msgctxt "field:lims.configuration,mail_send_invoice_body:"
msgid "Email body of Invoice report"
msgstr "Cuerpo del correo de Informe de factura"
msgctxt "field:lims.configuration,mail_send_invoice_smtp:"
msgid "SMTP for Invoice report"
msgstr "SMTP para Informe de factura"
msgctxt "field:lims.configuration,mail_send_invoice_subject:"
msgid "Email subject of Invoice report"
msgstr "Asunto del correo de Informe de factura"

View File

@ -2,6 +2,8 @@
<data>
<xpath expr="/form/notebook/page[@id='general']" position="after">
<page string="Mail Invoice Report" id="mail_send_invoice_report">
<label name="mail_send_invoice_smtp"/>
<field name="mail_send_invoice_smtp"/>
<separator string="Email subject of Invoice report"
colspan="4" id="mail_send_invoice_subject"/>
<field name="mail_send_invoice_subject" colspan="4"/>

View File

@ -412,7 +412,9 @@ class AdministrativeTask(Workflow, ModelSQL, ModelView):
@classmethod
def send_email_responsible(cls, tasks):
from_addr = tconfig.get('email', 'from')
smtp_server = None
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
if not from_addr:
logger.error("Missing configuration to send emails")
return
@ -429,12 +431,15 @@ class AdministrativeTask(Workflow, ModelSQL, ModelView):
continue
subject, body = task._get_mail_subject_body()
msg = cls._create_msg(from_addr, to_addrs, subject, body)
cls._send_msg(from_addr, to_addrs, msg, task.number)
cls._send_msg(smtp_server, from_addr, to_addrs, msg, task.number)
@classmethod
def send_email_update(cls, tasks):
from_addr = tconfig.get('email', 'from')
smtp_server = None
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
if not from_addr:
logger.error("Missing configuration to send emails")
return
@ -453,8 +458,9 @@ class AdministrativeTask(Workflow, ModelSQL, ModelView):
continue
subject, body = task._get_mail_subject_body(True)
msg = cls._create_msg(from_addr, to_addrs, subject, body)
cls._send_msg(from_addr, to_addrs, msg, task.number)
cls._send_msg(smtp_server, from_addr, to_addrs, msg, task.number)
def _get_mail_subject_body(self, update=False):
pool = Pool()
@ -526,17 +532,23 @@ class AdministrativeTask(Workflow, ModelSQL, ModelView):
return msg
@staticmethod
def _send_msg(from_addr, to_addrs, msg, task_number):
def _send_msg(smtp_server, from_addr, to_addrs, msg, task_number):
to_addrs = list(set(to_addrs))
success = False
server = None
try:
server = get_smtp_server()
if smtp_server:
server = smtp_server.get_smtp_server()
else:
server = get_smtp_server()
server.sendmail(from_addr, to_addrs, msg.as_string())
server.quit()
success = True
except Exception:
logger.error(
"Unable to deliver email for task '%s'" % (task_number))
"Unable to deliver email for task '%s'" % task_number)
if server is not None:
server.quit()
return success
@classmethod

View File

@ -20,6 +20,9 @@ class Configuration(metaclass=PoolMeta):
' results report',
help='<SAMPLES> will be replaced by the list of sample\'s labels')
mail_ack_report_hide_recipients = fields.Boolean('Hide recipients')
mail_ack_report_smtp = fields.Many2One('lims.smtp.server', 'SMTP for '
'Acknowledgment of results report',
domain=[('state', '=', 'done')])
result_report_format = fields.Many2One('lims.result_report.format',
'Default Results Report Name Format')

View File

@ -14,6 +14,10 @@ msgctxt "field:lims.configuration,mail_ack_report_hide_recipients:"
msgid "Hide recipients"
msgstr "Ocultar destinatarios"
msgctxt "field:lims.configuration,mail_ack_report_smtp:"
msgid "SMTP for Acknowledgment of results report"
msgstr "SMTP para Acuse de informe de resultados"
msgctxt "field:lims.configuration,mail_ack_report_subject:"
msgid "Email subject of Acknowledgment of results report"
msgstr "Asunto del correo de Acuse de informe de resultados"

View File

@ -483,16 +483,18 @@ class SendResultsReport(Wizard):
ResultsReport = pool.get('lims.results_report')
Lang = pool.get('ir.lang')
from_addr = tconfig.get('email', 'from')
config_ = Config(1)
smtp_server = config_.mail_ack_report_smtp
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
if not from_addr:
logger.warning('Send Results Report: FAILED')
self.failed.reports_not_ready = []
self.failed.reports_not_sent = []
return 'failed'
config = Config(1)
hide_recipients = config.mail_ack_report_hide_recipients
email_qa = config.email_qa
hide_recipients = config_.mail_ack_report_hide_recipients
email_qa = config_.email_qa
context = Transaction().context
model = context.get('active_model', None)
@ -606,7 +608,7 @@ class SendResultsReport(Wizard):
msg = self._create_msg(from_addr, to_addrs, subject,
body, hide_recipients, group['attachments_data'])
sent = self._send_msg(from_addr, to_addrs, msg)
sent = self._send_msg(smtp_server, from_addr, to_addrs, msg)
if not sent:
reports_not_sent.extend(group['reports_ready'])
logger.warning('Send Results Report: Not sent')
@ -635,12 +637,12 @@ class SendResultsReport(Wizard):
Config = pool.get('lims.configuration')
ResultsReport = pool.get('lims.results_report')
config = Config(1)
config_ = Config(1)
res = {}
results_reports = ResultsReport.browse(report_ids)
if not config.mail_ack_report_grouping:
if not config_.mail_ack_report_grouping:
for report in results_reports:
if (report.invoice_party and
hasattr(report.invoice_party,
@ -654,7 +656,7 @@ class SendResultsReport(Wizard):
}
return res
if config.mail_ack_report_grouping == 'party':
if config_.mail_ack_report_grouping == 'party':
for report in results_reports:
if (report.invoice_party and
hasattr(report.invoice_party,
@ -704,7 +706,7 @@ class SendResultsReport(Wizard):
User = pool.get('res.user')
Lang = pool.get('ir.lang')
config = Config(1)
config_ = Config(1)
lang = User(Transaction().user).language
if not lang:
@ -720,9 +722,9 @@ class SendResultsReport(Wizard):
else:
label = gettext('lims_email.msg_polisample')
subject = str('%s %s (%s)' % (
config.mail_ack_report_subject,
config_.mail_ack_report_subject,
report_list, label)).strip()
body = str(config.mail_ack_report_body)
body = str(config_.mail_ack_report_body)
body = body.replace('<SAMPLES>', '\n'.join(sample_list))
body = body.replace('&lt;SAMPLES&gt;', '\n'.join(sample_list))
@ -770,12 +772,15 @@ class SendResultsReport(Wizard):
msg.attach(attachment)
return msg
def _send_msg(self, from_addr, to_addrs, msg):
def _send_msg(self, smtp_server, from_addr, to_addrs, msg):
to_addrs = list(set(to_addrs))
success = False
server = None
try:
server = get_smtp_server()
if smtp_server:
server = smtp_server.get_smtp_server()
else:
server = get_smtp_server()
server.sendmail(from_addr, to_addrs, msg.as_string())
server.quit()
success = True

View File

@ -6,6 +6,8 @@
<field name="result_report_format"/>
<label name="mail_ack_report_grouping"/>
<field name="mail_ack_report_grouping"/>
<label name="mail_ack_report_smtp"/>
<field name="mail_ack_report_smtp"/>
<label name="mail_ack_report_hide_recipients"/>
<field name="mail_ack_report_hide_recipients"/>
<separator string="Email subject of Acknowledgment of results report"

View File

@ -16,7 +16,7 @@ from trytond.wizard import Wizard, StateView, StateTransition, Button
from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval, Bool
from trytond.transaction import Transaction
from trytond.config import config
from trytond.config import config as tconfig
from trytond.tools import get_smtp_server
from trytond.exceptions import UserError, UserWarning
from trytond.i18n import gettext
@ -291,7 +291,9 @@ class Sale(metaclass=PoolMeta):
@classmethod
def send_email_party(cls, sales):
from_addr = config.get('email', 'from')
smtp_server = None
from_addr = (smtp_server and smtp_server.smtp_email or
tconfig.get('email', 'from'))
if not from_addr:
logger.error("Missing configuration to send emails")
return
@ -302,21 +304,22 @@ class Sale(metaclass=PoolMeta):
logger.error("Missing address for '%s' to send email",
sale.party.rec_name)
continue
reply_to = sale.create_uid.email
reply_to = sale.create_uid.email
subject, body = sale._get_subject_body()
attachment_data = sale._get_attachment()
msg = cls.create_msg(from_addr, to_addr, reply_to, subject,
body, attachment_data)
cls.send_msg(from_addr, to_addr, msg, sale.number)
cls.send_msg(smtp_server, from_addr, to_addr, msg, sale.number)
def _get_subject_body(self):
pool = Pool()
Config = pool.get('sale.configuration')
config = Config(1)
subject = str(config.email_quotation_subject)
body = str(config.email_quotation_body)
config_ = Config(1)
subject = str(config_.email_quotation_subject)
body = str(config_.email_quotation_body)
return subject, body
def _get_attachment(self):
@ -359,16 +362,22 @@ class Sale(metaclass=PoolMeta):
return msg
@staticmethod
def send_msg(from_addr, to_addr, msg, task_number):
def send_msg(smtp_server, from_addr, to_addr, msg, task_number):
success = False
server = None
try:
server = get_smtp_server()
if smtp_server:
server = smtp_server.get_smtp_server()
else:
server = get_smtp_server()
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
success = True
except Exception:
logger.error(
"Unable to deliver email for task '%s'" % (task_number))
"Unable to deliver email for task '%s'" % task_number)
if server is not None:
server.quit()
return success
def create_invoice(self):