Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
ldestailleur 2025-02-21 18:04:16 +01:00
commit b8978e5cb9
7 changed files with 250 additions and 98 deletions

View file

@ -75,6 +75,10 @@ class FormAI extends Form
*/
public $withoptiononeemailperrecipient;
/**
* @var bool
*/
public $aicallfunctioncalled = false;
/**
* Constructor
@ -114,7 +118,6 @@ class FormAI extends Form
}
$out .= "</div>\n";
$out .= "<script type='text/javascript'>
$(document).ready(function() {
// for keydown
@ -131,108 +134,17 @@ class FormAI extends Form
var instructions = $('#ai_instructions".$htmlContent."').val();
var timeoutfinished = 0;
var apicallfinished = 0;
htmlname = '".$htmlContent."';
format = '".dol_escape_js($format)."';
functionai = '".dol_escape_js($function)."';
$('#ai_status_message".$htmlContent."').show();
$('.icon-container .loader').show();
setTimeout(function() {
timeoutfinished = 1;
if (apicallfinished) {
$('#ai_status_message".$htmlContent."').hide();
}
}, 2000);
if ('".$function."' === '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': '".dol_escape_js($format)."', /* the format for output */
'function': '".dol_escape_js($function)."', /* 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]);
}
}
// 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) {
alert(error);
console.error('error ajax', status, error);
$('#ai_status_message').hide();
}
});
} else {
// set editor in readonly
if (CKEDITOR.instances.".$htmlContent.") {
CKEDITOR.instances.".$htmlContent.".setReadOnly(1);
}
$.ajax({
url: '". DOL_URL_ROOT."/ai/ajax/generate_content.php?token=".currentToken()."',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
'format': '".dol_escape_js($format)."', /* the format for output */
'function': '".dol_escape_js($function)."', /* the AI feature to call */
'instructions': instructions, /* the prompt string */
}),
success: function(response) {
console.log('Add response into field \'#".$htmlContent."\': '+response);
jQuery('#".$htmlContent."').val(response); // If #htmlcontent is a input name or textarea
jQuery('#".$htmlContent."').html(response); // If #htmlContent is a div
//jQuery('#".$htmlContent."preview').val(response);
if (CKEDITOR.instances) {
var editorInstance = CKEDITOR.instances.".$htmlContent.";
if (editorInstance) {
editorInstance.setReadOnly(0);
editorInstance.setData(response);
}
//var editorInstancepreview = CKEDITOR.instances.".$htmlContent."preview;
//if (editorInstancepreview) {
// editorInstancepreview.setData(response);
//}
}
// remove readonly
$('#ai_instructions".$htmlContent."').val('');
apicallfinished = 1;
if (timeoutfinished) {
$('#ai_status_message".$htmlContent."').hide();
}
},
error: function(xhr, status, error) {
alert(error);
console.error('error ajax', status, error);
$('#ai_status_message".$htmlContent."').hide();
}
});
}
$('#ai_status_message".$htmlContent."').hide();
}, 30000);
callAIGenerator(functionai, instructions, format, htmlname);
});
});
</script>
@ -240,6 +152,115 @@ class FormAI extends Form
return $out;
}
/**
* Return javascript code for call to AI function callAIGenerator()
*
* @return string HTML code to ask AI instruction and autofill result
*/
public function getAjaxAICallFunction()
{
$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]);
}
}
// 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) {
alert(error);
console.error('error ajax', status, error);
$('#ai_status_message').hide();
}
});
} else {
// set editor in readonly
if (CKEDITOR.instances[htmlname]) {
CKEDITOR.instances[htmlname].setReadOnly(1);
}
$.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
jQuery('#'+htmlname).html(response); // If #htmlContent is a div
//jQuery('#'+htmlname+'preview').val(response);
if (CKEDITOR.instances) {
var editorInstance = CKEDITOR.instances[htmlname];
if (editorInstance) {
editorInstance.setReadOnly(0);
editorInstance.setData(response);
}
//var editorInstancepreview = CKEDITOR.instances[htmlname+'preview'];
//if (editorInstancepreview) {
// editorInstancepreview.setData(response);
//}
}
// remove readonly
$('#ai_instructions'+htmlname).val('');
$('#ai_status_message'+htmlname).hide();
},
error: function(xhr, status, error) {
alert(error);
console.error('error ajax', status, error);
$('#ai_status_message'+htmlname).hide();
}
});
}
}
</script>";
$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.
*

View file

@ -118,6 +118,7 @@ if ($showlinktolayout) {
$out .= '<!-- No link to the layout feature, $formmail->withlayout must be set to a string use case, module WYSIWYG must be enabled and MAIN_EMAIL_USE_LAYOUT must be set -->';
}
if ($showlinktoai) {
$out .= $formai->getAjaxAICallFunction();
$out .= $formai->getSectionForAIPrompt($showlinktoai, $formmail->withaiprompt, $htmlname);
} else {
$out .= '<!-- No link to the AI feature, $formmail->withaiprompt must be set to the ai feature and module ai must be enabled -->';

View file

@ -136,3 +136,28 @@ ALTER TABLE llx_categorie_supplier_invoice ADD INDEX idx_categorie_supplier_invo
ALTER TABLE llx_categorie_supplier_invoice ADD CONSTRAINT fk_categorie_supplier_invoice_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid);
ALTER TABLE llx_categorie_supplier_invoice ADD CONSTRAINT fk_categorie_supplier_invoice_fk_supplier_invoice_rowid FOREIGN KEY (fk_supplier_invoice) REFERENCES llx_facture_fourn (rowid);
CREATE TABLE llx_bank_record
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
ref varchar(50) NOT NULL,
fk_bank integer NOT NULL,
dt_from date NOT NULL,
dt_to date NOT NULL,
date_creation datetime NOT NULL,
date_valid datetime NULL,
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)ENGINE=innodb;
ALTER TABLE llx_bank_record ADD CONSTRAINT bank_record_fk_bank FOREIGN KEY (fk_bank) REFERENCES llx_bank_account (rowid);
CREATE TABLE llx_bank_record_link
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
fk_bank_record integer NOT NULL,
fk_bank_import integer NOT NULL
)ENGINE=innodb;
ALTER TABLE llx_bank_record_link ADD CONSTRAINT fk_bank_record_bank_record FOREIGN KEY (llx_bank_record) REFERENCES llx_bank_record (rowid);
ALTER TABLE llx_bank_record_link ADD CONSTRAINT fk_bank_import_bank_import FOREIGN KEY (fk_bank_import) REFERENCES llx_bank_import (rowid);

View file

@ -0,0 +1,23 @@
-- ===================================================================
-- Copyright (C) 2025 Florian HENRY <florian.henry@scopen.fr>
-- Copyright (C) 2025 Laurent MAGNIN <laurent.magnin@evarisk.com>
--
-- 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/>.
--
-- ===================================================================
-- Table to receive manual import of a bank statement
-- Try to match compatibility with external module banking to capitalize on knowledge but removed fields for advanced features.
ALTER TABLE llx_bank_record ADD CONSTRAINT bank_record_fk_bank FOREIGN KEY (fk_bank) REFERENCES llx_bank_account (rowid);

View file

@ -0,0 +1,33 @@
-- ===================================================================
-- Copyright (C) 2025 Florian HENRY <florian.henry@scopen.fr>
-- Copyright (C) 2025 Laurent MAGNIN <laurent.magnin@evarisk.com>
--
-- 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/>.
--
-- ===================================================================
-- Table to receive manual import of a bank statement
-- Try to match compatibility with external module banking to capitalize on knowledge but removed fields for advanced features.
CREATE TABLE llx_bank_record
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
ref varchar(50) NOT NULL,
fk_bank integer NOT NULL,
dt_from date NOT NULL,
dt_to date NOT NULL,
date_creation datetime NOT NULL,
date_valid datetime NULL,
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)ENGINE=innodb;

View file

@ -0,0 +1,21 @@
-- ===================================================================
-- Copyright (C) 2025 Florian HENRY <florian.henry@scopen.fr>
-- Copyright (C) 2025 Laurent MAGNIN <laurent.magnin@evarisk.com>
--
-- 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/>.
--
-- ===================================================================
ALTER TABLE llx_bank_record_link ADD CONSTRAINT fk_bank_record_bank_record FOREIGN KEY (llx_bank_record) REFERENCES llx_bank_record (rowid);
ALTER TABLE llx_bank_record_link ADD CONSTRAINT fk_bank_import_bank_import FOREIGN KEY (fk_bank_import) REFERENCES llx_bank_import (rowid);

View file

@ -0,0 +1,28 @@
-- ===================================================================
-- Copyright (C) 2025 Florian HENRY <florian.henry@scopen.fr>
-- Copyright (C) 2025 Laurent MAGNIN <laurent.magnin@evarisk.com>
--
-- 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/>.
--
-- ===================================================================
-- Table to receive manual import of a bank statement
-- Try to match compatibility with external module banking to capitalize on knowledge but removed fields for advanced features.
CREATE TABLE llx_bank_record_link
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
fk_bank_record integer NOT NULL,
fk_bank_import integer NOT NULL
)ENGINE=innodb;