Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into
develop
This commit is contained in:
commit
38d4ccbd2d
134 changed files with 2188 additions and 1732 deletions
|
|
@ -37,7 +37,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
require_once $path."../htdocs/master.inc.php";
|
||||
require_once $path."../../htdocs/master.inc.php";
|
||||
require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -377,6 +377,7 @@ if ($nboftargetok) {
|
|||
$TMPBUILDTOCHECKCHANGELOG=$BUILD;
|
||||
$TMPBUILDTOCHECKCHANGELOG =~ s/\-rc\d*//;
|
||||
$TMPBUILDTOCHECKCHANGELOG =~ s/\-beta\d*//;
|
||||
$TMPBUILDTOCHECKCHANGELOG =~ s/\-alpha\d*//;
|
||||
print "\nCheck if ChangeLog is ok for version $MAJOR.$MINOR\.$TMPBUILDTOCHECKCHANGELOG\n";
|
||||
$ret=`grep "ChangeLog for $MAJOR.$MINOR\.$TMPBUILDTOCHECKCHANGELOG" "$SOURCE/ChangeLog" 2>&1`;
|
||||
if (! $ret)
|
||||
|
|
@ -387,14 +388,16 @@ if ($nboftargetok) {
|
|||
{
|
||||
print "ChangeLog for $MAJOR.$MINOR\.$BUILD was found into '$SOURCE/ChangeLog'. But you can regenerate it with command:\n";
|
||||
}
|
||||
if (! $BUILD || $BUILD eq '0-rc') # For a major version
|
||||
if (! $BUILD || $BUILD eq '0-alpha' || $BUILD eq '0-beta' || $BUILD eq '0-rc') # For a major or future version
|
||||
{
|
||||
print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log `git rev-list --boundary '.$MAJOR.'.'.$MINOR.'..origin/develop | grep ^- | cut -c2- | head -n 1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\|PERF\|SEC\|QUAL\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/CLOSE/NEW/g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa';
|
||||
print "Building changeLog file for a major version:\n";
|
||||
print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log `git rev-list --boundary '.$MAJOR.'.'.$MINOR.'..origin/develop | grep ^- | cut -c2- | head -n 1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\|PERF\|SEC\|QUAL\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/CLOSE/NEW/g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' | sed \'s/^* //g\' > /tmp/aaa';
|
||||
}
|
||||
else # For a maintenance release
|
||||
{
|
||||
print "Building changeLog file for a maintenance version:\n";
|
||||
#print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\|PERF\|SEC\|QUAL\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/CLOSE/NEW/g\'| sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa';
|
||||
print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. | grep -v "Merge branch" | grep -v "Merge pull" | grep "^ " | sed -e "s/^[0-9a-z]* *//" | grep -e \'^FIX\|NEW\|PERF\|SEC\|QUAL\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/CLOSE/NEW/g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa';
|
||||
print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. | grep -v "Merge branch" | grep -v "Merge pull" | grep "^ " | sed -e "s/^[0-9a-z]* *//" | grep -e \'^FIX\|NEW\|PERF\|SEC\|QUAL\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/CLOSE/NEW/g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' | sed \'s/^* //g\' > /tmp/aaa';
|
||||
}
|
||||
print "\n";
|
||||
if (! $ret)
|
||||
|
|
|
|||
|
|
@ -180,12 +180,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/accountancy/bookkeeping/export.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$filter might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 4
|
||||
path: ../../../htdocs/accountancy/bookkeeping/export.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
|
|
@ -198,12 +192,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/accountancy/bookkeeping/list.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$filter might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 3
|
||||
path: ../../../htdocs/accountancy/bookkeeping/list.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$contextpage in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
|
|
@ -1452,12 +1440,6 @@ parameters:
|
|||
count: 2
|
||||
path: ../../../htdocs/admin/menus/edit.php
|
||||
|
||||
-
|
||||
message: '#^Property Menubase\:\:\$target \(string\) in isset\(\) is not nullable\.$#'
|
||||
identifier: isset.property
|
||||
count: 2
|
||||
path: ../../../htdocs/admin/menus/edit.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
|
|
@ -4656,12 +4638,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/compta/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$newlang in empty\(\) always exists and is always falsy\.$#'
|
||||
identifier: empty.variable
|
||||
count: 2
|
||||
path: ../../../htdocs/compta/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Comparison operation "\<" between '''' and 0 is always true\.$#'
|
||||
identifier: smaller.alwaysTrue
|
||||
|
|
@ -10164,12 +10140,6 @@ parameters:
|
|||
count: 4
|
||||
path: ../../../htdocs/core/lib/pdf.lib.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always true\.$#'
|
||||
identifier: ternary.alwaysTrue
|
||||
count: 12
|
||||
path: ../../../htdocs/core/lib/pdf.lib.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$refListsTxt in empty\(\) always exists and is not falsy\.$#'
|
||||
identifier: empty.variable
|
||||
|
|
@ -10224,12 +10194,6 @@ parameters:
|
|||
count: 6
|
||||
path: ../../../htdocs/core/lib/tax.lib.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always true\.$#'
|
||||
identifier: ternary.alwaysTrue
|
||||
count: 1
|
||||
path: ../../../htdocs/core/lib/ticket.lib.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$butactionbg in empty\(\) always exists and is always falsy\.$#'
|
||||
identifier: empty.variable
|
||||
|
|
@ -10386,12 +10350,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/core/menus/standard/auguria.lib.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#8 \$menuval of function print_text_menu_entry_auguria expects array\{\}\|array\{rowid\: string, fk_menu\: string, langs\: string, enabled\: int\<0, 2\>, type\: string, fk_mainmenu\: string, fk_leftmenu\: string, url\: string, \.\.\.\}, array\{url\: string, titre\: string, enabled\: int\<0, 2\>, target\: string, mainmenu\: string, leftmenu\: string, position\: int, level\?\: int, \.\.\.\} given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../htdocs/core/menus/standard/auguria.lib.php
|
||||
|
||||
-
|
||||
message: '#^Right side of && is always true\.$#'
|
||||
identifier: booleanAnd.rightAlwaysTrue
|
||||
|
|
@ -10422,12 +10380,6 @@ parameters:
|
|||
count: 4
|
||||
path: ../../../htdocs/core/menus/standard/eldy.lib.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#8 \$menuval of function print_text_menu_entry expects array\{\}\|array\{rowid\: string, fk_menu\: string, langs\: string, enabled\: int\<0, 2\>, type\: string, fk_mainmenu\: string, fk_leftmenu\: string, url\: string, \.\.\.\}, array\{url\: string, titre\: string, enabled\: int\<0, 2\>, target\: string, mainmenu\: string, leftmenu\: string, position\: int, level\?\: int, \.\.\.\} given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: ../../../htdocs/core/menus/standard/eldy.lib.php
|
||||
|
||||
-
|
||||
message: '#^Right side of && is always true\.$#'
|
||||
identifier: booleanAnd.rightAlwaysTrue
|
||||
|
|
@ -15066,24 +15018,12 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/fourn/facture/agenda.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$label might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/fourn/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$maxlength might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
count: 1
|
||||
path: ../../../htdocs/fourn/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$newlang in empty\(\) always exists and is always falsy\.$#'
|
||||
identifier: empty.variable
|
||||
count: 2
|
||||
path: ../../../htdocs/fourn/facture/card-rec.php
|
||||
|
||||
-
|
||||
message: '#^Comparison operation "\>" between 0 and 0 is always false\.$#'
|
||||
identifier: greater.alwaysFalse
|
||||
|
|
@ -20580,12 +20520,6 @@ parameters:
|
|||
count: 11
|
||||
path: ../../../htdocs/public/bookcal/bookcalAjax.php
|
||||
|
||||
-
|
||||
message: '#^Ternary operator condition is always true\.$#'
|
||||
identifier: ternary.alwaysTrue
|
||||
count: 1
|
||||
path: ../../../htdocs/public/bookcal/index.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$user might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
|
|
@ -20748,12 +20682,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/public/members/new.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
count: 1
|
||||
path: ../../../htdocs/public/members/new.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$php_self might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
|
|
@ -20826,12 +20754,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/public/partnership/new.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
count: 1
|
||||
path: ../../../htdocs/public/partnership/new.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$user might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
|
|
@ -20988,12 +20910,6 @@ parameters:
|
|||
count: 1
|
||||
path: ../../../htdocs/public/project/new.php
|
||||
|
||||
-
|
||||
message: '#^If condition is always true\.$#'
|
||||
identifier: if.alwaysTrue
|
||||
count: 1
|
||||
path: ../../../htdocs/public/project/new.php
|
||||
|
||||
-
|
||||
message: '#^Variable \$user might not be defined\.$#'
|
||||
identifier: variable.undefined
|
||||
|
|
|
|||
18
dev/setup/fail2ban/filter.d/web-dolibarr-hackattempt.conf
Normal file
18
dev/setup/fail2ban/filter.d/web-dolibarr-hackattempt.conf
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Fail2Ban configuration file
|
||||
#
|
||||
# Regexp to detect try to check a couple login/password so we can add mitigation
|
||||
# on IP making too much tries.
|
||||
|
||||
[Definition]
|
||||
|
||||
# To test, you can inject this example into log
|
||||
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 Hack attempt detected - xxx" >> /mypath/documents/dolibarr.log
|
||||
#
|
||||
# then
|
||||
# fail2ban-client status web-dolibarr-hackattempt
|
||||
#
|
||||
# To test rule file on a existing log file
|
||||
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-hackattempt.conf --print-all-matched
|
||||
|
||||
failregex = ^ [A-Z\s]+ <HOST>\s+Hack attempt detected
|
||||
ignoreregex =
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 --- Access to GET /passwordforgotten.php - action=buildnewpassword, massaction=" >> /mypath/documents/dolibarr.log
|
||||
#
|
||||
# then
|
||||
# fail2ban-client status web-dolibarr-rulespassforgotten
|
||||
# fail2ban-client status web-dolibarr-passf
|
||||
#
|
||||
# To test rule file on a existing log file
|
||||
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-passf.conf --print-all-matched
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ logpath = /mypath/documents/documents/dolibarr.log
|
|||
action = %(action_mw)s
|
||||
bantime = 86400 ; 1 day
|
||||
findtime = 3600 ; 1 hour
|
||||
maxretry = 20 ; 10 login error in 1 hour, we ban
|
||||
maxretry = 20 ; 20 login error in 1 hour, we ban
|
||||
11
dev/setup/fail2ban/jail.d/web-dolibarr-hackattempt.conf
Normal file
11
dev/setup/fail2ban/jail.d/web-dolibarr-hackattempt.conf
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[web-dolibarr-hackattempt]
|
||||
|
||||
; rule against bruteforce hacking (login + api)
|
||||
enabled = true
|
||||
port = http,https
|
||||
filter = web-dolibarr-hackattempt
|
||||
logpath = /mypath/documents/documents/dolibarr.log
|
||||
action = %(action_mw)s
|
||||
bantime = 86400 ; 1 day
|
||||
findtime = 3600 ; 1 hour
|
||||
maxretry = 3 ; 5 hack attempts in 1 hour, we ban
|
||||
|
|
@ -270,7 +270,7 @@ foreach ($output_arrglpu as $val) {
|
|||
// Parse the line to split interesting data
|
||||
$tmpval = cleanVal2($val);
|
||||
|
||||
if (preg_match('/(#yogosha|CVE|Sec:|Sec\s)/i', $tmpval['title'])) {
|
||||
if (preg_match('/(#yogosha|CVE|Sec:|Sec\s|Sec$)/i', $tmpval['title'])) { // Recommended git comment: "Sec: Fix #..."
|
||||
$alreadyfound = '';
|
||||
$alreadyfoundcommitid = '';
|
||||
foreach ($arrayofalerts as $val) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ doubleclick
|
|||
errorstring
|
||||
exten
|
||||
falsy
|
||||
focusin
|
||||
master
|
||||
medias
|
||||
projet
|
||||
|
|
|
|||
|
|
@ -87,8 +87,7 @@
|
|||
$datepaye = dol_mktime(GETPOSTINT("rehour"), GETPOSTINT("remin"), GETPOSTINT("resec"), GETPOSTINT("remonth"), GETPOSTINT("reday"), GETPOSTINT("reyear"), 'tzuserrel');
|
||||
$ensemblereponses = $obj->reponses;
|
||||
$head[$h][1] = $langs->trans('Referers');
|
||||
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $tmpval);
|
||||
$inj += preg_match('/on(dblclick|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $val);
|
||||
$inj += preg_match('/on(dblclick|drag|drop|durationchange|emptied|end|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)[a-z]*\s*=/i', $val);
|
||||
$opensurveysondage->mail_admin = $_SESSION['adresse'];
|
||||
$pdf->SetXY($savx, $savy);
|
||||
$savy = $pdf->getY();
|
||||
|
|
|
|||
|
|
@ -1000,16 +1000,12 @@ INVOICE_USE_SITUATION
|
|||
INVOICE_USE_SITUATION_CREDIT_NOTE
|
||||
ImpossibleToContactAuthority
|
||||
InterDate
|
||||
Inventory Code
|
||||
InvoiceReplace
|
||||
ItemID
|
||||
JobApplications
|
||||
JobPosition
|
||||
Journal
|
||||
Label Movement
|
||||
Labels
|
||||
Last
|
||||
LedgerAccount
|
||||
LocalTax1IsNotUsedExample
|
||||
LocalTax1IsUsedExample
|
||||
LocalTax2IsNotUsedExample
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ if (empty($reshook)) {
|
|||
$object->journal_label = $journal_label;
|
||||
$object->fk_doc = 0;
|
||||
$object->fk_docdet = 0;
|
||||
$object->ref = $numRefModel === 'mod_bookkeeping_neon' ? GETPOST('ref', 'alpha') : $object->getNextNumRef();
|
||||
$object->ref = (GETPOST('ref', 'alpha') ? GETPOST('ref', 'alpha') : $object->getNextNumRef());
|
||||
$object->montant = 0; // deprecated
|
||||
$object->amount = 0;
|
||||
|
||||
|
|
@ -490,13 +490,8 @@ if ($action == 'create') {
|
|||
|
||||
print '<table class="border centpercent">';
|
||||
|
||||
/*print '<tr>';
|
||||
print '<td class="titlefieldcreate fieldrequired">' . $langs->trans("NumPiece") . '</td>';
|
||||
print '<td>' . $next_num_mvt . '</td>';
|
||||
print '</tr>';*/
|
||||
|
||||
print '<tr>';
|
||||
print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Docdate").'</td>';
|
||||
print '<td class="fieldrequired">'.$langs->trans("Docdate").'</td>';
|
||||
print '<td>';
|
||||
print $form->selectDate('', 'doc_date', 0, 0, 0, "create_mvt", 1, 1);
|
||||
print '</td>';
|
||||
|
|
@ -508,16 +503,21 @@ if ($action == 'create') {
|
|||
print '</tr>';
|
||||
|
||||
print '<tr>';
|
||||
print '<td class="fieldrequired">'.$langs->trans("Piece").'</td>';
|
||||
print '<td class="fieldrequired">'.$form->textwithpicto($langs->trans("Piece"), $langs->trans("PieceDesc")).'</td>';
|
||||
print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.GETPOST('doc_ref', 'alpha').'"></td>';
|
||||
print '</tr>';
|
||||
|
||||
// Piece number
|
||||
print '<tr>';
|
||||
print '<td>'.$form->textwithpicto($langs->trans("Ref"), $langs->trans("BankTransactionRef")).'</td>';
|
||||
print '<td>';
|
||||
if ($numRefModel === 'mod_bookkeeping_neon') {
|
||||
print '<tr>';
|
||||
print '<td class="">'.$langs->trans("Ref").'</td>';
|
||||
print '<td><input type="text" class="minwidth200" name="ref" value="'.GETPOST('ref', 'alpha').'"></td>';
|
||||
print '</tr>';
|
||||
print '<input type="text" class="minwidth200" name="ref" value="">';
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans("Automatic").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
/*
|
||||
print '<tr>';
|
||||
|
|
@ -560,7 +560,12 @@ if ($action == 'create') {
|
|||
|
||||
print dol_get_fiche_head($head, 'transaction', '', -1);
|
||||
|
||||
$object->label = $object->doc_ref;
|
||||
//$object->label = $object->doc_ref;
|
||||
if ($mode == '_tmp') {
|
||||
$object->context['mode'] = $mode;
|
||||
$object->next_prev_filter = '1=0'; // Add a test always false to disable navigation into the dol_banner_tab. In tmp mode, we just want to create/edit lines of bank transaction.
|
||||
}
|
||||
$object->label = $object->ref;
|
||||
|
||||
$morehtmlref = '<div style="clear: both;"></div>';
|
||||
$morehtmlref .= '<div class="refidno opacitymedium">';
|
||||
|
|
@ -577,13 +582,15 @@ if ($action == 'create') {
|
|||
print '<table class="border tableforfield centpercent">';
|
||||
|
||||
// Account movement
|
||||
/*
|
||||
print '<tr>';
|
||||
print '<td class="titlefield">'.$langs->trans("NumMvts").'</td>';
|
||||
print '<td class="titlefieldmiddle">'.$langs->trans("NumMvts").'</td>';
|
||||
print '<td>'.($mode == '_tmp' ? '<span class="opacitymedium" title="Id tmp '.$object->piece_num.'">'.$langs->trans("Draft").'</span>' : $object->piece_num).'</td>';
|
||||
print '</tr>';
|
||||
*/
|
||||
|
||||
// Account movement ref. Edit allowed only for free ref num model.
|
||||
print '<tr><td>';
|
||||
print '<tr><td class="titlefieldmiddle">';
|
||||
print '<table class="nobordernopadding centpercent"><tr><td>';
|
||||
print $langs->trans('Ref');
|
||||
print '</td>';
|
||||
|
|
@ -607,7 +614,7 @@ if ($action == 'create') {
|
|||
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
|
||||
print '<input type="hidden" name="type" value="'.$type.'">';
|
||||
print '<input type="text" size="20" name="ref" value="'.dol_escape_htmltag($object->ref).'">';
|
||||
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
|
||||
print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans('Modify').'">';
|
||||
print '</form>';
|
||||
} else {
|
||||
print $object->ref;
|
||||
|
|
@ -618,7 +625,7 @@ if ($action == 'create') {
|
|||
// Ref document
|
||||
print '<tr><td>';
|
||||
print '<table class="nobordernopadding centpercent"><tr><td>';
|
||||
print $langs->trans('Piece');
|
||||
print $form->textwithpicto($langs->trans('Piece'), $langs->trans('PieceDesc'));
|
||||
print '</td>';
|
||||
if ($action != 'editdocref') {
|
||||
print '<td class="right">';
|
||||
|
|
@ -640,7 +647,7 @@ if ($action == 'create') {
|
|||
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
|
||||
print '<input type="hidden" name="type" value="'.$type.'">';
|
||||
print '<input type="text" size="20" name="doc_ref" value="'.dol_escape_htmltag($object->doc_ref).'">';
|
||||
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
|
||||
print '<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans('Modify').'">';
|
||||
print '</form>';
|
||||
} else {
|
||||
print $object->doc_ref;
|
||||
|
|
@ -1037,11 +1044,11 @@ if ($action == 'create') {
|
|||
print '<br>';
|
||||
print '<div class="center">';
|
||||
if (empty($total_debit) && empty($total_credit)) {
|
||||
print '<input type="submit" class="button" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("EnterNonEmptyLinesFirst")).'" value="'.dol_escape_htmltag($langs->trans("ValidTransaction")).'">';
|
||||
print '<a class="button disabled cursornotallowed" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("EnterNonEmptyLinesFirst")).'">'.dol_escape_htmltag($langs->trans("ValidTransaction")).'</a>';
|
||||
} elseif ($total_debit == $total_credit) {
|
||||
print '<a class="button" href="'.$_SERVER["PHP_SELF"].'?piece_num='.((int) $object->piece_num).(!empty($type) ? '&type=sub' : '').'&backtopage='.urlencode($backtopage).'&action=valid&token='.newToken().'">'.$langs->trans("ValidTransaction").'</a>';
|
||||
} else {
|
||||
print '<input type="submit" class="button" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("MvtNotCorrectlyBalanced", $total_debit, $total_credit)).'" value="'.dol_escape_htmltag($langs->trans("ValidTransaction")).'">';
|
||||
print '<a class="button disabled cursornotallowed" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("MvtNotCorrectlyBalanced", $total_debit, $total_credit)).'">'.dol_escape_htmltag($langs->trans("ValidTransaction")).'</a>';
|
||||
}
|
||||
|
||||
print ' ';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
* Copyright (C) 2022 Lionel Vessiller <lvessiller@open-dsi.fr>
|
||||
* Copyright (C) 2016-2017 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2022 Progiseize <a.bisotti@progiseize.fr>
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
|
|
@ -250,6 +250,7 @@ if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
|
|||
*/
|
||||
|
||||
$param = '';
|
||||
$filter = array();
|
||||
|
||||
if (GETPOST('cancel', 'alpha')) {
|
||||
$action = 'list';
|
||||
|
|
@ -332,7 +333,6 @@ if (empty($reshook)) {
|
|||
}
|
||||
|
||||
// Must be after the remove filter action, before the export.
|
||||
$filter = array();
|
||||
if (!empty($search_date_start)) {
|
||||
$filter['t.doc_date>='] = $search_date_start;
|
||||
$tmp = dol_getdate($search_date_start);
|
||||
|
|
@ -548,10 +548,6 @@ if (count($filter) > 0) {
|
|||
$sqlwhere[] = "t.doc_date >= '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.doc_date<=') {
|
||||
$sqlwhere[] = "t.doc_date <= '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.doc_date>') {
|
||||
$sqlwhere[] = "t.doc_date > '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.doc_date<') {
|
||||
$sqlwhere[] = "t.doc_date < '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.numero_compte>=') {
|
||||
$sqlwhere[] = "t.numero_compte >= '".$db->escape($value)."'";
|
||||
} elseif ($key == 't.numero_compte<=') {
|
||||
|
|
@ -560,12 +556,12 @@ if (count($filter) > 0) {
|
|||
$sqlwhere[] = "t.subledger_account >= '".$db->escape($value)."'";
|
||||
} elseif ($key == 't.subledger_account<=') {
|
||||
$sqlwhere[] = "t.subledger_account <= '".$db->escape($value)."'";
|
||||
} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
|
||||
$sqlwhere[] = $db->sanitize($key).'='.((int) $value);
|
||||
// } elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') { // these fields doesn't exists
|
||||
// $sqlwhere[] = $db->sanitize($key).'='.((int) $value);
|
||||
} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
|
||||
$sqlwhere[] = $db->sanitize($key)." LIKE '".$db->escape($db->escapeforlike($value))."%'";
|
||||
} elseif ($key == 't.subledger_account') {
|
||||
$sqlwhere[] = natural_search($key, $value, 0, 1);
|
||||
// } elseif ($key == 't.subledger_account') { // this code is unreachable, test is always false
|
||||
// $sqlwhere[] = natural_search($key, $value, 0, 1);
|
||||
} elseif ($key == 't.tms>=') {
|
||||
$sqlwhere[] = "t.tms >= '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.tms<=') {
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ $permissiontoadd = $user->hasRight('accounting', 'mouvements', 'creer');
|
|||
*/
|
||||
|
||||
$param = '';
|
||||
$filter = array();
|
||||
|
||||
if (GETPOST('cancel', 'alpha')) {
|
||||
$action = 'list';
|
||||
|
|
@ -300,7 +301,6 @@ if (empty($reshook)) {
|
|||
}
|
||||
|
||||
// Must be after the remove filter action, before the export.
|
||||
$filter = array();
|
||||
if (!empty($search_date_start)) {
|
||||
$filter['t.doc_date>='] = $search_date_start;
|
||||
$tmp = dol_getdate($search_date_start);
|
||||
|
|
@ -635,10 +635,6 @@ if (count($filter) > 0) {
|
|||
$sqlwhere[] = "t.doc_date >= '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.doc_date<=') {
|
||||
$sqlwhere[] = "t.doc_date <= '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.doc_date>') {
|
||||
$sqlwhere[] = "t.doc_date > '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.doc_date<') {
|
||||
$sqlwhere[] = "t.doc_date < '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.numero_compte>=') {
|
||||
$sqlwhere[] = "t.numero_compte >= '".$db->escape($value)."'";
|
||||
} elseif ($key == 't.numero_compte<=') {
|
||||
|
|
@ -647,12 +643,12 @@ if (count($filter) > 0) {
|
|||
$sqlwhere[] = "t.subledger_account >= '".$db->escape($value)."'";
|
||||
} elseif ($key == 't.subledger_account<=') {
|
||||
$sqlwhere[] = "t.subledger_account <= '".$db->escape($value)."'";
|
||||
} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
|
||||
$sqlwhere[] = $db->sanitize($key).' = '.((int) $value);
|
||||
/* } elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') { // these fields doesn't exists
|
||||
$sqlwhere[] = $db->sanitize($key).' = '.((int) $value); */
|
||||
} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
|
||||
$sqlwhere[] = $db->sanitize($key)." LIKE '".$db->escape($db->escapeforlike($value))."%'";
|
||||
} elseif ($key == 't.subledger_account') {
|
||||
$sqlwhere[] = natural_search($key, $value, 0, 1);
|
||||
/* } elseif ($key == 't.subledger_account') { // test is always false
|
||||
$sqlwhere[] = natural_search($key, $value, 0, 1); */
|
||||
} elseif ($key == 't.tms>=') {
|
||||
$sqlwhere[] = "t.tms >= '".$db->idate($value)."'";
|
||||
} elseif ($key == 't.tms<=') {
|
||||
|
|
|
|||
|
|
@ -791,7 +791,7 @@ class BookKeeping extends CommonObject
|
|||
$sql .= ' '.(empty($this->code_journal) ? 'NULL' : "'".$this->db->escape($this->code_journal)."'").',';
|
||||
$sql .= ' '.(empty($this->journal_label) ? 'NULL' : "'".$this->db->escape($this->journal_label)."'").',';
|
||||
$sql .= ' '.(empty($this->piece_num) ? 'NULL' : $this->db->escape((string) $this->piece_num)).',';
|
||||
$sql .= ' '.(empty($this->ref) ? '' : "'".$this->db->escape($this->ref)."'").',';
|
||||
$sql .= ' '.(empty($this->ref) ? "''" : "'".$this->db->escape($this->ref)."'").',';
|
||||
$sql .= ' '.(!isset($this->entity) ? $conf->entity : $this->entity);
|
||||
$sql .= ')';
|
||||
|
||||
|
|
|
|||
|
|
@ -347,7 +347,24 @@ for ($i = 1; $i <= 12; $i++) {
|
|||
if ($j > 12) {
|
||||
$j -= 12;
|
||||
}
|
||||
print '<td width="60" class="right">'.$langs->trans('MonthShort'.str_pad((string) $j, 2, '0', STR_PAD_LEFT)).'</td>';
|
||||
$cursormonth = $j;
|
||||
if ($cursormonth > 12) {
|
||||
$cursormonth -= 12;
|
||||
}
|
||||
$cursoryear = ($cursormonth < getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1)) ? $y + 1 : $y;
|
||||
$tmp = dol_getdate(dol_get_last_day($cursoryear, $cursormonth, 'gmt'), false, 'gmt');
|
||||
|
||||
print '<td width="60" class="right">';
|
||||
if (!empty($tmp['mday'])) {
|
||||
$param = 'search_date_startday=1&search_date_startmonth='.$cursormonth.'&search_date_startyear='.$cursoryear;
|
||||
$param .= '&search_date_endday='.$tmp['mday'].'&search_date_endmonth='.$tmp['mon'].'&search_date_endyear='.$tmp['year'];
|
||||
print '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/lines.php?'.$param.'">';
|
||||
}
|
||||
print $langs->trans('MonthShort'.str_pad((string) $j, 2, '0', STR_PAD_LEFT));
|
||||
if (!empty($tmp['mday'])) {
|
||||
print '</a>';
|
||||
}
|
||||
print '</td>';
|
||||
}
|
||||
print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>';
|
||||
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ if (!getDolGlobalInt('SOCIETE_DISABLE_BANKACCOUNT')) {
|
|||
print '<tr class="oddeven">';
|
||||
print '<td>'.$form->textwithpicto($langs->trans("AllowOnLineSign"), $langs->trans("AllowOnLineSignDesc")).'</td>';
|
||||
print '<td class="center">';
|
||||
print ajax_constantonoff('SOCIETE_RIB_ALLOW_ONLINESIGN', array(), null, 0, 0, 0, 2, 0, 1, '', '', 'inline-block', 0, $langs->transnoentitiesnoconv("WarningOnlineSignature"));
|
||||
print ajax_constantonoff('SOCIETE_RIB_ALLOW_ONLINESIGN', array(), null, 0, 0, 0, 2, 0, 1, '', '', 'inline-block', 0, $langs->transnoentitiesnoconv("WarningOnlineSignature", "https://www.dolistore.com"));
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,14 @@ $modules = array(
|
|||
array(
|
||||
'code' => 'MAIN_DELAY_SUPPLIER_BILLS_TO_PAY',
|
||||
'img' => 'bill'
|
||||
),
|
||||
array(
|
||||
'code' => 'MAIN_DELAY_SUPPLIER_PROPALS_TO_CLOSE',
|
||||
'img' => 'propal'
|
||||
),
|
||||
array(
|
||||
'code' => 'MAIN_DELAY_SUPPLIER_PROPALS_TO_BILL',
|
||||
'img' => 'propal'
|
||||
)
|
||||
),
|
||||
'service' => array(
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
|
||||
* Copyright (C) 2022 Anthony Berton <anthony.berton@bb2a.fr>
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -126,6 +126,7 @@ if ($action == 'updateMask') {
|
|||
require_once $file;
|
||||
|
||||
$module = new $classname($db);
|
||||
/** @var ModelePDFFactures $module */
|
||||
'@phan-var-force ModelePDFFactures $module';
|
||||
|
||||
if ($module->write_file($facture, $langs) > 0) {
|
||||
|
|
@ -344,6 +345,7 @@ foreach ($dirmodels as $reldir) {
|
|||
require_once $dir.$filebis;
|
||||
|
||||
$module = new $classname($db);
|
||||
/** @var ModeleNumRefFactures $module */
|
||||
'@phan-var-force ModeleNumRefFactures $module';
|
||||
|
||||
$arrayofmodules[] = $module;
|
||||
|
|
|
|||
|
|
@ -640,9 +640,16 @@ if ($action == 'edit') {
|
|||
print '"></td></tr>';
|
||||
|
||||
// Default from type
|
||||
$liste = array();
|
||||
$liste['user'] = $langs->trans('UserEmail');
|
||||
$liste['company'] = $langs->trans('CompanyEmail').' ('.(!getDolGlobalString('MAIN_INFO_SOCIETE_MAIL') ? $langs->trans("NotDefined") : getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')).')';
|
||||
$liste = array(
|
||||
'user' => array(
|
||||
'label' => $langs->trans('UserEmail'),
|
||||
'data-html' => $langs->trans('UserEmail')
|
||||
),
|
||||
'company' => array(
|
||||
'label' => $langs->trans('CompanyEmail').' ('.getDolGlobalString('MAIN_INFO_SOCIETE_MAIL', $langs->trans("NotDefined")).')',
|
||||
'data-html' => $langs->trans('CompanyEmail').' <span class="opacitymedium">('.getDolGlobalString('MAIN_INFO_SOCIETE_MAIL', $langs->trans("NotDefined")).')</span>'
|
||||
)
|
||||
);
|
||||
|
||||
print '<tr class="oddeven"><td>'.$langs->trans('MAIN_MAIL_DEFAULT_FROMTYPE').'</td><td>';
|
||||
print $form->selectarray('MAIN_MAIL_DEFAULT_FROMTYPE', $liste, getDolGlobalString('MAIN_MAIL_DEFAULT_FROMTYPE'), 0);
|
||||
|
|
@ -1026,6 +1033,10 @@ if ($action == 'edit') {
|
|||
|
||||
print '</div>';
|
||||
|
||||
|
||||
print '<br>';
|
||||
|
||||
|
||||
if (getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail') == 'mail' && !getDolGlobalString('MAIN_FIX_FOR_BUGGED_MTA')) {
|
||||
/*
|
||||
// Warning 1
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ foreach ($dirmenus as $dirmenu) {
|
|||
|
||||
$action = GETPOST('action', 'aZ09');
|
||||
|
||||
$menu = null;
|
||||
$menu = new Menubase($db);
|
||||
|
||||
$menu_handler_top = getDolGlobalString('MAIN_MENU_STANDARD');
|
||||
$menu_handler_smartphone = getDolGlobalString('MAIN_MENU_SMARTPHONE');
|
||||
$menu_handler_top = preg_replace('/_backoffice.php/i', '', $menu_handler_top);
|
||||
|
|
@ -137,7 +138,6 @@ if ($action == 'add') {
|
|||
}
|
||||
|
||||
if (!$error) {
|
||||
$menu = new Menubase($db);
|
||||
$menu->menu_handler = preg_replace('/_menu$/', '', GETPOST('menu_handler', 'aZ09'));
|
||||
$menu->type = (string) GETPOST('type', 'alphanohtml');
|
||||
$menu->title = (string) GETPOST('titre', 'alphanohtml');
|
||||
|
|
@ -148,6 +148,7 @@ if ($action == 'add') {
|
|||
$menu->enabled = (string) GETPOST('enabled', 'alphanohtml');
|
||||
$menu->perms = (string) GETPOST('perms', 'alphanohtml');
|
||||
$menu->target = (string) GETPOST('target', 'alphanohtml');
|
||||
$menu->showtopmenuinframe = GETPOSTINT('showtopmenuinframe');
|
||||
$menu->user = GETPOSTINT('user');
|
||||
$menu->mainmenu = (string) GETPOST('propertymainmenu', 'alphanohtml');
|
||||
if (is_numeric(GETPOST('menuIdParent', 'alphanohtml'))) {
|
||||
|
|
@ -197,7 +198,6 @@ if ($action == 'update') {
|
|||
}
|
||||
|
||||
if (!$error) {
|
||||
$menu = new Menubase($db);
|
||||
$result = $menu->fetch(GETPOSTINT('menuId'));
|
||||
if ($result > 0) {
|
||||
$menu->title = (string) GETPOST('titre', 'alphanohtml');
|
||||
|
|
@ -211,6 +211,8 @@ if ($action == 'update') {
|
|||
$menu->target = (string) GETPOST('target', 'alphanohtml');
|
||||
$menu->user = GETPOSTINT('user');
|
||||
$menu->mainmenu = (string) GETPOST('propertymainmenu', 'alphanohtml');
|
||||
$menu->showtopmenuinframe = GETPOSTINT('showtopmenuinframe');
|
||||
|
||||
if (is_numeric(GETPOST('menuIdParent', 'alphanohtml'))) {
|
||||
$menu->fk_menu = (int) GETPOST('menuIdParent', 'alphanohtml');
|
||||
} else {
|
||||
|
|
@ -318,22 +320,22 @@ if ($action == 'create') {
|
|||
}
|
||||
|
||||
// Handler
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('MenuHandler').'</td>';
|
||||
print '<tr><td class="fieldrequired">'.$form->textwithpicto($langs->trans('MenuHandler'), $langs->trans('DetailMenuHandler')).'</td>';
|
||||
print '<td>';
|
||||
$formadmin->select_menu_families($menu_handler.(preg_match('/_menu/', $menu_handler) ? '' : '_menu'), 'menu_handler', array_merge($dirstandard, $dirsmartphone));
|
||||
print '</td>';
|
||||
print '<td>'.$langs->trans('DetailMenuHandler').'</td></tr>';
|
||||
print '<td></td></tr>';
|
||||
|
||||
// User
|
||||
print '<tr><td class="nowrap fieldrequired">'.$langs->trans('MenuForUsers').'</td>';
|
||||
print '<td><select class="flat" name="user" id="menuuser">';
|
||||
print '<tr><td class="nowrap fieldrequired">'.$form->textwithpicto($langs->trans('MenuForUsers'), $langs->trans('DetailUser')).'</td>';
|
||||
print '<td><select class="flat width150" name="user" id="menuuser">';
|
||||
print '<option value="2" selected>'.$langs->trans("AllMenus").'</option>';
|
||||
print '<option value="0">'.$langs->trans('Internal').'</option>';
|
||||
print '<option value="1">'.$langs->trans('External').'</option>';
|
||||
print '</select>';
|
||||
print ajax_combobox('menuuser');
|
||||
print '</td>';
|
||||
print '<td>'.$langs->trans('DetailUser').'</td></tr>';
|
||||
print '<td></td></tr>';
|
||||
|
||||
// Type
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('Position').'</td><td>';
|
||||
|
|
@ -341,7 +343,7 @@ if ($action == 'create') {
|
|||
print $langs->trans('Left');
|
||||
print '<input type="hidden" name="type" value="left">';
|
||||
} else {
|
||||
print '<select name="type" class="flat" id="topleft">';
|
||||
print '<select name="type" class="flat width150" id="topleft">';
|
||||
print '<option value=""> </option>';
|
||||
print '<option value="top"'.(GETPOST("type") == 'top' ? ' selected' : '').'>'.$langs->trans('Top').'</option>';
|
||||
print '<option value="left"'.(GETPOST("type") == 'left' ? ' selected' : '').'>'.$langs->trans('Left').'</option>';
|
||||
|
|
@ -376,16 +378,6 @@ if ($action == 'create') {
|
|||
print '<tr><td>'.$langs->trans('LangFile').'</td>';
|
||||
print '<td><input type="text" class="minwidth300" name="langs" value="'.dol_escape_htmltag($parent_langs).'"></td><td>'.$langs->trans('DetailLangs').'</td></tr>';
|
||||
|
||||
// URL
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('URL').'</td>';
|
||||
print '<td><input type="text" class="minwidth500" name="url" value="'.dol_escape_htmltag(GETPOST("url", 'alphanohtml')).'"></td><td>'.$langs->trans('DetailUrl').'</td></tr>';
|
||||
|
||||
// Show URL into a frame
|
||||
if (getDolGlobalString("MAIN_SHOW_TOP_MENU_URL_IN_FRAME")) {
|
||||
print '<tr><td>'.$langs->trans('ShowTopMenuURLIntoAFrame').'</td>';
|
||||
print '<td><input type="checkbox" name="showtopmenuinframe" value="'.dol_escape_htmltag(GETPOST("showtopmenuinframe", 'alphanohtml')).'"></td><td></td></tr>';
|
||||
}
|
||||
|
||||
// Picto
|
||||
print '<tr><td>'.$langs->trans('Image').'</td>';
|
||||
print '<td><input type="text" class="minwidth300" name="picto" value="'.dol_escape_htmltag(GETPOST("picto", 'alphanohtml')).'"></td><td>'.$langs->trans('Example').': fa-globe-americas';
|
||||
|
|
@ -395,9 +387,27 @@ if ($action == 'create') {
|
|||
print '</span>';
|
||||
print '</td></tr>';
|
||||
|
||||
// URL
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('URL').'</td>';
|
||||
print '<td><input type="text" class="minwidth500" name="url" value="'.dol_escape_htmltag(GETPOST("url", 'alphanohtml')).'"></td><td>'.$langs->trans('DetailUrl').'</td></tr>';
|
||||
|
||||
// Target
|
||||
print '<tr><td>'.$langs->trans('OpenLinkInto').'</td><td><select class="flat" name="target" id="target">';
|
||||
print '<option value=""'.(isset($menu->target) && $menu->target == "" ? ' selected' : '').'>'.$langs->trans('SameWindow').'</option>';
|
||||
print '<option value="_blank"'.(isset($menu->target) && $menu->target == "_blank" ? ' selected' : '').'>'.$langs->trans('NewWindow').'</option>';
|
||||
print '</select>';
|
||||
print ajax_combobox("target");
|
||||
print '</td><td></td></tr>';
|
||||
|
||||
// Show URL into a frame
|
||||
if (getDolGlobalString("MAIN_FEATURE_TO_SHOW_TOP_MENU_URL_IN_FRAME")) {
|
||||
print '<tr class="hideforleftmenu"><td>'.$langs->trans('ShowTopMenuURLIntoAFrame').'</td>';
|
||||
print '<td><input type="checkbox" value="1" name="showtopmenuinframe"'.(GETPOSTINT("showtopmenuinframe") ? ' checked="checked"' : '').'"></td><td></td></tr>';
|
||||
}
|
||||
|
||||
// Position
|
||||
print '<tr><td>'.$langs->trans('Position').'</td>';
|
||||
print '<td><input type="text" class="width100" name="position" value="'.((int) (GETPOSTISSET("position") ? GETPOSTINT("position") : 100)).'"></td><td>'.$langs->trans('DetailPosition').'</td></tr>';
|
||||
print '<td><input type="number" class="minwidth50 maxwidth75" name="position" value="'.(GETPOSTISSET("position") ? GETPOSTINT("position") : 100).'"></td><td>'.$langs->trans('DetailPosition').'</td></tr>';
|
||||
|
||||
// Enabled
|
||||
print '<tr><td>'.$langs->trans('Enabled').'</td>';
|
||||
|
|
@ -407,14 +417,6 @@ if ($action == 'create') {
|
|||
print '<tr><td>'.$langs->trans('Rights').'</td>';
|
||||
print '<td><input type="text" class="minwidth500" name="perms" value="'.(GETPOSTISSET('perms') ? GETPOST('perms', 'alphanohtml') : '1').'"></td><td>'.$langs->trans('DetailRight').'</td></tr>';
|
||||
|
||||
// Target
|
||||
print '<tr><td>'.$langs->trans('Target').'</td><td><select class="flat" name="target" id="target">';
|
||||
print '<option value=""'.(isset($menu->target) && $menu instanceof Menubase && $menu->target == "" ? ' selected' : '').'> </option>';
|
||||
print '<option value="_blank"'.(isset($menu->target) && $menu instanceof Menubase && $menu->target == "_blank" ? ' selected' : '').'>'.$langs->trans('_blank').'</option>';
|
||||
print '</select>';
|
||||
print ajax_combobox("target");
|
||||
print '</td></td><td>'.$langs->trans('DetailTarget').'</td></tr>';
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
|
|
@ -425,7 +427,6 @@ if ($action == 'create') {
|
|||
print '</form>';
|
||||
} elseif ($action == 'edit') {
|
||||
print load_fiche_titre($langs->trans("ModifMenu"), '', 'title_setup');
|
||||
print '<br>';
|
||||
|
||||
print '<form action="./edit.php" method="POST" name="formmenuedit">';
|
||||
print '<input type="hidden" name="action" value="update">';
|
||||
|
|
@ -443,10 +444,10 @@ if ($action == 'create') {
|
|||
//var_dump($menu);
|
||||
|
||||
// Id
|
||||
print '<tr><td>'.$langs->trans('Id').'</td><td>'.$menu->id.'</td><td>'.$langs->trans('DetailId').'</td></tr>';
|
||||
print '<tr><td>'.$form->textwithpicto($langs->trans('MenuID'), $langs->trans('DetailId')).'</td><td>'.$menu->id.'</td><td></td></tr>';
|
||||
|
||||
// Module
|
||||
print '<tr><td>'.$langs->trans('MenuModule').'</td><td>'.(empty($menu->module) ? 'Core' : $menu->module).'</td><td><span class="opacitymedium">'.$langs->trans('DetailMenuModule').'</span></td></tr>';
|
||||
print '<tr><td>'.$form->textwithpicto($langs->trans('MenuModule'), $langs->trans('DetailMenuModule')).'</td><td>'.(empty($menu->module) ? 'Core' : $menu->module).'</td><td></td></tr>';
|
||||
|
||||
// Handler
|
||||
if ($menu->menu_handler == 'all') {
|
||||
|
|
@ -454,7 +455,8 @@ if ($action == 'create') {
|
|||
} else {
|
||||
$handler = $menu->menu_handler;
|
||||
}
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('MenuHandler').'</td><td>'.$handler.'</td><td>'.$langs->trans('DetailMenuHandler').'</td></tr>';
|
||||
print '<tr><td class="fieldrequired">'.$form->textwithpicto($langs->trans('MenuHandler'), $langs->transnoentitiesnoconv("DetailMenuHandler")).'</td><td>'.$handler.'</td>';
|
||||
print '<td></td></tr>';
|
||||
|
||||
// User
|
||||
print '<tr><td class="nowrap fieldrequired">'.$langs->trans('MenuForUsers').'</td><td>';
|
||||
|
|
@ -468,26 +470,23 @@ if ($action == 'create') {
|
|||
|
||||
// Type
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('Position').'</td>';
|
||||
print '<td>'.$langs->trans(ucfirst($menu->type)).'</td><td>'.$langs->trans('DetailType').'</td></tr>';
|
||||
print '<td>'.$langs->trans(ucfirst($menu->type));
|
||||
print '<input type="hidden" name="type" value="'.$menu->type.'">';
|
||||
print '</td><td>';
|
||||
print $langs->transnoentitiesnoconv("DetailType");
|
||||
print '</td></tr>';
|
||||
|
||||
// Mainmenu code
|
||||
if ($menu->type == 'top') {
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('MainMenuCode').'</td>';
|
||||
/*if ($parent_rowid)
|
||||
{
|
||||
print '<td>'.$parent_rowid.'<input type="hidden" name="propertyleftmenu" value="'.$parent_rowid.'"></td>';
|
||||
}
|
||||
else
|
||||
{*/
|
||||
print '<td><input type="text" class="minwidth300" id="propertymainmenu" name="propertymainmenu" value="'.(GETPOST("propertymainmenu", 'alphanohtml') ? GETPOST("propertymainmenu", 'alphanohtml') : $menu->mainmenu).'"></td>';
|
||||
//}
|
||||
print '<td>';
|
||||
print $langs->trans("Example").': mytopmenukey';
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
// MenuId Parent
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('MenuIdParent');
|
||||
print '<tr class="hideforleftmenu"><td class="fieldrequired">'.$langs->trans('MenuIdParent');
|
||||
print '</td>';
|
||||
$valtouse = $menu->fk_menu;
|
||||
if ($menu->fk_mainmenu) {
|
||||
|
|
@ -512,18 +511,8 @@ if ($action == 'create') {
|
|||
print '<tr><td>'.$langs->trans('LangFile').'</td>';
|
||||
print '<td><input type="text" class="minwidth300" name="langs" value="'.dol_escape_htmltag($menu->langs).'"></td><td>'.$langs->trans('DetailLangs').'</td></tr>';
|
||||
|
||||
// URL
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('URL').'</td>';
|
||||
print '<td><input type="text" class="quatrevingtpercent" name="url" value="'.dol_escape_htmltag($menu->url).'"></td><td>'.$langs->trans('DetailUrl').'</td></tr>';
|
||||
|
||||
// Show URL into a frame
|
||||
if (getDolGlobalString("MAIN_SHOW_TOP_MENU_URL_IN_FRAME")) {
|
||||
print '<tr><td>'.$langs->trans('ShowTopMenuURLIntoAFrame').'</td>';
|
||||
print '<td><input type="checkbox" name="showtopmenuinframe" value="'.dol_escape_htmltag($menu->showtopmenuinframe).'"></td><td></td></tr>';
|
||||
}
|
||||
|
||||
// Picto
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('Image').'</td>';
|
||||
print '<tr><td>'.$langs->trans('Image').'</td>';
|
||||
print '<td><input type="text" class="minwidth300" name="picto" value="'.dol_escape_htmltag($menu->prefix).'"></td><td>'.$langs->trans('Example').': fa-globe-americas';
|
||||
print '<span class="opacitymedium small">';
|
||||
print ' ';
|
||||
|
|
@ -531,9 +520,28 @@ if ($action == 'create') {
|
|||
print '</span>';
|
||||
print '</td></tr>';
|
||||
|
||||
// URL
|
||||
print '<tr><td class="fieldrequired">'.$langs->trans('URL').'</td>';
|
||||
print '<td><input type="text" class="quatrevingtpercent" name="url" value="'.dol_escape_htmltag($menu->url).'"></td><td>'.$langs->trans('DetailUrl').'</td></tr>';
|
||||
|
||||
// Target
|
||||
print '<tr><td>'.$langs->trans('OpenLinkInto').'</td><td>';
|
||||
print '<select class="flat" id="target" name="target">';
|
||||
print '<option value=""'.($menu->target == "" ? ' selected' : '').'>'.$langs->trans('SameWindow').'</option>';
|
||||
print '<option value="_blank"'.($menu->target == "_blank" ? ' selected' : '').'>'.$langs->trans('NewWindow').'</option>';
|
||||
print '</select>';
|
||||
print ajax_combobox("target");
|
||||
print '</td><td></td></tr>';
|
||||
|
||||
// Show URL into a frame
|
||||
if (getDolGlobalString("MAIN_FEATURE_TO_SHOW_TOP_MENU_URL_IN_FRAME") && $menu->type == 'top') {
|
||||
print '<tr class="hideforleftmenu"><td>'.$langs->trans('ShowTopMenuURLIntoAFrame').'</td>';
|
||||
print '<td><input type="checkbox" value="1" name="showtopmenuinframe" '.($menu->showtopmenuinframe ? ' checked="checked"' : '').'"></td><td></td></tr>';
|
||||
}
|
||||
|
||||
// Position
|
||||
print '<tr><td>'.$langs->trans('Position').'</td>';
|
||||
print '<td><input type="text" class="minwidth100" name="position" value="'.((int) $menu->position).'"></td><td>'.$langs->trans('DetailPosition').'</td></tr>';
|
||||
print '<td><input type="number" class="minwidth50 maxwidth75" name="position" value="'.((int) $menu->position).'"></td><td>'.$langs->trans('DetailPosition').'</td></tr>';
|
||||
|
||||
// Enabled
|
||||
print '<tr><td>'.$langs->trans('Enabled').'</td>';
|
||||
|
|
@ -551,15 +559,6 @@ if ($action == 'create') {
|
|||
}
|
||||
print '</td></tr>';
|
||||
|
||||
// Target
|
||||
print '<tr><td>'.$langs->trans('Target').'</td><td>';
|
||||
print '<select class="flat" id="target" name="target">';
|
||||
print '<option value=""'.($menu->target == "" ? ' selected' : '').'> </option>';
|
||||
print '<option value="_blank"'.($menu->target == "_blank" ? ' selected' : '').'>'.$langs->trans('_blank').'</option>';
|
||||
print '</select>';
|
||||
print ajax_combobox("target");
|
||||
print '</td><td>'.$langs->trans('DetailTarget').'</td></tr>';
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/* Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
|
||||
*
|
||||
* 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
|
||||
|
|
@ -170,6 +170,7 @@ foreach ($dirmodels as $reldir) {
|
|||
require_once $dir.$filebis;
|
||||
|
||||
$module = new $classname($db);
|
||||
/** @var ModeleNumRefPayments $module */
|
||||
'@phan-var-force ModeleNumRefPayments $module';
|
||||
|
||||
$arrayofmodules[] = $module;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ if ($action == "set") {
|
|||
if (!($res > 0)) {
|
||||
$error++;
|
||||
}
|
||||
} elseif (!$error) {
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$db->commit();
|
||||
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ foreach ($workflowcodes as $key => $params) {
|
|||
if ($params['family'] == 'separator') {
|
||||
if ($atleastoneline) {
|
||||
print '</table>';
|
||||
print '<br>';
|
||||
print '<br>'."\n";
|
||||
|
||||
$oldfamily = '';
|
||||
$atleastoneline = 0;
|
||||
|
|
@ -301,8 +301,10 @@ foreach ($workflowcodes as $key => $params) {
|
|||
if ($oldfamily != $params['family']) {
|
||||
// New group
|
||||
if ($params['family'] == 'create') {
|
||||
$headerfamily = $langs->trans("AutomaticCreation");
|
||||
$header = $langs->trans("AutomaticCreation");
|
||||
} elseif (preg_match('/classify_(.*)/', $params['family'], $reg)) {
|
||||
$headerfamily = $langs->trans("AutomaticClassification");
|
||||
$header = $langs->trans("AutomaticClassification");
|
||||
if ($reg[1] == 'proposal') {
|
||||
$header .= ' - '.$langs->trans('Proposal');
|
||||
|
|
@ -323,20 +325,31 @@ foreach ($workflowcodes as $key => $params) {
|
|||
$header .= ' - '.$langs->trans('Shipment');
|
||||
}
|
||||
} elseif (preg_match('/link_(.*)/', $params['family'], $reg)) {
|
||||
$headerfamily = $langs->trans("AutomaticLinking");
|
||||
$header = $langs->trans("AutomaticLinking");
|
||||
if ($reg[1] == 'ticket') {
|
||||
$header .= ' - '.$langs->trans('Ticket');
|
||||
}
|
||||
} else {
|
||||
$headerfamily = $langs->trans("Other");
|
||||
$header = $langs->trans("Description");
|
||||
}
|
||||
|
||||
if ($tableopen) {
|
||||
print '</table><br>'."\n";
|
||||
}
|
||||
|
||||
if ($oldfamily == '') {
|
||||
print load_fiche_titre($headerfamily);
|
||||
}
|
||||
|
||||
print "\n";
|
||||
print '<table class="noborder centpercent">';
|
||||
$tableopen = 1;
|
||||
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th>'.$header.'</th>';
|
||||
print '<th class="right">'.$langs->trans("Status").'</th>';
|
||||
print '<th class="right"></th>';
|
||||
print '</tr>';
|
||||
|
||||
$oldfamily = $params['family'];
|
||||
|
|
|
|||
|
|
@ -81,8 +81,16 @@ $aiservice = getDolGlobalString('AI_API_SERVICE', 'chatgpt');
|
|||
// Setup conf for AI model
|
||||
$formSetup->formHiddenInputs['action'] = "updatefeaturemodel";
|
||||
foreach ($arrayofaifeatures as $key => $val) {
|
||||
$newkey = $key;
|
||||
if (preg_match('/^text/', $key)) {
|
||||
$newkey = 'textgeneration';
|
||||
}
|
||||
$item = $formSetup->newItem('AI_API_'.strtoupper($aiservice).'_MODEL_'.$val["function"]); // Name of constant must end with _KEY so it is encrypted when saved into database.
|
||||
$item->nameText = $langs->trans("AI_API_MODEL_".$val["function"]);
|
||||
if ($arrayofai[$aiservice][$newkey] != 'na') {
|
||||
$item->nameText = $langs->trans("AI_API_MODEL_".$val["function"]).' <span class="opacitymedium">('.$langs->trans("Default").' = '.$arrayofai[$aiservice][$newkey].')</span>';
|
||||
} else {
|
||||
$item->nameText = $langs->trans("AI_API_MODEL_".$val["function"]).' <span class="opacitymedium">('.$langs->trans("None").')</span>';
|
||||
}
|
||||
$item->cssClass = 'minwidth500 input';
|
||||
}
|
||||
|
||||
|
|
@ -218,10 +226,15 @@ print load_fiche_titre($langs->trans($title), $linkback, 'title_setup');
|
|||
$head = aiAdminPrepareHead();
|
||||
print dol_get_fiche_head($head, 'custom', $langs->trans($title), -1, "ai");
|
||||
|
||||
//$newbutton = '<a href="'.$_SERVER["PHP_SELF"].'?action=create">'.$langs->trans("New").'</a>';
|
||||
$newbutton = '';
|
||||
$newcardbutton = dolGetButtonTitle($langs->trans('NewCustomPrompt'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?action=create', '', 1);
|
||||
/*
|
||||
$newbutton = '<a href="'.$_SERVER["PHP_SELF"].'?action=create" title="'.$langs->trans("NewCustomPrompt").'">';
|
||||
$newbutton .= img_picto('', 'add');
|
||||
$newbutton .= '</a>';
|
||||
*/
|
||||
|
||||
print load_fiche_titre($langs->trans("AIPromptForFeatures", $arrayofai[$aiservice]['label']), $newcardbutton, '');
|
||||
|
||||
print load_fiche_titre($langs->trans("AIPromptForFeatures"), $newbutton, '');
|
||||
|
||||
if ($action == 'deleteproperty') {
|
||||
$formconfirm = $form->formconfirm(
|
||||
|
|
@ -236,8 +249,12 @@ if ($action == 'deleteproperty') {
|
|||
print $formconfirm;
|
||||
}
|
||||
|
||||
if ($action == 'edit' || $action == 'deleteproperty') {
|
||||
$out = '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
|
||||
print '<br>';
|
||||
|
||||
if ($action == 'create') {
|
||||
$out = '<div class="addcustomprompt">';
|
||||
|
||||
$out .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
|
||||
$out .= '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
$out .= '<input type="hidden" name="action" value="update">';
|
||||
|
||||
|
|
@ -245,7 +262,7 @@ if ($action == 'edit' || $action == 'deleteproperty') {
|
|||
$out .= '<table class="noborder centpercent">';
|
||||
$out .= '<thead>';
|
||||
$out .= '<tr class="liste_titre">';
|
||||
$out .= '<td>'.$langs->trans('Add').'</td>';
|
||||
$out .= '<td>'.$langs->trans('NewCustomPrompt').'</td>';
|
||||
$out .= '<td></td>';
|
||||
$out .= '</tr>';
|
||||
$out .= '</thead>';
|
||||
|
|
@ -310,7 +327,7 @@ if ($action == 'edit' || $action == 'deleteproperty') {
|
|||
$out .= '</span>';
|
||||
$out .= '</td>';
|
||||
$out .= '<td>';
|
||||
$out .= '<textarea class="flat minwidth500 quatrevingtpercent" id="blacklistsInput" name="blacklists" rows="3"></textarea>';
|
||||
$out .= '<input type="text" class="flat minwidth500 quatrevingtpercent" id="blacklistsInput" name="blacklists">';
|
||||
$out .= '</td>';
|
||||
$out .= '</tr>';
|
||||
$out .= '</tbody>';
|
||||
|
|
@ -320,6 +337,7 @@ if ($action == 'edit' || $action == 'deleteproperty') {
|
|||
$out .= '</form>';
|
||||
|
||||
$out .= '<br><br><br>';
|
||||
$out .= '</div>';
|
||||
|
||||
print $out;
|
||||
}
|
||||
|
|
@ -370,25 +388,24 @@ if ($action == 'edit' || $action == 'create' || $action == 'deleteproperty') {
|
|||
$out .= '</tr>';
|
||||
|
||||
$out .= '<tr id="fichetwothirdright-'.$key.'" class="oddeven">';
|
||||
$out .= '<td>'.$langs->trans("BlackListWords").'</td>';
|
||||
$out .= '<td>'.$form->textwithpicto($langs->trans("BlackListWords"), $langs->trans("BlackListWordsHelp")).'</td>';
|
||||
$out .= '<td>';
|
||||
$out .= '<textarea class="flat minwidth500 quatrevingtpercent" id="blacklist_'.$key.'" name="blacklists" rows="3">'.(isset($config['blacklists']) ? implode(', ', (array) $config['blacklists']) : '').'</textarea>';
|
||||
$out .= '<input type="text" class="flat minwidth500 quatrevingtpercent" id="blacklist_'.$key.'" name="blacklists" value="'.(isset($config['blacklists']) ? implode(', ', (array) $config['blacklists']) : '').'">';
|
||||
$out .= '</td>';
|
||||
$out .= '</tr>';
|
||||
|
||||
$out .= '<tr>';
|
||||
$out .= '<td></td>';
|
||||
$out .= '<td>'.$langs->trans("Test").'</td>';
|
||||
$out .= '<td>';
|
||||
$out .= '<input type="submit" class="button small submitBtn reposition" name="modify" data-index="'.$key.'" value="'.dol_escape_htmltag($langs->trans("Save")).'"/>';
|
||||
$out .= ' ';
|
||||
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
||||
$showlinktoai = $key; // 'textgeneration', 'imagegeneration', ...
|
||||
$showlinktoailabel = $langs->trans("ToTest");
|
||||
$formmail = new FormMail($db);
|
||||
$htmlname = $key;
|
||||
$formmail->withaiprompt = 'html'; // set format
|
||||
|
||||
$out .= '<br><br>';
|
||||
$showlinktoai = $key; // 'textgenerationemail', 'textgenerationwebpage', 'imagegeneration', ...
|
||||
$showlinktoailabel = $langs->trans("ToTest");
|
||||
$htmlname = $key;
|
||||
$onlyenhancements = $key;
|
||||
|
||||
// Fill $out
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
|
||||
|
|
@ -401,7 +418,11 @@ if ($action == 'edit' || $action == 'create' || $action == 'deleteproperty') {
|
|||
$out .= '</tbody>';
|
||||
$out .= '</table>';
|
||||
|
||||
$out .= '<center><input type="submit" class="button small submitBtn reposition" name="modify" data-index="'.$key.'" value="'.dol_escape_htmltag($langs->trans("Save")).'"/></center>';
|
||||
|
||||
$out .= '</form>';
|
||||
|
||||
$out .= '<br><br>';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -412,7 +433,7 @@ if ($action == 'edit' || $action == 'create' || $action == 'deleteproperty') {
|
|||
|
||||
|
||||
if ($action == 'edit' || $action == 'create' || $action == 'deleteproperty') {
|
||||
print load_fiche_titre($langs->trans("AIModelForFeature", $arrayofai[$aiservice]), $newbutton, '');
|
||||
print load_fiche_titre($langs->trans("AIModelForFeature", $arrayofai[$aiservice]['label']), '', '');
|
||||
print $formSetup->generateOutput(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ $item = $formSetup->newItem('AI_API_SERVICE'); // Name of constant must end with
|
|||
$item->setAsSelect($arrayofai);
|
||||
$item->cssClass = 'minwidth150';
|
||||
|
||||
foreach ($arrayofai as $ia => $ialabel) {
|
||||
foreach ($arrayofai as $ia => $iarecord) {
|
||||
$ialabel = $iarecord['label'];
|
||||
// Setup conf AI_PUBLIC_INTERFACE_TOPIC
|
||||
/*$item = $formSetup->newItem('AI_API_'.strtoupper($ia).'_ENDPOINT'); // Name of constant must end with _KEY so it is encrypted when saved into database.
|
||||
$item->defaultFieldValue = '';
|
||||
|
|
@ -92,7 +93,7 @@ foreach ($arrayofai as $ia => $ialabel) {
|
|||
$item = $formSetup->newItem('AI_API_'.strtoupper($ia).'_URL'); // Name of constant must end with _KEY so it is encrypted when saved into database.
|
||||
$item->nameText = $langs->trans("AI_API_URL").' ('.$ialabel.')';
|
||||
$item->defaultFieldValue = '';
|
||||
$item->fieldParams['trClass'] = 'iaservice '.$ia;
|
||||
$item->fieldParams['trClass'] = 'iaservice iaurl '.$ia;
|
||||
$item->cssClass = 'minwidth500 input'.$ia;
|
||||
}
|
||||
|
||||
|
|
@ -123,8 +124,6 @@ $action = 'edit';
|
|||
* View
|
||||
*/
|
||||
|
||||
$form = new Form($db);
|
||||
|
||||
$help_url = '';
|
||||
$title = "AiSetup";
|
||||
|
||||
|
|
@ -160,11 +159,29 @@ if (empty($setupnotempty)) {
|
|||
print '<script type="text/javascript">
|
||||
jQuery(document).ready(function() {
|
||||
function showHideAIService(aiservice) {
|
||||
console.log("We select the AI service "+aiservice);
|
||||
console.log("showHideAIService: We select the AI service "+aiservice);
|
||||
jQuery(".iaservice").hide();
|
||||
|
||||
if (aiservice != "-1") {
|
||||
jQuery(".iaservice."+aiservice).show();
|
||||
const arrayofia = {';
|
||||
$i = 0;
|
||||
foreach ($arrayofai as $key => $airecord) {
|
||||
if ($key == -1) {
|
||||
continue;
|
||||
}
|
||||
if ($i) {
|
||||
print ', ';
|
||||
}
|
||||
$i++;
|
||||
print dol_escape_js($key).': \''.dol_escape_js($airecord['url']).'\'';
|
||||
}
|
||||
print '};
|
||||
console.log("Check URL for .iaurl."+aiservice+" .input"+aiservice);
|
||||
if (jQuery(".iaurl."+aiservice+" .input"+aiservice).val() == \'\') {
|
||||
console.log("URL is empty, we fill with default value of IA selected");
|
||||
jQuery(".iaurl."+aiservice+" .input"+aiservice).val(arrayofia[aiservice]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -182,6 +199,8 @@ print '<script type="text/javascript">
|
|||
print dol_get_fiche_end();
|
||||
|
||||
|
||||
// The section for test
|
||||
|
||||
if (getDolGlobalString("AI_API_SERVICE")) {
|
||||
// Section to test
|
||||
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
|
||||
|
|
@ -189,58 +208,50 @@ if (getDolGlobalString("AI_API_SERVICE")) {
|
|||
print '<input type="hidden" name="action" value="add">';
|
||||
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
|
||||
|
||||
$functioncode = GETPOST('functioncode');
|
||||
$out = '';
|
||||
|
||||
//if ($functioncode) {
|
||||
$key = 'textgenerationother'; // The HTML ID of field to fill
|
||||
$key = 'textgenerationother'; // The HTML ID of field to fill
|
||||
|
||||
$labeloffeature = empty($arrayofaifeatures[$key]['label']) ? 'Undefined' : $arrayofaifeatures[$key]['label'];
|
||||
//if (GETPOST('functioncode') == 'textgenerationemail') {
|
||||
|
||||
//$out .= $langs->trans("Test").' '.$labeloffeature.'...<br><br>';
|
||||
print '<br>';
|
||||
//print '<hr>';
|
||||
|
||||
//if (GETPOST('functioncode') == 'textgenerationemail') {
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
||||
include_once DOL_DOCUMENT_ROOT."/core/class/html.formai.class.php";
|
||||
$formai = new FormAI($db);
|
||||
$formmail = new FormMail($db);
|
||||
|
||||
print '<br>';
|
||||
//print '<hr>';
|
||||
$showlinktoai = $key; // 'textgeneration', 'imagegeneration', ...
|
||||
$showlinktoailabel = $langs->trans("AITestText");
|
||||
$showlinktolayout = 0;
|
||||
$htmlname = $key;
|
||||
$formmail->withaiprompt = '';
|
||||
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
|
||||
include_once DOL_DOCUMENT_ROOT."/core/class/html.formai.class.php";
|
||||
$formai = new FormAI($db);
|
||||
$formmail = new FormMail($db);
|
||||
|
||||
$showlinktoai = $key; // 'textgeneration', 'imagegeneration', ...
|
||||
$showlinktoailabel = $langs->trans("AITestText");
|
||||
$showlinktolayout = 0;
|
||||
$htmlname = $key;
|
||||
|
||||
// Fill $out
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
|
||||
|
||||
$out .= '<br><textarea id="'.$key.'" placeholder="Lore ipsum..." class="quatrevingtpercent" rows="4"></textarea>'; // The div
|
||||
//}
|
||||
|
||||
/*
|
||||
if (!$functioncode) {
|
||||
// Combo list of AI features
|
||||
$out .= '<select name="functioncode" id="functioncode" class="flat minwidth300" placeholder="Test feature">';
|
||||
$out .= '<option value="-1">'.$langs->trans("SelectFeatureToTest").'</option>';
|
||||
foreach ($arrayofaifeatures as $key => $val) {
|
||||
$labelhtml = $langs->trans($arrayofaifeatures[$key]['label']).($arrayofaifeatures[$key]['status'] == 'notused' ? ' <span class="opacitymedium">('.$langs->trans("NotYetAvailable").')</span>' : "");
|
||||
$labeltext = $langs->trans($arrayofaifeatures[$key]['label']);
|
||||
$out .= '<option value="'.$key.'" data-html="'.dol_escape_htmltag($labelhtml).'"';
|
||||
$out .= (GETPOST('functioncode') == $key ? ' selected="selected"' : '');
|
||||
$out .= '>'.dol_escape_htmltag($labeltext).'</option>';
|
||||
}
|
||||
$out .= '</select>';
|
||||
$out .= ajax_combobox("functioncode");
|
||||
|
||||
$out .= '<input class="button small" type="submit" name="testmode" value="'.$langs->trans("Test").'">';
|
||||
}
|
||||
*/
|
||||
// Fill $out
|
||||
|
||||
$out = $langs->trans("Test").': ';
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
|
||||
print $out;
|
||||
|
||||
print '<br><textarea id="'.$htmlname.'" placeholder="Lore ipsum..." class="quatrevingtpercent" rows="4"></textarea>'; // The div
|
||||
|
||||
print '<br><br>';
|
||||
|
||||
|
||||
$showlinktoai .= 'html';
|
||||
$htmlname .= 'html';
|
||||
$formmail->withaiprompt = 'html';
|
||||
|
||||
// Fill $out
|
||||
$out = $langs->trans("Test").': ';
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
|
||||
print $out;
|
||||
|
||||
print '<br>';
|
||||
$doleditor = new DolEditor($htmlname, '', '', 100, 'dolibarr_details');
|
||||
print $doleditor->Create(1);
|
||||
|
||||
|
||||
print '</form>';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
/* Copyright (C) 2008-2011 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
/* Copyright (C) 2008-2025 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2005-2016 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org>
|
||||
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
||||
* Copyright (C) 2023 Eric Seigne <eric.seigne@cap-rel.fr>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
*
|
||||
* 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
|
||||
|
|
@ -22,8 +22,8 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/ai/lib/generate_content.lib.php
|
||||
* \brief Library of ai script
|
||||
* \file htdocs/ai/ajax/generate_content.php
|
||||
* \brief Ajax page to generate content
|
||||
*/
|
||||
|
||||
if (!defined('NOTOKENRENEWAL')) {
|
||||
|
|
@ -70,33 +70,45 @@ $rawData = file_get_contents('php://input');
|
|||
$jsonData = json_decode($rawData, true);
|
||||
|
||||
if (is_null($jsonData)) {
|
||||
dol_print_error($db, 'data with format JSON valide.');
|
||||
dol_print_error($db, 'data in POST has not a valid JSON format.');
|
||||
}
|
||||
$ai = new Ai($db);
|
||||
|
||||
// Get parameters
|
||||
$function = empty($jsonData['function']) ? 'textgeneration' : $jsonData['function']; // Default value. Can also be 'textgeneration', 'textgenerationemail', 'textgenerationwebpage', 'imagegeneration', 'videogeneration', ...
|
||||
$instructions = dol_string_nohtmltag($jsonData['instructions'], 1, 'UTF-8');
|
||||
$format = empty($jsonData['format']) ? '' : $jsonData['format']; // Can be '' for text, 'html', ...
|
||||
$format = empty($jsonData['format']) ? '' : $jsonData['format']; // Can be '' for text, 'html', ...
|
||||
|
||||
if ($function == 'texttranslation' && $format == "html") {
|
||||
if ($format == "html") {
|
||||
$instructions = $jsonData['instructions'];
|
||||
} else {
|
||||
$instructions = dol_string_nohtmltag($jsonData['instructions'], 1, 'UTF-8');
|
||||
}
|
||||
|
||||
|
||||
// Note: The option AI_DEBUG will generate a log file dolibarr_ai.log when calling generateContent()
|
||||
dol_syslog("generate_content: function=".$function." format=".$format." instruction=".dol_substr($instructions, 0, 200));
|
||||
|
||||
|
||||
$generatedContent = $ai->generateContent($instructions, 'auto', $function, $format);
|
||||
|
||||
if (is_null($generatedContent) || (is_array($generatedContent) && $generatedContent['error'])) {
|
||||
if (empty($instructions)) {
|
||||
http_response_code(400);
|
||||
print "Error : empty message.";
|
||||
} elseif (is_null($generatedContent) || (is_array($generatedContent) && $generatedContent['error'])) {
|
||||
// Output error
|
||||
if (!empty($generatedContent['code']) && $generatedContent['code'] == 429) {
|
||||
http_response_code($generatedContent['code']);
|
||||
print "Quota or allowed period exceeded. Retry Later !";
|
||||
} elseif (!empty($generatedContent['code']) && $generatedContent['code'] >= 400) {
|
||||
http_response_code($generatedContent['code']);
|
||||
print "Error : " . $generatedContent['message'];
|
||||
print '<br><a href="'.DOL_MAIN_URL_ROOT.'/ai/admin/setup.php">'.$langs->trans('ErrorGoToModuleSetup').'</a>';
|
||||
} elseif (!empty($generatedContent['message'])) {
|
||||
http_response_code($generatedContent['code']);
|
||||
print "Error returned by API call: " . $generatedContent['message'];
|
||||
} else {
|
||||
http_response_code($generatedContent['code']);
|
||||
print "Error API returned no answer";
|
||||
}
|
||||
} else {
|
||||
|
|
@ -109,11 +121,13 @@ if (is_null($generatedContent) || (is_array($generatedContent) && $generatedCont
|
|||
} elseif ($function == 'audiogeneration') {
|
||||
// TODO
|
||||
} else {
|
||||
// Default case 'textgeneration'
|
||||
// Default case 'textgeneration', 'texttranslation', 'textsummarize'
|
||||
if ($format == "html") {
|
||||
print dolPrintHTML($generatedContent); // Note that common HTML tags are NOT escaped (but a sanitization is done)
|
||||
print dolPrintHTML($generatedContent);
|
||||
} else {
|
||||
print dolPrintText($generatedContent); // Note that common HTML tags are NOT escaped (but a sanitization is done)
|
||||
// We must not use dolPrintText because dolPrintText format data including accent in htmlentities for a HTML output. We need a non formatted output.
|
||||
//print dol_string_onlythesehtmltags('"Ça va" est une expression française et ceci une balise <a> html', 1, 1, 1);
|
||||
print dol_string_onlythesehtmltags($generatedContent, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/ai/class/ai.class.php
|
||||
* \ingroup ai
|
||||
* \brief Class files with common methods for Ai
|
||||
*/
|
||||
* \file htdocs/ai/class/ai.class.php
|
||||
* \ingroup ai
|
||||
* \brief Class files with common methods for Ai
|
||||
*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT."/ai/lib/ai.lib.php";
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -53,6 +54,11 @@ class Ai
|
|||
*/
|
||||
private $apiEndpoint;
|
||||
|
||||
const AI_DEFAULT_PROMPT_FOR_EMAIL = 'You are an email editor. Return all HTML content inside a section tag. Do not add explanation.';
|
||||
const AI_DEFAULT_PROMPT_FOR_WEBPAGE = 'You are a website editor. Return all HTML content inside a section tag. Do not add explanation.';
|
||||
const AI_DEFAULT_PROMPT_FOR_TEXT_TRANSLATION = 'You are a translator, give only the translation with no comment and explanation.';
|
||||
const AI_DEFAULT_PROMPT_FOR_TEXT_SUMMARIZE = 'You are a writer, make the answer in the same language than the original text to summarize.';
|
||||
const AI_DEFAULT_PROMPT_FOR_TEXT_REPHRASER = 'You are a writer, give only one answer with no comment and explanation and give the answer in the same language than the original to rephrase.';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
@ -82,53 +88,33 @@ class Ai
|
|||
{
|
||||
global $dolibarr_main_data_root;
|
||||
|
||||
if (empty($this->apiKey) && in_array($this->apiService, array('chatgpt', 'groq'))) {
|
||||
$arrayofai = getListOfAIServices();
|
||||
|
||||
// TODO Can store the need for a key into array returned by getListOfAIServices()
|
||||
if (empty($this->apiKey) && in_array($this->apiService, array('chatgpt', 'groq', 'mistral'))) {
|
||||
return array('error' => true, 'message' => 'API key is not defined for the AI enabled service ('.$this->apiService.')');
|
||||
}
|
||||
|
||||
// $this->apiEndpoint is set here only if forced.
|
||||
// $this->apiEndpoint is already set here only if it was previously forced.
|
||||
|
||||
if (empty($this->apiEndpoint) && $this->apiService == 'custom' && !getDolGlobalString('AI_API_CUSTOM_URL')) {
|
||||
return array('error' => true, 'message' => 'API URL is not defined for the AI enabled service ('.$this->apiService.')');
|
||||
}
|
||||
|
||||
// In most cases, it is empty and we must get it from $function and $this->apiService
|
||||
if (empty($this->apiEndpoint)) {
|
||||
if ($function == 'imagegeneration') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CHATGPT_URL', 'https://api.openai.com/v1').'/images/generations';
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_GROK_URL', 'https://api.groq.com/openai/v1').'/images/generations';
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CUSTOM_URL', '').'/images/generations';
|
||||
}
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_URL', $arrayofai[$this->apiService]['url']);
|
||||
$this->apiEndpoint .= (preg_match('/\/$/', $this->apiEndpoint) ? '' : '/').'images/generations';
|
||||
} elseif ($function == 'audiogeneration') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CHATGPT_URL', 'https://api.openai.com/v1').'/audio/speech';
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_GROK_URL', 'https://api.groq.com/openai/v1').'/audio/speech';
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CUSTOM_URL', '').'/audio/speech';
|
||||
}
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_URL', $arrayofai[$this->apiService]['url']);
|
||||
$this->apiEndpoint .= (preg_match('/\/$/', $this->apiEndpoint) ? '' : '/').'audio/speech';
|
||||
} elseif ($function == 'transcription') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CHATGPT_URL', 'https://api.openai.com/v1').'/transcriptions';
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_GROK_URL', 'https://api.groq.com/openai/v1').'/transcriptions';
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CUSTOM_URL', '').'/transcriptions';
|
||||
}
|
||||
} elseif ($function == 'translation') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CHATGPT_URL', 'https://api.openai.com/v1').'/translations';
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_GROK_URL', 'https://api.groq.com/openai/v1').'/translations';
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CUSTOM_URL', '').'/translations';
|
||||
}
|
||||
} else { // else textgeneration...
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CHATGPT_URL', 'https://api.openai.com/v1').'/chat/completions';
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_GROK_URL', 'https://api.groq.com/openai/v1').'/chat/completions';
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_CUSTOM_URL', '').'/chat/completions';
|
||||
}
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_URL', $arrayofai[$this->apiService]['url']);
|
||||
$this->apiEndpoint .= (preg_match('/\/$/', $this->apiEndpoint) ? '' : '/').'transcriptions';
|
||||
} else {
|
||||
$this->apiEndpoint = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_URL', $arrayofai[$this->apiService]['url']);
|
||||
$this->apiEndpoint .= (preg_match('/\/$/', $this->apiEndpoint) ? '' : '/').'chat/completions';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -137,45 +123,16 @@ class Ai
|
|||
if (empty($model) || $model == 'auto') {
|
||||
// Return the endpoint and the model from $this->apiService.
|
||||
if ($function == 'imagegeneration') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$model = getDolGlobalString('AI_API_CHATGPT_MODEL_IMAGE', 'dall-e-3');
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$model = getDolGlobalString('AI_API_GROK_MODEL_IMAGE', 'mixtral-8x7b-32768'); // 'llama3-8b-8192', 'gemma-7b-it'
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$model = getDolGlobalString('AI_API_CUSTOM_MODEL_IMAGE', 'dall-e-3');
|
||||
}
|
||||
$model = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_MODEL_IMAGE', $arrayofai[$this->apiService][$function]);
|
||||
} elseif ($function == 'audiogeneration') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$model = getDolGlobalString('AI_API_CHATGPT_MODEL_AUDIO', 'tts-1');
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$model = getDolGlobalString('AI_API_GROK_MODEL_AUDIO', 'mixtral-8x7b-32768'); // 'llama3-8b-8192', 'gemma-7b-it'
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$model = getDolGlobalString('AI_API_CUSTOM_MODEL_AUDIO', 'tts-1');
|
||||
}
|
||||
$model = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_MODEL_AUDIO', $arrayofai[$this->apiService][$function]);
|
||||
} elseif ($function == 'transcription') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$model = getDolGlobalString('AI_API_CHATGPT_MODEL_TRANSCRIPT', 'whisper-1');
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$model = getDolGlobalString('AI_API_GROK_MODEL_TRANSCRIPT', 'mixtral-8x7b-32768'); // 'llama3-8b-8192', 'gemma-7b-it'
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$model = getDolGlobalString('AI_API_CUSTOM_MODEL_TRANSCRIPT', 'whisper-1');
|
||||
}
|
||||
$model = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_MODEL_TRANSCRIPT', $arrayofai[$this->apiService][$function]);
|
||||
} elseif ($function == 'translation') {
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$model = getDolGlobalString('AI_API_CHATGPT_MODEL_TRANSLATE', 'whisper-1');
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$model = getDolGlobalString('AI_API_GROK_MODEL_TRANSLATE', 'mixtral-8x7b-32768'); // 'llama3-8b-8192', 'gemma-7b-it'
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$model = getDolGlobalString('AI_API_CUSTOM_MODEL_TRANSLATE', 'whisper-1');
|
||||
}
|
||||
} else { // else textgeneration...
|
||||
if ($this->apiService == 'chatgpt') {
|
||||
$model = getDolGlobalString('AI_API_CHATGPT_MODEL_TEXT', 'gpt-3.5-turbo');
|
||||
} elseif ($this->apiService == 'groq') {
|
||||
$model = getDolGlobalString('AI_API_GROK_MODEL_TEXT', 'mixtral-8x7b-32768'); // 'llama3-8b-8192', 'gemma-7b-it'
|
||||
} elseif ($this->apiService == 'custom') {
|
||||
$model = getDolGlobalString('AI_API_CUSTOM_MODEL_TEXT', 'tinyllama-1.1b'); // with JAN: 'tinyllama-1.1b', 'mistral-ins-7b-q4'
|
||||
}
|
||||
$model = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_MODEL_TRANSLATE', $arrayofai[$this->apiService][$function]);
|
||||
} else {
|
||||
// else 'textgenerationemail', 'textgenerationwebpage', 'textgeneration', 'texttranslation', 'textsummarize'
|
||||
$model = getDolGlobalString('AI_API_'.strtoupper($this->apiService).'_MODEL_TEXT', $arrayofai[$this->apiService]['textgeneration']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +158,22 @@ class Ai
|
|||
$postPrompt = $configurations[$function]['postPrompt'];
|
||||
}
|
||||
}
|
||||
if (empty($prePrompt) && $function == 'textgenerationemail') {
|
||||
$prePrompt = self::AI_DEFAULT_PROMPT_FOR_EMAIL;
|
||||
}
|
||||
if (empty($prePrompt) && $function == 'textgenerationwebpage') {
|
||||
$prePrompt = self::AI_DEFAULT_PROMPT_FOR_WEBPAGE;
|
||||
}
|
||||
if (empty($prePrompt) && $function == 'texttranslation') {
|
||||
$prePrompt = self::AI_DEFAULT_PROMPT_FOR_TEXT_TRANSLATION;
|
||||
}
|
||||
if (empty($prePrompt) && $function == 'textsummarize') {
|
||||
$prePrompt = self::AI_DEFAULT_PROMPT_FOR_TEXT_SUMMARIZE;
|
||||
}
|
||||
if (empty($prePrompt) && $function == 'textrephraser') {
|
||||
$prePrompt = self::AI_DEFAULT_PROMPT_FOR_TEXT_REPHRASER;
|
||||
}
|
||||
|
||||
$fullInstructions = $instructions.($postPrompt ? (preg_match('/[\.\!\?]$/', $instructions) ? '' : '.').' '.$postPrompt : '');
|
||||
|
||||
// Set payload string
|
||||
|
|
@ -276,6 +249,20 @@ class Ai
|
|||
throw new Exception('API request failed. No http received');
|
||||
}
|
||||
if (!empty($response['http_code']) && $response['http_code'] != 200) {
|
||||
if ($response['http_code'] == 400 && !empty($response['content'])) {
|
||||
$tmp = json_decode($response['content'], true);
|
||||
if (!empty($tmp['message'])) {
|
||||
return array(
|
||||
'error' => true,
|
||||
'message' => $tmp['message'],
|
||||
'code' => (empty($response['http_code']) ? 0 : $response['http_code']),
|
||||
'curl_error_no' => (empty($response['curl_error_no']) ? 0 : $response['curl_error_no']),
|
||||
'format' => $format,
|
||||
'service' => $this->apiService,
|
||||
'function' => $function
|
||||
);
|
||||
}
|
||||
}
|
||||
throw new Exception('API request on AI endpoint '.$this->apiEndpoint.' failed with status code '.$response['http_code'].(empty($response['content']) ? '' : ' - '.$response['content']));
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +294,7 @@ class Ai
|
|||
} else {
|
||||
$generatedContent = $decodedResponse['choices'][0]['message']['content'];
|
||||
}
|
||||
dol_syslog("generatedContent=".dol_trunc($generatedContent, 50));
|
||||
dol_syslog("ai->generatedContent returned: ".dol_trunc($generatedContent, 50));
|
||||
|
||||
// If content is not HTML, we convert it into HTML
|
||||
if ($format == 'html') {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ function getListOfAIFeatures()
|
|||
'textgeneration' => array('label' => $langs->trans('TextGeneration').' ('.$langs->trans("Other").')', 'picto'=>'', 'status'=>'notused', 'function' => 'TEXT'),
|
||||
'texttranslation' => array('label' => $langs->trans('TextTranslation'), 'picto'=>'', 'status'=>'dolibarr', 'function' => 'TEXT'),
|
||||
'textsummarize' => array('label' => $langs->trans('TextSummarize'), 'picto'=>'', 'status'=>'dolibarr', 'function' => 'TEXT'),
|
||||
'textrephrase' => array('label' => $langs->trans('TextRephraser'), 'picto'=>'', 'status'=>'dolibarr', 'function' => 'TEXT'),
|
||||
'imagegeneration' => array('label' => 'ImageGeneration', 'picto'=>'', 'status'=>'notused', 'function' => 'IMAGE'),
|
||||
'videogeneration' => array('label' => 'VideoGeneration', 'picto'=>'', 'status'=>'notused', 'function' => 'VIDEO'),
|
||||
'audiogeneration' => array('label' => 'AudioGeneration', 'picto'=>'', 'status'=>'notused', 'function' => 'AUDIO'),
|
||||
|
|
@ -59,16 +60,58 @@ function getListOfAIServices()
|
|||
global $langs;
|
||||
|
||||
$arrayofai = array(
|
||||
'-1' => $langs->trans('SelectAService'),
|
||||
'chatgpt' => 'ChatGPT',
|
||||
'groq' => 'Groq',
|
||||
'custom' => 'Custom'
|
||||
//'gemini' => 'Gemini'
|
||||
'-1' => array('label' => $langs->trans('SelectAService')),
|
||||
'chatgpt' => array(
|
||||
'label' => 'ChatGPT',
|
||||
'url' => 'https://api.openai.com/v1/',
|
||||
'textgeneration' => 'gpt-3.5-turbo', // a lot of text transformation like: 'textgenerationemail', 'textgenerationwebpage', 'textgeneration', 'texttranslation', 'textsummarize'
|
||||
'imagegeneration' => 'dall-e-3',
|
||||
'audiogeneration' => 'tts-1',
|
||||
'videogeneration' => 'na',
|
||||
'transcription' => 'whisper-1', // audio to text
|
||||
'translation' => 'whisper-1', // audio to text into another language
|
||||
),
|
||||
'groq' => array(
|
||||
'label' => 'Groq',
|
||||
'url' => 'https://api.groq.com/openai/',
|
||||
'textgeneration' => 'mixtral-8x7b-32768', // 'llama3-8b-8192', 'gemma-7b-it'
|
||||
'imagegeneration' => 'na',
|
||||
'audiogeneration' => 'na',
|
||||
'videogeneration' => 'na',
|
||||
'transcription' => 'na',
|
||||
'translation' => 'na',
|
||||
),
|
||||
'mistral' => array(
|
||||
'label' => 'Mistral',
|
||||
'url' => 'https://api.mistral.ai/v1/',
|
||||
'textgeneration' => 'open-mistral-7b',
|
||||
'imagegeneration' => 'na',
|
||||
'audiogeneration' => 'na',
|
||||
'videogeneration' => 'na',
|
||||
'transcription' => 'na',
|
||||
'translation' => 'na',
|
||||
),
|
||||
'custom' => array(
|
||||
'label' => 'Custom',
|
||||
'url' => 'https://mydomainofapi.com/v1/',
|
||||
'textgeneration' => 'tinyllama-1.1b',
|
||||
'imagegeneration' => 'mixtral-8x7b-32768',
|
||||
'audiogeneration' => 'mixtral-8x7b-32768',
|
||||
'videogeneration' => 'na',
|
||||
'transcription' => 'mixtral-8x7b-32768',
|
||||
'translation' => 'mixtral-8x7b-32768',
|
||||
)
|
||||
//'gemini' => array(
|
||||
// 'label' => 'Gemini',
|
||||
//)
|
||||
);
|
||||
|
||||
return $arrayofai;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get list for AI summarize
|
||||
*
|
||||
|
|
@ -76,10 +119,8 @@ function getListOfAIServices()
|
|||
*/
|
||||
function getListForAISummarize()
|
||||
{
|
||||
global $langs;
|
||||
|
||||
$arrayforaisummarize = array(
|
||||
'20_w' => 'SummarizeTwentyWords',
|
||||
//'20_w' => 'SummarizeTwentyWords',
|
||||
'50_w' => 'SummarizeFiftyWords',
|
||||
'100_w' => 'SummarizeHundredWords',
|
||||
'200_w' => 'SummarizeTwoHundredWords',
|
||||
|
|
@ -93,6 +134,21 @@ function getListForAISummarize()
|
|||
return $arrayforaisummarize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list for AI style of writing
|
||||
*
|
||||
* @return array<int|string,mixed>
|
||||
*/
|
||||
function getListForAIRephraseStyle()
|
||||
{
|
||||
$arrayforaierephrasestyle = array(
|
||||
'professional' => 'RephraseStyleProfessional',
|
||||
'humouristic' => 'RephraseStyleHumouristic'
|
||||
);
|
||||
|
||||
return $arrayforaierephrasestyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare admin pages header
|
||||
*
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ $formSetup = new FormSetup($db);
|
|||
// Setup conf BOOKCAL_PUBLIC_INTERFACE_TOPIC
|
||||
$item = $formSetup->newItem('BOOKCAL_PUBLIC_INTERFACE_TOPIC');
|
||||
$item->defaultFieldValue = 'MyBigCompany public interface for Bookcal';
|
||||
$item->cssClass = 'minwidth300';
|
||||
|
||||
$setupnotempty = + count($formSetup->items);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
|
||||
* Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class ActionCommReminder extends CommonObject
|
|||
'entity' => array('type' => 'integer', 'label' => 'Entity', 'visible' => 0, 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'index' => 1,),
|
||||
'dateremind' => array('type' => 'datetime', 'label' => 'DateRemind', 'visible' => 1, 'enabled' => 1, 'position' => 60, 'notnull' => 1, 'index' => 1,),
|
||||
'typeremind' => array('type' => 'varchar(32)', 'label' => 'TypeRemind', 'visible' => -1, 'enabled' => 1, 'position' => 55, 'notnull' => 1, 'comment' => "email, browser, sms",),
|
||||
'fk_user' => array('type' => 'integer', 'label' => 'User', 'visible' => -1, 'enabled' => 1, 'position' => 65, 'notnull' => 1, 'index' => 1,),
|
||||
'fk_user' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'User', 'visible' => -1, 'enabled' => 1, 'position' => 65, 'notnull' => 1, 'index' => 1,),
|
||||
'offsetvalue' => array('type' => 'integer', 'label' => 'OffsetValue', 'visible' => 1, 'enabled' => 1, 'position' => 56, 'notnull' => 1,),
|
||||
'offsetunit' => array('type' => 'varchar(1)', 'label' => 'OffsetUnit', 'visible' => 1, 'enabled' => 1, 'position' => 57, 'notnull' => 1, 'comment' => "y, m, d, w, h, i",),
|
||||
'status' => array('type' => 'integer', 'label' => 'Status', 'visible' => 1, 'enabled' => 1, 'position' => 58, 'notnull' => 1, 'default' => '0', 'index' => 0, 'arrayofkeyval' => array('0' => 'ToDo', '1' => 'Done')),
|
||||
|
|
|
|||
|
|
@ -1436,8 +1436,8 @@ if (empty($reshook)) {
|
|||
$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
|
||||
|
||||
// Margin
|
||||
$fournprice = price2num(GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : '');
|
||||
$buyingprice = price2num(GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''); // If buying_price is '0', we must keep this value
|
||||
$fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num((GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''), '', 2); // If buying_price is '0', we must keep this value
|
||||
|
||||
$date_start = dol_mktime(GETPOSTINT('date_start'.$predef.'hour'), GETPOSTINT('date_start'.$predef.'min'), GETPOSTINT('date_start'.$predef.'sec'), GETPOSTINT('date_start'.$predef.'month'), GETPOSTINT('date_start'.$predef.'day'), GETPOSTINT('date_start'.$predef.'year'));
|
||||
$date_end = dol_mktime(GETPOSTINT('date_end'.$predef.'hour'), GETPOSTINT('date_end'.$predef.'min'), GETPOSTINT('date_end'.$predef.'sec'), GETPOSTINT('date_end'.$predef.'month'), GETPOSTINT('date_end'.$predef.'day'), GETPOSTINT('date_end'.$predef.'year'));
|
||||
|
|
@ -1485,7 +1485,7 @@ if (empty($reshook)) {
|
|||
|
||||
if (!$error) {
|
||||
// Insert line
|
||||
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, min($rank, count($object->lines) + 1), 0, GETPOSTINT('fk_parent_line'), (int) $fournprice, (int) $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise);
|
||||
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, min($rank, count($object->lines) + 1), 0, GETPOSTINT('fk_parent_line'), (int) $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise);
|
||||
|
||||
if ($result > 0) {
|
||||
$db->commit();
|
||||
|
|
@ -1621,8 +1621,8 @@ if (empty($reshook)) {
|
|||
$pu_ttc = price2num(GETPOST('price_ttc'), '', 2);
|
||||
|
||||
// Add buying price
|
||||
$fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
|
||||
$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
|
||||
$fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num((GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''), '', 2); // If buying_price is '0', we must keep this value
|
||||
|
||||
$pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
|
||||
$pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2);
|
||||
|
|
@ -1746,7 +1746,7 @@ if (empty($reshook)) {
|
|||
$price_base_type = 'TTC';
|
||||
}
|
||||
|
||||
$result = $object->updateline(GETPOSTINT('lineid'), (float) $pu, (float) $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $description, $price_base_type, $info_bits, $special_code, GETPOSTINT('fk_parent_line'), 0, (int) $fournprice, (int) $buyingprice, $label, $type, $date_start, $date_end, $array_options, GETPOSTINT("units"), (float) $pu_ht_devise);
|
||||
$result = $object->updateline(GETPOSTINT('lineid'), (float) $pu, (float) $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $description, $price_base_type, $info_bits, $special_code, GETPOSTINT('fk_parent_line'), 0, (int) $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, GETPOSTINT("units"), (float) $pu_ht_devise);
|
||||
|
||||
if ($result >= 0) {
|
||||
$db->commit();
|
||||
|
|
@ -2066,7 +2066,7 @@ if ($action == 'create') {
|
|||
if ($soc->fk_warehouse > 0) {
|
||||
$warehouse_id = $soc->fk_warehouse;
|
||||
}
|
||||
if (isModEnabled('stock') && empty($warehouse_id) && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
|
||||
if (isModEnabled('stock') && empty($warehouse_id) && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL')) {
|
||||
if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
|
||||
$warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ class Propal extends CommonObject
|
|||
* @param int $special_code Special code (also used by externals modules!)
|
||||
* @param int $fk_parent_line Id of parent line
|
||||
* @param int $fk_fournprice Id supplier price
|
||||
* @param int $pa_ht Buying price without tax
|
||||
* @param float|string $pa_ht Buying price without tax ('' to keep PMP unchanged or a float)
|
||||
* @param string $label ???
|
||||
* @param int|string $date_start Start date of the line
|
||||
* @param int|string $date_end End date of the line
|
||||
|
|
@ -668,7 +668,7 @@ class Propal extends CommonObject
|
|||
}
|
||||
$txlocaltax1 = price2num($txlocaltax1);
|
||||
$txlocaltax2 = price2num($txlocaltax2);
|
||||
$pa_ht = price2num($pa_ht); // do not convert to float here, it breaks the functioning of $pa_ht_isemptystring
|
||||
$pa_ht = price2num($pa_ht); // do not convert to float here, it breaks the functioning of $pa_ht is empty string
|
||||
if ($price_base_type == 'HT') {
|
||||
$pu = $pu_ht;
|
||||
} else {
|
||||
|
|
@ -886,7 +886,7 @@ class Propal extends CommonObject
|
|||
* @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines).
|
||||
* @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules)
|
||||
* @param int $fk_fournprice Id of origin supplier price
|
||||
* @param float $pa_ht Price (without tax) of product when it was bought
|
||||
* @param float|string $pa_ht Price (without tax) of product when it was bought (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param string $label ???
|
||||
* @param int $type 0/1=Product/service
|
||||
* @param int|string $date_start Start date of the line
|
||||
|
|
@ -894,8 +894,8 @@ class Propal extends CommonObject
|
|||
* @param array<string,mixed> $array_options extrafields array
|
||||
* @param int|null $fk_unit Code of the unit to use. Null to use the default one
|
||||
* @param float $pu_ht_devise Unit price in currency
|
||||
* @param int $notrigger disable line update trigger
|
||||
* @param int $rang line rank
|
||||
* @param int $notrigger Disable line update trigger
|
||||
* @param int $rang Line rank
|
||||
* @return int 0 if OK, <0 if KO
|
||||
*/
|
||||
public function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $desc = '', $price_base_type = 'HT', $info_bits = 0, $special_code = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $type = 0, $date_start = '', $date_end = '', $array_options = array(), $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $rang = 0)
|
||||
|
|
|
|||
|
|
@ -572,6 +572,7 @@ if (isModEnabled('margin')) {
|
|||
$companystatic = new Societe($db);
|
||||
$projectstatic = new Project($db);
|
||||
$formcompany = new FormCompany($db);
|
||||
$userstatic = new User($db);
|
||||
|
||||
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
|
||||
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
|
||||
|
|
@ -891,9 +892,6 @@ if (!$resql) {
|
|||
exit;
|
||||
}
|
||||
|
||||
$objectstatic = new Propal($db);
|
||||
$userstatic = new User($db);
|
||||
|
||||
if ($socid > 0) {
|
||||
$soc = new Societe($db);
|
||||
$soc->fetch($socid);
|
||||
|
|
@ -1782,13 +1780,13 @@ while ($i < $imaxinloop) {
|
|||
$param .= "&search_option=".urlencode($search_option);
|
||||
}
|
||||
|
||||
$objectstatic->id = $obj->rowid;
|
||||
$objectstatic->ref = $obj->ref;
|
||||
$objectstatic->ref_customer = $obj->ref_client;
|
||||
$objectstatic->note_public = $obj->note_public;
|
||||
$objectstatic->note_private = $obj->note_private;
|
||||
$objectstatic->statut = $obj->status;
|
||||
$objectstatic->status = $obj->status;
|
||||
$object->id = $obj->rowid;
|
||||
$object->ref = $obj->ref;
|
||||
$object->ref_customer = $obj->ref_client;
|
||||
$object->note_public = $obj->note_public;
|
||||
$object->note_private = $obj->note_private;
|
||||
$object->statut = $obj->status;
|
||||
$object->status = $obj->status;
|
||||
|
||||
$companystatic->id = $obj->socid;
|
||||
$companystatic->name = $obj->name;
|
||||
|
|
@ -1812,7 +1810,7 @@ while ($i < $imaxinloop) {
|
|||
$multicurrency_totalInvoicedHT = 0;
|
||||
$multicurrency_totalInvoicedTTC = 0;
|
||||
|
||||
$TInvoiceData = $objectstatic->InvoiceArrayList($obj->rowid);
|
||||
$TInvoiceData = $object->InvoiceArrayList($object->id);
|
||||
|
||||
if (!empty($TInvoiceData)) {
|
||||
foreach ($TInvoiceData as $invoiceData) {
|
||||
|
|
@ -1832,8 +1830,8 @@ while ($i < $imaxinloop) {
|
|||
|
||||
$marginInfo = array();
|
||||
if ($with_margin_info) {
|
||||
$objectstatic->fetch_lines();
|
||||
$marginInfo = $formmargin->getMarginInfosArray($objectstatic);
|
||||
$object->fetch_lines();
|
||||
$marginInfo = $formmargin->getMarginInfosArray($object);
|
||||
$total_ht += $obj->total_ht;
|
||||
$total_margin += $marginInfo['total_margin'];
|
||||
}
|
||||
|
|
@ -1844,16 +1842,16 @@ while ($i < $imaxinloop) {
|
|||
print '<div class="box-flex-container kanban">';
|
||||
}
|
||||
// Output Kanban
|
||||
$objectstatic->thirdparty = $companystatic;
|
||||
$object->thirdparty = $companystatic;
|
||||
$userstatic->fetch($obj->fk_user_author);
|
||||
$arrayofparams = array('selected' => in_array($object->id, $arrayofselected), 'authorlink' => $userstatic->getNomUrl(-2), 'projectlink' => $projectstatic->getNomUrl(2));
|
||||
print $objectstatic->getKanbanView('', $arrayofparams);
|
||||
print $object->getKanbanView('', $arrayofparams);
|
||||
if ($i == ($imaxinloop - 1)) {
|
||||
print '</div>';
|
||||
print '</td></tr>';
|
||||
}
|
||||
} else {
|
||||
print '<tr data-rowid="'.$objectstatic->id.'" class="oddeven status'.$objectstatic->status.((getDolGlobalInt('MAIN_FINISHED_LINES_OPACITY') == 1 && $obj->status > 1) ? ' opacitymedium' : '').'">';
|
||||
print '<tr data-rowid="'.$object->id.'" class="oddeven status'.$object->status.((getDolGlobalInt('MAIN_FINISHED_LINES_OPACITY') == 1 && $obj->status > 1) ? ' opacitymedium' : '').'">';
|
||||
|
||||
// Action column
|
||||
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
||||
|
|
@ -1877,7 +1875,7 @@ while ($i < $imaxinloop) {
|
|||
print '<table class="nobordernopadding"><tr class="nocellnopadd">';
|
||||
// Picto + Ref
|
||||
print '<td class="nobordernopadding nowraponall">';
|
||||
print $objectstatic->getNomUrl(1, '', '', 0, 1, (isset($conf->global->PROPAL_LIST_SHOW_NOTES) ? $conf->global->PROPAL_LIST_SHOW_NOTES : 1));
|
||||
print $object->getNomUrl(1, '', '', 0, 1, (isset($conf->global->PROPAL_LIST_SHOW_NOTES) ? $conf->global->PROPAL_LIST_SHOW_NOTES : 1));
|
||||
print '</td>';
|
||||
// Warning
|
||||
$warnornote = '';
|
||||
|
|
@ -1894,7 +1892,7 @@ while ($i < $imaxinloop) {
|
|||
$filename = dol_sanitizeFileName($obj->ref);
|
||||
$filedir = $conf->propal->multidir_output[$obj->propal_entity].'/'.dol_sanitizeFileName($obj->ref);
|
||||
$urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->rowid;
|
||||
print $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir);
|
||||
print $formfile->getDocumentsLink($object->element, $filename, $filedir);
|
||||
print '</td></tr></table>';
|
||||
|
||||
print "</td>\n";
|
||||
|
|
@ -2410,7 +2408,7 @@ while ($i < $imaxinloop) {
|
|||
|
||||
// Status
|
||||
if (!empty($arrayfields['p.fk_statut']['checked'])) {
|
||||
print '<td class="nowrap center">'.$objectstatic->getLibStatut(5).'</td>';
|
||||
print '<td class="nowrap center">'.$object->getLibStatut(5).'</td>';
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1192,7 +1192,7 @@ if (empty($reshook)) {
|
|||
$localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty);
|
||||
|
||||
// Margin
|
||||
$fournprice = price2num(GETPOST('fournprice'.$predef) ? GETPOSTINT('fournprice'.$predef) : 0);
|
||||
$fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOSTINT('fournprice'.$predef) : 0); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num(GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
// Prepare a price equivalent for minimum price check
|
||||
|
|
@ -1238,7 +1238,7 @@ if (empty($reshook)) {
|
|||
|
||||
if (!$error) {
|
||||
// Insert line
|
||||
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, min($rank, count($object->lines) + 1), 0, GETPOSTINT('fk_parent_line'), $fournprice, (float) $buyingprice, $label, $array_options, $fk_unit, '', 0, (float) $pu_ht_devise);
|
||||
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, min($rank, count($object->lines) + 1), 0, GETPOSTINT('fk_parent_line'), (int) $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, (float) $pu_ht_devise);
|
||||
|
||||
if ($result > 0) {
|
||||
$ret = $object->fetch($object->id); // Reload to get new records
|
||||
|
|
@ -1352,7 +1352,7 @@ if (empty($reshook)) {
|
|||
*/
|
||||
|
||||
// Add buying price
|
||||
$fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
|
||||
$fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
// Extrafields Lines
|
||||
|
|
@ -1451,7 +1451,7 @@ if (empty($reshook)) {
|
|||
$price_base_type = 'TTC';
|
||||
}
|
||||
|
||||
$result = $object->updateline(GETPOSTINT('lineid'), $description, (float) $pu, (float) $qty, $remise_percent, (float) $vat_rate, $localtax1_rate, $localtax2_rate, $price_base_type, $info_bits, $date_start, $date_end, $type, GETPOSTINT('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOSTINT('units'), (float) $pu_ht_devise);
|
||||
$result = $object->updateline(GETPOSTINT('lineid'), $description, (float) $pu, (float) $qty, $remise_percent, (float) $vat_rate, $localtax1_rate, $localtax2_rate, $price_base_type, $info_bits, $date_start, $date_end, $type, GETPOSTINT('fk_parent_line'), 0, (int) $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOSTINT('units'), (float) $pu_ht_devise);
|
||||
|
||||
if ($result >= 0) {
|
||||
if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
|
||||
|
|
|
|||
|
|
@ -1541,7 +1541,7 @@ class Commande extends CommonOrder
|
|||
* @param int $special_code Special code (also used by externals modules!)
|
||||
* @param int $fk_parent_line Parent line
|
||||
* @param int $fk_fournprice Id supplier price
|
||||
* @param float $pa_ht Buying price (without tax)
|
||||
* @param float|string $pa_ht Buying price without tax (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param string $label Label
|
||||
* @param array<string,mixed> $array_options Extrafields array. Example array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...)
|
||||
* @param ?int $fk_unit Code of the unit to use. Null to use the default one
|
||||
|
|
@ -3064,7 +3064,7 @@ class Commande extends CommonOrder
|
|||
* @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines).
|
||||
* @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules)
|
||||
* @param int $fk_fournprice Id of origin supplier price
|
||||
* @param float $pa_ht Price (without tax) of product when it was bought
|
||||
* @param float|string $pa_ht Price (without tax) of product when it was bought (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param string $label Label
|
||||
* @param int $special_code Special code (also used by externals modules!)
|
||||
* @param array<string,mixed> $array_options extrafields array
|
||||
|
|
|
|||
|
|
@ -587,20 +587,20 @@ class Account extends CommonObject
|
|||
/**
|
||||
* Add an entry into table ".MAIN_DB_PREFIX."bank
|
||||
*
|
||||
* @param int $date Date operation
|
||||
* @param string $oper 'VIR','PRE','LIQ','VAD','CB','CHQ'...
|
||||
* @param string $label Description
|
||||
* @param float $amount Amount
|
||||
* @param string $num_chq Numero cheque or transfer
|
||||
* @param int $categorie Category id (optional)
|
||||
* @param User $user User that create
|
||||
* @param string $emetteur Name of cheque writer
|
||||
* @param string $banque Bank of cheque writer
|
||||
* @param string $accountancycode When we record a free bank entry, we must provide accounting account if accountancy module is on.
|
||||
* @param int $datev Date value
|
||||
* @param string $num_releve Label of bank receipt for reconciliation
|
||||
* @param int $date Date operation
|
||||
* @param string $oper 'VIR','PRE','LIQ','VAD','CB','CHQ'...
|
||||
* @param string $label Description
|
||||
* @param float $amount Amount
|
||||
* @param string $num_chq Numero cheque or transfer
|
||||
* @param int $categorie Category id (optional)
|
||||
* @param User $user User that create
|
||||
* @param string $emetteur Name of cheque writer
|
||||
* @param string $banque Bank of cheque writer
|
||||
* @param string $accountancycode When we record a free bank entry, we must provide accounting account if accountancy module is on.
|
||||
* @param int $datev Date value
|
||||
* @param string $num_releve Label of bank receipt for reconciliation
|
||||
* @param float $amount_main_currency Amount
|
||||
* @return int Rowid of added entry, <0 if KO
|
||||
* @return int Rowid of added entry, <0 if KO
|
||||
*/
|
||||
public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $
|
|||
$id = (GETPOSTINT('facid') ? GETPOSTINT('facid') : GETPOSTINT('id'));
|
||||
$lineid = GETPOSTINT('lineid');
|
||||
$ref = GETPOST('ref', 'alpha');
|
||||
$socid = 0;
|
||||
if ($user->socid) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
|
|
@ -714,7 +715,7 @@ if (empty($reshook)) {
|
|||
$date_end_fill = GETPOSTINT('date_end_fill');
|
||||
|
||||
// Margin
|
||||
$fournprice = price2num(GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : '');
|
||||
$fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num(GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
// Local Taxes
|
||||
|
|
@ -733,7 +734,7 @@ if (empty($reshook)) {
|
|||
setEventMessages($mesg, null, 'errors');
|
||||
} else {
|
||||
// Insert line
|
||||
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $info_bits, 0, $pu_ttc, $type, -1, $special_code, $label, (int) $fk_unit, 0, $date_start_fill, $date_end_fill, (int) $fournprice, (int) $buyingprice, $fk_parent_line);
|
||||
$result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $info_bits, 0, $pu_ttc, $type, -1, $special_code, $label, (int) $fk_unit, 0, $date_start_fill, $date_end_fill, (int) $fournprice, $buyingprice, $fk_parent_line);
|
||||
|
||||
if ($result > 0) {
|
||||
// Define output language and generate document
|
||||
|
|
@ -832,7 +833,7 @@ if (empty($reshook)) {
|
|||
$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
|
||||
|
||||
// Add buying price
|
||||
$fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
|
||||
$fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : '');
|
||||
$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
// Extrafields
|
||||
|
|
|
|||
|
|
@ -852,6 +852,8 @@ if (empty($reshook)) {
|
|||
$result = $object->setPaid($user, $close_code, $close_note);
|
||||
if ($result < 0) {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
} else {
|
||||
$object->fetch($object->id); // Reload properties
|
||||
}
|
||||
} else {
|
||||
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
|
||||
|
|
@ -865,6 +867,8 @@ if (empty($reshook)) {
|
|||
$result = $object->setCanceled($user, $close_code, $close_note);
|
||||
if ($result < 0) {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
} else {
|
||||
$object->fetch($object->id); // Reload properties
|
||||
}
|
||||
} else {
|
||||
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Reason")), null, 'errors');
|
||||
|
|
@ -1043,6 +1047,7 @@ if (empty($reshook)) {
|
|||
// Set invoice as paid
|
||||
$result = $object->setPaid($user);
|
||||
if ($result >= 0) {
|
||||
$object->fetch($object->id); // Reload properties
|
||||
$db->commit();
|
||||
} else {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
|
|
@ -2508,7 +2513,7 @@ if (empty($reshook)) {
|
|||
*/
|
||||
|
||||
// Margin
|
||||
$fournprice = price2num(GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : '');
|
||||
$fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num(GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
|
||||
|
|
@ -2707,7 +2712,7 @@ if (empty($reshook)) {
|
|||
$localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty);
|
||||
|
||||
// Add buying price
|
||||
$fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
|
||||
$fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
// Prepare a price equivalent for minimum price check
|
||||
|
|
@ -2898,7 +2903,7 @@ if (empty($reshook)) {
|
|||
$type,
|
||||
GETPOSTINT('fk_parent_line'),
|
||||
0,
|
||||
$fournprice,
|
||||
(int) $fournprice,
|
||||
$buyingprice,
|
||||
$label,
|
||||
$special_code,
|
||||
|
|
@ -4402,7 +4407,7 @@ if ($action == 'create') {
|
|||
}
|
||||
}
|
||||
|
||||
if ($object->paye) {
|
||||
if ($object->paye || $object->status == $object::STATUS_CLOSED) {
|
||||
$resteapayer = 0;
|
||||
}
|
||||
$resteapayeraffiche = $resteapayer;
|
||||
|
|
@ -4639,15 +4644,15 @@ if ($action == 'create') {
|
|||
$close = array();
|
||||
// Code
|
||||
$i = 0;
|
||||
$close[$i]['code'] = 'discount_vat'; // escompte
|
||||
$close[$i]['code'] = $object::CLOSECODE_DISCOUNTVAT; // escompte
|
||||
$i++;
|
||||
$close[$i]['code'] = 'badcustomer';
|
||||
$close[$i]['code'] = $object::CLOSECODE_BADDEBT;
|
||||
$i++;
|
||||
$close[$i]['code'] = 'bankcharge';
|
||||
$close[$i]['code'] = $object::CLOSECODE_BANKCHARGE;
|
||||
$i++;
|
||||
$close[$i]['code'] = 'withholdingtax';
|
||||
$close[$i]['code'] = $object::CLOSECODE_WITHHOLDINGTAX;
|
||||
$i++;
|
||||
$close[$i]['code'] = 'other';
|
||||
$close[$i]['code'] = $object::CLOSECODE_OTHER;
|
||||
$i++;
|
||||
// Help
|
||||
$i = 0;
|
||||
|
|
@ -4676,13 +4681,18 @@ if ($action == 'create') {
|
|||
// arrayreasons[code]=reason
|
||||
$arrayreasons = [];
|
||||
foreach ($close as $key => $val) {
|
||||
$arrayreasons[$close[$key]['code']] = $close[$key]['reason'];
|
||||
$arrayreasons[$close[$key]['code']] = '<span class="small">'.$close[$key]['reason'].'</span>';
|
||||
}
|
||||
|
||||
// Create a form table
|
||||
$formquestion = array('text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"), 0 => array('type' => 'radio', 'name' => 'close_code', 'label' => $langs->trans("Reason"), 'values' => $arrayreasons), 1 => array('type' => 'text', 'name' => 'close_note', 'label' => $langs->trans("Comment"), 'value' => '', 'morecss' => 'minwidth300'));
|
||||
$formquestion = array(
|
||||
'text' => $langs->trans("ConfirmClassifyPaidPartiallyQuestion"),
|
||||
0 => array('type' => 'radio', 'name' => 'close_code', 'label' => '', 'values' => $arrayreasons),
|
||||
1 => array('type' => 'text', 'name' => 'close_note', 'moreattr' => 'placeholder = "'.$langs->trans("Comment").'"', 'value' => '', 'morecss' => 'minwidth300'),
|
||||
2 => array('type' => 'separator')
|
||||
);
|
||||
// Incomplete payment. We ask if reason = discount or other
|
||||
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 380, 600);
|
||||
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidPartially', $object->ref), 'confirm_paid_partially', $formquestion, "yes", 1, 400, 600);
|
||||
}
|
||||
|
||||
// Confirmation of status abandoned
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
|
||||
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
|
||||
* Copyright (C) 2017-2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2017-2025 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2023 Nick Fragoulis
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
|
|
@ -956,8 +956,8 @@ class FactureRec extends CommonInvoice
|
|||
* @param float $pu_ht_devise Unit price in currency
|
||||
* @param int $date_start_fill 1=Flag to fill start date when generating invoice
|
||||
* @param int $date_end_fill 1=Flag to fill end date when generating invoice
|
||||
* @param ?int $fk_fournprice Supplier price id (to calculate margin) or ''
|
||||
* @param float $pa_ht Buying price of line (to calculate margin) or ''
|
||||
* @param int|string|null $fk_fournprice Supplier price id (to calculate margin) or string
|
||||
* @param float $pa_ht Buying price of line (to calculate margin) (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param int $fk_parent_line Id of parent line
|
||||
* @return int Return integer <0 if KO, Id of line if OK
|
||||
*/
|
||||
|
|
@ -1164,7 +1164,7 @@ class FactureRec extends CommonInvoice
|
|||
* @param int $date_start_fill 1=Flag to fill start date when generating invoice
|
||||
* @param int $date_end_fill 1=Flag to fill end date when generating invoice
|
||||
* @param ?int $fk_fournprice Id of origin supplier price
|
||||
* @param float $pa_ht Price (without tax) of product for margin calculation
|
||||
* @param float|string $pa_ht Price (without tax) of product for margin calculation (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param int $fk_parent_line Id of parent line
|
||||
* @return int Return integer <0 if KO, Id of line if OK
|
||||
*/
|
||||
|
|
@ -1368,7 +1368,7 @@ class FactureRec extends CommonInvoice
|
|||
*/
|
||||
public function createRecurringInvoices($restrictioninvoiceid = 0, $forcevalidation = 0, $notrigger = 0)
|
||||
{
|
||||
global $conf, $langs, $db, $user, $hookmanager;
|
||||
global $conf, $langs, $db, $user, $hookmanager, $action;
|
||||
|
||||
$error = 0;
|
||||
$nb_create = 0;
|
||||
|
|
@ -1455,10 +1455,12 @@ class FactureRec extends CommonInvoice
|
|||
}
|
||||
}
|
||||
|
||||
$parameters['facture'] = &$facture;
|
||||
$reshook = $hookmanager->executeHooks('beforeCreationOfEachRecurringInvoice', $parameters, $facturerec, $action); // note that $facturerec or $facture might be modified by hooks
|
||||
|
||||
$invoiceidgenerated = $facture->create($user);
|
||||
if ($invoiceidgenerated <= 0) {
|
||||
$this->errors = $facture->errors;
|
||||
$this->error = $facture->error;
|
||||
$this->setErrorsFromObject($facture);
|
||||
$error++;
|
||||
}
|
||||
|
||||
|
|
@ -1466,8 +1468,7 @@ class FactureRec extends CommonInvoice
|
|||
if (!$error && ($facturerec->auto_validate || $forcevalidation)) {
|
||||
$result = $facture->validate($user);
|
||||
if ($result <= 0) {
|
||||
$this->errors = $facture->errors;
|
||||
$this->error = $facture->error;
|
||||
$this->setErrorsFromObject($facture);
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1476,8 +1477,7 @@ class FactureRec extends CommonInvoice
|
|||
$facture->fetch($facture->id);
|
||||
$result = $facture->generateDocument($facturerec->model_pdf, $langs);
|
||||
if ($result <= 0) {
|
||||
$this->errors = $facture->errors;
|
||||
$this->error = $facture->error;
|
||||
$this->setErrorsFromObject($facture);
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1836,14 +1836,13 @@ class FactureRec extends CommonInvoice
|
|||
$this->socid = 1;
|
||||
$this->date = $nownotime;
|
||||
$this->date_lim_reglement = $nownotime + 3600 * 24 * 30;
|
||||
$this->cond_reglement_id = 1;
|
||||
$this->cond_reglement_id = 1;
|
||||
$this->cond_reglement_code = 'RECEP';
|
||||
$this->date_lim_reglement = $this->calculate_date_lim_reglement();
|
||||
$this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
|
||||
$this->mode_reglement_id = 0; // Not forced to show payment mode CHQ + VIR
|
||||
$this->mode_reglement_code = ''; // Not forced to show payment mode CHQ + VIR
|
||||
$this->note_public = 'This is a comment (public)';
|
||||
$this->note_private = 'This is a comment (private)';
|
||||
$this->note = 'This is a comment (private)';
|
||||
$this->fk_incoterms = 0;
|
||||
$this->location_incoterms = '';
|
||||
|
||||
|
|
@ -2415,7 +2414,7 @@ class FactureLigneRec extends CommonInvoiceLine
|
|||
|
||||
$this->rang = $objp->rang;
|
||||
$this->special_code = $objp->special_code;
|
||||
$this->fk_unit = $objp->fk_unit;
|
||||
$this->fk_unit = $objp->fk_unit;
|
||||
$this->fk_contract_line = $objp->fk_contract_line;
|
||||
$this->import_key = $objp->import_key;
|
||||
$this->fk_multicurrency = $objp->fk_multicurrency;
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ class Facture extends CommonInvoice
|
|||
* 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
|
||||
* Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
|
||||
* 'label' the translation key.
|
||||
* 'langfile' the key of the language file for translation.
|
||||
* 'enabled' is a condition when the field must be managed.
|
||||
* 'position' is the sort order of field.
|
||||
* 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
|
||||
|
|
@ -378,8 +379,8 @@ class Facture extends CommonInvoice
|
|||
'multicurrency_total_ttc' => array('type' => 'double(24,8)', 'label' => 'MulticurrencyAmountTTC', 'enabled' => 'isModEnabled("multicurrency")', 'visible' => -1, 'position' => 292, 'isameasure' => 1),
|
||||
'fk_fac_rec_source' => array('type' => 'integer', 'label' => 'RecurringInvoiceSource', 'enabled' => 1, 'visible' => -1, 'position' => 305),
|
||||
'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'visible' => -1, 'position' => 310),
|
||||
'module_source' => array('type' => 'varchar(32)', 'label' => 'POSModule', 'enabled' => "(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))", 'visible' => -1, 'position' => 315),
|
||||
'pos_source' => array('type' => 'varchar(32)', 'label' => 'POSTerminal', 'enabled' => "(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))", 'visible' => -1, 'position' => 320),
|
||||
'module_source' => array('type' => 'varchar(32)', 'label' => 'POSModule', 'langfile' => 'cashdesk', 'enabled' => "(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))", 'visible' => -1, 'position' => 315),
|
||||
'pos_source' => array('type' => 'varchar(32)', 'label' => 'POSTerminal', 'langfile' => 'cashdesk', 'enabled' => "(isModEnabled('cashdesk') || isModEnabled('takepos') || getDolGlobalInt('INVOICE_SHOW_POS'))", 'visible' => -1, 'position' => 320),
|
||||
'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 500),
|
||||
'tms' => array('type' => 'timestamp', 'label' => 'DateModificationShort', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 502),
|
||||
'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -1, 'position' => 506),
|
||||
|
|
@ -449,14 +450,6 @@ class Facture extends CommonInvoice
|
|||
*/
|
||||
const STATUS_ABANDONED = 3;
|
||||
|
||||
const CLOSECODE_DISCOUNTVAT = 'discount_vat'; // Abandoned remain - escompte
|
||||
const CLOSECODE_BADDEBT = 'badcustomer'; // Abandoned remain - bad customer
|
||||
const CLOSECODE_BANKCHARGE = 'bankcharge'; // Abandoned remain - bank charge
|
||||
const CLOSECODE_OTHER = 'other'; // Abandoned remain - other
|
||||
|
||||
const CLOSECODE_ABANDONED = 'abandon'; // Abandoned - other
|
||||
const CLOSECODE_REPLACED = 'replaced'; // Closed after doing a replacement invoice
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
@ -1490,6 +1483,7 @@ class Facture extends CommonInvoice
|
|||
$this->pos_source = $object->pos_source;
|
||||
|
||||
$this->origin = $object->element;
|
||||
$this->origin_type = $object->element;
|
||||
$this->origin_id = $object->id;
|
||||
|
||||
$this->fk_user_author = $user->id;
|
||||
|
|
@ -2175,10 +2169,36 @@ class Facture extends CommonInvoice
|
|||
*/
|
||||
public function fetch($rowid, $ref = '', $ref_ext = '', $notused = 0, $fetch_situation = false)
|
||||
{
|
||||
global $conf, $extrafields;
|
||||
|
||||
if (empty($rowid) && empty($ref) && empty($ref_ext)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$extraFieldsCheck = false;
|
||||
$doFetchInOneSqlRequest = getDolGlobalInt('MAIN_DO_FETCH_IN_ONE_SQL_REQUEST');
|
||||
|
||||
if ($doFetchInOneSqlRequest) {
|
||||
// If $extrafields is not a known object, we initialize it
|
||||
if (!isset($extrafields) || !is_object($extrafields)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
|
||||
$extrafields = new ExtraFields($this->db);
|
||||
}
|
||||
|
||||
// Load array of extrafields for elementype = $this->table_element
|
||||
if (empty($extrafields->attributes[$this->table_element]['loaded'])) {
|
||||
$extrafields->fetch_name_optionals_label($this->table_element);
|
||||
}
|
||||
|
||||
$extraFieldsCheck = (
|
||||
!empty($extrafields->attributes[$this->table_element]['label'])
|
||||
&& is_array($extrafields->attributes[$this->table_element]['label'])
|
||||
&& count($extrafields->attributes[$this->table_element]['label']) > 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Original SQL query from fetch()
|
||||
$sql = 'SELECT f.rowid, f.entity, f.ref, f.ref_client, f.ref_ext, f.type, f.subtype, f.fk_soc';
|
||||
$sql .= ', f.total_tva, f.localtax1, f.localtax2, f.total_ht, f.total_ttc, f.revenuestamp';
|
||||
$sql .= ', f.datef as df, f.date_pointoftax';
|
||||
|
|
@ -2198,10 +2218,34 @@ class Facture extends CommonInvoice
|
|||
$sql .= ', f.module_source, f.pos_source';
|
||||
$sql .= ", i.libelle as label_incoterms";
|
||||
$sql .= ", f.retained_warranty as retained_warranty, f.retained_warranty_date_limit as retained_warranty_date_limit, f.retained_warranty_fk_cond_reglement as retained_warranty_fk_cond_reglement";
|
||||
$sql .= ' FROM '.MAIN_DB_PREFIX.'facture as f';
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON f.fk_mode_reglement = p.id';
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON f.fk_incoterms = i.rowid';
|
||||
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
|
||||
$type = !empty($extrafields->attributes[$this->table_element]['type'][$key])
|
||||
? $extrafields->attributes[$this->table_element]['type'][$key]
|
||||
: '';
|
||||
|
||||
if ($type !== 'separate') {
|
||||
if (in_array($type, array('point','multipts','linestrg','polygon'))) {
|
||||
$sql .= ", ST_AsWKT(ef.".$key.") as ".$key;
|
||||
} else {
|
||||
$sql .= ", ef.".$key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql .= ' FROM '.$this->db->prefix().'facture as f';
|
||||
|
||||
// Add extrafields table to the join if we have extrafields for this entity
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
// Add LEFT JOIN for extrafields
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().$this->table_element.'_extrafields as ef ON f.rowid = ef.fk_object';
|
||||
}
|
||||
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().'c_payment_term as c ON f.fk_cond_reglement = c.rowid';
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().'c_paiement as p ON f.fk_mode_reglement = p.id';
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().'c_incoterms as i ON f.fk_incoterms = i.rowid';
|
||||
|
||||
if ($rowid) {
|
||||
$sql .= " WHERE f.rowid = ".((int) $rowid);
|
||||
|
|
@ -2302,13 +2346,53 @@ class Facture extends CommonInvoice
|
|||
$this->multicurrency_total_tva = $obj->multicurrency_total_tva;
|
||||
$this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
|
||||
|
||||
// Now process extrafields
|
||||
$this->array_options = array();
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
|
||||
$type = !empty($extrafields->attributes[$this->table_element]['type'][$key])
|
||||
? $extrafields->attributes[$this->table_element]['type'][$key]
|
||||
: '';
|
||||
|
||||
if ($type !== 'separate') {
|
||||
$rawval = $obj->$key;
|
||||
|
||||
// date/datetime
|
||||
if (in_array($type, array('date', 'datetime'))) {
|
||||
$this->array_options['options_' . $key] = $this->db->jdate($rawval);
|
||||
} elseif ($type == 'password') {
|
||||
if (!empty($rawval) && preg_match('/^dolcrypt:/', $rawval)) {
|
||||
$this->array_options['options_' . $key] = dolDecrypt($rawval);
|
||||
} else {
|
||||
$this->array_options['options_' . $key] = $rawval;
|
||||
}
|
||||
} else {
|
||||
$this->array_options['options_' . $key] = $rawval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Champs "computed"
|
||||
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
|
||||
if (!empty($extrafields->attributes[$this->table_element]['computed'][$key])) {
|
||||
if (empty($conf->disable_compute)) {
|
||||
global $objectoffield;
|
||||
$objectoffield = $this;
|
||||
$this->array_options['options_' . $key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, '2');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (($this->type == self::TYPE_SITUATION || ($this->type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation) {
|
||||
$this->fetchPreviousNextSituationInvoice();
|
||||
}
|
||||
|
||||
// Retrieve all extrafield
|
||||
// fetch optionals attributes and labels
|
||||
$this->fetch_optionals();
|
||||
if (!$doFetchInOneSqlRequest) {
|
||||
// Retrieve all extrafield
|
||||
// fetch optionals attributes and labels
|
||||
$this->fetch_optionals();
|
||||
}
|
||||
|
||||
// Lines
|
||||
$this->lines = array();
|
||||
|
|
@ -2346,9 +2430,33 @@ class Facture extends CommonInvoice
|
|||
*/
|
||||
public function fetch_lines($only_product = 0, $loadalsotranslation = 0)
|
||||
{
|
||||
global $conf, $extrafields;
|
||||
|
||||
// phpcs:enable
|
||||
$this->lines = array();
|
||||
|
||||
$extraFieldsCheck = false;
|
||||
$doFetchInOneSqlRequest = getDolGlobalInt('MAIN_DO_FETCH_IN_ONE_SQL_REQUEST');
|
||||
|
||||
if ($doFetchInOneSqlRequest) {
|
||||
// If $extrafields is not a known object, we initialize it
|
||||
if (!isset($extrafields) || !is_object($extrafields)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
|
||||
$extrafields = new ExtraFields($this->db);
|
||||
}
|
||||
|
||||
// Load array of extrafields for elementype = $this->table_element_line
|
||||
if (empty($extrafields->attributes[$this->table_element_line]['loaded'])) {
|
||||
$extrafields->fetch_name_optionals_label($this->table_element_line);
|
||||
}
|
||||
|
||||
$extraFieldsCheck = (
|
||||
!empty($extrafields->attributes[$this->table_element_line]['label'])
|
||||
&& is_array($extrafields->attributes[$this->table_element_line]['label'])
|
||||
&& count($extrafields->attributes[$this->table_element_line]['label']) > 0
|
||||
);
|
||||
}
|
||||
|
||||
$sql = 'SELECT l.rowid, l.fk_facture, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,';
|
||||
$sql .= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.remise_percent, l.fk_remise_except, l.subprice, l.ref_ext,';
|
||||
$sql .= ' l.situation_percent, l.fk_prev_id,';
|
||||
|
|
@ -2358,8 +2466,32 @@ class Facture extends CommonInvoice
|
|||
$sql .= ' l.fk_unit, l.extraparams,';
|
||||
$sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
|
||||
$sql .= ' p.ref as product_ref, p.fk_product_type as fk_product_type, p.label as product_label, p.description as product_desc, p.barcode as product_barcode';
|
||||
$sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as l';
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid';
|
||||
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
foreach ($extrafields->attributes[$this->table_element_line]['label'] as $key => $val) {
|
||||
$type = !empty($extrafields->attributes[$this->table_element_line]['type'][$key])
|
||||
? $extrafields->attributes[$this->table_element_line]['type'][$key]
|
||||
: '';
|
||||
|
||||
if ($type !== 'separate') {
|
||||
if (in_array($type, array('point','multipts','linestrg','polygon'))) {
|
||||
$sql .= ", ST_AsWKT(ef.".$key.") as ".$key;
|
||||
} else {
|
||||
$sql .= ", ef.".$key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql .= ' FROM '.$this->db->prefix().'facturedet as l';
|
||||
|
||||
// Add extrafields table to the join if we have extrafields for this entity
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
// Add LEFT JOIN for extrafields
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().$this->table_element_line.'_extrafields as ef ON l.rowid = ef.fk_object';
|
||||
}
|
||||
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().'product as p ON l.fk_product = p.rowid';
|
||||
$sql .= ' WHERE l.fk_facture = '.((int) $this->id);
|
||||
$sql .= ' ORDER BY l.rang, l.rowid';
|
||||
|
||||
|
|
@ -2436,7 +2568,47 @@ class Facture extends CommonInvoice
|
|||
$line->multicurrency_total_tva = $objp->multicurrency_total_tva;
|
||||
$line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
|
||||
|
||||
$line->fetch_optionals();
|
||||
$this->array_options = array();
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
foreach ($extrafields->attributes[$this->table_element_line]['label'] as $key => $val) {
|
||||
$type = !empty($extrafields->attributes[$this->table_element_line]['type'][$key])
|
||||
? $extrafields->attributes[$this->table_element_line]['type'][$key]
|
||||
: '';
|
||||
|
||||
if ($type !== 'separate') {
|
||||
$rawval = $objp->$key;
|
||||
|
||||
// date/datetime
|
||||
if (in_array($type, array('date', 'datetime'))) {
|
||||
$this->array_options['options_' . $key] = $this->db->jdate($rawval);
|
||||
} elseif ($type == 'password') {
|
||||
if (!empty($rawval) && preg_match('/^dolcrypt:/', $rawval)) {
|
||||
$this->array_options['options_' . $key] = dolDecrypt($rawval);
|
||||
} else {
|
||||
$this->array_options['options_' . $key] = $rawval;
|
||||
}
|
||||
} else {
|
||||
$this->array_options['options_' . $key] = $rawval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Champs "computed"
|
||||
foreach ($extrafields->attributes[$this->table_element_line]['label'] as $key => $val) {
|
||||
if (!empty($extrafields->attributes[$this->table_element_line]['computed'][$key])) {
|
||||
if (empty($conf->disable_compute)) {
|
||||
global $objectoffield;
|
||||
$objectoffield = $this;
|
||||
$this->array_options['options_' . $key] = dol_eval($extrafields->attributes[$this->table_element_line]['computed'][$key], 1, 0, '2');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$doFetchInOneSqlRequest) {
|
||||
// Retrieve all extrafield
|
||||
$this->fetch_optionals();
|
||||
}
|
||||
|
||||
// multilangs
|
||||
if (getDolGlobalInt('MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
|
||||
|
|
@ -3037,7 +3209,7 @@ class Facture extends CommonInvoice
|
|||
{
|
||||
$error = 0;
|
||||
|
||||
if ($this->paye != 1) {
|
||||
if ($this->paye != 1 || $this->status != self::STATUS_CLOSED) {
|
||||
$this->db->begin();
|
||||
|
||||
$now = dol_now();
|
||||
|
|
@ -3045,15 +3217,15 @@ class Facture extends CommonInvoice
|
|||
dol_syslog(get_class($this)."::setPaid rowid=".((int) $this->id), LOG_DEBUG);
|
||||
|
||||
$sql = 'UPDATE '.MAIN_DB_PREFIX.'facture SET';
|
||||
$sql .= ' fk_statut='.self::STATUS_CLOSED;
|
||||
$sql .= ' fk_statut = '.self::STATUS_CLOSED;
|
||||
if (!$close_code) {
|
||||
$sql .= ', paye=1';
|
||||
$sql .= ', paye = 1';
|
||||
}
|
||||
if ($close_code) {
|
||||
$sql .= ", close_code='".$this->db->escape($close_code)."'";
|
||||
$sql .= ", close_code = '".$this->db->escape($close_code)."'";
|
||||
}
|
||||
if ($close_note) {
|
||||
$sql .= ", close_note='".$this->db->escape($close_note)."'";
|
||||
$sql .= ", close_note = '".$this->db->escape($close_note)."'";
|
||||
}
|
||||
$sql .= ', fk_user_closing = '.((int) $user->id);
|
||||
$sql .= ", date_closing = '".$this->db->idate($now)."'";
|
||||
|
|
@ -3073,6 +3245,8 @@ class Facture extends CommonInvoice
|
|||
}
|
||||
|
||||
if (!$error) {
|
||||
$this->paye = 1;
|
||||
$this->status = self::STATUS_CLOSED;
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
} else {
|
||||
|
|
@ -3873,8 +4047,8 @@ class Facture extends CommonInvoice
|
|||
* @param string $origin Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be 'orderdet', 'propaldet'..., else 'order','propal,'....
|
||||
* @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id
|
||||
* @param int $fk_parent_line Id of parent line
|
||||
* @param int $fk_fournprice Supplier price id (to calculate margin) or ''
|
||||
* @param float|'' $pa_ht Buying price of line (to calculate margin) or ''
|
||||
* @param int|string $fk_fournprice Supplier price id (to calculate margin) or a string
|
||||
* @param float|'' $pa_ht Buying price of line (to calculate margin) (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param string $label Label of the line (deprecated, do not use)
|
||||
* @param array<string,mixed> $array_options extrafields array
|
||||
* @param float $situation_percent Situation advance percentage
|
||||
|
|
@ -4196,7 +4370,7 @@ class Facture extends CommonInvoice
|
|||
* @param int $fk_parent_line Id of parent line (0 in most cases, used by modules adding sublevels into lines).
|
||||
* @param int $skip_update_total Keep fields total_xxx to 0 (used for special lines by some modules)
|
||||
* @param int $fk_fournprice Id of origin supplier price
|
||||
* @param float $pa_ht Price (without tax) of product when it was bought
|
||||
* @param float|string $pa_ht Price (without tax) of product when it was bought (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param string $label Label of the line (deprecated, do not use)
|
||||
* @param int $special_code Special code (also used by externals modules!)
|
||||
* @param array<string,mixed> $array_options extrafields array
|
||||
|
|
|
|||
|
|
@ -204,6 +204,30 @@ class FactureLigne extends CommonInvoiceLine
|
|||
*/
|
||||
public function fetch($rowid)
|
||||
{
|
||||
global $conf, $extrafields;
|
||||
|
||||
$extraFieldsCheck = false;
|
||||
$doFetchInOneSqlRequest = getDolGlobalInt('MAIN_DO_FETCH_IN_ONE_SQL_REQUEST');
|
||||
|
||||
if ($doFetchInOneSqlRequest) {
|
||||
// If $extrafields is not a known object, we initialize it
|
||||
if (!isset($extrafields) || !is_object($extrafields)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
|
||||
$extrafields = new ExtraFields($this->db);
|
||||
}
|
||||
|
||||
// Load array of extrafields for elementype = $this->table_element
|
||||
if (empty($extrafields->attributes[$this->table_element]['loaded'])) {
|
||||
$extrafields->fetch_name_optionals_label($this->table_element);
|
||||
}
|
||||
|
||||
$extraFieldsCheck = (
|
||||
!empty($extrafields->attributes[$this->table_element]['label'])
|
||||
&& is_array($extrafields->attributes[$this->table_element]['label'])
|
||||
&& count($extrafields->attributes[$this->table_element]['label']) > 0
|
||||
);
|
||||
}
|
||||
|
||||
$sql = 'SELECT fd.rowid, fd.fk_facture, fd.fk_parent_line, fd.fk_product, fd.product_type, fd.label as custom_label, fd.description, fd.price, fd.qty, fd.vat_src_code, fd.tva_tx,';
|
||||
$sql .= ' fd.localtax1_tx, fd. localtax2_tx, fd.remise, fd.remise_percent, fd.fk_remise_except, fd.subprice, fd.ref_ext,';
|
||||
$sql .= ' fd.date_start as date_start, fd.date_end as date_end, fd.fk_product_fournisseur_price as fk_fournprice, fd.buy_price_ht as pa_ht,';
|
||||
|
|
@ -218,8 +242,31 @@ class FactureLigne extends CommonInvoiceLine
|
|||
$sql .= ' fd.multicurrency_total_ttc,';
|
||||
$sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
|
||||
$sql .= ' p.packaging';
|
||||
$sql .= ' FROM '.MAIN_DB_PREFIX.'facturedet as fd';
|
||||
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON fd.fk_product = p.rowid';
|
||||
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
|
||||
$type = !empty($extrafields->attributes[$this->table_element]['type'][$key])
|
||||
? $extrafields->attributes[$this->table_element]['type'][$key]
|
||||
: '';
|
||||
|
||||
if ($type !== 'separate') {
|
||||
if (in_array($type, array('point','multipts','linestrg','polygon'))) {
|
||||
$sql .= ", ST_AsWKT(ef.".$key.") as ".$key;
|
||||
} else {
|
||||
$sql .= ", ef.".$key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sql .= ' FROM '.$this->db->prefix().'facturedet as fd';
|
||||
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
// Add LEFT JOIN for extrafields
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().$this->table_element.'_extrafields as ef ON fd.rowid = ef.fk_object';
|
||||
}
|
||||
|
||||
$sql .= ' LEFT JOIN '.$this->db->prefix().'product as p ON fd.fk_product = p.rowid';
|
||||
$sql .= ' WHERE fd.rowid = '.((int) $rowid);
|
||||
|
||||
$result = $this->db->query($sql);
|
||||
|
|
@ -290,7 +337,47 @@ class FactureLigne extends CommonInvoiceLine
|
|||
|
||||
$this->packaging = $objp->packaging;
|
||||
|
||||
$this->fetch_optionals();
|
||||
$this->array_options = array();
|
||||
if ($doFetchInOneSqlRequest && $extraFieldsCheck) {
|
||||
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
|
||||
$type = !empty($extrafields->attributes[$this->table_element]['type'][$key])
|
||||
? $extrafields->attributes[$this->table_element]['type'][$key]
|
||||
: '';
|
||||
|
||||
if ($type !== 'separate') {
|
||||
$rawval = $objp->$key;
|
||||
|
||||
// date/datetime
|
||||
if (in_array($type, array('date', 'datetime'))) {
|
||||
$this->array_options['options_' . $key] = $this->db->jdate($rawval);
|
||||
} elseif ($type == 'password') {
|
||||
if (!empty($rawval) && preg_match('/^dolcrypt:/', $rawval)) {
|
||||
$this->array_options['options_' . $key] = dolDecrypt($rawval);
|
||||
} else {
|
||||
$this->array_options['options_' . $key] = $rawval;
|
||||
}
|
||||
} else {
|
||||
$this->array_options['options_' . $key] = $rawval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Champs "computed"
|
||||
foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) {
|
||||
if (!empty($extrafields->attributes[$this->table_element]['computed'][$key])) {
|
||||
if (empty($conf->disable_compute)) {
|
||||
global $objectoffield;
|
||||
$objectoffield = $this;
|
||||
$this->array_options['options_' . $key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, '2');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$doFetchInOneSqlRequest) {
|
||||
// Retrieve all extrafield
|
||||
$this->fetch_optionals();
|
||||
}
|
||||
|
||||
$this->db->free($result);
|
||||
|
||||
|
|
|
|||
|
|
@ -263,9 +263,9 @@ $arrayfields = array(
|
|||
'multicurrency_dynamount_payed' => array('label' => 'MulticurrencyAlreadyPaid', 'checked' => '0', 'enabled' => (!isModEnabled('multicurrency') ? '0' : '1'), 'position' => 295),
|
||||
'multicurrency_rtp' => array('label' => 'MulticurrencyRemainderToPay', 'checked' => '0', 'enabled' => (!isModEnabled('multicurrency') ? '0' : '1'), 'position' => 296), // Not enabled by default because slow
|
||||
'total_pa' => array('label' => ((getDolGlobalString('MARGIN_TYPE') == '1') ? 'BuyingPrice' : 'CostPrice'), 'checked' => '0', 'position' => 300, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') ? '0' : '1')),
|
||||
'total_margin' => array('label' => 'Margin', 'checked' => '0', 'position' => 301, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') ? '0' : '1')),
|
||||
'total_margin_rate' => array('label' => 'MarginRate', 'checked' => '0', 'position' => 302, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') || !getDolGlobalString('DISPLAY_MARGIN_RATES') ? '0' : '1')),
|
||||
'total_mark_rate' => array('label' => 'MarkRate', 'checked' => '0', 'position' => 303, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') || !getDolGlobalString('DISPLAY_MARK_RATES') ? '0' : '1')),
|
||||
'total_margin' => array('label' => 'Margin', 'langfile' => 'margins', 'checked' => '0', 'position' => 301, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') ? '0' : '1')),
|
||||
'total_margin_rate' => array('label' => 'MarginRate', 'langfile' => 'margins', 'checked' => '0', 'position' => 302, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') || !getDolGlobalString('DISPLAY_MARGIN_RATES') ? '0' : '1')),
|
||||
'total_mark_rate' => array('label' => 'MarkRate', 'langfile' => 'margins', 'checked' => '0', 'position' => 303, 'enabled' => (!isModEnabled('margin') || !$user->hasRight('margins', 'liretous') || !getDolGlobalString('DISPLAY_MARK_RATES') ? '0' : '1')),
|
||||
'f.datec' => array('label' => "DateCreation", 'checked' => '0', 'position' => 500),
|
||||
'f.tms' => array('type' => 'timestamp', 'label' => 'DateModificationShort', 'enabled' => '1', 'visible' => -1, 'notnull' => 1, 'position' => 502),
|
||||
'u.login' => array('label' => "UserAuthor", 'checked' => '1', 'visible' => -1, 'position' => 504),
|
||||
|
|
@ -2112,7 +2112,7 @@ if ($num > 0) {
|
|||
$multicurrency_totalpay = $multicurrency_paiement + $multicurrency_totalcreditnotes + $multicurrency_totaldeposits;
|
||||
$multicurrency_remaintopay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_totalpay);
|
||||
|
||||
if ($facturestatic->status == Facture::STATUS_CLOSED && $facturestatic->close_code == 'discount_vat') { // If invoice closed with discount for anticipated payment
|
||||
if ($facturestatic->status == Facture::STATUS_CLOSED) {
|
||||
$remaintopay = 0;
|
||||
$multicurrency_remaintopay = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -594,7 +594,7 @@ if ($id > 0) {
|
|||
print '<table class="border centpercent tableforfield">';
|
||||
|
||||
// Type
|
||||
print '<tr><td class="titlefieldmiddle">';
|
||||
print '<tr><td class="titlefield">';
|
||||
print $langs->trans("Type")."</td><td>";
|
||||
if ($action == 'edit' && $object->getSommePaiement() == 0) {
|
||||
$actionPostValue = GETPOSTINT('actioncode');
|
||||
|
|
@ -639,7 +639,7 @@ if ($id > 0) {
|
|||
|
||||
// Mode of payment
|
||||
print '<tr><td>';
|
||||
print '<table class="nobordernopadding" width="100%"><tr><td>';
|
||||
print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
|
||||
print $langs->trans('DefaultPaymentMode');
|
||||
print '</td>';
|
||||
if ($action != 'editmode') {
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class Contact extends CommonObject
|
|||
'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 65),
|
||||
'fk_departement' => array('type' => 'integer', 'label' => 'Fk departement', 'enabled' => 1, 'visible' => 3, 'position' => 70),
|
||||
'fk_pays' => array('type' => 'integer', 'label' => 'Fk pays', 'enabled' => 1, 'visible' => 3, 'position' => 75),
|
||||
'fk_soc' => array('type' => 'integer', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 77, 'searchall' => 1),
|
||||
'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 1, 'visible' => 1, 'position' => 77, 'searchall' => 1),
|
||||
'birthday' => array('type' => 'date', 'label' => 'Birthday', 'enabled' => 1, 'visible' => -1, 'position' => 80),
|
||||
'phone' => array('type' => 'varchar(30)', 'label' => 'Phone', 'enabled' => 1, 'visible' => 1, 'position' => 90, 'searchall' => 1),
|
||||
'phone_perso' => array('type' => 'varchar(30)', 'label' => 'PhonePerso', 'enabled' => 1, 'visible' => -1, 'position' => 95, 'searchall' => 1),
|
||||
|
|
@ -123,8 +123,8 @@ class Contact extends CommonObject
|
|||
'ip' => array('type' => 'ip', 'label' => 'IPAddress', 'enabled' => '1', 'position' => 700, 'notnull' => 0, 'visible' => '-2', 'comment' => 'ip used to create record (for public submission page)'),
|
||||
'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 300),
|
||||
'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 305),
|
||||
'fk_user_creat' => array('type' => 'integer', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => 3, 'position' => 310),
|
||||
'fk_user_modif' => array('type' => 'integer', 'label' => 'UserModif', 'enabled' => 1, 'visible' => 3, 'position' => 315),
|
||||
'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => 3, 'position' => 310),
|
||||
'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => 3, 'position' => 315),
|
||||
'statut' => array('type' => 'tinyint(4)', 'label' => 'Status', 'enabled' => 1, 'visible' => 1, 'notnull' => 1, 'position' => 500),
|
||||
'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -1, 'position' => 1000),
|
||||
);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1466,7 +1466,7 @@ class Contrat extends CommonObject
|
|||
* @param float $pu_ttc Prix unitaire TTC
|
||||
* @param int $info_bits Bits of type of lines
|
||||
* @param int $fk_fournprice Fourn price id
|
||||
* @param float $pa_ht Buying price HT
|
||||
* @param float|string $pa_ht Buying price HT (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param array<string,mixed> $array_options extrafields array
|
||||
* @param ?int $fk_unit Code of the unit to use. Null to use the default one
|
||||
* @param int $rang Position
|
||||
|
|
@ -1691,7 +1691,7 @@ class Contrat extends CommonObject
|
|||
* @param string $price_base_type HT or TTC
|
||||
* @param int $info_bits Bits of type of lines
|
||||
* @param int $fk_fournprice Fourn price id
|
||||
* @param float $pa_ht Buying price HT
|
||||
* @param float|string $pa_ht Buying price HT (Can be '' to keep AWP unchanged or a float value)
|
||||
* @param array<string,mixed> $array_options extrafields array
|
||||
* @param string $fk_unit Code of the unit to use. Null to use the default one
|
||||
* @param int $rang Position
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class box_graph_product_distribution extends ModeleBoxes
|
|||
if (!isModEnabled('invoice') || !$user->hasRight('facture', 'lire')) {
|
||||
$showinvoicenb = 0;
|
||||
}
|
||||
if (isModEnabled('propal') || !$user->hasRight('propal', 'lire')) {
|
||||
if (!isModEnabled('propal') || !$user->hasRight('propal', 'lire')) {
|
||||
$showpropalnb = 0;
|
||||
}
|
||||
if (!isModEnabled('order') || !$user->hasRight('commande', 'lire')) {
|
||||
|
|
|
|||
|
|
@ -415,10 +415,12 @@ class CMailFile
|
|||
|
||||
// Verify if $to, $addr_cc and addr_bcc have unwanted addresses
|
||||
if (getDolGlobalString('MAIN_MAIL_FORCE_NOT_SENDING_TO')) {
|
||||
// Parse to, cc and bcc to remove MAIN_MAIL_FORCE_NOT_SENDING_TO
|
||||
$listofemailstonotsendto = explode(',', getDolGlobalString('MAIN_MAIL_FORCE_NOT_SENDING_TO'));
|
||||
|
||||
//Verify for $to
|
||||
$replaceto = false;
|
||||
$tabto = explode(",", $to);
|
||||
$listofemailstonotsendto = explode(',', getDolGlobalString('MAIN_MAIL_FORCE_NOT_SENDING_TO'));
|
||||
foreach ($tabto as $key => $addrto) {
|
||||
$addrto = array_keys($this->getArrayAddress($addrto));
|
||||
if (in_array($addrto[0], $listofemailstonotsendto)) {
|
||||
|
|
|
|||
|
|
@ -196,8 +196,8 @@ abstract class CommonInvoice extends CommonObject
|
|||
public $situation_cycle_ref;
|
||||
|
||||
/**
|
||||
* ! Closing after partial payment: discount_vat, badsupplier, abandon
|
||||
* ! Closing when no payment: replaced, abandoned
|
||||
* ! Closing after partial payment: CLOSECODE_DISCOUNTVAT, CLOSECODE_BADDEBT, CLOSECODE_BANKCHARGE, CLOSECODE_OTHER
|
||||
* ! Closing when no payment: CLOSECODE_ABANDONED, CLOSECODE_REPLACED
|
||||
* @var string Close code
|
||||
*/
|
||||
public $close_code;
|
||||
|
|
@ -276,6 +276,15 @@ abstract class CommonInvoice extends CommonObject
|
|||
const STATUS_ABANDONED = 3;
|
||||
|
||||
|
||||
const CLOSECODE_DISCOUNTVAT = 'discount_vat'; // Abandoned remain - escompte
|
||||
const CLOSECODE_BADDEBT = 'badcustomer'; // Abandoned remain - bad customer
|
||||
const CLOSECODE_BANKCHARGE = 'bankcharge'; // Abandoned remain - bank charge
|
||||
const CLOSECODE_WITHHOLDINGTAX = 'withholdingtax'; // Abandoned remain - source tax
|
||||
const CLOSECODE_OTHER = 'other'; // Abandoned remain - other
|
||||
|
||||
const CLOSECODE_ABANDONED = 'abandon'; // Abandoned - other
|
||||
const CLOSECODE_REPLACED = 'replaced'; // Closed after doing a replacement invoice
|
||||
|
||||
|
||||
/**
|
||||
* Return remain amount to pay. Property ->id and ->total_ttc must be set.
|
||||
|
|
@ -918,22 +927,28 @@ abstract class CommonInvoice extends CommonObject
|
|||
*/
|
||||
public function getLibStatut($mode = 0, $alreadypaid = -1)
|
||||
{
|
||||
return $this->LibStatut($this->paye, $this->status, $mode, $alreadypaid, $this->type, $this->nbofopendirectdebitorcredittransfer);
|
||||
$moreparams = array(
|
||||
'nbofopendirectdebitorcredittransfer' => $this->nbofopendirectdebitorcredittransfer,
|
||||
'close_code' => $this->close_code,
|
||||
'close_note' => $this->close_note,
|
||||
);
|
||||
|
||||
return $this->LibStatut($this->paye, $this->status, $mode, $alreadypaid, $this->type, $moreparams);
|
||||
}
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
||||
/**
|
||||
* Return label of a status
|
||||
*
|
||||
* @param int $paye Status field paye (or $recur)
|
||||
* @param int $status Id status
|
||||
* @param int $paye Status field $paye (no more used, replaced with $status) or $recur.
|
||||
* @param int $status ID status
|
||||
* @param int<0,6> $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=short label + picto, 6=long label + picto
|
||||
* @param int|float $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommend to put here float amount paid if you have it, -1 otherwise)
|
||||
* @param int $type Type invoice. If -1, we use $this->type
|
||||
* @param int $nbofopendirectdebitorcredittransfer Nb of open direct debit or credit transfer
|
||||
* @param int|array<string,int|string> $moreparams More params. Example: array('nbofopendirectdebitorcredittransfer' => x) for nb of open direct debit or credit transfer
|
||||
* @return string Label of status
|
||||
*/
|
||||
public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1, $nbofopendirectdebitorcredittransfer = 0)
|
||||
public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1, $moreparams = array())
|
||||
{
|
||||
// phpcs:enable
|
||||
global $langs, $hookmanager;
|
||||
|
|
@ -943,6 +958,18 @@ abstract class CommonInvoice extends CommonObject
|
|||
$type = $this->type;
|
||||
}
|
||||
|
||||
// For backward compatibility
|
||||
if (is_int($moreparams)) {
|
||||
$moreparams = array('nbofopendirectdebitorcredittransfer' => (int) $moreparams);
|
||||
}
|
||||
|
||||
$nbofopendirectdebitorcredittransfer = 0;
|
||||
foreach ($moreparams as $moreparamkey => $moreparamvalue) {
|
||||
if ($moreparamkey == 'nbofopendirectdebitorcredittransfer') {
|
||||
$nbofopendirectdebitorcredittransfer = $moreparamvalue;
|
||||
}
|
||||
}
|
||||
|
||||
$statusType = 'status0';
|
||||
$prefix = 'Short';
|
||||
if (!$paye) {
|
||||
|
|
@ -1000,7 +1027,28 @@ abstract class CommonInvoice extends CommonObject
|
|||
return $hookmanager->resPrint;
|
||||
}
|
||||
|
||||
return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
|
||||
if ($moreparams['close_code']) {
|
||||
$titlestringtoshow = '';
|
||||
|
||||
if ($moreparams['close_code'] == self::CLOSECODE_DISCOUNTVAT) {
|
||||
$titlestringtoshow = $langs->trans("HelpEscompte");
|
||||
} elseif ($moreparams['close_code'] == self::CLOSECODE_BADDEBT) {
|
||||
$titlestringtoshow = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomer");
|
||||
} elseif ($moreparams['close_code'] == self::CLOSECODE_BANKCHARGE) {
|
||||
$titlestringtoshow = $langs->trans("ConfirmClassifyPaidPartiallyReasonBankCharge");
|
||||
} elseif ($moreparams['close_code'] == self::CLOSECODE_WITHHOLDINGTAX) {
|
||||
$titlestringtoshow = $langs->trans("ConfirmClassifyPaidPartiallyReasonWithholdingTax");
|
||||
} elseif ($moreparams['close_code'] == self::CLOSECODE_OTHER) {
|
||||
$titlestringtoshow = $langs->trans("Other");
|
||||
}
|
||||
|
||||
//$paramsbutton = array('badgeParams' => array('attr' => array('title' => 'rrrr')));
|
||||
$paramsbutton = array('badgeParams' => array('attr' => array('title' => $titlestringtoshow)));
|
||||
} else {
|
||||
$paramsbutton = array();
|
||||
}
|
||||
|
||||
return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode, '', $paramsbutton);
|
||||
}
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
||||
|
|
|
|||
|
|
@ -905,7 +905,7 @@ abstract class CommonObject
|
|||
{
|
||||
global $db, $conf;
|
||||
|
||||
$sql = "SELECT rowid, ref, ref_ext";
|
||||
$sql = "SELECT rowid";
|
||||
$sql .= " FROM ".$db->prefix().$element;
|
||||
$sql .= " WHERE entity IN (".getEntity($element).")";
|
||||
|
||||
|
|
@ -1240,7 +1240,6 @@ abstract class CommonObject
|
|||
// phpcs:enable
|
||||
global $user, $langs;
|
||||
|
||||
|
||||
dol_syslog(get_class($this)."::add_contact $fk_socpeople, $type_contact, $source, $notrigger");
|
||||
|
||||
// Check parameters
|
||||
|
|
@ -1257,20 +1256,20 @@ abstract class CommonObject
|
|||
return -2;
|
||||
}
|
||||
|
||||
if ($this->restrictiononfksoc && ! $user->hasRight('societe', 'client', 'voir')) {
|
||||
$sql_allowed_contacts = 'SELECT COUNT(*) as cnt FROM '.$this->db->prefix().'societe_commerciaux sc';
|
||||
$sql_allowed_contacts.= ' INNER JOIN '.$this->db->prefix().'societe s ON s.rowid = sc.fk_soc';
|
||||
$sql_allowed_contacts.= ' LEFT JOIN '.$this->db->prefix().'socpeople sp ON sp.fk_soc = sc.fk_soc';
|
||||
$sql_allowed_contacts.= ' WHERE sp.rowid = '.(int) $fk_socpeople;
|
||||
if ($this->restrictiononfksoc && property_exists('socid', $this) && !empty($this->socid) && !$user->hasRight('societe', 'client', 'voir')) {
|
||||
$sql_allowed_contacts = 'SELECT COUNT(*) as cnt FROM '.$this->db->prefix().'societe_commerciaux as sc';
|
||||
$sql_allowed_contacts.= ' WHERE sc.fk_soc = '.(int) $this->socid;
|
||||
$sql_allowed_contacts.= ' AND sc.fk_user = '.(int) $user->id;
|
||||
|
||||
$resql_allowed_contacts = $this->db->query($sql_allowed_contacts);
|
||||
|
||||
if (!$resql_allowed_contacts) {
|
||||
$this->errors[] = $this->db->lasterror();
|
||||
return -3;
|
||||
} elseif ($obj = $this->db->fetch_object($resql_allowed_contacts)) {
|
||||
if ($obj->cnt == 0) {
|
||||
$langs->load("companies");
|
||||
$this->error = $langs->trans("ErrorCommercialNotAllowedForThirdparty");
|
||||
$this->error = $langs->trans("ErrorCommercialNotAllowedForThirdparty", $user->admin);
|
||||
dol_syslog(get_class($this)."::add_contact ".$this->error, LOG_ERR);
|
||||
return -3;
|
||||
}
|
||||
|
|
@ -6318,6 +6317,7 @@ abstract class CommonObject
|
|||
/**
|
||||
* Function to get alternative languages of a data into $this->array_languages
|
||||
* This method is NOT called by method fetch of objects but must be called separately.
|
||||
* Used for example when PDF_USE_ALSO_LANGUAGE_CODE is set to a language for the name of a thirdparty.
|
||||
*
|
||||
* @return int<-1,1> Return integer <0 if error, 0 if no values of alternative languages to find nor found, 1 if a value was found and loaded
|
||||
* @see fetch_optionnals()
|
||||
|
|
@ -6387,6 +6387,7 @@ abstract class CommonObject
|
|||
|
||||
/**
|
||||
* Fill array_options property of object by extrafields value (using for data sent by forms)
|
||||
* Used for example when PDF_USE_ALSO_LANGUAGE_CODE is set to a language for the name of a thirdparty.
|
||||
*
|
||||
* @param string $onlykey Only the following key is filled. When we make update of only one language field ($action = 'update_languages'), calling page must set this to avoid to have other languages being reset.
|
||||
* @return int<-1,1> 1 if array_options set, 0 if no value, -1 if error (field required missing for example)
|
||||
|
|
@ -7028,9 +7029,10 @@ abstract class CommonObject
|
|||
}
|
||||
|
||||
/**
|
||||
* Add/Update all extra fields values for the current object.
|
||||
* Data to describe values to insert/update are stored into $this->array_options=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...)
|
||||
* This function delete record with all extrafields and insert them again from the array $this->array_options.
|
||||
* Add/Update all extra languages values for the current object.
|
||||
* Data to describe values to insert/update are stored into $this->array_languages=array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...)
|
||||
* This function delete record with all languages and insert them again from the array $this->array_languages.
|
||||
* Used for example when PDF_USE_ALSO_LANGUAGE_CODE is set to a language for the name of a thirdparty.
|
||||
*
|
||||
* @param string $trigger If defined, call also the trigger (for example COMPANY_MODIFY)
|
||||
* @param User $userused Object user
|
||||
|
|
|
|||
|
|
@ -995,6 +995,10 @@ class Conf extends stdClass
|
|||
if (!isset($this->global->MAIN_HTML_TITLE)) {
|
||||
$this->global->MAIN_HTML_TITLE = 'thirdpartynameonly,contactnameonly,projectnameonly';
|
||||
}
|
||||
// MAIN_FEATURE_TO_SHOW_TOP_MENU_URL_IN_FRAME
|
||||
if (!isset($this->global->MAIN_FEATURE_TO_SHOW_TOP_MENU_URL_IN_FRAME)) {
|
||||
$this->global->MAIN_FEATURE_TO_SHOW_TOP_MENU_URL_IN_FRAME = 1;
|
||||
}
|
||||
|
||||
// conf->liste_limit = constant to limit size of lists
|
||||
// This value can be overwritten by user choice in main.inc.php
|
||||
|
|
@ -1211,6 +1215,13 @@ class Conf extends stdClass
|
|||
$this->propal->cloture->warning_delay = getDolGlobalInt('MAIN_DELAY_PROPALS_TO_CLOSE') * 86400;
|
||||
$this->propal->facturation->warning_delay = getDolGlobalInt('MAIN_DELAY_PROPALS_TO_BILL') * 86400;
|
||||
}
|
||||
// @phpstan-ignore-next-line
|
||||
if (isset($this->supplier_proposal)) {
|
||||
$this->supplier_proposal->cloture = new stdClass();
|
||||
$this->supplier_proposal->facturation = new stdClass();
|
||||
$this->supplier_proposal->cloture->warning_delay = getDolGlobalInt('MAIN_DELAY_SUPPLIER_PROPALS_TO_CLOSE') * 86400;
|
||||
$this->supplier_proposal->facturation->warning_delay = getDolGlobalInt('MAIN_DELAY_SUPPLIER_PROPALS_TO_BILL') * 86400;
|
||||
}
|
||||
if (isset($this->facture)) {
|
||||
$this->facture->client = new stdClass();
|
||||
$this->facture->fournisseur = new stdClass();
|
||||
|
|
|
|||
|
|
@ -999,7 +999,7 @@ class ExtraFields
|
|||
$elementtype = 'commande_fournisseur';
|
||||
}
|
||||
|
||||
if ($elementtype != 'all' && isset($this->attributes[$elementtype]) && $this->attributes[$elementtype]['loaded'] == 1 && !$forceload) {
|
||||
if ($elementtype != 'all' && isset($this->attributes[$elementtype]) && $this->attributes[$elementtype]['loaded'] == 1 && !$forceload && isset($this->attributes[$elementtype]['label'])) {
|
||||
return $this->attributes[$elementtype]['label'];
|
||||
}
|
||||
|
||||
|
|
@ -2726,7 +2726,7 @@ class ExtraFields
|
|||
$value_key = dol_mktime(GETPOSTINT("options_".$key."hour"), GETPOSTINT("options_".$key."min"), GETPOSTINT("options_".$key."sec"), GETPOSTINT("options_".$key."month"), GETPOSTINT("options_".$key."day"), GETPOSTINT("options_".$key."year"), 'gmt');
|
||||
} elseif (in_array($key_type, array('duration'))) {
|
||||
$value_hours = GETPOSTINT("options_" . $key . "hour");
|
||||
$value_minutes = GETPOSTINT("options_" . $key . "minute");
|
||||
$value_minutes = GETPOSTINT("options_" . $key . "min");
|
||||
$value_key = $value_hours * 3600 + $value_minutes * 60;
|
||||
} elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) {
|
||||
$value_arr = GETPOST("options_".$key, 'array'); // check if an array
|
||||
|
|
|
|||
|
|
@ -5819,7 +5819,7 @@ class Form
|
|||
$moreattr = (!empty($input['moreattr']) ? ' ' . $input['moreattr'] : '');
|
||||
$morecss = (!empty($input['morecss']) ? ' ' . $input['morecss'] : '');
|
||||
|
||||
if ($input['type'] == 'text') {
|
||||
if ($input['type'] == 'text' || $input['type'] == 'input') { // traditional input
|
||||
$more .= '<div class="tagtr"><div class="tagtd' . (empty($input['tdclass']) ? '' : (' ' . $input['tdclass'])) . '">' . $input['label'] . '</div><div class="tagtd"><input type="text" class="flat' . $morecss . '" id="' . dol_escape_htmltag($input['name']) . '" name="' . dol_escape_htmltag($input['name']) . '"' . $size . ' value="' . (empty($input['value']) ? '' : $input['value']) . '"' . $moreattr . ' /></div></div>' . "\n";
|
||||
} elseif ($input['type'] == 'password') {
|
||||
$more .= '<div class="tagtr"><div class="tagtd' . (empty($input['tdclass']) ? '' : (' ' . $input['tdclass'])) . '">' . $input['label'] . '</div><div class="tagtd"><input type="password" class="flat' . $morecss . '" id="' . dol_escape_htmltag($input['name']) . '" name="' . dol_escape_htmltag($input['name']) . '"' . $size . ' value="' . (empty($input['value']) ? '' : $input['value']) . '"' . $moreattr . ' /></div></div>' . "\n";
|
||||
|
|
@ -10476,7 +10476,7 @@ class Form
|
|||
$morehtmlstatus = $hookmanager->resPrint;
|
||||
}
|
||||
if ($morehtmlstatus) {
|
||||
$ret .= '<div class="statusref">' . $morehtmlstatus . '</div>';
|
||||
$ret .= '<!-- status --><div class="statusref">' . $morehtmlstatus . '</div>';
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
|
|
@ -10497,7 +10497,7 @@ class Form
|
|||
}
|
||||
|
||||
//if ($conf->browser->layout == 'phone') $ret.='<div class="clearboth"></div>';
|
||||
$ret .= '<div class="inline-block floatleft valignmiddle maxwidth750 marginbottomonly refid' . (($shownav && ($previous_ref || $next_ref)) ? ' refidpadding' : '') . '">';
|
||||
$ret .= '<!-- Ref or ID --><div class="inline-block floatleft valignmiddle maxwidth750 marginbottomonly refid' . (($shownav && ($previous_ref || $next_ref)) ? ' refidpadding' : '') . '">';
|
||||
|
||||
// For thirdparty, contact, user, member, the ref is the id, so we show something else
|
||||
if ($object->element == 'societe') {
|
||||
|
|
@ -10553,6 +10553,8 @@ class Form
|
|||
$ret .= $object->label;
|
||||
} elseif ($object->element == 'ecm_directories') {
|
||||
$ret .= '';
|
||||
} elseif ($object->element == 'accountingbookkeeping' && !empty($object->context['mode']) && $object->context['mode'] == '_tmp') {
|
||||
$ret .= $langs->trans("Draft");
|
||||
} elseif ($fieldref != 'none') {
|
||||
$ret .= dol_htmlentities(!empty($object->$fieldref) ? $object->$fieldref : "");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ class FormAdmin
|
|||
ksort($menuarray);
|
||||
|
||||
// Show combo list of menu handlers
|
||||
print '<select class="flat maxwidth150" id="'.$htmlname.'" name="'.$htmlname.'">';
|
||||
print '<select class="flat width150" id="'.$htmlname.'" name="'.$htmlname.'">';
|
||||
foreach ($menuarray as $key => $val) {
|
||||
$tab = explode('_', $key);
|
||||
print '<option value="'.$key.'"';
|
||||
|
|
|
|||
|
|
@ -91,14 +91,15 @@ class FormAI extends Form
|
|||
}
|
||||
|
||||
/**
|
||||
* Return Html code for AI instructions of message and autofill result
|
||||
* Return Html code for AI instructions of message and autofill result.
|
||||
*
|
||||
* @param string $function Function ('textgenerationmail', 'textgenerationwebpage', ...)
|
||||
* @param string $format Format for output ('', 'html', ...)
|
||||
* @param string $htmlContent HTML name of WYSIWYG field
|
||||
* @return string HTML code to ask AI instructions 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 '')
|
||||
* @return string HTML code to ask AI instructions and autofill result
|
||||
*/
|
||||
public function getSectionForAIEnhancement($function = 'textgeneration', $format = '', $htmlContent = 'message')
|
||||
public function getSectionForAIEnhancement($function = 'textgeneration', $format = '', $htmlContent = 'message', $onlyenhancements = '')
|
||||
{
|
||||
global $langs, $form;
|
||||
require_once DOL_DOCUMENT_ROOT."/ai/lib/ai.lib.php";
|
||||
|
|
@ -111,31 +112,50 @@ class FormAI extends Form
|
|||
|
||||
$langs->load("other");
|
||||
|
||||
$messageaiwait = '<i class="fa fa-spinner fa-spin fa-2x fa-fw valignmiddle marginrightonly"></i>'.$langs->trans("AIProcessingPleaseWait", getDolGlobalString('AI_API_SERVICE', 'chatgpt'));
|
||||
|
||||
$htmlContent = preg_replace('/[^a-z0-9_]/', '', $htmlContent);
|
||||
|
||||
$out = '<!-- getSectionForAIEnhancement -->';
|
||||
$out .= '<div id="ai_dropdown'.$htmlContent.'" class="dropdown-menu ai_dropdown ai_dropdown'.$htmlContent.' paddingtop paddingbottom">';
|
||||
$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>';
|
||||
$out .= '<input id="generate_button'.$htmlContent.'" type="button" class="button smallpaddingimp" disabled data-functionai="textgeneration" value="'.$langs->trans('Generate').'"/>';
|
||||
$out .= '</div>';
|
||||
$out .= '<br>';
|
||||
$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>';
|
||||
$out .= '<input id="generate_button'.$htmlContent.'" type="button" class="button smallpaddingimp" disabled data-functionai="'.$function.'" value="'.$langs->trans('Generate').'"/>';
|
||||
$out .= '</div>';
|
||||
}
|
||||
|
||||
$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>';
|
||||
$out .= '<br>';
|
||||
if (empty($onlyenhancements) || in_array($onlyenhancements, array('texttranslation'))) {
|
||||
$out .= ($out ? '<br>' : '');
|
||||
$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>';
|
||||
}
|
||||
|
||||
$summarizearray = getListForAISummarize();
|
||||
$out .= '<div id="ai_summarize'.$htmlContent.'" class="ai_summarize'.$htmlContent.' paddingtop paddingbottom ai_feature">';
|
||||
$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 .= '</div>';
|
||||
if (empty($onlyenhancements) || in_array($onlyenhancements, array('textsummarize'))) {
|
||||
$summarizearray = getListForAISummarize();
|
||||
$out .= ($out ? '<br>' : '');
|
||||
$out .= '<div id="ai_summarize'.$htmlContent.'" class="ai_summarize'.$htmlContent.' paddingtop paddingbottom ai_feature">';
|
||||
$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 .= '</div>';
|
||||
}
|
||||
|
||||
if (empty($onlyenhancements) || in_array($onlyenhancements, array('textrephrase'))) {
|
||||
$stylearray = getListForAIRephraseStyle();
|
||||
$out .= ($out ? '<br>' : '');
|
||||
$out .= '<div id="ai_rephraser'.$htmlContent.'" class="ai_rephraser'.$htmlContent.' paddingtop paddingbottom ai_feature">';
|
||||
$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 .= '</div>';
|
||||
}
|
||||
|
||||
$out = '<!-- getSectionForAIEnhancement -->'.$out;
|
||||
$out = '<div id="ai_dropdown'.$htmlContent.'" class="dropdown-menu ai_dropdown ai_dropdown'.$htmlContent.' paddingtop paddingbottom">'.$out;
|
||||
|
||||
$out .= '<div id="ai_status_message'.$htmlContent.'" class="fieldrequired hideobject marginrightonly margintoponly">';
|
||||
$out .= '<i class="fa fa-spinner fa-spin fa-2x fa-fw valignmiddle marginrightonly"></i>'.$langs->trans("AIProcessingPleaseWait", getDolGlobalString('AI_API_SERVICE', 'chatgpt'));
|
||||
$out .= $messageaiwait;
|
||||
$out .= '</div>';
|
||||
|
||||
if ($function == 'imagegeneration') {
|
||||
|
|
@ -147,6 +167,7 @@ class FormAI extends Form
|
|||
$(document).ready(function() {
|
||||
$('#ai_translation".$htmlContent."_select').data('functionai', 'texttranslation')
|
||||
$('#ai_summarize".$htmlContent."_select').data('functionai', 'textsummarize')
|
||||
$('#ai_rephraser".$htmlContent."_select').data('functionai', 'textrephraser')
|
||||
|
||||
$('#ai_instructions".$htmlContent."').keyup(function(){
|
||||
console.log('We type a key up on #ai_instructions".$htmlContent."');
|
||||
|
|
@ -185,18 +206,27 @@ class FormAI extends Form
|
|||
}
|
||||
});
|
||||
|
||||
$('#ai_rephraser".$htmlContent."_select').on('change', function() {
|
||||
console.log('We change #ai_summarize".$htmlContent."_select with lang '+$(this).val());
|
||||
if ($(this).val() != null && $(this).val() != '' && $(this).val() != '-1') {
|
||||
prepareCallAIGenerator($(this));
|
||||
}
|
||||
});
|
||||
|
||||
function prepareCallAIGenerator(element) {
|
||||
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)."');
|
||||
|
||||
var userprompt = $('#ai_instructions".$htmlContent."').val();
|
||||
var timeoutfinished = 0;
|
||||
var apicallfinished = 0;
|
||||
instructions = '';
|
||||
htmlname = '".$htmlContent."';
|
||||
format = '".dol_escape_js($format)."';
|
||||
functionai = $(element).data('functionai');
|
||||
|
||||
console.log('htmlname='+htmlname);
|
||||
instructions = '';
|
||||
htmlname = '".dol_escape_js($htmlContent)."';
|
||||
format = '".dol_escape_js($format)."';
|
||||
functionai = $(element).data('functionai'); /* element is the html element we have manipulated in the ai tool */
|
||||
texttomodify = '';
|
||||
|
||||
console.log('htmlname='+htmlname+' functionai='+functionai);
|
||||
if ($('#'+htmlname).is('div')) {
|
||||
texttomodify = $('#'+htmlname).html(); /* for div */
|
||||
} else {
|
||||
|
|
@ -211,9 +241,12 @@ class FormAI extends Form
|
|||
}
|
||||
}
|
||||
*/
|
||||
|
||||
lang = $('#ai_translation'+htmlname+'_select').val();
|
||||
instructions = 'Translate the following text to ' + lang + ': ' + texttomodify;
|
||||
if (!texttomodify) {
|
||||
instructions = '';
|
||||
} else {
|
||||
lang = $('#ai_translation'+htmlname+'_select').val();
|
||||
instructions = 'Translate only the following text to ' + lang + ': ' + texttomodify;
|
||||
}
|
||||
} else if (functionai == 'textsummarize') {
|
||||
width = $('#ai_summarize'+htmlname+'_select').val();
|
||||
arr = width.split('_');
|
||||
|
|
@ -221,7 +254,7 @@ class FormAI extends Form
|
|||
unit = arr[1];
|
||||
if (width == undefined || unit == undefined){
|
||||
console.log('Bad value so we choose 20 words')
|
||||
width = '20';
|
||||
width = '50';
|
||||
unit = 'w';
|
||||
}
|
||||
switch(unit){
|
||||
|
|
@ -240,11 +273,16 @@ class FormAI extends Form
|
|||
break;
|
||||
}
|
||||
instructions = 'Summarize the following text '+ (unit == 'percent' ? 'by ' : 'in') + width + ' ' + unit + ': ' + texttomodify;
|
||||
}else {
|
||||
} else if (functionai == 'textrephraser') {
|
||||
style = $('#ai_rephraser'+htmlname+'_select').val();
|
||||
instructions = 'Rephrase the following text in a '+style+' style: ' + texttomodify;
|
||||
} else {
|
||||
instructions = userprompt;
|
||||
}
|
||||
|
||||
/* Show message API running */
|
||||
$('#ai_status_message".$htmlContent."').show();
|
||||
$('#ai_status_message".$htmlContent."').html('".dol_escape_js($messageaiwait)."');
|
||||
$('.icon-container .loader').show();
|
||||
|
||||
setTimeout(function() {
|
||||
|
|
@ -252,7 +290,7 @@ class FormAI extends Form
|
|||
$('#ai_status_message".$htmlContent."').hide();
|
||||
}, 30000);
|
||||
|
||||
console.log(instructions);
|
||||
console.log('Instruction forged by javascript = '+instructions);
|
||||
|
||||
callAIGenerator(functionai, instructions, format, htmlname);
|
||||
}
|
||||
|
|
@ -260,11 +298,15 @@ class FormAI extends Form
|
|||
CKEDITOR.on( 'instanceReady', function(e) {
|
||||
if (CKEDITOR.instances) {
|
||||
var htmlname = '".$htmlContent."';
|
||||
CKEDITOR.instances[htmlname].on('change', function() {
|
||||
data = CKEDITOR.instances[htmlname].getData();
|
||||
$('#'+htmlname).val(data); /* for input or textarea */
|
||||
$('#'+htmlname).html(data); /* for div */
|
||||
})
|
||||
/* 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 */
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
@ -324,9 +366,11 @@ class FormAI extends Form
|
|||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert(error);
|
||||
console.error('error ajax', status, error);
|
||||
$('#ai_status_message').hide();
|
||||
/* 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);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
@ -336,6 +380,7 @@ class FormAI extends Form
|
|||
CKEDITOR.instances[htmlname].setReadOnly(1);
|
||||
}
|
||||
|
||||
console.log('Call generate_content.php');
|
||||
$.ajax({
|
||||
url: '". DOL_URL_ROOT."/ai/ajax/generate_content.php?token=".currentToken()."',
|
||||
type: 'POST',
|
||||
|
|
@ -364,19 +409,28 @@ class FormAI extends Form
|
|||
//}
|
||||
}
|
||||
|
||||
// remove readonly
|
||||
// Remove all value from Ai Section select
|
||||
$('#ai_instructions'+htmlname).val('');
|
||||
$('#ai_translation'+htmlname+'_select').val('-1');
|
||||
$('#ai_translation'+htmlname+'_select').trigger('change');
|
||||
$('#ai_summarize'+htmlname+'_select').val('-1');
|
||||
$('#ai_summarize'+htmlname+'_select').trigger('change');
|
||||
$('#ai_rephraser'+htmlname+'_select').val('-1');
|
||||
$('#ai_rephraser'+htmlname+'_select').trigger('change');
|
||||
$('#ai_status_message'+htmlname).hide();
|
||||
$('#ai_dropdown'+htmlname).hide();
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert(error);
|
||||
console.error('error ajax', status, error);
|
||||
$('#ai_status_message'+htmlname).hide();
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@ class FormTicket
|
|||
}
|
||||
|
||||
print '<form method="POST" '.($withdolfichehead ? '' : 'style="margin-bottom: 30px;" ').'name="ticket" id="form_create_ticket" enctype="multipart/form-data" action="'.(!empty($this->param["returnurl"]) ? $this->param["returnurl"] : $_SERVER['PHP_SELF']).'">';
|
||||
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="'.$this->action.'">';
|
||||
if (!empty($object->id)) {
|
||||
|
|
@ -837,7 +838,7 @@ class FormTicket
|
|||
print dol_get_fiche_end();
|
||||
}
|
||||
|
||||
print '<br>';
|
||||
print '<br><br>';
|
||||
|
||||
if ($mode == 'create') {
|
||||
print $form->buttonsSaveCancel(((isset($this->withreadid) && $this->withreadid > 0) ? "SendResponse" : "CreateTicket"), ($this->withcancel ? "Cancel" : ""));
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class Menu
|
|||
/**
|
||||
* List of menu items
|
||||
*
|
||||
* @var array<array{url:string,titre:string,enabled:int<0,2>,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,id:string,idsel:string,classname:string,prefix?:string}>
|
||||
* @var array<array{url:string,titre:string,enabled:int<0,2>,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,id:string,idsel:string,classname:string,prefix?:string}>
|
||||
*/
|
||||
public $liste;
|
||||
|
||||
|
|
|
|||
|
|
@ -274,7 +274,8 @@ class Menubase
|
|||
$sql .= "langs,";
|
||||
$sql .= "perms,";
|
||||
$sql .= "enabled,";
|
||||
$sql .= "usertype";
|
||||
$sql .= "usertype,";
|
||||
$sql .= "showtopmenuinframe";
|
||||
$sql .= ") VALUES (";
|
||||
$sql .= " '".$this->db->escape($this->menu_handler)."',";
|
||||
$sql .= " '".$this->db->escape((string) $this->entity)."',";
|
||||
|
|
@ -293,7 +294,8 @@ class Menubase
|
|||
$sql .= " '".$this->db->escape($this->langs)."',";
|
||||
$sql .= " '".$this->db->escape($this->perms)."',";
|
||||
$sql .= " '".$this->db->escape($this->enabled)."',";
|
||||
$sql .= " '".$this->db->escape((string) $this->user)."'";
|
||||
$sql .= " '".$this->db->escape((string) $this->user)."',";
|
||||
$sql .= " ".((int) $this->showtopmenuinframe);
|
||||
$sql .= ")";
|
||||
|
||||
dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
||||
|
|
@ -352,24 +354,25 @@ class Menubase
|
|||
|
||||
// Update request
|
||||
$sql = "UPDATE ".$this->db->prefix()."menu SET";
|
||||
$sql .= " menu_handler='".$this->db->escape($this->menu_handler)."',";
|
||||
$sql .= " module='".$this->db->escape($this->module)."',";
|
||||
$sql .= " type='".$this->db->escape($this->type)."',";
|
||||
$sql .= " mainmenu='".$this->db->escape($this->mainmenu)."',";
|
||||
$sql .= " leftmenu='".$this->db->escape($this->leftmenu)."',";
|
||||
$sql .= " fk_menu=".((int) $this->fk_menu).",";
|
||||
$sql .= " fk_mainmenu=".($this->fk_mainmenu ? "'".$this->db->escape($this->fk_mainmenu)."'" : "null").",";
|
||||
$sql .= " fk_leftmenu=".($this->fk_leftmenu ? "'".$this->db->escape($this->fk_leftmenu)."'" : "null").",";
|
||||
$sql .= " position=".($this->position > 0 ? ((int) $this->position) : 0).",";
|
||||
$sql .= " url='".$this->db->escape($this->url)."',";
|
||||
$sql .= " target='".$this->db->escape($this->target)."',";
|
||||
$sql .= " titre='".$this->db->escape($this->title)."',";
|
||||
$sql .= " prefix='".$this->db->escape($this->prefix)."',";
|
||||
$sql .= " langs='".$this->db->escape($this->langs)."',";
|
||||
$sql .= " perms='".$this->db->escape($this->perms)."',";
|
||||
$sql .= " enabled='".$this->db->escape($this->enabled)."',";
|
||||
$sql .= " usertype='".$this->db->escape((string) $this->user)."'";
|
||||
$sql .= " WHERE rowid=".((int) $this->id);
|
||||
$sql .= " menu_handler = '".$this->db->escape($this->menu_handler)."',";
|
||||
$sql .= " module = '".$this->db->escape($this->module)."',";
|
||||
$sql .= " type = '".$this->db->escape($this->type)."',";
|
||||
$sql .= " mainmenu = '".$this->db->escape($this->mainmenu)."',";
|
||||
$sql .= " leftmenu = '".$this->db->escape($this->leftmenu)."',";
|
||||
$sql .= " fk_menu = ".((int) $this->fk_menu).",";
|
||||
$sql .= " fk_mainmenu = ".($this->fk_mainmenu ? "'".$this->db->escape($this->fk_mainmenu)."'" : "null").",";
|
||||
$sql .= " fk_leftmenu = ".($this->fk_leftmenu ? "'".$this->db->escape($this->fk_leftmenu)."'" : "null").",";
|
||||
$sql .= " position = ".($this->position > 0 ? ((int) $this->position) : 0).",";
|
||||
$sql .= " url = '".$this->db->escape($this->url)."',";
|
||||
$sql .= " target = '".$this->db->escape($this->target)."',";
|
||||
$sql .= " titre = '".$this->db->escape($this->title)."',";
|
||||
$sql .= " prefix = '".$this->db->escape($this->prefix)."',";
|
||||
$sql .= " langs = '".$this->db->escape($this->langs)."',";
|
||||
$sql .= " perms = '".$this->db->escape($this->perms)."',";
|
||||
$sql .= " enabled = '".$this->db->escape($this->enabled)."',";
|
||||
$sql .= " usertype = '".$this->db->escape((string) $this->user)."',";
|
||||
$sql .= " showtopmenuinframe = ".((int) $this->showtopmenuinframe);
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog(get_class($this)."::update", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
|
|
@ -413,7 +416,8 @@ class Menubase
|
|||
$sql .= " t.perms,";
|
||||
$sql .= " t.enabled,";
|
||||
$sql .= " t.usertype as user,";
|
||||
$sql .= " t.tms";
|
||||
$sql .= " t.tms,";
|
||||
$sql .= " t.showtopmenuinframe";
|
||||
$sql .= " FROM ".$this->db->prefix()."menu as t";
|
||||
$sql .= " WHERE t.rowid = ".((int) $id);
|
||||
|
||||
|
|
@ -444,6 +448,7 @@ class Menubase
|
|||
$this->enabled = str_replace("\"", "'", $obj->enabled);
|
||||
$this->user = $obj->user;
|
||||
$this->tms = $this->db->jdate($obj->tms);
|
||||
$this->showtopmenuinframe = $obj->showtopmenuinframe;
|
||||
}
|
||||
$this->db->free($resql);
|
||||
|
||||
|
|
@ -517,8 +522,8 @@ class Menubase
|
|||
* @param string $myleftmenu Value for leftmenu to filter menu to load (always '')
|
||||
* @param int $type_user 0=Menu for backoffice, 1=Menu for front office
|
||||
* @param string $menu_handler Filter on name of menu_handler used (auguria, eldy...)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @return array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> Return array with menu entries for top menu
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @return array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> Return array with menu entries for top menu
|
||||
*/
|
||||
public function menuTopCharger($mymainmenu, $myleftmenu, $type_user, $menu_handler, &$tabMenu)
|
||||
{
|
||||
|
|
@ -538,6 +543,7 @@ class Menubase
|
|||
return $newTabMenu;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load entries found from database (and stored into $tabMenu) in $this->newmenu array.
|
||||
* Warning: Entries in $tabMenu must have child after parent
|
||||
|
|
@ -547,7 +553,7 @@ class Menubase
|
|||
* @param string $myleftmenu Value for leftmenu to filter menu to load (always '')
|
||||
* @param int $type_user 0=Menu for backoffice, 1=Menu for front office
|
||||
* @param string $menu_handler Filter on name of menu_handler used (auguria, eldy...)
|
||||
* @param array<array{rowid:string,fk_menu:string,module:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $tabMenu Array with menu entries already loaded
|
||||
* @param array<array{rowid:string,fk_menu:string,module:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $tabMenu Array with menu entries already loaded
|
||||
* @return Menu Menu array for particular mainmenu value or full tabArray
|
||||
*/
|
||||
public function menuLeftCharger($newmenu, $mymainmenu, $myleftmenu, $type_user, $menu_handler, &$tabMenu)
|
||||
|
|
@ -629,7 +635,7 @@ class Menubase
|
|||
* @param string $myleftmenu Value for left that defined leftmenu
|
||||
* @param int $type_user Looks for menu entry for 0=Internal users, 1=External users
|
||||
* @param string $menu_handler Name of menu_handler used ('auguria', 'eldy'...)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $tabMenu Array to store new entries found (in most cases, it's empty, but may be already filled)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $tabMenu Array to store new entries found (in most cases, it's empty, but may be already filled)
|
||||
* @return int >0 if OK, <0 if KO
|
||||
*/
|
||||
public function menuLoad($mymainmenu, $myleftmenu, $type_user, $menu_handler, &$tabMenu)
|
||||
|
|
@ -641,7 +647,7 @@ class Menubase
|
|||
$leftmenu = $myleftmenu; // To export to dol_eval function
|
||||
|
||||
$sql = "SELECT m.rowid, m.type, m.module, m.fk_menu, m.fk_mainmenu, m.fk_leftmenu, m.url, m.titre,";
|
||||
$sql .= " m.prefix, m.langs, m.perms, m.enabled, m.target, m.mainmenu, m.leftmenu, m.position";
|
||||
$sql .= " m.prefix, m.langs, m.perms, m.enabled, m.target, m.mainmenu, m.leftmenu, m.position, m.showtopmenuinframe";
|
||||
$sql .= " FROM ".$this->db->prefix()."menu as m";
|
||||
$sql .= " WHERE m.entity IN (0,".$conf->entity.")";
|
||||
$sql .= " AND m.menu_handler IN ('".$this->db->escape($menu_handler)."','all')";
|
||||
|
|
@ -737,7 +743,8 @@ class Menubase
|
|||
$tabMenu[$b]['type'] = $menu['type'];
|
||||
$tabMenu[$b]['fk_mainmenu'] = $menu['fk_mainmenu'];
|
||||
$tabMenu[$b]['fk_leftmenu'] = $menu['fk_leftmenu'];
|
||||
$tabMenu[$b]['position'] = (int) $menu['position'];
|
||||
$tabMenu[$b]['position'] = (int) $menu['position'];
|
||||
$tabMenu[$b]['showtopmenuinframe'] = (int) $menu['showtopmenuinframe'];
|
||||
|
||||
$b++;
|
||||
}
|
||||
|
|
@ -760,7 +767,7 @@ class Menubase
|
|||
/**
|
||||
* Complete this->newmenu with menu entry found in $tab
|
||||
*
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $tab Tab array with all menu entries
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $tab Tab array with all menu entries
|
||||
* @param int $pere Id of parent
|
||||
* @param int $level Level
|
||||
* @return void
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class TimeSpent extends CommonObject
|
|||
'element_date_withhour' => array('type' => 'integer', 'label' => 'element_date_withhour', 'enabled' => 1, 'position' => 6, 'notnull' => 0, 'visible' => -1,),
|
||||
'element_duration' => array('type' => 'double', 'label' => 'element_duration', 'enabled' => 1, 'position' => 7, 'notnull' => 0, 'visible' => -1,),
|
||||
'fk_product' => array('type' => 'integer', 'label' => 'fk_product', 'enabled' => 1, 'position' => 8, 'notnull' => 0, 'visible' => -1,),
|
||||
'fk_user' => array('type' => 'integer', 'label' => 'fk_user', 'enabled' => 1, 'position' => 9, 'notnull' => 0, 'visible' => -1,),
|
||||
'fk_user' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'fk_user', 'enabled' => 1, 'position' => 9, 'notnull' => 0, 'visible' => -1,),
|
||||
'thm' => array('type' => 'double(24,8)', 'label' => 'thm', 'enabled' => 1, 'position' => 10, 'notnull' => 0, 'visible' => -1,),
|
||||
'invoice_id' => array('type' => 'integer', 'label' => 'invoice_id', 'enabled' => 1, 'position' => 11, 'notnull' => 0, 'visible' => -1, 'default' => 'NULL',),
|
||||
'invoice_line_id' => array('type' => 'integer', 'label' => 'invoice_line_id', 'enabled' => 1, 'position' => 12, 'notnull' => 0, 'visible' => -1, 'default' => 'NULL',),
|
||||
|
|
|
|||
149
htdocs/core/frames.php
Normal file
149
htdocs/core/frames.php
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
/* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
*
|
||||
* 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/frames.php
|
||||
* \ingroup core
|
||||
* \brief Page that build two frames: One for menu, the other for the target page to show
|
||||
* Usage:
|
||||
* /core/frames.php to show URL set into setup
|
||||
* /core/frames.php?keyforcontent=EXTERNAL_SITE_CONTENT_abc to show html text defined into conf 'EXTERNAL_SITE_CONTENT_abc'
|
||||
* /core/frames.php?keyforcontent=EXTERNAL_SITE_URL_abc to show URL defined into conf 'EXTERNAL_SITE_URL_abc'
|
||||
*/
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
* @var HookManager $hookmanager
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*
|
||||
* @var int $heightforframes
|
||||
*/
|
||||
|
||||
/** @phan-file-suppress PhanUndeclaredGlobalVariable */
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->load("other");
|
||||
|
||||
|
||||
$mainmenu = GETPOST('mainmenu', "aZ09");
|
||||
$leftmenu = GETPOST('leftmenu', "aZ09");
|
||||
$idmenu = GETPOSTINT('idmenu');
|
||||
$theme = GETPOST('theme', 'aZ09');
|
||||
$codelang = GETPOST('lang', 'aZ09');
|
||||
|
||||
$menu = new Menubase($db);
|
||||
$menu->fetch($idmenu);
|
||||
|
||||
if (!$menu->id || empty($menu->showtopmenuinframe)) {
|
||||
accessforbidden('Parameter idmenu is wrong. Must be the ID of a menu entry allowed to be output into a frame');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* View
|
||||
*/
|
||||
|
||||
// The content of the top frame
|
||||
if (GETPOST('top')) {
|
||||
top_htmlhead("", "");
|
||||
|
||||
print '<body id="mainbody">'."\n";
|
||||
|
||||
top_menu("", "", "_top");
|
||||
|
||||
print '</body>';
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
$reg = array();
|
||||
|
||||
$keyforcontent = '';
|
||||
if (preg_match('/^__[(.+)]__$/', $menu->url, $reg)) {
|
||||
$keyforcontent = $reg[1];
|
||||
}
|
||||
|
||||
if ($keyforcontent) {
|
||||
llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-externalsite page-frames');
|
||||
|
||||
print '<div class="framecontent" style="height: '.($_SESSION['dol_screenheight'] - 90).'px">';
|
||||
|
||||
if (!getDolGlobalString($keyforcontent)) {
|
||||
$langs->load("errors");
|
||||
print $langs->trans("ErrorVariableKeyForContentMustBeSet", $keyforcontent, $keyforcontent);
|
||||
} else {
|
||||
if (preg_match('/EXTERNAL_SITE_URL_/', $keyforcontent)) {
|
||||
print '<iframe src="'.getDolGlobalString($keyforcontent).'"></iframe>';
|
||||
} else {
|
||||
print getDolGlobalString($keyforcontent);
|
||||
}
|
||||
}
|
||||
|
||||
print '<div>';
|
||||
llxFooter();
|
||||
} else {
|
||||
if (preg_match('/^\//', $menu->url) || preg_match('/^http/i', $menu->url)) {
|
||||
// menu->url is an URL starting with http or /
|
||||
print "
|
||||
<html>
|
||||
<head>
|
||||
<title>Dolibarr frame for external web site</title>
|
||||
</head>
|
||||
|
||||
<frameset ".(!getDolGlobalString('MAIN_MENU_INVERT') ? "rows" : "cols")."=\"".$heightforframes.",*\" border=0 framespacing=0 frameborder=0>
|
||||
<frame name=\"barre\" src=\"".$_SERVER["PHP_SELF"]."?top=1&mainmenu=".$mainmenu."&leftmenu=".$leftmenu."&idmenu=".$idmenu.($theme ? '&theme='.$theme : '').($codelang ? '&lang='.$codelang : '')."&nobackground=1\" noresize scrolling=\"NO\" noborder>
|
||||
";
|
||||
print '<frame name="main" src="';
|
||||
print $menu->url;
|
||||
print '">';
|
||||
print "
|
||||
<noframes>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
|
||||
<noframes>
|
||||
<body>
|
||||
<br><div class=\"center\">
|
||||
Sorry, your browser is too old or not correctly configured to view this area.<br>
|
||||
Your browser must support frames.<br>
|
||||
</div>
|
||||
</body>
|
||||
</noframes>
|
||||
|
||||
</html>
|
||||
";
|
||||
} else {
|
||||
// menu->url is an URL starting with http or /
|
||||
llxHeader('', '', '', '', 0, 0, '', '', '', 'mod-externalsite page-frames');
|
||||
print '<div class="framecontent" style="height: '.($_SESSION['dol_screenheight'] - 90).'px">';
|
||||
print $menu->url;
|
||||
print '<div>';
|
||||
llxFooter();
|
||||
}
|
||||
}
|
||||
|
|
@ -1475,7 +1475,7 @@ $(document).ready(function() {
|
|||
|
||||
jQuery(document).ready(function() {
|
||||
// Force to hide menus when page is inside an iFrame so we can show any page into a dialog popup
|
||||
if (window.location && window.location.pathname.indexOf("externalsite/frametop.php") == -1 && window.location !== window.parent.location ) {
|
||||
if (window.location && window.location.pathname.indexOf("core/frames.php") == -1 && window.location.pathname.indexOf("externalsite/frametop.php") == -1 && window.location !== window.parent.location ) {
|
||||
console.log("Page is detected to be into an iframe, we hide by CSS the menus");
|
||||
// The page is in an iframe
|
||||
jQuery(".side-nav-vert, .side-nav, .websitebar").hide();
|
||||
|
|
|
|||
|
|
@ -529,7 +529,7 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete =
|
|||
/* Code to add class of origin OPTION propagated to the new select2 <li> tag */
|
||||
if (data.element) { $(container).addClass($(data.element).attr("class")); }
|
||||
//console.log("data html is "+$(data.element).attr("data-html"));
|
||||
if (data.id == '.((int) $idforemptyvalue).' && $(data.element).attr("data-html") == undefined) {
|
||||
if (data.id == \''.(dol_escape_js($idforemptyvalue)).'\' && $(data.element).attr("data-html") == undefined) {
|
||||
return \' \';
|
||||
}
|
||||
if ($(data.element).attr("data-html") != undefined) {
|
||||
|
|
@ -542,7 +542,7 @@ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete =
|
|||
return data.text;
|
||||
},
|
||||
templateSelection: function (selection) { /* Format visible output of selected value */
|
||||
if (selection.id == '.((int) $idforemptyvalue).') return \'<span class="placeholder">\'+selection.text+\'</span>\';
|
||||
if (selection.id == \''.(dol_escape_js($idforemptyvalue)).'\') return \'<span class="placeholder">\'+selection.text+\'</span>\';
|
||||
return selection.text;
|
||||
},
|
||||
escapeMarkup: function(markup) {
|
||||
|
|
|
|||
|
|
@ -2737,42 +2737,76 @@ function addMailingEventTypeSQL($actioncode, $objcon, $filterobj)
|
|||
|
||||
|
||||
/**
|
||||
* Show header of company in HTML public pages
|
||||
* Show the header of a company in HTML public pages
|
||||
*
|
||||
* @param Societe $mysoc Third party
|
||||
* @param Translate $langs Output language
|
||||
* @param int|string $showlogo '1'=Show logo or 'url' for click on logo
|
||||
* @param string $alttext Text to show in header
|
||||
* @param string $subimageconst Constant to check if we must add image under the main header
|
||||
* @param string $altlogo1 To use an alternative logo defined into setup (instead of company logo)
|
||||
* @param string $altlogo2 To use an alternative logo defined into setup (instead of company logo)
|
||||
* @return void
|
||||
*/
|
||||
function htmlPrintOnlineHeader($mysoc, $langs)
|
||||
function htmlPrintOnlineHeader($mysoc, $langs, $showlogo = 1, $alttext = '', $subimageconst = '', $altlogo1 = '', $altlogo2 = '')
|
||||
{
|
||||
global $conf;
|
||||
global $conf, $dolibarr_main_url_root;
|
||||
|
||||
// Define urllogo
|
||||
$urllogo = DOL_URL_ROOT.'/theme/common/login_logo.png';
|
||||
// Set logo of company by default
|
||||
$logosmall = $mysoc->logo_small;
|
||||
$logo = $mysoc->logo;
|
||||
|
||||
if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) {
|
||||
$urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
|
||||
} elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) {
|
||||
$urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo);
|
||||
} elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg')) {
|
||||
$urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg';
|
||||
if ($altlogo1 && getDolGlobalString($altlogo1)) {
|
||||
$logosmall = getDolGlobalString($altlogo1);
|
||||
} elseif ($altlogo2 && getDolGlobalString($altlogo2)) {
|
||||
$logosmall = getDolGlobalString($altlogo2);
|
||||
}
|
||||
|
||||
// Define $urllogo and $urllogopublic
|
||||
//$urllogo = '';
|
||||
$urllogopublic = '';
|
||||
if ($showlogo) {
|
||||
if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) {
|
||||
//$urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$logosmall);
|
||||
$urllogopublic = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall);
|
||||
} elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) {
|
||||
//$urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/'.$logo);
|
||||
$urllogopublic = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo);
|
||||
} elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg')) {
|
||||
//$urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg';
|
||||
$urllogopublic = $dolibarr_main_url_root.'/theme/dolibarr_logo.svg';
|
||||
}
|
||||
}
|
||||
|
||||
print '<header class="center">';
|
||||
|
||||
// Output html code for logo
|
||||
print '<div class="backgreypublicpayment">';
|
||||
print '<div class="logopublicpayment">';
|
||||
print '<img id="dolpaymentlogo" src="'.$urllogo.'">';
|
||||
print '</div>';
|
||||
if (!getDolGlobalString('MAIN_HIDE_POWERED_BY')) {
|
||||
print '<div class="poweredbypublicpayment opacitymedium right"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img class="poweredbyimg" src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
|
||||
if ($urllogopublic || $alttext) {
|
||||
print '<div class="backgreypublicpayment">';
|
||||
print '<div class="logopublicpayment">';
|
||||
if ($urllogopublic) {
|
||||
if (!is_numeric($showlogo)) {
|
||||
print '<a href="'.$showlogo.'">';
|
||||
}
|
||||
print '<img id="dolpaymentlogo" src="'.$urllogopublic.'">';
|
||||
if (!is_numeric($showlogo)) {
|
||||
print '</a>';
|
||||
}
|
||||
}
|
||||
if ($alttext) {
|
||||
print '<div class="clearboth"></div><strong>'.$alttext.'</strong>';
|
||||
}
|
||||
print '</div>';
|
||||
if (!getDolGlobalString('MAIN_HIDE_POWERED_BY')) {
|
||||
print '<div class="poweredbypublicpayment opacitymedium right hideonsmartphone"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img class="poweredbyimg" src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
|
||||
}
|
||||
print '</div>';
|
||||
}
|
||||
print '</div>';
|
||||
|
||||
if (getDolGlobalString('MEMBER_IMAGE_PUBLIC_REGISTRATION')) {
|
||||
print '<div class="backimagepublicregistration">';
|
||||
print '<img id="idEVENTORGANIZATION_IMAGE_PUBLIC_INTERFACE" src="' . getDolGlobalString('MEMBER_IMAGE_PUBLIC_REGISTRATION').'">';
|
||||
// Add an optional image under the ban with logo/title
|
||||
if (getDolGlobalString($subimageconst)) {
|
||||
print '<div class="backimagepublicsubimage">';
|
||||
print '<img id="id'.$subimageconst.'" src="' . getDolGlobalString($subimageconst).'">';
|
||||
print '</div>';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2247,7 +2247,7 @@ function dolPrintPassword($s)
|
|||
* @param int $keepb 1=Replace b tags with escaped value (except if in $noescapetags), 0=Remove them completely
|
||||
* @param int $keepn 1=Preserve \r\n strings, 0=Replace them with escaped value, -1=Remove them. Set to 1 when escaping for a <textarea>.
|
||||
* @param string $noescapetags '' (escape all html tags) or 'common' (do not escape some common tags) or list of tags to not escape.
|
||||
* @param int $escapeonlyhtmltags 1=Escape only html tags, not the special chars like accents.
|
||||
* @param int $escapeonlyhtmltags 1=Escape only html tags and double quotes, not the special chars like accents.
|
||||
* @param int $cleanalsojavascript Clean also javascript. @TODO switch this option to 1 by default.
|
||||
* @return string Escaped string
|
||||
* @see dol_string_nohtmltag(), dol_string_onlythesehtmltags(), dol_string_nospecial(), dol_string_unaccent(), dol_htmlentitiesbr()
|
||||
|
|
@ -7124,13 +7124,13 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $
|
|||
}
|
||||
|
||||
// If force rounding
|
||||
if ((string) $forcerounding != '-1') {
|
||||
if ((string) $forcerounding != '-1' && (string) $forcerounding != '') {
|
||||
if ($forcerounding === 'MU') {
|
||||
$nbdecimal = getDolGlobalInt('MAIN_MAX_DECIMALS_UNIT');
|
||||
} elseif ($forcerounding === 'MT') {
|
||||
$nbdecimal = getDolGlobalInt('MAIN_MAX_DECIMALS_TOT');
|
||||
} elseif ($forcerounding >= 0) {
|
||||
$nbdecimal = $forcerounding;
|
||||
$nbdecimal = (int) $forcerounding;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1102,6 +1102,9 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $
|
|||
}
|
||||
//print "maskraz=".$maskraz; // -1=no reset
|
||||
|
||||
$monthcomp = 0;
|
||||
$yearcomp = '';
|
||||
|
||||
if ($maskraz > 0) { // A reset is required
|
||||
if ($maskraz == 99) {
|
||||
$maskraz = (int) date('m', $date);
|
||||
|
|
@ -1154,7 +1157,7 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $
|
|||
|
||||
// Define $yearcomp and $monthcomp (that will be use in the select where to search max number)
|
||||
$monthcomp = $maskraz;
|
||||
$yearcomp = 0;
|
||||
$yearcomp = '';
|
||||
|
||||
if (!empty($yearoffsettype) && !is_numeric($yearoffsettype) && $yearoffsettype != '=') { // $yearoffsettype is - or +
|
||||
$currentyear = (int) date("Y", $date);
|
||||
|
|
@ -1183,7 +1186,7 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $
|
|||
} elseif ($yearlen == 2) {
|
||||
$yearcomp = sprintf("%02d", idate("y", $date) + $yearoffset);
|
||||
} elseif ($yearlen == 1) {
|
||||
$yearcomp = (int) substr(date('y', $date), 1, 1) + $yearoffset;
|
||||
$yearcomp = (string) ((int) substr(date('y', $date), 1, 1) + $yearoffset);
|
||||
}
|
||||
if ($monthcomp > 1 && empty($resetEveryMonth)) { // Test with month is useless if monthcomp = 1 (0 is same as 1)
|
||||
if ($yearlen == 4) {
|
||||
|
|
@ -1227,12 +1230,12 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $
|
|||
$maskLike = str_replace("%", "_", $maskLike);
|
||||
|
||||
// Replace protected special codes with matching number of _ as wild card character
|
||||
if ($resetEveryMonth) { // Perf optimization, when a reset is requested at each month, we can include the year and month inside the filter
|
||||
if ($resetEveryMonth && $yearcomp && $monthcomp) { // Perf optimization, when a reset is requested at each month, we can include the year and month inside the filter
|
||||
$maskLike = preg_replace('/\{yyyy\}/i', $yearcomp, $maskLike);
|
||||
$maskLike = preg_replace('/\{yy\}/i', $yearcomp, $maskLike);
|
||||
$maskLike = preg_replace('/\{y\}/i', $yearcomp, $maskLike);
|
||||
$maskLike = preg_replace('/\{mm\}/i', sprintf("%02d", $monthcomp), $maskLike);
|
||||
} elseif ($maskraz == 1) { // Perf optimization, when a reset is requested at first month, we can include the year inside the filter, but not the month
|
||||
} elseif ($maskraz == 1 && $yearcomp) { // Perf optimization, when a reset is requested at first month, we can include the year inside the filter, but not the month
|
||||
$maskLike = preg_replace('/\{yyyy\}/i', $yearcomp, $maskLike);
|
||||
$maskLike = preg_replace('/\{yy\}/i', $yearcomp, $maskLike);
|
||||
$maskLike = preg_replace('/\{y\}/i', $yearcomp, $maskLike);
|
||||
|
|
|
|||
|
|
@ -470,13 +470,20 @@ function pdf_build_address($outputlangs, $sourcecompany, $targetcompany = '', $t
|
|||
$withCountry = 1;
|
||||
}
|
||||
|
||||
$stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset(dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs))."\n";
|
||||
$fulladdress = dol_format_address($sourcecompany, $withCountry, "\n", $outputlangs);
|
||||
if ($fulladdress) {
|
||||
$stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->convToOutputCharset($fulladdress)."\n";
|
||||
}
|
||||
|
||||
if (!getDolGlobalString('MAIN_PDF_DISABLESOURCEDETAILS')) {
|
||||
// Phone
|
||||
if ($sourcecompany->phone) {
|
||||
$stringaddress .= ($stringaddress ? "\n" : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone);
|
||||
}
|
||||
// Phone mobile
|
||||
if ($sourcecompany->phone_mobile && getDolGlobalString('MAIN_PDF_SHOW_SOURCE_PHONE_MOBILE')) {
|
||||
$stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("PhoneShort").": ".$outputlangs->convToOutputCharset($sourcecompany->phone_mobile);
|
||||
}
|
||||
// Fax
|
||||
if ($sourcecompany->fax) {
|
||||
$stringaddress .= ($stringaddress ? ($sourcecompany->phone ? " - " : "\n") : '').$outputlangs->transnoentities("Fax").": ".$outputlangs->convToOutputCharset($sourcecompany->fax);
|
||||
|
|
|
|||
|
|
@ -465,10 +465,10 @@ function encodedecode_dbpassconf($level = 0)
|
|||
/**
|
||||
* Return a generated password using default module
|
||||
*
|
||||
* @param bool $generic true=Create generic password (32 chars/numbers), false=Use the configured password generation module
|
||||
* @param ?array<string> $replaceambiguouschars Discard ambiguous characters. For example array('I').
|
||||
* @param int $length Length of random string (Used only if $generic is true)
|
||||
* @return string New value for password
|
||||
* @param bool $generic true=Create a generic key (32 chars/numbers), false=Create a password using the configured password generation module.
|
||||
* @param ?array<string> $replaceambiguouschars Discard ambiguous characters. For example: array('I').
|
||||
* @param int $length Length of random string (Used only if $generic is true)
|
||||
* @return string New value for password
|
||||
* @see dol_hash(), dolJSToSetRandomPassword()
|
||||
*/
|
||||
function getRandomPassword($generic = false, $replaceambiguouschars = null, $length = 32)
|
||||
|
|
|
|||
|
|
@ -228,59 +228,12 @@ function generate_random_id($car = 16)
|
|||
*/
|
||||
function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = [], $arrayofcss = [])
|
||||
{
|
||||
global $user, $conf, $langs, $mysoc;
|
||||
global $conf, $langs, $mysoc;
|
||||
|
||||
$urllogo = "";
|
||||
top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss, 0, 1); // Show html headers
|
||||
|
||||
print '<body id="mainbody" class="publicnewticketform">';
|
||||
print '<div class="publicnewticketform2 flexcontainer centpercent" style="min-height: 100%;">';
|
||||
print '<div class="publicnewticketform2 centpercent" style="min-height: 100%;">';
|
||||
|
||||
print '<header class="center centpercent">';
|
||||
|
||||
// Define urllogo
|
||||
if (getDolGlobalInt('TICKET_SHOW_COMPANY_LOGO') || getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC')) {
|
||||
// Print logo
|
||||
if (getDolGlobalInt('TICKET_SHOW_COMPANY_LOGO')) {
|
||||
$urllogo = DOL_URL_ROOT.'/theme/common/login_logo.png';
|
||||
|
||||
if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) {
|
||||
$urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
|
||||
} elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) {
|
||||
$urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$mysoc->logo);
|
||||
} elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg')) {
|
||||
$urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output html code for logo
|
||||
if ($urllogo || getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC')) {
|
||||
print '<div class="backgreypublicpayment">';
|
||||
print '<div class="logopublicpayment">';
|
||||
if ($urllogo) {
|
||||
print '<a href="'.(getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE') ? getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE') : dol_buildpath('/public/ticket/index.php?entity='.$conf->entity, 1)).'">';
|
||||
print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
|
||||
print '>';
|
||||
print '</a>';
|
||||
}
|
||||
if (getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC')) {
|
||||
print '<div class="clearboth"></div><strong>'.(getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC') ? getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC') : $langs->trans("TicketSystem")).'</strong>';
|
||||
}
|
||||
print '</div>';
|
||||
if (!getDolGlobalInt('MAIN_HIDE_POWERED_BY')) {
|
||||
print '<div class="poweredbypublicpayment opacitymedium right hideonsmartphone"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
|
||||
}
|
||||
print '</div>';
|
||||
}
|
||||
|
||||
if (getDolGlobalInt('TICKET_IMAGE_PUBLIC_INTERFACE')) {
|
||||
print '<div class="backimagepublicticket">';
|
||||
print '<img id="idTICKET_IMAGE_PUBLIC_INTERFACE" src="'.getDolGlobalString('TICKET_IMAGE_PUBLIC_INTERFACE').'">';
|
||||
print '</div>';
|
||||
}
|
||||
|
||||
print '</header>';
|
||||
|
||||
//print '<div class="ticketlargemargin">';
|
||||
htmlPrintOnlineHeader($mysoc, $langs, (getDolGlobalInt('TICKET_SHOW_COMPANY_LOGO') ? getDolGlobalString('TICKET_URL_PUBLIC_INTERFACE', dol_buildpath('/public/ticket/index.php?entity='.$conf->entity, 1)) : '0'), getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC', $langs->trans("TicketSystem")), 'TICKET_IMAGE_PUBLIC_INTERFACE');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
|
||||
|
||||
|
||||
/** @phan-file-suppress PhanTypeInvalidDimOffset */
|
||||
|
||||
/**
|
||||
* Core function to output top menu auguria
|
||||
|
|
@ -33,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
|
|||
* @param DoliDB $db Database handler
|
||||
* @param string $atarget Target (Example: '' or '_top')
|
||||
* @param int $type_user 0=Menu for backoffice, 1=Menu for front office
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @param Menu $menu Object Menu to return back list of menu entries
|
||||
* @param int<0,1> $noout 1=Disable output (Initialise &$menu only).
|
||||
* @param string $mode 'top', 'topnb', 'left', 'jmobile'
|
||||
|
|
@ -53,7 +53,6 @@ function print_auguria_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout
|
|||
// Show personalized menus
|
||||
$menuArbo = new Menubase($db, 'auguria');
|
||||
$newTabMenu = $menuArbo->menuTopCharger('', '', $type_user, 'auguria', $tabMenu);
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,prefix:string}> $newTabMenu';
|
||||
|
||||
$substitarray = getCommonSubstitutionArray($langs, 0, null, null);
|
||||
|
||||
|
|
@ -79,6 +78,10 @@ function print_auguria_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout
|
|||
$showmode = dol_auguria_showmenu($type_user, $newTabMenu[$i], $listofmodulesforexternal);
|
||||
if ($showmode == 1) {
|
||||
$newTabMenu[$i]['url'] = make_substitutions($newTabMenu[$i]['url'], $substitarray);
|
||||
|
||||
// Phan issue #4881 requires that we reforce the type
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $newTabMenu';
|
||||
|
||||
// url = url from host, shorturl = relative path into dolibarr sources
|
||||
$url = $shorturl = $newTabMenu[$i]['url'];
|
||||
|
||||
|
|
@ -105,8 +108,15 @@ function print_auguria_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout
|
|||
}
|
||||
}
|
||||
|
||||
// Phan issue #4881 requires that we reforce the type
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,prefix:string}> $newTabMenu';
|
||||
// Modify URL for the case we are using the option showtopmenuinframe
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $newTabMenu';
|
||||
// @phan-suppress-next-line PhanTypeInvalidDimOffset
|
||||
if ($newTabMenu[$i]['showtopmenuinframe']) {
|
||||
if (preg_match("/^(http:\/\/|https:\/\/)/i", $newTabMenu[$i]['url'])) {
|
||||
$url = '/core/frames.php?idmenu='.$newTabMenu[$i]['rowid'];
|
||||
$shorturl = $url;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Find a generic solution
|
||||
if (preg_match('/search_project_user=__search_project_user__/', $shorturl)) {
|
||||
|
|
@ -118,9 +128,6 @@ function print_auguria_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout
|
|||
}
|
||||
}
|
||||
|
||||
// Phan issue #4881 requires that we reforce the type
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,prefix:string}> $newTabMenu';
|
||||
|
||||
// Define the class (top menu selected or not)
|
||||
if (!empty($_SESSION['idmenu']) && $newTabMenu[$i]['rowid'] == $_SESSION['idmenu']) {
|
||||
$classname = 'class="tmenusel"';
|
||||
|
|
@ -183,6 +190,8 @@ function print_auguria_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout
|
|||
|
||||
foreach ($menu->liste as $menuval) {
|
||||
print_start_menu_entry_auguria($menuval['idsel'], $menuval['classname'], $menuval['enabled']);
|
||||
// @phan-ignore-next-line
|
||||
// @phpstan-ignore-next-line
|
||||
print_text_menu_entry_auguria($menuval['titre'], $menuval['enabled'], ($menuval['url'] != '#' ? DOL_URL_ROOT : '').$menuval['url'], $menuval['id'], $menuval['idsel'], $menuval['classname'], ($menuval['target'] ? $menuval['target'] : $atarget), $menuval);
|
||||
print_end_menu_entry_auguria($menuval['enabled']);
|
||||
}
|
||||
|
|
@ -236,7 +245,7 @@ function print_start_menu_entry_auguria($idsel, $classname, $showmode)
|
|||
* @param string $idsel Id sel
|
||||
* @param string $classname Class name
|
||||
* @param string $atarget Target
|
||||
* @param array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}|array{} $menuval The full $menuval array
|
||||
* @param array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}|array{} $menuval The full $menuval array
|
||||
* @return void
|
||||
*/
|
||||
function print_text_menu_entry_auguria($text, $showmode, $url, $id, $idsel, $classname, $atarget, $menuval = array())
|
||||
|
|
@ -318,9 +327,9 @@ function print_end_menu_array_auguria()
|
|||
* Fill &$menu (example with $forcemainmenu='home' $forceleftmenu='all', return left menu tree of Home)
|
||||
*
|
||||
* @param DoliDB $db Database handler
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}> $menu_array_before Table of menu entries to show before entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}> $menu_array_after Table of menu entries to show after entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}> $menu_array_before Table of menu entries to show before entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}> $menu_array_after Table of menu entries to show after entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @param Menu $menu Object Menu to return back list of menu entries
|
||||
* @param int<0,1> $noout Disable output (Initialise &$menu only).
|
||||
* @param string $forcemainmenu 'x'=Force mainmenu to mainmenu='x'
|
||||
|
|
@ -534,7 +543,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t
|
|||
|
||||
// Phan has a hard time tracking the type, for instance because it get hookmanager->results
|
||||
// Force the typing at this point to get useful analysis below:
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,prefix:string,level:int}> $menu_array';
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,prefix:string,level:int}> $menu_array';
|
||||
|
||||
// Show menu
|
||||
$invert = !getDolGlobalString('MAIN_MENU_INVERT') ? "" : "invert";
|
||||
|
|
@ -706,14 +715,12 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t
|
|||
* Function to test if an entry is enabled or not
|
||||
*
|
||||
* @param int $type_user 0=We need backoffice menu, 1=We need frontoffice menu
|
||||
* @param array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string,module:string} $menuentry Array for menu entry
|
||||
* @param array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string,module:string} $menuentry Array for menu entry
|
||||
* @param string[] $listofmodulesforexternal Array with list of modules allowed to external users
|
||||
* @return int<0,2> 0=Hide, 1=Show, 2=Show gray
|
||||
*/
|
||||
function dol_auguria_showmenu($type_user, &$menuentry, &$listofmodulesforexternal)
|
||||
{
|
||||
global $conf;
|
||||
|
||||
//print 'type_user='.$type_user.' module='.$menuentry['module'].' enabled='.$menuentry['enabled'].' perms='.$menuentry['perms'];
|
||||
//print 'ok='.in_array($menuentry['module'], $listofmodulesforexternal);
|
||||
if (empty($menuentry['enabled'])) {
|
||||
|
|
|
|||
|
|
@ -58,16 +58,16 @@ class MenuManager
|
|||
public $menu;
|
||||
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $menu_array;
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $menu_array_after;
|
||||
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $tabMenu;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
|
|||
|
||||
|
||||
/**
|
||||
* Core function to output top menu eldy
|
||||
* Core function to output the top menu eldy
|
||||
*
|
||||
* @param DoliDB $db Database handler
|
||||
* @param string $atarget Target (Example: '' or '_top')
|
||||
* @param int $type_user 0=Menu for backoffice, 1=Menu for front office
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty). For eldy menu, it contains menu entries loaded from database.
|
||||
* @param array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty). For eldy menu, it contains menu entries loaded from database.
|
||||
* @param Menu $menu Object Menu to return back list of menu entries
|
||||
* @param int $noout 1=Disable output (Initialise &$menu only).
|
||||
* @param string $mode 'top', 'topnb', 'left', 'jmobile'
|
||||
|
|
@ -495,14 +495,16 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
|
|||
$menuArbo = new Menubase($db, 'eldy');
|
||||
$newTabMenu = $menuArbo->menuTopCharger('', '', $type_user, 'eldy', $tabMenu); // Set tabMenu with only top entries of non hardcoded core menu enties and external modules
|
||||
|
||||
// Add menu with top entries of non hardcoded core menu enties and external modules
|
||||
// Add menu with top entries of non hardcoded core menu entries and of external modules
|
||||
$num = count($newTabMenu);
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
//var_dump($type_user.' '.$newTabMenu[$i]['url'].' '.$showmode.' '.$newTabMenu[$i]['perms']);
|
||||
$idsel = (empty($newTabMenu[$i]['mainmenu']) ? 'none' : $newTabMenu[$i]['mainmenu']);
|
||||
|
||||
$newTabMenu[$i]['url'] = make_substitutions($newTabMenu[$i]['url'], $substitarray);
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,prefix:string}> $newTabMenu';
|
||||
|
||||
// Phan issue #4881 requires that we reforce the type
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,prefix:string}> $newTabMenu';
|
||||
|
||||
// url = url from host, shorturl = relative path into dolibarr sources
|
||||
$url = $shorturl = $newTabMenu[$i]['url'];
|
||||
|
|
@ -524,6 +526,13 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
|
|||
}
|
||||
}
|
||||
|
||||
// Modify URL for the case we are using the option showtopmenuinframe
|
||||
if ($newTabMenu[$i]['showtopmenuinframe']) {
|
||||
if (preg_match("/^(http:\/\/|https:\/\/)/i", $newTabMenu[$i]['url'])) {
|
||||
$url = $shorturl = '/core/frames.php?idmenu='.$newTabMenu[$i]['rowid'];
|
||||
}
|
||||
}
|
||||
|
||||
$showmode = isVisibleToUserType($type_user, $newTabMenu[$i], $listofmodulesforexternal);
|
||||
if ($showmode == 1) {
|
||||
// Define the class (top menu selected or not)
|
||||
|
|
@ -599,6 +608,8 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
|
|||
//var_dump($menu->liste);
|
||||
foreach ($menu->liste as $menuval) {
|
||||
print_start_menu_entry($menuval['idsel'], $menuval['classname'], $menuval['enabled']);
|
||||
// @phan-ignore-next-line
|
||||
// @phpstan-ignore-next-line
|
||||
print_text_menu_entry($menuval['titre'], $menuval['enabled'], (($menuval['url'] != '#' && !preg_match('/^(http:\/\/|https:\/\/)/i', $menuval['url'])) ? DOL_URL_ROOT : '').$menuval['url'], $menuval['id'], $menuval['idsel'], $menuval['classname'], ($menuval['target'] ? $menuval['target'] : $atarget), $menuval);
|
||||
print_end_menu_entry($menuval['enabled']);
|
||||
}
|
||||
|
|
@ -652,7 +663,7 @@ function print_start_menu_entry($idsel, $classname, $showmode)
|
|||
* @param string $idsel Id sel
|
||||
* @param string $classname Class name
|
||||
* @param string $atarget Target
|
||||
* @param array{}|array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string} $menuval All the $menuval array
|
||||
* @param array{}|array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string} $menuval All the $menuval array
|
||||
* @return void
|
||||
*/
|
||||
function print_text_menu_entry($text, $showmode, $url, $id, $idsel, $classname, $atarget, $menuval = array())
|
||||
|
|
@ -733,9 +744,9 @@ function print_end_menu_array()
|
|||
* Fill &$menu (example with $forcemainmenu='home' $forceleftmenu='all', return left menu tree of Home)
|
||||
*
|
||||
* @param DoliDB $db Database handler
|
||||
* @param array<array{rowid:string,fk_menu:string,module?:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $menu_array_before Table of menu entries to show before entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,module?:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $menu_array_after Table of menu entries to show after entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,module?:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @param array<array{rowid:string,fk_menu:string,module?:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $menu_array_before Table of menu entries to show before entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,module?:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $menu_array_after Table of menu entries to show after entries of menu handler (menu->liste filled with menu->add)
|
||||
* @param array<array{rowid:string,fk_menu:string,module?:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $tabMenu If array with menu entries already loaded, we put this array here (in most cases, it's empty)
|
||||
* @param Menu $menu Object Menu to return back list of menu entries
|
||||
* @param int<0,1> $noout Disable output (Initialise &$menu only).
|
||||
* @param string $forcemainmenu 'x'=Force mainmenu to mainmenu='x'
|
||||
|
|
@ -946,7 +957,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM
|
|||
}*/
|
||||
|
||||
// Force the typing at this point to get useful analysis below:
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $menu_array';
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $menu_array';
|
||||
|
||||
|
||||
// Show menu
|
||||
|
|
|
|||
|
|
@ -57,16 +57,16 @@ class MenuManager
|
|||
public $menu;
|
||||
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $menu_array;
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $menu_array_after;
|
||||
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $tabMenu;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@ class MenuManager
|
|||
public $menu;
|
||||
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $menu_array_after;
|
||||
|
||||
/**
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level:int,prefix:string}>
|
||||
* @var array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level:int,prefix:string}>
|
||||
*/
|
||||
public $tabMenu;
|
||||
|
||||
|
|
@ -407,7 +407,7 @@ class MenuManager
|
|||
return 0;
|
||||
}
|
||||
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string}> $menu_array';
|
||||
'@phan-var-force array<array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string}> $menu_array';
|
||||
|
||||
if (empty($noout)) {
|
||||
$alt = 0;
|
||||
|
|
@ -546,7 +546,7 @@ function print_start_menu_entry_empty($idsel, $classname, $showmode)
|
|||
* @param string $idsel Id sel
|
||||
* @param string $classname Class name
|
||||
* @param string $atarget Target
|
||||
* @param array{}|array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,level?:int,prefix:string} $menuval All the $menuval array
|
||||
* @param array{}|array{rowid:string,fk_menu:string,langs:string,enabled:int<0,2>,type:string,fk_mainmenu:string,fk_leftmenu:string,url:string,titre:string,perms:string,target:string,mainmenu:string,leftmenu:string,position:int,showtopmenuinframe:int,level?:int,prefix:string} $menuval All the $menuval array
|
||||
* @return void
|
||||
*/
|
||||
function print_text_menu_entry_empty($text, $showmode, $url, $id, $idsel, $classname, $atarget, $menuval = array())
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ class mod_bookkeeping_argon extends ModeleNumRefBookkeeping
|
|||
// Get entities
|
||||
//$entity = getEntity('invoicenumber', 1, $object);
|
||||
$entity = $conf->entity; // In accountancy, we never share entities
|
||||
$numFinal = get_next_value($db, $mask, 'facture', 'ref', $where, null, (empty($object) ? dol_now() : $object->date), $mode, false, null, $entity, $object);
|
||||
$numFinal = get_next_value($db, $mask, 'accounting_bookkeeping', 'ref', $where, null, $object->doc_date, $mode, false, null, (string) $entity, $object);
|
||||
if (!preg_match('/([0-9])+/', $numFinal)) {
|
||||
$this->error = $numFinal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ class mod_bookkeeping_helium extends ModeleNumRefBookkeeping
|
|||
//$entity = getEntity('accountingbookkeeping', 1, $object);
|
||||
$entity = $conf->entity; // In accountancy, we can't share entities
|
||||
|
||||
$numFinal = get_next_value($db, $mask, 'accounting_bookkeeping', 'ref', '', '', $object->doc_date, 'next', false, null, $entity, $object);
|
||||
$numFinal = get_next_value($db, $mask, 'accounting_bookkeeping', 'ref', '', '', $object->doc_date, 'next', false, null, (string) $entity, $object);
|
||||
|
||||
return $numFinal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class modExternalSite extends DolibarrModules
|
|||
// Module description used if translation string 'ModuleXXXDesc' not found (XXX is id value)
|
||||
$this->description = "This module include an external web site or page into Dolibarr menus and view it into a Dolibarr frame.";
|
||||
// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
|
||||
$this->version = 'dolibarr';
|
||||
$this->version = 'dolibarr_deprecated';
|
||||
// Key used in llx_const table to save module status enabled/disabled (XXX is id value)
|
||||
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
||||
// Name of png file (without png) used for this module
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
/* Copyright (C) 2017 Laurent Destailleur <eldy@stocks.sourceforge.net>
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2024 Nick Fragoulis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -908,14 +908,14 @@ class pdf_standard_movementstock extends ModelePDFMovement
|
|||
//$pdf->line($this->posxup-1, $tab_top, $this->posxup-1, $tab_top + $tab_height);
|
||||
if (empty($hidetop)) {
|
||||
$pdf->SetXY($this->posxup - 1, $tab_top + 1);
|
||||
$pdf->MultiCell($this->posxunit - $this->posxup, 2, $outputlangs->transnoentities("Inventory Code"), '', 'C');
|
||||
$pdf->MultiCell($this->posxunit - $this->posxup, 2, $outputlangs->transnoentities("InventoryCode"), '', 'C');
|
||||
}
|
||||
|
||||
//Label movement
|
||||
//$pdf->line($this->posxunit, $tab_top, $this->posxunit, $tab_top + $tab_height);
|
||||
if (empty($hidetop)) {
|
||||
$pdf->SetXY($this->posxunit, $tab_top + 1);
|
||||
$pdf->MultiCell($this->posxdiscount - $this->posxunit, 2, $outputlangs->transnoentities("Label Movement"), '', 'C');
|
||||
$pdf->MultiCell($this->posxdiscount - $this->posxunit, 2, $outputlangs->transnoentities("LabelMovement"), '', 'C');
|
||||
}
|
||||
|
||||
//Origin
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield
|
|||
}
|
||||
// If field is a computed field, we make computation to get value
|
||||
if ($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key]) {
|
||||
$objectoffield = $object; // For compatibility with the computed formula
|
||||
$objectoffield = $object; // For compatibility with the computed formula. $objectoffield is exported by dol_eval().
|
||||
$value = dol_eval((string) $extrafields->attributes[$extrafieldsobjectkey]['computed'][$key], 1, 1, '2');
|
||||
if (is_numeric(price2num($value)) && $extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key]) {
|
||||
$obj->$tmpkey = price2num($value);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ if ($showlinktolayout) { // May be set only if MAIN_EMAIL_USE_LAYOUT is set
|
|||
}
|
||||
// Add link to add AI content
|
||||
if ($showlinktoai) {
|
||||
// TODO Diff between showlinktoai and htmlname ? Why not using one key only ?
|
||||
$out .= '<a href="#" id="linkforaiprompt'.$showlinktoai.'" class="notasortlink inline-block alink marginrightonly">';
|
||||
$out .= img_picto($showlinktoailabel, 'ai', 'class="paddingrightonly"');
|
||||
$out .= '<span class="hideobject hideonsmartphone">'.$showlinktoailabel.'...</span>';
|
||||
|
|
@ -117,6 +118,7 @@ if ($showlinktoai) {
|
|||
</script>
|
||||
';
|
||||
}
|
||||
|
||||
if ($showlinktolayout) {
|
||||
if (!empty($formwebsite) && is_object($formwebsite)) {
|
||||
$out .= $formwebsite->getContentPageTemplate($htmlname);
|
||||
|
|
@ -126,13 +128,18 @@ if ($showlinktolayout) {
|
|||
} else {
|
||||
$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) {
|
||||
if (empty($formai) || $formai instanceof FormAI) {
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formai.class.php';
|
||||
$formai = new FormAI($db);
|
||||
}
|
||||
$out .= $formai->getAjaxAICallFunction();
|
||||
$out .= $formai->getSectionForAIEnhancement($showlinktoai, $formmail->withaiprompt, $htmlname);
|
||||
|
||||
if (empty($onlyenhancements)) {
|
||||
$onlyenhancements = '';
|
||||
}
|
||||
$out .= $formai->getSectionForAIEnhancement($showlinktoai, $formmail->withaiprompt, $htmlname, $onlyenhancements);
|
||||
} else {
|
||||
$out .= '<!-- No link to the AI feature, $formmail->withaiprompt must be set to the ai feature and module ai must be enabled -->';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ class EmailCollectorAction extends CommonObject
|
|||
'actionparam' => array('type' => 'text', 'label' => 'ParamForAction', 'enabled' => 1, 'visible' => 1, 'position' => 40, 'notnull' => -1),
|
||||
'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'position' => 500, 'notnull' => 1,),
|
||||
'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -2, 'position' => 501, 'notnull' => 1,),
|
||||
'fk_user_creat' => array('type' => 'integer', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'position' => 510, 'notnull' => 1, 'foreignkey' => 'llx_user.rowid',),
|
||||
'fk_user_modif' => array('type' => 'integer', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'position' => 511, 'notnull' => -1,),
|
||||
'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'position' => 510, 'notnull' => 1, 'foreignkey' => 'llx_user.rowid',),
|
||||
'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'position' => 511, 'notnull' => -1,),
|
||||
'position' => array('type' => 'integer', 'label' => 'Position', 'enabled' => 1, 'visible' => 1, 'position' => 600, 'default' => '0',),
|
||||
'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 1000, 'notnull' => -1,),
|
||||
'status' => array('type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'visible' => 1, 'position' => 1000, 'notnull' => 1, 'default' => '1', 'arrayofkeyval' => array(0 => 'Disabled', 1 => 'Enabled')),
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ class EmailCollectorFilter extends CommonObject
|
|||
'rulevalue' => array('type' => 'varchar(255)', 'label' => 'ValueOfRule', 'enabled' => 1, 'visible' => 1, 'position' => 30, 'notnull' => -1, 'help' => "Value of Rule",),
|
||||
'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -2, 'position' => 500, 'notnull' => 1,),
|
||||
'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -2, 'position' => 501, 'notnull' => 1,),
|
||||
'fk_user_creat' => array('type' => 'integer', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'position' => 510, 'notnull' => 1, 'foreignkey' => 'llx_user.rowid',),
|
||||
'fk_user_modif' => array('type' => 'integer', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'position' => 511, 'notnull' => -1,),
|
||||
'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'position' => 510, 'notnull' => 1, 'foreignkey' => 'llx_user.rowid',),
|
||||
'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'position' => 511, 'notnull' => -1,),
|
||||
'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 1000, 'notnull' => -1,),
|
||||
'status' => array('type' => 'integer', 'label' => 'Status', 'enabled' => 1, 'visible' => 1, 'position' => 1000, 'notnull' => 1, 'default' => '1', 'arrayofkeyval' => array(0 => 'Disabled', 1 => 'Enabled')),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -308,13 +308,13 @@ class ExpenseReport extends CommonObject
|
|||
'date_approve' => array('type' => 'datetime', 'label' => 'Date approve', 'enabled' => 1, 'visible' => -1, 'position' => 80),
|
||||
'date_refuse' => array('type' => 'datetime', 'label' => 'Date refuse', 'enabled' => 1, 'visible' => -1, 'position' => 85),
|
||||
'date_cancel' => array('type' => 'datetime', 'label' => 'Date cancel', 'enabled' => 1, 'visible' => -1, 'position' => 90),
|
||||
'fk_user_author' => array('type' => 'integer', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 100),
|
||||
'fk_user_modif' => array('type' => 'integer', 'label' => 'Fk user modif', 'enabled' => 1, 'visible' => -1, 'position' => 105),
|
||||
'fk_user_valid' => array('type' => 'integer', 'label' => 'Fk user valid', 'enabled' => 1, 'visible' => -1, 'position' => 110),
|
||||
'fk_user_validator' => array('type' => 'integer', 'label' => 'Fk user validator', 'enabled' => 1, 'visible' => -1, 'position' => 115),
|
||||
'fk_user_approve' => array('type' => 'integer', 'label' => 'Fk user approve', 'enabled' => 1, 'visible' => -1, 'position' => 120),
|
||||
'fk_user_refuse' => array('type' => 'integer', 'label' => 'Fk user refuse', 'enabled' => 1, 'visible' => -1, 'position' => 125),
|
||||
'fk_user_cancel' => array('type' => 'integer', 'label' => 'Fk user cancel', 'enabled' => 1, 'visible' => -1, 'position' => 130),
|
||||
'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 100),
|
||||
'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user modif', 'enabled' => 1, 'visible' => -1, 'position' => 105),
|
||||
'fk_user_valid' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user valid', 'enabled' => 1, 'visible' => -1, 'position' => 110),
|
||||
'fk_user_validator' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user validator', 'enabled' => 1, 'visible' => -1, 'position' => 115),
|
||||
'fk_user_approve' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user approve', 'enabled' => 1, 'visible' => -1, 'position' => 120),
|
||||
'fk_user_refuse' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user refuse', 'enabled' => 1, 'visible' => -1, 'position' => 125),
|
||||
'fk_user_cancel' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user cancel', 'enabled' => 1, 'visible' => -1, 'position' => 130),
|
||||
'fk_c_paiement' => array('type' => 'integer', 'label' => 'Fk c paiement', 'enabled' => 1, 'visible' => -1, 'position' => 140),
|
||||
'paid' => array('type' => 'integer', 'label' => 'Paid', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145),
|
||||
'note_public' => array('type' => 'html', 'label' => 'Note public', 'enabled' => 1, 'visible' => 0, 'position' => 150),
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class ExpenseReportRule extends CommonObject
|
|||
'datee' => array('type' => 'date', 'label' => 'Datee', 'enabled' => 1, 'visible' => -1, 'position' => 30),
|
||||
'amount' => array('type' => 'double', 'label' => 'Amount', 'enabled' => 1, 'visible' => -1, 'position' => 40),
|
||||
'restrictive' => array('type' => 'integer', 'label' => 'Restrictive', 'enabled' => 1, 'visible' => -1, 'position' => 50),
|
||||
'fk_user' => array('type' => 'integer', 'label' => 'User', 'enabled' => 1, 'visible' => -1, 'position' => 60),
|
||||
'fk_user' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'User', 'enabled' => 1, 'visible' => -1, 'position' => 60),
|
||||
'fk_usergroup' => array('type' => 'integer', 'label' => 'Usergroup', 'enabled' => 1, 'visible' => -1, 'position' => 70),
|
||||
'fk_c_type_fees' => array('type' => 'integer', 'label' => 'Type fees', 'enabled' => 1, 'visible' => -1, 'position' => 80),
|
||||
'code_expense_rules_type' => array('type' => 'string', 'label' => 'Expense rule code', 'enabled' => 1, 'visible' => -1, 'position' => 90),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class Fichinter extends CommonObject
|
|||
'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
|
||||
'fk_soc' => array('type' => 'integer:Societe:societe/class/societe.class.php', 'label' => 'ThirdParty', 'enabled' => 'isModEnabled("societe")', 'visible' => -1, 'notnull' => 1, 'position' => 15),
|
||||
'fk_projet' => array('type' => 'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label' => 'Fk projet', 'enabled' => 'isModEnabled("project")', 'visible' => -1, 'position' => 20),
|
||||
'fk_contrat' => array('type' => 'integer', 'label' => 'Fk contrat', 'enabled' => '$conf->contrat->enabled', 'visible' => -1, 'position' => 25),
|
||||
'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'Fk contrat', 'enabled' => '$conf->contrat->enabled', 'visible' => -1, 'position' => 25),
|
||||
'ref' => array('type' => 'varchar(30)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 30),
|
||||
'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 35),
|
||||
'ref_client' => array('type' => 'varchar(255)', 'label' => 'RefCustomer', 'enabled' => 1, 'visible' => -1, 'position' => 36),
|
||||
|
|
|
|||
|
|
@ -3465,6 +3465,7 @@ class CommandeFournisseur extends CommonOrder
|
|||
$response->label = $langs->trans("SuppliersOrdersAwaitingReception");
|
||||
$response->labelShort = $langs->trans("AwaitingReception");
|
||||
$response->url = DOL_URL_ROOT.'/fourn/commande/list.php?search_status=3,4&mainmenu=commercial&leftmenu=orders_suppliers';
|
||||
$response->url_late = DOL_URL_ROOT.'/fourn/commande/list.php?mainmenu=commercial&leftmenu=orders_suppliers&search_option=recv_late';
|
||||
}
|
||||
|
||||
while ($obj = $this->db->fetch_object($resql)) {
|
||||
|
|
|
|||
|
|
@ -75,18 +75,17 @@ class FactureFournisseurRec extends CommonInvoice
|
|||
protected $table_ref_field = 'titre';
|
||||
|
||||
/**
|
||||
* @var string The label of recurring invoice
|
||||
* @var string The ref of the recurring invoice
|
||||
* @deprecated Use $title
|
||||
*/
|
||||
public $titre;
|
||||
/**
|
||||
* @var string The label of recurring invoice
|
||||
* @var string The ref of the recurring invoice
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @deprecated
|
||||
*/
|
||||
public $ref_supplier;
|
||||
/**
|
||||
|
|
@ -351,7 +350,9 @@ class FactureFournisseurRec extends CommonInvoice
|
|||
$this->title = empty($this->title) ? '' : $this->title;
|
||||
$keyforref = $this->table_ref_field;
|
||||
$this->ref = $this->$keyforref;
|
||||
|
||||
$this->ref_supplier = empty($this->ref_supplier) ? '' : $this->ref_supplier;
|
||||
|
||||
$this->usenewprice = empty($this->usenewprice) ? 0 : $this->usenewprice;
|
||||
$this->suspended = empty($this->suspended) ? 0 : $this->suspended;
|
||||
// No frequency defined then no next date to execution
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
* Copyright (C) 2015-2022 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2016-2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
|
||||
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
||||
* Copyright (C) 2023 Nick Fragoulis
|
||||
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
|
|
@ -2103,7 +2103,7 @@ class FactureFournisseur extends CommonInvoice
|
|||
* @param array<string,mixed> $array_options extrafields array
|
||||
* @param int|null $fk_unit Code of the unit to use. Null to use the default one
|
||||
* @param int $origin_id id origin document
|
||||
* @param float $pu_devise Amount in currency
|
||||
* @param float $pu_devise Amount in currency
|
||||
* @param string $ref_supplier Supplier ref
|
||||
* @param int $special_code Special code
|
||||
* @param int $fk_parent_line Parent line id
|
||||
|
|
@ -2812,7 +2812,7 @@ class FactureFournisseur extends CommonInvoice
|
|||
|
||||
$datas['picto'] = img_picto('', $picto).' <u class="paddingrightonly">'.$langs->trans("SupplierInvoice").'</u>';
|
||||
if ($this->type == self::TYPE_REPLACEMENT) {
|
||||
$datas['picto'] .= '<u class="paddingrightonly">'.$langs->transnoentitiesnoconv("InvoiceReplace").'</u>';
|
||||
$datas['picto'] .= '<u class="paddingrightonly">'.$langs->transnoentitiesnoconv("InvoiceReplacement").'</u>';
|
||||
} elseif ($this->type == self::TYPE_CREDIT_NOTE) {
|
||||
$datas['picto'] .= '<u class="paddingrightonly">'.$langs->transnoentitiesnoconv("CreditNote").'</u>';
|
||||
} elseif ($this->type == self::TYPE_DEPOSIT) {
|
||||
|
|
|
|||
|
|
@ -149,6 +149,9 @@ $search_option = GETPOST('search_option', 'alpha');
|
|||
if ($search_option == 'late') {
|
||||
$search_status = '1,2';
|
||||
}
|
||||
if ($search_option == 'recv_late') {
|
||||
$search_status = '3,4';
|
||||
}
|
||||
|
||||
$diroutputmassaction = $conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id;
|
||||
|
||||
|
|
@ -1358,7 +1361,7 @@ if ($resql) {
|
|||
}
|
||||
// alert on late date
|
||||
$moreforfilter .= '<div class="divsearchfield">';
|
||||
$moreforfilter .= $langs->trans('Alert').' <input type="checkbox" name="search_option" value="late"'.($search_option == 'late' ? ' checked' : '').'>';
|
||||
$moreforfilter .= $langs->trans('Alert').' <input type="checkbox" name="search_option" value="'.(($search_status == '3,4') ? 'recv_late' : 'late').'"'.((array_search($search_option, array('late','recv_late')) !== false) ? ' checked' : '').'>';
|
||||
$moreforfilter .= '</div>';
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
|
|
|
|||
|
|
@ -71,9 +71,9 @@ $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $
|
|||
|
||||
$id = (GETPOSTINT('facid') ? GETPOSTINT('facid') : GETPOSTINT('id'));
|
||||
$lineid = GETPOSTINT('lineid');
|
||||
$title = GETPOST('title', 'alpha');
|
||||
$libelle = GETPOST('libelle', 'alpha');
|
||||
$ref_supplier = GETPOST('ref_supplier', 'alpha');
|
||||
$ref = GETPOST('title', 'alphanohtml') ? GETPOST('title', 'alphanohtml') : GETPOST('ref', 'alphanohtml');
|
||||
$label = GETPOST('label', 'alphanohtml');
|
||||
$ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
|
||||
$projectid = GETPOSTINT('projectid');
|
||||
$year_date_when = GETPOST('year_date_when');
|
||||
$month_date_when = GETPOST('month_date_when');
|
||||
|
|
@ -105,8 +105,8 @@ $pageprev = $page - 1;
|
|||
$pagenext = $page + 1;
|
||||
|
||||
$object = new FactureFournisseurRec($db);
|
||||
if (($id > 0 || $title) && $action != 'create' && $action != 'add') {
|
||||
$ret = $object->fetch($id, $title);
|
||||
if (($id > 0 || $ref) && $action != 'create' && $action != 'add') {
|
||||
$ret = $object->fetch($id, $ref);
|
||||
if (! $ret) {
|
||||
setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
|
||||
}
|
||||
|
|
@ -218,8 +218,8 @@ if (empty($reshook)) {
|
|||
if (! $error) {
|
||||
$object->subtype = GETPOSTINT('subtype');
|
||||
$object->title = GETPOST('title', 'alphanohtml');
|
||||
$object->libelle = GETPOST('libelle', 'alpha'); // deprecated
|
||||
$object->label = GETPOST('libelle', 'alpha');
|
||||
$object->ref = GETPOST('title', 'alphanohtml');
|
||||
$object->label = GETPOST('label', 'alpha');
|
||||
$object->ref_supplier = GETPOST('ref_supplier', 'alphanohtml');
|
||||
|
||||
$object->note_private = GETPOST('note_private', 'restricthtml');
|
||||
|
|
@ -280,7 +280,6 @@ if (empty($reshook)) {
|
|||
}
|
||||
|
||||
// Delete
|
||||
//TODO : Droits
|
||||
if ($action == 'confirm_deleteinvoice' && $confirm == 'yes' && $permissiontodelete) {
|
||||
$object->delete($user);
|
||||
|
||||
|
|
@ -311,17 +310,16 @@ if (empty($reshook)) {
|
|||
}
|
||||
}
|
||||
} elseif ($action == 'settitle' && $permissiontoadd) {
|
||||
$result = $object->setValueFrom('titre', $title, '', null, 'text', '', $user);
|
||||
$result = $object->setValueFrom('titre', $ref, '', null, 'text', '', $user);
|
||||
|
||||
if ($result > 0) {
|
||||
$object->titre = $title; // deprecated
|
||||
$object->title = $title;
|
||||
$object->ref = $object->title;
|
||||
$object->title = $ref;
|
||||
$object->ref = $ref;
|
||||
} else {
|
||||
$error++;
|
||||
if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
|
||||
$langs->load("errors");
|
||||
setEventMessages($langs->trans('ErrorTitreAlreadyExists', $title), null, 'errors');
|
||||
setEventMessages($langs->trans('ErrorTitreAlreadyExists', $ref), null, 'errors');
|
||||
} else {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
}
|
||||
|
|
@ -392,16 +390,9 @@ if (empty($reshook)) {
|
|||
} elseif ($action == 'setmulticurrencyrate' && $permissiontoadd) {
|
||||
// Multicurrency rate
|
||||
$result = $object->setMulticurrencyRate((float) price2num(GETPOST('multicurrency_tx')), GETPOSTINT('calculation_mode'));
|
||||
} elseif ($action == 'setlibelle' && $permissiontoadd) {
|
||||
// Set label
|
||||
$object->fetch($id);
|
||||
$object->label = GETPOST('libelle');
|
||||
$object->libelle = $object->label;
|
||||
$result = $object->update($user);
|
||||
|
||||
if ($result < 0) {
|
||||
dol_print_error($db);
|
||||
}
|
||||
} elseif ($action == 'setlabel' && $permissiontoadd) {
|
||||
// Set bank account
|
||||
$result = $object->setValueFrom('libelle', $label, '', null, 'text', '', $user);
|
||||
}
|
||||
|
||||
// Delete line
|
||||
|
|
@ -685,7 +676,7 @@ if (empty($reshook)) {
|
|||
$date_end_fill = GETPOSTINT('date_end_fill');
|
||||
|
||||
// Margin
|
||||
$fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
|
||||
$fournprice = (int) (GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
|
||||
$buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : ''); // If buying_price is '0', we must keep this value
|
||||
|
||||
// Local Taxes
|
||||
|
|
@ -998,7 +989,7 @@ if ($action == 'create') {
|
|||
|
||||
// Label
|
||||
print '<tr><td class="titlefieldcreate">' . $langs->trans("Label") . '</td><td>';
|
||||
print '<input class="flat quatrevingtpercent" type="text" name="libelle" value="' . $object->label . '">';
|
||||
print '<input class="flat quatrevingtpercent" type="text" name="label" value="' . $object->label . '">';
|
||||
print '</td></tr>';
|
||||
|
||||
// Author
|
||||
|
|
@ -1256,8 +1247,8 @@ if ($action == 'create') {
|
|||
|
||||
// Label
|
||||
print '<tr>';
|
||||
print '<td>' . $form->editfieldkey("Label", 'libelle', $object->libelle, $object, (int) $usercancreate) . '</td>';
|
||||
print '<td>' . $form->editfieldval("Label", 'libelle', $object->libelle, $object, $usercancreate) . '</td>';
|
||||
print '<td>' . $form->editfieldkey("Label", 'label', $object->label, $object, (int) $usercancreate) . '</td>';
|
||||
print '<td>' . $form->editfieldval("Label", 'label', $object->label, $object, $usercancreate) . '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Payment term
|
||||
|
|
|
|||
|
|
@ -711,8 +711,6 @@ while ($i < $imaxinloop) {
|
|||
print $object->getLibStatut(5);
|
||||
} elseif ($key == 'rowid') {
|
||||
print $object->showOutputField($val, $key, (string) $object->id, '');
|
||||
} elseif ($key == 'label') {
|
||||
print $object->showOutputField($val, $key, $object->label, '');
|
||||
} else {
|
||||
print $object->showOutputField($val, $key, $object->$key, '');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,5 +28,5 @@ create table llx_societe_perentity
|
|||
accountancy_code_supplier varchar(32), -- supplier accountancy auxiliary account
|
||||
accountancy_code_sell varchar(32), -- Selling accountancy code
|
||||
accountancy_code_buy varchar(32), -- Buying accountancy code
|
||||
vat_reverse_charge tinyint DEFAULT 0 -- VAT reverse charge
|
||||
vat_reverse_charge tinyint DEFAULT 0
|
||||
)ENGINE=innodb;
|
||||
|
|
|
|||
|
|
@ -5227,6 +5227,7 @@ function migrate_accountingbookkeeping(int $entity)
|
|||
|
||||
$error = 0;
|
||||
$resultstring = '';
|
||||
$bookKeepingAddon = '';
|
||||
|
||||
// For the moment we set the numbering rule to neon (the rule argon has a lot of critical bugs to fix first).
|
||||
if (getDolGlobalString('BOOKKEEPING_ADDON') == '') {
|
||||
|
|
@ -5241,7 +5242,7 @@ function migrate_accountingbookkeeping(int $entity)
|
|||
if ($bookKeepingAddon === 'mod_bookkeeping_argon') {
|
||||
$db->begin();
|
||||
|
||||
$sql = "SELECT DISTINCT YEAR(doc_date) as doc_year, MONTH(doc_date) as doc_month, code_journal, piece_num FROM {$db->prefix()}accounting_bookkeeping";
|
||||
$sql = "SELECT DISTINCT YEAR(doc_date) as doc_year, MONTH(doc_date) as doc_month, code_journal, piece_num FROM ".$db->prefix()."accounting_bookkeeping";
|
||||
$sql .= " WHERE ref IS NULL AND entity = ".((int) $entity);
|
||||
$sql .= " ORDER BY doc_year, doc_month, code_journal, piece_num";
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ AccountAccounting=Accounting account
|
|||
AccountAccountingShort=Account
|
||||
SubledgerAccount=Subledger account
|
||||
SubledgerAccountLabel=Subledger account label
|
||||
LedgerAccount=Ledger account
|
||||
ShowAccountingAccount=Show accounting account
|
||||
ShowAccountingJournal=Show accounting journal
|
||||
ShowAccountingAccountInLedger=Show accounting account in ledger
|
||||
|
|
@ -512,3 +513,5 @@ ClickToShowAlreadyExportedLines=Click to show already exported lines
|
|||
NAccounts=%s accounts
|
||||
ACCOUNTING_USE_TREASURY_Desc=This is the mode for treasury accountancy. We are using the payments only and their date for doing the accountancy.
|
||||
ACCOUNTING_USE_NON_TREASURY_Desc=This is the mode for real accountancy. We are using both the invoices and payments for doing the accountancy.
|
||||
PieceDesc=The reference of the source document that generates this bank transaction (Invoice Ref, Expense report ref, ...)
|
||||
BankTransactionRef=A reference for the bank transaction (Optional, an automatic ID is already generated)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ FileCheckDolibarr=Check integrity of application files
|
|||
AvailableOnlyOnPackagedVersions=The local file for integrity checking is only available when the application is installed from an official package
|
||||
XmlNotFound=Xml Integrity File of application not found
|
||||
SessionId=Session ID
|
||||
MenuID=Menu ID
|
||||
SessionSaveHandler=Handler to save sessions
|
||||
SessionSavePath=Session save location
|
||||
PurgeSessions=Purge of sessions
|
||||
|
|
@ -1281,6 +1282,8 @@ Delays_MAIN_DELAY_CHEQUES_TO_DEPOSIT=Check deposit not done
|
|||
Delays_MAIN_DELAY_EXPENSEREPORTS=Expense report to approve
|
||||
Delays_MAIN_DELAY_HOLIDAYS=Leave requests to approve
|
||||
Delays_MAIN_DELAY_MRP=Manufacturing order in progress
|
||||
Delays_MAIN_DELAY_SUPPLIER_PROPALS_TO_CLOSE=Supplier proposal not closed
|
||||
Delays_MAIN_DELAY_SUPPLIER_PROPALS_TO_BILL=Supplier proposal not billed
|
||||
SetupDescription1=Before starting to use Dolibarr some initial parameters must be defined and modules enabled/configured.
|
||||
SetupDescription2=The following two sections are mandatory (the two first entries in the Setup menu):
|
||||
SetupDescription3=<a href="%s">%s -> %s</a><br><br>Basic parameters used to customize the default behavior of your application (e.g for country-related features).
|
||||
|
|
@ -1864,6 +1867,7 @@ DetailLangs=Lang file name for label code translation
|
|||
DetailUser=Intern / Extern / All
|
||||
Target=Target
|
||||
Targets=Targets
|
||||
OpenLinkInto=Open link into
|
||||
DetailTarget=Target for links (_blank top opens a new window)
|
||||
DetailLevel=Level (-1:top menu, 0:header menu, >0 menu and sub menu)
|
||||
ModifMenu=Menu change
|
||||
|
|
@ -2546,7 +2550,9 @@ TextTranslation=Text translation
|
|||
ImageGeneration=Image generation
|
||||
VideoGeneration=Video generation
|
||||
AudioGeneration=Audio generation
|
||||
AIPromptForFeatures=AI custom prompts or models for features
|
||||
AIPromptForFeatures=AI custom prompts for features (AI service %s)
|
||||
AIModelForFeature=AI model for features (AI service %s)
|
||||
NewCustomPrompt=New custom prompt
|
||||
AudioTranscription=Audio transcription
|
||||
AudioTranslation=Audio translation
|
||||
EnterAnIP=Enter an IP address
|
||||
|
|
@ -2591,7 +2597,7 @@ MainAuthenticationOidcLogoutRedirectUrlDesc=Dolibarr logout URL to authorize on
|
|||
MainAuthenticationOidcLoginClaimName=Login claim
|
||||
MainAuthenticationOidcLoginClaimDesc=OpenID Connect claim matching the Dolibarr user login. If not set or empty, defaults to email
|
||||
BlackListWords=Black list of words
|
||||
BlackListWordsHelp=Words must be separated by a coma (",")
|
||||
BlackListWordsHelp=List of words that will be completely removed from any answer. Words must be separated by a coma (",")
|
||||
BlackListWordsAIHelp=This is a list of words that will be completely removed from the result of any AI requests
|
||||
Pre-PromptHelp=This text will always be added before the text you enter to make an AI request
|
||||
Post-PromptHelp=This text will always be added after the text you enter to make an AI request
|
||||
|
|
@ -2634,7 +2640,7 @@ FilesIntegrityDesc=If you want to check the integrity of files instead of databa
|
|||
AttributeCodeHelp=A code of your choice (without special chars and spaces) to identify the property.<br>Note that if an object B is created from an existing object A that has a different type (for example creation of an invoice from an order), the value of the complementary attributes of A are also copied into the complementary attributes of B when the code of the attribute is the same.
|
||||
ThereIsMoreThanXAnswers=There is more than %s answers with your filter. Please add more filters...
|
||||
PdfAddTermOfSaleHelp=You can upload the file at the bottom of this setup page
|
||||
WarningOnlineSignature=Please note that this function allows a person (customer, supplier...) to insert, online, the image of his signature in the PDF document. As for a handwritten signature, such a signature can be made by anyone and might not have the same legal value as a legal electronic signature system going through an authorized trusted third party. If you need this level of security, you can contact an integrator for more information or check for addons on www.dolistore.org.
|
||||
WarningOnlineSignature=Please note that this function allows a person (customer, supplier...) to insert, online, the image of his signature in the PDF document. As for a handwritten signature, such a signature can be made by anyone and might not have the same legal value as a legal electronic signature system going through an authorized trusted third party. If you need this level of security, you can contact an integrator for more information or check for addons on %s.
|
||||
UploadExtensionRestriction=List of forbidden file extensions to upload
|
||||
UploadExtensionRestrictionExemple=htm, html, shtml, js, php
|
||||
Privileges=Privileges
|
||||
|
|
@ -2643,7 +2649,6 @@ PDF_XXX_SHOW_PRICE_INCL_TAX=Show column Price including tax
|
|||
AvailableWithSomePDFTemplatesOnly=Feature not supported on old PDF templates
|
||||
SelectAService=Select the kind of service to use
|
||||
SelectFeatureToTest=Select the feature to test
|
||||
AIModelForFeature=AI model for features (AI service %s)
|
||||
communityRepo=Community repository
|
||||
online=Online
|
||||
NotConnected=Not connected
|
||||
|
|
@ -2662,4 +2667,6 @@ MULTICURRENCY_APP_ENDPOINT=API endpoint URL to get live multicurrencies from a s
|
|||
NoWebsite=No website
|
||||
UploadName=Upload
|
||||
MAIN_SECURITY_MAXFILESIZE_DOWNLOADED=Max size of downloaded files
|
||||
ShowTopMenuURLIntoAFrame=Show the top menu URL into a frame
|
||||
ShowTopMenuURLIntoAFrame=Show the content into a frame
|
||||
SameWindow=Same window
|
||||
NewWindow=New window / New tab
|
||||
|
|
|
|||
|
|
@ -209,3 +209,4 @@ ReadMore = Read more
|
|||
ReadLess = Read less
|
||||
RecurringEvent=Recurring event
|
||||
EventPartOfARecurringSerie=Event is part of a recurring serie with ID %s
|
||||
BookCalSystem=Online booking
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ Reconciliation=Reconciliation
|
|||
RIB=Bank Account Number
|
||||
IBAN=IBAN number
|
||||
BIC=BIC/SWIFT code
|
||||
CCI=Interbank code
|
||||
SwiftValid=BIC/SWIFT valid
|
||||
SwiftNotValid=BIC/SWIFT not valid
|
||||
IbanValid=BAN valid
|
||||
|
|
|
|||
|
|
@ -465,4 +465,4 @@ ThirdPartyMustBeACustomerToCreateBANOnStripe=The third-party must be a customer
|
|||
NewSocNameForClone=New company name
|
||||
ConfirmCloneThirdparties=Are you sure that you want to clone <b>%s</b> company ?
|
||||
SocialNetworksBusiness=Social networks for company
|
||||
ErrorCommercialNotAllowedForThirdparty=The sales representative is not allowed on this company.
|
||||
ErrorCommercialNotAllowedForThirdparty=The user %s has not the permission to see all thirdparties and is not an allowed sale representative of the company.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue