2025-02-18 14:34:35 +00:00
< ? php
/* Copyright ( C ) 2005 - 2012 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2005 - 2012 Regis Houssin < regis . houssin @ inodbox . com >
* Copyright ( C ) 2010 - 2011 Juanjo Menent < jmenent @ 2 byte . es >
* Copyright ( C ) 2015 - 2017 Marcos García < marcosgdf @ gmail . com >
* Copyright ( C ) 2015 - 2017 Nicolas ZABOURI < info @ inovea - conseil . com >
* Copyright ( C ) 2018 - 2024 Frédéric France < frederic . france @ free . fr >
* Copyright ( C ) 2022 Charlene Benke < charlene @ patas - monkey . com >
* Copyright ( C ) 2023 Anthony Berton < anthony . berton @ bb2a . fr >
2026-02-01 17:05:15 +00:00
* Copyright ( C ) 2024 - 2026 MDW < mdeweerd @ users . noreply . github . com >
2025-02-18 14:34:35 +00:00
*
*
* 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 < https :// www . gnu . org / licenses />.
*/
/**
* \file htdocs / core / class / html . formai . class . php
* \ingroup core
2026-02-01 17:05:15 +00:00
* \brief File for class FormAI class to generate HTML forms for single email
2025-02-18 14:34:35 +00:00
*/
require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php' ;
/**
2026-02-01 17:05:15 +00:00
* Class to generate HTML forms for single email
* Usage : $formai = new FormAI ( $db )
* $formai -> proprietes = 1 or string or table of values
* $formai -> show_form () shows the form
2025-02-18 14:34:35 +00:00
*/
2025-02-18 15:03:21 +00:00
class FormAI extends Form
2025-02-18 14:34:35 +00:00
{
/**
* @ 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 < string , string >
*/
public $substit = array ();
/**
* @ var array < int , array < string , string >>
*/
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 ;
2025-02-21 11:36:16 +00:00
/**
* @ var bool
*/
public $aicallfunctioncalled = false ;
2025-02-18 14:34:35 +00:00
/**
* Constructor
*
* @ param DoliDB $db Database handler
*/
public function __construct ( $db )
{
$this -> db = $db ;
}
/**
2025-04-08 21:18:23 +00:00
* Return Html code for AI instructions of message and autofill result .
2025-02-18 14:34:35 +00:00
*
2025-04-08 21:18:23 +00:00
* @ param string $function Function / variant for text generation ( 'textgenerationemail' , 'textgenerationwebpage' , ... )
2025-04-08 09:42:46 +00:00
* @ 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 '' )
2025-05-04 08:50:01 +00:00
* @ param string $aiprompt Ai prompt for textgenerationextrafield function
2025-04-08 09:42:46 +00:00
* @ return string HTML code to ask AI instructions and autofill result
2025-02-18 14:34:35 +00:00
*/
2025-05-04 08:50:01 +00:00
public function getSectionForAIEnhancement ( $function = 'textgeneration' , $format = '' , $htmlContent = 'message' , $onlyenhancements = '' , $aiprompt = " " )
2025-02-18 14:34:35 +00:00
{
2025-04-03 15:34:09 +00:00
global $langs , $form ;
require_once DOL_DOCUMENT_ROOT . " /ai/lib/ai.lib.php " ;
2025-03-20 18:32:01 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php' ;
$formadmin = new FormAdmin ( $this -> db );
2025-02-18 14:34:35 +00:00
2025-04-03 15:34:09 +00:00
if ( ! is_object ( $form )) {
$form = new Form ( $this -> db );
}
2025-02-18 14:34:35 +00:00
$langs -> load ( " other " );
2025-04-07 19:44:26 +00:00
$messageaiwait = '<i class="fa fa-spinner fa-spin fa-2x fa-fw valignmiddle marginrightonly"></i>' . $langs -> trans ( " AIProcessingPleaseWait " , getDolGlobalString ( 'AI_API_SERVICE' , 'chatgpt' ));
2025-02-18 14:34:35 +00:00
$htmlContent = preg_replace ( '/[^a-z0-9_]/' , '' , $htmlContent );
2025-04-08 09:42:46 +00:00
$out = '' ;
if ( empty ( $onlyenhancements ) || in_array ( $onlyenhancements , array ( 'textgenerationemail' , 'textgenerationwebpage' ))) {
$out .= '<div id="ai_textgeneration' . $htmlContent . '" class="ai_textgeneration' . $htmlContent . ' paddingtop paddingbottom ai_feature">' ;
//$out .= '<span>'.$langs->trans("FillMessageWithAIContent").'</span>';
$out .= '<textarea class="centpercent textarea-ai_feature" data-functionai="textgeneration" id="ai_instructions' . $htmlContent . '" name="instruction" placeholder="' . $langs -> trans ( " EnterYourAIPromptHere " ) . '..." /></textarea>' ;
2025-04-08 21:18:23 +00:00
$out .= '<input id="generate_button' . $htmlContent . '" type="button" class="button smallpaddingimp" disabled data-functionai="' . $function . '" value="' . $langs -> trans ( 'Generate' ) . '"/>' ;
2025-04-08 09:42:46 +00:00
$out .= '</div>' ;
}
2025-03-20 18:32:01 +00:00
2025-04-08 09:42:46 +00:00
if ( empty ( $onlyenhancements ) || in_array ( $onlyenhancements , array ( 'texttranslation' ))) {
2026-05-07 10:18:59 +00:00
$out .= ( $out ? '<div style="height: 10px;"></div>' : '' );
2025-04-08 09:42:46 +00:00
$out .= '<div id="ai_translation' . $htmlContent . '" class="ai_translation' . $htmlContent . ' paddingtop paddingbottom ai_feature">' ;
$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 .= '</div>' ;
}
2025-04-03 15:34:09 +00:00
2025-04-08 09:42:46 +00:00
if ( empty ( $onlyenhancements ) || in_array ( $onlyenhancements , array ( 'textsummarize' ))) {
$summarizearray = getListForAISummarize ();
2026-05-07 10:18:59 +00:00
$out .= ( $out ? '<div style="height: 10px;"></div>' : '' );
2025-04-08 09:42:46 +00:00
$out .= '<div id="ai_summarize' . $htmlContent . '" class="ai_summarize' . $htmlContent . ' paddingtop paddingbottom ai_feature">' ;
$out .= img_picto ( '' , 'edit' , 'class="pictofixedwidth paddingrightonly"' );
2026-04-24 12:15:34 +00:00
$out .= $form -> selectarray ( " ai_summarize " . $htmlContent . " _select " , $summarizearray , 0 , $langs -> trans ( " SummarizeByAI " ) . '...' , 0 , 0 , '' , 1 , 0 , 0 , '' , 'minwidth250 ai_summarize' . $htmlContent . '_select' );
2025-04-08 09:42:46 +00:00
$out .= '</div>' ;
}
2025-04-09 13:47:09 +00:00
if ( empty ( $onlyenhancements ) || in_array ( $onlyenhancements , array ( 'textrephrase' ))) {
$stylearray = getListForAIRephraseStyle ();
2026-05-07 10:18:59 +00:00
$out .= ( $out ? '<div style="height: 10px;"></div>' : '' );
2025-04-09 13:47:09 +00:00
$out .= '<div id="ai_rephraser' . $htmlContent . '" class="ai_rephraser' . $htmlContent . ' paddingtop paddingbottom ai_feature">' ;
$out .= img_picto ( '' , 'edit' , 'class="pictofixedwidth paddingrightonly"' );
2026-04-24 12:15:34 +00:00
$out .= $form -> selectarray ( " ai_rephraser " . $htmlContent . " _select " , $stylearray , 0 , $langs -> trans ( " RephraserByAI " ) . '...' , 0 , 0 , '' , 1 , 0 , 0 , '' , 'minwidth250 ai_rephraser' . $htmlContent . '_select' );
2025-04-09 13:47:09 +00:00
$out .= '</div>' ;
}
2025-04-25 23:59:36 +00:00
if ( in_array ( $onlyenhancements , array ( 'textgenerationextrafield' ))) {
$out .= '<div id="ai_textgenerationextrafield' . $htmlContent . '" class="ai_textgenerationextrafield' . $htmlContent . ' paddingtop paddingbottom ai_feature">' ;
2025-05-04 08:50:01 +00:00
$out .= '<input id="input_ai_textgenerationextrafield' . $htmlContent . '" type="hidden" class="button smallpaddingimp" data-functionai="textgenerationextrafield" value="' . $aiprompt . '"/>' ;
2025-04-25 23:59:36 +00:00
$out .= '</div>' ;
}
2025-04-08 09:42:46 +00:00
$out = '<!-- getSectionForAIEnhancement -->' . $out ;
$out = '<div id="ai_dropdown' . $htmlContent . '" class="dropdown-menu ai_dropdown ai_dropdown' . $htmlContent . ' paddingtop paddingbottom">' . $out ;
2025-03-20 18:32:01 +00:00
2025-02-18 14:34:35 +00:00
$out .= '<div id="ai_status_message' . $htmlContent . '" class="fieldrequired hideobject marginrightonly margintoponly">' ;
2025-04-07 19:44:26 +00:00
$out .= $messageaiwait ;
2025-02-18 14:34:35 +00:00
$out .= '</div>' ;
if ( $function == 'imagegeneration' ) {
$out .= '<div id="ai_image_result" class="margintoponly"></div>' ; // Div for displaying the generated image
}
$out .= " </div> \n " ;
$out .= " <script type='text/javascript'>
$ ( document ) . ready ( function () {
2025-03-20 18:32:01 +00:00
$ ( '#ai_translation".$htmlContent."_select' ) . data ( 'functionai' , 'texttranslation' )
2025-04-03 15:34:09 +00:00
$ ( '#ai_summarize".$htmlContent."_select' ) . data ( 'functionai' , 'textsummarize' )
2025-04-09 13:47:09 +00:00
$ ( '#ai_rephraser".$htmlContent."_select' ) . data ( 'functionai' , 'textrephraser' )
2025-03-20 18:32:01 +00:00
$ ( '#ai_instructions".$htmlContent."' ) . keyup ( function (){
2025-03-20 22:54:24 +00:00
console . log ( 'We type a key up on #ai_instructions".$htmlContent."' );
if ( $ ( this ) . val () != '' ) {
2025-03-20 18:32:01 +00:00
$ ( '#generate_button".$htmlContent."' ) . prop ( 'disabled' , false );
} else {
$ ( '#generate_button".$htmlContent."' ) . prop ( 'disabled' , true );
}
});
2025-02-18 14:34:35 +00:00
// for keydown
$ ( '#ai_instructions".$htmlContent."' ) . keydown ( function ( event ) {
2025-03-20 18:32:01 +00:00
if ( event . keyCode === 13 && $ ( this ) . val () != '' ) {
2025-03-20 22:54:24 +00:00
console . log ( 'We type enter on #ai_instructions".$htmlContent."' );
2025-02-18 14:34:35 +00:00
event . preventDefault ();
$ ( '#generate_button".$htmlContent."' ) . click ();
}
});
$ ( '#generate_button".$htmlContent."' ) . click ( function () {
2025-03-20 22:54:24 +00:00
console . log ( 'We click on #generate_button".$htmlContent."' );
2025-03-20 18:32:01 +00:00
prepareCallAIGenerator ( $ ( this ));
});
2025-02-18 14:34:35 +00:00
2025-03-20 18:32:01 +00:00
$ ( '#ai_translation".$htmlContent."_select' ) . on ( 'change' , function () {
2025-03-20 22:54:24 +00:00
console . log ( 'We change #ai_translation".$htmlContent."_select with lang ' + $ ( this ) . val ());
if ( $ ( this ) . val () != null && $ ( this ) . val () != '' && $ ( this ) . val () != '-1' ) {
2025-03-20 18:32:01 +00:00
prepareCallAIGenerator ( $ ( this ));
}
});
2025-04-03 15:34:09 +00:00
$ ( '#ai_summarize".$htmlContent."_select' ) . on ( 'change' , function () {
2026-05-07 10:11:48 +00:00
console . log ( 'We change #ai_summarize".$htmlContent."_select with length ' + $ ( this ) . val ());
2025-04-03 15:34:09 +00:00
if ( $ ( this ) . val () != null && $ ( this ) . val () != '' && $ ( this ) . val () != '-1' ) {
prepareCallAIGenerator ( $ ( this ));
}
});
2025-04-09 13:47:09 +00:00
$ ( '#ai_rephraser".$htmlContent."_select' ) . on ( 'change' , function () {
2026-05-07 10:11:48 +00:00
console . log ( 'We change #ai_summarize".$htmlContent."_select with mode ' + $ ( this ) . val ());
2025-04-09 13:47:09 +00:00
if ( $ ( this ) . val () != null && $ ( this ) . val () != '' && $ ( this ) . val () != '-1' ) {
prepareCallAIGenerator ( $ ( this ));
}
});
2025-05-04 08:50:01 +00:00
$ ( '#linkforaiprompt".$function."' ) . on ( 'click' , function () {
//Get value aiprompt + prepare ai generator
elementforprompt = $ ( '#input_ai_textgenerationextrafield".$htmlContent."' );
aiprompt = elementforprompt . val ();
if ( aiprompt != null && aiprompt != '' && aiprompt != '-1' ){
prepareCallAIGenerator ( elementforprompt );
}
});
2025-04-09 13:47:09 +00:00
2025-03-20 18:32:01 +00:00
function prepareCallAIGenerator ( element ) {
2025-03-20 22:54:24 +00:00
console . log ( 'We prepare ajax call to AI to url /ai/ajax/generate_content.php function=".dol_escape_js($function)." format=".dol_escape_js($format)."' );
2025-03-20 18:32:01 +00:00
var userprompt = $ ( '#ai_instructions".$htmlContent."' ) . val ();
2025-02-18 14:34:35 +00:00
var timeoutfinished = 0 ;
var apicallfinished = 0 ;
2025-04-07 19:44:26 +00:00
2025-03-20 18:32:01 +00:00
instructions = '' ;
2025-04-07 19:44:26 +00:00
htmlname = '".dol_escape_js($htmlContent)."' ;
2025-02-21 11:36:16 +00:00
format = '".dol_escape_js($format)."' ;
2026-05-07 10:11:48 +00:00
functionai = $ ( element ) . data ( 'functionai' ); /* element is the html element we have manipulated in the ai tool */
style = $ ( '#ai_rephraser' + htmlname + '_select' ) . val ();
2025-04-07 19:44:26 +00:00
texttomodify = '' ;
2025-03-20 18:32:01 +00:00
2026-05-07 10:11:48 +00:00
console . log ( 'htmlname=' + htmlname + ' functionai=' + functionai + ' style=' + style );
2025-04-03 15:34:09 +00:00
if ( $ ( '#' + htmlname ) . is ( 'div' )) {
texttomodify = $ ( '#' + htmlname ) . html (); /* for div */
} else {
texttomodify = $ ( '#' + htmlname ) . val (); /* for input or textarea */
}
2025-03-20 22:54:24 +00:00
if ( functionai == 'texttranslation' ) {
/*
2025-03-20 18:32:01 +00:00
if ( CKEDITOR . instances ) {
editorInstance = CKEDITOR . instances [ htmlname ];
if ( editorInstance ) {
texttomodify = editorInstance . getData ();
}
2025-03-20 22:54:24 +00:00
}
*/
2025-04-07 19:44:26 +00:00
if ( ! texttomodify ) {
instructions = '' ;
} else {
lang = $ ( '#ai_translation' + htmlname + '_select' ) . val ();
instructions = 'Translate only the following text to ' + lang + ': ' + texttomodify ;
}
2025-04-03 15:34:09 +00:00
} else if ( functionai == 'textsummarize' ) {
width = $ ( '#ai_summarize' + htmlname + '_select' ) . val ();
arr = width . split ( '_' );
width = arr [ 0 ];
unit = arr [ 1 ];
if ( width == undefined || unit == undefined ){
console . log ( 'Bad value so we choose 20 words' )
2025-04-07 19:44:26 +00:00
width = '50' ;
2025-04-03 15:34:09 +00:00
unit = 'w' ;
}
switch ( unit ){
case 'w' :
unit = 'words' ;
break ;
case 'p' :
unit = 'paragraphs' ;
break ;
2025-04-04 16:16:29 +00:00
case 'pc' :
unit = 'percent' ;
break ;
2025-04-03 15:34:09 +00:00
default :
console . log ( 'unit not found so we choose words' );
unit = 'words' ;
break ;
}
2025-04-04 16:16:29 +00:00
instructions = 'Summarize the following text ' + ( unit == 'percent' ? 'by ' : 'in' ) + width + ' ' + unit + ': ' + texttomodify ;
2025-04-09 13:47:09 +00:00
} else if ( functionai == 'textrephraser' ) {
2026-05-07 10:11:48 +00:00
if ( style == 'spellchecker' ) {
instructions = 'Fix spelling and grammar errors in the following text : ' + texttomodify ;
functionai = 'textspellchecker' ;
} else {
instructions = 'Rephrase the following text in a ' + style + ' style: ' + texttomodify ;
}
2025-05-04 08:50:01 +00:00
} else if ( functionai == 'textgenerationextrafield' ){
instructions = $ ( element ) . val ();
2025-04-09 13:47:09 +00:00
} else {
2025-03-20 18:32:01 +00:00
instructions = userprompt ;
}
2025-02-18 14:34:35 +00:00
2025-04-07 19:44:26 +00:00
/* Show message API running */
2025-02-18 14:34:35 +00:00
$ ( '#ai_status_message".$htmlContent."' ) . show ();
2025-04-07 19:44:26 +00:00
$ ( '#ai_status_message".$htmlContent."' ) . html ( '".dol_escape_js($messageaiwait)."' );
2025-02-18 14:34:35 +00:00
$ ( '.icon-container .loader' ) . show ();
2025-03-20 22:54:24 +00:00
2025-02-18 14:34:35 +00:00
setTimeout ( function () {
timeoutfinished = 1 ;
2025-02-21 11:36:16 +00:00
$ ( '#ai_status_message".$htmlContent."' ) . hide ();
}, 30000 );
2025-03-20 22:54:24 +00:00
2025-04-07 19:44:26 +00:00
console . log ( 'Instruction forged by javascript = ' + instructions );
2025-03-20 22:54:24 +00:00
2025-02-21 11:36:16 +00:00
callAIGenerator ( functionai , instructions , format , htmlname );
2025-03-20 18:32:01 +00:00
}
2025-04-03 15:34:09 +00:00
CKEDITOR . on ( 'instanceReady' , function ( e ) {
if ( CKEDITOR . instances ) {
var htmlname = '".$htmlContent."' ;
2025-04-08 21:18:23 +00:00
/* if a ckeditor handler exist for this div, we add a handler to have the main html component updated */
console . log ( 'Add handler on CKEDITOR.instances[".$htmlContent."]' );
if ( CKEDITOR . instances [ htmlname ] != undefined ) {
CKEDITOR . instances [ htmlname ] . on ( 'change' , function () {
data = CKEDITOR . instances [ htmlname ] . getData ();
$ ( '#' + htmlname ) . val ( data ); /* for input or textarea */
$ ( '#' + htmlname ) . html ( data ); /* for div */
})
}
2025-04-03 15:34:09 +00:00
}
})
2025-02-21 11:36:16 +00:00
});
</ script >
" ;
return $out ;
}
2025-02-18 14:34:35 +00:00
2025-02-21 11:36:16 +00:00
/**
* Return javascript code for call to AI function callAIGenerator ()
*
2025-03-20 22:54:24 +00:00
* @ return string HTML code to ask AI instructions and autofill result
2025-02-21 11:36:16 +00:00
*/
2025-02-21 11:45:02 +00:00
public function getAjaxAICallFunction ()
{
2025-02-21 11:36:16 +00:00
$out = " " ;
if ( $this -> aicallfunctioncalled ) {
return $out ;
}
$out .= "
< script >
function callAIGenerator ( aifunction , instructions , format , htmlname ){
if ( aifunction === 'imagegeneration' ) {
// Handle image generation request
$ . ajax ({
url : '". DOL_URL_ROOT."/ai/ajax/generate_content.php?token=".currentToken()."' ,
type : 'POST' ,
contentType : 'application/json' ,
data : JSON . stringify ({
'format' : format , /* the format for output */
'function' : aifunction , /* the AI feature to call */
'instructions' : instructions , /* the prompt string */
}),
success : function ( response ) {
console . log ( 'Received image URL: ' + response );
// make substitutions
let substit = " . json_encode( $this->substit ). " ;
for ( let key in substit ) {
if ( substit . hasOwnProperty ( key )) {
// Replace the placeholder with its corresponding value
response = response . replace ( key , substit [ key ]);
}
2025-02-18 14:34:35 +00:00
}
2025-02-21 11:36:16 +00:00
// Assuming response is the URL of the generated image
var imageUrl = response ;
$ ( '#ai_image_result' ) . html ( '<img src=\"' + imageUrl + '\" alt=\"Generated Image\" />' );
// Clear the input field
$ ( '#ai_instructions' ) . val ( '' );
apicallfinished = 1 ;
if ( timeoutfinished ) {
$ ( '#ai_status_message' ) . hide ();
}
},
error : function ( xhr , status , error ) {
2025-04-07 19:44:26 +00:00
/* alert(error); */
console . log ( 'error ajax' , status , error );
/*$('#ai_status_message'+htmlname).hide();*/
$ ( '#ai_status_message' + htmlname ) . val ( error );
$ ( '#ai_status_message' + htmlname ) . html ( error );
2025-02-21 11:36:16 +00:00
}
});
} else {
// set editor in readonly
if ( CKEDITOR . instances [ htmlname ]) {
CKEDITOR . instances [ htmlname ] . setReadOnly ( 1 );
}
2025-04-08 19:50:04 +00:00
console . log ( 'Call generate_content.php' );
2025-02-21 11:36:16 +00:00
$ . ajax ({
url : '". DOL_URL_ROOT."/ai/ajax/generate_content.php?token=".currentToken()."' ,
type : 'POST' ,
contentType : 'application/json' ,
data : JSON . stringify ({
'format' : format , /* the format for output */
'function' : aifunction , /* the AI feature to call */
'instructions' : instructions , /* the prompt string */
}),
success : function ( response ) {
console . log ( 'Add response into field \'#' + htmlname + '\': ' + response );
jQuery ( '#' + htmlname ) . val ( response ); // If #htmlcontent is a input name or textarea
2025-05-12 17:41:46 +00:00
jQuery ( '#' + htmlname ) . html ( response ) . trigger ( 'change' ); // If #htmlContent is a div and trigger event change for extrafield update
2025-02-21 11:36:16 +00:00
//jQuery('#'+htmlname+'preview').val(response);
if ( CKEDITOR . instances ) {
var editorInstance = CKEDITOR . instances [ htmlname ];
if ( editorInstance ) {
editorInstance . setReadOnly ( 0 );
editorInstance . setData ( response );
2025-02-18 14:34:35 +00:00
}
2025-02-21 11:36:16 +00:00
//var editorInstancepreview = CKEDITOR.instances[htmlname+'preview'];
//if (editorInstancepreview) {
// editorInstancepreview.setData(response);
//}
}
2025-02-18 14:34:35 +00:00
2025-04-09 13:47:09 +00:00
// Remove all value from Ai Section select
2025-02-21 11:36:16 +00:00
$ ( '#ai_instructions' + htmlname ) . val ( '' );
2025-03-20 22:54:24 +00:00
$ ( '#ai_translation' + htmlname + '_select' ) . val ( '-1' );
2025-04-03 15:34:09 +00:00
$ ( '#ai_translation' + htmlname + '_select' ) . trigger ( 'change' );
$ ( '#ai_summarize' + htmlname + '_select' ) . val ( '-1' );
$ ( '#ai_summarize' + htmlname + '_select' ) . trigger ( 'change' );
2025-04-09 13:47:09 +00:00
$ ( '#ai_rephraser' + htmlname + '_select' ) . val ( '-1' );
$ ( '#ai_rephraser' + htmlname + '_select' ) . trigger ( 'change' );
2025-02-21 11:36:16 +00:00
$ ( '#ai_status_message' + htmlname ) . hide ();
2025-03-20 18:32:01 +00:00
$ ( '#ai_dropdown' + htmlname ) . hide ();
2025-02-21 11:36:16 +00:00
},
error : function ( xhr , status , error ) {
2025-04-07 19:44:26 +00:00
/* alert(error); */
console . log ( 'error ajax ' , status , error );
/* $('#ai_status_message'+htmlname).hide(); */
if ( xhr . responseText ) {
$ ( '#ai_status_message' + htmlname ) . val ( xhr . responseText );
$ ( '#ai_status_message' + htmlname ) . html ( xhr . responseText );
} else {
$ ( '#ai_status_message' + htmlname ) . val ( error );
$ ( '#ai_status_message' + htmlname ) . html ( error );
}
2025-02-18 14:34:35 +00:00
}
2025-02-21 11:36:16 +00:00
2025-02-18 14:34:35 +00:00
});
2025-02-21 11:36:16 +00:00
}
}
</ script > " ;
$this -> aicallfunctioncalled = true ;
2025-02-18 14:34:35 +00:00
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 );
2025-02-18 15:03:21 +00:00
$product -> fetch ( $line -> fk_product );
2025-02-18 14:34:35 +00:00
$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
}
}
}
2025-02-18 14:47:29 +00:00
}