<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
                xmlns:content="http://purl.org/rss/1.0/modules/content/"
                xmlns:wfw="http://wellformedweb.org/CommentAPI/"
                xmlns:dc="http://purl.org/dc/elements/1.1/"
                xmlns:atom="http://www.w3.org/2005/Atom"
                xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
                xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
            >
        <channel>
            <title>I + D WEB</title>
            <atom:link href="https://imasdeweb.com/index.php?rss=blog" rel="self" type="application/rss+xml" />
            <link>https://imasdeweb.com</link>
            <description>diseño web · marketing en internet y redes sociales · desarrollo de aplicaciones web</description>
            <lastBuildDate>Thu, 19 Feb 2026 22:31:00 -0700</lastBuildDate>
            <language>es</language>
            <sy:updatePeriod>daily</sy:updatePeriod>
            <sy:updateFrequency>1</sy:updateFrequency>
    <image>
                <url>https://imasdeweb.com/UserFiles/admin/images/og_logo.jpg</url>
                <title>I + D WEB</title>
                <link>https://imasdeweb.com</link>
                <width>96</width>
                <height>96</height>
            </image> 
    
        <item>
            <title>Manual de usuario del módulo AI Writer</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=114</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=114</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Thu, 19 Feb 2026 13:39:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/114.jpg" style="display: block; margin: 1em auto" /></p><p>AI Writer es un asistente de inteligencia artificial integrado en Dolibarr que te ayuda a procesar texto de forma contextual. Permite resumir, traducir, mejorar redacción, cambiar el tono o aplicar transformaciones personalizadas al instante.<br /><br />
<br /><br />
Compatible con las principales plataformas de IA: **Mistral**, **DeepSeek**, **Anthropic** y **OpenAI**.<br /><br />
Además, recuerda tus preferencias para mantener un flujo de trabajo ágil y continuo. ⚡</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/114.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p><u>AI Writer</u> es un asistente de inteligencia artificial integrado en Dolibarr que te ayuda a procesar texto de forma contextual.</p>

<ul>
	<li>Permite <em>resumir</em>, <em>traducir</em>, <em>mejorar redacci&oacute;n</em>, <em>cambiar el tono</em>&nbsp;o aplicar <em>transformaciones personalizadas</em>&nbsp;al instante.</li>
	<li>Compatible con las principales plataformas de IA: <strong>Mistral, DeepSeek, Anthropic y OpenAI</strong>.</li>
	<li>Adem&aacute;s, <em>recuerda tus preferencias</em> para mantener un flujo de trabajo &aacute;gil y continuo. ⚡</li>
</ul>
</div>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-Writer_benefits_ES.png" style="max-width:100%;" /></p>

<h3>&Iacute;ndice</h3>

<p>Si no eres un usuario administrador en tu Dolibarr, puedes pasar al punto 3 de esta manual.</p>

<ol>
	<li><a href="#section_bubble">💬 Burbuja flotante en todas las p&aacute;ginas</a></li>
	<li><a href="#section_selection_mode">✏️ Modo de selecci&oacute;n de texto</a>
	<ul>
		<li><a href="#sec_selection_by_drag">Selección por arrastre y soltar</a></li>
		<li><a href="#sec_selection_of_containers">Selección de contenedores</a></li>
		<li><a href="#sec_selection_empty">Selección vacía para edición libre</a></li>
	</ul>
	</li>
	<li><a href="#section_transformation_options">⚙️ Opciones de transformaci&oacute;n de texto</a>
	<ul>
		<li><a href="#sec_preset_transformations">Tipos de transformaci&oacute;n predefinida</a></li>
		<li><a href="#sec_preset_languages">Idiomas disponibles predefinidos</a></li>
		<li><a href="#sec_additional_options">Opciones adicionales</a> (emojis &amp; hashtags)</li>
		<li><a href="#sec_custom_transformation">Transformaci&oacute;n personalizada</a></li>
	</ul>
	</li>
	<li><a href="#section_install">Proceso de instalaci&oacute;n</a></li>
	<li><a href="#section_AI_providers">Configuraci&oacute;n e integraci&oacute;n con proveedores de IA</a></li>
	<li><a href="#section_AI_writer_benefits">💎 Beneficios del m&oacute;dulo AI Writer</a></li>
</ol>

<div id="section_bubble" style="padding-top:100px;margin-top:-50px;">
<h2>💬 Burbuja flotante en todas las p&aacute;ginas</h2>

<p>Una vez instalado y configurado el m&oacute;dulo (consulta la secci&oacute;n <u>Instalaci&oacute;n y Configuraci&oacute;n</u> al final de esta gu&iacute;a), aparecer&aacute; una <strong>burbuja clicable</strong>&nbsp;en la esquina inferior derecha de todas las p&aacute;ginas de Dolibarr.</p>

<p>Esta burbuja es la puerta de entrada a las funciones del asistente de IA.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_02_magic-buble-to-fire-assistant_ES.png" style="max-width:100%;" /></p>
</div>

<div id="section_selection_mode" style="padding-top:100px;margin-top:-50px;">
<h2>✏️ Modo de selecci&oacute;n de texto</h2>

<p>Al pulsar la burbuja, la p&aacute;gina entrar&aacute; en&nbsp;<strong>modo de selecci&oacute;n</strong>, aplicando un color tenue al fondo.<br />
Mientras mueves el cursor, se ir&aacute;n <strong>resaltando los elementos editables</strong>&nbsp;que contienen texto, entre ellos:</p>

<p>- <u>Cajas de texto</u> de una l&iacute;nea (<em>formularios</em>).<br />
- <u>&Aacute;reas de texto</u> multil&iacute;nea (<em>textarea en formularios</em>).<br />
- Contenido dentro de <u>editores enriquecidos</u> como&nbsp;<strong>CKEditor</strong> (por ejemplo, en <em>notas o correos</em>).<br />
- <u>Textos visibles</u> en pantalla: t&iacute;tulos, p&aacute;rrafos, &iacute;tems de listas, etc.</p>

<p>👉 Al hacer clic sobre uno de estos elementos, se abrir&aacute; el <strong>cuadro de di&aacute;logo de transformaci&oacute;n</strong>&nbsp;del texto seleccionado.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_03_apply-text-transformation_ES.png" style="max-width:100%;" /></p>
</div>

<div class="block">
<p>De hecho, hay 4 modos de selecci&oacute;n de texto en la p&aacute;gina:</p>

<ul>
	<li><strong>SELECCI&Oacute;N CON UN CLIC</strong>, para seleccionar <u>un solo elemento</u> contenedor de texto (p&aacute;rrafo, textarea, editor, celda de una tabla, etc.)</li>
	<li><strong>SELECCI&Oacute;N POR ARRASTRE Y SOLTAR</strong>, para seleccionar <u>varios elementos</u> de la p&aacute;gina (por ejemplo, varias filas de una tabla).</li>
	<li><strong>SELECCION DE CONTENEDOR</strong> (con <em>SHIFT+CLIC</em>), para seleccionar <u>toda una tabla, secci&oacute;n o lista de items</u>&nbsp;completa.</li>
	<li><strong>SELECCI&Oacute;N VAC&Iacute;A</strong>&nbsp;(clicando sobre una zona vac&iacute;a de la p&aacute;gina), para poder <u>introducir manualmente el texto</u> a procesar (!!).</li>
</ul>
</div>

<h3 id="sec_selection_by_drag">SELECCI&Oacute;N POR ARRASTRE Y SOLTAR</h3>

<ul>
	<li>Si despu&eacute;s de <u>hacer clic</u> por ejemplo en una celda no vac&iacute;a de una tabla y <u>arrastramos hacia abajo o hacia arriba</u>, podremos seleccionar varias filas de una tabla, aunque no necesariamente toda. <u>Al soltar el rat&oacute;n</u> se abrir&aacute; el cuadro de di&aacute;logo para configurar la transformaci&oacute;n.</li>
	<li>Lo mismo puede usarse para escoger unos cuantos elementos de una lista de vi&ntilde;etas, en lugar de uno solo.</li>
</ul>

<h3 id="sec_selection_of_containers">SELECCI&Oacute;N DE CONTENEDORES</h3>

<p>Sin embargo, si queremos seleccionar toda una tabla, o toda una lista de vi&ntilde;etas o toda una secci&oacute;n de la p&aacute;gina, entonces haremos esto:</p>

<ol>
	<li>poner el cursor del rat&oacute;n dentro de esa &quot;zona&quot;</li>
	<li>pulsar la tecla SHIFT del teclado</li>
	<li>desplazar el rat&oacute;n hacia los lados o hacia arriba o hacia abajo para que se ilumine el contenedor de ese elemento</li>
	<li>si nos desplazamos fuera de ese contenedor, podremos iluminar el siguiente contenedor, incluso toda la p&aacute;gina</li>
	<li>cuando&nbsp;</li>
</ol>

<p>⚠️&nbsp;<strong><u>Nota</u>:</strong>&nbsp;este selector se queda con todo el HTML contenido en la zona se&ntilde;eccionada, y eso a veces incluye bastante c&oacute;digo CSS o incluso javascript... que ser&aacute; tambi&eacute;n enviado por el m&oacute;dulo al LLM para ser procesado. En el prompt ya viene la instrucci&oacute;n de &quot;no tocar&quot; (o &quot;no hacer caso&quot;) de CSS y javascript y solo traducir/transformar el &quot;texto visible&quot;. Pero yo he notado que al seleccionar demasiados elementos de la p&aacute;gina el LLM se confunde, se tarda y a veces no responde. As&iacute; que toma este modo de selecci&oacute;n como algo &quot;experimental&quot; de momento.</p>

<h3 id="sec_selection_empty">SELECCI&Oacute;N VAC&Iacute;A para EDICI&Oacute;N LIBRE</h3>

<p>Este modo de selecci&oacute;n est&aacute; interesante:</p>

<ol>
	<li>mueve el rat&oacute;n hasta situarlo en una &quot;zona vac&iacute;a de texto&quot;</li>
	<li>eso provocar&aacute; que ning&uacute;n elemento de la p&aacute;gina quede &quot;remarcado&quot;</li>
	<li>entonces haz clic con el rat&oacute;n</li>
	<li>y se abrir&aacute; el cuadro de di&aacute;logo para indicar la transformaci&oacute;n que queremos</li>
	<li>pero... ahora el recuadro de &quot;previsualizaci&oacute;n&quot; del texto seleccionado, ya no aparece y en su lugar tenemos una caja de texto multil&iacute;nea donde debemos escribir (o pegar) el texto que queramos editar.</li>
</ol>

<p>Este modo de selecci&oacute;n yo lo uso a menudo para mientras trabajo con otras apps que no son Dolibarr y necesito un editor/traductor de texto r&aacute;pido. Y como sabes, AI Writer es un asistente r&aacute;pido para usar.</p>

<div id="section_transformation_options" style="padding-top:100px;margin-top:-50px;">
<h2>⚙️ Opciones de transformaci&oacute;n de texto</h2>

<p>El cuadro de di&aacute;logo ofrece m&uacute;ltiples opciones de mejora y formato del texto.<br />
Puedes seleccionar una&nbsp;<strong>transformaci&oacute;n predefinida</strong> o escribir una <strong>instrucci&oacute;n personalizada</strong>.</p>

<h3 id="sec_preset_transformations">Tipos de transformaci&oacute;n predefinida</h3>

<ul style="list-style-type: none;line-height: 2em;">
	<li>✨&nbsp;<strong>Mejorar redacci&oacute;n</strong>&nbsp;&mdash; corrige gram&aacute;tica y estilo.</li>
	<li>🌍 <strong>Traducir a otro idioma</strong> &mdash; selecciona idioma y tono deseado.</li>
	<li>✂️&nbsp;<strong>Resumir</strong> &mdash; crea versiones breves y claras.</li>
	<li>📈 <strong>Extender o ampliar</strong>&nbsp;&mdash; desarrolla ideas o a&ntilde;ade m&aacute;s contexto.</li>
	<li>🤓 <strong>Simplificar lenguaje t&eacute;cnico</strong>&nbsp;&mdash; &uacute;til para textos complejos o p&uacute;blicos no especializados.</li>
	<li>👔 <strong>Hacer m&aacute;s formal</strong>&nbsp;&mdash; ideal para reportes o correos ejecutivos.</li>
	<li>💬 <strong>Hacer m&aacute;s casual</strong>&nbsp;&mdash; para mensajes informales o redes sociales.</li>
	<li>⚙️ <strong>Instrucci&oacute;n personalizada</strong>&nbsp;&mdash; combina cualquier ajuste libremente (ver siguiente secci&oacute;n).</li>
</ul>

<h3 id="sec_preset_languages">Idiomas disponibles predefinidos</h3>

<ul style="list-style-type: none;  line-height: 2em;">
	<li>El m&oacute;dulo incluye traducci&oacute;n directa a:&nbsp;<strong>Ingl&eacute;s, Franc&eacute;s, Espa&ntilde;ol, Alem&aacute;n, Italiano, Portugu&eacute;s, Catal&aacute;n, Holand&eacute;s, Ruso, Chino y Japon&eacute;s.</strong></li>
	<li>📌 Si necesitas otro idioma, selecciona la opci&oacute;n <u>Instrucci&oacute;n personalizada</u>&nbsp;e ind&iacute;calo manualmente.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_04_transformations_and_languages_ES.png" style="max-width:100%;" /></p>

<h3 id="sec_additional_options">Opciones adicionales</h3>

<ul style="line-height: 2em;">
	<li><strong>Emojis</strong>: inserta autom&aacute;ticamente al inicio o al final de cada p&aacute;rrafo.&nbsp;<br />
	Perfecto para redes sociales, mensajer&iacute;a o emails modernos.</li>
	<li><strong>Hashtags</strong>: genera etiquetas (#) al principio, al final o intercaladas en el texto.<br />
	Muy &uacute;til para publicaciones en LinkedIn, X o Instagram.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_05_add_emojis_and_hashtags_ES.png" style="max-width:100%;" /></p>

<p>&nbsp;</p>

<h3 id="sec_custom_transformation">Transformaci&oacute;n personalizada</h3>

<p>La transformaci&oacute;n &ldquo;<u>Instrucci&oacute;n personalizada</u>&rdquo; libera todo el potencial de la IA.<br />
Permite escribir cualquier indicaci&oacute;n natural, combinando acciones o reglas seg&uacute;n tus necesidades.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_06_custom_prompt_ES.png" style="max-width:100%;" /></p>

<p><strong>Ejemplos de uso:</strong></p>

<ul>
	<li>&ldquo;<em>Resume en un solo p&aacute;rrafo, y en h&uacute;ngaro.</em>&rdquo;</li>
	<li>&ldquo;<em>Corrige gramaticalmente, simplifica tecnicismos y agrega una disculpa por el retraso.</em>&rdquo;</li>
	<li>&ldquo;<em>Excluye de la lista los elementos no t&eacute;cnicos, deja solo los financieros y redacta en ingl&eacute;s b&aacute;sico.</em>&rdquo;</li>
</ul>

<p>Esta opci&oacute;n es ideal para redactores avanzados o tareas especializadas donde cada palabra importa.</p>
</div>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h2>Proceso de instalaci&oacute;n</h2>

<p>Primeramente lo de costumbre en la instalaci&oacute;n de cualquier m&oacute;dulo de Dolibarr:</p>

<ol>
	<li>Ir a la secci&oacute;n <u>Configuraci&oacute;n</u></li>
	<li>Ir a <u>M&oacute;dulos</u></li>
	<li>Ir a pesta&ntilde;a <u>Instalar m&oacute;dulo externo</u>, y ah&iacute; subes el ZIP del m&oacute;dulo o su actualizaci&oacute;n</li>
	<li>Volvemos a la pesta&ntilde;a <u>M&oacute;dulos disponibles</u></li>
	<li><u>Filtramos por Origen</u>: &quot;Externo - IMASDEWEB&quot;</li>
	<li><u>Activamos</u> el m&oacute;dulo</li>
</ol>
</div>

<div id="section_AI_providers" style="padding-top:100px;margin-top:-50px;">
<h2>Configuraci&oacute;n e integraci&oacute;n con proveedores de IA</h2>

<ol>
	<li>Pones la &quot;<u>API key</u>&quot; (clave de API) de al menos uno de los proveedores</li>
	<li>Despu&eacute;s de guardar cambios debes seleccionar el modelo LLM de ese proveedor que quieres usar por defecto.</li>
</ol>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_01_LLM-settings_ES.png" style="max-width:100%;" /></p>

<p><strong>Nota:</strong></p>

<ul>
	<li>La clave de API la debes conseguir en la plataforma del proveedor, se suele <u>pagar por uso</u>, normalmente pones saldo en tu cuenta con ellos (basta que inicies con $5USD)</li>
	<li>A veces al agregar la clave del proveedor en la configuraci&oacute;n del m&oacute;dulo no se activan los modelos del mismo. En este caso simplemente refresca la p&aacute;gina</li>
	<li>M&aacute;s adelante est&aacute; previsto agregar la posibilidad de escoger diferentes modelos y/o proveedores de LLM para diferentes tareas, porqu&eacute; algunos tipos de transformaci&oacute;n son bastante simples de procesar y cualquier modelo/proveedor es capaz de realizar a un costo muy m&iacute;nimo, pero algunos procesos de transformaci&oacute;n exigen usar un modelo m&aacute;s caro para conseguir resultados m&aacute;s saludables. Vaya, o simplemente a veces necesitamos una traducci&oacute;n &quot;mediocre&quot; para nosotros mismos, pero otras veces necesitamos que sea excelente (para publicar o enviar a un cliente). Entonces, pudiendo escoger el modelo/proveedor a usar en cada caso, el ahorro puede ser f&aacute;cilmente de 4-10x !!</li>
</ul>
</div>

<div id="section_AI_writer_benefits" style="padding-top:100px;margin-top:-50px;">
<h2>💎 Beneficios del m&oacute;dulo AI Writer</h2>

<table style="width:auto;margin:1.2rem auto;">
	<tbody>
		<tr>
			<td style="padding:2em 3em;line-height:3em;">🚀 <strong>Ahorra tiempo</strong>&nbsp;redactando, traduciendo o corrigiendo sin copiar y pegar.<br />
			🧩 <strong>100% integrado en Dolibarr</strong>, accesible desde cualquier m&oacute;dulo o vista.<br />
			🤖 <strong>Compatible con los principales proveedores de IA</strong>, elige tu preferido.<br />
			✨&nbsp;<strong>Resultados consistentes y personalizables</strong>, ajustados a tu estilo.<br />
			🌐 <strong>Ideal para equipos multiling&uuml;es</strong>, marketing, soporte o gesti&oacute;n documental.<br />
			🔄 <strong>Transformaciones instant&aacute;neas</strong>, sin salir del flujo de trabajo.</td>
		</tr>
	</tbody>
</table>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>User Manual for the AI Writer Module</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=115</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=115</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Thu, 19 Feb 2026 22:17:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/115.jpg" style="display: block; margin: 1em auto" /></p><p>AI Writer is an artificial intelligence assistant integrated into Dolibarr that helps you process text contextually. It allows you to summarize, translate, improve writing, change tone, or apply custom transformations instantly.<br /><br />
<br /><br />
Compatible with major AI platforms: Mistral, DeepSeek, Anthropic, and OpenAI.<br /><br />
Additionally, it remembers your preferences to maintain an agile and continuous workflow.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/115.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p><u>AI Writer</u> is an artificial intelligence assistant integrated into Dolibarr that helps you process text contextually.</p>

<ul>
	<li>It allows you to <em>summarize</em>, <em>translate</em>, <em>improve writing</em>, <em>change the tone</em>, or apply <em>custom transformations</em> instantly.</li>
	<li>Compatible with major AI platforms: <strong>Mistral, DeepSeek, Anthropic, and OpenAI</strong>.</li>
	<li>Additionally, it <em>remembers your preferences</em> to maintain an agile and continuous workflow. ⚡</li>
</ul>
</div>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-Writer_benefits_EN.png" style="max-width:100%;" /></p>

<h3>Index</h3>

<p>If you are not an administrator user in your Dolibarr, you can skip to point 3 of this manual.</p>

<ol>
	<li><a href="#section_bubble">💬 Floating bubble on all pages</a></li>
	<li><a href="#section_selection_mode">✏️ Text selection mode</a>
	<ul>
		<li><a href="#sec_selection_by_drag">Selection by drag and drop</a></li>
		<li><a href="#sec_selection_of_containers">Container selection</a></li>
		<li><a href="#sec_selection_empty">Empty selection for free editing</a></li>
	</ul>
	</li>
	<li><a href="#section_transformation_options">⚙️ Text transformation options</a>
	<ul>
		<li><a href="#sec_preset_transformations">Predefined transformation types</a></li>
		<li><a href="#sec_preset_languages">Available predefined languages</a></li>
		<li><a href="#sec_additional_options">Additional options</a> (emojis &amp; hashtags)</li>
		<li><a href="#sec_custom_transformation">Custom transformation</a></li>
	</ul>
	</li>
	<li><a href="#section_install">Installation process</a></li>
	<li><a href="#section_AI_providers">Configuration and integration with AI providers</a></li>
	<li><a href="#section_AI_writer_benefits">💎 Benefits of the AI Writer module</a></li>
</ol>

<div id="section_bubble" style="padding-top:100px;margin-top:-50px;">
<h2>💬 Floating bubble on all pages</h2>

<p>Once the module is installed and configured (see the <u>Installation and Configuration</u> section at the end of this guide), a <strong>clickable bubble</strong> will appear in the bottom right corner of all Dolibarr pages.</p>

<p>This bubble is the gateway to the AI assistant&#39;s functions.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_02_magic-buble-to-fire-assistant_EN.png" style="max-width:100%;" /></p>
</div>

<div id="section_selection_mode" style="padding-top:100px;margin-top:-50px;">
<h2>✏️ Text selection mode</h2>

<p>When you click the bubble, the page will enter <strong>selection mode</strong>, applying a faint color to the background.<br />
As you move the cursor, <strong>editable elements</strong> containing text will be highlighted, including:</p>

<ul>
	<li>Single-line <u>text boxes</u> (<em>forms</em>).</li>
	<li>Multi-line <u>text areas</u> (<em>textarea in forms</em>).</li>
	<li>Content within <u>rich editors</u> like <strong>CKEditor</strong> (e.g., in <em>notes or emails</em>).</li>
	<li><u>Visible texts</u> on screen: titles, paragraphs, list items, etc.</li>
</ul>

<p>👉 Clicking on one of these elements will open the <strong>transformation dialog box</strong> for the selected text.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_03_apply-text-transformation_EN.png" style="max-width:100%;" /></p>
</div>

<div class="block">
<p>In fact, there are 4 text selection modes on the page:</p>

<ul>
	<li><strong>SINGLE-CLICK SELECTION</strong>, to select <u>a single</u> text container element (paragraph, textarea, editor, table cell, etc.)</li>
	<li><strong>DRAG-AND-DROP SELECTION</strong>, to select <u>multiple elements</u> on the page (for example, several rows of a table).</li>
	<li><strong>CONTAINER SELECTION</strong> (with <em>SHIFT+CLICK</em>), to select <u>an entire table, section, or complete list of items</u>.</li>
	<li><strong>EMPTY SELECTION</strong> (by clicking on an empty area of the page), to be able to <u>manually enter the text</u> to process (!!).</li>
</ul>
</div>

<h3 id="sec_selection_by_drag">DRAG-AND-DROP SELECTION</h3>

<ul>
	<li>If after <u>clicking</u> for example on a non-empty cell in a table and <u>dragging up or down</u>, we can select multiple rows of a table, though not necessarily all of them. <u>Upon releasing the mouse button</u>, the dialog box to configure the transformation will open.</li>
	<li>The same can be used to choose a few items from a bulleted list, instead of just one.</li>
</ul>

<h3 id="sec_selection_of_containers">CONTAINER SELECTION</h3>

<p>However, if we want to select an entire table, or an entire bulleted list, or an entire section of the page, then we do this:</p>

<ol>
	<li>place the mouse cursor inside that &quot;zone&quot;</li>
	<li>press the SHIFT key on the keyboard</li>
	<li>move the mouse sideways or up or down so that the container of that element is highlighted</li>
	<li>if we move outside that container, we can highlight the next container, even the entire page</li>
	<li>when</li>
</ol>

<p>⚠️ <strong><u>Note</u>:</strong> this selector captures all the HTML contained in the selected zone, and that sometimes includes quite a bit of CSS or even javascript... which will also be sent by the module to the LLM to be processed. The prompt already includes the instruction to &quot;not touch&quot; (or &quot;ignore&quot;) CSS and javascript and only translate/transform the &quot;visible text&quot;. But I have noticed that when selecting too many elements from the page, the LLM gets confused, takes longer, and sometimes doesn&#39;t respond. So consider this selection mode as something &quot;experimental&quot; for now.</p>

<h3 id="sec_selection_empty">EMPTY SELECTION for FREE EDITING</h3>

<p>This selection mode is interesting:</p>

<ol>
	<li>move the mouse until it is positioned over an &quot;empty text zone&quot;</li>
	<li>this will cause no element on the page to be &quot;highlighted&quot;</li>
	<li>then click with the mouse</li>
	<li>and the dialog box to specify the transformation we want will open</li>
	<li>but... now the &quot;preview&quot; box for the selected text no longer appears, and in its place we have a multi-line text box where we must write (or paste) the text we want to edit.</li>
</ol>

<p>I often use this selection mode while working with other apps that are not Dolibarr and I need a quick text editor/translator. And as you know, AI Writer is a fast assistant to use.</p>

<div id="section_transformation_options" style="padding-top:100px;margin-top:-50px;">
<h2>⚙️ Text transformation options</h2>

<ul>
	<li>The dialog box offers multiple text enhancement and formatting options.</li>
	<li>You can select a <strong>predefined transformation</strong> or write a <strong>custom instruction</strong>.</li>
</ul>

<h3 id="sec_preset_transformations">Predefined transformation types</h3>

<ul style="list-style-type: none;line-height: 2em;">
	<li>✨&nbsp;<strong>Improve writing</strong>&nbsp;&mdash; corrects grammar and style.</li>
	<li>🌍 <strong>Translate to another language</strong> &mdash; select desired language and tone.</li>
	<li>✂️&nbsp;<strong>Summarize</strong> &mdash; creates brief and clear versions.</li>
	<li>📈 <strong>Extend or expand</strong>&nbsp;&mdash; develops ideas or adds more context.</li>
	<li>🤓 <strong>Simplify technical language</strong>&nbsp;&mdash; useful for complex texts or non-specialized audiences.</li>
	<li>👔 <strong>Make more formal</strong>&nbsp;&mdash; ideal for reports or executive emails.</li>
	<li>💬 <strong>Make more casual</strong>&nbsp;&mdash; for informal messages or social media.</li>
	<li>⚙️ <strong>Custom instruction</strong>&nbsp;&mdash; freely combine any adjustments (see next section).</li>
</ul>

<h3 id="sec_preset_languages">Available predefined languages</h3>

<ul style="list-style-type: none;  line-height: 2em;">
	<li>The module includes direct translation to:&nbsp;<strong>English, French, Spanish, German, Italian, Portuguese, Catalan, Dutch, Russian, Chinese, and Japanese.</strong></li>
	<li>📌 If you need another language, select the <u>Custom instruction</u>&nbsp;option and indicate it manually.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_04_transformations_and_languages_EN.png" style="max-width:100%;" /></p>

<h3 id="sec_additional_options">Additional options</h3>

<ul style="line-height: 2em;">
	<li><strong>Emojis</strong>: automatically inserts them at the beginning or end of each paragraph.&nbsp;<br />
	Perfect for social media, messaging, or modern emails.</li>
	<li><strong>Hashtags</strong>: generates tags (#) at the beginning, end, or interspersed in the text.<br />
	Very useful for posts on LinkedIn, X, or Instagram.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_05_add_emojis_and_hashtags_EN.png" style="max-width:100%;" /></p>

<p>&nbsp;</p>

<h3 id="sec_custom_transformation">Custom transformation</h3>

<ul>
	<li>The &quot;<u>Custom instruction</u>&quot; transformation unleashes the full potential of AI.</li>
	<li>It allows you to write any natural prompt, combining actions or rules according to your needs.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_06_custom_prompt_EN.png" style="max-width:100%;" /></p>

<p><strong>Usage examples:</strong></p>

<ul>
	<li>&quot;<em>Summarize in a single paragraph, and in Hungarian.</em>&quot;</li>
	<li>&quot;<em>Correct grammatically, simplify technical terms, and add an apology for the delay.</em>&quot;</li>
	<li>&quot;<em>Exclude non-technical items from the list, keep only financial ones, and draft in basic English.</em>&quot;</li>
</ul>

<p>This option is ideal for advanced writers or specialized tasks where every word matters.</p>
</div>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h2>Installation process</h2>

<p>First, as usual when installing any Dolibarr module:</p>

<ol>
	<li>Go to the <u>Configuration</u> section</li>
	<li>Go to <u>Modules</u></li>
	<li>Go to the <u>Install external module</u> tab, and there you upload the module ZIP or its update</li>
	<li>Return to the <u>Available modules</u> tab</li>
	<li><u>Filter by Origin</u>: &quot;External - IMASDEWEB&quot;</li>
	<li><u>Activate</u> the module</li>
</ol>
</div>

<div id="section_AI_providers" style="padding-top:100px;margin-top:-50px;">
<h2>Configuration and integration with AI providers</h2>

<ol>
	<li>Enter the &quot;<u>API key</u>&quot; for at least one of the providers</li>
	<li>After saving changes, you must select the LLM model from that provider you want to use by default.</li>
</ol>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_01_LLM-settings_EN.png" style="max-width:100%;" /></p>

<p><strong>Note:</strong></p>

<ul>
	<li>You must obtain the API key from the provider&#39;s platform; it is usually <u>pay-per-use</u>, typically you add credit to your account with them (starting with $5 USD is enough)</li>
	<li>Sometimes when adding the provider&#39;s key in the module configuration, its models are not activated. In this case, simply refresh the page</li>
	<li>In the future, it is planned to add the possibility to choose different models and/or LLM providers for different tasks, because some types of transformation are quite simple to process and any model/provider can perform them at a very minimal cost, but some transformation processes require using a more expensive model to achieve healthier results. That is, sometimes we need a &quot;mediocre&quot; translation for ourselves, but other times we need it to be excellent (to publish or send to a client). Therefore, being able to choose the model/provider to use in each case, savings can easily be 4-10x !!</li>
</ul>
</div>

<div id="section_AI_writer_benefits" style="padding-top:100px;margin-top:-50px;">
<h2>💎 Benefits of the AI Writer module</h2>

<table style="width:auto;margin:1.2rem auto;">
	<tbody>
		<tr>
			<td style="padding:2em 3em;line-height:3em;">🚀 <strong>Save time</strong>&nbsp;writing, translating, or correcting without copying and pasting.<br />
			🧩 <strong>100% integrated into Dolibarr</strong>, accessible from any module or view.<br />
			🤖 <strong>Compatible with major AI providers</strong>, choose your preferred one.<br />
			✨&nbsp;<strong>Consistent and customizable results</strong>, tailored to your style.<br />
			🌐 <strong>Ideal for multilingual teams</strong>, marketing, support, or document management.<br />
			🔄 <strong>Instant transformations</strong>, without leaving the workflow.</td>
		</tr>
	</tbody>
</table>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Manuel de l'utilisateur du module AI Writer</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=116</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=116</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Thu, 19 Feb 2026 22:31:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/116.jpg" style="display: block; margin: 1em auto" /></p><p>AI Writer est un assistant d'intelligence artificielle intégré à Dolibarr qui vous aide à traiter le texte de manière contextuelle. Il permet de résumer, traduire, améliorer la rédaction, changer le ton ou appliquer des transformations personnalisées instantanément.<br /><br />
<br /><br />
Compatible avec les principales plateformes d'IA : Mistral, DeepSeek, Anthropic et OpenAI.<br /><br />
De plus, il mémorise vos préférences pour maintenir un flux de travail agile et continu.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/116.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p><u>AI Writer</u> est un assistant d&#39;intelligence artificielle int&eacute;gr&eacute; &agrave; Dolibarr qui vous aide &agrave; traiter du texte de mani&egrave;re contextuelle.</p>

<ul>
	<li>Il vous permet de <em>r&eacute;sumer</em>, <em>traduire</em>, <em>am&eacute;liorer la r&eacute;daction</em>, <em>changer le ton</em>, ou appliquer des <em>transformations personnalis&eacute;es</em> instantan&eacute;ment.</li>
	<li>Compatible avec les principales plateformes d&#39;IA : <strong>Mistral, DeepSeek, Anthropic et OpenAI</strong>.</li>
	<li>De plus, il <em>m&eacute;morise vos pr&eacute;f&eacute;rences</em> pour maintenir un flux de travail agile et continu. ⚡</li>
</ul>
</div>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-Writer_benefits_FR.png" style="max-width:100%;" /></p>

<h3>Index</h3>

<p>Si vous n&#39;&ecirc;tes pas un utilisateur administrateur dans votre Dolibarr, vous pouvez passer directement au point 3 de ce manuel.</p>

<ol>
	<li><a href="#section_bubble">💬 Bulle flottante sur toutes les pages</a></li>
	<li><a href="#section_selection_mode">✏️ Mode s&eacute;lection de texte</a>
	<ul>
		<li><a href="#sec_selection_by_drag">S&eacute;lection par glisser-d&eacute;poser</a></li>
		<li><a href="#sec_selection_of_containers">S&eacute;lection de conteneurs</a></li>
		<li><a href="#sec_selection_empty">S&eacute;lection vide pour &eacute;dition libre</a></li>
	</ul>
	</li>
	<li><a href="#section_transformation_options">⚙️ Options de transformation de texte</a>
	<ul>
		<li><a href="#sec_preset_transformations">Types de transformations pr&eacute;d&eacute;finies</a></li>
		<li><a href="#sec_preset_languages">Langues pr&eacute;d&eacute;finies disponibles</a></li>
		<li><a href="#sec_additional_options">Options suppl&eacute;mentaires</a> (emojis &amp; hashtags)</li>
		<li><a href="#sec_custom_transformation">Transformation personnalis&eacute;e</a></li>
	</ul>
	</li>
	<li><a href="#section_install">Processus d&#39;installation</a></li>
	<li><a href="#section_AI_providers">Configuration et int&eacute;gration avec les fournisseurs d&#39;IA</a></li>
	<li><a href="#section_AI_writer_benefits">💎 Avantages du module AI Writer</a></li>
</ol>

<div id="section_bubble" style="padding-top:100px;margin-top:-50px;">
<h2>💬 Bulle flottante sur toutes les pages</h2>

<p>Une fois le module install&eacute; et configur&eacute; (voir la section <u>Installation et Configuration</u> &agrave; la fin de ce guide), une <strong>bulle cliquable</strong> appara&icirc;tra dans le coin inf&eacute;rieur droit de toutes les pages Dolibarr.</p>

<p>Cette bulle est la porte d&#39;entr&eacute;e vers les fonctions de l&#39;assistant IA.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_02_magic-buble-to-fire-assistant_FR.png" style="max-width:100%;" /></p>
</div>

<div id="section_selection_mode" style="padding-top:100px;margin-top:-50px;">
<h2>✏️ Mode s&eacute;lection de texte</h2>

<p>Lorsque vous cliquez sur la bulle, la page passe en <strong>mode s&eacute;lection</strong>, appliquant une l&eacute;g&egrave;re coloration au fond.<br />
En d&eacute;pla&ccedil;ant le curseur, les <strong>&eacute;l&eacute;ments modifiables</strong> contenant du texte seront mis en surbrillance, notamment :</p>

<ul>
	<li>Les <u>champs de texte</u> sur une ligne (<em>formulaires</em>).</li>
	<li>Les <u>zones de texte</u> multilignes (<em>textarea dans les formulaires</em>).</li>
	<li>Le contenu des <u>&eacute;diteurs enrichis</u> comme <strong>CKEditor</strong> (par ex., dans les <em>notes ou emails</em>).</li>
	<li>Les <u>textes visibles</u> &agrave; l&#39;&eacute;cran : titres, paragraphes, &eacute;l&eacute;ments de liste, etc.</li>
</ul>

<p>👉 Cliquer sur l&#39;un de ces &eacute;l&eacute;ments ouvrira la <strong>bo&icirc;te de dialogue de transformation</strong> pour le texte s&eacute;lectionn&eacute;.</p>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_03_apply-text-transformation_FR.png" style="max-width:100%;" /></p>
</div>

<div class="block">
<p>En effet, il existe 4 modes de s&eacute;lection de texte sur la page :</p>

<ul>
	<li><strong>S&Eacute;LECTION PAR UN CLIC</strong>, pour s&eacute;lectionner <u>un seul &eacute;l&eacute;ment</u> conteneur de texte (paragraphe, textarea, &eacute;diteur, cellule d&#39;un tableau, etc.)</li>
	<li><strong>S&Eacute;LECTION PAR GLISSER-D&Eacute;POSER</strong>, pour s&eacute;lectionner <u>plusieurs &eacute;l&eacute;ments</u> de la page (par exemple, plusieurs lignes d&#39;un tableau).</li>
	<li><strong>S&Eacute;LECTION DE CONTENEUR</strong> (avec <em>MAJ+CLIC</em>), pour s&eacute;lectionner <u>un tableau entier, une section ou une liste d&#39;&eacute;l&eacute;ments</u>&nbsp;compl&egrave;te.</li>
	<li><strong>S&Eacute;LECTION VIDE</strong>&nbsp;(en cliquant sur une zone vide de la page), pour pouvoir <u>saisir manuellement le texte</u> &agrave; traiter (!!).</li>
</ul>
</div>

<h3 id="sec_selection_by_drag">S&Eacute;LECTION PAR GLISSER-D&Eacute;POSER</h3>

<ul>
	<li>Si apr&egrave;s avoir <u>cliqu&eacute;</u> par exemple sur une cellule non vide d&#39;un tableau et que nous <u>glissons vers le bas ou vers le haut</u>, nous pourrons s&eacute;lectionner plusieurs lignes d&#39;un tableau, bien que pas n&eacute;cessairement toutes. <u>En rel&acirc;chant la souris</u>, la bo&icirc;te de dialogue pour configurer la transformation s&#39;ouvrira.</li>
	<li>La m&ecirc;me chose peut &ecirc;tre utilis&eacute;e pour choisir quelques &eacute;l&eacute;ments d&#39;une liste &agrave; puces, au lieu d&#39;un seul.</li>
</ul>

<h3 id="sec_selection_of_containers">S&Eacute;LECTION DE CONTENEURS</h3>

<p>Cependant, si nous voulons s&eacute;lectionner un tableau entier, ou toute une liste &agrave; puces ou toute une section de la page, alors nous ferons ceci :</p>

<ol>
	<li>placer le curseur de la souris &agrave; l&#39;int&eacute;rieur de cette &quot;zone&quot;</li>
	<li>appuyer sur la touche MAJ du clavier</li>
	<li>d&eacute;placer la souris sur les c&ocirc;t&eacute;s ou vers le haut ou le bas pour que le conteneur de cet &eacute;l&eacute;ment soit mis en &eacute;vidence</li>
	<li>si nous nous d&eacute;pla&ccedil;ons en dehors de ce conteneur, nous pourrons mettre en &eacute;vidence le conteneur suivant, voire toute la page</li>
	<li>lorsque&nbsp;</li>
</ol>

<p>⚠️&nbsp;<strong><u>Note</u> :</strong>&nbsp;ce s&eacute;lecteur r&eacute;cup&egrave;re tout le HTML contenu dans la zone s&eacute;lectionn&eacute;e, et cela inclut parfois beaucoup de code CSS ou m&ecirc;me javascript... qui sera &eacute;galement envoy&eacute; par le module au LLM pour &ecirc;tre trait&eacute;. L&#39;instruction de &quot;ne pas toucher&quot; (ou &quot;ignorer&quot;) le CSS et le javascript et de ne traduire/transformer que le &quot;texte visible&quot; est d&eacute;j&agrave; pr&eacute;sente dans le prompt. Mais j&#39;ai remarqu&eacute; qu&#39;en s&eacute;lectionnant trop d&#39;&eacute;l&eacute;ments de la page, le LLM se trompe, prend du temps et parfois ne r&eacute;pond pas. Consid&eacute;rez donc ce mode de s&eacute;lection comme quelque chose d&#39;&quot;exp&eacute;rimental&quot; pour le moment.</p>

<h3 id="sec_selection_empty">S&Eacute;LECTION VIDE pour &Eacute;DITION LIBRE</h3>

<p>Ce mode de s&eacute;lection est int&eacute;ressant :</p>

<ol>
	<li>d&eacute;placez la souris jusqu&#39;&agrave; la placer dans une &quot;zone vide de texte&quot;</li>
	<li>cela fera qu&#39;aucun &eacute;l&eacute;ment de la page ne sera &quot;surlign&eacute;&quot;</li>
	<li>alors cliquez avec la souris</li>
	<li>et la bo&icirc;te de dialogue pour indiquer la transformation que nous voulons s&#39;ouvrira</li>
	<li>mais... maintenant le cadre de &quot;pr&eacute;visualisation&quot; du texte s&eacute;lectionn&eacute; n&#39;appara&icirc;t plus et &agrave; sa place nous avons une zone de texte multiligne o&ugrave; nous devons &eacute;crire (ou coller) le texte que nous souhaitons &eacute;diter.</li>
</ol>

<p>J&#39;utilise souvent ce mode de s&eacute;lection lorsque je travaille avec d&#39;autres applications qui ne sont pas Dolibarr et que j&#39;ai besoin d&#39;un &eacute;diteur/traducteur de texte rapide. Et comme vous le savez, AI Writer est un assistant rapide &agrave; utiliser.</p>

<div id="section_transformation_options" style="padding-top:100px;margin-top:-50px;">
<h2>⚙️ Options de transformation de texte</h2>

<ul>
	<li>La bo&icirc;te de dialogue propose plusieurs options d&#39;am&eacute;lioration et de mise en forme du texte.</li>
	<li>Vous pouvez s&eacute;lectionner une <strong>transformation pr&eacute;d&eacute;finie</strong> ou &eacute;crire une <strong>instruction personnalis&eacute;e</strong>.</li>
</ul>

<h3 id="sec_preset_transformations">Types de transformations pr&eacute;d&eacute;finies</h3>

<ul style="list-style-type: none;line-height: 2em;">
	<li>✨&nbsp;<strong>Am&eacute;liorer la r&eacute;daction</strong>&nbsp;&mdash; corrige la grammaire et le style.</li>
	<li>🌍 <strong>Traduire dans une autre langue</strong> &mdash; s&eacute;lectionnez la langue et le ton souhait&eacute;s.</li>
	<li>✂️&nbsp;<strong>R&eacute;sumer</strong> &mdash; cr&eacute;e des versions br&egrave;ves et claires.</li>
	<li>📈 <strong>&Eacute;tendre ou d&eacute;velopper</strong>&nbsp;&mdash; d&eacute;veloppe les id&eacute;es ou ajoute plus de contexte.</li>
	<li>🤓 <strong>Simplifier le langage technique</strong>&nbsp;&mdash; utile pour les textes complexes ou un public non sp&eacute;cialis&eacute;.</li>
	<li>👔 <strong>Rendre plus formel</strong>&nbsp;&mdash; id&eacute;al pour les rapports ou les emails ex&eacute;cutifs.</li>
	<li>💬 <strong>Rendre plus d&eacute;contract&eacute;</strong>&nbsp;&mdash; pour les messages informels ou les r&eacute;seaux sociaux.</li>
	<li>⚙️ <strong>Instruction personnalis&eacute;e</strong>&nbsp;&mdash; combinez librement tous les ajustements (voir section suivante).</li>
</ul>

<h3 id="sec_preset_languages">Langues pr&eacute;d&eacute;finies disponibles</h3>

<ul style="list-style-type: none;  line-height: 2em;">
	<li>Le module inclut la traduction directe vers :&nbsp;<strong>l&#39;anglais, le fran&ccedil;ais, l&#39;espagnol, l&#39;allemand, l&#39;italien, le portugais, le catalan, le n&eacute;erlandais, le russe, le chinois et le japonais.</strong></li>
	<li>📌 Si vous avez besoin d&#39;une autre langue, s&eacute;lectionnez l&#39;option <u>Instruction personnalis&eacute;e</u>&nbsp;et indiquez-la manuellement.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_04_transformations_and_languages_FR.png" style="max-width:100%;" /></p>

<h3 id="sec_additional_options">Options suppl&eacute;mentaires</h3>

<ul style="line-height: 2em;">
	<li><strong>Emojis</strong> : les ins&egrave;re automatiquement au d&eacute;but ou &agrave; la fin de chaque paragraphe.&nbsp;<br />
	Parfait pour les r&eacute;seaux sociaux, la messagerie ou les emails modernes.</li>
	<li><strong>Hashtags</strong> : g&eacute;n&egrave;re des balises (#) au d&eacute;but, &agrave; la fin ou ins&eacute;r&eacute;es dans le texte.<br />
	Tr&egrave;s utile pour les publications sur LinkedIn, X ou Instagram.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_05_add_emojis_and_hashtags_FR.png" style="max-width:100%;" /></p>

<p>&nbsp;</p>

<h3 id="sec_custom_transformation">Transformation personnalis&eacute;e</h3>

<ul>
	<li>La transformation &quot;<u>Instruction personnalis&eacute;e</u>&quot; lib&egrave;re tout le potentiel de l&#39;IA.</li>
	<li>Elle vous permet d&#39;&eacute;crire n&#39;importe quelle instruction naturelle, combinant actions ou r&egrave;gles selon vos besoins.</li>
</ul>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_06_custom_prompt_FR.png" style="max-width:100%;" /></p>

<p><strong>Exemples d&#39;utilisation :</strong></p>

<ul>
	<li>&quot;<em>R&eacute;sumez en un seul paragraphe, et en hongrois.</em>&quot;</li>
	<li>&quot;<em>Corrigez grammaticalement, simplifiez les termes techniques, et ajoutez des excuses pour le retard.</em>&quot;</li>
	<li>&quot;<em>Excluez les &eacute;l&eacute;ments non techniques de la liste, ne gardez que les financiers, et r&eacute;digez en anglais basique.</em>&quot;</li>
</ul>

<p>Cette option est id&eacute;ale pour les r&eacute;dacteurs avanc&eacute;s ou les t&acirc;ches sp&eacute;cialis&eacute;es o&ugrave; chaque mot compte.</p>
</div>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h2>Processus d&#39;installation</h2>

<p>Premi&egrave;rement, comme d&#39;habitude lors de l&#39;installation de tout module Dolibarr :</p>

<ol>
	<li>Allez dans la section <u>Configuration</u></li>
	<li>Allez dans <u>Modules</u></li>
	<li>Allez dans l&#39;onglet <u>Installer un module externe</u>, et l&agrave; vous t&eacute;l&eacute;versez le ZIP du module ou sa mise &agrave; jour</li>
	<li>Retournez &agrave; l&#39;onglet <u>Modules disponibles</u></li>
	<li><u>Filtrez par Origine</u> : &quot;Externe - IMASDEWEB&quot;</li>
	<li><u>Activez</u> le module</li>
</ol>
</div>

<div id="section_AI_providers" style="padding-top:100px;margin-top:-50px;">
<h2>Configuration et int&eacute;gration avec les fournisseurs d&#39;IA</h2>

<ol>
	<li>Entrez la &quot;<u>cl&eacute; API</u>&quot; pour au moins l&#39;un des fournisseurs</li>
	<li>Apr&egrave;s avoir sauvegard&eacute; les modifications, vous devez s&eacute;lectionner le mod&egrave;le LLM de ce fournisseur que vous souhaitez utiliser par d&eacute;faut.</li>
</ol>

<p style="text-align:center;"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2026/AI-WRITER_01_LLM-settings_FR.png" style="max-width:100%;" /></p>

<p><strong>Note :</strong></p>

<ul>
	<li>Vous devez obtenir la cl&eacute; API depuis la plateforme du fournisseur ; elle est g&eacute;n&eacute;ralement <u>payante &agrave; l&#39;usage</u>, typiquement vous ajoutez du cr&eacute;dit &agrave; votre compte chez eux (commencer avec 5 $ US suffit)</li>
	<li>Parfois, lors de l&#39;ajout de la cl&eacute; du fournisseur dans la configuration du module, ses mod&egrave;les ne sont pas activ&eacute;s. Dans ce cas, il suffit de rafra&icirc;chir la page</li>
	<li>&Agrave; l&#39;avenir, il est pr&eacute;vu d&#39;ajouter la possibilit&eacute; de choisir diff&eacute;rents mod&egrave;les et/ou fournisseurs LLM pour diff&eacute;rentes t&acirc;ches, car certains types de transformation sont assez simples &agrave; traiter et n&#39;importe quel mod&egrave;le/fournisseur peut les ex&eacute;cuter &agrave; un co&ucirc;t tr&egrave;s minime, mais certains processus de transformation n&eacute;cessitent d&#39;utiliser un mod&egrave;le plus co&ucirc;teux pour obtenir des r&eacute;sultats plus sains. C&#39;est-&agrave;-dire que parfois nous avons besoin d&#39;une traduction &quot;m&eacute;diocre&quot; pour nous-m&ecirc;mes, mais d&#39;autres fois nous avons besoin qu&#39;elle soit excellente (pour publier ou envoyer &agrave; un client). Par cons&eacute;quent, pouvoir choisir le mod&egrave;le/fournisseur &agrave; utiliser dans chaque cas, les &eacute;conomies peuvent facilement &ecirc;tre de 4 &agrave; 10 fois !!</li>
</ul>
</div>

<div id="section_AI_writer_benefits" style="padding-top:100px;margin-top:-50px;">
<h2>💎 Avantages du module AI Writer</h2>

<table style="width:auto;margin:1.2rem auto;">
	<tbody>
		<tr>
			<td style="padding:2em 3em;line-height:3em;">🚀 <strong>Gagnez du temps</strong>&nbsp;en &eacute;crivant, traduisant ou corrigeant sans copier-coller.<br />
			🧩 <strong>100% int&eacute;gr&eacute; &agrave; Dolibarr</strong>, accessible depuis n&#39;importe quel module ou vue.<br />
			🤖 <strong>Compatible avec les principaux fournisseurs d&#39;IA</strong>, choisissez celui que vous pr&eacute;f&eacute;rez.<br />
			✨&nbsp;<strong>R&eacute;sultats coh&eacute;rents et personnalisables</strong>, adapt&eacute;s &agrave; votre style.<br />
			🌐 <strong>Id&eacute;al pour les &eacute;quipes multilingues</strong>, marketing, support ou gestion documentaire.<br />
			🔄 <strong>Transformations instantan&eacute;es</strong>, sans quitter le flux de travail.</td>
		</tr>
	</tbody>
</table>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>NotePlus Module User Guide</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=111</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=111</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Sat, 27 Dec 2025 16:58:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/111.jpg" style="display: block; margin: 1em auto" /></p><p>This module enhances Dolibarr’s native notes functionality by allowing unlimited, highly secure notes to be added to nearly any ERP element. It features AES-256 encryption, personal or shared keys, PBKDF2 password management, and multi-company compatibility.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/111.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>This module enhances Dolibarr&rsquo;s native notes functionality by allowing unlimited, highly secure notes to be added to nearly any ERP element. It features&nbsp;<em>AES-256 encryption</em>, personal or shared keys,&nbsp;<em>PBKDF2 password management</em>, and&nbsp;<em>multi-company compatibility</em>.</p>

<div class="a_c"><a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=112">Guide en fran&ccedil;ais</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=111">Guide in english</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=110">Gu&iacute;a en espa&ntilde;ol</a></div>

<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">I am interested in accessing the DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_14_3375' action='index.php?pag=m_contactos&gad=formulario&id=14'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='14' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>I am interested to test Dolibarr DEMO</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Which module are you most interested in? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login and Country Filter								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login and Country Filter"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI Assistants								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="AI Assistants"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus and HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus and HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Editable lists								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Editable lists"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Purchases								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Purchases"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Annual billing charts								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Annual billing charts"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								StockTransfers								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="StockTransfers"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Search For Help in Forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Search For Help in Forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								 Mexican CFDI								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value=" Mexican CFDI"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								All								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="All"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>What is your preferred language? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Your email address *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Your name *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comment (optional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_22217' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_22217').html('<br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' />2<br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /> + <br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' />7<br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /><br style=\'display:none;\' rel=\'464\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_77246' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_77246' name='captcha_formstamp' value='YzB0eVprOTBielJYZUVSRVRYRm9NVGxGV25OSWMxVkhkM05DTjJOcGVGSjBZM2xxVUZBclVXc3phejA2T21NeFpERTNZVEU1TlRBMU1qTmpZVFU1TjJJME5HSTVaVEExWlRReU5ETXg' />
    <input type='hidden' id='captcha_valid_77246' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_77246').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_77246();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_77246').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_77246').val('');
                    $('#captcha_answer_77246').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_77246').val())+'&captcha_answer='+($('#captcha_answer_77246').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_77246').val(data.valid);
                    $('#captcha_answer_77246').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_77246').addClass('valid_captcha');
                    else
                        $('#captcha_answer_77246').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_77246(){
        if($('#captcha_answer_77246').val() == ''
                || $('#captcha_valid_77246').val()!='1'){

            $('#captcha_answer_77246').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_77246').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_14_3375();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_14_3375(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_14_3375');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_14_3375').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/NotePlus_features_en.jpg" /></p>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h3>Unlimited Notes for Every Element</h3>

<ul>
	<li>
	<p>Add an <em>unlimited</em> number of notes to each element.</p>
	</li>
	<li>
	<p>Each note includes a <em>title and content</em>.</p>
	</li>
	<li>
	<p>The system logs the <em>date and user</em> of the last modification:</p>
	</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/001-unlimited-notes_en.png" style="max-width: 100%;" /></p>

<h3>Elements Supporting NotePlus Notes</h3>

<ul>
	<li>The &quot;Note+&quot; tab will appear in the following Dolibarr elements:<br />
	<em>Products, services, customers, suppliers, contacts, members, users, projects, contracts, quotes, customer orders, supplier orders, customer invoices, supplier invoices, calendar events, Bills of Materials (BOM), manufacturing orders, workstations, and tickets.</em><br />
	&nbsp;</li>
	<li>Some of these elements (e.g., calendar events) <u>do not have Dolibarr&rsquo;s native</u> &quot;Private Note&quot; or &quot;Public Note&quot; options:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/002-notes-on-agenda-event_en.png" style="max-width: 100%;" /></p>


<h3>Use of Markdown Format</h3>

<p>In unencrypted notes, it will be very useful for you to use "simple Markdown formatting" to make your notes much more readable and able to include elements such as tables, links, images, numbered lists, bold text, etc.</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2026/noteplus-006_markdown_en.png" style="max-width:100%;" /></p>

<p style="text-align:center;"><i class="fa fa-info-circle">&nbsp;</i>&nbsp; At the end of this article there is a <a href="#markdown">QUICK MARKDOWN GUIDE</a>.</p>

<h3>Optional Note Encryption</h3>

<ul>
	<li>You can <u>optionally encrypt</u> note content.</li>
	<li>The module generates a&nbsp;<u>random 256-bit key</u>.</li>
	<li>The system prompts the user for an &quot;<em>unlock key</em>&quot;.</li>
	<li>This key is <u>not stored</u> in the database.</li>
	<li><strong>If lost or forgotten, encrypted data cannot be recovered.<br />
	&nbsp;</strong></li>
	<li>Adding encrypted notes is simple:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/003-encrypted-notes_en.gif" style="max-width: 100%;" /></p>

<ul>
	<li>To access encrypted note content, only <u>the unlock key is required</u>:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/004-decrypt-note_en.png" style="max-width: 100%;" /></p>

<h3>Personal Keys vs. Shared Keys&nbsp;</h3>

<ul>
	<li>Each user can create&nbsp;<u>as many encryption keys as needed</u>.</li>
	<li>Users can also create&nbsp;<u>shared keys</u> for team access.</li>
	<li>When using <u>personal keys</u>: Only the creator can decrypt notes</li>
	<li>When using <u>shared keys</u>: Any user with the key can decrypt notes.</li>
	<li>Each user manages their own keys:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/005-manage_encryption-keys_en.gif" style="max-width: 100%;" /></p>

<p><strong>Shared Note Considerations:</strong></p>

<ul>
	<li>When a user marks a key as <u>SHARED</u>, others can use it to encrypt notes with the <u>same unlock key</u>, enabling secure collaboration.</li>
	<li><u>Only the key creator</u>&nbsp;can modify or delete it (!!).</li>
</ul>

<h3>Technical Considerations</h3>

<p><strong>Secure Key Storage</strong></p>

<ul>
	<li>Encryption keys are <u>256-bit (64 hex characters)</u>, generated using PHP&rsquo;s `openssl_random_pseudo_bytes()` with a unique salt. Example:<br />
	<code style="word-wrap: break-word!important;">e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</code></li>
	<li>The key is stored in the database <u>encrypted with AES-256</u>, using the user&rsquo;s unlock key (which is typically weak). To strengthen it, the system applies <u>PBKDF2 with 600,000 iterations and a unique salt</u>&mdash;double the OWASP 2025 recommendation (!!).</li>
	<li>Notes are encrypted using the <u>256-bit key</u>&nbsp;also via <u>AES-256</u>.<br />
	&nbsp;<br />
	⚠️ <strong>Performance Note:</strong> Encryption/decryption may add <em>~0.5 seconds</em>&nbsp;(depends on server power).<br />
	&nbsp;</li>
</ul>

<p><strong>Encryption Recommendations</strong></p>

<p>While PBKDF2 hardening makes brute-force attacks difficult, we recommend:</p>

<ol>
	<li><u>Avoid reusing keys</u>&mdash;use different keys for different purposes to limit exposure.</li>
	<li><u>Use strong unlock keys</u>&mdash;avoid short or dictionary-based passwords. Instead, use <em>mixed case, numbers, and symbols</em>. If using words, make them a <em>long, nonsensical phrase</em>.</li>
</ol>

<p><strong>Change Tracking</strong></p>

<p>Currently, only the **last modification time and user** are logged. A full **change log** may be added in the future if demand exists.</p>

<p><strong>Multi-Company Compatibility</strong></p>

<ul>
	<li>Notes added to a company&rsquo;s elements are **only visible within that company**.</li>
	<li>Keys created by a user are **only accessible when working in that company**.</li>
</ul>

<h3>Installation Process</h3>

<p>Follow the standard Dolibarr module installation steps:</p>

<ol>
	<li>Go to <u>Configuration</u> &rarr; <u>Modules</u>.</li>
	<li>Navigate to the &quot;<u>Install External Module</u>&quot; tab and upload the module&rsquo;s ZIP file.</li>
	<li>Return to the &quot;<u>Available Modules</u>&quot; tab.</li>
	<li>Filter by Origin: &quot;<u>External - IMASDEWEB</u>&quot;.</li>
	<li><u>Activate the module</u>.</li>
</ol>

<p><img alt="" src="https://imasdeweb.com/UserFiles/Image/2025/NotePlus_install_en.jpg" /></p>
</div>

<p id="markdown">&nbsp;</p>

<h2>Appendix: Quick Markdown Formatting Guide</h2>

<div class="block">
<p>Imagine you&#39;re writing a text message or a note, and you want to highlight some words to make them appear bold, italic, or as a large title. Normally, in programs like Word, you click on buttons to apply those styles.</p>

<p>Markdown is like a <u>keyboard shortcut for styling text</u>, but <u>using simple symbols instead of buttons</u>. It was created so that anyone can format text quickly and readably, even if they&#39;re just writing in a simple notepad.</p>

<p><u>Many platforms recognize it automatically</u>: WhatsApp, Telegram, Discord, forums, blogs (like Medium), and even note-taking apps like Obsidian or Notion.</p>
</div>

<h3>Headers</h3>

<p>Use <code>#</code> symbols to create headers (1-6 levels):</p>

<pre>
<code># H1 - Main Title
## H2 - Section
### H3 - Subsection</code></pre>

<h3>Text Formatting</h3>

<ul>
	<li><strong>Bold text</strong>: <code>**bold**</code> or <code>__bold__</code></li>
	<li><em>Italic text</em>: <code>*italic*</code> or <code>_italic_</code></li>
	<li><strong><em>Bold and italic</em></strong>: <code>***text***</code></li>
	<li><del>Strikethrough</del>: <code>~~strikethrough~~</code></li>
	<li><code>Inline code</code>: <code>`code`</code></li>
</ul>

<h3>Links</h3>

<p>Create hyperlinks with <code>[text](URL)</code>:</p>

<pre>
<code>[OpenAI](https://openai.com)</code></pre>

<p>Result: <a href="https://openai.com" target="_blank">OpenAI</a></p>

<h3>Images</h3>

<p>Insert images using <code>![alt text](image-url)</code>:</p>

<pre>
<code>![Logo](https://example.com/ubuntu.png)</code></pre>

<p><img alt="" src="https://imasdeweb.com/https://imasdeweb.com/UserFiles/Image/linux-distros/ubuntu.png" /></p>

<h3>Quotes</h3>

<blockquote>
<p>Single-level quote using <code>&gt;</code></p>

<blockquote>
<p>Nested quote using <code>&gt;&gt;</code></p>
</blockquote>

<p>Continuation...</p>
</blockquote>

<p>Using this:</p>

<pre>
<code>&gt; Single-level quote using `&gt;`
&gt;&gt; Nested quote using `&gt;&gt;`
&gt;
&gt; Continuation...</code></pre>

<h3>Lists</h3>

<h4>Unordered Lists</h4>

<p>Use <code>-</code>, <code>*</code>, or <code>+</code> for bullets:</p>

<pre>
<code>- First item
- Second item
 - Nested item (indented with TAB character)
 - Another nested item
- Third item</code></pre>

<h4>Ordered Lists</h4>

<p>Use numbers followed by periods:</p>

<pre>
<code>1. First item
2. Second item
3. Third item</code></pre>

<h3>Code Blocks</h3>

<h4>Inline Code</h4>

<p>Use single backticks: <code>`code here`</code></p>

<h4>Code Blocks</h4>

<p>Use triple backticks with optional language identifier:</p>

<pre>
<code>```php
$variable = &quot;Hello World&quot;;
echo $variable;
```</code></pre>

<h3>Horizontal Rules</h3>

<p>Create dividers with <code>---</code>, <code>***</code>, or <code>___</code>:</p>

<hr />
<h3>Tables</h3>

<p>Create tables using pipes <code>|</code> and dashes <code>-</code>:</p>

<pre>
<code>| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Data 1 | Data 2 | Data 3 |
| Data 4 | Data 5 | Data 6 |</code></pre>

<p>Result:</p>

<table>
	<thead>
		<tr>
			<th>Column 1</th>
			<th>Column 2</th>
			<th>Column 3</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>Data 1</td>
			<td>Data 2</td>
			<td>Data 3</td>
		</tr>
		<tr>
			<td>Data 4</td>
			<td>Data 5</td>
			<td>Data 6</td>
		</tr>
	</tbody>
</table>

<h3>Task Lists</h3>

<p>Create checkboxes with <code>- [ ]</code> or <code>- [x]</code>:</p>

<pre>
<code>[x] Completed task
[ ] Pending task
[ ] Another pending task</code></pre>

<p>Result:<br />
<input checked="checked" disabled="disabled" readonly="readonly" type="checkbox" /> Completed task<br />
<input disabled="disabled" readonly="readonly" type="checkbox" /> Pending task<br />
<input disabled="disabled" readonly="readonly" type="checkbox" /> Another pending task</p>

<h3>Escaping Special Characters</h3>

<p>If you need to include characters in your text that Markdown uses for formatting, you can &quot;escape&quot; them by placing a backslash <code>\</code> as a prefix:</p>

<table>
	<thead>
		<tr>
			<th>Character</th>
			<th>Name</th>
			<th>Example</th>
			<th>Result</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><code>\\</code></td>
			<td>backslash</td>
			<td><code>\\</code></td>
			<td>\</td>
		</tr>
		<tr>
			<td><code>\*</code></td>
			<td>asterisk</td>
			<td><code>\*text\*</code></td>
			<td>*text*</td>
		</tr>
		<tr>
			<td><code>\_</code></td>
			<td>underscore</td>
			<td><code>\_text\_</code></td>
			<td>_text_</td>
		</tr>
		<tr>
			<td><code>\{ \}</code></td>
			<td>curly braces</td>
			<td><code>\{code\}</code></td>
			<td>{code}</td>
		</tr>
		<tr>
			<td><code>\[ \]</code></td>
			<td>square brackets</td>
			<td><code>\[text\]</code></td>
			<td>[text]</td>
		</tr>
		<tr>
			<td><code>\&lt; \&gt;</code></td>
			<td>less than/greater than</td>
			<td><code>\</code></td>
			<td>\</td>
		</tr>
		<tr>
			<td><code>\( \)</code></td>
			<td>parentheses</td>
			<td><code>\(note\)</code></td>
			<td>(note)</td>
		</tr>
		<tr>
			<td><code>\#</code></td>
			<td>hash/pound</td>
			<td><code>\# not a title</code></td>
			<td># not a title</td>
		</tr>
		<tr>
			<td><code>\+</code></td>
			<td>plus</td>
			<td><code>\+ item</code></td>
			<td>+ item</td>
		</tr>
		<tr>
			<td><code>\-</code></td>
			<td>hyphen</td>
			<td><code>\- not a list</code></td>
			<td>- not a list</td>
		</tr>
		<tr>
			<td><code>\.</code></td>
			<td>period</td>
			<td><code>1\. not a list</code></td>
			<td>1. not a list</td>
		</tr>
		<tr>
			<td><code>\!</code></td>
			<td>exclamation</td>
			<td><code>\!\[not an image\]</code></td>
			<td>![not an image]</td>
		</tr>
		<tr>
			<td><code>\|</code></td>
			<td>pipe</td>
			<td><code>\| not a table \|</code></td>
			<td>| not a table |</td>
		</tr>
	</tbody>
</table>

<h4>Common Use Cases</h4>

<pre>
<code>Without escaping: *italic* **bold** `code`
Escaped: \*asterisks\* \*\*stars\*\* \`backticks\`</code></pre>

<p>Result:</p>

<ul>
	<li>Without escaping: <em>italic</em> <strong>bold</strong> <code>code</code></li>
	<li>Escaped: *asterisks* **stars** `backticks`</li>
</ul>

<hr />
<p><strong>Note</strong>: Markdown rendering may vary depending on the platform (GitHub, GitLab, Reddit, Dolibarr, etc.).</p>
<style type="text/css">/* + + + MARKDOWN parsed to HTML + + + */

    /* `inline & block code` */
    .blog_post_body code{background-color:#8882;} 
    /* ```only block code``` */
    .blog_post_body pre{max-width:100%;}
    .blog_post_body pre code{
        display:block;
        padding:1em;
        border-left:10px #8888 solid;
        max-width: 100%;
        overflow-x: auto;
        font-family:ui-monospace,SFMono-Regular,'SF Mono',Menlo,Consolas,'Liberation Mono',monospace!important;
    } 
    /* blockquote */
    .blog_post_body blockquote{
        display:block;
        padding:0.5em 1.5em;
        margin-left: 1em;
        border-left:5px #8886 solid;
        background-color: #8881;
        max-width: 100%;
        font-style: italic;
        overflow-x: auto;
    } 
    /* table */
    .blog_post_body  > table{
        border-collapse:collapse!important;
    } 
    /* table thead */
    .blog_post_body  > table thead{
        background-color: #8882 !important;
    }
    /* table tbody cells */
    .blog_post_body  table thead th,
    .blog_post_body  table tbody td{
        border:1px #8885 solid!important;padding:0.3em 0.5em!important;
    }
    /* checkbox */
    .blog_post_body input[type=checkbox]{
        float:none!important;
        opacity:1!important;
        display:inline-block!important;
        appearance:auto!important;
        margin-right:0.3em!important;
    }
    /* horizontal line */
    .blog_post_body hr{
        border-color: #8888 !important;
    }
</style>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">I am interested in accessing the DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_14_6669' action='index.php?pag=m_contactos&gad=formulario&id=14'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='14' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>I am interested to test Dolibarr DEMO</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Which module are you most interested in? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login and Country Filter								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login and Country Filter"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI Assistants								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="AI Assistants"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus and HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus and HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Editable lists								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Editable lists"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Purchases								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Purchases"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Annual billing charts								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Annual billing charts"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								StockTransfers								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="StockTransfers"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Search For Help in Forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Search For Help in Forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								 Mexican CFDI								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value=" Mexican CFDI"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								All								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="All"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>What is your preferred language? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Your email address *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Your name *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comment (optional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_26291' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_26291').html('<br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' />1<br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /> + <br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' />9<br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /><br style=\'display:none;\' rel=\'4184\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_39996' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_39996' name='captcha_formstamp' value='Vm5nMVVXNTJNRXB6Tm5OeWFrOTVhMm92WW1GaVRGSnZWRFJYZDJ0NFZHeFNNalpFVHpaS1ozUnNXVDA2T2pFM01XVTRZVFJqTVdZMlltUTNNbVEyTUdZNU1qQTNNV0ZrTXpJNFpXRmw' />
    <input type='hidden' id='captcha_valid_39996' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_39996').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_39996();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_39996').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_39996').val('');
                    $('#captcha_answer_39996').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_39996').val())+'&captcha_answer='+($('#captcha_answer_39996').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_39996').val(data.valid);
                    $('#captcha_answer_39996').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_39996').addClass('valid_captcha');
                    else
                        $('#captcha_answer_39996').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_39996(){
        if($('#captcha_answer_39996').val() == ''
                || $('#captcha_valid_39996').val()!='1'){

            $('#captcha_answer_39996').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_39996').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_14_6669();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_14_6669(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_14_6669');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_14_6669').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Manuel d'utilisation du module NotePlus</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=112</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=112</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Sat, 27 Dec 2025 17:25:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/112.jpg" style="display: block; margin: 1em auto" /></p><p>Ce module étend la fonctionnalité native de notes dans Dolibarr en permettant d’ajouter des notes illimitées et hautement sécurisées à presque n’importe quel élément de l’ERP. Il intègre un chiffrement AES 256 bits, des clés personnelles ou partagées, une gestion des mots de passe via PBKDF2 et une compatibilité multi-entreprise.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/112.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>Ce module &eacute;tend la fonctionnalit&eacute; native de notes dans <em>Dolibarr</em>&nbsp;en permettant d&rsquo;ajouter des <em>notes illimit&eacute;es et hautement s&eacute;curis&eacute;es</em>&nbsp;&agrave; presque n&rsquo;importe quel &eacute;l&eacute;ment de l&rsquo;ERP. Il int&egrave;gre un <em>chiffrement AES 256 bits</em>, des <em>cl&eacute;s personnelles ou partag&eacute;es</em>, une <em>gestion des mots de passe via PBKDF2</em>&nbsp;et une <em>compatibilit&eacute; multi-entreprise</em>.</p>

<div class="a_c"><a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=112">Guide en fran&ccedil;ais</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=111">Guide in english</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=110">Gu&iacute;a en espa&ntilde;ol</a></div>

<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Je suis intéressé à accéder à la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_17_3714' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_74120' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_74120').html('<br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' />0<br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /> + <br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' />9<br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /><br style=\'display:none;\' rel=\'51\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_47343' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_47343' name='captcha_formstamp' value='YTFaS1lVOVBSMDR5UVZrNFkzSnVOems1UkdzMlNUWklaRFZCVFc1MFdVSnBlRWQ0UlRsRlRrd3JjejA2T2pWak5qVXhNbVJoT0RnNVlURm1ZbVl6WkRsbFpEVTVZVEJtWm1ZMFpXTTQ' />
    <input type='hidden' id='captcha_valid_47343' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_47343').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_47343();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_47343').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_47343').val('');
                    $('#captcha_answer_47343').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_47343').val())+'&captcha_answer='+($('#captcha_answer_47343').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_47343').val(data.valid);
                    $('#captcha_answer_47343').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_47343').addClass('valid_captcha');
                    else
                        $('#captcha_answer_47343').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_47343(){
        if($('#captcha_answer_47343').val() == ''
                || $('#captcha_valid_47343').val()!='1'){

            $('#captcha_answer_47343').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_47343').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_3714();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_3714(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_3714');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_3714').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/NotePlus_features_fr.jpg" /></p>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h3>Notes illimit&eacute;es pour chaque &eacute;l&eacute;ment</h3>

<ul>
	<li>Vous pouvez ajouter&nbsp;<u>un nombre illimit&eacute; de notes</u> &agrave; chaque &eacute;l&eacute;ment.</li>
	<li>Chaque note dispose de&nbsp;<u>son propre titre et contenu</u>.</li>
	<li>Le syst&egrave;me enregistre&nbsp;<u>la date et l&rsquo;utilisateur</u> ayant effectu&eacute; la derni&egrave;re modification&nbsp;:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/001-unlimited-notes_fr.png" style="max-width: 100%;" /></p>

<h3>&Eacute;l&eacute;ments compatibles avec NotePlus</h3>

<ul>
	<li>Vous trouverez l&rsquo;onglet &laquo;<em> Note+ </em>&raquo; sur les &eacute;l&eacute;ments suivants de Dolibarr&nbsp;: Produits, Services, Clients, Fournisseurs, Contacts, Membres, Utilisateurs, Projets, Contrats, Devis, Commandes clients, Commandes fournisseurs, Factures clients, Factures fournisseurs, &Eacute;v&eacute;nements du calendrier (Agenda), Nomenclatures (Bill of Materials), Ordres de fabrication, Postes de travail, Tickets.<br />
	&nbsp;</li>
	<li>Certains de ces &eacute;l&eacute;ments (comme les <em>&eacute;v&eacute;nements de l&rsquo;Agenda</em>) <u>n&rsquo;ont pas</u>&nbsp;la fonctionnalit&eacute; native de Dolibarr permettant d&rsquo;ajouter une &laquo; <em>Note priv&eacute;e</em> &raquo; ou une &laquo; <em>Note publique</em> &raquo;. NotePlus comble cette lacune !&nbsp;:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/002-notes-on-agenda-event_fr.png" style="max-width: 100%;" /></p>

<h3>Utilisation du format Markdown</h3>

<p>Dans les notes non chiffr&eacute;es, il vous sera tr&egrave;s utile d&#39;utiliser le &quot;formatage Markdown simple&quot; pour rendre vos notes beaucoup plus lisibles et pouvoir inclure des &eacute;l&eacute;ments tels que des tableaux, des liens, des images, des listes num&eacute;rot&eacute;es, du texte en gras, etc.</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2026/noteplus-006_markdown_fr.png" style="max-width:100%;" /></p>

<p style="text-align:center;"><i class="fa fa-info-circle">&nbsp;</i>&nbsp; &Agrave; la fin de cet article se trouve un <a href="#markdown">GUIDE RAPIDE DE MARKDOWN</a>.</p>

<h3>Notes chiffr&eacute;es (optionnel)</h3>

<p>Vous avez la possibilit&eacute; de **chiffrer le contenu des notes** pour une s&eacute;curit&eacute; renforc&eacute;e.</p>

<p><strong>Comment &ccedil;a marche ?</strong></p>

<ol>
	<li>Le module g&eacute;n&egrave;re une <u>cl&eacute; al&eacute;atoire de 256 bits</u>&nbsp;(64 caract&egrave;res hexad&eacute;cimaux).</li>
	<li>Le syst&egrave;me vous demande une &laquo; <u>cl&eacute; de d&eacute;verrouillage</u> &raquo; (mot de passe).<br />
	<br />
	⚠️ Cette cl&eacute; n&rsquo;est jamais stock&eacute;e en base de donn&eacute;es.<br />
	⚠️ Si vous la perdez ou l&rsquo;oubliez, vous perdrez l&rsquo;acc&egrave;s aux donn&eacute;es chiffr&eacute;es !<br />
	&nbsp;</li>
	<li>Pour <u>acc&eacute;der au contenu d&rsquo;une note chiffr&eacute;e</u>, il suffit de conna&icirc;tre la cl&eacute; de d&eacute;verrouillage.</li>
</ol>

<p><strong>Exemple d&rsquo;utilisation :</strong></p>

<ul>
	<li>Vous cr&eacute;ez une note sensible sur un client et la chiffrez avec une cl&eacute; personnelle :</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/003-encrypted-notes_fr.gif" style="max-width: 100%;" /></p>

<ul>
	<li>Seul vous (ou ceux avec qui vous partagez la cl&eacute;) pourrez la lire :&nbsp;</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/004-decrypt-note_fr.png" style="max-width: 100%;" /></p>

<h3>Cl&eacute;s personnelles vs. cl&eacute;s partag&eacute;es</h3>

<p><strong>Cl&eacute;s personnelles</strong></p>

<ul>
	<li>Chaque utilisateur peut cr&eacute;er autant de cl&eacute;s de chiffrement qu&rsquo;il le souhaite.</li>
	<li>Les notes chiffr&eacute;es avec une cl&eacute; personnelle ne sont <u>d&eacute;verrouillables que par leur cr&eacute;ateur</u>.</li>
</ul>

<p><strong>Cl&eacute;s partag&eacute;es</strong></p>

<ul>
	<li>Un utilisateur peut aussi cr&eacute;er des cl&eacute;s partag&eacute;es pour permettre &agrave; d&rsquo;autres utilisateurs d&rsquo;acc&eacute;der aux notes chiffr&eacute;es.</li>
	<li>Les notes chiffr&eacute;es avec une cl&eacute; partag&eacute;e sont accessibles &agrave; <u>tous ceux qui connaissent la cl&eacute; de d&eacute;verrouillage</u>.</li>
</ul>

<p><strong>Gestion des cl&eacute;s</strong></p>

<ul>
	<li>Chaque utilisateur g&egrave;re **ses propres cl&eacute;s** (personnelles et partag&eacute;es).</li>
	<li>Seul le cr&eacute;ateur d&rsquo;une cl&eacute; partag&eacute;e peut la modifier ou la supprimer.</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/005-manage_encryption-keys_fr.gif" style="max-width: 100%;" /></p>

<p><strong>Cas d&rsquo;usage des cl&eacute;s partag&eacute;es :</strong></p>

<ul>
	<li>Un utilisateur cr&eacute;e une cl&eacute; partag&eacute;e et la marque comme &laquo; PARTAG&Eacute;E &raquo;.</li>
	<li>D&rsquo;autres utilisateurs peuvent alors <u>l&rsquo;utiliser pour chiffrer des notes</u>, en utilisant toujours la m&ecirc;me cl&eacute; de d&eacute;verrouillage.</li>
	<li>Cela permet de **partager des informations chiffr&eacute;es entre diff&eacute;rentes &eacute;quipes** de l&rsquo;entreprise.</li>
</ul>

<p>⚠️&nbsp;<strong>Attention :</strong></p>

<ul>
	<li>Seul le cr&eacute;ateur de la cl&eacute; peut la modifier ou la supprimer.</li>
	<li>Si un utilisateur quitte l&rsquo;entreprise, il faut **changer la cl&eacute; partag&eacute;e** pour &eacute;viter tout acc&egrave;s non autoris&eacute;.</li>
</ul>

<h3>Consid&eacute;rations techniques</h3>

<p><strong>Stockage robuste des cl&eacute;s de chiffrement</strong></p>

<ul>
	<li>Les cl&eacute;s de chiffrement des notes sont de 256 bits (64 caract&egrave;res hexad&eacute;cimaux) g&eacute;n&eacute;r&eacute;es al&eacute;atoirement &agrave; l&rsquo;aide de l&rsquo;algorithme openssl_random_pseudo_bytes() de PHP, en utilisant un &quot;salt&quot; unique. Elles ressemblent &agrave; cet exemple&nbsp;:<br />
	<code style="word-wrap: break-word!important;">e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</code></li>
	<li>Cette cl&eacute; de chiffrement est stock&eacute;e dans la base de donn&eacute;es apr&egrave;s avoir &eacute;t&eacute; chiffr&eacute;e avec l&rsquo;algorithme AES 256 bits, de niveau militaire, en utilisant comme cl&eacute; de chiffrement la &quot;cl&eacute; de d&eacute;verrouillage&quot; fournie par l&rsquo;utilisateur, qui est g&eacute;n&eacute;ralement assez faible. Pour cette raison, le syst&egrave;me la renforce en appliquant l&rsquo;<u>algorithme PBKDF2 avec 600 000 it&eacute;rations</u> et un &quot;salt&quot; al&eacute;atoire unique. Cela <u>d&eacute;passe largement les recommandations OWASP</u> pour 2025 (!!).<br />
	&nbsp;<br />
	<strong>Note :</strong> pour cette raison, vous remarquerez peut-&ecirc;tre que lors du chiffrement/d&eacute;chiffrement d&rsquo;une cl&eacute; ou d&rsquo;une note, votre Dolibarr peut prendre environ <em>0,5 seconde de plus</em> (selon la puissance de votre serveur).<br />
	&nbsp;</li>
	<li>Enfin, les notes sont chiffr&eacute;es &agrave; l&rsquo;aide de cette cl&eacute; de 256 bits mentionn&eacute;e au premier point, en utilisant &agrave; nouveau l&rsquo;algorithme AES 256 bits.<br />
	&nbsp;&nbsp;</li>
	<li>Ainsi, m&ecirc;me si quelqu&rsquo;un pouvait acc&eacute;der &agrave; une sauvegarde de votre base de donn&eacute;es, il lui faudrait un effort computationnel consid&eacute;rable pour mener une attaque par force brute.&nbsp;</li>
</ul>

<p><strong>Recommandations concernant le chiffrement</strong></p>

<p>Ce syst&egrave;me, qui utilise une version &quot;renforc&eacute;e avec PBKDF2&quot;, rend tr&egrave;s difficile la r&eacute;ussite d&rsquo;une attaque par force brute. Cependant, il est recommand&eacute; :</p>

<ol>
	<li><u>Ne mettez pas tous vos &oelig;ufs dans le m&ecirc;me panier</u>. Utilisez des cl&eacute;s diff&eacute;rentes pour diff&eacute;rents &quot;sujets&quot;. Cela augmentera toujours la difficult&eacute; pour un attaquant, qu&rsquo;il tente une attaque par force brute ou que l&rsquo;une de vos cl&eacute;s soit compromise via des techniques d&#39;&quot;ing&eacute;nierie sociale&quot;.<br />
	&nbsp;</li>
	<li><u>Utilisez des cl&eacute;s de verrouillage robustes</u>. &Eacute;vitez les cl&eacute;s de d&eacute;verrouillage trop courtes ou bas&eacute;es sur des mots du dictionnaire. &Agrave; la place : combinez majuscules et minuscules, incluez des signes de ponctuation et des chiffres. Si vous pr&eacute;f&eacute;rez utiliser des mots &quot;du dictionnaire&quot;, optez pour une phrase longue compos&eacute;e de mots &quot;sans lien apparent&quot;.</li>
</ol>

<p><strong>Tra&ccedil;abilit&eacute; minimale des modifications</strong></p>

<p>Pour le moment, seule la minute et l&rsquo;utilisateur ayant effectu&eacute; la derni&egrave;re modification sur une note sont enregistr&eacute;s. &Agrave; l&rsquo;avenir, un journal des changements (LOG) pourrait &ecirc;tre ajout&eacute;, s&rsquo;il existe un int&eacute;r&ecirc;t pour une fonctionnalit&eacute; de ce type.</p>

<p><strong>Compatibilit&eacute; avec la multi-soci&eacute;t&eacute;</strong></p>

<p>Les notes ajout&eacute;es &agrave; un &eacute;l&eacute;ment d&rsquo;une soci&eacute;t&eacute; ne sont visibles que pour cette soci&eacute;t&eacute;. De plus, les cl&eacute;s qu&rsquo;un utilisateur cr&eacute;e dans une soci&eacute;t&eacute; ne sont accessibles que lorsqu&rsquo;il op&egrave;re au sein de cette m&ecirc;me soci&eacute;t&eacute;.</p>

<h3>Processus d&rsquo;installation</h3>

<p>Comme pour tout module Dolibarr, suivez ces &eacute;tapes :</p>

<ol>
	<li>Allez dans&nbsp;<u>Configuration</u> &rarr;&nbsp;<u>Modules</u>.</li>
	<li>S&eacute;lectionnez l&rsquo;onglet &laquo; <u>Installer un module externe</u> &raquo;.</li>
	<li>T&eacute;l&eacute;chargez le&nbsp;<u>fichier ZIP</u> du module (ou son update).</li>
	<li>Retournez dans l&rsquo;onglet &laquo; <u>Modules disponibles</u> &raquo;.</li>
	<li>Filtrez par Origine : &laquo; <u>Externe - IMASDEWEB</u> &raquo;.</li>
	<li><u>Activez le module</u> NotePlus</li>
</ol>

<p><img alt="" src="https://imasdeweb.com/UserFiles/Image/2025/NotePlus_install_fr.jpg" /></p>

<p id="markdown">&nbsp;</p>

<h2>Annexe : Guide rapide de formatage avec Markdown</h2>

<div class="block">
<p>Imaginez que vous &eacute;crivez un message texte ou une note, et vous voulez mettre en &eacute;vidence certains mots pour qu&#39;ils apparaissent en gras, en italique ou comme un grand titre. Normalement, dans des programmes comme Word, vous cliquez sur des boutons pour appliquer ces styles.</p>

<p>Markdown est comme un <u>raccourci clavier pour styliser le texte</u>, mais <u>en utilisant des symboles simples au lieu de boutons</u>. Il a &eacute;t&eacute; cr&eacute;&eacute; pour que n&#39;importe qui puisse formater du texte rapidement et de mani&egrave;re lisible, m&ecirc;me en &eacute;crivant dans un simple bloc-notes.</p>

<p><u>De nombreuses plateformes le reconnaissent automatiquement</u> : WhatsApp, Telegram, Discord, forums, blogs (comme Medium), et m&ecirc;me dans des applications de notes comme Obsidian ou Notion.</p>
</div>

<h3>Titres</h3>

<p>Utilisez les symboles <code>#</code> pour cr&eacute;er des titres (1-6 niveaux) :</p>

<pre>
<code># H1 - Titre principal
## H2 - Section
### H3 - Sous-section</code></pre>

<h3>Formatage de texte</h3>

<ul>
	<li><strong>Texte en gras</strong> : <code>**gras**</code> ou <code>__gras__</code></li>
	<li><em>Texte en italique</em> : <code>*italique*</code> ou <code>_italique_</code></li>
	<li><strong><em>Gras et italique</em></strong> : <code>***texte***</code></li>
	<li><del>Barr&eacute;</del> : <code>~~barr&eacute;~~</code></li>
	<li><code>Code en ligne</code> : <code>`code`</code></li>
</ul>

<h3>Liens</h3>

<p>Cr&eacute;ez des hyperliens avec <code>[texte](URL)</code> :</p>

<pre>
<code>[OpenAI](https://openai.com)</code></pre>

<p>R&eacute;sultat : <a href="https://openai.com" target="_blank">OpenAI</a></p>

<h3>Images</h3>

<p>Ins&eacute;rez des images en utilisant <code>![texte alternatif](url-image)</code> :</p>

<pre>
<code>![Logo](https://example.com/ubuntu.png)</code></pre>

<p><img alt="" src="https://imasdeweb.com/https://imasdeweb.com/UserFiles/Image/linux-distros/ubuntu.png" /></p>

<h3>Citations</h3>

<blockquote>
<p>Citation simple en utilisant <code>&gt;</code></p>

<blockquote>
<p>Citation imbriqu&eacute;e en utilisant <code>&gt;&gt;</code></p>
</blockquote>

<p>Suite...</p>
</blockquote>

<p>En utilisant ceci :</p>

<pre>
<code>&gt; Citation simple en utilisant `&gt;`
&gt;&gt; Citation imbriqu&eacute;e en utilisant `&gt;&gt;`
&gt;
&gt; Suite...</code></pre>

<h3>Listes</h3>

<h4>Listes non ordonn&eacute;es</h4>

<p>Utilisez <code>-</code>, <code>*</code>, ou <code>+</code> pour les puces :</p>

<pre>
<code>- Premier &eacute;l&eacute;ment
- Deuxi&egrave;me &eacute;l&eacute;ment
 - &Eacute;l&eacute;ment imbriqu&eacute; (indent&eacute; avec le caract&egrave;re TAB)
 - Autre &eacute;l&eacute;ment imbriqu&eacute;
- Troisi&egrave;me &eacute;l&eacute;ment</code></pre>

<h4>Listes ordonn&eacute;es</h4>

<p>Utilisez des nombres suivis de points :</p>

<pre>
<code>1. Premier &eacute;l&eacute;ment
2. Deuxi&egrave;me &eacute;l&eacute;ment
3. Troisi&egrave;me &eacute;l&eacute;ment</code></pre>

<h3>Blocs de code</h3>

<h4>Code en ligne</h4>

<p>Utilisez des backticks simples : <code>`code ici`</code></p>

<h4>Blocs de code</h4>

<p>Utilisez des triples backticks avec un identifiant de langage optionnel :</p>

<pre>
<code>```php
$variable = &quot;Bonjour Monde&quot;;
echo $variable;
```</code></pre>

<h3>R&egrave;gles horizontales</h3>

<p>Cr&eacute;ez des s&eacute;parateurs avec <code>---</code>, <code>***</code>, ou <code>___</code> :</p>

<hr />
<h3>Tableaux</h3>

<p>Cr&eacute;ez des tableaux en utilisant des &quot;pipes&quot; <code>|</code> et des tirets <code>-</code> :</p>

<pre>
<code>| Colonne 1 | Colonne 2 | Colonne 3 |
|----------|----------|----------|
| Donn&eacute;es 1 | Donn&eacute;es 2 | Donn&eacute;es 3 |
| Donn&eacute;es 4 | Donn&eacute;es 5 | Donn&eacute;es 6 |</code></pre>

<p>R&eacute;sultat :</p>

<table>
	<thead>
		<tr>
			<th>Colonne 1</th>
			<th>Colonne 2</th>
			<th>Colonne 3</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>Donn&eacute;es 1</td>
			<td>Donn&eacute;es 2</td>
			<td>Donn&eacute;es 3</td>
		</tr>
		<tr>
			<td>Donn&eacute;es 4</td>
			<td>Donn&eacute;es 5</td>
			<td>Donn&eacute;es 6</td>
		</tr>
	</tbody>
</table>

<h3>Listes de t&acirc;ches</h3>

<p>Cr&eacute;ez des cases &agrave; cocher avec <code>- [ ]</code> ou <code>- [x]</code> :</p>

<pre>
<code>[x] T&acirc;che termin&eacute;e
[ ] T&acirc;che en attente
[ ] Autre t&acirc;che en attente</code></pre>

<p>R&eacute;sultat :<br />
<input checked="checked" disabled="disabled" readonly="readonly" type="checkbox" /> T&acirc;che termin&eacute;e<br />
<input disabled="disabled" readonly="readonly" type="checkbox" /> T&acirc;che en attente<br />
<input disabled="disabled" readonly="readonly" type="checkbox" /> Autre t&acirc;che en attente</p>

<h3>&Eacute;chapper les caract&egrave;res sp&eacute;ciaux</h3>

<p>Si vous devez inclure dans votre texte des caract&egrave;res que Markdown utilise pour le formatage, vous pouvez les &quot;&eacute;chapper&quot; en pla&ccedil;ant une barre oblique inverse <code>\</code> comme pr&eacute;fixe :</p>

<table>
	<thead>
		<tr>
			<th>Caract&egrave;re</th>
			<th>Nom</th>
			<th>Exemple</th>
			<th>R&eacute;sultat</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><code>\\</code></td>
			<td>barre oblique inverse</td>
			<td><code>\\</code></td>
			<td>\</td>
		</tr>
		<tr>
			<td><code>\*</code></td>
			<td>ast&eacute;risque</td>
			<td><code>\*texte\*</code></td>
			<td>*texte*</td>
		</tr>
		<tr>
			<td><code>\_</code></td>
			<td>tiret bas</td>
			<td><code>\_texte\_</code></td>
			<td>_texte_</td>
		</tr>
		<tr>
			<td><code>\{ \}</code></td>
			<td>accolades</td>
			<td><code>\{code\}</code></td>
			<td>{code}</td>
		</tr>
		<tr>
			<td><code>\[ \]</code></td>
			<td>crochets</td>
			<td><code>\[texte\]</code></td>
			<td>[texte]</td>
		</tr>
		<tr>
			<td><code>\&lt; \&gt;</code></td>
			<td>inf&eacute;rieur/sup&eacute;rieur &agrave;</td>
			<td><code>\</code></td>
			<td>\</td>
		</tr>
		<tr>
			<td><code>\( \)</code></td>
			<td>parenth&egrave;ses</td>
			<td><code>\(note\)</code></td>
			<td>(note)</td>
		</tr>
		<tr>
			<td><code>\#</code></td>
			<td>di&egrave;se</td>
			<td><code>\# pas un titre</code></td>
			<td># pas un titre</td>
		</tr>
		<tr>
			<td><code>\+</code></td>
			<td>plus</td>
			<td><code>\+ &eacute;l&eacute;ment</code></td>
			<td>+ &eacute;l&eacute;ment</td>
		</tr>
		<tr>
			<td><code>\-</code></td>
			<td>tiret</td>
			<td><code>\- pas une liste</code></td>
			<td>- pas une liste</td>
		</tr>
		<tr>
			<td><code>\.</code></td>
			<td>point</td>
			<td><code>1\. pas une liste</code></td>
			<td>1. pas une liste</td>
		</tr>
		<tr>
			<td><code>\!</code></td>
			<td>point d&#39;exclamation</td>
			<td><code>\!\[pas une image\]</code></td>
			<td>![pas une image]</td>
		</tr>
		<tr>
			<td><code>\|</code></td>
			<td>pipe</td>
			<td><code>\| pas un tableau \|</code></td>
			<td>| pas un tableau |</td>
		</tr>
	</tbody>
</table>

<h4>Cas d&#39;utilisation courants</h4>

<pre>
<code>Sans &eacute;chappement : *italique* **gras** `code`
&Eacute;chapp&eacute; : \*ast&eacute;risques\* \*\*&eacute;toiles\*\* \`backticks\`</code></pre>

<p>R&eacute;sultat :</p>

<ul>
	<li>Sans &eacute;chappement : <em>italique</em> <strong>gras</strong> <code>code</code></li>
	<li>&Eacute;chapp&eacute; : *ast&eacute;risques* **&eacute;toiles** `backticks`</li>
</ul>

<hr />
<p><strong>Note</strong> : le rendu Markdown peut varier selon la plateforme (GitHub, GitLab, Reddit, Dolibarr, etc.).</p>
</div>
<style type="text/css">/* + + + MARKDOWN parsed to HTML + + + */

    /* `inline & block code` */
    .blog_post_body code{background-color:#8882;} 
    /* ```only block code``` */
    .blog_post_body pre{max-width:100%;}
    .blog_post_body pre code{
        display:block;
        padding:1em;
        border-left:10px #8888 solid;
        max-width: 100%;
        overflow-x: auto;
        font-family:ui-monospace,SFMono-Regular,'SF Mono',Menlo,Consolas,'Liberation Mono',monospace!important;
    } 
    /* blockquote */
    .blog_post_body blockquote{
        display:block;
        padding:0.5em 1.5em;
        margin-left: 1em;
        border-left:5px #8886 solid;
        background-color: #8881;
        max-width: 100%;
        font-style: italic;
        overflow-x: auto;
    } 
    /* table */
    .blog_post_body  > table{
        border-collapse:collapse!important;
    } 
    /* table thead */
    .blog_post_body  > table thead{
        background-color: #8882 !important;
    }
    /* table tbody cells */
    .blog_post_body  table thead th,
    .blog_post_body  table tbody td{
        border:1px #8885 solid!important;padding:0.3em 0.5em!important;
    }
    /* checkbox */
    .blog_post_body input[type=checkbox]{
        float:none!important;
        opacity:1!important;
        display:inline-block!important;
        appearance:auto!important;
        margin-right:0.3em!important;
    }
    /* horizontal line */
    .blog_post_body hr{
        border-color: #8888 !important;
    }
</style>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Je suis intéressé à accéder à la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_17_6238' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_27378' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_27378').html('<br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' />0<br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /> + <br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' />1<br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /><br style=\'display:none;\' rel=\'1540\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_69385' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_69385' name='captcha_formstamp' value='TWxaU2JrWnNVV05GT0ZFemEwUlJWRzVQUkVRMFdIQTVZV2t4YlU1Vk1EbHZhV1I1ZW1nMFNWSTFiejA2T21VMk1XRTVNelkwWTJZM1lqVmtaR1l4TVdSbFlXWTVaV0UzT0dFME5XRmw' />
    <input type='hidden' id='captcha_valid_69385' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_69385').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_69385();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_69385').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_69385').val('');
                    $('#captcha_answer_69385').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_69385').val())+'&captcha_answer='+($('#captcha_answer_69385').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_69385').val(data.valid);
                    $('#captcha_answer_69385').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_69385').addClass('valid_captcha');
                    else
                        $('#captcha_answer_69385').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_69385(){
        if($('#captcha_answer_69385').val() == ''
                || $('#captcha_valid_69385').val()!='1'){

            $('#captcha_answer_69385').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_69385').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_6238();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_6238(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_6238');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_6238').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Manual de usuario del módulo NotePlus</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=110</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=110</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Fri, 26 Dec 2025 15:53:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/110.jpg" style="display: block; margin: 1em auto" /></p><p>Este módulo amplía la función nativa de notas en Dolibarr permitiendo agregar notas ilimitadas y altamente seguras a casi cualquier elemento del ERP, con cifrado AES de 256 bits y claves personales o compartidas, gestión de contraseñas mediante PBKDF2 y compatibilidad multi-company.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/110.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>Este m&oacute;dulo ampl&iacute;a la funci&oacute;n nativa de notas en Dolibarr permitiendo agregar notas ilimitadas y altamente seguras a casi cualquier elemento del ERP, con cifrado AES de 256 bits y claves personales o compartidas, gesti&oacute;n de contrase&ntilde;as mediante PBKDF2 y compatibilidad multi-company.</p>

<div class="a_c"><a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=112">Guide en fran&ccedil;ais</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=111">Guide in english</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=110">Gu&iacute;a en espa&ntilde;ol</a></div>

<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Me interesa acceder a la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_13_3580' action='index.php?pag=m_contactos&gad=formulario&id=13'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='13' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Me interesa probar la DEMO de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>¿Cuál módulo te interesa más? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login y Filtro por país								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login y Filtro por país"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Asistentes IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Asistentes IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus y HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus y HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listas editables								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Listas editables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Compras								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Compras"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferencia de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferencia de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Gráficos facturación anual								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Gráficos facturación anual"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Buscar ayuda en Foros								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Buscar ayuda en Foros"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI y contabilidad México								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI y contabilidad México"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Todos								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Todos"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>¿Cuál es tu idioma preferido? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Tu correo electrónico *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Tu nombre *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comentario (opcional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_62227' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_62227').html('<br style=\'display:none;\' rel=\'45\' /><br style=\'display:none;\' rel=\'45\' />0<br style=\'display:none;\' rel=\'45\' /><br style=\'display:none;\' rel=\'45\' /> + <br style=\'display:none;\' rel=\'45\' /><br style=\'display:none;\' rel=\'45\' />8<br style=\'display:none;\' rel=\'45\' /><br style=\'display:none;\' rel=\'45\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_52450' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_52450' name='captcha_formstamp' value='VEd4Wk1qVkJLekV5U1VKWlQzcFFObkUxTWpabWRXMXRaMjFWWlRsQ05DdFBjblp4ZVVRNVRtSm9hejA2T2pnd05qZGpOalprTUdJMVkyVXdNakJtWVdWaE1UazROMlpoWWpnNE5tTTM' />
    <input type='hidden' id='captcha_valid_52450' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_52450').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_52450();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_52450').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_52450').val('');
                    $('#captcha_answer_52450').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_52450').val())+'&captcha_answer='+($('#captcha_answer_52450').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_52450').val(data.valid);
                    $('#captcha_answer_52450').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_52450').addClass('valid_captcha');
                    else
                        $('#captcha_answer_52450').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_52450(){
        if($('#captcha_answer_52450').val() == ''
                || $('#captcha_valid_52450').val()!='1'){

            $('#captcha_answer_52450').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_52450').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_13_3580();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_13_3580(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_13_3580');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_13_3580').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/NotePlus_features_es.jpg" /></p>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h3>Notas ilimitadas para cada elemento</h3>

<ul>
	<li>Puedes agregar ilimitadas notas a cada elemento.</li>
	<li>Cada una con su t&iacute;tulo y contenido.</li>
	<li>El sistema recordar&aacute; la fecha y el usuario que hizo la &uacute;ltima modificaci&oacute;n:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/001-unlimited-notes_es.png" style="max-width:100%;" /></p>

<h3>Elementos que admiten notas de NotePlus</h3>

<ul>
	<li>Ver&aacute;s la pesta&ntilde;a &quot;Note+&quot; en estos elementos de Dolibarr: Productos, servicios, clientes, proveedores, contactos, miembros, usuarios, proyectos, contratos, cotizaciones, pedidos de cliente, pedidos a proveedor, facturas a clientes, facturas de proveedor, eventos de calendario, &quot;Bill of Materials&quot; (listas de materiales, &oacute;rdenes de manufactura, workstations, tickets.</li>
	<li>Algunos de los anteriores incluso <u>no tienen la opci&oacute;n nativa de Dolibarr</u> de agregar una &quot;Nota Privada&quot; y una &quot;Nota p&uacute;blica&quot;, como por ejemplo los eventos de la Agenda:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/002-notes-on-agenda-event_es.png" style="max-width:100%;" /></p>

<h3>Uso de formato Markdown</h3>

<p>En las notas no encriptadas te ser&aacute; muy &uacute;til usar el &quot;sencillo formato Markdown&quot; para que tus notas sean mucho m&aacute;s legibles y puedan incluir elementos como tablas, enlaces, im&aacute;genes, listas numeradas, negritas, etc.</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2026/noteplus-006_markdown_es.png" style="max-width:100%;" /></p>

<p style="text-align:center;"><i class="fa fa-info-circle">&nbsp;</i>&nbsp; Al final de este art&iacute;culo hay una <a href="#markdown">GU&Iacute;A R&Aacute;PIDA DE MARKDOWN</a>.</p>

<h3>Notas encriptadas, opcionalmente</h3>

<ul>
	<li>Opcionalmente puedes encriptar el contenido de las notas.</li>
	<li>Para ello el m&oacute;dulo genera una clave aleatoria de 256bits.</li>
	<li>El sistema solicita al usuario una &quot;clave de desbloqueo&quot;.</li>
	<li>Esta clave no se guarda en la base de datos.</li>
	<li>As&iacute; que si se pierde/olvida perder&aacute;s el acceso a los datos cifrados.</li>
	<li>Agregar notas encriptadas es muy sencillo:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/003-encrypted-notes_es.gif" style="max-width:100%;" /></p>

<ul>
	<li>Para acceder al contenido de una nota encriptada tan solo es necesario conocer la clave de desbloqueo:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/004-decrypt-note_es.png" style="max-width:100%;" /></p>

<h3>Claves personales vs. claves compartidas&nbsp;</h3>

<ul>
	<li>Cada usuario puede crear tantas claves de encriptaci&oacute;n como necesite.</li>
	<li>Pero tambi&eacute;n puede crear claves para compartir.</li>
	<li>Las notas encriptadas con claves personales solo ser&aacute;n desencriptables por el usuario que las cre&oacute;, mientras que las <u>encriptadas con claves compartidas est&aacute;n al acceso de cualquiera que conozca la clave</u>.</li>
	<li>Cada usuario gestiona sus propias claves:</li>
</ul>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2025/005-manage_encryption-keys_es.gif" style="max-width:100%;" /></p>

<p><strong>Consideraciones de notas compartidas:</strong></p>

<ul>
	<li>Cuando un usuario marca una clave creada por &eacute;l como COMPARTIDA entonces otros usuarios pueden usarla para crear notas encriptadas, usando siempre la misma clave de desbloqueo. De este modo se puede tener informaci&oacute;n encriptada por diferentes equipos de la empresa.</li>
	<li>El usuario que cre&oacute; esa clave es el &uacute;nico que puede modificarla o eliminarla (!!).</li>
</ul>

<h3>Consideraciones t&eacute;cnicas</h3>

<p><strong>Guardado robusto de las claves de cifrado</strong></p>

<ul>
	<li>Las claves de cifrado de las notas son de 256 bits (64 car&aacute;cteres hexadecimales) generadas aleatoriamente usando el algoritmo openssl_random_pseudo_bytes() de PHP, usando una &quot;salt&quot; &uacute;nica. Se ven como esta de ejemplo:<br />
	<code style="word-wrap: break-word!important;">e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</code><br />
	&nbsp;</li>
	<li>Esta clave de cifrado se guarda en la base de datos encript&aacute;ndola con el <u>algoritmo AES de 256bits</u>, de grado militar, usando como clave de encriptaci&oacute;n la &quot;clave de desbloqueo&quot; proporcionada por el usuario, que normalmente es bastante d&eacute;bil, y por esta raz&oacute;n el sistema la hace m&aacute;s poderosa aplicando el <u>algoritmo PBKDF2 con 600 mil iteraciones</u> y un &quot;salt&quot; aleatorio &uacute;nico. Esto&nbsp;<u>dobla la recomendaci&oacute;n OWASP</u> para 2025 (!!).<br />
	&nbsp;<br />
	<strong>Nota:</strong> por esta raz&oacute;n podr&aacute;s notar que al encriptar/desencriptar una clave o una nota, tu Dolibarr puede tardar aprox. 0.5 segundos de m&aacute;s (depende de la potencia de tu servidor).<br />
	&nbsp;</li>
	<li>Por &uacute;ltimo, las notas se encriptan usando esta clave de 256bits del primer punto, de nuevo usando el algoritmo AES de 256 bits.&nbsp;<br />
	&nbsp;</li>
	<li>As&iacute; que aunque alguien pudiera acceder a un backup de tu base de datos requerir&iacute;a demasiado esfuerzo computacional para un ataque de fuerza bruta.&nbsp;</li>
</ul>

<p><strong>Recomendaciones en cuanto al cifrado</strong></p>

<p>Este sistema usando una versi&oacute;n &quot;hardenizada con PBKDF2&quot; hace muy d&iacute;ficil el &eacute;xito de un ataque de fuerza bruta, pero se recomienda:</p>

<ol>
	<li><u>No pongas todas las manzanas en la misma cesta</u>. Usa diferentes claves para diferentes &quot;asuntos&quot;. Eso siempre aumentar&aacute; la dificultad para un atacante, ya sea que intente un ataque de fuerza bruta o ya sea que una de tus claves se vea comprometida por t&eacute;cnicas de &quot;hacking social&quot;.<br />
	&nbsp;</li>
	<li><u>Usa claves de bloqueo robustas</u>. No uses claves de desbloqueo ni muy cortas ni con palabras de diccionario... M&aacute;s bien: mezcla may&uacute;sculas y min&uacute;sculas, incluye signos de puntuaci&oacute;n y n&uacute;meros. Y si prefieres usar palabras &quot;de diccionario&quot;, entonces que sea una frase larga de palabras &quot;sin sentido&quot;</li>
</ol>

<p><strong>Trazabilidad m&iacute;nima de cambios</strong>&nbsp;</p>

<p>De momento solamente se guarda el minuto y el usuario que hizo el &uacute;ltimo cambio en una nota. A futuro podr&iacute;a agregarse un LOG de cambios, si hay inter&eacute;s de una funcionalidad as&iacute;.</p>

<p><strong>Compatibilidad con multi-company</strong></p>

<p>las notas que se agregan a un elemento de una compa&ntilde;&iacute;a quedan visibles &uacute;nicamente para esa compa&ntilde;&iacute;a. Y las claves que un usuario crea en una compa&ntilde;&iacute;a tambi&eacute;n solamente son accesibles cuando opera en esa compa&ntilde;&iacute;a.</p>

<h3>Proceso de instalaci&oacute;n</h3>

<p>Primeramente lo de costumbre en la instalaci&oacute;n de cualquier m&oacute;dulo de Dolibarr:</p>

<ol>
	<li>Ir a la secci&oacute;n <u>Configuraci&oacute;n</u></li>
	<li>Ir a <u>M&oacute;dulos</u></li>
	<li>Ir a pesta&ntilde;a <u>Instalar m&oacute;dulo externo</u>, y ah&iacute; subes el ZIP del m&oacute;dulo o su actualizaci&oacute;n</li>
	<li>Volvemos a la pesta&ntilde;a <u>M&oacute;dulos disponibles</u></li>
	<li><u>Filtramos por Origen</u>: &quot;Externo - IMASDEWEB&quot;</li>
	<li><u>Activamos</u> el m&oacute;dulo</li>
</ol>

<p><img alt="" src="https://imasdeweb.com/UserFiles/Image/2025/NotePlus_install_es.jpg" /></p>
</div>

<p id="markdown">&nbsp;</p>

<h2>Anexo: Gu&iacute;a r&aacute;pida de formateo con Markdown</h2>

<div class="block">
<p>Imagina que est&aacute;s escribiendo un mensaje de texto o una nota, y quieres resaltar algunas palabras para que se vean en negrita, en cursiva o como un t&iacute;tulo grande. Normalmente, en programas como Word, haces clic en botones para aplicar esos estilos.</p>

<p>Mientras que Markdown es como un <u>atajo de teclado para dar estilo al texto</u>, pero <u>usando s&iacute;mbolos simples en lugar de botones</u>. Fue creado para que cualquier persona pueda formatear texto de manera r&aacute;pida y legible, incluso si solo est&aacute; escribiendo en un bloc de notas sencillo.</p>

<p><u>Muchas plataformas lo reconocen autom&aacute;ticamente</u>: WhatsApp, Telegram, Discord, foros, blogs (como Medium), e incluso en aplicaciones de notas como Obsidian o Notion.</p>
</div>

<h3>Encabezados</h3>

<p>Usos <code>#</code> s&iacute;mbolos para crear encabezados (1-6 niveles):</p>

<pre>
<code># H1 - Main Title
## H2 - Section
### H3 - Subsection</code></pre>

<h3>Formato de texto</h3>

<ul>
	<li><strong>Texto en negrita</strong>: <code>**bold**</code> o <code>__bold__</code></li>
	<li><em>Texto en cursiva</em>: <code>*italic*</code> o <code>_italic_</code></li>
	<li><strong><em>Negrita y cursiva</em></strong>: <code>***text***</code></li>
	<li><del>Strikethrough</del>: <code>~~strikethrough~~</code></li>
	<li><code>Inline code</code>: <code>`code`</code></li>
</ul>

<h3>Enlaces</h3>

<p>Crea hiperv&iacute;nculos con <code>[text](URL)</code>:</p>

<pre>
<code>[OpenAI](https://openai.com)</code></pre>

<p>Resultado: <a href="https://openai.com" target="_blank">OpenAI</a></p>

<h3>Im&aacute;genes</h3>

<p>Insertar im&aacute;genes usando <code>![alt text](image-url)</code>:</p>

<pre>
<code>![Logo](https://example.com/ubuntu.png)</code></pre>

<p><img alt="" src="https://imasdeweb.com/https://imasdeweb.com/UserFiles/Image/linux-distros/ubuntu.png" /></p>

<h3>Citas</h3>

<blockquote>
<p>Cita de un solo nivel utilizando <code>&gt;</code></p>

<blockquote>
<p>Cita anidada usando <code>&gt;&gt;</code></p>
</blockquote>

<p>Continuaci&oacute;n...</p>
</blockquote>

<p>Usando esto:</p>

<pre>
<code>&gt; Cita de un solo nivel utilizando `&gt;`
&gt;&gt; Cita anidada usando `&gt;&gt;`
&gt;
&gt; Continuaci&oacute;n...</code></pre>

<h3>Listas</h3>

<h4>Listas desordenadas</h4>

<p>Usos <code>-</code>, <code>*</code>, o <code>+</code> Para vi&ntilde;etas:</p>

<pre>
<code>- Primer elemento
- Segundo elemento
 - Elemento anidado (sangrado con el caracter TAB)
 - Otro elemento anidado
- Tercer elemento</code></pre>

<h4>Listas ordenadas</h4>

<p>Utilice n&uacute;meros seguidos de per&iacute;odos:</p>

<pre>
<code>1. Primer elemento
2. Segundo elemento
3. Tercer elemento</code></pre>

<h3>Bloques de c&oacute;digo</h3>

<h4>C&oacute;digo en l&iacute;nea</h4>

<p>Utilice comillas invertidas individuales: <code>`c&oacute;digo aqu&iacute;`</code></p>

<h4>Bloques de c&oacute;digo</h4>

<p>Utilice &quot;backticks&quot; triples con identificador de lenguaje opcional:</p>

<pre>
<code>```php
$variable = &quot;Hola Mundo&quot;;
echo $variable;
```</code></pre>

<h3>Reglas horizontales</h3>

<p>Crea divisores con <code>---</code>, <code>***</code>, o <code>___</code>:</p>

<hr />
<h3>Tablas</h3>

<p>Crea tablas usando &quot;pipes&quot; <code>|</code> y guiones <code>-</code>:</p>

<pre>
<code>| Columna 1 | Columna 2 | Columna 3 |
|----------|----------|----------|
| Datos 1 | Datos 2 | Datos 3 |
| Datos 4 | Datos 5 | Datos 6 |</code></pre>

<p>Resultado:</p>

<table>
	<thead>
		<tr>
			<th>Columna 1</th>
			<th>Columna 2</th>
			<th>Columna 3</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>Datos 1</td>
			<td>Datos 2</td>
			<td>Datos 3</td>
		</tr>
		<tr>
			<td>Datos 4</td>
			<td>Datos 5</td>
			<td>Datos 6</td>
		</tr>
	</tbody>
</table>

<h3>Listas de tareas</h3>

<p>Crea casillas de verificaci&oacute;n con <code>- [ ]</code> o <code>- [x]</code>:</p>

<pre>
<code>[x] Tarea completada
[ ] Tarea pendiente
[ ] Otra tarea pendiente</code></pre>

<p>Result:<br />
<input checked="checked" disabled="disabled" readonly="readonly" type="checkbox" /> Tarea completada<br />
<input disabled="disabled" readonly="readonly" type="checkbox" /> Tarea pendiente<br />
<input disabled="disabled" readonly="readonly" type="checkbox" /> Otra tarea pendiente</p>

<h3>Escapando car&aacute;cteres especiales</h3>

<p>Si necesitas incluir en tu texto los caracteres que Markdown usa para formateo, puedes &quot;escaparlos&quot; colocando la barra inclinada <code>\</code> como prefijo:</p>

<table>
	<thead>
		<tr>
			<th>Caracter</th>
			<th>Nombre</th>
			<th>Ejemplo</th>
			<th>Resultado</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><code>\\</code></td>
			<td>barra invertida</td>
			<td><code>\\</code></td>
			<td>\</td>
		</tr>
		<tr>
			<td><code>\*</code></td>
			<td>asterisco</td>
			<td><code>\*texto\*</code></td>
			<td>*texto*</td>
		</tr>
		<tr>
			<td><code>\_</code></td>
			<td>gui&oacute;n bajo</td>
			<td><code>\_texto\_</code></td>
			<td>_texto_</td>
		</tr>
		<tr>
			<td><code>\{ \}</code></td>
			<td>llaves</td>
			<td><code>\{codigo\}</code></td>
			<td>{codigo}</td>
		</tr>
		<tr>
			<td><code>\[ \]</code></td>
			<td>corchetes</td>
			<td><code>\[texto\]</code></td>
			<td>[texto]</td>
		</tr>
		<tr>
			<td><code>\&lt; \&gt;</code></td>
			<td>menor/mayor que</td>
			<td><code>\</code></td>
			<td>\</td>
		</tr>
		<tr>
			<td><code>\( \)</code></td>
			<td>par&eacute;ntesis</td>
			<td><code>\(nota\)</code></td>
			<td>(nota)</td>
		</tr>
		<tr>
			<td><code>\#</code></td>
			<td>gato/almohadilla</td>
			<td><code>\# no es un t&iacute;tulo</code></td>
			<td># no es un t&iacute;tulo</td>
		</tr>
		<tr>
			<td><code>\+</code></td>
			<td>sumar</td>
			<td><code>\+ elemento</code></td>
			<td>+ elemento</td>
		</tr>
		<tr>
			<td><code>\-</code></td>
			<td>gui&oacute;n</td>
			<td><code>\- no es lista</code></td>
			<td>- no es lista</td>
		</tr>
		<tr>
			<td><code>\.</code></td>
			<td>punto</td>
			<td><code>1\. no es lista</code></td>
			<td>1. no es lista</td>
		</tr>
		<tr>
			<td><code>\!</code></td>
			<td>exclamaci&oacute;n</td>
			<td><code>\!\[no es imagen\]</code></td>
			<td>![no es imagen]</td>
		</tr>
		<tr>
			<td><code>\|</code></td>
			<td>pipe</td>
			<td><code>\| no es tabla \|</code></td>
			<td>| no es tabla |</td>
		</tr>
	</tbody>
</table>

<h4>Casos de uso habituales</h4>

<pre>
<code>Sin escapar: *it&aacute;lica* **negrita** `c&oacute;digo`
Escapado: \*asteriscos\* \*\*estrellas\*\* \`backticks\`</code></pre>

<p>Resultado:</p>

<ul>
	<li>Sin escapar: <em>it&aacute;lica</em> <strong>negrita</strong> <code>c&oacute;digo</code></li>
	<li>Escapado: *asteriscos* **estrellas** `backticks`</li>
</ul>

<hr />
<p><strong>Nota</strong>: el renderizado de Markdown puede variar dependiendo de la plataforma (GitHub, GitLab, Reddit, Dolibarr, etc.).</p>
<style type="text/css">/* + + + MARKDOWN parsed to HTML + + + */

    /* `inline & block code` */
    .blog_post_body code{background-color:#8882;} 
    /* ```only block code``` */
    .blog_post_body pre{max-width:100%;}
    .blog_post_body pre code{
        display:block;
        padding:1em;
        border-left:10px #8888 solid;
        max-width: 100%;
        overflow-x: auto;
        font-family:ui-monospace,SFMono-Regular,'SF Mono',Menlo,Consolas,'Liberation Mono',monospace!important;
    } 
    /* blockquote */
    .blog_post_body blockquote{
        display:block;
        padding:0.5em 1.5em;
        margin-left: 1em;
        border-left:5px #8886 solid;
        background-color: #8881;
        max-width: 100%;
        font-style: italic;
        overflow-x: auto;
    } 
    /* table */
    .blog_post_body  > table{
        border-collapse:collapse!important;
    } 
    /* table thead */
    .blog_post_body  > table thead{
        background-color: #8882 !important;
    }
    /* table tbody cells */
    .blog_post_body  table thead th,
    .blog_post_body  table tbody td{
        border:1px #8885 solid!important;padding:0.3em 0.5em!important;
    }
    /* checkbox */
    .blog_post_body input[type=checkbox]{
        float:none!important;
        opacity:1!important;
        display:inline-block!important;
        appearance:auto!important;
        margin-right:0.3em!important;
    }
    /* horizontal line */
    .blog_post_body hr{
        border-color: #8888 !important;
    }
</style>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Me interesa acceder a la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_13_7920' action='index.php?pag=m_contactos&gad=formulario&id=13'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='13' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Me interesa probar la DEMO de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>¿Cuál módulo te interesa más? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login y Filtro por país								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login y Filtro por país"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Asistentes IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Asistentes IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus y HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus y HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listas editables								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Listas editables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Compras								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Compras"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferencia de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferencia de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Gráficos facturación anual								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Gráficos facturación anual"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Buscar ayuda en Foros								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Buscar ayuda en Foros"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI y contabilidad México								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI y contabilidad México"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Todos								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Todos"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>¿Cuál es tu idioma preferido? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Tu correo electrónico *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Tu nombre *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comentario (opcional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_29011' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_29011').html('<br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' />7<br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /> + <br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' />9<br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /><br style=\'display:none;\' rel=\'68\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_35445' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_35445' name='captcha_formstamp' value='THpsbGVrdEpVemx5Ym5sUGJYQkxNMWd2VUhGSGNVNVJVMUpqVWpWMlVFYzJSVk4zVm01bFpsUm5WVDA2T2pJek5HVTVPRFUwWm1Rek5qZzJZbU0zTkdNNFpUazRNMk5tTkRObFpERXc' />
    <input type='hidden' id='captcha_valid_35445' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_35445').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_35445();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_35445').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_35445').val('');
                    $('#captcha_answer_35445').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_35445').val())+'&captcha_answer='+($('#captcha_answer_35445').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_35445').val(data.valid);
                    $('#captcha_answer_35445').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_35445').addClass('valid_captcha');
                    else
                        $('#captcha_answer_35445').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_35445(){
        if($('#captcha_answer_35445').val() == ''
                || $('#captcha_valid_35445').val()!='1'){

            $('#captcha_answer_35445').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_35445').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_13_7920();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_13_7920(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_13_7920');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_13_7920').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Cómo agregar el widget de comentarios de WordPress a la plantilla de entrada de blog de Brizy</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=108</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=108</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Fri, 10 Jan 2025 23:17:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/108.jpg" style="display: block; margin: 1em auto" /></p><p>Brizy PRO es mi constructor de páginas preferido para WordPress; tiene casi todo; sin embargo, una característica que aún le falta hoy es la integración con comentarios nativos de WordPress para entradas de blog; en esta guía, compartiré cómo lo resolví.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/108.jpg" style="display: block; margin: 1em auto" /></p><h3>Introducci&oacute;n</h3>

<p>Brizy PRO es mi constructor de p&aacute;ginas preferido para WordPress. Lo tiene casi todo. Sin embargo, una caracter&iacute;stica que a&uacute;n le falta hoy es la integraci&oacute;n con los comentarios nativos de WordPress para entradas de blog.</p>

<p>En esta gu&iacute;a, compartir&eacute; c&oacute;mo lo resolv&iacute;.</p>

<h3>Un shortcode para comentarios de WordPress</h3>

<p>El primer problema por resolver es que (hasta donde pude averiguar) no existe un shortcode que nos permita insertar el widget de comentarios de WordPress en, por ejemplo, una plantilla de Brizy. Brizy permite agregar shortcodes existentes de WordPress (nativos o de cualquier otro plugin instalado), pero no tiene uno para comentarios. Es una de esas cosas raras de WordPress que nunca he entendido.</p>

<h3>Mi propio plugin para tener un shortcode de comentarios</h3>

<p>Despu&eacute;s de probar varios enfoques, descubr&iacute; que se puede &quot;f&aacute;cilmente&quot; cargar un nuevo shortcode en WordPress agregando este c&oacute;digo PHP, por ejemplo, en el archivo functions.php de su tema actual:</p>

<pre class="language-php" tabindex="0">
<code class="language-php">&lt;?php
/*
Plugin Name: My Comments Shortcode
Plugin URI: 
Description: Lets you to use shortcode [wpse_comments_template] to insert native Wordpress post comments.
Version: 1.0
Author: IMASDEWEB
License: GPL v2 or later
*/

// Prevenir acceso directo al archivo
if (!defined(&#39;ABSPATH&#39;)) {
    exit;
}

// Registrar el shortcode
function register_comments_shortcode() {
    add_shortcode(&#39;wpse_comments_template&#39;, &#39;render_comments_template&#39;);
}

// Funci&oacute;n que maneja la l&oacute;gica del shortcode 
function render_comments_template($atts = array(), $content = &#39;&#39;) {
    if (is_singular() &amp;&amp; post_type_supports(get_post_type(), &#39;comments&#39;)) {
        ob_start();
        comments_template();
        add_filter(&#39;comments_open&#39;, &#39;wpse_comments_open&#39;);
        add_filter(&#39;get_comments_number&#39;, &#39;wpse_comments_number&#39;);
        return ob_get_clean();
    }
    return &#39;&#39;;
}

// Inicializar el plugin
add_action(&#39;init&#39;, &#39;register_comments_shortcode&#39;);
</code>
</pre>

<p>El problema es que este m&eacute;todo es muy poco conveniente, as&iacute; que busqu&eacute; una forma de crear un plugin de WordPress que haga lo mismo. Y en realidad es muy simple:</p>

<ul>
	<li>puedes descargarlo aqu&iacute;: <a class="a_icon" href="https://imasdeweb.com/index.php?pag=m_&amp;gad=share&amp;token=axiA2P" target="_blank">my-comments-shortcode.zip</a></li>
</ul>

<p>Es un archivo ZIP que contiene solo estos 2 archivos:</p>

<ul>
	<li>readme.txt</li>
	<li>my-comments-shortcode.php</li>
</ul>

<h3>C&oacute;mo insertar comentarios en una plantilla de Brizy</h3>

<p>Primero, instale este plugin en su WordPress. Luego, edite la plantilla de Brizy que cre&oacute; para ENTRADAS de blog (modo SINGLE), y por ejemplo, debajo del cuadro donde indic&oacute; que debe aparecer el contenido de la ENTRADA, cree otro bloque de tipo &quot;shortcode&quot; y config&uacute;relo con este c&oacute;digo:</p>

<div class="block" style="text-align:center;font-size:1.1em;letter-spacing:2px;">[wpse_comments_template]</div>

<p>Es tan simple. Despu&eacute;s de guardar los cambios, ver&aacute; que los comentarios de WordPress ahora aparecen en ENTRADAS que usan esa plantilla.<br />
&nbsp;<br />
<strong><u>Nota</u>:</strong> <em>puede trabajar en el formato de los elementos de la lista de comentarios y el formulario para agregar un nuevo comentario reescribiendo los estilos que los afectan en el CSS adicional de su tema. Ya deber&iacute;a saber que los desarrolladores de Brizy recomiendan usar un hijo de Blocksy como el &quot;tema host&quot; &oacute;ptimo para Brizy.</em></p>
]]></content:encoded>
        </item>
        
        <item>
            <title>How to add WORDPRESS comments widget to Brizy blog post template</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=107</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=107</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Tue, 17 Dec 2024 22:20:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/107.jpg" style="display: block; margin: 1em auto" /></p><p>Brizy PRO is my preferred page builder for WordPress; it has almost everything; however, one feature it still lacks today is the integration with native WordPress comments for blog posts; in this guide, I'll share how I solved this.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/107.jpg" style="display: block; margin: 1em auto" /></p><h3>Introduction</h3>

<p>Brizy PRO is my preferred page builder for WordPress. It has almost everything. However, one feature it still lacks today is the integration with native WordPress comments for blog posts.</p>

<p>In this guide, I&#39;ll share how I solved this.</p>

<h3>A shortcode for WordPress comments</h3>

<p>The first problem to solve is that (as far as I could find out) there isn&#39;t a shortcode that allows us to insert the WordPress comments widget in, for example, a Brizy template. Brizy allows you to add existing shortcodes from your WordPress (native or from any other installed plugin), but it doesn&#39;t have one for comments. It&#39;s one of those rare things about WordPress that I&#39;ve never understood.</p>

<h3>My own plugin to have a comments shortcode</h3>

<p>After trying several approaches, I found that you can &quot;easily&quot; load a new shortcode in WordPress by adding this PHP code, for example, in the functions.php file of your current theme:</p>

<pre class="language-php" tabindex="0">
<code class="language-php">&lt;?php
/*
Plugin Name: My Comments Shortcode
Plugin URI: 
Description: Lets you to use shortcode [wpse_comments_template] to insert native Wordpress post comments.
Version: 1.0
Author: IMASDEWEB
License: GPL v2 or later
*/

// Prevenir acceso directo al archivo
if (!defined(&#39;ABSPATH&#39;)) {
    exit;
}

// Registrar el shortcode
function register_comments_shortcode() {
    add_shortcode(&#39;wpse_comments_template&#39;, &#39;render_comments_template&#39;);
}

// Funci&oacute;n que maneja la l&oacute;gica del shortcode 
function render_comments_template($atts = array(), $content = &#39;&#39;) {
    if (is_singular() &amp;&amp; post_type_supports(get_post_type(), &#39;comments&#39;)) {
        ob_start();
        comments_template();
        add_filter(&#39;comments_open&#39;, &#39;wpse_comments_open&#39;);
        add_filter(&#39;get_comments_number&#39;, &#39;wpse_comments_number&#39;);
        return ob_get_clean();
    }
    return &#39;&#39;;
}

// Inicializar el plugin
add_action(&#39;init&#39;, &#39;register_comments_shortcode&#39;);
</code>
</pre>

<p>The problem is that this method is very inconvenient, so I looked for a way to create a WordPress plugin that does the same thing. And it&#39;s actually very simple:</p>

<ul>
	<li>you can download it here: <a class="a_icon" href="https://imasdeweb.com/index.php?pag=m_&amp;gad=share&amp;token=axiA2P" target="_blank">my-comments-shortcode.zip</a></li>
</ul>

<p>It&#39;s a ZIP file containing just these 2 files:</p>

<ul>
	<li>readme.txt</li>
	<li>my-comments-shortcode.php</li>
</ul>

<h3>How to insert comments in a Brizy template</h3>

<p>First, install this plugin in your WordPress. Then, edit the Brizy template you created for blog POSTS (SINGLE mode), and for example, below the box where you indicated the POST content should appear, create another block of type &quot;shortcode&quot; and configure it with this code:</p>

<div class="block" style="text-align:center;font-size:1.1em;letter-spacing:2px;">[wpse_comments_template]</div>

<p>It&#39;s that simple. After saving changes, you&#39;ll see that WordPress comments now appear in POSTS using that template.<br />
&nbsp;<br />
<strong><u>Note</u>:</strong> <em>you can work on the format of those comment list elements and the form to add a new comment by rewriting the styles that affect them in your theme&#39;s additional CSS. You should already know that Brizy developers recommend using a Blocksy-child as the optimal &quot;host theme&quot; for Brizy.</em></p>
]]></content:encoded>
        </item>
        
        <item>
            <title>Manuel d'utilisation du module Assistants IA pour Dolibarr</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=105</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=105</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Wed, 11 Sep 2024 18:55:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/105.jpg" style="display: block; margin: 1em auto" /></p><p>Ce module, que vous pouvez acheter sur Dolistore, vous offre la possibilité d'utiliser de nombreux modèles d'IA générative directement depuis votre propre Dolibarr, en consommant le minimum via les API des différents fournisseurs, au lieu de souscrire à des abonnements mensuels fixes pour chaque employé de votre entreprise.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/105.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>Ce module, que vous pouvez acheter sur Dolistore, vous offre la possibilit&eacute; d&#39;utiliser de nombreux mod&egrave;les d&#39;IA g&eacute;n&eacute;rative directement depuis votre propre Dolibarr, en consommant le minimum via les API des diff&eacute;rents fournisseurs, au lieu de souscrire &agrave; des abonnements mensuels fixes pour chaque employ&eacute; de votre entreprise.</p>

<div class="a_c"><a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=105">Guide en fran&ccedil;ais</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=106">Guide in english</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=104">Gu&iacute;a en espa&ntilde;ol</a></div>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Je suis intéressé à accéder à la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_17_8886' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_20876' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_20876').html('<br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' />0<br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /> + <br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' />1<br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /><br style=\'display:none;\' rel=\'70559\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_25258' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_25258' name='captcha_formstamp' value='WjJWWGFWZEVjSFZVZW0xUlQzVkdUMlJ1TURWVGVtb3JNRXcwVW10UVMzUjBPVlE1YUdWM1oyVjBPRDA2T21aa05qZzBPRGt5Wm1NeFpqZGhNV00xTW1NM05USmhNak5sTVdSbE9HTmo' />
    <input type='hidden' id='captcha_valid_25258' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_25258').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_25258();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_25258').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_25258').val('');
                    $('#captcha_answer_25258').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_25258').val())+'&captcha_answer='+($('#captcha_answer_25258').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_25258').val(data.valid);
                    $('#captcha_answer_25258').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_25258').addClass('valid_captcha');
                    else
                        $('#captcha_answer_25258').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_25258(){
        if($('#captcha_answer_25258').val() == ''
                || $('#captcha_valid_25258').val()!='1'){

            $('#captcha_answer_25258').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_25258').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_8886();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_8886(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_8886');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_8886').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/dolibarr-ASSISTANTS-AI-module_napkin-FR.svg" style="width:100%;max-width:1000px;" /></p>

<h3>Index</h3>

<p>Si vous n&#39;&ecirc;tes pas un utilisateur administrateur de votre Dolibarr, vous pouvez passer au point 3 de ce manuel.</p>

<ol>
	<li><a href="#section_install">Processus d&#39;installation</a></li>
	<li><a href="#section_providers">Int&eacute;gration avec les fournisseurs d&#39;IA</a>
	<ul>
		<li><a href="#sec_openai">OpenAI</a> (g&eacute;n&eacute;ration de texte)</li>
		<li><a href="#sec_anthropic">Anthropic.com</a> (g&eacute;n&eacute;ration de texte avec vision)</li>
		<li><a href="#sec_perplexity">Perplexity</a> (g&eacute;n. de texte et recherche sur internet)</li>
		<li><a href="#sec_falai">Fal.ai</a> (g&eacute;n. d&#39;images avec FLUX et StableDiffusion)</li>
	</ul>
	</li>
	<li><a href="#section_chat">Converser avec une IA</a></li>
	<li><a href="#section_next">Prochainement</a></li>
	<li><a href="#section_demo">Acc&egrave;s &agrave; DEMO</a></li>
</ol>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h3>1. Processus d&#39;installation</h3>

<p>Tout d&#39;abord, comme d&#39;habitude pour l&#39;installation de tout module Dolibarr :</p>

<ol>
	<li>Allez &agrave; la section <u>Configuration</u></li>
	<li>Allez &agrave; <u>Modules</u></li>
	<li>Allez &agrave; l&#39;onglet <u>Installer un module externe</u>, et l&agrave; vous t&eacute;l&eacute;chargez le ZIP du module ou sa mise &agrave; jour</li>
	<li>Revenons &agrave; l&#39;onglet <u>Modules disponibles</u></li>
	<li><u>Filtrons par Origine</u> : &quot;Externe - IMASDEWEB&quot;</li>
	<li><u>Activons</u> le module</li>
	<li>Cliquons sur l&#39;<u>ic&ocirc;ne de Configuration</u></li>
</ol>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-04_FR.png" /></p>

<p>Dans une premi&egrave;re section Divers, nous pouvons configurer des choses comme le &quot;Mod&egrave;le par d&eacute;faut&quot;. Ce sera le mod&egrave;le avec lequel un chat sera initialis&eacute; lorsque le syst&egrave;me n&#39;a pas d&#39;information dans la variable de session de l&#39;utilisateur sur le dernier mod&egrave;le qu&#39;il a utilis&eacute;.</p>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-05_FR.png" /></p>

<h4>Limite d&#39;utilisation par utilisateur</h4>

<p>Vous pouvez configurer la limite d&#39;utilisation par utilisateur, aussi bien par heure que par jour :</p>

<ul>
	<li>Chaque fois qu&#39;un utilisateur fait une demande d&#39;IA, le syst&egrave;me compte combien de demandes il a faites au cours des 60 derni&egrave;res minutes, et aussi au cours des derni&egrave;res 24 heures. Et si l&#39;une de ces valeurs d&eacute;passe la limite correspondante, alors <u>il affiche un message &agrave; l&#39;utilisateur</u> l&#39;encourageant &agrave; r&eacute;essayer plus tard.<br />
	&nbsp;</li>
	<li>Selon la taille de votre organisation et le type d&#39;utilisation que vos utilisateurs/employ&eacute;s feront ou ont besoin de faire, il vous conviendra de configurer ces deux param&egrave;tres diff&eacute;remment.<br />
	&nbsp;<br />
	<em>Par exemple, peut-&ecirc;tre que vous ne voulez pas qu&#39;un utilisateur puisse faire une utilisation tr&egrave;s intensive de l&#39;IA (g&eacute;n&eacute;rant des textes, des images, etc.) pendant quelques heures. Vous pouvez alors configurer une limite horaire &eacute;lev&eacute;e (par exemple, une demande toutes les 10 secondes serait 6 par minute et 360 par heure. Mais comme vous ne voulez pas que cela encourage une utilisation excessive, vous pourriez fixer une limite de seulement 1400 toutes les 24 heures. De cette fa&ccedil;on, vous permettriez des utilisations intensives de l&#39;IA, tout en garantissant un certain contr&ocirc;le sur une utilisation abusive prolong&eacute;e.</em></li>
</ul>
</div>

<div id="section_providers" style="padding-top:100px;margin-top:-50px;">
<h3>2. Int&eacute;gration avec les fournisseurs d&#39;IA</h3>

<p>C&#39;est la partie la plus int&eacute;ressante et qui variera le plus fr&eacute;quemment avec chaque mise &agrave; jour. Au cours des prochains mois, de plus en plus d&#39;int&eacute;grations avec de nouveaux fournisseurs ou de nouveaux mod&egrave;les des m&ecirc;mes fournisseurs seront ajout&eacute;es. Donc, si vous voulez en tirer le meilleur parti, <u>il serait recommand&eacute; de mettre &agrave; jour r&eacute;guli&egrave;rement</u>.</p>

<div class="block">
<p>Pour configurer chaque fournisseur :</p>

<ol>
	<li>Ouvrez un <u>compte sur la plateforme du fournisseur</u> (le lien appara&icirc;t dans le panneau)</li>
	<li>G&eacute;n&eacute;rez une <u>cl&eacute; unique pour utiliser l&#39;API</u> de ce fournisseur et placez-la ici</li>
	<li>Indiquez quels mod&egrave;les de ce fournisseur vous voulez :<br />
	&nbsp;<br />
	- AUTORISER LEUR UTILISATION aux utilisateurs<br />
	- AFFICHER aux utilisateurs <em>**</em></li>
</ol>
</div>

<p style="margin-left: 80px;"><em>** Dans certains cas, il pourrait &ecirc;tre int&eacute;ressant d&#39;afficher un mod&egrave;le qui n&#39;est pas ouvert &agrave; l&#39;utilisation, mais que vous &ecirc;tes pr&ecirc;t &agrave; activer si quelqu&#39;un en a besoin. Parce qu&#39;il y a certainement des mod&egrave;les assez co&ucirc;teux &agrave; utiliser normalement, mais qui peuvent &ecirc;tre tr&egrave;s utiles &agrave; activer &agrave; des moments ponctuels.</em></p>

<p style="margin-left: 80px;"><strong><u>Note</u> :</strong> &agrave; l&#39;avenir, il est pr&eacute;vu d&#39;impl&eacute;menter la possibilit&eacute; d&#39;activer/d&eacute;sactiver les mod&egrave;les PAR UTILISATEUR. De cette fa&ccedil;on, vous aurez un meilleur contr&ocirc;le sur qui consomme chaque service d&#39;IA.<br />
&nbsp;</p>

<h4 id="sec_openai" style="padding-top:100px;margin-top:-50px;"><strong>OpenAI</strong></h4>

<ul>
	<li>C&#39;est l&#39;entreprise cr&eacute;atrice du c&eacute;l&egrave;bre <u>chatGPT</u>, qui a une particularit&eacute; : elle a des mod&egrave;les pour les EMBEDDINGS, qui est un service d&#39;IA fondamental pour d&eacute;velopper tout syst&egrave;me de <u>recherche s&eacute;mantique</u>, c&#39;est-&agrave;-dire qu&#39;un utilisateur recherche &quot;f&eacute;lins&quot; et le syst&egrave;me lui trouve tout ce qui est li&eacute; aux chats et autres f&eacute;lins, m&ecirc;me si le mot &agrave; rechercher a &eacute;t&eacute; mal &eacute;crit.<br />
	&nbsp;<br />
	Ce <u>syst&egrave;me d&#39;embeddings est celui qui sera utilis&eacute; pour le moteur de recherche dans l&#39;historique des chats de chaque utilisateur</u>, dans un avenir tr&egrave;s proche. C&#39;est en r&eacute;alit&eacute; une fonctionnalit&eacute; qui sera impl&eacute;ment&eacute;e comme OPTIONNELLE, mais elle en vaut vraiment la peine et la consommation de ce type d&#39;IA d&#39;embeddings est tr&egrave;s bon march&eacute;, c&#39;est pourquoi je vous le recommande fortement. Cela peut augmenter votre consommation d&#39;IA d&#39;&agrave; peine 1%, mais ce que vous obtenez en &eacute;change est radicalement b&eacute;n&eacute;fique.<br />
	&nbsp;</li>
	<li>Les mod&egrave;les de texte ont des <u>prix diff&eacute;rents pour l&#39;INPUT</u> (ce que l&#39;utilisateur &eacute;crit, y compris tout document qu&#39;il joint) que pour l&#39;OUTPUT (la r&eacute;ponse du mod&egrave;le).<br />
	&nbsp;</li>
	<li><u>La consommation se mesure</u> en MILLIONS DE TOKENS. Les &quot;tokens&quot; sont &quot;une partie d&#39;un mot&quot; et &eacute;quivalent approximativement &agrave; une ou deux syllabes humaines. Ainsi, un million de tokens &eacute;quivaut &agrave; plus de DEUX MILLE PAGES D&#39;UN LIVRE moyen. L&#39;utilisation de ces IA est donc assez &eacute;conomique.<br />
	&nbsp;<br />
	<em>Note : Dans une conversation avec l&#39;IA, <u>chaque nouveau message inclut tous les pr&eacute;c&eacute;dents</u>. Cela permet &agrave; l&#39;IA de &quot;se souvenir&quot; du contexte, mais <u>augmente exponentiellement la consommation de ressources</u> au fur et &agrave; mesure que la conversation avance, car l&#39;IA relit tout l&#39;historique &agrave; chaque interaction.<br />
	&nbsp;<br />
	La recommandation est que <u>lorsque vous devez changer de sujet, vous ouvriez une nouvelle conversation</u>.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-06_FR.png" /></p>

<p>&nbsp;</p>

<h4 id="sec_anthropic" style="padding-top:100px;margin-top:-50px;">Anthropic.com</h4>

<p>Anthropic est l&#39;entreprise derri&egrave;re les mod&egrave;les Claude, qui sont &agrave; mon avis actuellement les plus comp&eacute;tents pour la g&eacute;n&eacute;ration de code, la traduction multilingue et la structuration de contenu textuel :</p>

<ul>
	<li>Pour &quot;<u><strong>travailler avec des textes et g&eacute;n&eacute;rer des textes</strong></u>&quot;, qui fonctionne comme nous sommes habitu&eacute;s avec ChatGPT :<br />
	&nbsp;<br />
	<em><u>Le mod&egrave;le r&eacute;pondra en fonction de toutes les informations sur lesquelles il a &eacute;t&eacute; entra&icirc;n&eacute;</u>, qui ont une date limite sp&eacute;cifique. Au-del&agrave; de la fin de leur date d&#39;entra&icirc;nement, ces mod&egrave;les n&#39;ont pas acc&egrave;s aux informations actualis&eacute;es.<br />
	<br />
	Le mod&egrave;le Haiku, qui est le plus &eacute;conomique, est tr&egrave;s bon pour 90% des t&acirc;ches demand&eacute;es. Le mod&egrave;le Sonnet est brillant mais co&ucirc;te environ 4 fois plus par million de tokens.</em><br />
	&nbsp;</li>
	<li>Pour &quot;<u><strong>VOIR le contenu des images</strong></u>&quot;, c&#39;est-&agrave;-dire que dans la conversation chat nous pouvons joindre des images pour qu&#39;il les &quot;voie&quot; et r&eacute;ponde &agrave; des questions &agrave; leur sujet. Par exemple : interpr&eacute;ter des tableaux ou des graphiques statistiques, lire des formules chimiques, ou des probl&egrave;mes math&eacute;matiques de g&eacute;om&eacute;trie, etc.<br />
	&nbsp;<br />
	<em>Cette capacit&eacute; de VISION n&#39;est disponible que dans le mod&egrave;le Sonnet. Vous remarquerez que dans le module, les mod&egrave;les disposant de cette capacit&eacute; de VISION sont marqu&eacute;s d&#39;une ic&ocirc;ne &OElig;IL.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2025/ai-assistants-settings-09_FR.jpg" /></p>

<p>&nbsp;</p>

<h4 id="sec_perplexity" style="padding-top:100px;margin-top:-50px;">Perplexity</h4>

<p>Perplexity est un fournisseur fabuleux de recherche sur Internet utilisant l&#39;IA, qui int&egrave;gre dans ses serveurs diff&eacute;rents mod&egrave;les open source de diff&eacute;rents fournisseurs. Concr&egrave;tement, via son API, &agrave; ce jour, il propose la famille de mod&egrave;les Llama 3.1 de Meta &agrave; utiliser dans deux modalit&eacute;s :</p>

<ul>
	<li><u>Simplement pour &quot;<strong>chatter</strong>&quot;</u>, qui fonctionnerait comme nous sommes habitu&eacute;s &agrave; ce que fait chatGPT.<br />
	&nbsp;<br />
	<em>C&#39;est-&agrave;-dire que <u>le mod&egrave;le r&eacute;pondra sur la base de toutes les informations avec lesquelles il a &eacute;t&eacute; entra&icirc;n&eacute;</u>, qui ont une date limite concr&egrave;te. Au-del&agrave; de la fin de sa date d&#39;entra&icirc;nement, ces mod&egrave;les n&#39;ont pas acc&egrave;s &agrave; des informations actualis&eacute;es.</em><br />
	&nbsp;</li>
	<li><u>Pour &quot;<strong>rechercher en ligne</strong>&quot;</u>, ce qui est assez diff&eacute;rent : il recherche sur Internet (en utilisant Bing) des informations int&eacute;ressantes pour notre question et construit une &quot;bonne r&eacute;ponse&quot;.<br />
	&nbsp;<br />
	<em>&Eacute;videmment, la qualit&eacute; de la r&eacute;ponse d&eacute;pend beaucoup de la qualit&eacute; des r&eacute;sultats de recherche.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-07_FR.png" /></p>

<p>&nbsp;</p>

<h4 id="sec_falai" style="padding-top:100px;margin-top:-50px;">fal.ai</h4>

<p>FAL.AI est une entreprise qui nous permet d&#39;acc&eacute;der &agrave; leurs serveurs via API pour utiliser des mod&egrave;les de g&eacute;n&eacute;ration et d&#39;&eacute;dition d&#39;images et de vid&eacute;os tiers. Plus pr&eacute;cis&eacute;ment, dans ce module Dolibarr, nous utiliserons :</p>

<ul>
	<li>La famille de mod&egrave;les FLUX, apparue d&eacute;but 2024, qui pendant plusieurs mois a &eacute;t&eacute; la meilleure pour g&eacute;n&eacute;rer des images photor&eacute;alistes incluant du texte &eacute;crit (sur des panneaux, casquettes, t-shirts, voitures, etc.), principalement en ANGLAIS. Elle ne fonctionne pas aussi bien dans d&#39;autres langues, particuli&egrave;rement avec des phrases longues ou des mots qui &quot;ne sont pas dans le dictionnaire&quot;, comme les noms d&#39;entreprises ou de marques inconnues. En &eacute;t&eacute;, le mod&egrave;le Ideogram 2.0 (d&#39;une autre entreprise) a d&eacute;pass&eacute; FLUX dans sa capacit&eacute; &agrave; inclure du texte dans les images, et &agrave; ce jour (novembre 2024), il reste le seul qui le fait bien 80% du temps dans les langues non anglaises.<br />
	&nbsp;<br />
	<em>Bien que les mod&egrave;les FLUX.1 aient &eacute;t&eacute; publi&eacute;s, fal.ai ne nous propose que les mod&egrave;les FLUX initiaux, qui sont toujours tr&egrave;s bons pour g&eacute;n&eacute;rer des images avec du texte :</em>

	<p><em>- <u>flux-schnell</u>: le plus &eacute;conomique... <b>environ 300 images pour 1 USD</b> !!!!<br />
	- <u>flux-pro</u>: qualit&eacute; maximale, bien que pour 1 USD vous ne puissiez g&eacute;n&eacute;rer &quot;que&quot; 20 images de super qualit&eacute;<br />
	- <u>flux-dev</u>: le mod&egrave;le interm&eacute;diaire... environ 40 images pour 1 USD</em></p>
	</li>
	<li>Vous pouvez &eacute;galement utiliser certains mod&egrave;les Stable Diffusion, qui est un v&eacute;t&eacute;ran dans la g&eacute;n&eacute;ration d&#39;images, notamment ces mod&egrave;les :<br />
	<br />
	<em>- fast-turbo-difussion: 14 000 images pour 1 USD !!!<br />
	- sd-v3-medium: 30 images pour 1 USD.</em><br />
	<br />
	<u>Note</u>: Ces mod&egrave;les sont tr&egrave;s bons avec les dessins vectoriels et artistiques, les bandes dessin&eacute;es, etc. Moins avec les images photor&eacute;alistes, sauf si vous les utilisez avec LORAS. Mais cela d&eacute;passe le cadre de ce module. Si cela vous int&eacute;resse, je vous recommande d&#39;utiliser StableDiffusion via l&#39;interface web de <u>fal.ai</u>.<br />
	&nbsp;</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-08_FR.png" /></p>

<p><strong>D&eacute;tails techniques concernant la g&eacute;n&eacute;ration d&#39;images</strong></p>

<ul>
	<li>Les images que vos utilisateurs Dolibarr g&eacute;n&egrave;rent dans leurs conversations seront stock&eacute;es dans /documents/1/99 (o&ugrave; &quot;1&quot; est l&#39;ID utilisateur et &quot;99&quot; l&#39;ID de chaque chat). Plus tard, je mettrai en place un moyen de contr&ocirc;ler l&#39;espace occup&eacute; par les images g&eacute;n&eacute;r&eacute;es. Actuellement, elles occupent environ entre 500Ko et 1Mo, selon les dimensions et le mod&egrave;le.</li>
	<li>J&#39;ai programm&eacute; le module pour faciliter le partage d&#39;images entre utilisateurs Dolibarr : s&#39;ils transmettent le lien de l&#39;image (vous pouvez l&#39;obtenir en ouvrant l&#39;image dans un nouvel onglet), ils peuvent t&eacute;l&eacute;charger l&#39;image tant qu&#39;ils sont connect&eacute;s.</li>
	<li>Comme avec les mod&egrave;les de chat et de recherche, diff&eacute;rents mod&egrave;les peuvent &ecirc;tre utilis&eacute;s dans la m&ecirc;me conversation : vous pouvez passer &agrave; un mod&egrave;le de g&eacute;n&eacute;ration d&#39;images au milieu d&#39;une conversation avec n&#39;importe quel mod&egrave;le de texte pour g&eacute;n&eacute;rer quelques images.</li>
	<li>Dans tous les cas, les mod&egrave;les qui g&eacute;n&egrave;rent des images ne prennent pas du tout en compte les autres messages de cette conversation, et de m&ecirc;me, les images g&eacute;n&eacute;r&eacute;es ne sont pas prises en compte par les mod&egrave;les de texte, m&ecirc;me si elles sont dans la m&ecirc;me conversation.</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-04_FR.jpg" /></p>
</div>

<div id="section_chat" style="padding-top:100px;margin-top:-50px;">
<h3>3. Converser avec une IA</h3>

<p>En acc&eacute;dant &agrave; la section IA du menu sup&eacute;rieur, nous verrons un &eacute;cran comme celui-ci, o&ugrave; chaque utilisateur :</p>

<ol>
	<li>&quot;conversera&quot; avec les diff&eacute;rents mod&egrave;les d&#39;IA</li>
	<li>interagira avec son historique de conversations</li>
</ol>

<p>C&#39;est une interface simple &agrave; deux panneaux :</p>

<ul>
	<li>Panneau gauche : historique des conversations</li>
	<li>Panneau droit : conversation</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-01_FR.png" /></p>

<p>Je ne veux pas allonger ce guide inutilement, je pense que presque toutes les fonctions et boutons sont assez &eacute;vidents, donc je ne commenterai que les plus pertinents. Si vous pensez que quelque chose n&#39;est pas r&eacute;pondu, veuillez laisser un commentaire tout en bas pour que je compl&egrave;te cette information ici. Merci !</p>

<h4>&Eacute;l&eacute;ments graphiques</h4>

<ul>
	<li>Les <u>boutons en niveaux de gris</u> sont des boutons de fonctions pr&eacute;vues pour &ecirc;tre impl&eacute;ment&eacute;es prochainement. Ils seront activ&eacute;s dans les mises &agrave; jour successives.</li>
	<li>La <u>fa&ccedil;on basique de travailler</u> est d&#39;appuyer sur le bouton &quot;+&quot; pour commencer une nouvelle conversation, ou de cliquer sur n&#39;importe laquelle de l&#39;historique pour la continuer.</li>
	<li>Dans le panneau droit, vous avez un bouton pour <u>masquer le panneau gauche</u>.</li>
	<li>Dans le panneau droit, vous avez un <u>bouton pour &quot;maximiser&quot; la zone de chat</u> :<br />
	1. cache le panneau gauche<br />
	2. cache la barre sup&eacute;rieure des menus de Dolibarr<br />
	3. maximise votre fen&ecirc;tre de navigateur</li>
	<li>Lorsque vous r&eacute;digez un nouveau message, vous pouvez utiliser la touche ENTR&Eacute;E pour ajouter des sauts de ligne, et vous pouvez <u>utiliser la touche TAB pour positionner le focus sur le bouton ENVOYER MESSAGE</u>. De cette fa&ccedil;on, vous pouvez maintenir une conversation sans lever la main du clavier.</li>
</ul>

<h4>Options d&#39;un chat</h4>

<p>En cliquant sur n&#39;importe quelle ic&ocirc;ne du type trois points (&middot;&middot;&middot;), une fen&ecirc;tre modale (popup) appara&icirc;t avec :</p>

<ul>
	<li>l&#39;<u>ID num&eacute;rique</u> de la conversation</li>
	<li>la <u>date de d&eacute;but</u> de la conversation</li>
	<li>le <u>mod&egrave;le d&#39;IA</u> actif ou utilis&eacute; dans le dernier message de ce chat (rappelez-vous que dans chaque message d&#39;un m&ecirc;me chat, vous pouvez utiliser diff&eacute;rents mod&egrave;les !)</li>
	<li>bouton pour <u>partager</u> (prochainement)</li>
	<li>bouton pour <u>changer le titre</u> dans l&#39;historique (prochainement)</li>
	<li>bouton <u>SUPPRIMER</u> (fonctionne d&eacute;j&agrave; !), qui vous demandera confirmation avant de supprimer</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-02_FR.png" /></p>

<h4>S&eacute;lection du mod&egrave;le d&#39;IA</h4>

<p>En appuyant sur le bouton pr&eacute;c&eacute;dent &quot;Mod&egrave;le IA&quot;, un second cadre de dialogue appara&icirc;t :</p>

<ul>
	<li>avec la <u>liste des mod&egrave;les</u> que l&#39;administrateur a configur&eacute;s comme VISIBLES dans le panneau d&#39;administration</li>
	<li><u>apparaissent d&eacute;sactiv&eacute;s</u> les mod&egrave;les qui ont &eacute;t&eacute; configur&eacute;s comme VISIBLES mais NON UTILISABLES</li>
	<li>j&#39;ai d&eacute;cid&eacute; <u>d&#39;inclure le prix</u> pour faire participer les utilisateurs finaux &agrave; la diff&eacute;rence (grande !) de prix entre l&#39;utilisation d&#39;un mod&egrave;le ou d&#39;un autre, et <u>encourager une utilisation responsable</u></li>
</ul>

<p style="margin-left: 40px;"><em><strong><u>Note</u> :</strong> pour le moment, il n&#39;y a que des mod&egrave;les de g&eacute;n&eacute;ration de texte, mais <u>prochainement</u> il y aura des mod&egrave;les de g&eacute;n&eacute;ration d&#39;images, de transcription audio, etc.</em></p>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-03_FR.png" /></p>

<p>&nbsp;</p>
</div>

<div id="section_next" style="padding-top:100px;margin-top:-50px;">
<h4>Prochainement</h4>

<p>&nbsp;</p>

<p><strong>Plus d&#39;int&eacute;grations avec des fournisseurs d&#39;IA</strong></p>

<p>Si vous avez suivi cette r&eacute;volution technologique que nous vivons avec les &quot;IA g&eacute;n&eacute;ratives&quot;, vous savez que chaque semaine apporte des nouveaut&eacute;s. Donc ma volont&eacute; est d&#39;ajouter l&#39;int&eacute;gration de plus en plus de mod&egrave;les et de fournisseurs de mod&egrave;les. L&#39;id&eacute;e est que depuis un m&ecirc;me panneau (depuis notre Dolibarr) nous ayons une base solide &agrave; partir de laquelle b&eacute;n&eacute;ficier de ces IA, dans un environnement multi-utilisateurs.</p>

<ul>
	<li>transcription multi-langue d&#39;audios (avec Whisper d&#39;OpenAI)</li>
	<li>g&eacute;n&eacute;ration de vid&eacute;os (cela va exploser avant la fin de 2024 !)</li>
	<li>g&eacute;n&eacute;ration audio &agrave; partir de texte (OpenAI, Azure Cognitive Services ?)</li>
</ul>

<p>&nbsp;</p>

<p><strong>Interagir avec la base de donn&eacute;es de Dolibarr</strong></p>

<p>De plus, &eacute;videmment, je suis d&eacute;j&agrave; en train de voir comment on pourrait int&eacute;grer dans ces conversations avec l&#39;IA l&#39;acc&egrave;s aux donn&eacute;es stock&eacute;es dans notre base de donn&eacute;es, que ce soit pour :</p>

<ul>
	<li>analyser les tendances</li>
	<li>r&eacute;sumer ou r&eacute;cup&eacute;rer des donn&eacute;es de clients, projets, produits, etc.</li>
	<li>comparer des produits, des commandes, etc...</li>
</ul>

<p>Il ne fait aucun doute que l&#39;IA peut nous &ecirc;tre tr&egrave;s utile pour interagir avec nos propres donn&eacute;es. Je travaillerai dessus. Si vous avez une r&eacute;f&eacute;rence utile de personnes qui ont d&eacute;j&agrave; avanc&eacute; sur ce sujet, m&ecirc;me si c&#39;est dans un autre ERP, s&#39;il vous pla&icirc;t, laissez-moi la r&eacute;f&eacute;rence dans les commentaires !</p>

<p>&nbsp;</p>

<p><strong>Fonctions d&#39;IA contextuelles</strong></p>

<p>J&#39;aimerais aussi pouvoir ajouter des &quot;boutons rapides d&#39;assistance&quot; dans les diff&eacute;rentes listes et fiches des objets de Dolibarr, et dans les &eacute;diteurs de texte, avec des prompts pr&eacute;-enregistr&eacute;s du type :</p>

<ul>
	<li>traduire vers la langue X</li>
	<li>corriger grammaticalement et am&eacute;liorer une r&eacute;daction (email, r&eacute;ponse de ticket, etc.)</li>
	<li>r&eacute;sumer un tableau de donn&eacute;es (de factures d&#39;un client, de production, etc.)</li>
</ul>
</div>

<div id="section_demo" style="padding-top:100px;margin-top:-50px;">
<h4>Accès à la DÉMO</h4>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Je suis intéressé à accéder à la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_17_9480' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_64169' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_64169').html('<br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' />1<br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /> + <br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' />1<br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /><br style=\'display:none;\' rel=\'3203\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_77185' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_77185' name='captcha_formstamp' value='TVhkUGJUaE1aRGxpZG5KV1QxbFNWMjQ1YUdaYVFVRlNhMHM1ZURaSEt6Rk9ka0owYkhCb1VIRm9UVDA2T21aak9UTXdOREl5T0dGaFkyVTBZemN4TkdReVpHWTBaamRqTVRnNE5ETmw' />
    <input type='hidden' id='captcha_valid_77185' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_77185').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_77185();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_77185').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_77185').val('');
                    $('#captcha_answer_77185').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_77185').val())+'&captcha_answer='+($('#captcha_answer_77185').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_77185').val(data.valid);
                    $('#captcha_answer_77185').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_77185').addClass('valid_captcha');
                    else
                        $('#captcha_answer_77185').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_77185(){
        if($('#captcha_answer_77185').val() == ''
                || $('#captcha_valid_77185').val()!='1'){

            $('#captcha_answer_77185').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_77185').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_9480();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_9480(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_9480');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_9480').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>User Manual for the AI Assistants Module for Dolibarr</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=106</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=106</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Wed, 11 Sep 2024 19:11:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/106.jpg" style="display: block; margin: 1em auto" /></p><p>This module, which you can purchase from Dolistore, offers you the ability to use many generative AI models directly from your own Dolibarr installation, consuming the minimum through the APIs of different providers, instead of subscribing to fixed monthly payments for each employee in your company.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/106.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>This module, which you can purchase from Dolistore, offers you the ability to use many generative AI models directly from your own Dolibarr installation, consuming the minimum through the APIs of different providers, instead of subscribing to fixed monthly payments for each employee in your company.</p>

<div class="a_c"><a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=105">Guide en fran&ccedil;ais</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=106">Guide in english</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=104">Gu&iacute;a en espa&ntilde;ol</a></div>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">I am interested in accessing the DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_14_7268' action='index.php?pag=m_contactos&gad=formulario&id=14'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='14' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>I am interested to test Dolibarr DEMO</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Which module are you most interested in? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login and Country Filter								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login and Country Filter"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI Assistants								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="AI Assistants"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus and HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus and HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Editable lists								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Editable lists"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Purchases								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Purchases"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Annual billing charts								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Annual billing charts"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								StockTransfers								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="StockTransfers"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Search For Help in Forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Search For Help in Forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								 Mexican CFDI								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value=" Mexican CFDI"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								All								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="All"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>What is your preferred language? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Your email address *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Your name *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comment (optional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_46471' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_46471').html('<br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' />5<br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /> + <br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' />9<br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /><br style=\'display:none;\' rel=\'22204\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_11127' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_11127' name='captcha_formstamp' value='TURoWmJIWjBTa05yWmpWcFZGQmFlV016Um1Kek5XSkJWbFZ3VWtkTmVHOU9iMUpqYlVsRVdVUnhXVDA2T2pabE5EYzJOalZpTTJJeE56azRPV1poWmpBNVlqQm1ZbUZrTVRSaFlURTA' />
    <input type='hidden' id='captcha_valid_11127' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_11127').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_11127();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_11127').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_11127').val('');
                    $('#captcha_answer_11127').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_11127').val())+'&captcha_answer='+($('#captcha_answer_11127').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_11127').val(data.valid);
                    $('#captcha_answer_11127').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_11127').addClass('valid_captcha');
                    else
                        $('#captcha_answer_11127').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_11127(){
        if($('#captcha_answer_11127').val() == ''
                || $('#captcha_valid_11127').val()!='1'){

            $('#captcha_answer_11127').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_11127').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_14_7268();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_14_7268(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_14_7268');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_14_7268').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/dolibarr-ASSISTANTS-AI-module_napkin-EN.svg" style="width:100%;max-width:1000px;" /></p>

<h3>Index</h3>

<p>If you are not an administrative user of your Dolibarr, you can skip to point 3 of this manual.</p>

<ol>
	<li><a href="#section_install">Installation Process</a></li>
	<li><a href="#section_providers">Integration with AI Providers</a>
	<ul>
		<li><a href="#sec_openai">OpenAI</a> (text generation)</li>
		<li><a href="#sec_anthropic">Anthropic.com</a> (text generation with vision)</li>
		<li><a href="#sec_perplexity">Perplexity</a> (text generation and online search)</li>
		<li><a href="#sec_falai">Fal.ai</a> (image generation with FLUX &amp; StableDifussion)</li>
	</ul>
	</li>
	<li><a href="#section_chat">Conversing with an AI</a></li>
	<li><a href="#section_next">Coming Soon</a></li>
	<li><a href="#section_demo">Access to DEMO</a></li>
</ol>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h3>1. Installation Process</h3>

<p>First, as usual for installing any Dolibarr module:</p>

<ol>
	<li>Go to the <u>Configuration</u> section</li>
	<li>Go to <u>Modules</u></li>
	<li>Go to the <u>Install an external module</u> tab, and there you upload the ZIP of the module or its update</li>
	<li>Return to the <u>Available modules</u> tab</li>
	<li><u>Filter by Origin</u>: &quot;External - IMASDEWEB&quot;</li>
	<li><u>Activate</u> the module</li>
	<li>Click on the <u>Configuration icon</u></li>
</ol>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-04_EN.png" /></p>

<p>In a first Miscellaneous section, we can configure things like the &quot;Default model&quot;. This will be the model with which a chat will be initialized when the system has no information in the user&#39;s session variable about the last model they used.</p>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-05_EN.png" /></p>

<h4>Usage Limit per User</h4>

<p>You can configure the usage limit per user, both per hour and per day:</p>

<ul>
	<li>Every time a user makes an AI request, the system counts how many requests they have made in the last 60 minutes, and also in the last 24 hours. And if either of these values exceeds the corresponding limit, then <u>it displays a message to the user</u> encouraging them to try again later.<br />
	&nbsp;</li>
	<li>Depending on the size of your organization and the type of use that your users/employees will make or need to make, it will be convenient for you to configure these two parameters differently.<br />
	&nbsp;<br />
	<em>For example, maybe you don&#39;t want a user to be able to make very intensive use of AI (generating texts, images, etc.) for a few hours. You can then configure a high hourly limit (for example, one request every 10 seconds would be 6 per minute and 360 per hour. But since you don&#39;t want this to encourage excessive use, you could set a limit of only 1400 every 24 hours. This way, you would allow intensive uses of AI, while ensuring some control over prolonged abusive use.</em></li>
</ul>
</div>

<div id="section_providers" style="padding-top:100px;margin-top:-50px;">
<h3>2. Integration with AI Providers</h3>

<p>This is the most interesting part and the one that will vary most frequently with each update. Over the coming months, more and more integrations with new providers or new models from the same providers will be added. So, if you want to make the most of it, <u>it would be recommended to update regularly</u>.</p>

<div class="block">
<p>To configure each provider:</p>

<ol>
	<li>Open an <u>account on the provider&#39;s platform</u> (the link appears in the panel)</li>
	<li>Generate a <u>unique key to use the API</u> of this provider and place it here</li>
	<li>Indicate which models from this provider you want to:<br />
	&nbsp;<br />
	- ALLOW THEIR USE to users<br />
	- DISPLAY to users <em>**</em></li>
</ol>
</div>

<p style="margin-left: 80px;"><em>** In some cases, it might be interesting to display a model that is not open for use, but that you are willing to activate if someone needs it. Because there are certainly models that are quite expensive to use normally, but can be very useful to activate at specific times.</em></p>

<p style="margin-left: 80px;"><strong><u>Note</u>:</strong> in the future, it is planned to implement the possibility of activating/deactivating models PER USER. This way, you will have better control over who consumes each AI service.<br />
&nbsp;</p>

<h4 id="sec_openai" style="padding-top:100px;margin-top:-50px;"><strong>OpenAI</strong></h4>

<ul>
	<li>This is the company that created the famous <u>chatGPT</u>, which has a particularity: it has models for EMBEDDINGS, which is a fundamental AI service to develop any <u>semantic search</u> system, that is, a user searches for &quot;felines&quot; and the system finds everything related to cats and other felines, even if the word to search was misspelled.<br />
	&nbsp;<br />
	This <u>embeddings system is the one that will be used for the search engine in the chat history of each user</u>, in the very near future. It&#39;s actually a feature that will be implemented as OPTIONAL, but it&#39;s really worth it and the consumption of this type of AI embeddings is very cheap, which is why I highly recommend it. It can increase your AI consumption by barely 1%, but what you get in return is radically beneficial.<br />
	&nbsp;</li>
	<li>The text models have <u>different prices for INPUT</u> (what the user writes, including any document they attach) than for OUTPUT (the model&#39;s response).<br />
	&nbsp;</li>
	<li><u>Consumption is measured</u> in MILLIONS OF TOKENS. &quot;Tokens&quot; are &quot;a part of a word&quot; and roughly equivalent to one or two human syllables. Thus, a million tokens is equivalent to more than TWO THOUSAND PAGES OF AN AVERAGE BOOK. The use of these AIs is therefore quite economical.<br />
	&nbsp;<br />
	<em>Note: In a conversation with the AI, <u>each new message includes all the previous ones</u>. This allows the AI to &quot;remember&quot; the context, but <u>exponentially increases resource consumption</u> as the conversation progresses, as the AI rereads the entire history with each interaction.<br />
	&nbsp;<br />
	The recommendation is that <u>when you need to change the subject, you open a new conversation</u>.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-06_EN.png" /></p>

<p>&nbsp;</p>

<h4 id="sec_anthropic" style="padding-top:100px;margin-top:-50px;">Anthropic.com</h4>

<p>Anthropic is the company behind the Claude models, which in my opinion are currently the most competent for code generation, multilingual translation, and text content structuring:</p>

<ul>
	<li>For &quot;<u><strong>working with texts and generating texts</strong></u>&quot;, which works as we are accustomed to what ChatGPT does:<br />
	&nbsp;<br />
	<em><u>The model will respond based on all the information it has been trained on</u>, which has a specific cut-off date. Beyond the end of their training date, these models do not have access to updated information.<br />
	<br />
	The Haiku model, which is the most economical, is quite good for 90% of the tasks requested. The Sonnet model is brilliant but costs about 4 times more per million tokens.</em><br />
	&nbsp;</li>
	<li>For &quot;<u><strong>SEEING image content</strong></u>&quot;, meaning that in the chat conversation we can attach images for it to &quot;see&quot; and respond to queries about them. For example: interpreting statistical tables or graphs, reading chemical formulas, or geometric mathematical problems, etc.<br />
	&nbsp;<br />
	<em>This VISION capability is only available in the Sonnet model. You&#39;ll notice that in the module, models with this VISION capability are marked with an EYE icon.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2025/ai-assistants-settings-09_EN.jpg" /></p>

<p>&nbsp;</p>

<h4 id="sec_perplexity" style="padding-top:100px;margin-top:-50px;">Perplexity</h4>

<p>Perplexity is a fabulous provider of Internet search using AI, which integrates different open source models from different providers on its servers. Specifically, through its API, to date, it offers the Llama 3.1 family of models from Meta to be used in two modalities:</p>

<ul>
	<li><u>Simply to &quot;<strong>chat</strong>&quot;</u>, which would work as we are used to chatGPT doing.<br />
	&nbsp;<br />
	<em>That is, <u>the model will respond based on all the information with which it has been trained</u>, which has a specific cut-off date. Beyond the end of its training date, these models do not have access to updated information.</em><br />
	&nbsp;</li>
	<li><u>To &quot;<strong>search online</strong>&quot;</u>, which is quite different: it searches the Internet (using Bing) for interesting information for our question and builds a &quot;good answer&quot;.<br />
	&nbsp;<br />
	<em>Obviously, the quality of the answer depends a lot on the quality of the search results.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-07_EN.png" /></p>

<h4 id="sec_falai" style="padding-top:100px;margin-top:-50px;">fal.ai</h4>

<p>FAL.AI is a company that allows us to access their servers via API to use <strong>third-party image and video generation and editing models</strong>. Specifically, in this Dolibarr module, we will be using:</p>

<ul>
	<li><u>The FLUX family of models</u>, which appeared in early 2024 and for several months were the best at generating photo-realistic images that include written text (on signs, caps, t-shirts, cars, etc.), although mainly in ENGLISH. It doesn&#39;t perform as well in other languages, especially with long phrases or words that &quot;aren&#39;t in the dictionary,&quot; like unknown company names or brands. In summer, the Ideogram 2.0 model (from another company) surpassed FLUX in its ability to include text in images, and as of today (November 2024), it remains the only one that does it well 80% of the time in non-English languages.<br />
	&nbsp;<br />
	<em>Although FLUX.1 models were released, fal.ai only offers us the initial FLUX models, which are still very good at generating images with text:</em>

	<p><em>- <u>flux-schnell</u>: the most economical... about <strong>300 images per $1 USD!!!!</strong><br />
	- <u>flux-pro</u>: maximum quality, although for $1 USD you can generate &quot;only&quot; 20 super-quality images<br />
	- <u>flux-dev</u>: the intermediate model... about 40 images per $1 USD</em></p>
	</li>
	<li>You can also use <u>some Stable Diffusion models</u>, which is a veteran in image generation, specifically these models:<br />
	<br />
	<em>- fast-turbo-difussion: 14,000 images per $1 USD !!!<br />
	- sd-v3-medium: 30 images per $1 USD.</em><br />
	<br />
	<u>Note</u>: These models are very good with vector drawings and artistic drawings, comics, etc. Not so much with photo-realistic images unless you use them with LORAS. But this is beyond the scope of this module. If you&#39;re interested in this, I recommend using StableDiffusion through <u>fal.ai</u>&#39;s web interface.</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-08_EN.png" /></p>

<p><strong>Technical details regarding image generation:</strong></p>

<ul>
	<li>The images that your Dolibarr users generate in their conversations will be stored in /documents/1/99 (where &quot;1&quot; is the user ID, and &quot;99&quot; is the ID of each chat). Later, I will implement some way to control how much space the generated images occupy. Currently, they take up approximately between 500Kb and 1Mb, depending on the dimensions and model.</li>
	<li>I have programmed the module to make it easy to share images between Dolibarr users: if they pass the image link (you can get it by opening the image in a new tab), they can download the image as long as they are logged in.</li>
	<li>Just like with chat and search models, different models can be used in the same conversation: that is, you can switch to an image generation model mid-conversation with any of the text models to generate some images.</li>
	<li>In any case, the models that generate images don&#39;t take into account the other messages in that conversation at all, and similarly, the generated images are not taken into account by the text models, even if they are in the same conversation.</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-04_EN.jpg" /></p>
</div>

<div id="section_chat" style="padding-top:100px;margin-top:-50px;">
<h3>3. Conversing with an AI</h3>

<p>When accessing the AI section from the top menu, we&#39;ll see a screen like the following, which is where each user will:</p>

<ol>
	<li>&quot;converse&quot; with different AI models</li>
	<li>interact with their conversation history</li>
</ol>

<p>It&#39;s a simple two-panel interface:</p>

<ul>
	<li>Left panel: conversation history</li>
	<li>Right panel: conversation</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-01_EN.png" /></p>

<p>I don&#39;t want to unnecessarily lengthen this guide, I think almost all functions and buttons are quite obvious, so I&#39;ll only comment on the most relevant. If you think something is not answered, please leave a comment at the bottom so I can complement that information here. Thank you!</p>

<h4>Graphic Elements</h4>

<ul>
	<li><u>Grayscale buttons</u> are buttons for functions planned to be implemented soon. They will be activated in successive updates.</li>
	<li>The <u>basic way of working</u> is by pressing the &quot;+&quot; button to start a new conversation, or by clicking on any from the history to continue with it.</li>
	<li>In the right panel, you have a button to <u>hide the left panel</u>.</li>
	<li>In the right panel, you have a <u>button to &quot;maximize&quot; the chat area</u>:<br />
	1. hides the left panel<br />
	2. hides the top Dolibarr menu bar<br />
	3. maximizes your browser window</li>
	<li>When writing a new message, you can use the ENTER key to add line breaks, and you can <u>use the TAB key to position the focus on the SEND MESSAGE button</u>. This way you can maintain a conversation without lifting your hand from the keyboard.</li>
</ul>

<h4>Chat Options</h4>

<p>When clicking on any three-dot icon (&middot;&middot;&middot;), a modal window (popup) emerges with:</p>

<ul>
	<li>the <u>numeric ID</u> of the conversation</li>
	<li>the <u>start date</u> of the conversation</li>
	<li>the <u>AI model</u> active or used in the last message of that chat (remember that in each message of the same chat you can use different models!)</li>
	<li>button to <u>share</u> (coming soon)</li>
	<li>button to <u>change the title</u> in the history (coming soon)</li>
	<li><u>DELETE</u> button (already working!), which will ask for confirmation before deleting</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-02_EN.png" /></p>

<h4>AI Model Selection</h4>

<p>When clicking on the previous &quot;AI Model&quot; button, a second dialog box emerges:</p>

<ul>
	<li>with the <u>list of models</u> that the administrator has configured as VISIBLE in the admin panel</li>
	<li><u>models appear disabled</u> that were configured as VISIBLE but NOT USABLE</li>
	<li>I decided to <u>include the price</u> to make end users aware of the (big!) price difference between using one model or another, and <u>encourage responsible use</u></li>
</ul>

<p style="margin-left: 40px;"><em><strong><u>Note</u>:</strong> right now there are only text generation models, but <u>soon</u> there will be image generation models, audio transcription, etc.</em></p>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-03_EN.png" /></p>

<p>&nbsp;</p>
</div>

<div id="section_next" style="padding-top:100px;margin-top:-50px;">
<h4>Coming Soon</h4>

<p>&nbsp;</p>

<p><strong>More integrations with AI providers</strong></p>

<p>If you&#39;ve been keeping up with this technological revolution we&#39;re experiencing with &quot;generative AIs&quot;, you know that new developments appear every week. So my intention is to add integration with more and more models and model providers. The idea is that from a single panel (from our Dolibarr) we have a solid base from which to benefit from these AIs, in a multi-user environment.</p>

<ul>
	<li>multi-language audio transcription (with OpenAI&#39;s Whisper)</li>
	<li>video generation (this is going to explode before the end of 2024!)</li>
	<li>audio generation from text (OpenAI, Azure Cognitive Services?)</li>
</ul>

<p>&nbsp;</p>

<p><strong>Interacting with the Dolibarr database</strong></p>

<p>Additionally, obviously, I&#39;m already looking at how access to data stored in our database could be integrated into these conversations with AI, whether to:</p>

<ul>
	<li>analyze trends</li>
	<li>summarize or retrieve data on customers, projects, products, etc.</li>
	<li>compare products, orders, etc...</li>
</ul>

<p>There&#39;s no doubt that AI can be very useful for interacting with our own data. I&#39;ll be working on it. If you have any useful references from people who already have something advanced in this, even if it&#39;s in another ERP, please leave me the reference in the comments!</p>

<p>&nbsp;</p>

<p><strong>Contextual AI functions</strong></p>

<p>I would also like to be able to add &quot;quick assistance buttons&quot; in the different listings and sheets of Dolibarr objects, and in text editors, with pre-recorded prompts such as:</p>

<ul>
	<li>translate to language X</li>
	<li>grammatically correct and improve a draft (email, ticket response, etc.)</li>
	<li>summarize a data table (of a customer&#39;s invoices, production, etc.)</li>
</ul>
</div>

<div id="section_demo" style="padding-top:100px;margin-top:-50px;">
<h4>Access to DEMO</h4>

<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">I am interested in accessing the DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_14_4562' action='index.php?pag=m_contactos&gad=formulario&id=14'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='14' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>I am interested to test Dolibarr DEMO</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Which module are you most interested in? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login and Country Filter								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login and Country Filter"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI Assistants								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="AI Assistants"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus and HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus and HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Editable lists								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Editable lists"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Purchases								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Purchases"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Annual billing charts								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Annual billing charts"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								StockTransfers								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="StockTransfers"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Search For Help in Forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Search For Help in Forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								 Mexican CFDI								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value=" Mexican CFDI"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								All								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="All"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>What is your preferred language? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Your email address *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Your name *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comment (optional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_11387' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_11387').html('<br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' />4<br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /> + <br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' />4<br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /><br style=\'display:none;\' rel=\'135\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_88759' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_88759' name='captcha_formstamp' value='ZVVaSmVVeFlOV0ppYVdKc2FWVnNUVTF3VFc5RFNXbFlObWQ1YmxOSVZHZzBWSEpVU1ROa1R6WnFjejA2T2pKa04yTTRNakkyWm1Ka01XSTJNekl5WVRZM1ltSmhZVEJqTXpkaVpqRTU' />
    <input type='hidden' id='captcha_valid_88759' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_88759').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_88759();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_88759').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_88759').val('');
                    $('#captcha_answer_88759').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_88759').val())+'&captcha_answer='+($('#captcha_answer_88759').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_88759').val(data.valid);
                    $('#captcha_answer_88759').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_88759').addClass('valid_captcha');
                    else
                        $('#captcha_answer_88759').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_88759(){
        if($('#captcha_answer_88759').val() == ''
                || $('#captcha_valid_88759').val()!='1'){

            $('#captcha_answer_88759').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_88759').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_14_4562();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_14_4562(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_14_4562');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_14_4562').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Manual de usuario del módulo Asistentes de IA para Dolibarr</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=104</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=104</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Tue, 10 Sep 2024 22:00:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/104.jpg" style="display: block; margin: 1em auto" /></p><p>Este módulo que puedes comprar en Dolistore te ofrece la posibilidad de poder usar muchos modelos de IAs generativas desde tu propio Dolibarr consumiendo lo mínimo a través de las APIs de los diferentes proveedores, en lugar de contratar pagos fijos mensuales por cada empleado de tu empresa.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/104.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>Este m&oacute;dulo que puedes comprar en Dolistore te ofrece la posibilidad de poder usar muchos modelos de IAs generativas desde tu propio Dolibarr consumiendo lo m&iacute;nimo a trav&eacute;s de las APIs de los diferentes proveedores, en lugar de contratar pagos fijos mensuales por cada empleado de tu empresa.</p>

<div class="a_c"><a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=105">Guide en fran&ccedil;ais</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=106">Guide in english</a> &nbsp;&middot;&nbsp; <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=104">Gu&iacute;a en espa&ntilde;ol</a></div>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Me interesa acceder a la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_13_2937' action='index.php?pag=m_contactos&gad=formulario&id=13'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='13' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Me interesa probar la DEMO de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>¿Cuál módulo te interesa más? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login y Filtro por país								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login y Filtro por país"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Asistentes IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Asistentes IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus y HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus y HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listas editables								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Listas editables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Compras								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Compras"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferencia de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferencia de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Gráficos facturación anual								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Gráficos facturación anual"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Buscar ayuda en Foros								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Buscar ayuda en Foros"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI y contabilidad México								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI y contabilidad México"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Todos								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Todos"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>¿Cuál es tu idioma preferido? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Tu correo electrónico *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Tu nombre *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comentario (opcional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_33998' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_33998').html('<br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' />8<br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' /> + <br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' />5<br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' /><br style=\'display:none;\' rel=\'79258\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_82193' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_82193' name='captcha_formstamp' value='ZGxjM2VXaGpaVXh4VlhadVUwNDVjbUUyYTBOU2FYbFNiRTVQVFRKT0sxQkJVR2h6VUdGbFUyUjVUVDA2T21Vek1qYzJPREk0Tmprek5tUmxNR0l6WWpSbE5qbGpNamxoTkRWa09EUTA' />
    <input type='hidden' id='captcha_valid_82193' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_82193').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_82193();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_82193').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_82193').val('');
                    $('#captcha_answer_82193').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_82193').val())+'&captcha_answer='+($('#captcha_answer_82193').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_82193').val(data.valid);
                    $('#captcha_answer_82193').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_82193').addClass('valid_captcha');
                    else
                        $('#captcha_answer_82193').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_82193(){
        if($('#captcha_answer_82193').val() == ''
                || $('#captcha_valid_82193').val()!='1'){

            $('#captcha_answer_82193').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_82193').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_13_2937();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_13_2937(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_13_2937');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_13_2937').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/dolibarr-ASSISTANTS-AI-module_napkin-ES.svg" style="width:100%;max-width:1000px;" /></p>

<h3>&Iacute;ndice</h3>

<p>Si no eres un usuario administrador en tu Dolibarr, puedes pasar al punto 3 de esta manual.</p>

<ol>
	<li><a href="#section_install">Proceso de instalaci&oacute;n</a></li>
	<li><a href="#section_providers">Integraci&oacute;n con proveedores de IA</a>
	<ul>
		<li><a href="#sec_openai">OpenAI.com</a> (generaci&oacute;n de texto)</li>
		<li><a href="#sec_anthropic">Anthropic.com</a> (generaci&oacute;n de texto con visi&oacute;n)</li>
		<li><a href="#sec_perplexity">Perplexity.ai</a> (gen. de texto y b&uacute;squeda en internet)</li>
		<li><a href="#sec_falai">Fal.ai</a> (gen. de im&aacute;genes con FLUX y StableDifussion)</li>
	</ul>
	</li>
	<li><a href="#section_chat">Conversar con una IA</a></li>
	<li><a href="#section_next">Pr&oacute;ximamente</a></li>
	<li><a href="#section_demo">Acceso a DEMO</a></li>
</ol>

<div id="section_install" style="padding-top:100px;margin-top:-50px;">
<h3>1. Proceso de instalaci&oacute;n</h3>

<p>Primeramente lo de costumbre en la instalaci&oacute;n de cualquier m&oacute;dulo de Dolibarr:</p>

<ol>
	<li>Ir a la secci&oacute;n <u>Configuraci&oacute;n</u></li>
	<li>Ir a <u>M&oacute;dulos</u></li>
	<li>Ir a pesta&ntilde;a <u>Instalar m&oacute;dulo externo</u>, y ah&iacute; subes el ZIP del m&oacute;dulo o su actualizaci&oacute;n</li>
	<li>Volvemos a la pesta&ntilde;a <u>M&oacute;dulos disponibles</u></li>
	<li><u>Filtramos por Origen</u>: &quot;Externo - IMASDEWEB&quot;</li>
	<li><u>Activamos</u> el m&oacute;dulo</li>
	<li>Pulsamos sobre el <u>icono de Configuraci&oacute;n</u></li>
</ol>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-04_ES.png" /></p>

<p>En un primer apartado Miscel&aacute;nea podemos configurar cosas como el &quot;Modelo por defecto&quot;. Este ser&aacute; el modelo con el que se iniciar&aacute; un chat cuando el sistema no tenga en la variable de sesi&oacute;n del usuario informaci&oacute;n de cu&aacute;l es el &uacute;ltimo modelo que us&oacute;.</p>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-05_ES.png" /></p>

<h4>L&iacute;mite de uso por usuario</h4>

<p>Puedes configurar el l&iacute;mite de uso por usuario, tanto por hora como por d&iacute;a:</p>

<ul>
	<li>Cada vez que un usuario hace una solicitud de IA, el sistema cuenta cuantas solicitudes hizo en los &uacute;ltimos 60 minutos, y tambi&eacute;n en las &uacute;ltimas 24 horas. Y si algunos de esos valores superan el l&iacute;mite correspondiente entonces <u>le muestra un mensaje al usuario</u> anim&aacute;ndole a que pruebe m&aacute;s tarde.<br />
	&nbsp;</li>
	<li>Seg&uacute;n lo grande de tu organizaci&oacute;n y el tipo de uso que har&aacute;n o necesitan hacer tus usuarios/empleados, te convendr&aacute; configurar estos dos par&aacute;metros de manera diferente.<br />
	&nbsp;<br />
	<em>Por ejemplo, tal vez, no quieres que un usuario no pueda hacer un uso muy intensivo de la IA (generando textos, im&aacute;genes, etc.) durante un par de horas. Entonces puedes configurar un l&iacute;mite por hora alto (por ejemplo, una solicitud cada 10 segundos ser&iacute;an 6 por minuto y 360 por hora. Pero como no quieres que eso aliente a que lo usen demasiado, podr&iacute;as poner un l&iacute;mite de solamente 1400 cada 24 horas. De ese modo permitir&iacute;as usos intensivos de la IA, garantizando cierto control sobre un uso abusivo prolongado.</em></li>
</ul>
</div>

<div id="section_providers" style="padding-top:100px;margin-top:-50px;">
<h3>2. Integraci&oacute;n con proveedores de IA</h3>

<p>Esta es la parte m&aacute;s interesante y que ir&aacute; variando m&aacute;s frecuentemente con cada actualizaci&oacute;n. A lo largo de los siguiente meses se a&ntilde;adir&aacute;n m&aacute;s y m&aacute;s integraciones con nuevos proveedores o con nuevos modelos de mismos proveedores. As&iacute; que si quieres sacarle el m&aacute;ximo partido a esta materia, <u>ser&iacute;a recomendable actualizar regularmente</u>.</p>

<div class="block">
<p>Para configurar cada proveedor:</p>

<ol>
	<li>Abre una <u>cuenta en la plataforma del proveedor</u> (el enlace aparece en el panel)</li>
	<li>Genera una <u>clave &uacute;nica para usar la API</u> de ese proveedor y la colocas aqu&iacute;</li>
	<li>Indicas qu&eacute; modelos de ese proveedor quieres:<br />
	&nbsp;<br />
	- PERMITIT SU USO a los usuarios<br />
	- VISUALIZAR a los usuarios <em>**</em></li>
</ol>
</div>

<p style="margin-left: 80px;"><em>** En alg&uacute;n caso podr&iacute;a interesar mostrar alg&uacute;n modelo que no est&aacute; abierto para ser usado, pero que est&aacute;s dispuesto a habilitarlo si alguien lo necesita. Porqu&eacute; ciertamente hay modelos bastante caros para ser usado con normalidad, pero que pueden resultar muy &uacute;tiles activarlos en momentos puntuales.</em></p>

<p style="margin-left: 80px;"><strong><u>Nota</u>:</strong> a futuro est&aacute; previsto implementar la posibilidad de que habilites/deshabilites los modelos POR USUARIO. De este modo tendr&aacute;s mayor control sobre quien consume cada servicio de IA.<br />
&nbsp;</p>

<h4 id="sec_openai" style="padding-top:100px;margin-top:-50px;"><strong>OpenAI.com</strong></h4>

<ul>
	<li>Es la empresa creadora del famoso <u>chatGPT</u>, que tiene una particularidad: tiene modelos para EMBEDDINGS, que es un servicio de IA fundamental para desarrollar cualquier sistema de <u>b&uacute;squeda sem&aacute;ntica</u>, es decir que un usuario busque &quot;felinos&quot; y el sistema le encuentre cualquier cosa relacionada con gatos y otros felinos, incluso aunque la palabra a buscar se haya escrito mal.<br />
	&nbsp;<br />
	Este <u>sistema de embeddings es el que se va a usar para el buscador en el historial de los chats de cada usuario</u>, en un futuro muy pr&oacute;ximo. Realmente es una funcionalidad que se va a implementar como OPCIONAL, pero ciertamente vale mucho la pena y es barat&iacute;simo el consumo de este tipo de IA de embeddings, por eso te lo recomiendo enormemente. Puede incrementar tu consumo de IA en un 1% apenas, pero lo que obtienes a cambios es radicalmente provechoso.<br />
	&nbsp;</li>
	<li>Los modelos de texto tienen <u>precios diferentes para el INPUT</u> (lo que escribe el usuario, inclu&iacute;do cualquier documento que adjunte) que para el OUTPUT (la respuesta del modelo).<br />
	&nbsp;</li>
	<li><u>El consumo se mide</u> en MILLONES DE TOKENS. Los &quot;tokens&quot; son &quot;una parte de una palabra&quot; y equivalen aproximadamente a una o dos s&iacute;labas humanas. Entonces un mill&oacute;n de tokens equivale como a m&aacute;s de DOS MIL P&Aacute;GINAS DE UN LIBRO medio. As&iacute; que es bastante econ&oacute;mico el uso de estas IAs.<br />
	&nbsp;<br />
	<em>Nota: En una conversaci&oacute;n con IA, <u>cada nuevo mensaje incluye todos los anteriores</u>. Esto permite que la IA &quot;recuerde&quot; el contexto, pero <u>aumenta exponencialmente el consumo de recursos</u> a medida que la conversaci&oacute;n avanza, ya que la IA relee todo el historial en cada interacci&oacute;n.<br />
	&nbsp;<br />
	La recomendaci&oacute;n es que <u>cuando tengas que cambiar de tema abras una nueva conversaci&oacute;n</u>.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-06_ES.png" /></p>

<p>&nbsp;</p>

<h4 id="sec_anthropic" style="padding-top:100px;margin-top:-50px;">Anthropic.com</h4>

<p>Anthropic es la empresa detr&aacute;s de los modelos Claude, que par a mi gusto a fecha de hoy son los m&aacute;s competentes para cuestiones de generaci&oacute;n de c&oacute;digo, traducci&oacute;n multling&uuml;e y estructuraci&oacute;n de contenidos de texto:</p>

<ul>
	<li><u>Para &quot;<strong>trabajar con textos y generando textos</strong>&quot;</u>, que funciona a como estamos acostumbrado a lo que hace chatGPT:<br />
	&nbsp;<br />
	<em><u>El modelo responder&aacute; en base a toda la informaci&oacute;n con la que ha sido entrenado</u>, la cu&aacute;l tiene una fecha l&iacute;mite concreta. M&aacute;s all&aacute; de la finalizaci&oacute;n de su fecha de entrenamiento, estos modelos no tienen acceso a informaci&oacute;n actualizada.<br />
	<br />
	El modelo Haiku que es el m&aacute;s econ&oacute;mico es bastante bueno para el 90% de las tareas que se le pida. El modelo Sonnet es brillante, pero cuesta unas 4 veces m&aacute;s por mill&oacute;n de tokens.</em><br />
	&nbsp;</li>
	<li><u>Para &quot;<strong>VER el contenido en im&aacute;genes</strong>&quot;</u>, es decir, que en la conversaci&oacute;n de chat podemos adjuntar im&aacute;genes para que las &quot;vea&quot; y nos responda consultas sobre ello. Por ejemplo: interpretar tablas o gr&aacute;ficos estad&iacute;sticos, o leer f&oacute;rmulas qu&iacute;micas, o problemas matem&aacute;ticos de geomter&iacute;a, etc.<br />
	&nbsp;<br />
	<em>Esta habilidad de VISION solamente la tiene el modelo Sonnet. Ver&aacute;s que en el m&oacute;dulo se se&ntilde;alan con el icono de un OJO los modelos que tienen esta capacidad de VISION.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2025/ai-assistants-settings-09_ES.jpg" /></p>

<p>&nbsp;</p>

<h4 id="sec_perplexity" style="padding-top:100px;margin-top:-50px;">Perplexity.ai</h4>

<p>Perplexity es un proveedor fabuloso de b&uacute;squeda en internet usando IA, que integra en sus servidores diferentes modelos opensource de diferentes proveedores. En concreto, a trav&eacute;s de su API, a d&iacute;a de hoy ofrece la familia de modelos Llama 3.1 de Meta para usar en dos modalidades :</p>

<ul>
	<li><u>Simplemente para &quot;<strong>chatear</strong>&quot;</u>, que funcionar&iacute;a como estamos acostumbrado a lo que hace chatGPT.<br />
	&nbsp;<br />
	<em>Es decir, que <u>el modelo responder&aacute; en base a toda la informaci&oacute;n con la que ha sido entrenado</u>, la cu&aacute;l tiene una fecha l&iacute;mite concreta. M&aacute;s all&aacute; de la finalizaci&oacute;n de su fecha de entrenamiento, estos modelos no tienen acceso a informaci&oacute;n actualizada.</em><br />
	&nbsp;</li>
	<li><u>Para &quot;<strong>buscar en l&iacute;nea</strong>&quot;</u>, que es algo bastante diferente: busca en internet (usando Bing) informaci&oacute;n de inter&eacute;s a nuestra pregunta y construye una &quot;buena respuesta&quot;.<br />
	&nbsp;<br />
	<em>Obviamente la calidad de la respuesta depende mucho de la calidad de los resultados de b&uacute;squeda.</em></li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-07_ES.png" /></p>

<p>&nbsp;</p>

<h4 id="sec_falai" style="padding-top:100px;margin-top:-50px;">fal.ai</h4>

<p>FAL.AI es una empresa que nos permite acceder por API a sus servidores para usar modelos de generaci&oacute;n y edici&oacute;n de im&aacute;genes y/o video de terceros. En concreto en este m&oacute;dulo para Dolibarr estaremos usando:</p>

<ul>
	<li>La familia de modelos <u>FLUX</u>, que aparecieron a principios de 2024 y por unos meses fueron los mejores generando im&aacute;genes foto-realistas que incluyen texto escrito (en carteles, gorras, camisetas, autom&oacute;viles, etc.), aunque sobre todo en INGL&Eacute;S. En otros idiomas no lo hace tan bien, especialmente si son frases largas o palabras que &quot;no est&aacute;n en el diccionario&quot;, como nombres de empresas o marcas no conocidas. En verano, el modelo Ideogram 2.0 (que es de otra empresa) super&oacute; a FLUX en su habilidad para incluir texto en las im&aacute;genes, y a d&iacute;a de hoy (Noviembre 2024) sigue siendo la &uacute;nica que lo hace bien el 80% de las veces que lo intenta en idiomas que no son el ingl&eacute;s.<br />
	&nbsp;<br />
	<em>Aunque ya salieron los modelos FLUX.1 en fal.ai solo nos ofrecen usar los FLUX iniciales, que de todos modos son muy buenos generando im&aacute;genes con texto:</em>

	<p><em>- <u>flux-schnell</u>: el m&aacute;s econ&oacute;mico... unas <strong>300 im&aacute;genes por $1 USD</strong> !!!!<br />
	- <u>flux-pro</u>: calidad m&aacute;xima, aunque por $1 USD podr&aacute;s generar &quot;solo&quot; 20 im&aacute;genes de super-calidad<br />
	- <u>flux-dev</u>: el modelo intermedio...unas 40 im&aacute;genes por $1USD</em></p>
	</li>
	<li>Tambi&eacute;n puedes usar algunos de los modelos de Stable Difussion, que es un veterano en este asunto de generar im&aacute;genes, en concreto estos modelos:<br />
	<br />
	<em>- fast-turbo-difussion: 14 mil im&aacute;genes por $1 USD !!!<br />
	- sd-v3-medium: 30 im&aacute;genes por $1 USD.</em><br />
	<br />
	<u>Nota</u>: estos modelos son muy buenos con dibujos vectoriales y dibujos art&iacute;sticos, c&oacute;mics, etc. No tanto con las im&aacute;genes foto-realistas, a menos que los uses con LORAS. Pero esto ya se escapa al objetivo de este m&oacute;dulo. Si te interesa esto te recomiendo que uses StableDifussion desde la interfaz web de <u>fal.ai</u>.<br />
	&nbsp;</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-settings-08_ES.png" /></p>

<p><strong>Detalles t&eacute;cnicos en cuanto a la generaci&oacute;n de im&aacute;genes</strong></p>

<ul>
	<li>Las im&aacute;genes que los usuarios de tu Dolibarr vayan generando en sus conversaciones quedar&aacute;n almacenadas en /documents/1/99 (donde &quot;1&quot; es el ID de usuario, y &quot;99&quot; el ID de cada chat en cuesti&oacute;n). M&aacute;s adelante implementar&eacute; alguna manera de poder controlar cu&aacute;nto espacio van ocupando las im&aacute;genes generadas. Apr&oacute;ximadamente ahora pesan entre 500Kb y 1Mb, dependiendo de las dimensiones y del modelo.</li>
	<li>He programado el m&oacute;dulo para que sea f&aacute;cil compartirse las im&aacute;genes entre usuarios de Dolibarr: si se pasan el enlace de la imagen (puedes obtenerlo abriendo la imagen en una pesta&ntilde;a nueva) pueden descargarse la imagen siempre y cuando tengan sesi&oacute;n iniciada.</li>
	<li>Igual que con los modelos de chat y de b&uacute;squeda, en una misma conversaci&oacute;n pueden usarse diferentes modelos: es decir, puedes cambiar a un modelo de generaci&oacute;n de im&aacute;genes a media conversaci&oacute;n con cualquiera de los modelos de texto para generar unas cuantas im&aacute;genes.</li>
	<li>En cualquier caso, los modelos que generan im&aacute;genes no tienen en cuenta para nada los otros mensajes de esa conversaci&oacute;n, y del mismo modo, las im&aacute;genes generadas tampoco se tienen en cuenta por los modelos de texto, aunque est&eacute;n en la misma conversaci&oacute;n.</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-04_ES.jpg" /></p>
</div>

<div id="section_chat" style="padding-top:100px;margin-top:-50px;">
<h3>3. Conversar con una IA</h3>

<p>Al acceder a la secci&oacute;n IA del men&uacute; superior, veremos una pantalla como la siguiente, que ser&aacute; d&oacute;nde cada usuario:</p>

<ol>
	<li>&quot;conversar&aacute;&quot; con los diferentes modelos de IA</li>
	<li>interactuar&aacute; con su historial de conversaciones</li>
</ol>

<p>Es una interfaz sencilla de dos paneles:</p>

<ul>
	<li>Panel izquierdo: historial de conversaciones</li>
	<li>Panel derecho: conversaci&oacute;n</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-01_ES.png" /></p>

<p>No quiero alargar esta gu&iacute;a innecesariamente, creo que casi todas las funciones y botones son bastante obvios, as&iacute; que comentar&eacute; nada m&aacute;s lo m&aacute;s relevante. Si crees que algo no queda respondido, por favor deja un comentario abajo de todo para que complemente esa informaci&oacute;n ac&aacute;. Gracias!</p>

<h4>Elementos gr&aacute;ficos</h4>

<ul>
	<li>Los <u>botones en escala de grises</u> son botones de funciones previstas de implementar pr&oacute;ximamente. En sucesivas actualizaciones se ir&aacute;n activando.</li>
	<li>La <u>forma b&aacute;sica de trabajar</u> es pulsando el bot&oacute;n &quot;+&quot; para iniciar una nueva conversaci&oacute;n, o bien pulsar sobre cualquiera del historial para continuar con ella.</li>
	<li>En el panel derecho tienes un bot&oacute;n para <u>ocultar el panel izquierdo</u>.</li>
	<li>En el panel derecho tienes un <u>bot&oacute;n para &quot;maximizar&quot; el &aacute;rea de chat</u>:<br />
	1. oculta el panel izquierdo<br />
	2. oculta la barra superior de men&uacute;s de Dolibarr<br />
	3. maximiza tu ventana del navegador</li>
	<li>Cuando redactes un nuevo mensaje, puedes usar la tecla INTRO/ENTER para agregar saltos de l&iacute;nea, y puedes <u>usar la tecla TABULADOR para posicionar el foco en el bot&oacute;n de ENVIAR MENSAJE</u>. De este modo puedes mantener una conversaci&oacute;n sin levantar la mano del teclado.</li>
</ul>

<h4>Opciones de un chat</h4>

<p>Al pulsar sobre cualquier icono del tipo tres puntos (&middot;&middot;&middot;) emerge una ventana modal (popup) con:</p>

<ul>
	<li>el <u>ID num&eacute;rico</u> de la conversaci&oacute;n</li>
	<li>la <u>fecha de inicio</u> de la conversaci&oacute;n</li>
	<li>el <u>modelo de IA</u> activo o usado en el &uacute;ltimo mensaje de ese chat (recuerda que en cada mensaje de un mismo chat puedes usar diferentes modelos!)</li>
	<li>bot&oacute;n para <u>compartir</u> (pr&oacute;ximamente)</li>
	<li>bot&oacute;n para <u>cambiar el t&iacute;tulo</u> en el historial (pr&oacute;ximamente)</li>
	<li>bot&oacute;n <u>ELIMINAR</u> (ya funciona!), que te pedir&aacute; confirmaci&oacute;n antes de eliminar</li>
</ul>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-02_ES.png" /></p>

<h4>Selecci&oacute;n de modelo de IA</h4>

<p>Al pulsar sobre el anterior bot&oacute;n &quot;Modelo IA&quot; emerge un segundo recuadro de di&aacute;logo:</p>

<ul>
	<li>con la <u>lista de modelos</u> que el administrador haya configurado como VISIBLES en el panel de administrador</li>
	<li><u>aparecen desactivados</u> los modelos que se configuraron como VISIBLES pero NO USABLES</li>
	<li>he decidido <u>incluir el precio</u> para hacer copart&iacute;cipe a los usuarios finales de la diferencia (grande!) de precio entre usar un modelo u otro, y <u>fomentar un uso responsable</u></li>
</ul>

<p style="margin-left: 40px;"><em><strong><u>Nota</u>:</strong> ahora mismo solo hay modelos de generaci&oacute;n de texto, pero <u>pr&oacute;ximamente</u> habr&aacute; modelos de generaci&oacute;n de im&aacute;genes, de transcripci&oacute;n de audio, etc.</em></p>

<p class="a_c"><img alt="" src="https://imasdeweb.com/UserFiles/Image/2024/ai-assistants-chat-dashboard-03_ES.png" /></p>

<p>&nbsp;</p>
</div>

<div id="section_next" style="padding-top:100px;margin-top:-50px;">
<h4>Pr&oacute;ximamente</h4>

<p>&nbsp;</p>

<p><strong>M&aacute;s integraciones con proveedores de IA</strong></p>

<p>Si has estado al tanto de esta revoluci&oacute;n tecnol&oacute;gica que estamos viviendo con las &quot;IAs generativas&quot; sabes que cada semana aparecen novedades. As&iacute; que mi voluntad es la de agregar integraci&oacute;n que m&aacute;s y m&aacute;s modelos y proveedores de modelos. La idea es que desde un mismo panel (desde nuestro Dolibarr) tengamos una base s&oacute;lida desde donde beneficiarnos de estas IAs, en un entorno multisuario.</p>

<ul>
	<li>transcripci&oacute;n multi-idioma de audios (con Whisper de OpenAI)</li>
	<li>generaci&oacute;n de videos (esto va a explotar antes de fin de 2024!)</li>
	<li>generaci&oacute;n de audio a partir de texto (OpenAI, Azure Cognitive Services?)</li>
</ul>

<p>&nbsp;</p>

<p><strong>Interactuar con la base de datos de Dolibarr</strong></p>

<p>Adem&aacute;s, obviamente, tambi&eacute;n ando ya viendo c&oacute;mo podr&iacute;a integrarse en estas conversaciones con la IA el acceso a los datos almacenados en nuestra base de datos, ya sea para:</p>

<ul>
	<li>analizar tendencias</li>
	<li>resumir o recuperar datos de clientes, proyectos, productos, etc.</li>
	<li>comparar productos, pedidos, etc...</li>
</ul>

<p>No cabe duda de que la IA puede sernos muy &uacute;til para interactuar con nuestros propios datos. Estar&eacute; trabajando en ello. Si tienes cualquier referencia &uacute;til de gente que ya tenga algo avanzado en eso, aunque sea en otro ERP, por favor, d&eacute;jame la referencia en los comentarios!</p>

<p>&nbsp;</p>

<p><strong>Funciones de IA contextuales</strong></p>

<p>Tambi&eacute;n me gustar&iacute;a poder agregar &quot;botones r&aacute;pidos de asistencia&quot; en los diferentes listados y fichas de los objetos de Dolibarr, y en los editores de texto, con prompts pre-grabados del tipo:</p>

<ul>
	<li>traducir al idioma X</li>
	<li>corregir gramaticalmente y mejorar un redactado (email, respuesta de ticket, etc.)</li>
	<li>resumir una tabla de datos (de facturas de un cliente, de producci&oacute;n, etc.)</li>
</ul>
</div>

<div id="section_demo" style="padding-top:100px;margin-top:-50px;">
<h4>Acceso a la DEMO</h4>
<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Me interesa acceder a la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_13_9625' action='index.php?pag=m_contactos&gad=formulario&id=13'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='13' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Me interesa probar la DEMO de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>¿Cuál módulo te interesa más? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login y Filtro por país								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login y Filtro por país"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Asistentes IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Asistentes IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus y HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus y HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listas editables								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Listas editables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Compras								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Compras"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferencia de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferencia de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Gráficos facturación anual								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Gráficos facturación anual"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Buscar ayuda en Foros								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Buscar ayuda en Foros"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI y contabilidad México								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI y contabilidad México"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Todos								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Todos"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>¿Cuál es tu idioma preferido? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Tu correo electrónico *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Tu nombre *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Comentario (opcional) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_40940' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_40940').html('<br style=\'display:none;\' rel=\'85\' /><br style=\'display:none;\' rel=\'85\' />6<br style=\'display:none;\' rel=\'85\' /><br style=\'display:none;\' rel=\'85\' /> + <br style=\'display:none;\' rel=\'85\' /><br style=\'display:none;\' rel=\'85\' />1<br style=\'display:none;\' rel=\'85\' /><br style=\'display:none;\' rel=\'85\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_83314' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_83314' name='captcha_formstamp' value='TTNSd1ltbDRWRWhYUTBSTU0yc3piV3RYYUVzNVUzZFdkbXhVYmpaNFUxaG1RVUl6YmpNelRVUlhNRDA2T21SaVl6TTRaV1ZpWTJVM05qaGxNR1JpTVRZNE9ERTVOemhoTlRsaE5EWXg' />
    <input type='hidden' id='captcha_valid_83314' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_83314').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_83314();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_83314').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_83314').val('');
                    $('#captcha_answer_83314').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_83314').val())+'&captcha_answer='+($('#captcha_answer_83314').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_83314').val(data.valid);
                    $('#captcha_answer_83314').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_83314').addClass('valid_captcha');
                    else
                        $('#captcha_answer_83314').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_83314(){
        if($('#captcha_answer_83314').val() == ''
                || $('#captcha_valid_83314').val()!='1'){

            $('#captcha_answer_83314').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_83314').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_13_9625();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_13_9625(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_13_9625');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_13_9625').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
</div>

<p>&nbsp;</p>
]]></content:encoded>
        </item>
        
        <item>
            <title>Install Jitsi on HestiaCP using docker</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=103</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=103</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Tue, 27 Aug 2024 23:39:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/103.jpg" style="display: block; margin: 1em auto" /></p><p>The official Jitsi Docker allows for easy installation on an empty VM without much difficulty. However, installing it on a VM managed by HestiaCP, which handles multiple (sub)domains, is not straightforward. After spending half a week trying and reading many frustrated accounts of failed attempts, I finally succeeded. Here is what I describe below. It is essentially the same as the official guide, but the key lies in properly defining the ports and the NGINX reverse proxy.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/103.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>The official Jitsi Docker allows for easy installation on an empty VM without much difficulty. However, <u>installing Jitsi docker on a VM managed by HestiaCP</u>, which handles multiple (sub)domains, is not straightforward.<br />
&nbsp;<br />
After spending half a week trying and reading many frustrated accounts of failed attempts, I finally succeeded. Here is what I describe below. It is essentially the same as the official guide, but <u>the key lies in properly defining the ports and the NGINX reverse proxy</u>.</p>
</div>

<h3>Requeriments</h3>

<ul>
	<li>Minimum required hardware:&nbsp; 2 CPU + 2Gb RAM</li>
	<li>From HestiaCP, create a new user and new subdomain: <strong>live.mydomain.com</strong></li>
	<li>From HestiaCP install SSL certificate and set auto-redirect to the https for it.</li>
</ul>

<h3>Create a NGINX template</h3>

<p>You could edit the file <code>/etc/nginx/conf.d/domains/live.mydomain.com.ssl.conf</code> directly, but any changes would be lost when you update HestiaCP. To preserve the changes, the correct approach is to create an NGINX template and then assign it to your recently created subdomain.</p>

<p><u>Note</u>: <span>I chose port</span> <code>8445</code> <span>because it is free on my VM, but you can use any other port that is available. Keep in mind that this port number will be used later in the</span> <code>.env</code> <span>file for the Jitsi Docker container to listen on.</span></p>

<pre class="language-bash">
<code>cd /usr/local/hestia/data/templates/web/nginx/
cp default.tpl jitsi-port-8445.tpl
cp default.stpl jitsi-port-8445.stpl</code></pre>

<p>We only need to customize the <code>.stpl</code> :</p>

<pre class="language-bash">
<code>nano jitsi-port-8445.stpl</code></pre>

<p>You must set these lines replacing the existing ones:</p>

<pre class="language-bash">
<code>location / {
	proxy_pass https://%ip%:8445;
	proxy_http_version 1.1;
	proxy_set_header Host $host;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header X-Forwarded-Proto $scheme;

	# WebSocket support
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection &quot;upgrade&quot;;

	# Aumentar los timeouts para conexiones largas
	proxy_read_timeout 3600s;
	proxy_send_timeout 3600s;

	# Buffering
	proxy_buffering off;
}</code></pre>

<p>also change the port on this @fallback:</p>

<pre class="language-bash">
<code>location @fallback {
        proxy_pass https://%ip%:8445;
}</code></pre>

<p>and comment this line aswell:</p>

<pre class="language-bash">
<code># proxy_hide_header Upgrade;</code></pre>

<h3>Create a NGINX template</h3>

<p>Then we need set this template as <code>Proxy Template</code> for this subdomain:</p>

<ol>
	<li>go to <u>HestiaCP</u> on web browser</li>
	<li>edit the <u>subdomain</u> you have created</li>
	<li>click on <u>Advanced options</u></li>
	<li>on <u>Proxy Template</u> choose <u>jitsi-port-8445</u></li>
	<li>click <u>Save</u></li>
</ol>

<h3>Install docker</h3>

<pre class="language-bash">
<code>sudo apt update
sudo apt upgrade -y

sudo apt install apt-transport-https ca-certificates curl software-properties-common -y

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo &quot;deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &gt; /dev/null

sudo apt update
sudo apt install docker-ce -y
sudo systemctl status docker
docker ps
</code></pre>

<h3>Install docker compose:</h3>

<pre class="language-bash">
<code>sudo curl -L &quot;https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

docker-compose --version
</code></pre>

<h3>Install docker of Jitsi:</h3>

<ul>
	<li><code>live30</code> is the user i created on HestiaCP to admin the subdomain <code>live.mydomain.com</code>.</li>
	<li>I installed it in a new <code>docker</code> directory within the user&#39;s home directory, but you can perform the next installation steps in any other directory on your VM. I simply thought it would be a good idea to do it here.</li>
</ul>

<pre class="language-bash">
<code>mkdir /home/live30/docker
cd /home/live30/docker

wget $(curl -s https://api.github.com/repos/jitsi/docker-jitsi-meet/releases/latest | grep &#39;zip&#39; | cut -d\&quot; -f4)

unzip stable-9646
rm -rf stable-9646
mv jitsi-docker-jitsi-meet-1797ac8/ jitsi
cd jitsi

cp env.example .env
./gen-passwords.sh
nano .env
</code></pre>

<p>At the .env file you must set these lines as minimum:</p>

<ul>
	<li>i recommend to use the absolute path to the <code>.jitsi-meet-cfg</code> directory on CONFIG parameter</li>
	<li>i recommend to use 2 ports 100% free in your VM</li>
</ul>

<pre class="language-bash">
<code>...
CONFIG=/home/live30/docker/jitsi/.jitsi-meet-cfg
HTTP_PORT=8005
HTTPS_PORT=8445
TZ=America/Hermosillo
PUBLIC_URL=https://live.mydomain.com
...
ENABLE_AUTH=1 # let only registered users to create rooms
ENABLE_GUESTS=1
AUTH_TYPE=internal # using username &amp; passdord 
...
RESTART_POLICY=unless-stopped
</code></pre>

<p>Permanent storage out of docker container:</p>

<pre class="language-bash">
<code>mkdir -p ./.jitsi-meet-cfg/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
</code></pre>

<p>Modify <code>docker-compose.yml</code> to set jitsi network with static IPs:</p>

<pre class="language-bash">
<code>networks:
    meet.jitsi:
      ipam:
         driver: default
         config:
          - subnet: 172.20.0.0/16
</code></pre>

<p>on each web service set (incrementing the 172.20.0.2 on ipv4_address):</p>

<pre class="language-bash">
<code>        networks:
            meet.jitsi:
              ipv4_address: 172.20.0.2
</code></pre>

<p id="resulting-docker-compose-yml">The resulting <code>docker-compose.yml</code> file should look something like this:</p>

<pre class="language-bash">
<code>version: &#39;3.5&#39;

services:
    # Frontend
    web:
        image: jitsi/web:${JITSI_IMAGE_VERSION:-stable-9646}
        restart: ${RESTART_POLICY:-unless-stopped}
        ports:
            - &#39;${HTTP_PORT}:80&#39;
            - &#39;${HTTPS_PORT}:443&#39;
        volumes:
            - ${CONFIG}/web:/config:Z
            - ${CONFIG}/web/crontabs:/var/spool/cron/crontabs:Z
            - ${CONFIG}/transcripts:/usr/share/jitsi-meet/transcripts:Z
            - ./imasdeweb/watermark.svg:/usr/share/jitsi-meet/images/watermark.svg
        environment:
            - AMPLITUDE_ID
            - ANALYTICS_SCRIPT_URLS
 			- ... (long list)
            
        networks:
            meet.jitsi:
              ipv4_address: 172.20.0.2
        depends_on:
            - jvb

    # XMPP server
    prosody:
        image: jitsi/prosody:${JITSI_IMAGE_VERSION:-stable-9646}
        restart: ${RESTART_POLICY:-unless-stopped}
        expose:
            - &#39;${XMPP_PORT:-5222}&#39;
            - &#39;${PROSODY_S2S_PORT:-5269}&#39;
            - &#39;5347&#39;
            - &#39;${PROSODY_HTTP_PORT:-5280}&#39;
        volumes:
            - ${CONFIG}/prosody/config:/config:Z
            - ${CONFIG}/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z
        environment:
            - AUTH_TYPE
            - DISABLE_POLLS
 			- ... (long list)
 			
        networks:
            meet.jitsi:
                aliases:
                    - ${XMPP_SERVER:-xmpp.meet.jitsi}
                ipv4_address: 172.20.0.3

    # Focus component
    jicofo:
        image: jitsi/jicofo:${JITSI_IMAGE_VERSION:-stable-9646}
        restart: ${RESTART_POLICY:-unless-stopped}
        ports:
            - &#39;127.0.0.1:${JICOFO_REST_PORT:-8888}:8888&#39;
        volumes:
            - ${CONFIG}/jicofo:/config:Z
        environment:
            - AUTH_TYPE
            - BRIDGE_AVG_PARTICIPANT_STRESS
 			- ... (long list)
   			
        depends_on:
            - prosody
        networks:
            meet.jitsi:
              ipv4_address: 172.20.0.4

    # Video bridge
    jvb:
        image: jitsi/jvb:${JITSI_IMAGE_VERSION:-stable-9646}
        restart: ${RESTART_POLICY:-unless-stopped}
        ports:
            - &#39;${JVB_PORT:-10000}:${JVB_PORT:-10000}/udp&#39;
            - &#39;127.0.0.1:${JVB_COLIBRI_PORT:-8080}:8080&#39;
        volumes:
            - ${CONFIG}/jvb:/config:Z
        environment:
            - AUTOSCALER_SIDECAR_KEY_FILE
            - AUTOSCALER_SIDECAR_KEY_ID
 			- ... (long list)

        depends_on:
            - prosody
        networks:
            meet.jitsi:
              ipv4_address: 172.20.0.5

# Custom network so all services can communicate using a FQDN
networks:
    meet.jitsi:
      ipam:
         driver: default
         config:
          - subnet: 172.20.0.0/16
</code></pre>

<p>Run docker compose:</p>

<pre class="language-bash">
<code>docker compose up -d</code></pre>

<h3>Create user with authentication</h3>

<p>which are the unique which can create rooms:</p>

<pre class="language-bash">
<code>docker-compose exec prosody prosodyctl --config=/config/prosody.cfg.lua register [USERNAME] meet.jitsi [PASSWORD]
</code></pre>

<h3>BONUS EXTRA: Change&nbsp; corner logo</h3>

<p>As a final but important detail, especially in professional scenarios, is to change the default logo that appears in the top-left corner on both the home page and the conference view. By default, you see a semi-transparent Jitsi SVG logo. To replace it with your own, follow these steps:</p>

<p>1. upload the new SVG from your local console</p>

<pre class="language-bash">
<code>scp -P 22 watermark.svg root@live.mydomain.com:/home/live30/docker/jitsi</code></pre>

<p>2. from your VM console:</p>

<pre class="language-bash">
<code>cd /home/live30/docker/jitsi
nano docker-compose.yml</code></pre>

<p>on &quot;web&quot; service &quot;volumes&quot; add this line:</p>

<pre class="language-bash">
<code> - ./watermark.svg:/usr/share/jitsi-meet/images/watermark.svg</code></pre>

<p>3. finally restart your containers:</p>

<pre class="language-bash">
<code>docker compose up -d --force-recreate</code></pre>

<p style="text-align: center;"><b>It&#39;s all !!!</b><br />
Enjoy it 😎</p>

<p style="text-align: center;">&nbsp;</p>
]]></content:encoded>
        </item>
        
        <item>
            <title>Descubre los 4 trucos para crear imágenes increíbles con IA</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=102</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=102</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Mon, 19 Aug 2024 12:13:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/102.jpg" style="display: block; margin: 1em auto" /></p><p>Cuando le das a una IA generadora de imágenes una instrucción poco precisa, el resultado puede ser sorprendentemente alejado de lo que esperabas. En este artículo, te comparto cuatro consejos clave para lograr que la IA entienda y ejecute exactamente lo que tienes en mente. Desde cómo describir los elementos de la imagen, hasta la importancia de usar inglés en las instrucciones, pasando por el apoyo que puedes obtener de las IAs generadoras de texto, aquí encontrarás todo lo que necesitas saber para mejorar drásticamente los resultados de tus creaciones.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/102.jpg" style="display: block; margin: 1em auto" /></p><div class="block">Cuando le das a una IA generadora de im&aacute;genes una instrucci&oacute;n poco precisa, el resultado puede ser sorprendentemente alejado de lo que esperabas. En este art&iacute;culo, te comparto <u>cuatro consejos clave</u> para lograr que la IA entienda y ejecute exactamente lo que tienes en mente.<br />
&nbsp;<br />
Desde c&oacute;mo describir los elementos de la imagen, hasta la importancia de usar ingl&eacute;s en las instrucciones, pasando por el apoyo que puedes obtener de las IAs generadoras de texto, aqu&iacute; encontrar&aacute;s todo lo que necesitas saber para mejorar dr&aacute;sticamente los resultados de tus creaciones.</div>

<p>Esta imagen es lo que obtienes cuando le das una mala instrucci&oacute;n a una IA generadora de im&aacute;genes: &quot;<em>Anuncio cartel neum&aacute;ticos de ocasi&oacute;n para coches, furgonetas y camiones</em>&quot;. Claramente la imagen producida no es lo que el usuario esperaba.</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2024/generar-imagenes-con-IA_1.jpg" style="max-width:100%;" /></p>

<h3>🔸Primer consejo: <u>DESCRIBIR</u></h3>

<p>A las IAs generadoras de im&aacute;genes le has de dar una <strong>descripci&oacute;n de los elementos</strong> de la imagen. En este caso, algo como: &quot;Una fila de neum&aacute;ticos ordenados de menor a mayor sobre una carretera vac&iacute;a en el desierto.&quot; (por poner un ejemplo). No le hagas preguntas o esperes que le ponga creatividad para decidir qu&eacute; incluir o no en la imagen.</p>

<p>Los detalles de m&aacute;s que coloque la IA de im&aacute;genes ser&aacute;n para &quot;rellenar&quot; o &quot;adornar&quot; e ir&aacute;n en consonancia con los elementos que le hayas pedido. Pero si le pides algo como &quot;Haz un anuncio para neum&aacute;ticos de coches y camiones&quot;, puede salir cualquier cosa, y posiblemente muy alejado de lo que esperabas.</p>

<h3>🔸 Segundo consejo: <u>USAr IA DE TEXTO</u></h3>

<p>Si lo que quieres es algo de ayuda por parte de una IA para posibles ideas de COMPOSICI&Oacute;N de esa imagen, entonces <strong>debes ir a una IA generadora de texto</strong> (chatGPT, Claude, Llama, Mistral, etc.) y tener una CONVERSACI&Oacute;N explic&aacute;ndole acerca de la intenci&oacute;n y funci&oacute;n de tu imagen. Y pidi&eacute;ndole que te de varias ideas alternativas.</p>

<p>Finalmente, incluso es muy &uacute;til cerrar esa conversaci&oacute;n pidi&eacute;ndole algo como: &quot;Redacta una descripci&oacute;n de esta idea de imagen con todo detalle, para que una IA generadora de im&aacute;genes pueda crearla.&quot;. Y ver&aacute;s que te dar&aacute; una descripci&oacute;n que te va a funcionar muy bien. Abajo te muestro unos cuantos ejemplos pr&aacute;cticos.</p>

<h3>🔸 Tercer consejo: <u>USAR INGL&Eacute;S</u></h3>

<p>Las IAs generadoras de im&aacute;genes trabajan <strong>10 veces mejor</strong> si les das la descripci&oacute;n de la imagen en <strong>ingl&eacute;s</strong>!! Usa una IA de texto para traducir del espa&ntilde;ol al ingl&eacute;s. No trates de hacerlo t&uacute; mism@!!! digo, a menos que tengas nivel nativo. En este tipo de composiciones, escoger la palabra correcta determina demasiado el resultado.</p>

<h3>🔸 Cuarto consejo: <u>REDUCIR TEXTOS</u></h3>

<p>De momento las IAs generadoras de texto tienen bastantes problemas para <strong>agregar texto a las im&aacute;genes</strong> que producen. Estoy usando FLUX que es la m&aacute;s avanzada en este sentido (hasta donde s&eacute;, y a d&iacute;a de hoy Agosto 2024), y se sigue confundiendo much&iacute;simo.</p>

<p>Si el texto que quieres poner es de <strong>una sola palabra</strong> aumenta por mucho las probabilidades de que lo escriba bien. Y si es en ingl&eacute;s, incluso frases completas sin problema. Lo malo es en otros idiomas, como el espa&ntilde;ol. 🙁</p>

<p>Por tanto, mi consejo es que 1) uses poco texto, 2) tal vez el texto lo agregas despu&eacute;s con una herramienta de edici&oacute;n gr&aacute;fica cl&aacute;sica.<br />
&nbsp;</p>

<h2>😎 Procedimiento recomendado</h2>

<h3>1. IA GENERADORA DE TEXTO</h3>

<p>En mi caso he ido a <a class="a_icon" href="https://chatgpt.com/" target="_blank">chatGPT</a>, pero puedes usar <a class="a_icon" href="https://claude.ai/" target="_blank">ClaudeAI</a>, <a class="a_icon" href="https://www.meta.ai/" target="_blank">Llama (de Meta)</a>, <a class="a_icon" href="https://mistral.ai/" target="_blank">Mistral</a>, <a class="a_icon" href="https://www.perplexity.ai/" target="_blank">Perplexity</a>, o cualquier otra plataforma donde puedas interactuar con un chatbot conversacional tipo LLM.</p>

<p>Le he hecho esta petici&oacute;n:</p>

<blockquote>&quot;Ay&uacute;dame a generar un baner gr&aacute;fico que sirva como Anuncio cartel neum&aacute;ticos de ocasi&oacute;n para coches, furgonetas y camiones. Dame 3 alternativas interesantes.&quot;</blockquote>

<p>y me ha respondido esto:</p>

<blockquote style="font-size:0.9em;">
<p>Aqu&iacute; tienes tres ideas diferentes para un banner gr&aacute;fico sobre la venta de neum&aacute;ticos de ocasi&oacute;n:</p>

<p><strong>1. Opci&oacute;n 1: Estilo moderno y profesional</strong><br />
&nbsp;&nbsp; - <u>Fondo</u>: Un fondo oscuro con un patr&oacute;n sutil de textura de neum&aacute;tico.<br />
&nbsp;&nbsp; - <u>Texto principal</u>: &quot;&iexcl;Neum&aacute;ticos de Ocasi&oacute;n para Cualquier Veh&iacute;culo!&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp; - <u>Subtexto</u>: &quot;Coches, Furgonetas y Camiones&quot;<br />
&nbsp;&nbsp; - <u>Elementos gr&aacute;ficos</u>: Im&aacute;genes de neum&aacute;ticos de diferentes tama&ntilde;os colocados estrat&eacute;gicamente, como si estuvieran alineados en una fila, resaltando la variedad disponible.<br />
&nbsp;&nbsp; - <u>Llamada a la acci&oacute;n</u>: Un bot&oacute;n prominente que diga &quot;Ver Ofertas&quot; en color rojo o amarillo para captar la atenci&oacute;n.</p>

<p><strong>2. Opci&oacute;n 2: Estilo llamativo y din&aacute;mico</strong><br />
&nbsp;&nbsp; - <u>Fondo</u>: Colores vibrantes, como rojo y negro, con un efecto de velocidad o movimiento.<br />
&nbsp;&nbsp; - <u>Texto principal</u>: &quot;&iexcl;Las Mejores Ofertas en Neum&aacute;ticos de Ocasi&oacute;n!&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp; - <u>Subtexto</u>: &quot;Desde coches compactos hasta camiones pesados&quot;<br />
&nbsp;&nbsp; - <u>Elementos gr&aacute;ficos</u>: Un coche deportivo, una furgoneta y un cami&oacute;n en diferentes &aacute;ngulos, con neum&aacute;ticos destacados en primer plano. Podr&iacute;as incluir un medidor de ahorro en una esquina.<br />
&nbsp;&nbsp; - <u>Llamada a la acci&oacute;n</u>: Un banner inferior con &quot;Compra Ahora y Ahorra&quot;.</p>

<p><strong>3. Opci&oacute;n 3: Estilo limpio y minimalista</strong><br />
&nbsp;&nbsp; - <u>Fondo</u>: Blanco o gris claro con sombras suaves.<br />
&nbsp;&nbsp; - <u>Texto principal</u>: &quot;Neum&aacute;ticos de Ocasi&oacute;n para Cada Necesidad&quot;<br />
&nbsp;&nbsp;&nbsp;&nbsp; - <u>Subtexto</u>: &quot;Calidad a Precios Imbatibles para Coches, Furgonetas y Camiones&quot;<br />
&nbsp;&nbsp; - <u>Elementos gr&aacute;ficos</u>: Una sola imagen central de un neum&aacute;tico de alta calidad con reflejos, acompa&ntilde;ado por peque&ntilde;os &iacute;conos de coche, furgoneta y cami&oacute;n.<br />
&nbsp;&nbsp; - <u>Llamada a la acci&oacute;n</u>: Un bot&oacute;n en azul que diga &quot;Descubre M&aacute;s&quot;.</p>

<p>Estas opciones te dan variedad en cuanto a estilo y enfoque, para que puedas elegir la que mejor se ajuste a la imagen que quieres proyectar. &iquest;Te gustar&iacute;a que generara una de estas alternativas como imagen?</p>
</blockquote>

<p>Entonces el siguiente paso es <u>pedirle que no los ponga m&aacute;s f&aacute;cil</u> para trabajar con la <u>IA generadora de im&aacute;genes</u>, y le ped&iacute; esto:</p>

<blockquote>Ok, me encant&oacute; la primera. Redacta por favor un p&aacute;rrafo descriptivo para una IA generadora de im&aacute;genes, dando todos los detalles que puedan ayudar.</blockquote>

<p>A lo que respondi&oacute;:</p>

<blockquote>Create a modern and professional banner advertising second-hand tires for cars, vans, and trucks. The background should be dark with a subtle tire texture, giving a sleek and industrial feel. The main text reads &quot;<u>&iexcl;Neum&aacute;ticos de Ocasi&oacute;n para Cualquier Veh&iacute;culo!</u>&quot; in bold, metallic silver letters, with a smaller subtext below: &quot;<u>Coches, Furgonetas y Camiones</u>&quot; in a lighter shade of silver or white. Arrange images of tires in different sizes, aligned horizontally, to showcase the variety available. Each tire should be realistically detailed, with highlights and shadows to emphasize their texture and quality. Include a prominent call-to-action button in the lower right corner that says &quot;<u>Ver Ofertas</u>&quot; in bold red or yellow, contrasting sharply with the dark background. Ensure the overall layout is balanced, with the text and images well-distributed, giving the banner a professional and eye-catching look.</blockquote>

<h3>2. IA GENERADORA DE IM&Aacute;GENES: FLUX</h3>

<p>Entonces me fui a la plataforma <a class="a_icon" href="https://fal.ai/" target="_blank">fal.ai</a> donde puedes darte de alta gratuitamente y te regalan $12 USD de saldo para usar cualquiera de las IAs generadoras de im&aacute;genes que tienen, y us&eacute; el modelo FLUX-PRO (de <a class="a_icon" href="https://blackforestlabs.ai/" target="_blank">Black Forest Labs</a>, en Alemania) que es el m&aacute;s avanzado a d&iacute;a de hoy, apenas hace un mes que fue su estreno mundial y ha sido todo un exitazo.</p>

<p>Veamos la imagen que me gener&oacute; con el prompt anterior:</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2024/generar-imagenes-con-IA_2.jpg" style="max-width:100%;" /></p>

<p>No est&aacute; nada mal! mucho mejor!! ahora si parece un banner gr&aacute;fico publicitario. Aunque tal como puedes ver, &iexcl;&iexcl;el texto est&aacute; nefasto!!</p>

<p>De hecho, me fui de nuevo a chatGPT y le ped&iacute; <strong>un prompt para generar la segunda idea</strong> que me hab&iacute;a propuesto y me di&oacute; esto:</p>

<blockquote>Create a vibrant and dynamic banner for second-hand tires, targeting cars, vans, and trucks. The background should feature bold colors like red and black, with a motion effect to convey speed and energy. The main text reads &quot;<u>&iexcl;Las Mejores Ofertas en Neum&aacute;ticos de Ocasi&oacute;n!</u>&quot; in large, bold white letters, with a subtext underneath: &quot;<u>Desde coches compactos hasta camiones pesados</u>&quot; in a smaller, italicized font. Include dynamic images of a sports car, a van, and a truck, positioned at different angles to create a sense of motion. Highlight the tires prominently in the foreground, ensuring they appear glossy and new. In one corner, add a small savings meter to emphasize affordability. At the bottom of the banner, include a bright, eye-catching call-to-action bar with the text &quot;<u>Compra Ahora y Ahorra</u>&quot; in bold letters. The overall design should be energetic and attention-grabbing, perfect for attracting customers looking for a great deal.</blockquote>

<p>y al darle ese prompt a FLUX-PRO gener&oacute; esto otro:</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2024/generar-imagenes-con-IA_3.jpg" style="max-width:100%;" /></p>

<p>&iexcl;es mucho m&aacute;s espectacular! y tambi&eacute;n sigue teniendo ese aspecto de anuncio publicitario que andamos persiguiendo. Aunque de nuevo, el texto en espa&ntilde;ol qued&oacute; ilegible.</p>

<p>Repet&iacute; el proceso para la &uacute;ltima idea de chatGPT y me di&oacute; este prompt:</p>

<blockquote>Design a clean and minimalist banner for second-hand tires suitable for cars, vans, and trucks. Use a light background in white or soft grey, with gentle shadows to add depth. The main text reads &quot;<u>Neum&aacute;ticos de Ocasi&oacute;n para Cada Necesidad</u>&quot; in sleek, modern black or dark grey letters, centered on the banner. Below, in smaller, lighter text, add the subtext &quot;<u>Calidad a Precios Imbatibles para Coches, Furgonetas y Camiones.</u>&quot; Place a single, high-quality tire image in the center of the banner, with detailed reflections and textures to showcase its quality. Surround the tire with small, subtle icons representing a car, a van, and a truck, evenly spaced around it. In the bottom center, include a simple blue call-to-action button that reads &quot;<u>Descubre M&aacute;s</u>&quot; in a clean, readable font. The overall aesthetic should be refined, with a focus on simplicity and elegance, appealing to a discerning audience.</blockquote>

<p>y al d&aacute;rselo a FLUX me gener&oacute; esto:</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2024/generar-imagenes-con-IA_4.jpg" style="max-width:100%;" /></p>

<p>&iexcl;tambi&eacute;n est&aacute; estupenda! y de nuevo el texto es lo que est&aacute; mal 😞</p>

<p>No te confundas, esta IA sabe <strong>dibujar texto &quot;estupendamente&quot; mientras sea en INGL&Eacute;S.</strong> D&eacute;jame mostrarte la imagen que gener&oacute; al reemplazar en el prompt anterior los textos a incluir en el banner al <strong>espa&ntilde;ol</strong>:</p>

<blockquote>Design a clean and minimalist banner for second-hand tires suitable for cars, vans, and trucks. Use a light background in white or soft grey, with gentle shadows to add depth. The main text reads &quot;<u>Used Tires for Every Need</u>&quot; in sleek, modern black or dark grey letters, centered on the banner. Below, in smaller, lighter text, add the subtext &quot;<u>Quality at Unbeatable Prices for Cars, Vans, and Trucks.</u>&quot; Place a single, high-quality tire image in the center of the banner, with detailed reflections and textures to showcase its quality. Surround the tire with small, subtle icons representing a car, a van, and a truck, evenly spaced around it. In the bottom center, include a simple blue call-to-action button that reads &quot;<u>Discover More</u>&quot; in a clean, readable font. The overall aesthetic should be refined, with a focus on simplicity and elegance, appealing to a discerning audience.</blockquote>

<p>as&iacute; qued&oacute; la imagen: ... impecable! 🤗</p>

<p style="text-align:center;"><img src="https://imasdeweb.com/UserFiles/Image/2024/generar-imagenes-con-IA_5.jpg" style="max-width:100%;" /></p>
]]></content:encoded>
        </item>
        
        <item>
            <title>Optimización masiva de imágenes en Wordpress con script de PHP</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=101</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=101</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Mon, 22 Jul 2024 14:23:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/101.jpg" style="display: block; margin: 1em auto" /></p><p>Aunque WordPress gestiona bien las copias de imágenes para diferentes usos, no elimina los originales. Esto puede resultar en varios gigabytes de almacenamiento innecesario, especialmente en sitios web antiguos con muchas publicaciones. Para solucionar esto, he creado un script PHP simple que optimiza miles de imágenes rápidamente desde el terminal del servidor. </p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/101.jpg" style="display: block; margin: 1em auto" /></p><h2>Introducci&oacute;n</h2>

<p>Ya sabr&aacute;s que la mayor&iacute;a de usuarios de wordpress no se preocupan muchos por ciertos &quot;detalles&quot; t&eacute;cnicos como la optimizaci&oacute;n de las im&aacute;genes. Normalmente Wordpress hace una gesti&oacute;n muy buena de las im&aacute;genes de la Biblioteca de Medios, generando diferentes copias de la imagen subida por el usuario, para usar una u otra en funci&oacute;n del contexto y tama&ntilde;o de pantalla del visitante. Lo cu&aacute;l agiliza mucho la navegaci&oacute;n de los visitantes.</p>

<p>Sin embargo, cuando una web empieza a tener varios a&ntilde;os de uso y con un ritmo de publicaci&oacute;n intensa de art&iacute;culos, el problema empieza a ser el aumento considerable del espacio de almacenamiento de esas im&aacute;genes, y no tanto las copias optimizadas generadas de forma autom&aacute;tica por wordpress sino las im&aacute;genes originales, que wordpress NO ELIMINA.</p>

<p>Entonces, queriendo hacer algo al respecto de esta situaci&oacute;n (pueden ser varios Gb de almacenamiento! que aparte de ocupar espacio ralentiza y sobredimensiona los backups) decid&iacute; hacer un simple script de PHP que ejecutado desde el terminal del servidor para optimizar miles de im&aacute;genes en un par de minutos con un solo comando.</p>

<p>Nota anecd&oacute;tica: la IA de Claude fue la art&iacute;fice del script, obviamente guiada por un atinado &quot;prompt&quot;, y un par de iteraciones para dotar al script de algunos extras interesantes.</p>

<h2>Detalles del script</h2>

<p>Qu&eacute; hace el script:</p>

<ul>
	<li>revisar recursivamente todo un directorio</li>
	<li>busca las im&aacute;genes JPG, JPEG y PNG</li>
	<li>redimensiona las im&aacute;genes que sobrepasen cierta resoluci&oacute;n</li>
	<li>opcionalmente comprime las im&aacute;genes</li>
</ul>

<p>Las opciones de ejecuci&oacute;n (para hacerllo m&aacute;s seguro) se definen al inicio del script:</p>

<pre class="language-php">
<code>$dir = &#39;/ruta/al/directorio&#39;; // Directorio a procesar
$maxWidth = 1920; // Ancho m&aacute;ximo
$maxHeight = 1080; // Alto m&aacute;ximo
$jpegQuality = 85; // Calidad JPEG (0-100)
$pngCompression = 9; // Nivel de compresi&oacute;n PNG (0-9)
$processAllImages = false; // False para procesar solo las que exceden las dimensiones m&aacute;ximas</code></pre>

<p>Puedes descargarlo aqu&iacute;: <a class="a_icon" href="UserFiles/Image/2024/optimizar-imagenes-recursivamente.php.zip">optimizar-imagenes-recursivamente.php.zip</a></p>

<pre class="language-php">
<code>// Configuraci&oacute;n
$dir = &#39;/ruta/al/directorio&#39;; // Directorio a procesar
$maxWidth = 1920; // Ancho m&aacute;ximo
$maxHeight = 1080; // Alto m&aacute;ximo
$jpegQuality = 78; // Calidad JPEG (0-100)
$pngCompression = 9; // Nivel de compresi&oacute;n PNG (0-9)
$processAllImages = false; // Establecer en true para procesar todas las im&aacute;genes, false para procesar solo las que exceden las dimensiones m&aacute;ximas

// Funci&oacute;n para optimizar una imagen
function optimizeImage($file) {
    global $maxWidth, $maxHeight, $jpegQuality, $pngCompression, $processAllImages;

    $image = new Imagick($file);
    $origWidth = $image-&gt;getImageWidth();
    $origHeight = $image-&gt;getImageHeight();

    $needsRescaling = ($origWidth &gt; $maxWidth || $origHeight &gt; $maxHeight);

    if ($needsRescaling || $processAllImages) {
        // Redimensionar si excede las dimensiones m&aacute;ximas
        if ($needsRescaling) {
            $image-&gt;resizeImage($maxWidth, $maxHeight, Imagick::FILTER_LANCZOS, 1, true);
        }

        // Optimizar seg&uacute;n el tipo de imagen
        $format = strtolower($image-&gt;getImageFormat());
        if ($format === &#39;jpeg&#39; || $format === &#39;jpg&#39;) {
            $image-&gt;setImageCompression(Imagick::COMPRESSION_JPEG);
            $image-&gt;setImageCompressionQuality($jpegQuality);
        } elseif ($format === &#39;png&#39;) {
            $image-&gt;setImageCompression(Imagick::COMPRESSION_ZIP);
            $image-&gt;setImageCompressionQuality($pngCompression * 10); // Imagick usa escala 0-100
        }

        // Guardar la imagen optimizada
        $image-&gt;writeImage($file);
        echo &quot;Imagen procesada: &quot; . $file . PHP_EOL;
    } else {
        echo &quot;Imagen no procesada (dimensiones dentro de los l&iacute;mites): &quot; . $file . PHP_EOL;
    }

    $image-&gt;clear();
}

// Funci&oacute;n para procesar un directorio recursivamente
function processDirectory($dir) {
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($files as $file) {
        if ($file-&gt;isFile()) {
            $extension = strtolower($file-&gt;getExtension());
            if (in_array($extension, [&#39;jpg&#39;, &#39;jpeg&#39;, &#39;png&#39;])) {
                optimizeImage($file-&gt;getPathname());
            }
        }
    }
}

// Ejecutar el proceso
processDirectory($dir);

echo &quot;Proceso completado.&quot; . PHP_EOL;
</code></pre>

<h2>Eficacia de la optimizaci&oacute;n de las im&aacute;genes</h2>

<p>Aumentar&aacute; la eficacia si:</p>

<ul>
	<li>tienes im&aacute;genes demasiado grandes</li>
	<li>o decides poner un m&aacute;ximo de resoluci&oacute;n ajustado (por ejemplo 1200px por 800px)</li>
	<li>calibras el script para una compresi&oacute;n JPEG por debajo de 75</li>
</ul>

<div class="block">
<p><b><u>Ejemplo</u>:</b> a m&iacute; el directorio&nbsp;<code>wp-content/uploads</code> con unas mil im&aacute;genes ha pasado de <strong>886Mb a 582Mb</strong>, es decir, un ahorro del <strong>34%</strong>, usando compresi&oacute;n <u>JPG 78</u> y resoluci&oacute;n m&aacute;xima de <u>1920x1080</u> px.</p>
</div>

<h2>Aviso a navegantes</h2>

<ul>
	<li>Si defines <code>$processAllImages = true;</code> entonces el script abrir&aacute; todas las im&aacute;genes y las volvera a guardar. Este es un proceso que produce una p&eacute;rdida de calidad de imagen CADA VEZ QUE SE EJCUTA. Es decir, idealmente no lo ejecutes DOS VECES en la misma imagen!<br />
	&nbsp;</li>
	<li>En cambio, s&iacute; puedes configurar sin riesgos una ejecuci&oacute;n autom&aacute;tica con esa opci&oacute;n en FALSE, y no hay problema con ello, porqu&eacute; &quot;lo &uacute;nico&quot; que har&aacute; en cada ejecuci&oacute;n es controlar que nunca haya im&aacute;genes con &quot;demasiada resoluci&oacute;n&quot;, pero las otras im&aacute;genes no las tocar&aacute; 😁</li>
</ul>
]]></content:encoded>
        </item>
        
        <item>
            <title>Automate Database Backup for Castopod with BASH</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=100</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=100</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Mon, 15 Jul 2024 18:16:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/100.jpg" style="display: block; margin: 1em auto" /></p><p>Castopod is the ultimate self-hosted solution for podcasters. Streamline your workflow, syndicate across platforms, and monetize your content - all in one powerful, open-source package. <br /><br />
<br /><br />
I show you here how to automate the backup of your castopod database, with a single and simple bash script that you can run every X hours/days, keeping only the last N copies.  </p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/100.jpg" style="display: block; margin: 1em auto" /></p><p><!-- cómo usarlo: ver nota del blog 98, para los prompts -->
<style type="text/css">.copy-container {
            width: 100%;
            max-width: 800px;
            margin: 2em auto;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            overflow: hidden;
            font-size: 0.9em;
            transition: background-color 0.5s ease;
        }
        .copy-header {
            background-color: #f8f8f8;
            padding: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .copy-title {
            font-weight: bold;
            font-size: 1.1em;
            padding-left: 10px;
        }
        .copy-btn {
            background-color: #2e3842;
            color: #fff!important;
            border: none;
            padding: 5px 10px;
            border-radius: 4px;
            cursor: pointer;
            line-height: 1em;
            font-size: 0.7em;
        }
        .copy-btn:hover {
            color: #2e3842!important;
        }
        .copy-content {
            padding: 20px;
            font-family: monospace;
            white-space: pre-wrap;
            word-wrap: break-word;
            cursor: pointer;
        }
        .copy-content.code {
            font-size: 0.7rem;
            line-height: 1rem;
        }
        @keyframes copy-backgroundChange {
            0% { background-color: white; }
            50% { background-color: #e0fff0; }
            100% { background-color: white; }
        }
        .copy-animate-bg {
            animation: copy-backgroundChange 0.5s ease;
        }
</style>
<script>
	function copyText(div_id) {
		const container = $('#'+div_id);
		const text = $.trim($(container).find('.copy-content').text());
		
		navigator.clipboard.writeText(text).then(() => {
			$(container).addClass('copy-animate-bg');
			setTimeout(() => {
				$(container).removeClass('copy-animate-bg');
			}, 500);
		}).catch(err => {
			console.error('Error al copiar el texto: ', err);
		});
	}
</script></p>

<div class="block">
<p>Castopod is the ultimate self-hosted solution for podcasters. Streamline your workflow, syndicate across platforms, and monetize your content - all in one powerful, open-source package.</p>

<p>I show you here how to automate the backup of your castopod database, with a single and simple bash script that you can run every X hours/days, keeping only the last N copies.&nbsp;</p>
</div>

<h3>Considerations</h3>

<ul>
	<li>Each time it&#39;s runned generate a backup like: <strong>backup_20240715_173357.sql.gz</strong> using year, month, day, hour, minute and second to build the filename.</li>
	<li>So it&#39;s a <u>Gzipped</u> file (it occupy about 7 times less)</li>
	<li>Let you specify <u>how many backups to keep</u>, so you can set this script on your server cronjobs (scheduled tasks) to be runned each X hours/days.</li>
	<li>You must put this file in the same root directory than <strong>.env</strong> file of Castopod</li>
	<li>To run it from the <u>server cronjobs</u> (run this: <strong>crontab -e</strong>) you can define a line like this for a daily backup:</li>
</ul>

<p class="code" style="margin:2rem 3rem;">@daily sh /home/podcast.myserver.com/backup_database.sh &gt; /dev/null</p>

<ul>
	<li><u>It took me about 3 hours of work</u> to get this script running with these requirements, even <u>with the help of Claude AI</u>, which after <u>8 iterations in code generation</u>, we managed to get it so complete!!</li>
</ul>

<h3>Bash script</h3>

<p>You can download it here: <a href="UserFiles/Image/2024/castopod_backup_database.sh.zip">castopod_backup_database.sh.zip</a></p>

<p>This is the content:</p>

<div class="copy-container" id="prompt_01_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">bash</div>
<button class="copy-btn">Copiar</button></div>

<pre class="copy-content code">
#!/bin/bash
# 
# caos30 &amp; Claude AI - 2024-07-15
#
# - This script dumps the Castopod database
# - It also lets you specify how many backups to keep
# - So you can run it from your cron jobs
# - The DB connection is taken from the .env Castopod file

# Number of backups to keep
KEEP_BACKUPS=5

# Determine the script&#39;s directory
SCRIPT_DIR=&quot;$( cd &quot;$( dirname &quot;${BASH_SOURCE[0]}&quot; )&quot; &amp;&amp; pwd )&quot;

# Function to read variables from .env file
read_env() {
    ENV_FILE=&quot;${SCRIPT_DIR}/.env&quot;
    if [ -f &quot;$ENV_FILE&quot; ]; then
        while IFS= read -r line || [[ -n &quot;$line&quot; ]]; do
            if [[ -z &quot;$line&quot; || &quot;$line&quot; == \#* ]]; then
                continue
            fi
            if [[ &quot;$line&quot; =~ ^([^=]+)=(.*)$ ]]; then
                key=&quot;${BASH_REMATCH[1]}&quot;
                value=&quot;${BASH_REMATCH[2]}&quot;
                value=$(echo &quot;$value&quot; | sed -e &#39;s/^&quot;//&#39; -e &#39;s/&quot;$//&#39;)
                eval &quot;${key//./_}=&#39;$value&#39;&quot;
            else
                echo &quot;Warning: Malformed line in .env file: $line&quot;
            fi
        done &lt; &quot;$ENV_FILE&quot;
    else
        echo &quot;The .env file does not exist in ${SCRIPT_DIR}&quot;
        exit 1
    fi
}

# Read variables from .env file
read_env

# Assign variables
HOST=&quot;${database_default_hostname}&quot;
DB=&quot;${database_default_database}&quot;
USER=&quot;${database_default_username}&quot;
PASS=&quot;${database_default_password}&quot;
PREFIX=&quot;${database_default_DBPrefix}&quot;

# Backup file name
BACKUP_FILE=&quot;${SCRIPT_DIR}/backup_$(date +%Y%m%d_%H%M%S).sql&quot;
COMPRESSED_BACKUP_FILE=&quot;${BACKUP_FILE}.gz&quot;

# Function to perform the backup
do_backup() {
    mysqldump --host=&quot;$HOST&quot; --user=&quot;$USER&quot; --password=&quot;$PASS&quot; \
              --skip-lock-tables --no-tablespaces \
              &quot;$DB&quot; &gt; &quot;$BACKUP_FILE&quot;
}

# Function to compress the backup
compress_backup() {
    gzip -f &quot;$BACKUP_FILE&quot;
}

# Function to cleanup old backups
cleanup_old_backups() {
    local backup_files=($(ls -t &quot;${SCRIPT_DIR}&quot;/backup_*.sql.gz 2&gt;/dev/null))
    local count=${#backup_files[@]}

    if [ $count -gt $KEEP_BACKUPS ]; then
        echo &quot;Cleaning up old backups...&quot;
        for ((i=$KEEP_BACKUPS; i&lt;$count; i++)); do
            echo &quot;Removing old backup: ${backup_files[i]}&quot;
            rm &quot;${backup_files[i]}&quot;
        done
    fi
}

# Change to the script&#39;s directory
cd &quot;$SCRIPT_DIR&quot;

# Cleanup old backups before creating a new one
cleanup_old_backups

# Perform the database dump
if do_backup; then
    echo &quot;Backup created successfully: $BACKUP_FILE&quot;
    
    # Compress the backup
    if compress_backup; then
        echo &quot;Backup compressed successfully: $COMPRESSED_BACKUP_FILE&quot;
        # Note: gzip has already removed the original file, so we don&#39;t need to do it manually
    else
        echo &quot;Error compressing the backup.&quot;
        exit 1
    fi
else
    echo &quot;Error performing database backup.&quot;
    exit 1
fi

# Final cleanup to ensure we don&#39;t exceed the limit
cleanup_old_backups

echo &quot;Backup process completed.&quot;</pre>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Generar diagramas con Claude y el artifact Mermaid</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=99</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=99</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Sun, 14 Jul 2024 19:57:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/99.jpg" style="display: block; margin: 1em auto" /></p><p>El chat de Claude ahora puede generar diagramas y otros tipos de contenido visual interactivo gracias a su nueva funcionalidad llamada "Artifacts". Y es relativamente nuevo la generación de Diagramas de flujo, mapas mentales, etc. si se le pide adecuadamente desde el "prompt" a la IA.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/99.jpg" style="display: block; margin: 1em auto" /></p><p>Estaba hoy usando el chat de Claude para solicitarle ideas para monetizar un podcast usando IA (spoiler: es un proyecto que estoy cocinando), cuando sin pedirselo me gener&oacute; un &quot;artefacto&quot; (&quot;artifact&quot; le llaman en ingl&eacute;s) a la derecha del chat con un gr&aacute;fico del tipo &quot;mapa mental&quot;. En realidad yo nunca le ped&iacute; que me hiciera un gr&aacute;fico, pero la IA entendi&oacute; que en el contexto de lo que le estaba comentando (mi idea de unir la IA con los contenidos de un podcast) <strong>tom&oacute; la iniciativa de generar un diagrama</strong>!!</p>

<p>Para que sepas de qu&eacute; estoy hablando, te muestro a continuaci&oacute;n otro ejemplo que he probado a continuaci&oacute;n: le ped&iacute; directamente &quot;Genera un diagrama ...&quot; y esto es lo que gener&oacute;!!</p>

<p class="a_c"><a href="UserFiles/Image/2024/Diagramas-con-Claude-Mermaid.jpg"><img alt="Captura de pantalla del chat Claude generando un artifact del tipo Diagrama de flujo" src="https://imasdeweb.com/UserFiles/Image/2024/Diagramas-con-Claude-Mermaid.jpg" style="max-width:100%;" /></a></p>

<h3>Trucos</h3>

<ul>
	<li>Despu&eacute;s de que te haya creado el diagrama, le puedes pedir que le cambie lo que t&uacute; creas necesario: colores, disposici&oacute;n etc.</li>
	<li>Por ejemplo, le puedes pedir que en lugar de disposici&oacute;n &quot;arriba a abajo&quot; o construya con disposici&oacute;n &quot;izquierda a derecha&quot;.</li>
	<li>Una vez creado el diagrama, puedes pulsar el bot&oacute;n &quot;Code&quot; y te mostrar&aacute; que el diagrama est&aacute; construido de forma &quot;super-natural&quot; con un c&oacute;digo como este:</li>
</ul>

<p class="a_c"><a href="UserFiles/Image/2024/diagrama-con-claude-artifacts-y-mermaid-code.jpg"><img alt="Captura de pantalla del código de un Diagrama creado con mermaid en un artifact de Claude" src="https://imasdeweb.com/UserFiles/Image/2024/diagrama-con-claude-artifacts-y-mermaid-code.jpg" style="max-width:100%;" /></a></p>

<h3>Mermaid</h3>

<p>Vengo descubriendo que detr&aacute;s de este &quot;motor de construcci&oacute;n de diagramas&quot; est&aacute; <strong>Mermaid</strong>, que es una herramienta de c&oacute;digo abierto para crear diagramas y gr&aacute;ficos de forma sencilla utilizando texto en formato similar a Markdown:</p>

<ol>
	<li><u>Facilidad de uso</u>: Permite crear diagramas complejos escribiendo texto simple en lugar de dibujar manualmente.</li>
	<li><u>Versatilidad</u>: Soporta varios tipos de diagramas, incluyendo diagramas de flujo, diagramas de secuencia, gr&aacute;ficos Gantt, diagramas de clases, entre otros.</li>
	<li><u>Basado en JavaScript</u>: Es una herramienta basada en JavaScript que convierte el texto en diagramas visuales de forma din&aacute;mica.</li>
	<li><u>Integraci&oacute;n</u>: Se puede integrar f&aacute;cilmente en diversas plataformas y aplicaciones, como GitHub, GitLab, Confluence y m&aacute;s.</li>
	<li><u>Editor en l&iacute;nea</u>: Cuenta con un editor en vivo (Mermaid Live Editor) que permite crear y visualizar diagramas en tiempo real.</li>
	<li><u>Aplicaciones en educaci&oacute;n</u>: Es &uacute;til para crear mapas conceptuales, mapas mentales y gr&aacute;ficos de flujo, lo que la hace valiosa en entornos educativos.</li>
	<li><u>Colaboraci&oacute;n</u>: Facilita la colaboraci&oacute;n en equipos, especialmente en entornos empresariales y de desarrollo de software.</li>
	<li><u>Sintaxis inspirada en Markdown</u>: Utiliza una sintaxis simple y f&aacute;cil de aprender, similar a Markdown.</li>
	<li><u>Exportaci&oacute;n</u>: Los diagramas creados pueden exportarse en varios formatos, como PNG, SVG, etc.</li>
	<li><u>C&oacute;digo como diagrama</u>: Permite mantener los diagramas como c&oacute;digo, lo que facilita su versionado y mantenimiento.</li>
</ol>

<p>Editor oficial gratuito de <a class="a_icon" href="https://mermaid.live/" target="_blank">Mermaid</a>.</p>

<h3>Claude chat vs chatGPT</h3>

<p>En fin, se nota que Claude se est&aacute; esforzando en superar a competidores como chatGPT. Al d&iacute;a en el que estamos (Julio 2024) su modelo Sonnet 3.5 ya supera a los GPT4 disponibles de OpenAI, y su innovaci&oacute;n de los <u>artifacts</u> que generan y ejecutan c&oacute;digo interactivo y visual junto al chat, en tiempo real, est&aacute; siendo un chatGPT killer en toda regla.</p>

<p>A d&iacute;a de hoy ambos generan c&oacute;digo, aunque chatGPT no lo ejecuta en pantalla. Aunque es muy posible que implementen esto en su interfaz pr&oacute;ximamente. De momento los de Claude (Anthropic) les han adelantado.</p>

<ul>
	<li><a href="https://claude.ai/" target="_blank">https://claude.ai/</a></li>
	<li><a href="https://chatgpt.com/" target="_blank">https://chatgpt.com/</a></li>
</ul>
]]></content:encoded>
        </item>
        
        <item>
            <title>IA generativa en el día a día de la empresa</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=98</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=98</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Fri, 21 Jun 2024 09:08:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/98.jpg" style="display: block; margin: 1em auto" /></p><p>¿Porqué ahora todos hablan de IA? Aplicaciones de la IA generativa en el sector industrial, con ejemplos prácticos y ejercicios. Consideraciones éticas y retos del uso controlado de la IA en la empresa.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/98.jpg" style="display: block; margin: 1em auto" /></p><p><!-- cómo usarlo: ver nota del blog 98, para los prompts -->
<style type="text/css">.copy-container {
            width: 100%;
            max-width: 800px;
            margin: 2em auto;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            overflow: hidden;
            font-size: 0.9em;
            transition: background-color 0.5s ease;
        }
        .copy-header {
            background-color: #f8f8f8;
            padding: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .copy-title {
            font-weight: bold;
            font-size: 1.1em;
            padding-left: 10px;
        }
        .copy-btn {
            background-color: #2e3842;
            color: #fff!important;
            border: none;
            padding: 5px 10px;
            border-radius: 4px;
            cursor: pointer;
            line-height: 1em;
            font-size: 0.7em;
        }
        .copy-btn:hover {
            color: #2e3842!important;
        }
        .copy-content {
            padding: 20px;
            font-family: monospace;
            white-space: pre-wrap;
            word-wrap: break-word;
            cursor: pointer;
        }
        .copy-content.code {
            font-size: 0.7rem;
            line-height: 1rem;
        }
        @keyframes copy-backgroundChange {
            0% { background-color: white; }
            50% { background-color: #e0fff0; }
            100% { background-color: white; }
        }
        .copy-animate-bg {
            animation: copy-backgroundChange 0.5s ease;
        }
</style>
<script>
	function copyText(div_id) {
		const container = $('#'+div_id);
		const text = $.trim($(container).find('.copy-content').text());
		
		navigator.clipboard.writeText(text).then(() => {
			$(container).addClass('copy-animate-bg');
			setTimeout(() => {
				$(container).removeClass('copy-animate-bg');
			}, 500);
		}).catch(err => {
			console.error('Error al copiar el texto: ', err);
		});
	}
</script></p>

<p style="text-align: center;"><a class="a_icon" href="https://www.canva.com/design/DAGIon6695k/hgdeNX7irGXIouByPg7DSQ/view?utm_content=DAGIon6695k" target="_blank">Ver presentaci&oacute;n en CANVA</a></p>

<div class="block">&iquest;Porqu&eacute; ahora todos hablan de IA? Aplicaciones de la IA generativa en el sector industrial, con ejemplos pr&aacute;cticos y ejercicios. Consideraciones &eacute;ticas y retos del uso controlado de la IA en la empresa.</div>

<div style="max-width:700px;margin:3rem auto;width: auto;display: table;">
<h3 class="a_c">&Iacute;ndice del contenido</h3>

<ul>
	<li>&iquest; Porqu&eacute; ahora todos hablan de IA ?</li>
	<li>Qu&eacute; son los LLM y principales proveedores</li>
	<li>Gobernanza digital y retos del uso de IA</li>
	<li>Aplicaciones estrella: ChatGPT vs Perplexity</li>
	<li>Aplicaciones de la IA generativa en el sector industrial</li>
	<li>10 ejemplos pr&aacute;cticos y en vivo y en directo !</li>
	<li>Los GPTs de Openai: c&oacute;mo automatizar nuestros prompts</li>
</ul>

<p class="a_c"><em><u>Duraci&oacute;n aproximada de exposici&oacute;n</u>: 2 horas</em></p>
</div>

<div class="a_c" style="max-width:450px;margin:3em auto;font-size:0.9em;padding:1.5em 1em;padding-bottom:0.5em;border-top: 1px #888 solid;border-bottom: 1px #888 solid;">Si crees que puede ser interesante para tu empresa recibir esta formaci&oacute;n en vivo y de forma personalizada, cont&aacute;ctame y hablamos.<br />
<a class="button fit special icon fa-comment scrolly" href="#cta" onclick="$('#contact_form_9').slideDown('slow');return false;" style="max-width:220px;margin:2em auto;">HABLEMOS</a></div>

<h2>&nbsp;</h2>

<h2>Gui&oacute;n de la presentaci&oacute;n en <a href="https://www.canva.com/design/DAGIon6695k/hgdeNX7irGXIouByPg7DSQ/view?utm_content=DAGIon6695k" target="_blank">CANVA</a></h2>

<h3>INTRODUCCI&Oacute;N &iquest;PORQU&Eacute; AHORA TODOS HABLAN DE IA ?</h3>

<p><strong>Porqu&eacute; llegaron las IA generativas</strong></p>

<p>#RedesNeuronales #CrearContenidoOriginal #AprendizajeProfundo #GenerarTexto<br />
#GenerarIm&aacute;genes #GenerarAudio #GenerarVideo #DatosExistentes<br />
#BecarioMuyMotivadoPeroBecario</p>

<p><strong>Diferencias con otras ramas de la IA</strong></p>

<p>#GeneraContenidoNuevo #EsUnReplicadorCasiPerfecto<br />
#AprendePatronesYEstructurasSoloViendo #MultiModal<br />
#SonModelosPorqueModelanLoQueVen #LLM</p>

<p><strong>Evoluci&oacute;n hist&oacute;rica y estado actual de la IA generativa</strong></p>

<p>#OrigenesDecada1940 #VAEsA&ntilde;o2013 #TransformersA&ntilde;o2017 #GPTA&ntilde;o2018<br />
#chatGPTA&ntilde;o2022NOV #Expansi&oacute;nReciente #AplicacionesGeneralizadas<br />
#Revoluci&oacute;nCreativa #PropiedadesEmergentesSorpresa</p>

<p><strong>Principales modelos y aplicaciones</strong></p>

<p>#GPT4 #ChatGPT #DALLE #StableDiffusion #Midjourney #Gemini #Bard #Perplexity<br />
#ClaudeAnthropic #ModelosOpensource #LLamaDeMeta #MixtralFrancia #Generaci&oacute;nTexto<br />
#Generaci&oacute;nIm&aacute;genes #Dise&ntilde;oProductos #MarketingPublicidad<br />
#EntretenimientoVideojuegos #ExtraccionYResumenDeDocumentos<br />
#GeneracionAutomatizadaDeContenidosPersonalizados #AutomatizacionDeAnalisisSemanticos</p>

<p>&nbsp;</p>

<h3>APLICACIONES DE LA IA GENERATIVA EN EL SECTOR INDUSTRIAL</h3>

<p><strong>DISE&Ntilde;O Y DESARROLLO DE PRODUCTOS :</strong></p>

<ul>
	<li>Generaci&oacute;n de ideas y conceptos innovadores</li>
	<li>Optimizaci&oacute;n de dise&ntilde;os basada en restricciones</li>
	<li>Creaci&oacute;n de prototipos virtuales y simulaciones</li>
</ul>

<p><strong>CONTROL DE CALIDAD :</strong></p>

<ul>
	<li>Elaboraci&oacute;n de planes en base a normas del sector</li>
	<li>An&aacute;lisis predictivo de fallos y mantenimiento</li>
	<li>An&aacute;lisis y generaci&oacute;n de informes</li>
</ul>

<p><strong>GESTI&Oacute;N DE RECURSOS HUMANOS :</strong></p>

<ul>
	<li>Soporte en procesos de reclutamiento y selecci&oacute;n</li>
	<li>Generaci&oacute;n de contenidos formativos personalizados</li>
	<li>Asistentes virtuales para consultas de empleados</li>
</ul>

<p><strong>GESTI&Oacute;N DE INVENTARIOS Y CADENA DE SUMINISTRO :</strong></p>

<ul>
	<li>Predicci&oacute;n de demanda y optimizaci&oacute;n de stocks</li>
	<li>Generaci&oacute;n autom&aacute;tica de descripciones de productos</li>
	<li>Soporte en negociaciones con proveedores</li>
</ul>

<h3>&nbsp;</h3>
<script>
	$(document).ready(function(){
		$('div.ejercicio').hide();
	});

</script>

<h3>EJEMPLOS PR&Aacute;CTICOS Y EJERCICIOS</h3>

<p onclick="$('#ejercicio-01').toggle();" style="cursor:pointer;"><strong>1. ALGO SENCILLO PARA EMPEZAR: REDACTAR UNA CARTA FAMILIAR</strong></p>

<div class="ejercicio block " id="ejercicio-01">
<ul>
	<li>Quiero empezar esta serie de ejercicios de introducci&oacute;n para que veas de forma muy f&aacute;cil y evidente estas habilidades de los LLM:</li>
</ul>

<ol>
	<li>FACILIDAD DE USO</li>
	<li>RAPIDEZ EN LA GENERACI&Oacute;N</li>
	<li>ENTENDIMIENTO EMOCIONAL</li>
	<li>HABILIDAD CON LOS IDIOMAS</li>
</ol>

<div class="copy-container" id="prompt_01_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Redacta una carta efusiva a mi hijo que viene de un viaje largo.</div>
</div>

<div class="copy-container" id="prompt_01_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Reescr&iacute;bela por favor m&aacute;s corta y con algo de humor.</div>
</div>

<div class="copy-container" id="prompt_01_03" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 3</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Reescr&iacute;belo en ingl&eacute;s.</div>
</div>

<ul>
	<li>Respuestas de chatGPT: <a href="https://chatgpt.com/share/6c25c650-457c-4f8a-9432-8738b276a52e" target="_blank">https://chatgpt.com/share/6c25...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-02').toggle();" style="cursor:pointer;"><strong>2. GENERAR IDEAS INNOVADORAS PARA NUEVOS PRODUCTOS USANDO CHATGPT</strong></p>

<div class="ejercicio block " id="ejercicio-02">
<ul>
	<li>Se debe especificar las restricciones del dise&ntilde;o a realizar: funcionalidad, s&iacute;miles, materiales a utilizar, dimensiones aproximadas, etc.</li>
	<li>Se puede indicar ciertos criterios o m&eacute;tricas a optimizar: comodidad, precio, facilidad de uso, eficiencia energ&eacute;tica, etc.</li>
	<li>Se consiguen mejores resultados solicitando varios dise&ntilde;os alternativos: de tres a cinco es un buen n&uacute;mero.</li>
</ul>

<div class="copy-container" id="prompt_02_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Si tuviera que inventar un nuevo mueble para el hogar que cumpla la misma funci&oacute;n que una silla, es decir, que sirva para que los humanos se sienten a la hora de comer o de trabajar delante de una mesa, &iquest;qu&eacute; se te ocurre que podr&iacute;amos hacer? Quiero hacer un brainstorming contigo. Dame 5 propuestas descriptivas de un mueble que pudiera servir para sentarse.</div>
</div>

<div class="copy-container" id="prompt_02_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Cual de estos dise&ntilde;os son m&aacute;s aptos para gente de edad avanzada? &iquest;Alguno de estos dise&ntilde;os ser&iacute;a no recomendable para gente mayor?</div>
</div>

<ul>
	<li>Respuestas de chatGPT: <a href="https://chatgpt.com/share/7da61d27-e68a-45c9-a41d-4a5a0e0b7b7d" target="_blank">https://chatgpt.com/share/7da6...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-03').toggle();" style="cursor:pointer;"><strong>3. ANALIZAR UN CURR&Iacute;CULUM Y GENERAR UN INFORME CON CHATGPT</strong></p>

<div class="ejercicio block " id="ejercicio-03">
<ul>
	<li>Podemos pedir a la IA que haga un res&uacute;men de los datos m&aacute;s relevantes, o bien que eval&uacute;e la conveniencia del perfil del individuo seg&uacute;n ciertos par&aacute;metros (vacantes, habilidades requeridas, etc.).</li>
	<li>Podemos automatizar este an&aacute;lisis. Por ejemplo, que cuando nos llegue un nuevo curr&iacute;culum a nuestro cuestionario en l&iacute;nea, se eval&uacute;e de forma autom&aacute;tica y se env&iacute;e un correo con el informe al responsable.</li>
</ul>

<div class="copy-container" id="prompt_03_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Lee el curr&iacute;culum en este documento y dime solamente para cu&aacute;l de estas vacantes servir&iacute;a el candidato:<br />
- Supervisor de campa&ntilde;as de marketing<br />
- Asistente fiscal en departamento de cuentas</div>
</div>

<div class="copy-container" id="prompt_03_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Dame una respuesta en formato JSON que contenga un array con tantos elementos como vacantes de trabajo, y donde coloques un &quot;cero&quot; o un &quot;uno&quot;, seg&uacute;n la val&iacute;a del candidato a cada vacante.</div>
</div>

<ul>
	<li>Generar curriculum ficticio: <a href="https://www.perplexity.ai/search/Genera-un-currculum-dwWhkdfrQ4es4a5LXO2dcA" target="_blank">https://www.perplexity.ai/search/Gene...</a></li>
	<li>Curr&iacute;culum generado en PDF: <a href="https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/material-curriculum.pdf" target="_blank">https://imasdeweb.com/UserFiles/Image...</a></li>
	<li>Respuestas de chatGPT: <a href="https://chatgpt.com/share/1e996180-2cf8-43a9-bf57-da3c6b536bea" target="_blank">https://chatgpt.com/share/1e99...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-04').toggle();" style="cursor:pointer;"><strong>4. IDEAR UN PLAN PARA MEJORAR LA SEGURIDAD SEG&Uacute;N NORMAS OFICIALES CON PERPLEXITY.AI</strong></p>

<div class="ejercicio block " id="ejercicio-04">
<ul>
	<li>Perplexity es un &ldquo;motor de respuestas&rdquo; aunque parezca un &ldquo;motor de b&uacute;squeda en internet&rdquo; inteligente.</li>
	<li>En este ejercicio vamos a ir a &ldquo;ciegas&rdquo; explorando los est&aacute;ndares del sector, hasta conseguir nuestro objetivo de idear un plan. Vamos a elaborar un nuevo prompt en base a las respuestas que nos de en el anterior, de forma que vayamos profundizando en la informaci&oacute;n que nos interesa.</li>
</ul>

<div class="copy-container" id="prompt_04_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">&iquest;que son las normas del IATF en el sector industrial?</div>
</div>

<div class="copy-container" id="prompt_04_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">&iquest;Qu&eacute; dice la norma IATF 16949 respecto a la infraestructura y procesos de TI?</div>
</div>

<div class="copy-container" id="prompt_04_03" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 3</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">&iquest;hay alguna norma o est&aacute;ndar internacional que hable acerca de la seguridad de infraestructuras de TI en las empresas, como en las salas de servidores de una planta de producci&oacute;n?</div>
</div>

<div class="copy-container" id="prompt_04_04" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 4</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Hazme un resumen de consideraciones y buenas pr&aacute;cticas recomendadas por la norma IEC 62443 para poder ser aplicadas en la sala de servidores y routers que tenemos en nuestra planta industrial.</div>
</div>

<ul>
	<li>Respuestas de Perplexity: <a href="https://www.perplexity.ai/search/que-son-las-yyb_D_E4Rt6JRUr.7Di.vQ" target="_blank">https://www.perplexity.ai/search/que...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-05').toggle();" style="cursor:pointer;"><strong>5. GENERAR UN PLAN DE &ldquo;ONBOARDING&ldquo; PERSONALIZADO CON PERPLEXITY.AI</strong></p>

<div class="ejercicio block " id="ejercicio-05">
<ul>
	<li>Usaremos la potencia de b&uacute;squeda y extracci&oacute;n de informaci&oacute;n de Perplexity, y as&iacute; se &ldquo;inspirar&aacute;&rdquo; en ejemplos publicados por otras empresas o agencias.</li>
	<li>En el primer prompt le pedimos que cree un esquema de contenidos segmentados en 3 sesiones.</li>
	<li>En el segundo prompt le pedimos que genere un cuestionario de 10 preguntas que permita a los &ldquo;alumnos&rdquo; evaluar la calidad de esta formaci&oacute;n.</li>
</ul>

<div class="copy-container" id="prompt_05_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Genera el esquema de una propuesta formativa para nuevos empleados en la empresa, organizado en 3 sesiones.</div>
</div>

<div class="copy-container" id="prompt_05_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Genera un cuestionario de 10 preguntas que ser&aacute; rellenado por el personal nuevo de la empresa despu&eacute;s de recibir la formaci&oacute;n de onboarding, para poder evaluar la calidad de esta formaci&oacute;n y poder mejorarla.</div>
</div>

<ul>
	<li>Respuestas de Perplexity: <a href="https://www.perplexity.ai/search/Genera-el-esquema-sLWtELygQgKtwJYyJyWITA" target="_blank">https://www.perplexity.ai/search/Gene...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-06').toggle();" style="cursor:pointer;"><strong>6. ANALIZAR UN DOCUMENTO DE EXCEL CON DATOS TABULADOS</strong></p>

<div class="ejercicio block " id="ejercicio-06">
<ul>
	<li>Disponiendo de un plan de pago de chatGPT o de PerplexityAI podemos analizar el contenido de documentos de Excel con tablas de datos.</li>
	<li>En el primer prompt solicitamos unos c&aacute;lculos de exploraci&oacute;n y agregaci&oacute;n por a&ntilde;o. Podemos ser tan espec&iacute;ficos como necesitemos con los c&aacute;lculos a realizar.</li>
	<li>En el segundo prompt le solicitamos que analice tendencias y detecte patrones si los hay. Vemos que lo hace estupendamente, mencionando incluso la posible afectaci&oacute;n por la PANDEMIA del COVID-19 !?</li>
</ul>

<div class="copy-container" id="prompt_06_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Hazme un resumen de la informaci&oacute;n contenida en este documento CSV sobre mi facturaci&oacute;n en los &uacute;ltimos a&ntilde;os. Genera una tabla con tantas filas como a&ntilde;os. Suma el valor de las facturas de cada a&ntilde;o para cada una de las monedas, en diferentes columnas. Al final agrega dos columnas m&aacute;s: la primera con el n&uacute;mero total de facturas por a&ntilde;o, y la segunda con el incremento (en porcentaje) de esta cantidad respecto al a&ntilde;o anterior.</div>
</div>

<div class="copy-container" id="prompt_06_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Analiza los n&uacute;meros calculados en la tabla anterior y extrae alguna posible tendencia en alguna de las m&eacute;tricas.</div>
</div>

<ul>
	<li>CSV con facturas: <a href="https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/llx_facture-2024-06-20-23-40-13.csv" target="_blank">https://imasdeweb.com/UserFiles/Image...</a></li>
	<li>Respuestas de Perplexity: <a href="https://www.perplexity.ai/search/Hazme-un-resumen-aV_kGZyRTomLALIAYtk9kw" target="_blank">https://www.perplexity.ai/search/Haz...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-07').toggle();" style="cursor:pointer;"><strong>7. REDACCI&Oacute;N DE CORREOS DIF&Iacute;CILES A CLIENTES O PROVEEDORES EN INGL&Eacute;S!</strong></p>

<div class="ejercicio block " id="ejercicio-07">
<ul>
	<li>Donde m&aacute;s brillan y son excelentes los modelos del lenguaje es redactando, ya sea resumiendo o como en este caso desarrollando un texto de comunicaci&oacute;n emocionalmente dif&iacute;cil.</li>
	<li>En el primer prompt le exponemos que necesitamos redactar un correo &ldquo;diciendo que NO&rdquo; a la solicitud de un cliente veterano. Y el LLM se sale de la situaci&oacute;n impecablemente. Incluso proponiendo una &ldquo;v&iacute;a de acci&oacute;n&rdquo;.</li>
	<li>Adem&aacute;s, la mayor&iacute;a de estos LLM son muy buenos TRADUCIENDO. Esto se ve al pedirle que redacte el mismo correo en ingl&eacute;s ! Fabuloso.</li>
</ul>

<div class="copy-container" id="prompt_07_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Redacta un correo formal y breve para un cliente de muchos a&ntilde;os que me ha solicitado un desarrollo a medida para el software que le proveo pero que ahora mismo me es imposible realizar por falta de tiempo. No hace falta que le digas eso. S&eacute; prudente y excusate lo m&aacute;s amablemente posible.</div>
</div>

<div class="copy-container" id="prompt_07_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Redacta de nuevo el correo, pero en ingl&eacute;s.</div>
</div>

<ul>
	<li>Respuestas de Perplexity: <a href="https://www.perplexity.ai/search/Redacta-un-correo-GP_QL02qRDK37dfmb1P.KQ" target="_blank">https://www.perplexity.ai/search/Red...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-08').toggle();" style="cursor:pointer;"><strong>8. GENERAR M&Eacute;TODO DE C&Aacute;LCULO DE COSTOS DE PRODUCCI&Oacute;N Y SUGERENCIAS PARA POWER BI</strong></p>

<div class="ejercicio block " id="ejercicio-08">
<ul>
	<li>Una de los aspectos m&aacute;s valiosos de los textos y an&aacute;lisis realizados por estos LLM es que son muy exhaustivos: tienden a no dejarse NADA, especialmente analizando PROS y CONTRAS, o planificando M&Eacute;TODOS.</li>
	<li>Adem&aacute;s, tienen amplio conocimiento de los softwares m&aacute;s conocidos, como la plataforma de Business Intelligence de Microsoft: PowerBI.</li>
</ul>

<div class="copy-container" id="prompt_08_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Explica c&oacute;mo calcular el costo por pieza en un proceso de inyecci&oacute;n, considerando material, energ&iacute;a, mano de obra y overhead.</div>
</div>

<div class="copy-container" id="prompt_08_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Recomiendame indicadores de producci&oacute;n de piezas para un dashobard de PowerBI para el informe diario de producci&oacute;n, e indica en qu&eacute; formato idealmente para cada indicador. Dame ejemplos tambi&eacute;n.</div>
</div>

<ul>
	<li>Respuestas de Perplexity: <a href="https://www.perplexity.ai/search/explica-como-calcular-el-costo-KPKhSi0ySKi3tGa3kl6Mbg" target="_blank">https://www.perplexity.ai/search/expl...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-09').toggle();" style="cursor:pointer;"><strong>9. ANALIZAR DATOS ESTAD&Iacute;STICOS EN IM&Aacute;GENES Y CONVERSI&Oacute;N DE MONEDAS</strong></p>

<div class="ejercicio block " id="ejercicio-09">
<ul>
	<li>Tanto en chatGPT como en Perplexity podemos subir documentos de texto o de excel o im&aacute;genes, para solicitar que la IA trabaje sobre ellos y extraiga informaci&oacute;n.</li>
	<li>Incluso puede convertir precios en otras monedas!</li>
</ul>

<div class="copy-container" id="prompt_09_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Analiza el dashboard en esta imagen y hazme un resumen ejecutivo, donde aparezca destacado lo m&aacute;s relevante para la junta directiva.</div>
</div>

<div class="copy-container" id="prompt_09_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Reescribe tu informe anterior en ingl&eacute;s, recalculando las cantidades monetarias a su valor en d&oacute;lares USD.</div>
</div>

<ul>
	<li>Pantallazo de Dashboard: <a href="https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/dashboard-bi-ventas.png" target="_blank">https://imasdeweb.com/UserFiles/Image...</a></li>
	<li>Respuestas de Perplexity: <a href="https://www.perplexity.ai/search/analiza-el-dashboard-en-esta-i-zXYbu8EYRZWAaJ.jvgZK3g" target="_blank">https://www.perplexity.ai/search/analiza...</a></li>
</ul>
</div>

<p onclick="$('#ejercicio-10').toggle();" style="cursor:pointer;"><strong>10. ANALIZAR DATOS CONTABLES EN TABLA PDF Y GENERAR UN INFORME EN WORD</strong></p>

<div class="ejercicio block " id="ejercicio-10">
<ul>
	<li>Estos LLM pueden leer documentos contables, analizarlos, hacer res&uacute;menes sobre ellos e incluso generar informes.</li>
	<li>Tambi&eacute;n pueden generar documentos para descargar tipo Word y Powerpoint.</li>
</ul>

<div class="copy-container" id="prompt_10_01" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 1</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Haz el balance general en formato horizontal con la informaci&oacute;n del archivo anexo.</div>
</div>

<div class="copy-container" id="prompt_10_02" onclick="copyText($(this).attr('id'))">
<div class="copy-header">
<div class="copy-title">Prompt 2</div>
<button class="copy-btn">Copiar</button></div>

<div class="copy-content">Dame un informe financiero en archivo word con la razones financieros y analiza el resultado, ademas presentalo en un informe ejecutivo como el director de finanzas de la empresa.</div>
</div>

<ul>
	<li>Balanza de comprobaci&oacute;n en PDF: <a href="https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/Balanza-de-Comprobacion_MAYO-2020.pdf" target="_blank">https://imasdeweb.com/UserFiles/Image...</a></li>
	<li>Respuestas de chatGPT: <a href="https://chatgpt.com/share/1818d3dd-ffcb-440d-8678-c6295702495e" target="_blank">https://chatgpt.com/share/1818...</a></li>
	<li>Informe generado en Word: <a href="https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/Informe_Financiero_Empresa_XYZ.docx" target="_blank">https://imasdeweb.com/UserFiles/Image...</a></li>
</ul>
</div>

<p>&nbsp;</p>

<h3>CONSIDERACIONES &Eacute;TICAS Y RETOS</h3>

<ul>
	<li>Sesgos y falta de transparencia en los modelos</li>
	<li>Responsabilidad y Rendici&oacute;n de Cuentas</li>
	<li>Propiedad intelectual del contenido generado</li>
	<li>Privacidad y seguridad de los datos</li>
	<li>Impacto en el empleo y desplazamiento de tareas</li>
</ul>

<p>&nbsp;</p>

<h3 class="a_c">Masterclass IA para New Concept Technology</h3>

<p class="a_c"><strong>Hermosillo, Sonora, M&eacute;xico - Junio 2024</strong></p>
<style type="text/css">.wrapper-video-container {
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .video-container {
            width: 100%;
            max-width: 600px;
            background-color: #000;
        }
        video {
            width: 100%;
            height: auto;
            display: block;
        }
</style>
<div class="wrapper-video-container">
<div class="video-container">
<video controls="" poster="https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/record/2024-07-02_19.06.34_Video_MasterClass_IA.jpg" preload="metadata"><source src="https://imasdeweb.com/https://imasdeweb.com/UserFiles/Image/2024/MASTERCLASS-IA/record/2024-07-02_19.06.34_Video_MasterClass_IA.mp4" type="video/mp4" /> Su navegador no soporta el elemento de video.</video>
</div>
</div>

<p>&nbsp;</p>

<div style="text-align:center!important;"><style>
    /* ---- mosaic css ---- */

        .gallery_type3{ display:inline-block; position:relative; padding:0px; background-color:#ddd; border-radius:5px; }
        .gallery_type3 *{ white-space: normal; }
        .gallery_type3 ul{ text-align:center; margin:11px; display:inline-block; padding:0px; }
        .gallery_type3 ul li{position:relative; list-style: none; display:inline-block; float:center; }
        .gallery_type3 ul a{ display:inline-block; width: 100px; height: 100px; margin: 2px 11px; background-size: cover; background-repeat:no-repeat; border: none; border-radius:3px; }
        .gallery_type3 ul a.current, 
        .gallery_type3 ul a:hover{ box-shadow:0px 0px 4px #555; transition: box-shadow 0.2s ease-in 0s; }
        .gallery_type3 ul li span{ position:absolute;top:0; right:0;z-index:11; display:inline-block; width:1.5rem; height:1.5rem; line-height: 1.4rem; text-align:center; border-radius:100%; background-color: black; background-color: rgba(0,0,0,0.5);  color:white; font-weight: bold; font-size:2rem; cursor:pointer; }
        .gallery_type3 ul li span:hover{ box-shadow: 0px 0px 2px 2px white; }

    /* ---- viewbox.css ---- */

        .viewbox-container{ position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,.5); z-index: 700; }
        .viewbox-body{ position: absolute; top: 50%; left: 50%; background: #fff; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); overflow: auto; }
        .viewbox-header{ margin: 10px; }
        .viewbox-content{ margin: 10px; width: 300px; height: 300px; }
        .viewbox-footer{ margin: 10px; }
        .viewbox-content .viewbox-image{ width: 100%; height: 100%; }

        /* buttons */
        .viewbox-button-default{ cursor: pointer; height: 64px; width: 64px; }
        .viewbox-button-default > svg{ width: 100%; height: 100%; background: inherit; fill: inherit; pointer-events: none; transform: translateX(0px); }
        .viewbox-button-default{ fill: #999; }
        .viewbox-button-default:hover{ fill: #fff; }

        .viewbox-button-close{ position:absolute; top:10px; right: 10px; z-index:9; }
        .viewbox-button-next,
        .viewbox-button-prev{ position:absolute; top: 50%; height: 128px; width: 128px; margin: -64px 0 0; z-index:9; }
        .viewbox-button-next{ right: 10px; }
        .viewbox-button-prev{ left: 10px; }

        /* loader */
        .viewbox-container .loader{ widows: 100%; position: absolute; left: 50%; top: 50%; margin:-25px 0 0 -25px; }
        .viewbox-container .loader *{ margin: 0; padding: 0; }
        .viewbox-container .loader .spinner{ width: 50px; height: 50px; position: relative; margin: 0 auto; }
        .viewbox-container .loader .double-bounce1,
        .viewbox-container .loader .double-bounce2{ width: 100%; height: 100%; border-radius: 50%; background-color: #999; opacity: 0.6; position: absolute; top: 0; left: 0; -webkit-animation: sk-bounce 2.0s infinite ease-in-out; animation: sk-bounce 2.0s infinite ease-in-out; }
        .viewbox-container .loader .double-bounce2 { -webkit-animation-delay: -1.0s; animation-delay: -1.0s; }

        @-webkit-keyframes sk-bounce{ 0%, 100% { -webkit-transform: scale(0.0) } 50% { -webkit-transform: scale(1.0) } }
        @keyframes sk-bounce{ 0%, 100% {      transform: scale(0.0);     -webkit-transform: scale(0.0); } 50% {      transform: scale(1.0);     -webkit-transform: scale(1.0); } }
</style>
<div id="gallery_type3_37118" class="gallery_type3 relative" style="width:100%;max-width:100%;">
    
            
    <ul>
                <li>
            <a href="UserFiles/admin/modulo_galeria_imagenes/large/26.jpg" title="Masterclass IA - New Concept Technology 01"
               style="background-image:url('UserFiles/admin/modulo_galeria_imagenes/thumbs/26.jpg');" class="image-link">
            </a>
                    </li>
                <li>
            <a href="UserFiles/admin/modulo_galeria_imagenes/large/27.jpg" title="Masterclass IA - New Concept Technology 03"
               style="background-image:url('UserFiles/admin/modulo_galeria_imagenes/thumbs/27.jpg');" class="image-link">
            </a>
                    </li>
                <li>
            <a href="UserFiles/admin/modulo_galeria_imagenes/large/28.jpg" title="Masterclass IA - New Concept Technology 02"
               style="background-image:url('UserFiles/admin/modulo_galeria_imagenes/thumbs/28.jpg');" class="image-link">
            </a>
                    </li>
                <li>
            <a href="UserFiles/admin/modulo_galeria_imagenes/large/29.jpg" title="Masterclass IA - New Concept Technology 04"
               style="background-image:url('UserFiles/admin/modulo_galeria_imagenes/thumbs/29.jpg');" class="image-link">
            </a>
                    </li>
            </ul>
    <div style="float:none;clear:both;"></div>
</div>

<script>
	$(document).ready(function(){
		
		$(function(){
			$('.image-link').viewbox({
				setTitle: true,
				margin: 20,
				resizeDuration: 300,
				openDuration: 200,
				closeDuration: 200,
				closeButton: true,
				navButtons: true,
				closeOnSideClick: true,
				nextOnContentClick: true
			});
		});		

	});
	
</script>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Manuel d'utilisation du module StockTransfers pour le ERP Dolibarr</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=94</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=94</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Thu, 28 Dec 2023 10:27:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/94.jpg" style="display: block; margin: 1em auto" /></p><p>Chez IMASDEWEB, nous avons développé le module "Stocktransfers" pour le projet Dolibarr ERP/CRM en PHP. Sur cette page, nous présentons son fonctionnement, que vous soyez déjà utilisateur ou que vous envisagiez de l'utiliser.<br /><br />
<br /><br />
L'objectif de ce module est de fournir une interface plus conviviale que celle native de Dolibarr pour effectuer des transferts de produits d'un entrepôt à un autre de la société propriétaire de Dolibarr. Si le module "Purchases" (également d'IMASDEWEB) est installé, un bouton apparaît en cas de rupture de stock pour le transfert, permettant de créer un nouveau processus d'achat pour le stock manquant.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/94.jpg" style="display: block; margin: 1em auto" /></p><p>Chez IMASDEWEB, nous avons d&eacute;velopp&eacute; le <u>module Stocktransfers</u> pour le projet open source <u>Dolibarr ERP/CRM</u> en PHP. Sur cette page, nous pr&eacute;sentons son fonctionnement, que vous soyez d&eacute;j&agrave; utilisateur ou que vous envisagiez de l&#39;utiliser.</p>

<p><strong>Dolistore:</strong> <a class="a_icon" href="https://www.dolistore.com/fr/modules/866-Stock-transfers.html" style="font-size:0.8em;" target="_blank">https://www.dolistore.com/fr/modules/866-Stock-transfers.html</a></p>

<div class="block">
<ul>
	<li><a href="#">Pr&eacute;sentation</a></li>
	<li><a href="#instalacion">Installation</a></li>
	<li><a href="#acceso">Acc&egrave;s au module</a></li>
	<li><a href="#listado">Liste des transferts</a></li>
	<li><a href="#creando">Cr&eacute;ation d&#39;un transfert</a></li>
	<li><a href="#stock">Rupture de stock</a></li>
	<li><a href="#de_compras">Faire des achats</a></li>
	<li><a href="#received">Marchandise exp&eacute;di&eacute;e, marchandise re&ccedil;ue</a></li>
	<li><a href="#custom-columns">Personnaliser le tableau des produits</a></li>
	<li><a href="#pdf">PDF pour le transfert</a></li>
	<li><a href="#demo">Site Web de d&eacute;monstration</a></li>
</ul>
</div>

<p><b>Note:</b> <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=39">english version</a> of this user guide.</p>

<p id="presentacion"><b>Nota:</b> <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=38">versi&oacute;n en espa&ntilde;ol</a> de esta gu&iacute;a.</p>

<p>&nbsp;</p>

<h2>Pr&eacute;sentation</h2>

<p>L&#39;objectif de ce module est d&#39;offrir <strong>une interface plus conviviale que celle native de Dolibarr pour effectuer des transferts de produits d&#39;un entrep&ocirc;t &agrave; un autre</strong> (entrep&ocirc;ts de notre entreprise). Si le <a class="a_icon" href="https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=95" target="_blank">module Achats</a> (&eacute;galement d&#39;IMASDEWEB) est install&eacute;, un bouton appara&icirc;t en cas de rupture de stock pour le transfert, permettant la cr&eacute;ation d&#39;un nouveau processus d&#39;achat pour le stock manquant.</p>

<p>Le module permet le t&eacute;l&eacute;chargement d&#39;un fichier PDF avec la liste des produits &agrave; transf&eacute;rer et un espace en bas pour les trois signatures de l&#39;exp&eacute;diteur, du transporteur et de la personne qui recevra les produits dans l&#39;entrep&ocirc;t de destination, comme c&#39;est habituel dans ce type de mouvement de marchandises.</p>

<div class="iframe_wrapper"><iframe allowfullscreen="" frameborder="0" mozallowfullscreen="" scrolling="no" src="https://imasdeweb.com///slides.com/caos30/dolibarr-stocktransfers/embed" webkitallowfullscreen=""></iframe></div>

<p>
<style type="text/css">.iframe_wrapper {
		position: relative;
		padding-bottom: 65.25%;
		padding-top: 100px;
		height: 0;
		overflow: auto; 
	} 
	.iframe_wrapper iframe {
		position: absolute;
		top: 0;
		left: 0;
		width: 90%;
		height: 100%;
		margin-left:5%;
	}
</style>
</p>

<p id="instalacion">&nbsp;</p>

<h2>Installation</h2>

<p>Vous devez d&eacute;j&agrave; savoir qu&#39;installer un module dans Dolibar est aussi simple que :</p>

<div class="block">
<ol>
	<li>Aller dans <code>Configuration &gt; Modules &gt; Installer un module externe</code></li>
	<li>T&eacute;l&eacute;charger le fichier ZIP que vous avez obtenu depuis la boutique</li>
</ol>
</div>

<p>Une fois que vous l&#39;avez fait, il appara&icirc;tra dans la configuration des modules, dans le panneau Dolibarr du groupe <u>Gestion des Produits (PM)</u>, sous le nom <u>Produits - stocktransfers</u>:</p>

<p class="a_c"><a href="UserFiles/Image/2023/Modules.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/Modules.png" style="max-width:100%;" /></a></p>

<p id="acceso">&nbsp;</p>

<h2>Acc&egrave;s au module</h2>

<p>Une fois activ&eacute;, vous pouvez y acc&eacute;der de deux mani&egrave;res possibles:</p>

<ul>
	<li>en visitant la section Produits, puis dans le menu lat&eacute;ral gauche, vous verrez les deux options pour ce module: <u>Transferts</u> / <u>Nouveau transfert</u><br />
	<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="UserFiles/Image/2023/entrepots-menu.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/entrepots-menu.png" style="max-width: 100%;" /></a><br />
	&nbsp;</li>
	<li>ou bien, depuis le Tableau de bord, o&ugrave; vous trouverez une bo&icirc;te avec <u>les 5 derniers transferts</u> de stock.<br />
	<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="UserFiles/Image/2023/5-demiers-transferts-de-stock.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/5-demiers-transferts-de-stock.png" style="max-width: 100%;" /></a><br />
	&nbsp;</li>
</ul>

<p id="listado">&nbsp;</p>

<h2>Liste des transferts</h2>

<p>Il n&#39;y a pas grand-chose &agrave; dire sur la liste des transferts. Ce qui est le plus int&eacute;ressant, c&#39;est d&#39;expliquer les valeurs possibles pour la colonne <u>&Eacute;tat</u>:</p>

<div class="block">
<ul>
	<li><strong>Brouillon :</strong> lorsque nous <strong>pr&eacute;parons la liste des produits</strong> &agrave; transf&eacute;rer</li>
	<li><strong>Valid&eacute; :</strong> lorsque <strong>la liste des produits est d&eacute;j&agrave; &eacute;tablie</strong> et finalis&eacute;e</li>
	<li><strong>Envoy&eacute;</strong>&nbsp;<strong>:</strong> lorsque la marchandise a d&eacute;j&agrave; <b>quitt&eacute; l&#39;entrep&ocirc;t d&#39;origine</b></li>
	<li><strong>Re&ccedil;u</strong>&nbsp;<strong>:</strong> lorsque la marchandise a d&eacute;j&agrave; &eacute;t&eacute; <b>re&ccedil;ue dans l&#39;entrep&ocirc;t de destination</b></li>
</ul>
</div>

<p class="a_c"><a href="UserFiles/Image/2026/stock-transfer-list_fr.png"><img src="https://imasdeweb.com/UserFiles/Image/2026/stock-transfer-list_fr.png" style="max-width: 100%;" /></a></p>

<p id="creando">&nbsp;</p>

<h2>Cr&eacute;ation d&#39;un transfert</h2>

<p>La fiche d&#39;un transfert &agrave; l&#39;&eacute;tat <u>Brouillon</u> ressemblerait &agrave; celle illustr&eacute;e ci-dessous:</p>

<p class="a_c"><a href="UserFiles/Image/2026/ficha-de-transferencia-de-stock_fr.png"><img src="https://imasdeweb.com/UserFiles/Image/2026/ficha-de-transferencia-de-stock_fr.png" style="max-width: 100%;" /></a></p>

<ul>
	<li>En haut, il y a une premi&egrave;re partie descriptive o&ugrave; les champs obligatoires sont toujours l&#39;<u>Entrep&ocirc;t d&#39;origine</u> et l&#39;<u>Entrep&ocirc;t de destination</u>. Optionnellement, ce mouvement de stock peut &ecirc;tre associ&eacute; &agrave; un <u>projet</u> que nous avons dans Dolibarr (si le <u>module Projets</u> est activ&eacute;). Les <u>dates de d&eacute;part et d&#39;arriv&eacute;e</u> seront obligatoires lorsque nous voudrons changer l&#39;&eacute;tat &agrave; <u>Envoy&eacute;</u> ou <u>Re&ccedil;u</u>, respectivement.<br />
	&nbsp;</li>
	<li>&Agrave; tout moment, nous pouvons t&eacute;l&eacute;charger un PDF qui sera utile pour que le transporteur l&#39;ait avec lui et le signe lors de la livraison et de la r&eacute;ception de la marchandise.<br />
	&nbsp;</li>
	<li>Tant que l&#39;&eacute;tat reste en <u>Brouillon</u>, nous pourrons ajouter plus de produits au transfert.</li>
</ul>

<p id="stock">&nbsp;</p>

<h2>Rupture de stock</h2>

<p>La colonne <u>Stock</u> indique la quantit&eacute; de produit disponible <strong>dans l&#39;entrep&ocirc;t d&#39;origine</strong>. Dans le cas o&ugrave; elle est inf&eacute;rieure &agrave; celle que nous devons transf&eacute;rer, un symbole d&#39;alerte appara&icirc;tra dans cette colonne. De plus, <strong>tant que le stock n&#39;est pas suffisant pour tous les produits, nous ne pourrons pas changer l&#39;&eacute;tat du transfert &agrave; <u>Envoy&eacute;</u></strong>.</p>

<p class="a_c"><a href="UserFiles/Image/2026/falta-de-stock_fr.png"><img src="https://imasdeweb.com/UserFiles/Image/2026/falta-de-stock_fr.png" style="max-width: 100%;" /></a></p>

<p>Comment r&eacute;soudre le probl&egrave;me de rupture de stock? Cela d&eacute;pendra du cas:</p>

<ul>
	<li>Si la quantit&eacute; de stock indiqu&eacute;e dans cette colonne ne correspond pas &agrave; celle r&eacute;ellement disponible dans l&#39;entrep&ocirc;t, <strong>nous devrons effectuer une correction de stock en suivant la fonction native de Dolibarr &agrave; cet effet.</strong><br />
	&nbsp;</li>
	<li>Mais si cette quantit&eacute; de stock est correcte, alors <strong>nous devrons <u>faire des achats</u> pour augmenter notre stock</strong> dans l&#39;entrep&ocirc;t d&#39;origine et pouvoir proc&eacute;der au transfert.</li>
</ul>

<p>Dans tous les cas, le <u>module Stocktransfers</u> facilite la t&acirc;che. Dans le premier cas, nous voyons qu&#39;il y a un bouton pour chaque ligne de produit avec le symbole d&#39;alerte qui <img alt="" src="https://imasdeweb.com/UserFiles/Image/2023/exclamation-button.png" />, lorsqu&#39;on le presse, ouvre dans un autre onglet du navigateur le formulaire Dolibarr pour cr&eacute;er une <u>correction de stock</u> pour ce produit:</p>

<p class="a_c"><a href="UserFiles/Image/2023/correction-de-stock.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/correction-de-stock.png" style="max-width:100%;" /></a></p>

<p>Nous devrons indiquer l&#39;<u>entrep&ocirc;t</u> dans lequel nous voulons corriger le stock, s&eacute;lectionner &quot;<u>Ajouter</u>&quot; dans la liste d&eacute;roulante et indiquer le <u>nombre de pi&egrave;ces</u> &agrave; ajouter. <strong>Attention:</strong> nous devons nous r&eacute;f&eacute;rer au tableau qui appara&icirc;t en bas du formulaire, car il indique le nombre actuel de pi&egrave;ces pour chaque entrep&ocirc;t. Dans notre exemple : 37. Ainsi, si apr&egrave;s avoir fait un inventaire dans l&#39;entrep&ocirc;t, il s&#39;av&egrave;re qu&#39;il y a 57 pi&egrave;ces, <strong>nous devons faire une correction pour ajouter la diff&eacute;rence:</strong> 20 pi&egrave;ces, dans notre exemple.</p>

<p>Une fois que nous avons g&eacute;n&eacute;r&eacute; cette correction de stock, nous devrons rafra&icirc;chir la page du transfert pour mettre &agrave; jour les chiffres de stock.</p>

<p id="de_compras">&nbsp;</p>

<h2>Faire des achats</h2>

<p>Comme mentionn&eacute; pr&eacute;c&eacute;demment, si la raison de la rupture de stock n&#39;est pas une erreur, mais que nous avons simplement besoin d&#39;acheter quelques pi&egrave;ces avant de pouvoir les transf&eacute;rer vers l&#39;autre entrep&ocirc;t, alors le <u>module StockTransfers</u> facilite la t&acirc;che si le <u>module Achats</u> (&eacute;galement d&#39;IMASDEWEB) est install&eacute;. Si ce n&#39;est pas le cas, il vous suffira de suivre les proc&eacute;dures habituelles de Dolibarr pour passer des commandes &agrave; vos fournisseurs afin de vous approvisionner.</p>

<p>Si le <u>module Achats</u> est install&eacute;, vous verrez le bouton &quot;<u>Faire des achats</u>&quot;:</p>

<p class="a_c"><a href="UserFiles/Image/2026/falta-de-stock_fr.png"><img src="https://imasdeweb.com/UserFiles/Image/2026/falta-de-stock_fr.png" style="max-width: 100%;" /></a></p>

<p>En le cliquant, un &quot;processus d&#39;achat&quot; sera g&eacute;n&eacute;r&eacute; dans le <u>module Achats</u>, <strong>incluant tous les produits pour lesquels nous avons un manque de stock</strong> pour ce transfert, avec <strong>la diff&eacute;rence entre les quantit&eacute;s &agrave; transf&eacute;rer et le stock que nous avons en entrep&ocirc;t</strong>. Tout cela en un seul clic:</p>

<p class="a_c"><a href="UserFiles/Image/2023/acheter.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/acheter.png" style="max-width:100%;" /></a></p>

<p>De plus, comme c&#39;est habituel dans le <u>module Achats</u>, il affichera d&eacute;j&agrave; les prix existants des fournisseurs qui nous fournissent ces produits, pr&ecirc;t &agrave; demander des devis si n&eacute;cessaire, ou &agrave; passer les commandes.</p>

<div class="block">
<p><strong>Remarque:</strong> Si vous n&#39;&ecirc;tes pas familier avec le <u>module Achats</u>, il serait utile de lire le <a class="a_icon" href="https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=95" target="_blank">Manuel d&#39;utilisation</a> que nous avons publi&eacute; ici.</p>
</div>

<p id="received">&nbsp;</p>

<h2>Marchandise envoy&eacute;e, marchandise re&ccedil;ue</h2>

<p>Une fois que nous avons le stock n&eacute;cessaire de tous les produits &agrave; transf&eacute;rer, le bouton &quot;<u>Changer l&#39;&eacute;tat en Envoy&eacute;</u>&quot; deviendra visible. Il suffit de le presser pour changer l&#39;&eacute;tat de notre transfert. Le syst&egrave;me nous obligera &agrave; remplir la &quot;<u>Date de d&eacute;part</u>&quot;. Une fois que l&#39;&eacute;tat est pass&eacute; &agrave; &quot;<u>Envoy&eacute;</u>&quot;, le bouton &quot;<u>Changer l&#39;&eacute;tat en Re&ccedil;u</u>&quot; appara&icirc;tra, nous obligeant &eacute;galement &agrave; remplir la &quot;<u>Date d&#39;arriv&eacute;e</u>&quot;.</p>

<p>Dans tous les cas, il ne sera plus possible d&#39;ajouter de nouveaux produits, bien que le bouton &quot;<u>Revenir &agrave; l&#39;&eacute;tat Brouillon</u>&quot; soit toujours disponible.</p>

<p class="a_c"><a href="UserFiles/Image/2026/mercancia-enviada-mercancia-recibida_fr.png"><img src="https://imasdeweb.com/UserFiles/Image/2026/mercancia-enviada-mercancia-recibida_fr.png" style="max-width: 100%;" /></a></p>

<p>&nbsp;</p>

<p id="custom-columns">&nbsp;</p>

<h2>Personnaliser le tableau des produits</h2>

<p>Chaque entreprise organise ses produits de mani&egrave;re l&eacute;g&egrave;rement diff&eacute;rente. Pour cette raison, vous pouvez choisir les colonnes &agrave; afficher dans le tableau des produits d&#39;un transfert&nbsp;:</p>

<ul>
	<li><u>Propri&eacute;t&eacute;s uniques pour ce transfert</u> de produit : lot, note</li>
	<li><u>Propri&eacute;t&eacute;s natives du produit</u> dans Dolibarr : note priv&eacute;e/publique, prix, co&ucirc;t, etc.</li>
	<li><u>Propri&eacute;t&eacute;s suppl&eacute;mentaires</u> du produit : celles que vous avez d&eacute;finies dans la configuration du module <u>Produits</u>.</li>
</ul>

<p class="a_c"><a href="UserFiles/Image/2026/columnas-personalizables-tabla-de-productos_fr.png"><img src="https://imasdeweb.com/UserFiles/Image/2026/columnas-personalizables-tabla-de-productos_fr.png" style="max-width: 100%;" /></a></p>

<p>&nbsp;</p>

<p id="pdf">&nbsp;</p>

<h2>PDF pour le transfert</h2>

<p>En appuyant sur le bouton &quot;<u>T&eacute;l&eacute;charger le PDF</u>&quot;, un document PDF est g&eacute;n&eacute;r&eacute; en temps r&eacute;el, comme celui que nous voyons ci-dessous, qui est g&eacute;n&eacute;ralement imprim&eacute; et port&eacute; sur soi pour &ecirc;tre sign&eacute; par les personnes qui livrent la marchandise, le destinataire et le transporteur. Ce document reprend certaines des donn&eacute;es figurant dans le formulaire, si elles ont &eacute;t&eacute; remplies, telles que le projet, le nom du transporteur et le nombre de colis.</p>

<p class="a_c"><a href="UserFiles/Image/2023/PDF-pour-le-transfert.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/PDF-pour-le-transfert.png" style="max-width:100%;" /></a></p>

<p>Dans la section <u>Param&egrave;tres</u> du module <u>Stocktransfers</u>, <strong>vous pouvez configurer en d&eacute;tail l&#39;apparence et le contenu du PDF</strong> :</p>

<ul>
	<li>en-t&ecirc;te et pied de page du document</li>
	<li>colonnes de produits &agrave; afficher</li>
	<li>signatures &agrave; afficher &agrave; la fin du document</li>
</ul>

<h2>Site Web de type DEMO</h2>

<p class="a_c"><a href="UserFiles/Image/2023/site-web-de-type-DEMO.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/site-web-de-type-DEMO.png" style="max-width:100%;" /></a></p>

<p>Si vous souhaitez essayer le module Stocktransfers, contactez-nous et nous vous fournirons volontiers le nom d&#39;utilisateur et le mot de passe. Nous ne les mettons pas ici publiquement pour &eacute;viter des attaques inutiles.</p>

<p class="a_c"><a class="bt" href="#" onclick="$('#TestDemoForm').toggle();$(this).hide();return false;">&rarr; Formulaire de contact</a></p>

<div id="TestDemoForm" style="display:none;"><form method='post' id='contactos_form_17_6283' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_82530' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_82530').html('<br style=\'display:none;\' rel=\'4410\' /><br style=\'display:none;\' rel=\'4410\' />5<br style=\'display:none;\' rel=\'4410\' /><br style=\'display:none;\' rel=\'4410\' /> + <br style=\'display:none;\' rel=\'4410\' /><br style=\'display:none;\' rel=\'4410\' />4<br style=\'display:none;\' rel=\'4410\' /><br style=\'display:none;\' rel=\'4410\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_92664' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_92664' name='captcha_formstamp' value='Um1nclRDc3dTVWhCWW5kTFNFZDFXRTVZTjI1QlYwYzVhbGc0UXpOUVJHTkRSR0YxT1hKSFZ6VlFNRDA2T2pKa01HWmlaalJpTkdKbE9USTFZakl4TldFellUWm1ORE5qWWpnNFpURms' />
    <input type='hidden' id='captcha_valid_92664' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_92664').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_92664();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_92664').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_92664').val('');
                    $('#captcha_answer_92664').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_92664').val())+'&captcha_answer='+($('#captcha_answer_92664').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_92664').val(data.valid);
                    $('#captcha_answer_92664').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_92664').addClass('valid_captcha');
                    else
                        $('#captcha_answer_92664').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_92664(){
        if($('#captcha_answer_92664').val() == ''
                || $('#captcha_valid_92664').val()!='1'){

            $('#captcha_answer_92664').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_92664').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_6283();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_6283(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_6283');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_6283').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Guide d'utilisation du module Achats (Purchases) pour l'ERP Dolibarr</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=95</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=95</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Thu, 28 Dec 2023 10:38:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/95.jpg" style="display: block; margin: 1em auto" /></p><p>Chez IMASDEWEB, nous avons développé le module "Achats" pour le projet open source Dolibarr ERP / CRM en PHP. Dans ce guide, nous présentons son fonctionnement, que vous soyez déjà utilisateur ou que vous envisagiez de l'utiliser.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/95.jpg" style="display: block; margin: 1em auto" /></p>
<p>Chez IMASDEWEB, nous avons d&eacute;velopp&eacute; le module &quot;<u>Purchases</u>&quot; (Achats) pour le <strong>projet open source Dolibarr ERP/CRM</strong> en PHP. Dans ce guide, nous pr&eacute;sentons son fonctionnement, que vous soyez d&eacute;j&agrave; utilisateur ou que vous envisagiez de l&#39;utiliser.</p>
<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/dolibarr-PURCHASES-COMPRAS-module_napkin-FR.svg" style="width:100%;max-width:1000px;" /></p>

<div class="block">
<ul>
	<li><a href="#presentacion">Pr&eacute;sentation</a></li>
	<li><a href="#instalacion">Installation</a></li>
	<li><a href="#acceso">Acc&egrave;s au module</a></li>
	<li><a href="#listado">Liste des achats</a></li>
	<li><a href="#editando">&Eacute;dition d&#39;un achat</a></li>
	<li><a href="#cotizaciones">Demander des devis aux fournisseurs</a></li>
	<li><a href="#demo">Site web de D&Eacute;MO</a></li>
</ul>
</div>

<p><b>Nota:</b> <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=35">versi&oacute;n en castellano</a> de este manual de usuario.</p>

<p><b>Note:</b> <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=36">english version</a> of this user guide.</p>

<p id="presentacion">&nbsp;</p>

<h2>Pr&eacute;sentation</h2>

<p>Ce module Achats a &eacute;t&eacute; d&eacute;velopp&eacute; comme un assistant permettant de r&eacute;aliser de mani&egrave;re rapide et simple l&#39;achat de X produits:</p>

<div class="block">
<ul>
	<li>En permettant de <strong>comparer les prix de plusieurs fournisseurs</strong>, m&ecirc;me dans diff&eacute;rentes devises.<br />
	&nbsp;</li>
	<li>En permettant d&#39;envoyer par courriel en un seul clic des <strong>invitations &agrave; nos fournisseurs s&eacute;lectionn&eacute;s</strong> pour qu&#39;ils visitent un lien. Ce lien leur donne acc&egrave;s &agrave; un <strong>formulaire multilingue</strong> simple o&ugrave; ils peuvent saisir les prix pour nous, d&eacute;cliner ou confirmer la vente de certains des produits demand&eacute;s, et ajouter des commentaires suppl&eacute;mentaires sur les conditions de livraison et/ou de paiement.<br />
	&nbsp;</li>
	<li>En permettant de <strong>modifier / ajouter / supprimer les prix</strong> de n&#39;importe quel fournisseur pour n&#39;importe quel produit depuis ce m&ecirc;me tableau de prix, en seulement deux clics.<br />
	&nbsp;</li>
	<li>En permettant de <strong>cr&eacute;er les commandes correspondantes</strong> &eacute;galement avec deux clics, remplies automatiquement avec toutes les informations de chaque fournisseur et les produits.</li>
</ul>
</div>

<p>En fin de compte, une interface plus facile et plus agile &agrave; utiliser qui permet de faire la m&ecirc;me chose que vous pouvez d&eacute;j&agrave; faire avec l&#39;interface native de Dolibarr, mais de mani&egrave;re beaucoup plus confortable. Bien, en fait, dans Dolibarr, il serait tr&egrave;s complexe de comparer les prix de chaque produit pour chaque fournisseur, puis d&#39;assembler les diff&eacute;rentes commandes. Et &eacute;videmment, il n&#39;y a aucun moyen de capturer les prix dont vous avez besoin.</p>

<div class="iframe_wrapper"><iframe allowfullscreen="" frameborder="0" mozallowfullscreen="" scrolling="no" src="https://imasdeweb.com///slides.com/caos30/dolibarr-purchases-en/embed" webkitallowfullscreen=""></iframe></div>

<p>
<style type="text/css">.iframe_wrapper {
		position: relative;
		padding-bottom: 65.25%;
		padding-top: 100px;
		height: 0;
		overflow: auto; 
	} 
	.iframe_wrapper iframe {
		position: absolute;
		top: 0;
		left: 0;
		width: 90%;
		height: 100%;
		margin-left:5%;
	}
</style>
</p>

<p id="instalacion">&nbsp;</p>

<h2>Installation</h2>

<p>Vous devez d&eacute;j&agrave; savoir qu&#39;installer un module dans Dolibar est aussi simple que:</p>

<div class="block">
<ol>
	<li>Aller dans <code>Configuration &gt; Modules &gt; Installer un module externe</code></li>
	<li>T&eacute;l&eacute;charger le fichier ZIP que vous avez obtenu depuis la boutique</li>
</ol>
</div>

<p>Une fois cela fait, il appara&icirc;tra dans la configuration des modules, dans le panneau de Dolibarr. Dans le cas de ce module, vous le verrez dans le groupe <u>Gestion des Relations avec les Fournisseurs (SRM)</u>, sous le nom <u>Achats</u>.</p>

<p class="a_c"><a href="UserFiles/Image/2023/ACHATS-Gestion-de-la-relation-fournisseur.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS-Gestion-de-la-relation-fournisseur.png" /></a></p>

<p id="acceso">&nbsp;</p>

<h2>Acc&egrave;s au module</h2>

<p>Une fois activ&eacute;, nous y acc&eacute;derons de deux mani&egrave;res possibles:</p>

<p>&nbsp;</p>

<ul>
	<li>en visitant la section <u>Commerciale</u>, puis dans le menu lat&eacute;ral gauche, nous verrons les deux options pour ce module : <u>Nouvel achat</u> / <u>Liste</u><br />
	<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="UserFiles/Image/2023/ACHATS_lateral-menu.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_lateral-menu.png" /></a><br />
	&nbsp;</li>
	<li>ou bien, depuis le Tableau de bord de d&eacute;marrage, o&ugrave; nous aurons une bo&icirc;te avec les <u>5 derniers achats</u>.<br />
	<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="UserFiles/Image/2023/ACHATS_5-derniers-achats.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_5-derniers-achats.png" /></a><br />
	&nbsp;</li>
</ul>

<p id="listado">&nbsp;</p>

<h2>Liste des achats</h2>

<p>Il n&#39;y a pas grand-chose &agrave; dire sur la liste des processus d&#39;achat. Le plus int&eacute;ressant est d&#39;expliquer les valeurs possibles pour la colonne <u>&Eacute;tat</u>:</p>

<div class="block">
<ul>
	<li><strong>Brouillon</strong>: lorsque nous avons seulement une liste de produits &agrave; acheter</li>
	<li><strong>En cours de cotation</strong>: lorsque nous avons des prix d&#39;un ou plusieurs fournisseurs pour certains des produits &agrave; acheter</li>
	<li><strong>En cours d&#39;achat</strong>: lorsque un prix a &eacute;t&eacute; s&eacute;lectionn&eacute; pour certains des produits et qu&#39;une commande d&#39;achat correspondante a &eacute;t&eacute; cr&eacute;&eacute;e</li>
	<li><strong>Compl&eacute;t&eacute;</strong>: lorsque des commandes d&#39;achat ont &eacute;t&eacute; cr&eacute;&eacute;es pour tous les produits</li>
</ul>
</div>

<p class="a_c"><a href="UserFiles/Image/2023/ACHATS_Processus-d-achat.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Processus-d-achat.png" /></a></p>

<p id="editando">&nbsp;</p>

<h2>&Eacute;dition d&#39;un achat</h2>

<p>La fiche d&#39;un achat en cours se pr&eacute;senterait comme celle montr&eacute;e ci-dessous (cliquez pour ouvrir dans un nouvel onglet du navigateur et voir le d&eacute;tail):</p>

<p class="a_c" style="text-align: center;"><a href="UserFiles/Image/2023/ACHATS_Acheter-fiche.png"><img height="300" src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Acheter-fiche.png" /> </a></p>

<ul>
	<li>En haut, il y a un bref formulaire avec juste les informations descriptives minimales, parmi lesquelles il vaut la peine de souligner que nous pouvons <strong>lier l&#39;achat &agrave; un projet</strong> que nous avons cr&eacute;&eacute; dans Dolibarr, si nous avons activ&eacute; le <u>module Projets</u>.<br />
	&nbsp;</li>
	<li>Sous ce bref formulaire, il y a une barre de boutons d&#39;action, pour enregistrer des modifications dans ledit formulaire, pour envoyer par courriel des demandes de devis aux fournisseurs s&eacute;lectionn&eacute;s, pour cr&eacute;er des commandes ou pour supprimer l&#39;achat:<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_Acheter-card-buttons.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Acheter-card-buttons.png" /></a><br />
	&nbsp;</li>
	<li>Sous ces boutons, nous avons la liste des produits : un tableau o&ugrave; chaque ligne contiendra un produit &agrave; acheter et &agrave; son tour un tableau comparant les prix d&#39;un ou plusieurs fournisseurs. Dans la premi&egrave;re ligne, nous avons l&#39;<strong>&eacute;tat de ce produit</strong> : <strong>1)</strong> sans prix, <strong>2)</strong> avec prix mais sans commande, <strong>3)</strong> une commande cr&eacute;&eacute;e.<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_Acheter-card-produit.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Acheter-card-produit.png" /></a><br />
	<br />
	De plus, tant que nous n&#39;avons pas pass&eacute; la commande, nous pouvons changer la quantit&eacute; que nous avons besoin d&#39;acheter. Les <strong>boutons</strong> situ&eacute;s &agrave; la fin de la ligne nous permettent de : retirer le produit de ce processus d&#39;achat, enregistrer les modifications (si nous modifions une valeur dans l&#39;une des bo&icirc;tes de texte de cette ligne du tableau), acc&eacute;der &agrave; la page de gestion des stocks du produit dans Dolibarr.<br />
	<br />
	<strong>Note:</strong> il est important de comprendre que nous pouvons changer les valeurs des bo&icirc;tes de texte de ce tableau de prix, c&#39;est-&agrave;-dire changer la quantit&eacute; du produit, le prix unitaire ou le minimum d&#39;unit&eacute;s que le fournisseur exige que nous achetions, et la page recalculera automatiquement en temps r&eacute;el le prix final dans la derni&egrave;re colonne, dans la monnaie de notre entreprise, mais ces changements ne seront pas sauvegard&eacute;s automatiquement sur le serveur (!!) donc si nous voulons sauvegarder les changements, nous devons appuyer sur le bouton d&#39;enregistrement des modifications.<br />
	<br />
	&nbsp;</li>
	<li>Examinons en d&eacute;tail le <strong>tableau de comparaison des prix</strong>. La partie contenant les bo&icirc;tes pour &eacute;diter les prix est particuli&egrave;rement int&eacute;ressante:<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_Acheter-card-comparaison-des-prix.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Acheter-card-comparaison-des-prix.png" /></a><br />
	<br />
	<strong>Couleurs</strong>: les zones de texte appara&icirc;tront en <u>vert</u> si le fournisseur concern&eacute; a r&eacute;pondu &agrave; la demande de devis (nous verrons plus bas comment faire cette demande) et a confirm&eacute; avoir en stock ce produit. En revanche, elles appara&icirc;tront en <u>orange</u> si la demande a d&eacute;j&agrave; &eacute;t&eacute; envoy&eacute;e &agrave; ce fournisseur mais qu&#39;il n&#39;a pas encore r&eacute;pondu. Finalement, elles seront en <u>rouge</u> lorsque le fournisseur aura r&eacute;pondu et indiqu&eacute; qu&#39;il ne peut pas fournir ce produit. Dans ce dernier cas, le contr&ocirc;le circulaire pour <u>Cr&eacute;er une commande</u> (derni&egrave;re colonne du tableau des prix) sera d&eacute;sactiv&eacute; et remplac&eacute; par une ic&ocirc;ne qui affichera le commentaire laiss&eacute; par le fournisseur.<br />
	<br />
	<strong>Calculs</strong>: cela dit, avec ce module Achats et le patch Dolibarr sugg&eacute;r&eacute;, nous pouvons g&eacute;rer &quot;normalement&quot; les prix des fournisseurs dans d&#39;autres monnaies (premi&egrave;re colonne) et en m&ecirc;me temps pouvoir comparer le prix final (avant-derni&egrave;re colonne) dans notre propre monnaie (MXN dans mon cas). Gardez &agrave; l&#39;esprit que pour calculer le <u>Prix final</u>, le <u>Prix unitaire</u> est multipli&eacute; par le <u>Minimum d&#39;unit&eacute;s</u> ou par le nombre d&#39;<u>Unit&eacute;s</u> (le plus &eacute;lev&eacute; de ces deux valeurs est pris). Par exemple, dans le cas du deuxi&egrave;me fournisseur de l&#39;image (celui en orange), il exige d&#39;acheter un minimum de 5 unit&eacute;s, donc nous multiplions le prix unitaire par 5 pour obtenir le Prix final. Tandis que pour les autres fournisseurs, nous multiplions par 4, qui est le nombre d&#39;unit&eacute;s dont nous avons besoin.<br />
	<br />
	<strong>Changements de monnaie</strong>: les changements de monnaie (c&#39;est-&agrave;-dire, combien de MXN sont un USD) sont pris <strong>en temps r&eacute;el</strong> par le module Achats sur le site web du <a class="a_icon" href="https://www.imf.org/external/np/fin/data/rms_rep.aspx" target="_blank">Fonds Mon&eacute;taire International</a>. En r&eacute;alit&eacute;, pour ne pas appeler trop souvent ce site externe et pour ne pas ralentir le chargement de cette page de devis, une consultation de ce site est faite <strong>seulement toutes les 12 heures</strong>. En d&eacute;finitive, nous pouvons &ecirc;tre assez s&ucirc;rs que le calcul entre monnaies est suffisamment ajust&eacute; &agrave; la r&eacute;alit&eacute;, et fonctionne totalement de mani&egrave;re automatique et en arri&egrave;re-plan. Au fait, vous devez aussi savoir que une fois que nous passons la commande d&#39;un produit, le module Achats enregistre les changements de monnaie &agrave; ce moment-l&agrave;, et &agrave; l&#39;avenir, lorsque vous reviendrez consulter la fiche de cet achat, il vous montrera le tableau comparatif des prix conform&eacute;ment aux changements de monnaie au moment de passer la commande. Tant qu&#39;une commande n&#39;est pas cr&eacute;&eacute;e, les changements seront mis &agrave; jour, donc aujourd&#39;hui vous pouvez voir un prix de $11USD en pesos mexicains diff&eacute;rent de celui que vous voyiez hier dans le m&ecirc;me tableau, &eacute;videmment parce que chaque jour les taux de change fluctuent.<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_Acheter-card-comparaison-des-prix.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Acheter-card-comparaison-des-prix.png" /></a><br />
	<br />
	<br />
	<img alt="" src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_bouton-retirer.png" /> <strong>Delete button</strong>: when clicked, it will show us a dialog box asking if we want to only remove this price from this comparison, or if <strong>we also want to eliminate the price of this supplier for this Dolibarr system product</strong>. If you are sure that the supplier is never going to sell you that product or simply has never given you a price, it is advisable that you choose the second option.<br />
	<br />
	<img alt="" src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_bouton-edit.png" /> <strong>Edit price button</strong>: will open in a new tab of the browser the usual Dolibarr form for editing the price of this supplier for this product. What is useful for us? Well, because there we have more editing options than in our comparison table. For example, there we can edit the VAT to apply for this product.<br />
	<br />
	<img alt="" src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_bouton-email.png" /> <strong>Email button</strong>: is a link of the type &quot;mailto&quot; and therefore will open our mailing program that we have configured on our machine, by filling in the recipient&#39;s box with the email address of the supplier in question. For this reason, this button does not appear when in Dolibarr we have not filled in the email field for the supplier in question.<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_Acheter-card-comparaison-des-prix.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_Acheter-card-comparaison-des-prix.png" /></a><br />
	<br />
	<strong>Cr&eacute;er une commande</strong>: finalement, lorsque nous aurons les prix que nous attendions des diff&eacute;rents fournisseurs, ou lorsque nous devrons passer une commande, nous cocherons la case circulaire de la derni&egrave;re colonne Cr&eacute;er une commande. En r&eacute;alit&eacute;, la mani&egrave;re de proc&eacute;der est la suivante : pour chacun des produits que nous avons inclus dans cet achat, nous marquerons les offres des fournisseurs qui nous semblent les plus appropri&eacute;es. <strong>Et sans avoir besoin d&#39;avoir fait ce choix pour tous les produits</strong>, nous cliquerons sur le bouton <u>Cr&eacute;er des commandes</u> situ&eacute; au-dessus du tableau des produits et la page d&eacute;ploiera un nouveau tableau avec les commandes &agrave; cr&eacute;er pour chaque fournisseur, s&#39;il y a plusieurs fournisseurs s&eacute;lectionn&eacute;s, et les produits &agrave; commander &agrave; chacun:<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_creer-les-commandes.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_creer-les-commandes.png" /></a><br />
	<br />
	Si nous cliquons &agrave; nouveau sur le bouton <u>Cr&eacute;er des commandes</u>, la bo&icirc;te de dialogue se cachera, et si nous le faisons &agrave; nouveau, elle r&eacute;appara&icirc;tra mais mise &agrave; jour. C&#39;est-&agrave;-dire que si entre les deux clics nous avons chang&eacute; notre s&eacute;lection de fournisseur pour un produit, <strong>cette liste de commandes/fournisseurs sera mise &agrave; jour</strong>.<br />
	<br />
	Lorsque nous cliquons sur l&#39;un des boutons <u>Cr&eacute;er une commande</u> dans la colonne <u>Action</u>, le module Achats <strong>cr&eacute;era la commande correspondante en mode brouillon</strong>, en remplissant les informations du fournisseur, du taux de change (si elle est dans une monnaie diff&eacute;rente de celle de notre entreprise) et la liste des produits et quantit&eacute;s que nous devons acheter. Le nouveau bon de commande s&#39;ouvrira dans <strong>un nouvel onglet du navigateur</strong>.<br />
	<br />
	Une fois une commande cr&eacute;&eacute;e de cette mani&egrave;re, en actualisant cette page d&#39;achat, nous verrons que le <strong>tableau comparatif des prix des produits command&eacute;s a &eacute;t&eacute; d&eacute;sactiv&eacute;</strong> et un bouton appara&icirc;t, nous donnant <strong>acc&egrave;s &agrave; la fiche de la commande</strong> en question:<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_commande-aprouve.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_commande-aprouve.png" /></a><br />
	<br />
	&nbsp;</li>
</ul>

<p id="cotizaciones">&nbsp;</p>

<h2>Demander des devis aux fournisseurs</h2>

<div class="block">
<p>La premi&egrave;re chose &agrave; noter est que ce module Achats n&#39;utilise pas la fonctionnalit&eacute; native de Demande de devis aux fournisseurs que Dolibarr int&egrave;gre de mani&egrave;re native. Nous avons choisi de construire notre propre solution pour &eacute;viter les probl&egrave;mes li&eacute;s &agrave; la multidevise dans Dolibarr. Ainsi, vous allez voir que le syst&egrave;me que nous avons d&eacute;velopp&eacute; est hautement fonctionnel, multidevise et multilingue, mais il ne cr&eacute;e aucun enregistrement dans Dolibarr pour les devis des fournisseurs.</p>
</div>

<p>Cela dit, nous devons proc&eacute;der de cette mani&egrave;re:</p>

<ol>
	<li>Une fois que dans notre achat, nous avons pr&eacute;par&eacute; la liste des produits &agrave; acheter<br />
	&nbsp;</li>
	<li>Le syst&egrave;me aura automatiquement ajout&eacute; les prix des fournisseurs d&eacute;j&agrave; pr&eacute;sents dans notre syst&egrave;me pour ces produits<br />
	&nbsp;</li>
	<li>Optionnellement, nous pouvons ajouter plus de fournisseurs &agrave; un produit sp&eacute;cifique (vous pouvez indiquer un prix de &quot;0&quot; si vous n&#39;avez pas encore le prix de ces fournisseurs pour ce produit)<br />
	&nbsp;</li>
	<li>Ensuite, en cliquant sur le bouton <u>Envoyer des e-mails demandant un devis</u>, une bo&icirc;te de dialogue s&#39;affichera, d&#39;o&ugrave; avec un seul clic sur le nouveau bouton <u>Envoyer des e-mails demandant un devis</u>, ces e-mails seront envoy&eacute;s, au moins aux fournisseurs pour lesquels nous avons une adresse e-mail d&eacute;finie. Dans le cas de l&#39;image ci-dessous, seulement le premier.<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_demander-des-devis.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_demander-des-devis.png" /></a><br />
	&nbsp;</li>
	<li>Dans cet e-mail que recevront les fournisseurs, il leur est sp&eacute;cifi&eacute; DANS LEUR LANGUE (tant que le module Achats est traduit dans cette langue) la <strong>liste des produits</strong> que nous souhaitons faire chiffrer et ils sont <strong>invit&eacute;s &agrave; visiter un formulaire web</strong> o&ugrave; ils peuvent eux-m&ecirc;mes saisir les prix et les conditions.<br />
	&nbsp;</li>
	<li><strong>Nous pouvons visiter ce formulaire web de saisie des prix</strong> en cliquant sur les boutons Formulaire de la bo&icirc;te de dialogue pr&eacute;c&eacute;dente. Chaque formulaire est unique pour chaque achat et fournisseur, et <strong>les param&egrave;tres de l&#39;URL sont crypt&eacute;s pour &eacute;viter qu&#39;ils puissent manipuler l&#39;URL et acc&eacute;der aux prix d&#39;autres fournisseurs</strong>.<br />
	<br />
	Il est recommand&eacute; que si le fournisseur en question n&#39;a pas d&#39;e-mail ou nous transmet ses prix par un autre moyen (t&eacute;l&eacute;phone, WhatsApp, courrier, etc.), nous utilisions son formulaire de saisie pour introduire ses prix. De cette fa&ccedil;on, nous les verrons marqu&eacute;s en vert (ou en rouge, si un produit n&#39;est pas disponible) dans le tableau comparatif des prix de ce module.<br />
	&nbsp;</li>
	<li>Voici &agrave; quoi ressemble ce formulaire web de saisie des prix pour le fournisseur:<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_demande-de-devis-MULTI-LANGUAGE.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_demande-de-devis-MULTI-LANGUAGE.png" /></a><br />
	<br />
	Il n&#39;a pas besoin de beaucoup de commentaires, <strong>car il est con&ccedil;u pour &ecirc;tre auto-explicatif </strong>afin que les fournisseurs se sentent le plus &agrave; l&#39;aise possible. Si nous cliquons sur le bouton <u>Informations suppl&eacute;mentaires</u>, le fournisseur a la possibilit&eacute; d&#39;ajouter un commentaire g&eacute;n&eacute;ral sur cette &quot;&eacute;ventuelle commande&quot;, et peut &eacute;galement nous fournir des informations de contact plus compl&egrave;tes. Mais c&#39;est une &eacute;tape facultative:<br />
	<br />
	<a href="UserFiles/Image/2023/ACHATS_demande-de-devis-INFORMATIONS-COMPLEMENTAIRES.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_demande-de-devis-INFORMATIONS-COMPLEMENTAIRES.png" /></a><br />
	<br />
	<strong>Note:</strong> <strong>au moment o&ugrave; nous passons une commande</strong> incluant certains de ces produits, que ce soit pour ce fournisseur ou pour un autre de notre liste, l&#39;introduction de prix dans les lignes correspondantes de ce <strong>tableau des prix sera bloqu&eacute;e</strong>, si le fournisseur entre tardivement ou visite ce formulaire ult&eacute;rieurement.<br />
	&nbsp;</li>
	<li>aAapr&egrave;s que le fournisseur ait appuy&eacute; sur le bouton Envoyer de ce formulaire de devis, le syst&egrave;me enverra un e-mail &agrave; l&#39;utilisateur de Dolibarr qui a cr&eacute;&eacute; cet achat dans le syst&egrave;me, avec les prix et les commentaires du fournisseur. Informations qui, par ailleurs, sont affich&eacute;es dans le tableau comparatif des prix du module. <strong>Ces prix modifient &eacute;galement les prix que nous avons stock&eacute;s dans Dolibarr</strong> pour ces produits et ce fournisseur.</li>
</ol>

<p id="demo">&nbsp;</p>

<h2>Site web de type D&Eacute;MO</h2>

<p class="a_c"><a href="UserFiles/Image/2023/ACHATS_demo-login.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/ACHATS_demo-login.png" /></a></p>

<p>Si vous &ecirc;tes int&eacute;ress&eacute; &agrave; tester le module Achats sur un Dolibarr 5.0.8, contactez-nous et nous serons heureux de vous fournir le nom d&#39;utilisateur et le mot de passe. Nous ne les publions pas ici pour &eacute;viter des attaques inutiles.</p>

<p class="a_c"><a class="bt" href="#" onclick="$('#TestDemoForm').toggle();$(this).hide();return false;">&rarr; Contact form</a></p>

<div id="TestDemoForm" style="display:none;"><form method='post' id='contactos_form_17_8999' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_58001' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_58001').html('<br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' />6<br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /> + <br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' />8<br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /><br style=\'display:none;\' rel=\'38962\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_65984' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_65984' name='captcha_formstamp' value='YlhkMVZHa3ZVbTVqVGtndlVrRkxZVVV6UkZOWFRXWTJkbGM0Y1V0cVZrNUtTa3RHYURGUFRHMHJRVDA2T21FMVpHSXpOR013Tm1Sa1pEVXdNREV3WXpJeE1ESXhZV0kwWmpBeU5ETXc' />
    <input type='hidden' id='captcha_valid_65984' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_65984').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_65984();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_65984').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_65984').val('');
                    $('#captcha_answer_65984').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_65984').val())+'&captcha_answer='+($('#captcha_answer_65984').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_65984').val(data.valid);
                    $('#captcha_answer_65984').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_65984').addClass('valid_captcha');
                    else
                        $('#captcha_answer_65984').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_65984(){
        if($('#captcha_answer_65984').val() == ''
                || $('#captcha_valid_65984').val()!='1'){

            $('#captcha_answer_65984').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_65984').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_8999();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_8999(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_8999');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_8999').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
]]></content:encoded>
        </item>
        
        <item>
            <title>Guide d'utilisation du module TOTP 2FA LOGIN (Authentification à Deux Facteurs) pour Dolibarr</title>
            <link>https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=97</link>
            <guid isPermaLink="false">https://imasdeweb.com/index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=97</guid>
            <dc:creator><![CDATA[Sergi Rodríguez]]></dc:creator>
            <pubDate>Thu, 28 Dec 2023 21:38:00 -0700</pubDate>
            <description><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/97.jpg" style="display: block; margin: 1em auto" /></p><p>Ce module a été développé par IMASDEWEB, avec une compatibilité à partir des versions 8 de Dolibarr. Permettez à vos utilisateurs Dolibarr d'accéder en utilisant l'authentification à deux facteurs (2FA) avec des codes temporaires (30 secondes) de 6 chiffres (Mot de Passe à Usage Unique Basé sur le Temps ou TOTP) que les utilisateurs génèrent avec une multitude d'applications pour smartphone ou navigateur web (Authy, Aegis, Google Authenticator, etc.) car en fait, c'est déjà une norme. Ou vous pouvez demander que ces codes soient envoyés à votre email chaque fois que vous souhaitez vous connecter.</p>]]></description>
            <content:encoded><![CDATA[<p><img src="https://imasdeweb.com/UserFiles/admin/modulo_blog/images/97.jpg" style="display: block; margin: 1em auto" /></p><div class="block">
<p>Ce module a &eacute;t&eacute; d&eacute;velopp&eacute; par IMASDEWEB, compatible avec les versions de Dolibarr 8 et ult&eacute;rieures. Il permet aux utilisateurs de votre Dolibarr d&#39;acc&eacute;der en utilisant une authentification &agrave; deux facteurs (Two-Factor Authentication ou 2FA) avec des codes temporaires (30 secondes) de 6 chiffres (Time-based One-Time Password ou TOTP) que les utilisateurs g&eacute;n&egrave;rent avec de nombreuses applications de t&eacute;l&eacute;phone portable ou de navigateur web (Authy, Aegis, Google Authenticator, etc.) car c&#39;est d&eacute;sormais un standard. C&#39;est le compl&eacute;ment d&eacute;finitif pour s&eacute;curiser davantage vos installations de Dolibarr.</p>

<p>Depuis la version 1.4, il <strong>est possible de filtrer les visiteurs par leur pays d&#39;origine</strong> (avec une liste blanche de pays).</p>

<p>&Agrave; partir de la version 1.7, il <strong>est d&eacute;sormais possible d&#39;activer l&#39;envoi du code temporaire de 6 chiffres par courriel</strong> &agrave; l&#39;utilisateur s&#39;il le demande depuis la page d&#39;acc&egrave;s.</p>

<p>Depuis la version 22.1, vous <strong>pouvez l&#39;utiliser comme PARE-FEU</strong> : vous pouvez d&eacute;finir quelques listes d&#39;IP et de plages d&#39;IP de confiance pour lesquelles vous pouvez soit les exempter de saisir le second facteur lors de la connexion, soit interdire la connexion &agrave; tout visiteur qui ne provient PAS de ces IP.</p>

<p><br />
<a class="a_icon" href="https://www.dolistore.com/fr/modules/1575-TOTP-2FA-Login---Filtre-de-pays.html" target="_blank">Disponible &agrave; la vente sur Dolistore uniquement pour 20&euro;.</a></p>
</div>

<p><b><u>Nota</u>:</b> <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=88">versi&oacute;n en espa&ntilde;ol</a> de esta gu&iacute;a de usuario.</p>

<p><b><u>Note</u>:</b> <a href="index.php?pag=m_blog&amp;gad=detalle_entrada&amp;entry=89">english version</a> of this user guide.</p>

<h3 class="a_c">Acc&egrave;s &agrave; la D&Eacute;MO</h3>

<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Je suis intéressé à accéder à la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_17_4606' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_85584' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_85584').html('<br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' />6<br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' /> + <br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' />0<br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' /><br style=\'display:none;\' rel=\'6\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_80557' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_80557' name='captcha_formstamp' value='Y1dKVGFFODBOMDlwYjBsaFZVaExaV2x5U3pabE5WaHlkR1ppYjFkVVJGVjVkV0ozY1RsRk1VdHhaejA2T21RNU5XRmtZV0UxWW1JeE9XTTROems0TWpVM05qVmhZell3TUdJd056Wm0' />
    <input type='hidden' id='captcha_valid_80557' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_80557').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_80557();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_80557').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_80557').val('');
                    $('#captcha_answer_80557').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_80557').val())+'&captcha_answer='+($('#captcha_answer_80557').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_80557').val(data.valid);
                    $('#captcha_answer_80557').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_80557').addClass('valid_captcha');
                    else
                        $('#captcha_answer_80557').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_80557(){
        if($('#captcha_answer_80557').val() == ''
                || $('#captcha_valid_80557').val()!='1'){

            $('#captcha_answer_80557').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_80557').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_4606();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_4606(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_4606');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_4606').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>

<table style="width:auto;margin:2em auto;">
	<tbody>
		<tr>
			<td>
			<ol>
				<li><a href="#a-quoi-sert-ce-module">&Agrave; quoi sert ce module ?</a></li>
				<li><a href="#connexion-recevoir-code-par-email">Connexion en recevant le code par e-mail</a></li>
				<li><a href="#activer-cle-totp-utilisateur">Activer la cl&eacute; TOTP d&#39;un utilisateur</a></li>
				<li><a href="#definir-votre-cle-secrete-personnalisee">Vous pouvez d&eacute;finir votre propre cl&eacute; secr&egrave;te</a></li>
				<li><a href="#considerations-de-securite">Consid&eacute;rations de s&eacute;curit&eacute;</a></li>
				<li><a href="#desactiver-cle-totp-utilisateur">D&eacute;sactivation de la cl&eacute; TOTP d&#39;un utilisateur</a></li>
				<li><a href="#filtrer-visiteurs-par-pays-origine">Filtrer les visiteurs en fonction de leur pays d&#39;origine</a></li>
				<li><a href="#listes-blanches-ip-de-confiance-pare-feu">Listes blanches d&#39;IP de confiance (Pare-feu)</a>
				<ol>
					<li><a href="#quelle-ip-dois-je-utiliser">Quelle IP dois-je utiliser ?</a></li>
					<li><a href="#utiliser-plages-ip-pour-flexibilite">Utiliser des plages d&#39;IP pour la flexibilit&eacute;</a></li>
					<li><a href="#guide-rapide-CIDR">Guide rapide CIDR</a></li>
					<li><a href="#deux-listes-blanches-separees">Deux listes blanches s&eacute;par&eacute;es</a></li>
				</ol>
				</li>
				<li><a href="#memoriser-appareil-comme-sur">M&eacute;moriser un appareil comme s&ucirc;r</a></li>
				<li><a href="#comment-acceder-a-dolibarr">Alors, comment dois-je acc&eacute;der &agrave; Dolibarr maintenant ?</a></li>
				<li><a href="#foire-aux-questions">Foire aux questions</a>
				<ol>
					<li><a href="#si-je-suis-bloque">que faire si je suis bloqu&eacute;</a></li>
				</ol>
				</li>
				<li><a href="#acces-a-demo">Acc&egrave;s &agrave; la DEMO</a></li>
			</ol>
			</td>
		</tr>
	</tbody>
</table>

<p id="a-quoi-sert-ce-module">&nbsp;</p>

<h3 class="a_c">&Agrave; quoi sert ce module</h3>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2025/dolibarr-TOTPFA-module_napkin-FR.svg" style="width:100%;max-width:800px;" /></p>

<p>Une fois install&eacute; et activ&eacute;, le module ajoutera une troisi&egrave;me zone de texte sur la page de connexion:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_login.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_login.png" /></a></p>

<p>Consid&eacute;rations pour remplir cette troisi&egrave;me zone:</p>

<ul>
	<li>Il est OPTIONNEL de la remplir: <strong>elle ne sera valid&eacute;e que si l&#39;utilisateur qui essaie de se connecter a activ&eacute; l&#39;utilisation de TOTP 2FA</strong>. Pour les autres utilisateurs, l&#39;authentification continuera de se faire uniquement avec le nom d&#39;utilisateur et le mot de passe.<br />
	&nbsp;</li>
	<li>Vous devez entrer un <strong>code TOTP de 6 chiffres</strong> g&eacute;n&eacute;r&eacute; par des applications telles que <a class="a_icon" href="https://f-droid.org/en/packages/com.beemdevelopment.aegis/" target="_blank">Aegis</a> (Android) ou d&#39;autres applications multiplateformes comme <a class="a_icon" href="https://authy.com/download/" target="_blank">Authy</a> ou <a class="a_icon" href="https://support.google.com/accounts/answer/1066447" target="_blank">Google Authenticator</a>.<br />
	&nbsp;</li>
	<li>Ce syst&egrave;me d&#39;authentification d&eacute;pend du fait que le serveur sur lequel Dolibarr est install&eacute; et l&#39;appareil sur lequel l&#39;utilisateur a install&eacute; l&#39;application de g&eacute;n&eacute;ration de codes aient leur <strong>horloge interne synchronis&eacute;e</strong> avec l&#39;heure sur internet. Normalement, cela n&#39;est pas exact, et le code g&eacute;n&eacute;r&eacute; par l&#39;application est en avance ou en retard par rapport &agrave; celui du serveur, donc ne vous inqui&eacute;tez pas si vous ne r&eacute;ussissez pas &agrave; vous connecter du premier coup. Dans ces cas, essayez d&#39;utiliser le code d&#39;acc&egrave;s au d&eacute;but de la p&eacute;riode de 30 secondes que vous donne l&#39;application, ou bien &agrave; la fin. Normalement, cela fonctionnera &agrave; l&#39;une de ces deux extr&eacute;mit&eacute;s. Si ce n&#39;est pas le cas, vous devrez v&eacute;rifier lequel n&#39;est pas correctement r&eacute;gl&eacute; : votre application ou votre serveur Dolibarr (g&eacute;n&eacute;ralement, le probl&egrave;me vient de l&#39;application ou de l&#39;heure du t&eacute;l&eacute;phone sur lequel l&#39;application est install&eacute;e).</li>
</ul>

<p id="connexion-recevoir-code-par-email">&nbsp;</p>

<h3>Acc&egrave;s en recevant le code par courriel</h3>

<p>Cela est possible depuis la version 1.7 (D&eacute;c. 2022). C&#39;est une alternative d&#39;utilisation que chaque utilisateur doit activer s&#39;il souhaite l&#39;utiliser. Une fois activ&eacute;, pour se connecter, il faut:</p>

<ol>
	<li>saisir le nom d&#39;utilisateur et le mot de passe corrects, et laisser vide la case du code</li>
	<li>
	<p>en cliquant sur le bouton CONNEXION, le syst&egrave;me actualisera le formulaire d&#39;acc&egrave;s. <u>Si les identifiants &eacute;taient corrects</u>, il affichera alors un lien pour envoyer l&#39;email dans ces conditions :</p>

	<p>a) l&#39;utilisateur a <u>activ&eacute; l&#39;envoi par email de ce code</u> (c&#39;est une option que chaque utilisateur peut activer/d&eacute;sactiver)<br />
	b) ou bien l&#39;administrateur a configur&eacute; le module pour <u>exiger TOUJOURS de tous les utilisateurs l&#39;utilisation du deuxi&egrave;me facteur</u> et a &eacute;galement <u>activ&eacute; l&#39;option d&#39;envoi par email pendant la &laquo; p&eacute;riode de gr&acirc;ce &raquo;</u>, pendant que l&#39;utilisateur n&#39;a pas encore configur&eacute; son TOTP.</p>
	</li>
	<li>en cliquant sur ce lien, le syst&egrave;me envoie un code temporaire de 6 chiffres au courriel de l&#39;utilisateur et le confirme &agrave; l&#39;&eacute;cran</li>
	<li>apr&egrave;s avoir re&ccedil;u le courriel, il faut saisir le code re&ccedil;u avant 30 secondes et appuyer de nouveau sur le bouton CONNEXION</li>
</ol>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_login-mail-code.png" /></p>

<p>&Eacute;videmment, ce m&eacute;canisme est &eacute;galement utile pour pouvoir acc&eacute;der lorsque l&#39;on n&#39;a pas acc&egrave;s au g&eacute;n&eacute;rateur TOTP. Mais il sera aussi le m&eacute;canisme pr&eacute;f&eacute;r&eacute; de nombreux de vos utilisateurs, qui ne sont pas encore habitu&eacute;s &agrave; utiliser une application g&eacute;n&eacute;ratrice de codes TOTP. 😅</p>

<p id="activer-cle-totp-utilisateur">&nbsp;</p>

<h3>Activer la cl&eacute; TOTP d&#39;un utilisateur</h3>

<p>Nous irons &agrave; notre fiche utilisateur (personne ne peut l&#39;activer pour nous) et l&agrave;, nous verrons un bouton ACTIVER:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_Activer-la-cle-TOTP.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Activer-la-cle-TOTP.png" /></a></p>

<p>En le pressant, le navigateur demandera au serveur une cl&eacute; TOTP de 16 chiffres et son code QR correspondant. Vous devez ouvrir votre application de g&eacute;n&eacute;ration de codes et chercher l&#39;option &quot;ajouter un nouveau compte&quot;. Si c&#39;est une application mobile, elle vous donnera normalement l&#39;option de &quot;scanner un code QR&quot;, mais si ce n&#39;est pas le cas, vous pouvez toujours copier manuellement la cl&eacute; de 16 chiffres:</p>

<p class="a_c"><a href="FR-TOTP_Activer-la-cle-TOTP-validation.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Activer-la-cle-TOTP-validation.png" /></a></p>

<p>Pour que cette cl&eacute; soit LI&Eacute;E &Agrave; VOTRE UTILISATEUR, vous devez utiliser cette application de g&eacute;n&eacute;ration de codes pour prendre votre premier code TOTP et le valider (voir ci-dessus). Vous pouvez essayer autant de fois que n&eacute;cessaire. Si vous ne parvenez pas &agrave; valider aucun code, v&eacute;rifiez alors la configuration horaire de votre appareil (ou peut-&ecirc;tre aussi de votre serveur, bien que ce soit &eacute;trange qu&#39;un serveur soit &quot;hors du temps&quot;).</p>

<div class="block">
<p><strong><u>Note</u>:</strong> depuis la version 1.7 (d&eacute;c. 2022), nous pouvons choisir de ne pas utiliser une application g&eacute;n&eacute;ratrice de TOTP (ou de la configurer plus tard) et, entre-temps, utiliser l&#39;email pour recevoir le code &agrave; 6 chiffres &agrave; valider. Comme le montre l&#39;image ci-dessus, vous avez un bouton pour demander au syst&egrave;me de vous envoyer le code. Rappelez-vous que ce sont des codes temporaires <u>valides pendant 30 secondes</u>.<br />
<br />
D&#39;ailleurs, gardez &agrave; l&#39;esprit que si vous utilisez l&#39;envoi par email du code de validation &agrave; 6 chiffres, l&#39;option &quot;envoi par email&quot; sera activ&eacute;e pour les acc&egrave;s ult&eacute;rieurs. Bien que vous puissiez d&eacute;sactiver ou activer manuellement cette option pour votre utilisateur.</p>
</div>

<p>Une fois que vous avez valid&eacute; un code, la cl&eacute; devient LI&Eacute;E:</p>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Activer-la-cle-TOTP-validation-ok.png" /></p>

<p>&Agrave; partir de ce moment, si vous ou quelqu&#39;un d&#39;autre essaie d&#39;acc&eacute;der &agrave; Dolibarr avec votre nom d&#39;utilisateur et votre mot de passe sans saisir un code TOTP correct, il ne pourra plus acc&eacute;der &agrave; Dolibarr:</p>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_error-login.png" /></p>

<p id="definir-votre-cle-secrete-personnalisee">&nbsp;</p>

<h3>Vous pouvez d&eacute;finir votre propre cl&eacute; secr&egrave;te</h3>

<p>Particuli&egrave;rement utile pour ceux d&#39;entre nous qui administrent plusieurs instances de Dolibarr est la possibilit&eacute; d&#39;utiliser la m&ecirc;me cl&eacute; secr&egrave;te dans toutes ces instances pour le 2FA. Pour cela, le module facilite les choses de la mani&egrave;re suivante (&agrave; partir de la version 1.2) : lorsque nous essayons d&#39;activer le 2FA, il g&eacute;n&egrave;re un jeton al&eacute;atoire et affiche son code QR, comme nous l&#39;avons vu ci-dessus. &Agrave; ce moment, nous devons appuyer sur le bouton avec le crayon qui se trouve au-dessus du code QR, &agrave; c&ocirc;t&eacute; du jeton g&eacute;n&eacute;rateur:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_Activer-la-cle-TOTP-validation.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Activer-la-cle-TOTP-validation.png" /></a></p>

<p>Et ainsi nous pourrons &eacute;diter manuellement la cl&eacute; secr&egrave;te:</p>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Custom-Activer-la-cle-TOTP.png" /></p>

<p>En appuyant sur le bouton avec le code QR (&agrave; sa droite) ou en faisant ENTR&Eacute;E, le processus de validation et d&#39;activation continue comme dans le cas ci-dessus:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_Custom-Activer-la-cle-TOTP-validation.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Custom-Activer-la-cle-TOTP-validation.png" /></a></p>

<p id="considerations-de-securite">&nbsp;</p>

<h3>Consid&eacute;rations de s&eacute;curit&eacute;</h3>

<p>Veuillez prendre en compte ce qui suit:</p>

<ul>
</ul>

<ul>
	<li>Chaque utilisateur doit activer sa propre cl&eacute; TOTP de 16 chiffres. Personne ne peut le faire &agrave; sa place, pas m&ecirc;me un utilisateur administrateur.</li>
	<li>Les utilisateurs administrateurs peuvent voir quels utilisateurs ont activ&eacute; leur cl&eacute; TOTP, mais ils ne peuvent pas conna&icirc;tre la cl&eacute; elle-m&ecirc;me. Cela permet d&#39;&eacute;viter les risques d&#39;usurpation d&#39;identit&eacute; lors de l&#39;acc&egrave;s &agrave; Dolibarr.</li>
	<li>Cependant, un utilisateur administrateur peut D&Eacute;SACTIVER la cl&eacute; TOTP d&#39;autres utilisateurs. Cette proc&eacute;dure est mise en place comme un m&eacute;canisme simple pour d&eacute;sactiver les cl&eacute;s TOTP dans le cas o&ugrave; un utilisateur perd sa cl&eacute; et a besoin d&#39;acc&eacute;der au syst&egrave;me pour en g&eacute;n&eacute;rer une autre. Bien entendu, tous les utilisateurs peuvent changer leur cl&eacute; &agrave; tout moment, tant qu&#39;ils ont acc&egrave;s au syst&egrave;me.</li>
</ul>

<p>Voici comment cela est indiqu&eacute; dans la Liste des utilisateurs qui ont activ&eacute; une cl&eacute;:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_Liste-des-utilisateurs.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_Liste-des-utilisateurs.png" /></a></p>

<p>Bien que si un utilisateur acc&egrave;de &agrave; la fiche d&#39;un autre utilisateur (m&ecirc;me s&#39;il est administrateur), il verra la cl&eacute; semi-masqu&eacute;e:</p>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_utilisateur-third.png" /></p>

<p id="desactiver-cle-totp-utilisateur">&nbsp;</p>

<h3>D&eacute;sactivation de la cl&eacute; TOTP de votre utilisateur</h3>

<p>En revanche, lorsqu&#39;on visite sa propre fiche utilisateur, on peut parfaitement voir sa cl&eacute; et m&ecirc;me scanner le code avec d&#39;autres applications:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_utilisateur-own.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_utilisateur-own.png" /></a></p>

<p>Pour d&eacute;sactiver la cl&eacute; TOTP active, il faut Modifier ma fiche utilisateur:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_utilisateur-desactivater.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_utilisateur-desactivater.png" /></a></p>

<p><strong><u>Note</u>:</strong> en fait, si un administrateur acc&egrave;de &agrave; Modifier la fiche d&#39;un autre utilisateur, il verra &eacute;galement le m&ecirc;me bouton D&Eacute;SACTIVER.<br />
&nbsp;</p>

<p id="filtrer-visiteurs-par-pays-origine">&nbsp;</p>

<h3>Filtrer les visiteurs selon leur pays d&#39;origine</h3>

<p>Cette am&eacute;lioration a &eacute;t&eacute; introduite avec la version 1.4 et vise &agrave; limiter l&#39;acc&egrave;s &agrave; votre Dolibarr depuis n&#39;importe quelle IP qui n&#39;est pas dans le pays que vous d&eacute;finissez. Pour cela, dans la section de configuration, vous pouvez d&eacute;finir une LISTE BLANCHE DE PAYS.</p>

<p>La premi&egrave;re chose que vous devez faire (si vous avez une version de PHP 8 ou sup&eacute;rieure) est de t&eacute;l&eacute;charger la base de donn&eacute;es &quot;GeoLite2&quot; de MaxMind, qui est gratuite. Vous devez vous inscrire et la t&eacute;l&eacute;charger.</p>

<p class="a_c"><a class="a_icon" href="https://dev.maxmind.com/geoip/geolite2-free-geolocation-data" target="_blank">https://dev.maxmind.com/geoip/geolite2-free-geolocation-data</a></p>

<p>Le module l&#39;installera dans Dolibarr et activera le module natif de g&eacute;olocalisation, dont nous avons besoin pour consulter cette base de donn&eacute;es et pouvoir filtrer les adresses IP par pays d&#39;origine.</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_config-IP-database.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_config-IP-database.png" /></a></p>

<p>&Eacute;videmment, au visiteur d&eacute;tect&eacute; venant d&#39;un autre pays, il ne sera pas mentionn&eacute; le pays depuis lequel il doit acc&eacute;der. L&#39;id&eacute;e est de rendre la t&acirc;che difficile aux intrus ind&eacute;sirables et aux bots. Autrement dit, cette mesure seule constitue d&eacute;j&agrave; une barri&egrave;re int&eacute;ressante pour une large majorit&eacute; de bots qui explorent aveugl&eacute;ment o&ugrave; s&#39;introduire. &Eacute;videmment, si quelqu&#39;un vous lance une attaque, il saura comment d&eacute;couvrir votre pays et utilisera un VPN pour essayer d&#39;entrer.</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_config-IP-country-filter.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_config-IP-country-filter.png" /></a></p>

<p>Si vous laissez cette liste de pays vide, alors le module ne tiendra simplement pas compte de l&#39;IP de ceux qui tentent d&#39;acc&eacute;der.</p>

<p><strong><u>Note technique</u>:</strong> il est n&eacute;cessaire d&#39;avoir install&eacute; et activ&eacute; sur votre serveur le module PHP mod_geoip (par exemple le paquet php7.4-geoip dans le cas de PHP 7.4). Si vous ne l&#39;avez pas install&eacute;, alors le module vous l&#39;indiquera dans cet onglet ci-dessus &quot;Configuration IP&quot;.</p>

<p id="listes-blanches-ip-de-confiance-pare-feu">&nbsp;</p>

<h3>Listes blanches d&#39;IP de confiance (PARE-FEU)</h3>

<p>Depuis la version 22.1, vous pouvez l&#39;utiliser comme PARE-FEU : vous pouvez d&eacute;finir quelques listes d&#39;IP et de plages d&#39;IP de confiance pour lesquelles vous pouvez soit les exempter de saisir le second facteur lors de la connexion, soit interdire la connexion &agrave; tout visiteur qui ne provient PAS de ces IP.</p>

<p>Comment &ccedil;a marche ? Dans la section de configuration du module, dans l&#39;onglet &quot;Filtrage par IP&quot;, vous disposez de deux zones de texte brut pour d&eacute;finir une liste d&#39;IP ou de plages d&#39;IP s&eacute;par&eacute;es par des virgules.</p>

<p class="a_c"><img src="https://imasdeweb.com/UserFiles/Image/2026/totp2fa-ip-white-listing_fr.png" /></p>

<p id="quelle-ip-dois-je-utiliser">&nbsp;</p>

<h4>Quelle IP Dois-je Utiliser ?</h4>

<p>Le module affiche <u>votre adresse IP actuelle en haut des param&egrave;tres</u>. C&#39;est <strong>l&#39;adresse IP que votre serveur d&eacute;tecte</strong> lorsque vous vous connectez &agrave; Dolibarr&mdash;et c&#39;est exactement ce que vous devez saisir dans la liste blanche.</p>

<p>Important : Votre &quot;IP actuelle&quot; peut diff&eacute;rer selon votre configuration r&eacute;seau :</p>

<ul>
	<li><u>Acc&egrave;s public/Internet</u> : Vous verrez votre IP publique (ex., 217.71.206.235)</li>
	<li><u>R&eacute;seau local</u> (LAN) : Vous verrez une IP priv&eacute;e (ex., 10.0.8.28, 192.168.1.x)</li>
	<li><u>VPN/SDN</u> (ZeroTier, Tailscale, etc.) : Vous verrez l&#39;IP de r&eacute;seau virtuel assign&eacute;e par votre VPN</li>
</ul>

<p>Toujours <strong>v&eacute;rifier l&#39;IP affich&eacute;e dans l&#39;interface du module</strong> avant de configurer votre liste blanche <strong>pour &eacute;viter de vous bloquer</strong>.</p>

<p id="utiliser-plages-ip-pour-flexibilite">&nbsp;</p>

<h4>Utilisation de Plages d&#39;IP pour Plus de Flexibilit&eacute;</h4>

<p>Au lieu d&#39;ajouter des IP individuelles, vous pouvez d&eacute;finir des plages d&#39;IP pour couvrir plusieurs appareils ou des IP dynamiques (utile avec DHCP). Le module supporte trois formats :</p>

<ul>
	<li><u>IP unique</u> : 203.0.113.10<br />
	<em>Seulement cette IP exacte<br />
	&nbsp;</em></li>
	<li><u>Notation CIDR</u> : 10.0.8.0/24<br />
	<em>Toutes les IP de 10.0.8.0 &agrave; 10.0.8.255 (256 adresses)<br />
	&nbsp;</em></li>
	<li><u>Plage de&ndash;&agrave;</u> : 203.0.113.10-203.0.113.50<br />
	<em>Toutes les IP entre ces deux adresses (41 IP)<br />
	&nbsp;</em></li>
	<li><u>Combinaison</u> : 200.1.2.3, 200.1.2.4, 203.0.113.0/24<br />
	<em>Plusieurs IP/plages s&eacute;par&eacute;es par des virgules</em></li>
</ul>

<p id="guide-rapide-CIDR">&nbsp;</p>

<div class="block">
<h4>Guide rapide CIDR</h4>

<ul>
	<li>/24 = correspond aux 3 premiers octets<br />
	&rarr; 10.0.8.XXX (courant pour les LAN domestiques/bureau)<br />
	&nbsp;</li>
	<li>/16 = correspond aux 2 premiers octets<br />
	&rarr; 10.0.XXX.XXX (r&eacute;seaux plus grands)<br />
	&nbsp;</li>
	<li>/8 = correspond au premier octet<br />
	&rarr; 10.XXX.XXX.XXX (tr&egrave;s large, utiliser avec pr&eacute;caution)</li>
</ul>

<p><strong>Exemples Pratiques</strong></p>

<p><u>Sc&eacute;nario 1 : LAN domestique/bureau avec DHCP</u><br />
Votre routeur assigne des IP comme 192.168.1.10, 192.168.1.25, etc.<br />
&rarr; <em>Utilisez 192.168.1.0/24 pour faire confiance &agrave; tous les appareils de votre r&eacute;seau local.</em></p>

<p><u>Sc&eacute;nario 2 : Plusieurs emplacements</u><br />
LAN bureau (10.0.8.0/24) + IP domicile (203.45.67.89) + Sous-r&eacute;seau VPN (100.64.0.0/24)<br />
&rarr; <em>Saisissez : 10.0.8.0/24, 203.45.67.89, 100.64.0.0/24</em></p>

<p><u>Sc&eacute;nario 3 : Appareils sp&eacute;cifiques uniquement</u><br />
Faire confiance seulement &agrave; votre portable (192.168.1.100) et serveur (192.168.1.10)<br />
&rarr; <em>Saisissez : 192.168.1.100, 192.168.1.10</em></p>
</div>

<p id="deux-listes-blanches-separees">&nbsp;</p>

<h4>Deux Listes Blanches S&eacute;par&eacute;es</h4>

<p>Le module fournit deux listes d&#39;IP ind&eacute;pendantes :</p>

<ol>
	<li><u>Restreindre l&#39;acc&egrave;s &agrave; Dolibarr</u> : Bloque les tentatives de connexion depuis des IP non list&eacute;es (mode pare-feu)</li>
	<li><u>Ne pas demander 2FA</u> : Ignore l&#39;authentification &agrave; deux facteurs pour les IP de confiance (mode commodit&eacute;)</li>
</ol>

<p><strong>Si vous laissez les deux listes vides, le module ne filtrera aucune IP&mdash;tout le monde peut acc&eacute;der normalement.</strong></p>

<div class="block">
<p><strong>Notes Importantes</strong></p>

<ul>
	<li>Le module d&eacute;tecte les IP depuis la connexion directe &agrave; votre serveur. Si vous &ecirc;tes derri&egrave;re un proxy inverse ou un &eacute;quilibreur de charge, consultez votre administrateur syst&egrave;me.</li>
	<li>Les adresses IPv6 ne sont pas actuellement support&eacute;es&mdash;seulement IPv4.</li>
	<li>Testez toujours votre configuration de liste blanche depuis une connexion secondaire avant de vous d&eacute;connecter, pour &eacute;viter les blocages accidentels.</li>
</ul>
</div>

<p id="memoriser-appareil-comme-sur">&nbsp;</p>

<h3>Se souvenir d&#39;un appareil comme s&ucirc;r</h3>

<p>Depuis la version 1.5, le module vous permet de d&eacute;finir une p&eacute;riode de temps (1 jour/semaine/mois) pendant laquelle il se souviendra de votre navigateur web et ne vous demandera pas &agrave; nouveau le code TOTP &agrave; 6 chiffres. Vous pouvez &eacute;galement d&eacute;finir que le code TOTP soit TOUJOURS demand&eacute;. En fait, c&#39;est l&#39;option par d&eacute;faut.</p>

<p>Bien que ce soit une nouvelle caract&eacute;ristique qui am&eacute;liore grandement l&#39;usabilit&eacute; des codes TOTP, surtout lorsque vous g&eacute;rez plusieurs instances de Dolibarr tout au long de la semaine, vous devez vous rappeler que PLUS DE CONFORT signifie toujours MOINS DE S&Eacute;CURIT&Eacute;... malheureusement, ils sont toujours inversement proportionnels. Donc, je vous recommande d&#39;&eacute;valuer l&#39;environnement de s&eacute;curit&eacute; depuis lequel vos utilisateurs acc&egrave;dent avant de d&eacute;cider d&#39;assouplir l&#39;utilisation des TOTP.</p>

<p>De plus, comme ce syst&egrave;me fonctionne GR&Acirc;CE AUX COOKIES, il cessera de fonctionner si vous visitez votre Dolibarr depuis <u>un onglet en mode incognito</u> ou si vous <u>supprimez les cookies</u> dans votre navigateur apr&egrave;s votre visite. Ce que je vous recommande si vous n&#39;&ecirc;tes pas sur votre propre machine, par exemple. Le module peut se souvenir d&#39;autant d&#39;appareils que l&#39;utilisateur souhaite utiliser. Ainsi, en acc&eacute;dant temporairement depuis un onglet incognito sur un nouvel appareil, le module n&#39;oubliera aucun de vos autres appareils d&eacute;j&agrave; utilis&eacute;s.</p>

<p>Bien s&ucirc;r, toujours limit&eacute; au temps d&#39;expiration que vous d&eacute;finissez dans la configuration du module:</p>

<p class="a_c"><a href="UserFiles/Image/2023/FR-TOTP_config-TOTP-memory.png"><img src="https://imasdeweb.com/UserFiles/Image/2023/FR-TOTP_config-TOTP-memory.png" /></a></p>

<p id="comment-acceder-a-dolibarr">&nbsp;</p>

<h3><strong>Alors, comment dois-je acc&eacute;der &agrave; Dolibarr maintenant?</strong></h3>

<p>Si vous avez d&eacute;fini une p&eacute;riode pour se souvenir des appareils, alors ma recommandation est de vous connecter de la mani&egrave;re suivante:</p>

<div class="block">
<ol>
	<li>saisissez votre <u>nom d&#39;utilisateur et votre mot de passe</u> dans le formulaire de connexion</li>
	<li>appuyez sur <u>ENTR&Eacute;E pour envoyer</u> le formulaire</li>
	<li>si les donn&eacute;es saisies sont correctes et que votre p&eacute;riode de m&eacute;morisation n&#39;est pas expir&eacute;e, alors vous &ecirc;tes d&eacute;j&agrave; connect&eacute;!<br />
	&nbsp;</li>
	<li><u>si votre p&eacute;riode de m&eacute;morisation a expir&eacute;</u>, le formulaire de connexion se rechargera, d&eacute;j&agrave; REMPLI avec les identifiants que vous avez entr&eacute;s et le curseur sera d&eacute;j&agrave; dans la case du code TOTP &agrave; 6 chiffres avec un message vous demandant de saisir le code pour pouvoir acc&eacute;der</li>
	<li>entrez le <u>code &agrave; 6 chiffres</u> et vous pouvez appuyer de nouveau <u>sur ENTR&Eacute;E</u> pour envoyer le formulaire</li>
	<li>si toutes les donn&eacute;es sont correctes, vous serez connect&eacute; et le syst&egrave;me affichera le tableau de bord de d&eacute;marrage et un message vous informant que votre navigateur sera m&eacute;moris&eacute; pour X temps</li>
</ol>
</div>

<p><strong><u>En r&eacute;sum&eacute;</u>:</strong> vous devez seulement entrer l&#39;utilisateur et le mot de passe et appuyer sur ENTR&Eacute;E. Et de temps en temps (lorsque la p&eacute;riode de m&eacute;morisation expire), le code TOTP &agrave; 6 chiffres vous sera demand&eacute;. Pratique, n&#39;est-ce pas?</p>

<p id="foire-aux-questions">&nbsp;</p>

<h3><u>Question fr&eacute;quente</u></h3>

<p id="si-je-suis-bloque">&nbsp;</p>

<h4>Que faire si vous vous retrouvez bloqu&eacute;</h4>

<p>Si vous vous &ecirc;tes retrouv&eacute; &quot;bloqu&eacute; hors de votre Dolibarr&quot; pour l&#39;une de ces raisons :</p>

<ul>
	<li>apr&egrave;s avoir configur&eacute; ces options d&#39;IP ou de pays de mani&egrave;re trop stricte</li>
	<li>ou peut-&ecirc;tre apr&egrave;s avoir perdu l&#39;application g&eacute;n&eacute;ratrice de jetons &agrave; 6 chiffres</li>
</ul>

<p>Alors la solution est &quot;facile&quot; :</p>

<ol>
	<li>connectez-vous &agrave; votre serveur via FTP/SSH et sortez le r&eacute;pertoire du module (normalement dans /htdocs/custom/totp2fa) hors de /htdocs</li>
	<li>acc&eacute;dez &agrave; nouveau &agrave; votre Dolibarr avec votre compte utilisateur, et vous verrez qu&#39;il ne vous demande pas le second facteur</li>
	<li>replacez le r&eacute;pertoire du module &agrave; sa place</li>
	<li>et si vous ne vous &ecirc;tes pas d&eacute;connect&eacute; de Dolibarr, vous pouvez aller dans la configuration du module et corriger ce qui bloquait votre acc&egrave;s</li>
</ol>

<p><strong><u>Remarque</u> :</strong> n&#39;ayez pas peur de &quot;perdre des informations&quot; en effectuant ces d&eacute;placements du r&eacute;pertoire du module, car vous n&#39;affectez pas la base de donn&eacute;es, donc vous ne perdrez pas les configurations de tous vos utilisateurs.</p>

<p id="acces-a-demo">&nbsp;</p>

<h3>Acc&egrave;s &agrave; la D&Eacute;MO</h3>

<div><div class="block">
<p style="text-align:center;"><b><i class="fa fa-hand-point-right">&nbsp;</i></b> <a href="#" onclick="$(this).parent().next().slideDown();return false;">Je suis intéressé à accéder à la DEMO</a></p>

<div style="display:none;"><form method='post' id='contactos_form_17_5427' action='index.php?pag=m_contactos&gad=formulario&id=17'
      class='generic_form block relative' enctype='multipart/form-data' style='padding:1.5em 0.5em;position:relative;'>
    <input type='hidden' name='form_id' value='17' />
    <input type='hidden' name='module' value='contactos' />
    <input type='hidden' name='module_ref' value='' />
    <input type='hidden' name='module_eref' value='' />
    <input type='hidden' name='answer_id'  value="" />
    <input type='hidden' name='answer_eid' value="" />

    <!-- FLOATING SHARE BUTTON --> 
    
    <!-- ERROR MESSAGE -->
    
    <!-- FIELDS DEFINED FOR THIS FORM -->
    

			<h3 class='clear form_field_1 ' style=''>Je suis intéressé à tester la démo de Dolibarr</h3>


			<div class="control form_field_2" data-type="checkbox">
								<label class='required'>Quel module vous intéresse le plus? *</label>
								<div>
					                    <div type='div--checkbox' class='barllo-control-group required'>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								TOTP 2FA Login et Filtre de pays								<input type="checkbox" name='fields[2][]'  id='fields_2_0'
									value="TOTP 2FA Login et Filtre de pays"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								AI writer								<input type="checkbox" name='fields[2][]'  id='fields_2_1'
									value="AI writer"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Assistants IA								<input type="checkbox" name='fields[2][]'  id='fields_2_2'
									value="Assistants IA"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Ticket Plus et HelpDesk								<input type="checkbox" name='fields[2][]'  id='fields_2_3'
									value="Ticket Plus et HelpDesk"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Listes modifiables								<input type="checkbox" name='fields[2][]'  id='fields_2_4'
									value="Listes modifiables"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Note Plus								<input type="checkbox" name='fields[2][]'  id='fields_2_5'
									value="Note Plus"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Achats								<input type="checkbox" name='fields[2][]'  id='fields_2_6'
									value="Achats"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Transferts de Stock								<input type="checkbox" name='fields[2][]'  id='fields_2_7'
									value="Transferts de Stock"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Graphiques de facturation annuelle								<input type="checkbox" name='fields[2][]'  id='fields_2_8'
									value="Graphiques de facturation annuelle"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Recherchez aide dans les forums								<input type="checkbox" name='fields[2][]'  id='fields_2_9'
									value="Recherchez aide dans les forums"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								CFDI Mexicaine								<input type="checkbox" name='fields[2][]'  id='fields_2_10'
									value="CFDI Mexicaine"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
							<label class='barllo-control barllo-control--checkbox '
									style=''>
								Tous								<input type="checkbox" name='fields[2][]'  id='fields_2_11'
									value="Tous"
																									   />
								<div class="barllo-control__indicator"></div>
							</label>
                    </div>

				</div>
			</div>



			<div class="control form_field_3" data-type="text">
								<label class='required'>votre langue préférée? *</label>
								<div>
					                    <input type='text' name='fields[3]' id='fields_3'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_4" data-type="email">
								<label class='required'>Votre adresse e-mail *</label>
								<div>
					<input type='text' name='fields[4]' id='fields_4' value=""
                         class='MustBeEmail w100p required' style=''                        data-wellformed='0' />
				</div>
			</div>



			<div class="control form_field_5" data-type="text">
								<label class='required'>Votre nom *</label>
								<div>
					                    <input type='text' name='fields[5]' id='fields_5'   class='w100p required' style=''                                         value="" />
				</div>
			</div>



			<div class="control form_field_6" data-type="textarea">
								<label class=''>Commentaire (facultatif) </label>
								<div>
					                    <textarea name='fields[6]' id='fields_6'  class='w100p' style=''></textarea>
				</div>
			</div>


    <!-- HANDWRITTEN SIGNATURE -->
    
    <!-- PRIVACY TERMS -->
    
    	<!-- CAPTCHA -->
    <div class='row_captcha a_c' style='margin-bottom:1rem;margin:2em auto!important;'>
        <span id='captcha_question_62379' class='captcha_question n_w' style='display:inline-block;padding-top:0.5em;'></span><script>$(document).ready(function(){ $('#captcha_question_62379').html('<br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' />0<br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /> + <br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' />7<br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /><br style=\'display:none;\' rel=\'4332\' /> = ');});</script>        <span class="captcha_answer">
    <input type='text' value='' id='captcha_answer_68295' name='captcha_answer' rel='' style='width:4em;display:inline-block;' />
    <span class='n_w'>(pregunta anti-robots)</span>
    <input type='hidden' id='captcha_formstamp_68295' name='captcha_formstamp' value='T0ZaUVptbEljRTgxU1dWYVdGSmljbEpDT0N0MVZFWmtVeTlXWmtsV1ZHbEtWMVlyYzFOa2VGaFphejA2T2psa1pESm1ZVGxpTlRjMVlqUTJPR00xWkRRM01qWXhZakpoTnprNU9XVXg' />
    <input type='hidden' id='captcha_valid_68295' value='0' />
</span>
<style>
    .valid_captcha{background-color:rgba(80,200,80,0.2)!important;border-color:rgba(80,200,80,0.7)!important;}
    .not_valid_captcha{background-color:rgba(200,80,80,0.2)!important;border-color:rgba(200,80,80,0.7)!important;}
</style>
<script>
    $(document).ready(function(){

        /* === this for the checking the VALID state of the captcha before submit the PARENT form === */

        $('#captcha_answer_68295').closest('form').on('submit',function(event){

            var valid_captcha = js_check_captcha_68295();
            if (!valid_captcha){
                event.preventDefault();
                event.stopPropagation();
            }

        });

        /* === this validate the answer each time there are a change in the value of the answer === */

        $('#captcha_answer_68295').on('change input',function(){
            /* = reset and exit if the value is blank = */
                if ($(this).val()==''){
                    $('#captcha_valid_68295').val('');
                    $('#captcha_answer_68295').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    return;
                }

            /* = check if there are changes = */
                var rel = $(this).attr('rel');
                if (rel==$(this).val()) return;

            /* = use remote JSON call to server for validate answer = */
                $(this).attr('rel',$(this).val());
                var url_json = 'index.php?module=contactos&json=check_captcha&captcha_formstamp='+($('#captcha_formstamp_68295').val())+'&captcha_answer='+($('#captcha_answer_68295').val());
                $.getJSON(url_json,function(data){
                    $('#captcha_valid_68295').val(data.valid);
                    $('#captcha_answer_68295').removeClass('valid_captcha').removeClass('not_valid_captcha');
                    if (data.valid=='1')
                        $('#captcha_answer_68295').addClass('valid_captcha');
                    else
                        $('#captcha_answer_68295').addClass('not_valid_captcha');
                });
        });

    });

    /* === function to check if captcha has been validated (useful for AJAX web forms to be called)  === */

    function js_check_captcha_68295(){
        if($('#captcha_answer_68295').val() == ''
                || $('#captcha_valid_68295').val()!='1'){

            $('#captcha_answer_68295').addClass('alerted_field');
            var msg = "La pregunta anti-robots no fue respondida correctamente o bien se excedió el tiempo máximo para responder el formulario.<br /><br />Si está seguro de que la suma es correcta, deberá recargar el formulario y llenarlo de nuevo.";

            if (typeof js_modal == 'function'){
                js_modal({type:'error',html:msg});
            }else{
                alert(msg);
            }

            var scroll_to = parseInt($('#captcha_answer_68295').offset().top, 10) - 100;
            $('html, body').animate({scrollTop: scroll_to}, 2000);

            return false;
        }else{
            return true;
        }
    }


</script>
    </div>

    <!-- SUBMIT button -->
    <p class="a_c">
        <a class='bt' href='#' onclick='js_validate_contactos_form_17_5427();return false;'>
            <i class='fa fa-send opa07'></i>&nbsp; Enviar</a>
    </p>

    <!-- EDIT button (only for logged admin users) -->
    
</form>

<script>

    function js_validate_contactos_form_17_5427(){

        /* ===== verify fields of registration form ===== */
            var fields_are_ok = js_form_validation('contactos_form_17_5427');
            if (!fields_are_ok) return false;

        /* ===== check digital signature (if it is required) ===== */
            if ($('#signature_type').length > 0){
                var fine_signature = js_check_signature();
                if (fine_signature!='1'){
                    alert("Es necesario que aporte su firma manuscrita para poder continuar.");
                    $('#signature_type').addClass('alerted_field');
                    js_scroll_to('signature_type');
                    processing_submit = false;
                    return false;
                }
            }

        /* ===== submit ===== */
            var module = 'contactos';
            var module_ref = '';
            if (module=='contactos' || module_ref!=''){
                $('#contactos_form_17_5427').submit();
            }else{
                js_modal({type:'warning',html:"Ha cargado este formulario en modo de prueba. No se puede enviar datos."});
                console.log('This is a form that must be created from module "'+module+'". So it will not be sent to server.');
            }
    }

    $(document).ready(function(){
        $('form *').on('focus click','.alerted_field',function(){
            if ($(this).attr('type')=='radio'){
                var this_name = $(this).attr('name');
                $(this).parent().find('input[name="'+this_name+'"]').removeClass('alerted_field');
            }else if ($(this).attr('type')=='checkbox'){
                var this_rel = $(this).attr('rel');
                $(this).parent().find('input[rel='+this_rel+']').removeClass('alerted_field');
            }else{
                $(this).removeClass('alerted_field');
            }
        });
    });

</script>
</div>
</div>
</div>
]]></content:encoded>
        </item>
        
</channel></rss>