* Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2015-2017 Marcos García * Copyright (C) 2015-2017 Nicolas ZABOURI * Copyright (C) 2018-2024 Frédéric France * Copyright (C) 2022 Charlene Benke * Copyright (C) 2023 Anthony Berton * Copyright (C) 2024 MDW * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** * \file htdocs/core/class/html.formai.class.php * \ingroup core * \brief Fichier de la class permettant la generation du formulaire html d'envoi de mail unitaire */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; /** * Class permettant la generation du formulaire html d'envoi de mail unitaire * Usage: $formail = new FormAI($db) * $formai->proprietes=1 ou chaine ou tableau de valeurs * $formai->show_form() affiche le formulaire */ class FormAI extends Form { /** * @var DoliDB Database handler. */ public $db; /** * @var string Use case string to a button "Fill with layout" for this use case. Example 'wesitepage', 'emailing', 'email', ... */ public $withlayout; /** * @var string 'text' or 'html' to add a button "Fill with AI generation" */ public $withaiprompt; /** * @var array */ public $substit = array(); /** * @var array> */ public $substit_lines = array(); /** * @var array{}|array{models:string,langsmodels?:string,fileinit?:string[],returnurl:string} */ public $param = array(); /** * @var int<-1,1> -1 suggests the checkbox 'one email per recipient' not checked, 0 = no suggestion, 1 = suggest and checked */ public $withoptiononeemailperrecipient; /** * @var bool */ public $aicallfunctioncalled = false; /** * Constructor * * @param DoliDB $db Database handler */ public function __construct($db) { $this->db = $db; } /** * Return Html code for AI instructions of message and autofill result. * * @param string $function Function/variant for text generation ('textgenerationemail', 'textgenerationwebpage', ...) * @param string $format Format for output ('', 'html', ...) * @param string $htmlContent HTML name of WYSIWYG field * @param string $onlyenhancements Show only this enhancement features (show all if '') * @param string $aiprompt Ai prompt for textgenerationextrafield function * @return string HTML code to ask AI instructions and autofill result */ public function getSectionForAIEnhancement($function = 'textgeneration', $format = '', $htmlContent = 'message', $onlyenhancements = '', $aiprompt = "") { global $langs, $form; require_once DOL_DOCUMENT_ROOT."/ai/lib/ai.lib.php"; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $formadmin = new FormAdmin($this->db); if (!is_object($form)) { $form = new Form($this->db); } $langs->load("other"); $messageaiwait = ''.$langs->trans("AIProcessingPleaseWait", getDolGlobalString('AI_API_SERVICE', 'chatgpt')); $htmlContent = preg_replace('/[^a-z0-9_]/', '', $htmlContent); $out = ''; if (empty($onlyenhancements) || in_array($onlyenhancements, array('textgenerationemail', 'textgenerationwebpage'))) { $out .= '
'; //$out .= ''.$langs->trans("FillMessageWithAIContent").''; $out .= ''; $out .= ''; $out .= '
'; } if (empty($onlyenhancements) || in_array($onlyenhancements, array('texttranslation'))) { $out .= ($out ? '
' : ''); $out .= '
'; $out .= img_picto('', 'language', 'class="pictofixedwidth paddingrightonly"'); $out .= $formadmin->select_language("", "ai_translation".$htmlContent."_select", 0, array(), $langs->trans("TranslateByAI").'...', 0, 0, 'minwidth250 ai_translation'.$htmlContent.'_select'); $out .= '
'; } if (empty($onlyenhancements) || in_array($onlyenhancements, array('textsummarize'))) { $summarizearray = getListForAISummarize(); $out .= ($out ? '
' : ''); $out .= '
'; $out .= img_picto('', 'edit', 'class="pictofixedwidth paddingrightonly"'); $out .= $form->selectarray("ai_summarize".$htmlContent."_select", $summarizearray, 0, $langs->trans("SummarizeByAI").'...', 0, 0, 'minwidth250 ai_summarize'.$htmlContent.'_select', 1); $out .= '
'; } if (empty($onlyenhancements) || in_array($onlyenhancements, array('textrephrase'))) { $stylearray = getListForAIRephraseStyle(); $out .= ($out ? '
' : ''); $out .= '
'; $out .= img_picto('', 'edit', 'class="pictofixedwidth paddingrightonly"'); $out .= $form->selectarray("ai_rephraser".$htmlContent."_select", $stylearray, 0, $langs->trans("RephraserByAI").'...', 0, 0, 'minwidth250 ai_rephraser'.$htmlContent.'_select', 1); $out .= '
'; } if (in_array($onlyenhancements, array('textgenerationextrafield'))) { $out .= '
'; $out .= ''; $out .= '
'; } $out = ''.$out; $out = '\n"; $out .= " "; return $out; } /** * Return javascript code for call to AI function callAIGenerator() * * @return string HTML code to ask AI instructions and autofill result */ public function getAjaxAICallFunction() { $out = ""; if ($this->aicallfunctioncalled) { return $out; } $out .= " "; $this->aicallfunctioncalled = true; return $out; } /** * Set ->substit (and ->substit_line) array from object. This is call when suggesting the email template into forms before sending email. * * @param CommonObject $object Object to use * @param Translate $outputlangs Object lang * @return void * @see getCommonSubstitutionArray() */ public function setSubstitFromObject($object, $outputlangs) { global $extrafields; $parameters = array(); $tmparray = getCommonSubstitutionArray($outputlangs, 0, null, $object); complete_substitutions_array($tmparray, $outputlangs, null, $parameters); $this->substit = $tmparray; // Fill substit_lines with each object lines content if (is_array($object->lines)) { foreach ($object->lines as $line) { $substit_line = array( '__PRODUCT_REF__' => isset($line->product_ref) ? $line->product_ref : '', '__PRODUCT_LABEL__' => isset($line->product_label) ? $line->product_label : '', '__PRODUCT_DESCRIPTION__' => isset($line->product_desc) ? $line->product_desc : '', '__LABEL__' => isset($line->label) ? $line->label : '', '__DESCRIPTION__' => isset($line->desc) ? $line->desc : '', '__DATE_START_YMD__' => dol_print_date($line->date_start, 'day', false, $outputlangs), '__DATE_END_YMD__' => dol_print_date($line->date_end, 'day', false, $outputlangs), '__QUANTITY__' => $line->qty, '__SUBPRICE__' => price($line->subprice), '__AMOUNT__' => price($line->total_ttc), '__AMOUNT_EXCL_TAX__' => price($line->total_ht) ); // Create dynamic tags for __PRODUCT_EXTRAFIELD_FIELD__ if (!empty($line->fk_product)) { if (!is_object($extrafields)) { $extrafields = new ExtraFields($this->db); } $product = new Product($this->db); $product->fetch($line->fk_product); $product->fetch_optionals(); $extrafields->fetch_name_optionals_label($product->table_element, true); if (!empty($extrafields->attributes[$product->table_element]['label']) && is_array($extrafields->attributes[$product->table_element]['label']) && count($extrafields->attributes[$product->table_element]['label']) > 0) { foreach ($extrafields->attributes[$product->table_element]['label'] as $key => $label) { $substit_line['__PRODUCT_EXTRAFIELD_'.strtoupper($key).'__'] = isset($product->array_options['options_'.$key]) ? $product->array_options['options_'.$key] : ''; } } } $this->substit_lines[$line->id] = $substit_line; // @phan-suppress-current-line PhanTypeMismatchProperty } } } }