Bienvenido a los foros %s

Foro comunidad hispana Dolibarr

Identificarse Registrarse

Añadir archivo al email de presupuesto de forma automática

Cuestiones sobre cómo utilizar Dolibarr, ayudas sobre las funcionalidades o cualquier cuestión que no está relacionada con un error.
aliber
Novato
Mensajes: 5
Registrado: Mié, 03/03/2021, 10:20

Añadir archivo al email de presupuesto de forma automática

Mensaje por aliber »

Hola, ante todo agradecer a Aitorxs que compartiera unas modificaciones en el código para adjuntar automáticamente archivos adicionales al correo enviado desde la ficha de factura.
https://www.dolibarr.es/foro/viewtopic.php?t=8589
El caso es que necesitaba adjuntar automáticamente un archivo adicional al correo, pero desde la ficha de presupuesto. He probado el código hasta entender (creo) cómo ponerlo en la versión 13.0.0, y al ver que funcionaba he probado para adjuntar un tercer archivo repitiendo el mismo código de Aitorxs. He de decir que no estoy muy puesto en php e igual estoy haciendo algo mal.

El código sería así:
• core/lib/files.lib.php
Al ser la versión 13.0.1 me sale que debería poner el código por la línea 2214 en el apartado de << Return file(s) into a directory (by default most recent)>> y añado el código para los dos archivos:

Código: Seleccionar todo

function dol_most_recent_file_1($dir, $regexfilter = '', $excludefilter = array('(\.meta|_preview.*\.png)$', '^\.'), $nohook = false, $mode = '')
{
	$tmparray = dol_dir_list($dir, 'files', 0, $regexfilter, $excludefilter, 'date', SORT_DESC, $mode,$nohook);
	return $tmparray[1];
}

function dol_most_recent_file_2($dir, $regexfilter = '', $excludefilter = array('(\.meta|_preview.*\.png)$', '^\.'), $nohook = false, $mode = '')
{
	$tmparray = dol_dir_list($dir, 'files', 0, $regexfilter, $excludefilter, 'date', SORT_DESC, $mode,$nohook);
	return $tmparray[2];
}
• core/tpl/card_presend.tpl.php
En el apartado << Code to ouput content when action is presend >> en la condición que comienza en la línea 44 agrego el código indicado por Aitorxs añadiendo el caso especial de presupuesto (propal)

Código: Seleccionar todo

if (!in_array($object->element, array('societe', 'user', 'member')))
	{
		// TODO get also the main_lastdoc field of $object. If not found, try to guess with following code

		$ref = dol_sanitizeFileName($object->ref);
		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
		// Special case
		if ($object->element == 'invoice_supplier')
		{
			$fileparams = dol_most_recent_file($diroutput.'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
			$fileparams_1 = dol_most_recent_file_1($diroutput .'/'.$ref, preg_quote($ref, '/').'[^\-]+');
			$fileparams_2 = dol_most_recent_file_2($diroutput .'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		} else {
			$fileparams = dol_most_recent_file($diroutput.'/'.$ref, preg_quote($ref, '/').'[^\-]+');
			//$fileparams_1 = dol_most_recent_file_1($diroutput .'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
			//$fileparams_2 = dol_most_recent_file_2($diroutput .'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
		}
		// Special case facture
		if ($object->element == 'facture')
		{
			
			$fileparams = dol_most_recent_file($diroutput.'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
		} else {
			$fileparams = dol_most_recent_file($diroutput.'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		}
		// Special case presupuesto
		if ($object->element == 'propal')
		{
			$fileparams = dol_most_recent_file($diroutput.'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
			$fileparams_1 = dol_most_recent_file_1($diroutput .'/'.$ref, preg_quote($ref, '/').'[^\-]+');
			$fileparams_2 = dol_most_recent_file_2($diroutput .'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		} else {
			$fileparams = dol_most_recent_file($diroutput.'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		}
		
		$file = $fileparams['fullname'];
		$file_1 = $fileparams_1['fullname'];
		$file_2 = $fileparams_2['fullname'];
	}
Al final del documento en el apartado <<Array of substitutions>> añado

Código: Seleccionar todo

	$formmail->param['fileinit_1'] = array($file_1);
	$formmail->param['fileinit_2'] = array($file_2);
• core/class/html.formmail.class.php
En el apartado << Add a file into the list of attached files (stored in SECTION array)>> que comienza en la línea 215 añado la siguiente función, aunque uso la original (public function add_attached_files) que es igual por lo que esta sobraría (creo)

Código: Seleccionar todo

	public function add_attached_files_1($path, $file='', $type='')
	{
		$listofpaths=array();
		$listofnames=array();
		$listofmimes=array();

		if (empty($file)) $file=basename($path);
		if (empty($type)) $type=dol_mimetype($file);

		$keytoavoidconflict = empty($this->trackid)?'':'-'.$this->trackid; // this->trackid must be defined
		if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]);
		if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]);
		if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]);
		if (! in_array($file,$listofnames))
		{
			$listofpaths[]=$path;
			$listofnames[]=$file;
			$listofmimes[]=$type;
			$_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths);
			$_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames);
			$_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes);
		}
	}
Por último, al agregar la función anterior me quedaría el siguiente código por la línea 410 en el apartado << // Define list of attached files>>

Código: Seleccionar todo

			if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1'))
			{
				if (!empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit']))
				{
					foreach ($this->param['fileinit'] as $file)
					{
						$this->add_attached_files($file, basename($file), dol_mimetype($file));
					}
					foreach($this->param['fileinit_1'] as $file_1 )
					{
					if (!empty($file_1)){
					$this->add_attached_files($file_1, basename($file_1), dol_mimetype($file_1));
					}
					}
					
					foreach($this->param['fileinit_2'] as $file_2 )
					{
					if (!empty($file_2)){
					$this->add_attached_files($file_2, basename($file_2), dol_mimetype($file_2));
					}
					}
				}
			}
doli.png
doli.png (10.85 KiB) Visto 4241 veces
El caso es que adjunta los tres archivos siempre y cuando:
• El archivo empiece por la referencia del presupuesto seguido de un guion bajo (_) “PR2103-0003_SPECIMEN(6).pdf”
• El archivo termine por la referencia del presupuesto “informePR2103-0003.pdf”
• Por supuesto si el nombre del archivo es la referencia “PR2103-0003.pdf”
Sin embargo cuando el archivo tiene la referencia seguido de un guion medio (-) y otro texto no funciona.

Mi intención es adjuntar junto al presupuesto sólo un archivo que contenga un texto determinado como “informe” he visto en el código que hay un parámetro llamado $regexfilter = ' ' que creo que serviría, pero no encuentro documentación para utilizarlo.

Cualquier ayuda sería de agradecer.

Un saludo

aliber
Novato
Mensajes: 5
Registrado: Mié, 03/03/2021, 10:20

Mensaje por aliber »

Bueno, después del fin de semana parece que he dado con la tecla.
He dejado el código para que solo adjunte dos archivos al correo de presupuesto y por fin he encontrado lo que tenía que modificar para adjuntar el archivo que contuviese el texto "informe".
El código que he modificado con respecto al anterior mensaje está en el archivo \dolibarr\core\tpl\card_presend.tpl.php

Código: Seleccionar todo

$fileparams_1 = dol_most_recent_file_1($diroutput.'/'.$ref, 'informe'.'[^\-]+');
Quedando:

Código: Seleccionar todo

// Special case presupuesto
		if ($object->element == 'propal')
		{
			$fileparams = dol_most_recent_file($diroutput.'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
			$fileparams_1 = dol_most_recent_file_1($diroutput.'/'.$ref, 'informe'.'[^\-]+');
		} else {
			$fileparams = dol_most_recent_file($diroutput.'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		}
		$file = $fileparams['fullname'];
		$file_1 = $fileparams_1['fullname'];
	}
El único problema que me queda por solucionar es que sigue sin funcionar lo del guion después del texto buscado.
Espero que sea de utilidad para la comunidad.
Un saludo

igorae
Novato
Mensajes: 20
Registrado: Mar, 02/02/2021, 16:16

Mensaje por igorae »

Muchas gracias por el aporte. Muy bueno.

Una pena lo del guión medio, porque por defecto al adjuntar documentos pone un guión medio entre la referencia y el nombre del archivo subido, con lo que luego hay que editar sí o sí a mano el nombre del archivo subido para que funcione.

Veo además que funciona cualquier caracter que pongas entre la referencia y el nombre del archivo, ya sea _ + ( ) o incluso letras, pero el guión medio - no.

Confirmo que esta parte que indicas no es necesario ponerla:
• core/class/html.formmail.class.php
En el apartado << Add a file into the list of attached files (stored in SECTION array)>> que comienza en la línea 215 añado la siguiente función, aunque uso la original (public function add_attached_files) que es igual por lo que esta sobraría (creo)
Y en el archivo:

core/tpl/card_presend.tpl.php

Podemos añadir más casos especiales:

Código: Seleccionar todo

// Special case presupuesto
		if ($object->element == 'propal')
		{
			$fileparams = dol_most_recent_file($diroutput.'/'.get_exdir($object->id, 2, 0, 0, $object, $object->element).$ref, preg_quote($ref, '/').'([^\-])+');
			$fileparams_1 = dol_most_recent_file_1($diroutput .'/'.$ref, preg_quote($ref, '/').'[^\-]+');
			$fileparams_2 = dol_most_recent_file_2($diroutput .'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		} else {
			$fileparams = dol_most_recent_file($diroutput.'/'.$ref, preg_quote($ref, '/').'[^\-]+');
		}
simplemente cambiando 'propal' por lo que corresponda. Por ejemplo 'order_supplier' para pedidos a proveedor.

aliber
Novato
Mensajes: 5
Registrado: Mié, 03/03/2021, 10:20

Mensaje por aliber »

igorae escribió: Mar, 09/03/2021, 14:28 Una pena lo del guión medio, porque por defecto al adjuntar documentos pone un guión medio entre la referencia y el nombre del archivo subido, con lo que luego hay que editar sí o sí a mano el nombre del archivo subido para que funcione.
En principio el programa cuando subes un archivo lo renombra por defecto con la referencia del presupuesto (Nº de presupuesto) , guion medio y luego el nombre del archivo que subes. Aquí no habría problema porque el fallo del guion es después del texto buscado y no al principio, a menos que ya lo tuviese el archivo adjuntado.

Un saludo,

igorae
Novato
Mensajes: 20
Registrado: Mar, 02/02/2021, 16:16

Mensaje por igorae »

En mi caso lo que quería es que al añadir cualquier archivo, tuviera el nombre que tuviera, se adjuntara automáticamente (en mi caso son los presupuestos que me envían los proveedores que pueden tener cualquier nombre) y como en ese caso solo funciona si hay un guión bajo entre la Referencia y el nombre del archivo, pues toca renombrar los archivos.

Aún así, me es de gran ayuda, para no tener que volver a resubir documentos que ya tenía subidos a Dolibarr.

Muchas gracias por haberlo compartido.

igorae
Novato
Mensajes: 20
Registrado: Mar, 02/02/2021, 16:16

Mensaje por igorae »

Acabo de solucionar mi problema del guión bajo. Simplemente el cambiado la máscara que añade Dolibarr a los archivos que sube, para que sea del tipo:

REF_nombredearchivo

en lugar de la que viene predefinida con guión medio:

REF-nombredearchivo

Para hacerlo, hay que cambiar este código en el archivo core\tpl\document_actions_post_headers.tpl.php (Linea 104 en Dolibarr 12.0.4):

Código: Seleccionar todo

$savingdocmask = dol_sanitizeFileName($object->ref).'-__file__';
Por este otro:

Código: Seleccionar todo

$savingdocmask = dol_sanitizeFileName($object->ref).'___file__';
Nótese que en el segundo texto hay 3 guiones bajos antes de file (___file__) y en el original hay guión medio y 2 guiones bajos (-__file__)

Con esto, todos los archivos que se suben a Dolibarr se renombran con un guión bajo entre la Referencia del Presupuesto, Pedido o lo que sea y el nombre original del archivo, adjuntándose luego automáticamente a los e-mails, gracias al código aportado por aliber en el primer mensaje.

Avatar de Usuario
aitorxs
Almirante
Mensajes: 306
Registrado: Mar, 03/02/2015, 17:46

Mensaje por aitorxs »

Me alegra mucho que te haya servido mi aporte y lograras solucionar tu requerimiento. Saludos!
sistemas@machfree.com | http://www.machfree.com | Trujillo - Perú
*Si no respondo los mensajes....enviame un email ;)