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

This commit is contained in:
Laurent Destailleur 2024-12-30 21:57:18 +01:00
commit 7968fc7799
213 changed files with 2574 additions and 1779 deletions

View File

@ -36,7 +36,7 @@ Definition:
As the Developer:
1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/DCO)
1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/blob/develop/DCO)
2. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr).
3. Clone your fork.
4. Choose a branch(See the [Branches](#branches) section below).

View File

@ -18,3 +18,4 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/changed-lines-count-labeler.yml
continue-on-error: true

View File

@ -18,7 +18,7 @@ repos:
# git commit -a -m "My message" --no-verify
# (Recommendation: run git commit -a .. once, then with `--no-verify`)
- id: no-commit-to-branch
args: [--branch, develop, --pattern, \d+.0]
args: [--branch, develop, --pattern, \d+.0$]
# This checks that xml files are correct
- id: check-xml
exclude: |

View File

@ -1,6 +1,7 @@
# DOLIBARR ERP & CRM
![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg)
![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/)
[![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521)

View File

@ -1,6 +1,7 @@
# DOLIBARR ERP & CRM
![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg)
![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/)
[![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521)

View File

@ -4,7 +4,7 @@
# \brief Dolibarr package builder (tgz, zip, rpm, deb, exe, aps)
# \author (c)2004-2023 Laurent Destailleur <eldy@users.sourceforge.net>
#
# This is list of constant you can set to have generated packages moved into a specific dir:
# This is list of constant you can set to have generated packages moved into a specific dir:
#DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild'
#DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable'
#DESTIMODULES='/media/HDDATA1_LD/Mes Sites/Web/Admin1/wwwroot/files/modules'
@ -129,7 +129,7 @@ if (! $TEMP || ! -d $TEMP) {
print "$PROG.$Extension aborted.\n";
sleep 2;
exit 2;
}
}
$BUILDROOT="$TEMP/buildroot";
@ -172,7 +172,7 @@ $newbuild = $BUILD;
$newbuild =~ s/(dev|alpha)/1/gi; # dev
$newbuild =~ s/beta(.?)/2/gi; # beta (we want beta1, beta2, betax to be same package name)
$newbuild =~ s/rc(.?)/3/gi; # rc (we want rc1, rc2, rcx to be same package name)
if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc.
if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc.
# now newbuild is 0-1 or 0-4 for example. Note that for native package (see debian/source/format), we should not use a dash part but to get a better version management
$build = $newbuild;
$build =~ s/-.*$//g;
@ -190,8 +190,8 @@ for (0..@ARGV-1) {
if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; }
if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; }
if ($ARGV[$_] =~ /^-*prefix=(.+)/i) {
$PREFIX=$1;
$FILENAMESNAPSHOT.="-".$PREFIX;
$PREFIX=$1;
$FILENAMESNAPSHOT.="-".$PREFIX;
}
}
if ($ENV{"DESTIBETARC"} && $BUILD =~ /[a-z]/i) { $DESTI = $ENV{"DESTIBETARC"}; } # Force output dir if env DESTIBETARC is defined
@ -210,7 +210,7 @@ print "Target directory (DESTI) : $DESTI\n";
# Choose package targets
#-----------------------
if ($target) {
if ($target eq "ALL") {
if ($target eq "ALL") {
foreach my $key (@LISTETARGET) {
if ($key ne 'SNAPSHOT' && $key ne 'SF' && $key ne 'ASSO') { $CHOOSEDTARGET{$key}=1; }
}
@ -236,10 +236,10 @@ else {
printf(" %2d - %-14s (%s)\n",$cpt,"ASSO (publish)","Need ".$REQUIREMENTPUBLISH{"ASSO"});
$cpt=99;
printf(" %2d - %-14s (%s)\n",$cpt,"SF (publish)","Need ".$REQUIREMENTPUBLISH{"SF"});
# Ask which target to build
print "Choose one target number or several separated with space (0 - ".$cpt."): ";
$NUM_SCRIPT=<STDIN>;
$NUM_SCRIPT=<STDIN>;
chomp($NUM_SCRIPT);
if ($NUM_SCRIPT !~ /^[0-9\s]+$/)
{
@ -286,11 +286,11 @@ foreach my $target (sort keys %CHOOSEDTARGET) {
print "Error: You asked creation of several rpms. Because all rpm have same name, you must defined an environment variable DESTI to tell packager where it can create subdirs for each generated package.\n";
exit;
}
$atleastonerpm=1;
}
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target}))
$atleastonerpm=1;
}
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target}))
{
# Test
# Test
print "Test requirement for target $target: Search '$req'... ";
$newreq=$req; $newparam='';
if ($newreq eq 'zip') { $newparam.='-h'; }
@ -299,12 +299,12 @@ foreach my $target (sort keys %CHOOSEDTARGET) {
print "Test command ".$cmd."... ";
$ret=`$cmd`;
$coderetour=$?; $coderetour2=$coderetour>>8;
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
# Not found error, we try in PROGPATH
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
}
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
# Not found error
@ -333,7 +333,7 @@ $nbofpublishneedchangelog=0;
foreach my $target (sort keys %CHOOSEDTARGET) {
if ($target eq '-CHKSUM') { $nbofpublishneedchangelog++; }
if ($CHOOSEDTARGET{$target} < 0) { next; }
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM')
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM')
{
$nboftargetneedbuildroot++;
}
@ -397,10 +397,10 @@ if ($nboftargetok) {
print "Go to directory $SOURCE\n";
$olddir=getcwd();
chdir("$SOURCE");
print "Clean $SOURCE/htdocs/includes/autoload.php\n";
$ret=`rm -f $SOURCE/htdocs/includes/autoload.php`;
$ret=`git ls-files . --exclude-standard --others`;
if ($ret)
{
@ -409,7 +409,7 @@ if ($nboftargetok) {
print "Canceled.\n";
exit;
}
print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n";
$ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`;
print $ret."\n";
@ -427,13 +427,13 @@ if ($nboftargetok) {
print "Go to directory $SOURCE\n";
$olddir=getcwd();
chdir("$SOURCE");
print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n";
$ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`;
if ($ret =~ /(already exists|existe déjà)/)
{
print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? ";
$QUESTIONOVERWRITETAG=<STDIN>;
$QUESTIONOVERWRITETAG=<STDIN>;
chomp($QUESTIONOVERWRITETAG);
if ($QUESTIONOVERWRITETAG =~ /(o|y)/)
{
@ -452,7 +452,7 @@ if ($nboftargetok) {
}
chdir("$olddir");
}
# Update buildroot if required
#-----------------------------
if ($nboftargetneedbuildroot)
@ -462,7 +462,7 @@ if ($nboftargetok) {
print "Delete directory $BUILDROOT\n";
$ret=`rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/$PROJECT";
print "Copy $SOURCE into $BUILDROOT/$PROJECT\n";
@ -491,7 +491,7 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT/phpstan.neon.dist`;
$ret=`rm -f $BUILDROOT/$PROJECT/pom.xml`;
$ret=`rm -f $BUILDROOT/$PROJECT/README-*.md`;
$ret=`rm -fr $BUILDROOT/$PROJECT/build/html`;
$ret=`rm -f $BUILDROOT/$PROJECT/build/Doli*-*`;
$ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr_*.deb`;
@ -507,6 +507,7 @@ if ($nboftargetok) {
$ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr-*.xz`;
$ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr-*.zip`;
$ret=`rm -f $BUILDROOT/$PROJECT/build/doxygen/doxygen_warnings.log`;
$ret=`rm -fr $BUILDROOT/$PROJECT/build/phpstan/phpstan`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/cache.manifest`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.mysql`;
@ -560,20 +561,20 @@ if ($nboftargetok) {
$ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot11.png`;
$ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot12.png`;
# Security to avoid to package data files
# Security to avoid to package data files
print "Remove documents dir\n";
$ret=`rm -fr $BUILDROOT/$PROJECT/document`;
$ret=`rm -fr $BUILDROOT/$PROJECT/documents`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/document`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/documents`;
print "Remove subdir of custom dir\n";
print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\;\n";
$ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs but not files
print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\;\n";
$ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs, even symbolic links, but not files
# Removed known external modules to avoid any error when packaging from env where external modules are tested
# Removed known external modules to avoid any error when packaging from env where external modules are tested
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/abricot*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/allscreens*`;
@ -599,15 +600,15 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`;
# Removed other test files
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`;
$ret=`rm -fr $BUILDROOT/$PROJECT/test`;
$ret=`rm -fr $BUILDROOT/$PROJECT/Thumbs.db $BUILDROOT/$PROJECT/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/*/Thumbs.db`;
$ret=`rm -f $BUILDROOT/$PROJECT/.cvsignore $BUILDROOT/$PROJECT/*/.cvsignore $BUILDROOT/$PROJECT/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.cvsignore`;
$ret=`rm -f $BUILDROOT/$PROJECT/.gitignore $BUILDROOT/$PROJECT/*/.gitignore $BUILDROOT/$PROJECT/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.gitignore`;
# Removed files installed by the awful composer
# Removed files installed by the awful composer
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/geoip/sample*.*`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/bin`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/adapters`; # Keep this removal in case we embed libraries
@ -642,7 +643,7 @@ if ($nboftargetok) {
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/vendor`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/webmozart`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/autoload.php`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/bin`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/bin`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/*/bin`;
@ -652,14 +653,14 @@ if ($nboftargetok) {
# Build package for each target
#------------------------------
foreach my $target (sort keys %CHOOSEDTARGET)
foreach my $target (sort keys %CHOOSEDTARGET)
{
if ($CHOOSEDTARGET{$target} < 0) { next; }
if ($target eq '-CHKSUM') { next; }
print "\nBuild package for target $target\n";
if ($target eq 'SNAPSHOT')
if ($target eq 'SNAPSHOT')
{
$NEWDESTI=$DESTI;
@ -683,13 +684,13 @@ if ($nboftargetok) {
next;
}
if ($target eq 'TGZ')
if ($target eq 'TGZ')
{
$NEWDESTI=$DESTI;
if ($NEWDESTI =~ /stable/)
{
mkdir($DESTI.'/standard');
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
}
print "Remove target $FILENAMETGZ.tgz...\n";
@ -703,7 +704,7 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$FILENAMETGZ/build/exe`;
$ret=`rm -fr $BUILDROOT/$FILENAMETGZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages
print "Compress $FILENAMETGZ into $FILENAMETGZ.tgz...\n";
$cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMETGZ.tgz\" $FILENAMETGZ";
print "$cmd\n";
@ -715,14 +716,14 @@ if ($nboftargetok) {
next;
}
if ($target eq 'XZ')
if ($target eq 'XZ')
{
$NEWDESTI=$DESTI;
if ($NEWDESTI =~ /stable/)
{
mkdir($DESTI.'/standard');
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
}
}
print "Remove target $FILENAMEXZ.xz...\n";
unlink("$NEWDESTI/$FILENAMEXZ.xz");
@ -735,7 +736,7 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$FILENAMEXZ/build/exe`;
$ret=`rm -fr $BUILDROOT/$FILENAMEXZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages
print "Compress $FILENAMEXZ into $FILENAMEXZ.xz...\n";
print "Go to directory $BUILDROOT\n";
@ -751,15 +752,15 @@ if ($nboftargetok) {
$ret=`mv "$BUILDROOT/$FILENAMEXZ.xz" "$NEWDESTI/$FILENAMEXZ.xz"`;
next;
}
if ($target eq 'ZIP')
if ($target eq 'ZIP')
{
$NEWDESTI=$DESTI;
if ($NEWDESTI =~ /stable/)
{
mkdir($DESTI.'/standard');
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
}
}
print "Remove target $FILENAMEZIP.zip...\n";
unlink("$NEWDESTI/$FILENAMEZIP.zip");
@ -782,14 +783,14 @@ if ($nboftargetok) {
print $cmd."\n";
$ret= `$cmd`;
chdir("$olddir");
# Move to final dir
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
$ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
next;
}
if ($target =~ /RPM/) # Linux only
if ($target =~ /RPM/) # Linux only
{
$NEWDESTI=$DESTI;
$subdir="package_rpm_generic";
@ -800,7 +801,7 @@ if ($nboftargetok) {
{
mkdir($DESTI.'/'.$subdir);
if (-d $DESTI.'/'.$subdir) { $NEWDESTI=$DESTI.'/'.$subdir; }
}
}
if ($RPMDIR eq "") { $RPMDIR=$ENV{'HOME'}."/rpmbuild"; }
@ -813,7 +814,7 @@ if ($nboftargetok) {
print "Create directory $BUILDROOT/$FILENAMETGZ2\n";
$ret=`rm -fr $BUILDROOT/$FILENAMETGZ2`;
print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$FILENAMETGZ2\n";
$cmd="cp -pr '$BUILDROOT/$PROJECT' '$BUILDROOT/$FILENAMETGZ2'";
$ret=`$cmd`;
@ -839,7 +840,7 @@ if ($nboftargetok) {
if ($target =~ /FEDO/i) { $BUILDFICSRC="${FILENAME}_fedora.spec"; }
if ($target =~ /MAND/i) { $BUILDFICSRC="${FILENAME}_mandriva.spec"; }
if ($target =~ /OPEN/i) { $BUILDFICSRC="${FILENAME}_opensuse.spec"; }
use Date::Language;
$lang=Date::Language->new('English');
$datestring = $lang->time2str("%a %b %e %Y", time);
@ -857,7 +858,7 @@ if ($nboftargetok) {
}
close SPECFROM;
close SPECTO;
print "Copy patch file to $RPMDIR/SOURCES\n";
$ret=`cp "$SOURCE/build/rpm/dolibarr-forrpm.patch" "$RPMDIR/SOURCES"`;
$ret=`chmod 644 $RPMDIR/SOURCES/dolibarr-forrpm.patch`;
@ -879,14 +880,14 @@ if ($nboftargetok) {
next;
}
if ($target eq 'DEB')
if ($target eq 'DEB')
{
$NEWDESTI=$DESTI;
if ($NEWDESTI =~ /stable/)
{
mkdir($DESTI.'/package_debian-ubuntu');
if (-d $DESTI.'/package_debian-ubuntu') { $NEWDESTI=$DESTI.'/package_debian-ubuntu'; }
}
}
$olddir=getcwd();
@ -967,13 +968,13 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/jquery/plugins/select2/LICENSE`;
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mike42/escpos-php/LICENSE.md`;
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mobiledetect/mobiledetectlib/LICENSE.txt`;
# Removed files we don't need (already removed)
#$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/ckeditor/ckeditor/_source`;
# Rename upstream changelog to match debian rules
$ret=`mv $BUILDROOT/$PROJECT.tmp/ChangeLog $BUILDROOT/$PROJECT.tmp/changelog`;
# Prepare source package (init debian dir)
print "Create directory $BUILDROOT/$PROJECT.tmp/debian\n";
$ret=`mkdir "$BUILDROOT/$PROJECT.tmp/debian"`;
@ -1011,7 +1012,7 @@ if ($nboftargetok) {
$ret=`cp -f "$SOURCE/build/debian/dolibarr.postrm" "$BUILDROOT/$PROJECT.tmp/debian"`;
$ret=`cp -f "$SOURCE/build/debian/dolibarr.templates" "$BUILDROOT/$PROJECT.tmp/debian"`;
$ret=`cp -f "$SOURCE/build/debian/install.forced.php.install" "$BUILDROOT/$PROJECT.tmp/debian"`;
# Set owners and permissions
#print "Set owners on files/dir\n";
#$ret=`chown -R root.root $BUILDROOT/$PROJECT.tmp`;
@ -1042,8 +1043,8 @@ if ($nboftargetok) {
$ret=`$cmd`;
$cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.sh' -type f -exec chmod 755 {} \\; ";
$ret=`$cmd`;
print "Rename directory $BUILDROOT/$PROJECT.tmp into $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n";
$cmd="mv $BUILDROOT/$PROJECT.tmp $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build";
$ret=`$cmd`;
@ -1051,14 +1052,14 @@ if ($nboftargetok) {
print "Go into directory $BUILDROOT\n";
chdir("$BUILDROOT");
# We need a tarball to be able to build "quilt" debian package (not required for native but we need patch so it is not a native)
print "Compress $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build into $BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz...\n";
$cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz\" $PROJECT-$MAJOR.$MINOR.$build";
print $cmd."\n";
$ret=`$cmd`;
# Creation of source package
# Creation of source package
print "Go into directory $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n";
chdir("$BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build");
#$cmd="dpkg-source -b $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build";
@ -1077,12 +1078,12 @@ if ($nboftargetok) {
$ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`;
#$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option
#$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option
$ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`;
next;
}
if ($target eq 'EXEDOLIWAMP')
{
$NEWDESTI=$DESTI;
@ -1090,22 +1091,22 @@ if ($nboftargetok) {
{
mkdir($DESTI.'/package_windows');
if (-d $DESTI.'/package_windows') { $NEWDESTI=$DESTI.'/package_windows'; }
}
}
print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe";
if ($OS eq 'windows') {
print "Check that ISCC.exe is in your PATH.\n";
} else {
print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n";
}
$SOURCEBACK=$SOURCE;
$SOURCEBACK =~ s/\//\\/g;
print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n";
#$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!;
open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!;
@ -1118,7 +1119,7 @@ if ($nboftargetok) {
close(OUT);
print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n";
if ($OS eq 'windows') {
$cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"";
} else {
@ -1132,26 +1133,26 @@ if ($nboftargetok) {
print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n";
rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe");
print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n";
use File::Copy;
#$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`;
$ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe");
print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n";
#$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
$ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss");
next;
}
}
# Publish package for each target
#--------------------------------
foreach my $target (sort keys %CHOOSEDPUBLISH)
foreach my $target (sort keys %CHOOSEDPUBLISH)
{
if ($CHOOSEDPUBLISH{$target} < 0) { next; }
print "\nList of files to publish (BUILD=$BUILD)\n";
%filestoscansf=(
"$DESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml"=>'none', # none means it won't be published on SF
@ -1209,26 +1210,26 @@ if ($nboftargetok) {
print "\n";
}
if ($target eq 'SF' || $target eq 'ASSO')
if ($target eq 'SF' || $target eq 'ASSO')
{
print "\n";
if ($target eq 'SF') { $PUBLISH = $PUBLISHSTABLE; }
if ($target eq 'ASSO' && $BUILD =~ /[a-z]/i) { $PUBLISH = $PUBLISHBETARC.'/lastbuild'; }
if ($target eq 'ASSO' && $BUILD =~ /^[0-9]+$/) { $PUBLISH = $PUBLISHBETARC.'/stable'; }
$NEWPUBLISH=$PUBLISH;
print "Publish to target $NEWPUBLISH. Click enter or CTRL+C...\n";
# Ask which target to build
$NUM_SCRIPT=<STDIN>;
$NUM_SCRIPT=<STDIN>;
chomp($NUM_SCRIPT);
print "Create empty dir /tmp/emptydir. We need it to create target dir using rsync.\n";
$ret=`mkdir -p "/tmp/emptydir/"`;
%filestoscan=%filestoscansf;
foreach my $file (sort keys %filestoscan)
{
$found=0;
@ -1238,30 +1239,30 @@ if ($nboftargetok) {
if ($target eq 'SF') {
if ($filestoscan{$file} eq 'none') {
next;
}
}
$destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD;
}
elsif ($target eq 'ASSO' and $NEWPUBLISH =~ /stable/) {
$destFolder="$NEWPUBLISH/$filestoscanstableasso{$file}";
}
}
elsif ($target eq 'ASSO' and $NEWPUBLISH !~ /stable/) {
$destFolder="$NEWPUBLISH";
}
}
else # No more used
{
$dirnameonly=$file;
$dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/;
$dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/;
$filenameonly=$file;
$filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/;
$filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/;
$destFolder="$NEWPUBLISH/$dirnameonly";
}
print "\n";
print "Publish file ".$file." to ".$destFolder."\n";
# mkdir
# mkdir
#my $ssh = Net::SSH::Perl->new("frs.sourceforge.net");
#$ssh->login("$user","$pass");
#$ssh->login("$user","$pass");
#use String::ShellQuote qw( shell_quote );
#$ssh->cmd('mkdir '.shell_quote($destFolder).' && exit');
@ -1270,20 +1271,20 @@ if ($nboftargetok) {
#$sftp->mkdir($destFolder)
#$command="ssh eldy,dolibarr\@frs.sourceforge.net mkdir -p \"$destFolder\"";
#print "$command\n";
#print "$command\n";
#my $ret=`$command 2>&1`;
$command="rsync -s -e 'ssh' --recursive /tmp/emptydir/ \"".$destFolder."\"";
print "$command\n";
print "$command\n";
my $ret=`$command 2>&1`;
$command="rsync -s -e 'ssh' \"$file\" \"".$destFolder."\"";
print "$command\n";
print "$command\n";
my $ret2=`$command 2>&1`;
print "$ret2\n";
}
}
}
}
}
print "\n----- Summary -----\n";

View File

@ -463,7 +463,7 @@ parameters:
path: ../../htdocs/accountancy/class/accountingaccount.class.php
-
message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\<int\|string, array\{date\: mixed, ref\: mixed, lines\: non\-empty\-array\<int\|string, mixed\>\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#'
message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\<array\{date\: mixed, ref\: mixed, lines\: non\-empty\-array\<mixed\>\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#'
identifier: function.impossibleType
count: 1
path: ../../htdocs/accountancy/class/accountingjournal.class.php
@ -625,7 +625,7 @@ parameters:
path: ../../htdocs/accountancy/class/lettering.class.php
-
message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\<array\<string, int\>\>, array\<int\|string, array\<string, string\>\> given\.$#'
message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\<array\<string, int\>\>, array\<array\<string, string\>\> given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/accountancy/class/lettering.class.php
@ -894,10 +894,16 @@ parameters:
count: 1
path: ../../htdocs/adherents/card.php
-
message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/adherents/class/adherent.class.php
-
message: '#^Call to function is_array\(\) with array\<mixed\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
count: 1
path: ../../htdocs/adherents/class/adherent.class.php
-
@ -942,12 +948,6 @@ parameters:
count: 1
path: ../../htdocs/adherents/class/adherent.class.php
-
message: '#^Property Adherent\:\:\$first_subscription_amount \(int\|string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
count: 1
path: ../../htdocs/adherents/class/adherent.class.php
-
message: '#^Property Adherent\:\:\$last_subscription_amount \(int\|string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@ -1098,12 +1098,6 @@ parameters:
count: 1
path: ../../htdocs/adherents/messaging.php
-
message: '#^Variable \$socid might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/adherents/messaging.php
-
message: '#^Property Partnership\:\:\$entity \(int\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@ -1116,42 +1110,12 @@ parameters:
count: 1
path: ../../htdocs/adherents/partnership.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
count: 1
path: ../../htdocs/adherents/subscription.php
-
message: '#^Variable \$bankline in empty\(\) always exists and is not falsy\.$#'
identifier: empty.variable
count: 1
path: ../../htdocs/adherents/subscription/card.php
-
message: '#^Empty array passed to foreach\.$#'
identifier: foreach.emptyArray
count: 1
path: ../../htdocs/adherents/subscription/list.php
-
message: '#^If condition is always false\.$#'
identifier: if.alwaysFalse
count: 2
path: ../../htdocs/adherents/subscription/list.php
-
message: '#^Result of && is always false\.$#'
identifier: booleanAnd.alwaysFalse
count: 1
path: ../../htdocs/adherents/subscription/list.php
-
message: '#^Right side of && is always false\.$#'
identifier: booleanAnd.rightAlwaysFalse
count: 1
path: ../../htdocs/adherents/subscription/list.php
-
message: '#^Variable \$object might not be defined\.$#'
identifier: variable.undefined
@ -1812,6 +1776,48 @@ parameters:
count: 2
path: ../../htdocs/admin/tools/purge.php
-
message: '#^Method Documentation\:\:displayMenu\(\) has parameter \$menu with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Method Documentation\:\:displaySummary\(\) has parameter \$menu with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Method Documentation\:\:setMenu\(\) should return mixed but return statement is missing\.$#'
identifier: return.missing
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Method Documentation\:\:showCode\(\) has parameter \$lines with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Property Documentation\:\:\$menu type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Property Documentation\:\:\$summary type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Property Documentation\:\:\$view type has no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: ../../htdocs/admin/tools/ui/class/documentation.class.php
-
message: '#^Variable \$massactionbutton in empty\(\) always exists and is always falsy\.$#'
identifier: empty.variable
@ -3343,7 +3349,7 @@ parameters:
path: ../../htdocs/categories/class/categorie.class.php
-
message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\> but returns array\<int\|string, array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\> but returns array\<array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
identifier: return.type
count: 1
path: ../../htdocs/categories/class/categorie.class.php
@ -3361,7 +3367,7 @@ parameters:
path: ../../htdocs/categories/class/categorie.class.php
-
message: '#^Property Categorie\:\:\$cats \(array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\>\) does not accept array\<int\|string, array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
message: '#^Property Categorie\:\:\$cats \(array\<int, array\{rowid\: int, id\: int, fk_parent\: int, label\: string, description\: string, color\: string, position\: string, visible\: int, \.\.\.\}\>\) does not accept array\<array\{rowid\: mixed, id\: mixed, fk_parent\: mixed, label\: mixed, description\: mixed, color\: mixed, position\: mixed, visible\: mixed, \.\.\.\}\>\.$#'
identifier: assign.propertyType
count: 2
path: ../../htdocs/categories/class/categorie.class.php
@ -5311,7 +5317,7 @@ parameters:
path: ../../htdocs/compta/cashcontrol/class/cashcontrol.class.php
-
message: '#^Call to function is_array\(\) with non\-empty\-array\<int\|string, \(float\|int\)\> will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with non\-empty\-array\<\(float\|int\)\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/compta/cashcontrol/report.php
@ -5586,12 +5592,6 @@ parameters:
count: 3
path: ../../htdocs/compta/facture/class/facture-rec.class.php
-
message: '#^Parameter \#1 \$qty of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/compta/facture/class/facture-rec.class.php
-
message: '#^Parameter \#1 \$vatrate of function getLocalTaxesFromRate expects int\|string, float given\.$#'
identifier: argument.type
@ -5604,12 +5604,6 @@ parameters:
count: 1
path: ../../htdocs/compta/facture/class/facture-rec.class.php
-
message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/compta/facture/class/facture-rec.class.php
-
message: '#^Property CommonObject\:\:\$array_options \(array\<string, mixed\>\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@ -5664,12 +5658,6 @@ parameters:
count: 3
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#1 \$qty of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 2
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#1 \$substitutionarray of function complete_substitutions_array expects array\<string, string\>, array\<string, int\|string\> given\.$#'
identifier: argument.type
@ -5682,42 +5670,18 @@ parameters:
count: 2
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#15 \$pu_devise of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 2
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#2 \$alreadypaid of method CommonInvoice\:\:getLibStatut\(\) expects int, float given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 2
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#4 \$txtva of method Facture\:\:addline\(\) expects float, string given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#5 \$uselocaltax1_rate of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Parameter \#6 \$uselocaltax2_rate of function calcul_price_total expects float, string given\.$#'
identifier: argument.type
count: 1
path: ../../htdocs/compta/facture/class/facture.class.php
-
message: '#^Property CommonInvoice\:\:\$close_code \(string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@ -6601,7 +6565,7 @@ parameters:
path: ../../htdocs/compta/resultat/index.php
-
message: '#^Call to function is_array\(\) with non\-empty\-array\<int\|string, array\{NP\: mixed, N\?\: \(float\|int\), M\?\: non\-empty\-array\<0\|1\|2\|3\|4\|5\|6\|7\|8\|9\|10\|11, mixed\>\}\> will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with non\-empty\-array\<array\{NP\: mixed, N\?\: \(float\|int\), M\?\: non\-empty\-array\<0\|1\|2\|3\|4\|5\|6\|7\|8\|9\|10\|11, mixed\>\}\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/compta/resultat/result.php
@ -7969,7 +7933,7 @@ parameters:
path: ../../htdocs/core/actions_linkedfiles.inc.php
-
message: '#^Call to function is_array\(\) with non\-empty\-array\<int\|string, array\{paths\: array\{mixed\}, names\: array\{string\}, mimes\: array\{mixed\}\}\> will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with non\-empty\-array\<array\{paths\: array\{mixed\}, names\: array\{string\}, mimes\: array\{mixed\}\}\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/core/actions_massactions.inc.php
@ -10537,7 +10501,7 @@ parameters:
path: ../../htdocs/core/class/notify.class.php
-
message: '#^Call to function is_array\(\) with non\-empty\-array\<int\|string, string\> will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with non\-empty\-array\<string\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/core/class/openid.class.php
@ -12252,12 +12216,6 @@ parameters:
count: 1
path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php
-
message: '#^Variable \$outputlangsbis might not be defined\.$#'
identifier: variable.undefined
count: 7
path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php
-
message: '#^Property mod_asset_standard\:\:\$prefix has no type specified\.$#'
identifier: missingType.property
@ -13603,7 +13561,7 @@ parameters:
path: ../../htdocs/core/modules/hrm/mod_evaluation_standard.php
-
message: '#^Call to function is_array\(\) with non\-empty\-array will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with non\-empty\-list\<string\|null\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/core/modules/import/import_csv.modules.php
@ -16908,18 +16866,6 @@ parameters:
count: 1
path: ../../htdocs/core/tpl/objectline_view.tpl.php
-
message: '#^Variable \$action might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../htdocs/core/tpl/objectline_view.tpl.php
-
message: '#^Variable \$i might not be defined\.$#'
identifier: variable.undefined
count: 5
path: ../../htdocs/core/tpl/objectline_view.tpl.php
-
message: '#^Variable \$objp might not be defined\.$#'
identifier: variable.undefined
@ -23305,7 +23251,7 @@ parameters:
path: ../../htdocs/master.inc.php
-
message: '#^Call to function is_array\(\) with array\<int\|string, array\{modulenamewithcase\: mixed, moduledescriptorrelpath\: string, moduledescriptorfullpath\: mixed, moduledescriptorrootpath\: mixed, moduletype\?\: ''external''\|''internal''\}\> will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with array\<array\{modulenamewithcase\: mixed, moduledescriptorrelpath\: string, moduledescriptorfullpath\: mixed, moduledescriptorrootpath\: mixed, moduletype\?\: ''external''\|''internal''\}\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/modulebuilder/index.php
@ -24864,18 +24810,6 @@ parameters:
count: 1
path: ../../htdocs/product/canvas/product/actions_card_product.class.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/product/canvas/product/tpl/card_create.tpl.php
-
message: '#^Variable \$refalreadyexists might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/product/canvas/product/tpl/card_create.tpl.php
-
message: '#^Property ActionsCardService\:\:\$field_list has no type specified\.$#'
identifier: missingType.property
@ -24888,30 +24822,6 @@ parameters:
count: 1
path: ../../htdocs/product/canvas/service/actions_card_service.class.php
-
message: '#^Cannot access property \$control on mixed\.$#'
identifier: property.nonObject
count: 2
path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php
-
message: '#^Variable \$refalreadyexists might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php
-
message: '#^Variable \$this might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
@ -29658,12 +29568,6 @@ parameters:
count: 1
path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php
-
message: '#^Negated boolean expression is always true\.$#'
identifier: booleanNot.alwaysTrue
count: 2
path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php
-
message: '#^Property CommonObject\:\:\$ismultientitymanaged \(int\<0, 1\>\|string\) in isset\(\) is not nullable\.$#'
identifier: isset.property
@ -29676,12 +29580,6 @@ parameters:
count: 1
path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php
-
message: '#^Variable \$error in empty\(\) always exists and is always falsy\.$#'
identifier: empty.variable
count: 1
path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php
-
message: '#^Parameter \#1 \$object of method CommonDocGenerator\:\:get_substitutionarray_each_var_object\(\) expects array\<string, CommonObject\|float\|int\|string\>, RecruitmentJobPosition given\.$#'
identifier: argument.type
@ -29730,12 +29628,6 @@ parameters:
count: 1
path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php
-
message: '#^Variable \$outputlangsbis might not be defined\.$#'
identifier: variable.undefined
count: 7
path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php
-
message: '#^Variable \$badgeStatus0 might not be defined\.$#'
identifier: variable.undefined
@ -30336,12 +30228,6 @@ parameters:
count: 1
path: ../../htdocs/salaries/list.php
-
message: '#^Variable \$resteapayer might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/salaries/list.php
-
message: '#^Variable \$selected might not be defined\.$#'
identifier: variable.undefined
@ -30360,12 +30246,6 @@ parameters:
count: 2
path: ../../htdocs/salaries/paiement_salary.php
-
message: '#^Variable \$sumpaid might not be defined\.$#'
identifier: variable.undefined
count: 3
path: ../../htdocs/salaries/paiement_salary.php
-
message: '#^Negated boolean expression is always false\.$#'
identifier: booleanNot.alwaysFalse
@ -30456,24 +30336,6 @@ parameters:
count: 1
path: ../../htdocs/societe/ajax/company.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/societe/canvas/company/tpl/card_create.tpl.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/societe/canvas/company/tpl/card_edit.tpl.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php
-
message: '#^Variable \$db might not be defined\.$#'
identifier: variable.undefined
@ -30498,24 +30360,6 @@ parameters:
count: 3
path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/societe/canvas/individual/tpl/card_create.tpl.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 1
path: ../../htdocs/societe/canvas/individual/tpl/card_edit.tpl.php
-
message: '#^Variable \$canvas might not be defined\.$#'
identifier: variable.undefined
count: 2
path: ../../htdocs/societe/canvas/individual/tpl/card_view.tpl.php
-
message: '#^Variable \$objcanvas might not be defined\.$#'
identifier: variable.undefined
@ -30961,7 +30805,7 @@ parameters:
path: ../../htdocs/societe/notify/card.php
-
message: '#^Call to function is_array\(\) with array\<int\|string, array\{available\: mixed, currency\: mixed, pending\?\: \(array\|float\|int\)\}\> will always evaluate to true\.$#'
message: '#^Call to function is_array\(\) with array\<array\{available\: mixed, currency\: mixed, pending\?\: \(array\|float\|int\)\}\> will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: ../../htdocs/societe/paymentmodes.php

View File

@ -883,7 +883,7 @@ $html .= '<h2><span class="fas fa-code pictofixedwidth"></span>'.$title_security
$html .= '<div class="boxallwidth">'."\n";
$html .= '<div class="div-table-responsive">'."\n";
$html .= '<table class="list_technical_debt centpercent">'."\n";
$html .= '<tr class="trgroup"><td>Commit ID</td><td>Date</td><td style="white-space: nowrap">Reported on<br>Yogosha</td><td style="white-space: nowrap">Reported on<br>GIT</td><td style="white-space: nowrap">Reported on<br>CVE</td><td>Title</td><td>Branch of fix</td></tr>'."\n";
$html .= '<tr class="trgroup"><td>Commit ID</td><td>Date</td><td style="white-space: nowrap">Reported on<br>Yogosha</td><td style="white-space: nowrap">Reported on<br>GIT</td><td style="white-space: nowrap"><a href="https://www.cve.org/CVERecord/SearchResults?query=dolibarr">Reported on<br>CVE</a></td><td>Title</td><td>Branch of fix</td></tr>'."\n";
foreach ($arrayofalerts as $key => $alert) {
$cve = '';
$yogosha = empty($alert['issueidyogosha']) ? '' : $alert['issueidyogosha'];

View File

@ -17,7 +17,7 @@ return [
// PhanTypeMismatchProperty : 130+ occurrences
// PhanPluginUnknownArrayMethodParamType : 120+ occurrences
// PhanPluginUnknownPropertyType : 110+ occurrences
// PhanPossiblyUndeclaredVariable : 80+ occurrences
// PhanPossiblyUndeclaredVariable : 65+ occurrences
// PhanRedefineFunction : 45+ occurrences
// PhanTypeExpectedObjectPropAccess : 45+ occurrences
// PhanTypeMismatchArgumentNullableInternal : 40+ occurrences
@ -507,7 +507,7 @@ return [
'htdocs/recruitment/admin/setup_candidatures.php' => ['PhanEmptyForeach'],
'htdocs/recruitment/class/recruitmentcandidature.class.php' => ['PhanUndeclaredProperty'],
'htdocs/recruitment/class/recruitmentjobposition.class.php' => ['PhanUndeclaredProperty'],
'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'],
'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'],
'htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'],
'htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'],
'htdocs/recruitment/index.php' => ['PhanUndeclaredGlobalVariable'],
@ -523,7 +523,7 @@ return [
'htdocs/salaries/card.php' => ['PhanPossiblyUndeclaredGlobalVariable'],
'htdocs/salaries/class/api_salaries.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'],
'htdocs/salaries/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'],
'htdocs/salaries/paiement_salary.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'],
'htdocs/salaries/paiement_salary.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'],
'htdocs/salaries/virement_request.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/societe/admin/societe.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredMethod'],
'htdocs/societe/ajax/company.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'],

View File

@ -3,7 +3,8 @@
* Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2015-2020 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Jose MARTINEZ <jose.martinez@pichinov.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -68,7 +69,7 @@ class BookKeeping extends CommonObject
public $doc_date;
/**
* @var int Deadline for payment
* @var int|null|'' Deadline for payment
*/
public $date_lim_reglement;
@ -324,7 +325,7 @@ class BookKeeping extends CommonObject
$this->piece_num = 0;
// First check if line not yet already in bookkeeping.
// Note that we must include 'doc_type - fk_doc - numero_compte - label' to be sure to have unicity of line (because we may have several lines
// Note that we must include 'doc_type - fk_doc - numero_compte - label - subledger_account (if not empty)' to be sure to have unicity of line (because we may have several lines
// with same doc_type, fk_doc, numero_compte for 1 invoice line when using localtaxes with same account)
// WARNING: This is not reliable, label may have been modified. This is just a small protection.
// The page that make transfer make the test on couple (doc_type - fk_doc) only.
@ -338,6 +339,9 @@ class BookKeeping extends CommonObject
}
$sql .= " AND numero_compte = '".$this->db->escape($this->numero_compte)."'";
$sql .= " AND label_operation = '".$this->db->escape($this->label_operation)."'";
if (!empty($this->subledger_account)) {
$sql .= " AND subledger_account = '".$this->db->escape($this->subledger_account)."'";
}
$sql .= " AND entity = ".$conf->entity; // Do not use getEntity for accounting features
$resql = $this->db->query($sql);
@ -2863,10 +2867,8 @@ class BookKeeping extends CommonObject
$sql = 'SELECT';
$sql .= " t.numero_compte,";
$sql .= " t.label_compte,";
if ($separate_auxiliary_account) {
$sql .= " t.subledger_account,";
$sql .= " t.subledger_label,";
$sql .= " NULLIF(t.subledger_account, '') as subledger_account,"; // fix db issues with Null or "" values
}
$sql .= " aa.pcg_type,";
$sql .= " (SUM(t.credit) - SUM(t.debit)) as opening_balance";
@ -2878,10 +2880,11 @@ class BookKeeping extends CommonObject
$sql .= ' AND aa.pcg_type IN (' . $this->db->sanitize(implode(',', $pcg_type_filter), 1) . ')';
$sql .= " AND DATE(t.doc_date) >= '" . $this->db->idate($fiscal_period->date_start) . "'";
$sql .= " AND DATE(t.doc_date) <= '" . $this->db->idate($fiscal_period->date_end) . "'";
$sql .= ' GROUP BY t.numero_compte, t.label_compte, aa.pcg_type';
$sql .= ' GROUP BY t.numero_compte, aa.pcg_type';
if ($separate_auxiliary_account) {
$sql .= ' ,t.subledger_account, t.subledger_label';
$sql .= " , NULLIF(t.subledger_account, '')";
}
$sql .= ' HAVING (SUM(t.credit) - SUM(t.debit)) != 0 '; // Exclude rows with opening_balance = 0
$sql .= $this->db->order("t.numero_compte", "ASC");
$resql = $this->db->query($sql);
@ -2902,24 +2905,41 @@ class BookKeeping extends CommonObject
$bookkeeping = new BookKeeping($this->db);
$bookkeeping->doc_date = $new_fiscal_period->date_start;
$bookkeeping->date_lim_reglement = 0;
$bookkeeping->doc_ref = $new_fiscal_period->label;
$bookkeeping->date_lim_reglement = '';
$bookkeeping->doc_ref = $fiscal_period->label;
$bookkeeping->date_creation = $now;
$bookkeeping->doc_type = 'closure';
$bookkeeping->fk_doc = $new_fiscal_period->id;
$bookkeeping->fk_doc = $fiscal_period->id;
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
$bookkeeping->thirdparty_code = '';
if ($separate_auxiliary_account) {
$bookkeeping->subledger_account = $obj->subledger_account;
$bookkeeping->subledger_label = $obj->subledger_label;
$sql = 'SELECT';
$sql .= " subledger_label";
$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
$sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'";
$sql .= " ORDER BY doc_date DESC";
$sql .= " LIMIT 1";
$result = $this->db->query($sql);
if (!$result) {
$this->errors[] = 'Error: ' . $this->db->lasterror();
dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
$error++;
}
$objtmp = $this->db->fetch_object($result);
$bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
$bookkeeping->subledger_account = null;
$bookkeeping->subledger_label = null;
}
$bookkeeping->numero_compte = $obj->numero_compte;
$bookkeeping->label_compte = $obj->label_compte;
$accountingaccount = new AccountingAccount($this->db);
$accountingaccount->fetch(0, $obj->numero_compte);
$bookkeeping->label_compte = $accountingaccount->label; // latest account label used
$bookkeeping->label_operation = $new_fiscal_period->label;
$bookkeeping->montant = $mt;
@ -2933,8 +2953,7 @@ class BookKeeping extends CommonObject
$result = $bookkeeping->create($user);
if ($result < 0) {
$this->error = $bookkeeping->error;
$this->errors = $bookkeeping->errors;
$this->setErrorsFromObject($bookkeeping);
$error++;
break;
}
@ -2949,21 +2968,35 @@ class BookKeeping extends CommonObject
$bookkeeping = new BookKeeping($this->db);
$bookkeeping->doc_date = $new_fiscal_period->date_start;
$bookkeeping->date_lim_reglement = 0;
$bookkeeping->doc_ref = $new_fiscal_period->label;
$bookkeeping->date_lim_reglement = '';
$bookkeeping->doc_ref = $fiscal_period->label;
$bookkeeping->date_creation = $now;
$bookkeeping->doc_type = 'closure';
$bookkeeping->fk_doc = $new_fiscal_period->id;
$bookkeeping->fk_doc = $fiscal_period->id;
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
$bookkeeping->thirdparty_code = '';
if ($separate_auxiliary_account) {
$bookkeeping->subledger_label = '';
$bookkeeping->subledger_account = $obj->subledger_account;
$bookkeeping->subledger_label = $obj->subledger_label;
$sql = 'SELECT';
$sql .= " subledger_label";
$sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element;
$sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'";
$sql .= " ORDER BY doc_date DESC";
$sql .= " LIMIT 1";
$result = $this->db->query($sql);
if (!$result) {
$this->errors[] = 'Error: ' . $this->db->lasterror();
dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
$error++;
}
$objtmp = $this->db->fetch_object($result);
$bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
$bookkeeping->subledger_account = null;
$bookkeeping->subledger_label = null;
}
$bookkeeping->numero_compte = $accountingaccount->account_number;
@ -2981,8 +3014,7 @@ class BookKeeping extends CommonObject
$result = $bookkeeping->create($user);
if ($result < 0) {
$this->error = $bookkeeping->error;
$this->errors = $bookkeeping->errors;
$this->setErrorsFromObject($bookkeeping);
$error++;
}
}

View File

@ -461,12 +461,12 @@ SELECT
fk_facture,
COUNT(fd.rowid) as nb
FROM
".MAIN_DB_PREFIX."facturedet as fd
".MAIN_DB_PREFIX."facturedet as fd
WHERE
fd.product_type <= 2
AND fd.fk_code_ventilation <= 0
AND fd.total_ttc <> 0
AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).")
AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).")
GROUP BY fk_facture
";
$resql = $db->query($sql);

View File

@ -1351,7 +1351,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// EMail
print '<tr><td>'.(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '<span class="fieldrequired">' : '').$langs->trans("EMail").(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '</span>' : '').'</td>';
print '<td>'.img_picto('', 'object_email', 'class="pictofixedwidth"').'<input type="text" name="member_email" class="minwidth300" maxlength="255" value="'.(GETPOSTISSET("member_email") ? GETPOST("member_email", '', 2) : $object->email).'"></td></tr>';
print '<td>'.img_picto('', 'object_email', 'class="pictofixedwidth"').'<input type="text" name="member_email" class="minwidth300" maxlength="255" value="'.(GETPOSTISSET("member_email") ? GETPOST("member_email", 'alphanohtml', 2) : $object->email).'"></td></tr>';
// Website
print '<tr><td>'.$form->editfieldkey('Web', 'member_url', GETPOST('member_url', 'alpha'), $object, 0).'</td>';

View File

@ -236,12 +236,12 @@ class Adherent extends CommonObject
public $need_subscription;
/**
* @var int user_id
* @var int|null user_id
*/
public $user_id;
/**
* @var string user_login
* @var string|null user_login
*/
public $user_login;
@ -254,32 +254,32 @@ class Adherent extends CommonObject
// Fields loaded by fetch_subscriptions() from member table
/**
* @var int|string date
* @var int|string|null date
*/
public $first_subscription_date;
/**
* @var int|string date
* @var int|string|null date
*/
public $first_subscription_date_start;
/**
* @var int|string date
* @var int|string|null date
*/
public $first_subscription_date_end;
/**
* @var int|string date
* @var int|string|null date
*/
public $first_subscription_amount;
/**
* @var int|string date
* @var int|string|null date
*/
public $last_subscription_date;
/**
* @var int|string date
* @var int|string|null date
*/
public $last_subscription_date_start;

View File

@ -235,10 +235,10 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa
$massaction = '';
}
$permissiontoread = ($user->hasRight('adherent', 'lire') == 1);
$permissiontodelete = ($user->hasRight('adherent', 'supprimer') == 1);
$permissiontoadd = ($user->hasRight('adherent', 'creer') == 1);
$uploaddir = $conf->adherent->dir_output;
$permissiontoread = $user->hasRight('adherent', 'lire');
$permissiontodelete = $user->hasRight('adherent', 'supprimer');
$permissiontoadd = $user->hasRight('adherent', 'creer');
$uploaddir = $conf->member->dir_output;
$error = 0;
$parameters = array('socid' => isset($socid) ? $socid : null, 'arrayfields' => &$arrayfields);

View File

@ -81,7 +81,10 @@ if (!$sortfield) {
if (!$sortorder) {
$sortorder = 'DESC,DESC';
}
$socid = GETPOSTINT('socid');
if ($user->socid > 0) {
$socid = $user->socid;
}
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
$hookmanager->initHooks(array('agendathirdparty', 'globalcard'));

View File

@ -179,35 +179,33 @@ if (empty($reshook) && $action == 'setuserid' && ($user->hasRight('user', 'self'
if (empty($reshook) && $action == 'setsocid' && $permissiontoaddmember) {
$error = 0;
if (!$error) {
if (GETPOSTINT('socid') != $object->socid) { // If link differs from currently in database
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
$sql .= " WHERE fk_soc = ".((int) GETPOSTINT('socid'));
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
if ($obj && $obj->rowid > 0) {
$othermember = new Adherent($db);
$othermember->fetch($obj->rowid);
$thirdparty = new Societe($db);
$thirdparty->fetch(GETPOSTINT('socid'));
$error++;
setEventMessages($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty", $othermember->getFullName($langs), $othermember->login, $thirdparty->name), null, 'errors');
}
if (GETPOSTINT('socid') != $object->socid) { // If link differs from currently in database
$sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "adherent";
$sql .= " WHERE fk_soc = " . ((int) GETPOSTINT('socid'));
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
if ($obj && $obj->rowid > 0) {
$othermember = new Adherent($db);
$othermember->fetch($obj->rowid);
$thirdparty = new Societe($db);
$thirdparty->fetch(GETPOSTINT('socid'));
$error++;
setEventMessages($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty", $othermember->getFullName($langs), $othermember->login, $thirdparty->name), null, 'errors');
}
}
if (!$error) {
$result = $object->setThirdPartyId(GETPOSTINT('socid'));
if ($result < 0) {
dol_print_error(null, $object->error);
}
$action = '';
if (!$error) {
$result = $object->setThirdPartyId(GETPOSTINT('socid'));
if ($result < 0) {
dol_print_error(null, $object->error);
}
$action = '';
}
}
}
if ($user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscription' && !$cancel) {
if (empty($reshook) && $user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscription' && !$cancel) {
$error = 0;
$langs->load("banks");
@ -701,7 +699,7 @@ if ($user->hasRight('adherent', 'cotisation', 'creer')) {
if ($action != 'addsubscription' && $action != 'create_thirdparty') {
print '<div class="tabsAction">';
if ($object->statut > 0) {
if ($object->status > 0) {
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?rowid='.$rowid.'&action=addsubscription&token='.newToken().'">'.$langs->trans("AddSubscription")."</a></div>";
} else {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("ValidateBefore")).'">'.$langs->trans("AddSubscription").'</a></div>';

View File

@ -63,7 +63,7 @@ $search_login = GETPOST('search_login', 'alpha');
$search_note = GETPOST('search_note', 'alpha');
$search_account = GETPOST('search_account', 'alpha');
$search_amount = GETPOST('search_amount', 'alpha');
$search_all = '';
$search_all = trim(GETPOST('search_all', 'alphanohtml'));
$date_select = GETPOST("date_select", 'alpha');
@ -98,6 +98,8 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
// List of fields to search into when doing a "search in all"
$fieldstosearchall = array(
'c.rowid' => 'Ref',
'c.note' => "Label",
);
$arrayfields = array(
'd.ref' => array('label' => "Ref", 'checked' => 1),
@ -105,7 +107,7 @@ $arrayfields = array(
'd.lastname' => array('label' => "Lastname", 'checked' => 1),
'd.firstname' => array('label' => "Firstname", 'checked' => 1),
'd.login' => array('label' => "Login", 'checked' => 1),
't.libelle' => array('label' => "Label", 'checked' => 1),
'c.note' => array('label' => "Label", 'checked' => 1),
'd.bank' => array('label' => "BankAccount", 'checked' => 1, 'enabled' => (isModEnabled('bank'))),
/*'d.note_public'=>array('label'=>"NotePublic", 'checked'=>0),
'd.note_private'=>array('label'=>"NotePrivate", 'checked'=>0),*/
@ -166,7 +168,7 @@ if (empty($reshook)) {
// Mass actions
$objectclass = 'Subscription';
$objectlabel = 'Subscription';
$uploaddir = $conf->adherent->dir_output;
$uploaddir = $conf->member->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
@ -395,7 +397,6 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
if ($search_all) {
$setupstring = '';
// @phan-suppress-next-line PhanEmptyForeach
foreach ($fieldstosearchall as $key => $val) {
$fieldstosearchall[$key] = $langs->trans($val);
$setupstring .= $key."=".$val.";";
@ -474,7 +475,7 @@ if (!empty($arrayfields['d.login']['checked'])) {
print '<input class="flat maxwidth75" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'"></td>';
}
if (!empty($arrayfields['t.libelle']['checked'])) {
if (!empty($arrayfields['c.note']['checked'])) {
print '<td class="liste_titre">';
print '';
print '</td>';
@ -557,8 +558,8 @@ if (!empty($arrayfields['d.login']['checked'])) {
print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['t.libelle']['checked'])) {
print_liste_field_titre($arrayfields['t.libelle']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder);
if (!empty($arrayfields['c.note']['checked'])) {
print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder);
$totalarray['nbfield']++;
}
if (!empty($arrayfields['d.bank']['checked'])) {
@ -725,7 +726,7 @@ while ($i < $imaxinloop) {
}
// Label
if (!empty($arrayfields['t.libelle']['checked'])) {
if (!empty($arrayfields['c.note']['checked'])) {
print '<td class="tdoverflowmax400" title="'.dol_escape_htmltag($obj->note_private).'">';
print dol_escape_htmltag(dolGetFirstLineOfText($obj->note_private));
print '</td>';

View File

@ -457,6 +457,21 @@ print '<tr class="liste_titre"><th class="titlefieldcreate wordbreak">'.$langs->
print '<tr class="oddeven"><td class="fieldrequired wordbreak"><label for="name">'.$langs->trans("CompanyName").'</label></td><td>';
print '<input name="name" id="name" maxlength="'.$mysoc->fields['nom']['length'].'" class="minwidth250" value="'.dol_escape_htmltag((GETPOSTISSET('name') ? GETPOST('name', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_NOM')))).'"'.(!getDolGlobalString('MAIN_INFO_SOCIETE_NOM') ? ' autofocus="autofocus"' : '').'></td></tr>'."\n";
// Main currency
print '<tr class="oddeven"><td class="fieldrequired"><label for="currency">'.$langs->trans("CompanyCurrency").'</label></td><td>';
print img_picto('', 'multicurrency', 'class="pictofixedwidth"');
print $form->selectCurrency($conf->currency, "currency");
print '</td></tr>'."\n";
// Country
print '<tr class="oddeven"><td class="fieldrequired"><label for="selectcountry_id">'.$langs->trans("Country").'</label></td><td>';
print img_picto('', 'globe-americas', 'class="pictofixedwidth"');
print $form->select_country($mysoc->country_id, 'country_id', '', 0);
if ($user->admin) {
print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
}
print '</td></tr>'."\n";
// Address
print '<tr class="oddeven"><td><label for="MAIN_INFO_SOCIETE_ADDRESS">'.$langs->trans("CompanyAddress").'</label></td><td>';
print '<textarea name="MAIN_INFO_SOCIETE_ADDRESS" id="MAIN_INFO_SOCIETE_ADDRESS" class="quatrevingtpercent" rows="'.ROWS_3.'">'.(GETPOSTISSET('MAIN_INFO_SOCIETE_ADDRESS') ? GETPOST('MAIN_INFO_SOCIETE_ADDRESS', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS'))).'</textarea></td></tr>'."\n";
@ -468,15 +483,7 @@ print '<input class="width100" name="MAIN_INFO_SOCIETE_ZIP" id="MAIN_INFO_SOCIET
print '<tr class="oddeven" id="trtownbeforecountry"><td><label for="MAIN_INFO_SOCIETE_TOWN">'.$langs->trans("CompanyTown").'</label></td><td>';
print '<input name="MAIN_INFO_SOCIETE_TOWN" class="minwidth200" id="MAIN_INFO_SOCIETE_TOWN" value="'.dol_escape_htmltag((GETPOSTISSET('MAIN_INFO_SOCIETE_TOWN') ? GETPOST('MAIN_INFO_SOCIETE_TOWN', 'alphanohtml') : (getDolGlobalString('MAIN_INFO_SOCIETE_TOWN')))).'"></td></tr>'."\n";
// Country
print '<tr class="oddeven"><td class="fieldrequired"><label for="selectcountry_id">'.$langs->trans("Country").'</label></td><td>';
print img_picto('', 'globe-americas', 'class="pictofixedwidth"');
print $form->select_country($mysoc->country_id, 'country_id', '', 0);
if ($user->admin) {
print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
}
print '</td></tr>'."\n";
// State
print '<tr class="oddeven"><td class="wordbreak"><label for="state_id">'.$langs->trans("State").'</label></td><td>';
$state_id = 0;
if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) {
@ -487,12 +494,6 @@ print img_picto('', 'state', 'class="pictofixedwidth"');
print $formcompany->select_state($state_id, $mysoc->country_code, 'state_id', 'maxwidth200onsmartphone minwidth300');
print '</td></tr>'."\n";
// Currency
print '<tr class="oddeven"><td><label for="currency">'.$langs->trans("CompanyCurrency").'</label></td><td>';
print img_picto('', 'multicurrency', 'class="pictofixedwidth"');
print $form->selectCurrency($conf->currency, "currency");
print '</td></tr>'."\n";
// Phone
print '<tr class="oddeven"><td><label for="phone">'.$langs->trans("Phone").'</label></td><td>';
print img_picto('', 'object_phoning', '', 0, 0, 0, '', 'pictofixedwidth');
@ -604,6 +605,16 @@ if ($mysoc->country_code) {
}
print '</td></tr>';
// Object of the company
print '<tr class="oddeven"><td><label for="socialobject">'.$langs->trans("CompanyObject").'</label></td><td>';
print '<textarea class="flat quatrevingtpercent" name="socialobject" id="socialobject" rows="'.ROWS_3.'">'.(getDolGlobalString('MAIN_INFO_SOCIETE_OBJECT')).'</textarea></td></tr>';
print '</td></tr>';
// Tax ID Intra-community VAT number
print '<tr class="oddeven"><td><label for="intra_vat">'.$langs->trans("VATIntra").'</label></td><td>';
print '<input name="tva" id="intra_vat" class="minwidth200" value="'.dol_escape_htmltag(getDolGlobalString('MAIN_INFO_TVAINTRA')).'">';
print '</td></tr>';
// ProfId1
if ($langs->transcountry("ProfId1", $mysoc->country_code) != '-') {
print '<tr class="oddeven"><td><label for="profid1">'.$langs->transcountry("ProfId1", $mysoc->country_code).'</label></td><td>';
@ -714,16 +725,6 @@ if ($langs->transcountry("ProfId10", $mysoc->country_code) != '-') {
print '</td></tr>';
}
// Intra-community VAT number
print '<tr class="oddeven"><td><label for="intra_vat">'.$langs->trans("VATIntra").'</label></td><td>';
print '<input name="tva" id="intra_vat" class="minwidth200" value="'.dol_escape_htmltag(getDolGlobalString('MAIN_INFO_TVAINTRA')).'">';
print '</td></tr>';
// Object of the company
print '<tr class="oddeven"><td><label for="socialobject">'.$langs->trans("CompanyObject").'</label></td><td>';
print '<textarea class="flat quatrevingtpercent" name="socialobject" id="socialobject" rows="'.ROWS_5.'">'.(getDolGlobalString('MAIN_INFO_SOCIETE_OBJECT')).'</textarea></td></tr>';
print '</td></tr>';
print '</table>';
print '</div>';

View File

@ -8,7 +8,7 @@
* Copyright (C) 2011 Remy Younes <ryounes@gmail.com>
* Copyright (C) 2012-2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@ltairis.fr>
* Copyright (C) 2011-2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2011-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2015 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2019-2024 Frédéric France <frederic.france@free.fr>
@ -723,10 +723,8 @@ if ($id == DICT_TYPE_CONTACT) {
'supplier_proposal' => img_picto('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans('SupplierProposal'),
'order_supplier' => img_picto('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans('SupplierOrder'),
'invoice_supplier' => img_picto('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans('SupplierBill'),
'conferenceorbooth' => img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'),
);
if (getDolGlobalString('MAIN_FEATURES_LEVEL') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
$elementList['conferenceorbooth'] = img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth');
}
complete_elementList_with_modules($elementList);

View File

@ -195,8 +195,11 @@ if ($action == 'set') {
dolibarr_set_const($db, "SUPPLIER_PROPOSAL_ADDON", $value, 'chaine', 0, '', $conf->entity);
} elseif (preg_match('/set_(.*)/', $action, $reg)) {
$code = $reg[1];
$value = (GETPOST($code) ? GETPOST($code) : 1);
if ($code == "SUPPLIER_PROPOSAL_FREE_TEXT") {
$value = (GETPOST($code, 'restricthtml') ? GETPOST($code, 'restricthtml') : 1);
} else {
$value = (GETPOST($code) ? GETPOST($code) : 1);
}
$res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;

View File

@ -1,5 +1,6 @@
<?php
/* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.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
@ -57,6 +58,7 @@ class Documentation
* Constructor
*
* @param DoliDB $db Database handler
* @return void
*/
public function __construct(DoliDB $db)
{
@ -75,7 +77,6 @@ class Documentation
*/
private function setMenu()
{
global $hookmanager;
@ -223,7 +224,8 @@ class Documentation
}
/**
* Output sidebar
* Output sidebar
*
* @return void
*/
public function showSidebar()
@ -312,7 +314,8 @@ class Documentation
}
/**
* Output summary
* Output summary
*
* @param int $showsubmenu Show Sub menus: 0 = No, 1 = Yes
* @param int $showsubmenu_summary Show summary of sub menus: 0 = No, 1 = Yes
* @return void
@ -320,6 +323,7 @@ class Documentation
public function showSummary($showsubmenu = 1, $showsubmenu_summary = 1)
{
$i = 0;
$menu_entry = [];
if (!empty($this->view)) :
// On se place au bon niveau
foreach ($this->view as $view) {
@ -384,16 +388,16 @@ class Documentation
* Output a View Code area
*
* @param array $lines Lines of code to show
* @param string $option Source code language ('html', 'php' etc)
* @return void
*/
public function showCode($lines = array())
public function showCode($lines = array(), $option = 'html')
{
print '<div class="documentation-code"><pre>';
if (!empty($lines)) {
foreach ($lines as $lineofcode) {
print dol_htmlentities($lineofcode).'<br/>';
}
}
print '</pre></div>';
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
print '<div class="documentation-code">';
$content = implode("\n", $lines) . "\n";
$doleditor = new DolEditor(md5($content), $content, '', 0, 'Basic', 'In', true, false, 'ace', 0, '99%', 1);
print $doleditor->Create(1, '', false, '', $option);
print '</div>';
}
}

View File

@ -1,36 +1,39 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php';
endif;
if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php';
endif;
if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php';
endif;
// Load Dolibarr environment
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) : accessforbidden();
endif;
if ($user->socid > 0) {
accessforbidden();
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');
@ -38,8 +41,13 @@ $langs->load('uxdocumentation');
//
$documentation = new Documentation($db);
$morejs = [
'/includes/ace/src/ace.js',
'/includes/ace/src/ext-statusbar.js',
'/includes/ace/src/ext-language_tools.js',
];
// Output html head + body - Param is Title
$documentation->docHeader('Badges');
$documentation->docHeader('Badges', $morejs);
// Set view for menu and breadcrumb
// Menu must be set in constructor of documentation class
@ -49,7 +57,7 @@ $documentation->view = array('Components','Badges');
$documentation->showSidebar(); ?>
<div class="doc-wrapper">
<?php $documentation->showBreadCrumb(); ?>
<div class="doc-content-wrapper">
@ -310,4 +318,4 @@ $documentation->showSidebar(); ?>
<?php
// Output close body + html
$documentation->docFooter();
?>
?>

View File

@ -1,45 +1,52 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php';
endif;
if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php';
endif;
if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php';
endif;
// Load Dolibarr environment
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) : accessforbidden();
endif;
if ($user->socid > 0) {
accessforbidden();
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');
//
$documentation = new Documentation($db);
$morejs = [
'/includes/ace/src/ace.js',
'/includes/ace/src/ext-statusbar.js',
'/includes/ace/src/ext-language_tools.js',
];
// Output html head + body - Param is Title
$documentation->docHeader('Buttons');
$documentation->docHeader('Buttons', $morejs);
// Set view for menu and breadcrumb
// Menu must be set in constructor of documentation class
@ -128,7 +135,7 @@ $documentation->showSidebar(); ?>
' */',
'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);',
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
<!-- Example of modal usage -->
@ -144,7 +151,7 @@ $documentation->showSidebar(); ?>
$id = 'button-id-7';
$url = '#'.$id;
$params = array(
'confirm' => true
'confirm' => [],
);
print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);
@ -170,7 +177,7 @@ $documentation->showSidebar(); ?>
$id = 'button-id-9';
$url = '#'.$id;
$params = array(
'confirm' => true
'confirm' => [],
);
print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); ?>
</div>
@ -179,7 +186,7 @@ $documentation->showSidebar(); ?>
'<?php',
'// Default parameters',
'$params = array(',
' \'confirm\' => true',
' \'confirm\' => [],',
');',
'',
'// Custom parameters',
@ -189,13 +196,13 @@ $documentation->showSidebar(); ?>
' \'title\' => \'Your title to display\',',
' \'action-btn-label\' => \'Your confirm label\',',
' \'cancel-btn-label\' => \'Your cancel label\',',
' \'content\' => \'Content to display with <strong>HTML</strong> compatible <ul><li>test 01</li><li>test 02</li><li>test 03</li></ul>\'',
' \'content\' => \'Content to display with <strong>HTML</strong> compatible <ul><li>test 01</li><li>test 02</li><li>test 03</li></ul>\',',
' )',
');',
'',
'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);',
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
<!-- Example of subbutton usage -->
@ -214,13 +221,15 @@ $documentation->showSidebar(); ?>
'lang'=>'documentation@documentation',
'url'=> $submenu_url.'#'.$id,
'label' => 'My SubAction 1',
'perm' => 1
'perm' => true,
'enabled' => true,
),
array(
'lang'=>'documentation@documentation',
'url'=> $submenu_url.'#'.$id,
'label' => 'My SubAction 2',
'perm' => 0
'perm' => false,
'enabled' => true,
),
);
$params = array();
@ -250,7 +259,7 @@ $documentation->showSidebar(); ?>
');',
'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);'
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
@ -277,7 +286,7 @@ $documentation->showSidebar(); ?>
'print \' <button class="btn-low-emphasis --btn-icon" title="\'.dol_escape_htmltag($btnLabel).\'" aria-label="\'.dol_escape_htmltag($btnLabel).\'" >\'.img_picto($btnLabel, \'eraser\', \'aria-hidden="true"\', 0, 0, 1).\'</button>\';',
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
<!-- Example of subbutton usage -->
@ -313,18 +322,16 @@ $documentation->showSidebar(); ?>
'print dolGetButtonTitle($btnLabel, \'\', \'fa fa-file\', \'#\', \'\', $status);',
);
echo $documentation->showCode($lines); ?><div class="documentation-example">
echo $documentation->showCode($lines, 'php'); ?><div class="documentation-example">
<?php
$btnLabel = $langs->trans('Label');
$btnLabel = $langs->trans('Label', 'php');
print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 0, ['forcenohideoftext'=>1]); // Not Enough Permissions
print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 1, ['forcenohideoftext'=>1]); // Active
print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 2, ['forcenohideoftext'=>1]); // Active and selected
print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', -1, ['forcenohideoftext'=>1]); // Functionality is disabled
print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', -2, ['forcenohideoftext'=>1]); // Disabled without info
?>
</div>
@ -343,15 +350,9 @@ $documentation->showSidebar(); ?>
'$status = -2; // Disabled without info',
'print dolGetButtonTitle($btnLabel, \'\', \'fa fa-download\', \'#\', \'\', $status, [\'forcenohideoftext\'=>1]);',
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
</div>
</div>

View File

@ -1,37 +1,39 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php';
endif;
if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php';
endif;
if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php';
endif;
// Load Dolibarr environment
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) : accessforbidden();
endif;
if ($user->socid > 0) {
accessforbidden();
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');
@ -55,9 +57,13 @@ if ($action == 'displayeventmessage') {
//
$documentation = new Documentation($db);
$morejs = [
'/includes/ace/src/ace.js',
'/includes/ace/src/ext-statusbar.js',
'/includes/ace/src/ext-language_tools.js',
];
// Output html head + body - Param is Title
$documentation->docHeader('SetEventMessages');
$documentation->docHeader('SetEventMessages', $morejs);
// Set view for menu and breadcrumb
// Menu must be set in constructor of documentation class
@ -121,7 +127,7 @@ $documentation->showSidebar(); ?>
'setEventMessages("message", null);',
'setEventMessages(null, messages[]);',
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
<!-- Contextual variations -->
@ -156,11 +162,12 @@ $documentation->showSidebar(); ?>
</div>
<?php
$lines = array(
'<?php',
'setEventMessages("message", null)',
'setEventMessages("message", null, "warnings")',
'setEventMessages("message", null, "errors")'
);
echo $documentation->showCode($lines); ?>
echo $documentation->showCode($lines, 'php'); ?>
</div>
<!-- -->
</div>

View File

@ -1,36 +1,39 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php';
endif;
if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php';
endif;
if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php';
endif;
// Load Dolibarr environment
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) : accessforbidden();
endif;
if ($user->socid > 0) {
accessforbidden();
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');
@ -48,7 +51,7 @@ $documentation->view = array('Components');
$documentation->showSidebar(); ?>
<div class="doc-wrapper">
<?php $documentation->showBreadCrumb(); ?>
<div class="doc-content-wrapper">
@ -56,11 +59,11 @@ $documentation->showSidebar(); ?>
<h1 class="documentation-title"><?php echo $langs->trans('DocComponentsTitle'); ?></h1>
<p class="documentation-text"><?php echo $langs->trans('DocComponentsMainDescription'); ?></p>
<?php $documentation->showSummary(); ?>
<?php $documentation->showSummary(); ?>
</div>
</div>
<?php
// Output close body + html
$documentation->docFooter();
?>
?>

View File

@ -1,36 +1,39 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php';
endif;
if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php';
endif;
if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php';
endif;
// Load Dolibarr environment
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) : accessforbidden();
endif;
if ($user->socid > 0) {
accessforbidden();
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');
@ -38,8 +41,13 @@ $langs->load('uxdocumentation');
//
$documentation = new Documentation($db);
$morejs = [
'/includes/ace/src/ace.js',
'/includes/ace/src/ext-statusbar.js',
'/includes/ace/src/ext-language_tools.js',
];
// Output html head + body - Param is Title
$documentation->docHeader('Progress-bars');
$documentation->docHeader('Progress-bars', $morejs);
// Set view for menu and breadcrumb
// Menu must be set in constructor of documentation class
@ -247,6 +255,7 @@ $documentation->showSidebar(); ?>
' <div class="progress-bar progress-bar-danger" role="progressbar" style="width: 40%" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>',
'</div>',
'',
'',
);
echo $documentation->showCode($lines); ?>

View File

@ -1,17 +1,43 @@
<?php
/* 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/>.
*/
// Load Dolibarr environment
@include '../../main.inc.php';
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*
* @var int $dolibarr_main_prod
*/
// Security
if ($dolibarr_main_prod) {
accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1');
}
// Protection if external user
if ($user->socid > 0) {
accessforbidden();
}
$optioncss = GETPOST('optioncsss', 'alpha');
/*
* View
@ -19,7 +45,9 @@ if ($dolibarr_main_prod) {
$form = new Form($db);
$usedolheader = 1; // 1 = Test inside a dolibarr page, 0 = Use hard coded header
// 1 = Test inside a dolibarr page, 0 = Use hard coded header
// Using a dolibarr constant avoid phpstan hardcoded value always true or false
$usedolheader = getDolGlobalInt('MAIN_TEST_UI_IN_DOLIBARR_PAGE', 1);
// HEADER
//--------
@ -163,15 +191,14 @@ $productspecimen = new Product($db);
$productspecimen->initAsSpecimen();
$object = $productspecimen;
$param = '';
$actioncode = '';
$status = '';
$filter = '';
$filtert = '';
$socid = 0;
$type = 0;
$usergroup = 0;
$sortfield = 'aaa';
$actioncode = getDolGlobalString('MAIN_TEST_UI_ACTION_CODE'); // '' by default
$status = getDolGlobalString('MAIN_TEST_UI_STATUS'); // '' by default;
$filter = getDolGlobalString('MAIN_TEST_UI_FILTER'); // '' by default;
$filtert = getDolGlobalString('MAIN_TEST_UI_FILTERT'); // '' by default;
$socid = getDolGlobalInt('MAIN_TEST_UI_SOCID', 0); // 0 by default;
$type = getDolGlobalInt('MAIN_TEST_UI_TYPE', 0); // 0 by default;
$usergroup = getDolGlobalInt('MAIN_TEST_UI_USERGROUP', 0); // 0 by default;
$sortfield = getDolGlobalString('MAIN_TEST_UI_SORTFIELD', 'aaa'); // 'aaa' by default;
$sortorder = 'ASC';
$tasksarray = array(1, 2, 3); // To force having several lines
$tagidfortablednd = 'tablelines3';
@ -242,18 +269,16 @@ $cate_arbo = array('field1' => 'value1d into the select list D', 'field2' => 'va
$moreforfilter .= $form->selectarray('search_ddd', $cate_arbo, '', 1, 0, 0, '', 0, 0, 0, '', 'maxwidth300', 1); // List with js combo forced
$moreforfilter .= '</div>';
if (!empty($moreforfilter)) {
print '<div class="liste_titre liste_titre_bydiv centpercent">';
print $moreforfilter;
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print '</div>';
}
print '<div class="liste_titre liste_titre_bydiv centpercent">';
print $moreforfilter;
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print '</div>';
?>
<table class="stripe row-border order-column centpercent tagtable liste<?php echo $moreforfilter ? " listwithfilterbefore" : ""; ?>" id="tablelines3">
<table class="stripe row-border order-column centpercent tagtable liste<?php echo /* $moreforfilter ? */ " listwithfilterbefore" /* : "" */; ?>" id="tablelines3">
<thead>
<tr class="liste_titre">
<?php print getTitleFieldOfList($langs->trans('title1'), 0, $_SERVER["PHP_SELF"], 'aaa', '', '', 'align="left"', $sortfield, $sortorder); ?>

View File

@ -1,4 +1,20 @@
<?php
/* 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/>.
*/
if (!defined('NOREQUIRESOC')) {
define('NOREQUIRESOC', '1');
}
@ -25,9 +41,18 @@ if (!defined('NOREQUIREMENU')) {
}
session_cache_limiter('public');
require_once '../../main.inc.php';
require '../../../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*
* @var int $dolibarr_main_prod
*/
// Security
if ($dolibarr_main_prod) {
accessforbidden();
@ -129,7 +154,7 @@ llxHeader('', 'Documentation and examples for theme');
$url = '#'.$id;
$userRight = 1;
$params = array(
'confirm' => true
'confirm' => [],
);
print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);
@ -142,13 +167,13 @@ llxHeader('', 'Documentation and examples for theme');
$url = $_SERVER['PHP_SELF'] . '?token='.newToken().'#'.$id;
$params = array(
'confirm' => array(
'confirm' => array(
'url' => 'your confirm action url',
'title' => 'Your title to display',
'action-btn-label' => 'Your confirm label',
'cancel-btn-label' => 'Your cancel label',
'content' => 'Content to display with <strong>HTML</strong> compatible <ul><li>test 01</li><li>test 02</li><li>test 03</li></ul>'
)
'content' => 'Content to display with <strong>HTML</strong> compatible <ul><li>test 01</li><li>test 02</li><li>test 03</li></ul>',
)
);
print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);
@ -168,7 +193,7 @@ llxHeader('', 'Documentation and examples for theme');
$url = '#'.$id;
$userRight = 0;
$params = array(
'confirm' => true
'confirm' => [],
);
print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);
@ -181,13 +206,13 @@ llxHeader('', 'Documentation and examples for theme');
$url = $_SERVER['PHP_SELF'] . '?token='.newToken().'#'.$id;
$params = array(
'confirm' => array(
'confirm' => array(
'url' => 'your confirm action url',
'title' => 'Your title to display',
'action-btn-label' => 'Your confirm label',
'cancel-btn-label' => 'Your cancel label',
'content' => 'Content to display with <strong>HTML</strong> compatible <ul><li>test 01</li><li>test 02</li><li>test 03</li></ul>'
)
'content' => 'Content to display with <strong>HTML</strong> compatible <ul><li>test 01</li><li>test 02</li><li>test 03</li></ul>',
)
);
print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);

View File

@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
//define("NOLOGIN",1); // This means this output page does not require to be logged.
/*if (!defined('NOSESSION')) {
@ -21,9 +22,18 @@ define("NOCSRFCHECK", 1); // We accept to go on this page from external web site
}*/
// Load Dolibarr environment
require '../../main.inc.php';
require '../../../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*
* @var int $dolibarr_main_prod
*/
// Security
if ($dolibarr_main_prod) {
accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1');

View File

@ -1,32 +1,31 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../../main.inc.php")) {
$res=@include '../../main.inc.php';
}
if (! $res && file_exists("../../../main.inc.php")) {
$res=@include '../../../main.inc.php';
}
if (! $res && file_exists("../../../../main.inc.php")) {
$res=@include '../../../../main.inc.php';
}
// Load Dolibarr environment
require '../../../../main.inc.php';
/**
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) {
@ -34,7 +33,7 @@ if ($user->socid > 0) {
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');

View File

@ -1,36 +1,38 @@
<?php
/*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the
* GNU Affero General Public License (AGPL) as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 AGPL for more details.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU AGPL
* along with this program. If not, see <https://www.gnu.org/licenses/agpl-3.0.html>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$res=0;
if (! $res && file_exists("../main.inc.php")) : $res=@include '../main.inc.php';
endif;
if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php';
endif;
if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php';
endif;
// Load Dolibarr environment
require '../../../main.inc.php';
/**
* @var DoliDB $db
* @var Translate $langs
* @var User $user
*/
// Protection if external user
if ($user->socid > 0) : accessforbidden();
endif;
if ($user->socid > 0) {
accessforbidden();
}
// Includes
dol_include_once('admin/tools/ui/class/documentation.class.php');
require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
// Load documentation translations
$langs->load('uxdocumentation');
@ -48,7 +50,7 @@ $documentation->view = array('DocumentationHome');
$documentation->showSidebar(); ?>
<div class="doc-wrapper">
<?php $documentation->showBreadCrumb(); ?>
<div class="doc-content-wrapper">
@ -61,4 +63,4 @@ $documentation->showSidebar(); ?>
<?php
// Output close body + html
$documentation->docFooter();
?>
?>

View File

@ -456,6 +456,8 @@ if ($id) {
print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
// Form to add a new line
@ -471,12 +473,12 @@ if ($id) {
// dans les dictionnaires de donnees
$valuetoshow = ucfirst($fieldlist[$field]); // By default
$valuetoshow = $langs->trans($valuetoshow); // try to translate
$align = '';
$css = '';
if ($fieldlist[$field] == 'lang') {
$valuetoshow = $langs->trans("Language");
}
if ($valuetoshow != '') {
print '<td class="'.$align.'">';
print '<td class="'.$css.'">';
if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
print '<a href="'.$tabhelp[$id][$value].'" target="_blank" rel="noopener noreferrer">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>';
} elseif (!empty($tabhelp[$id][$value])) {
@ -523,6 +525,8 @@ if ($id) {
}
print '</table>';
print '</div>';
print '</form>';
@ -631,15 +635,24 @@ if ($id) {
foreach ($fieldlist as $field => $value) {
$showfield = 1;
$fieldname = $fieldlist[$field];
$align = "left";
$css = "";
if ($fieldlist[$field] == 'description') {
$css .= ' tdoverflowmax300';
}
if (in_array($fieldname, array('pageviews_total', 'pageviews_previous_month'))) {
$align = 'right';
$css = 'right';
}
if ($fieldlist[$field] == 'date_creation') {
$css .= ' nowraponall';
}
if ($fieldlist[$field] == 'lastaccess') {
$css .= ' nowraponall';
}
$valuetoshow = $obj->$fieldname;
// Show value for field
if ($showfield) {
print '<td class="'.$align.'">'.$valuetoshow.'</td>';
print '<td class="'.$css.'">'.$valuetoshow.'</td>';
}
}
}

View File

@ -585,7 +585,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
$tmparray = $object->product->getSellPrice($mysoc, $mysoc);
$manufacturedvalued = $tmparray['pu_ht'] * $object->qty;
}
print '<tr><td>'.$langs->trans("ManufacturingGeneratedValue").'</td><td>'.price($manufacturedvalued).'</td></tr>';
print '<tr><td>'.$langs->trans("ManufacturingGeneratedValue").'</td><td><span class="amount">'.price($manufacturedvalued).'</span></td></tr>';
// Other attributes
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';

View File

@ -1546,8 +1546,8 @@ if ($action == 'create') {
$listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing
}
}
print '<div class="assignedtouser">';
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid);
print '<!-- list of user to assign --><div class="assignedtouser">';
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid);
print '</div>';
print '</td></tr>';
@ -1811,7 +1811,7 @@ if ($action == 'create') {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
const reminderDefaultEventTypes = '.$reminderDefaultEventTypes.';
const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
$("#actioncode").change(function(){
var selected_event_type = $("#actioncode option:selected").val();
@ -1820,9 +1820,9 @@ if ($action == 'create') {
$("#addreminder").prop("checked", true);
// Set period with default reminder period
$("[name=\"offsetvalue\"]").val("' . $reminderDefaultOffset . '");
$("[name=\"offsetvalue\"]").val(\'' . dol_escape_js((string) $reminderDefaultOffset) . '\');
$("#select_offsetunittype_duration").select2("destroy");
$("#select_offsetunittype_duration").val("'.$reminderDefaultUnit.'");
$("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
$("#select_offsetunittype_duration").select2();
$("#selectremindertype").select2("destroy");
@ -1832,7 +1832,7 @@ if ($action == 'create') {
// Set default reminder mail model
$("#select_actioncommsendmodel_mail").closest("tr").show();
$("#select_actioncommsendmodel_mail").select2("destroy");
$("#select_actioncommsendmodel_mail").val("'.$reminderDefaultEmailModel.'");
$("#select_actioncommsendmodel_mail").val(\''.dol_escape_js((string) $reminderDefaultEmailModel).'\');
$("#select_actioncommsendmodel_mail").select2();
}
});
@ -1955,6 +1955,8 @@ if ($id > 0) {
}
if ($action == 'edit') {
$caneditdateorowner = ($object->type != 'systemauto');
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
@ -1972,7 +1974,9 @@ if ($id > 0) {
$(".fulldayendmin").prop("disabled", true).val("59");
}
}
setdatefields();
'.($caneditdateorowner ? ' setdatefields();' : '').'
$("#fullday").change(function() {
setdatefields();
});
@ -2052,7 +2056,8 @@ if ($id > 0) {
print '<tr><td'.(!getDolGlobalString('AGENDA_USE_EVENT_TYPE') ? ' class="fieldrequired titlefieldcreate"' : '').'>'.$langs->trans("Title").'</td><td colspan="3"><input type="text" name="label" class="soixantepercent" value="'.$object->label.'"></td></tr>';
// Full day event
print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td colspan="3" class="valignmiddle height30 small"><input type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'>';
print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td colspan="3" class="valignmiddle height30 small">';
print '<input '.($caneditdateorowner ? '' : ' disabled').' type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'>';
print '<label for="fullday">'.$langs->trans("EventOnFullDay").'</label>';
// // Recurring event
@ -2123,9 +2128,9 @@ if ($id > 0) {
*/
print '</td><td td colspan="3">';
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel');
print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 2, ($caneditdateorowner ? 0 : 1), 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel');
print ' <span class="hideonsmartphone">&nbsp; &nbsp; - &nbsp; &nbsp;</span> ';
print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel');
print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 2, ($caneditdateorowner ? 0 : 1), 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel');
print '</td></tr>';
print '<tr><td class="">&nbsp;</td><td></td></tr>';
@ -2164,7 +2169,7 @@ if ($id > 0) {
print '<tr><td class="tdtop nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td colspan="3">';
print '<div class="assignedtouser">';
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid);
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, $caneditdateorowner);
print '</div>';
/*if (in_array($user->id,array_keys($listofuserid)))
{
@ -2414,7 +2419,7 @@ if ($id > 0) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
const reminderDefaultEventTypes = '.$reminderDefaultEventTypes.';
const reminderDefaultEventTypes = \''.dol_escape_js($reminderDefaultEventTypes).'\';
$("#actioncode").change(function(){
var selected_event_type = $("#actioncode option:selected").val();
@ -2423,9 +2428,9 @@ if ($id > 0) {
$("#addreminder").prop("checked", true);
// Set period with default reminder period
$("#offsetvalue").val('.$reminderDefaultOffset.');
$("#offsetvalue").val(\''.dol_escape_js($reminderDefaultOffset).'\');
$("#select_offsetunittype_duration").select2("destroy");
$("#select_offsetunittype_duration").val("'.$reminderDefaultUnit.'");
$("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\');
$("#select_offsetunittype_duration").select2();
$("#selectremindertype").select2("destroy");
@ -2435,7 +2440,7 @@ if ($id > 0) {
// Set default reminder mail model
$("#select_actioncommsendmodel_mail").closest("tr").show();
$("#select_actioncommsendmodel_mail").select2("destroy");
$("#select_actioncommsendmodel_mail").val("'.$reminderDefaultEmailModel.'");
$("#select_actioncommsendmodel_mail").val(\''.dol_escape_js($reminderDefaultEmailModel).'\');
$("#select_actioncommsendmodel_mail").select2();
}
});

View File

@ -569,12 +569,12 @@ $viewmode .= '<span class="marginrightonly"></span>'; // To add a space before t
$newparam = '';
$newcardbutton = '';
if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
$tmpforcreatebutton = dol_getdate(dol_now(), true);
$tmpforcreatebutton = dol_getdate(dol_now('tzuserrel'), true);
$newparam .= '&month='.((int) $month).'&year='.((int) $tmpforcreatebutton['year']).'&mode='.urlencode($mode);
//$param='month='.$monthshown.'&year='.$year;
$hourminsec = dol_print_date(dol_mktime(10, 0, 0, 1, 1, 1970, 'gmt'), '%H', 'gmt').'0000'; // Set $hourminsec to '100000' to auto set hour to 10:00 at creation
//$hourminsec = dol_print_date(dol_mktime(10, 0, 0, 1, 1, 1970, 'gmt'), '%H', 'gmt').'0000'; // Set $hourminsec to '100000' to auto set hour to 10:00 at creation
$urltocreateaction = DOL_URL_ROOT.'/comm/action/card.php?action=create';
$urltocreateaction .= '&apyear='.$tmpforcreatebutton['year'].'&apmonth='.$tmpforcreatebutton['mon'].'&apday='.$tmpforcreatebutton['mday'].'&aphour='.$tmpforcreatebutton['hours'].'&apmin='.$tmpforcreatebutton['minutes'];
@ -2001,9 +2001,14 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa
$nextindextouse++; // Prepare to use next color
}
}
//print '|'.($color).'='.($idusertouse?$idusertouse:0).'='.$colorindex.'<br>';
// Define color // @suppress-next-line PhanPluginPrintfIncompatibleArgumentType
$color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
if (isset($theme_datacolor[$colorindex])) {
$color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]);
} elseif (getDolGlobalString('THEME_ELDY_BACKBODY')) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
$color = colorArrayToHex(explode(',', getDolGlobalString('THEME_ELDY_BACKBODY')));
} else {
$color = "ffffff";
}
}
$cssclass = $cssclass.' eventday_'.$ymd;
@ -2377,7 +2382,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa
function dol_color_minus($color, $minus, $minusunit = 16)
{
$newcolor = $color;
if ($minusunit == 16) {
if ($minusunit == 16 && is_array($newcolor)) {
$newcolor[0] = dechex(max(min(hexdec($newcolor[0]) - $minus, 15), 0));
$newcolor[2] = dechex(max(min(hexdec($newcolor[2]) - $minus, 15), 0));
$newcolor[4] = dechex(max(min(hexdec($newcolor[4]) - $minus, 15), 0));

View File

@ -736,13 +736,13 @@ $viewmode .= '</div>';
$viewmode .= '<span class="marginrightonly"></span>';
$tmpforcreatebutton = dol_getdate(dol_now(), true);
$tmpforcreatebutton = dol_getdate(dol_now('tzuserrel'), true);
$newparam = '&month='.str_pad((string) $month, 2, "0", STR_PAD_LEFT).'&year='.$tmpforcreatebutton['year'];
$url = DOL_URL_ROOT.'/comm/action/card.php?action=create';
$url .= '&apyear='.$tmpforcreatebutton['year'].'&apmonth='.$tmpforcreatebutton['mon'].'&apday='.$tmpforcreatebutton['mday'].'&aphour='.$tmpforcreatebutton['hours'].'&apmin='.$tmpforcreatebutton['minutes'];
$url .= '&apyear='.$tmpforcreatebutton['year'].'&apmonth='.$tmpforcreatebutton['mon'].'&apday='.$tmpforcreatebutton['mday'];
$url .= '&aphour='.$tmpforcreatebutton['hours'].'&apmin='.$tmpforcreatebutton['minutes'];
$url .= '&backtopage='.urlencode($_SERVER["PHP_SELF"].($newparam ? '?'.$newparam : ''));
$newcardbutton = dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', $url, '', (int) ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')));

View File

@ -487,7 +487,7 @@ $viewmode .= '<span class="marginrightonly"></span>';
$newparam = '';
$newcardbutton = '';
if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
$tmpforcreatebutton = dol_getdate(dol_now(), true);
$tmpforcreatebutton = dol_getdate(dol_now('tzuserrel'), true);
$newparam .= '&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$tmpforcreatebutton['year'];

View File

@ -492,7 +492,7 @@ $viewmode .= '<span class="marginrightonly"></span>';
$newparam = '';
$newcardbutton = '';
if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
$tmpforcreatebutton = dol_getdate(dol_now(), true);
$tmpforcreatebutton = dol_getdate(dol_now('tzuserrel'), true);
$newparam .= '&month='.urlencode(str_pad((string) $month, 2, "0", STR_PAD_LEFT)).'&year='.((int) $tmpforcreatebutton['year']);
if ($begin_h !== '') {

View File

@ -376,7 +376,7 @@ if ($object->id > 0) {
}
if ($object->client) {
$langs->load("compta");
$langs->loadLangs(array("compta", "accountancy"));
print '<tr><td>';
print $langs->trans('CustomerCode').'</td><td>';
@ -1712,35 +1712,37 @@ if ($object->id > 0) {
}
// Add invoice
if ($user->socid == 0) {
if (isModEnabled('deplacement') && $object->status == 1) {
$langs->load("trips");
print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/deplacement/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddTrip").'</a></div>';
}
if (isModEnabled('deplacement') && $object->status == 1) {
$langs->load("trips");
print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/deplacement/card.php?socid='.$object->id.'&amp;action=create">'.$langs->trans("AddTrip").'</a></div>';
}
if (isModEnabled('invoice') && $object->status == 1) {
if (!$user->hasRight('facture', 'creer')) {
$langs->load("bills");
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("NotAllowed")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
if (isModEnabled('invoice') && $object->status == 1) {
if (!$user->hasRight('facture', 'creer')) {
$langs->load("bills");
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("NotAllowed")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
} else {
$langs->loadLangs(array("orders", "bills"));
if ($object->client != 0 && $object->client != 2) {
print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&socid='.$object->id.'">'.$langs->trans("AddBill").'</a></div>';
} else {
$langs->loadLangs(array("orders", "bills"));
if (isModEnabled('order')) {
if ($object->client != 0 && $object->client != 2) {
if (!empty($orders2invoice) && $orders2invoice > 0) {
print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->id.'&search_billed=0&autoselectall=1">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
} else {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("NoOrdersToInvoice")).'" href="#">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
}
} else {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
}
}
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
}
}
}
if (isModEnabled('invoice') && $object->status == 1) {
if ($user->hasRight('facture', 'creer')) {
if (isModEnabled('order')) {
if ($object->client != 0 && $object->client != 2) {
print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&socid='.$object->id.'">'.$langs->trans("AddBill").'</a></div>';
if (!empty($orders2invoice) && $orders2invoice > 0) {
print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->id.'&search_billed=0&autoselectall=1">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
} else {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("NoOrdersToInvoice")).'" href="#">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
}
} else {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("CreateInvoiceForThisCustomer").'</a></div>';
}
}
}

View File

@ -889,7 +889,7 @@ if ($action == 'create') { // aaa
print '<div style="padding-top: 10px">';
// wysiwyg editor
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, true, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%');
$doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%');
$doleditor->Create();
print '</div>';
@ -1174,7 +1174,7 @@ if ($action == 'create') { // aaa
}
if (($object->status == 0 || $object->status == 1 || $object->status == 2) && $user->hasRight('mailing', 'creer')) {
if (isModEnabled('fckeditor') && getDolGlobalString('FCKEDITOR_ENABLE_MAILING') && $object->messtype != 'sms') {
if (isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_MAILING') && $object->messtype != 'sms') {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Edit").'</a>';
} else {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=edittxt&token='.newToken().'&id='.$object->id.'">'.$langs->trans("EditWithTextEditor").'</a>';
@ -1329,7 +1329,7 @@ if ($action == 'create') { // aaa
$readonly = 1;
// wysiwyg editor
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, true, !getDolGlobalString('FCKEDITOR_ENABLE_MAILING') ? 0 : 1, 20, '90%', $readonly);
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%', $readonly);
$doleditor->Create();
} else {
print dol_htmlentitiesbr($object->body);
@ -1548,19 +1548,19 @@ if ($action == 'create') { // aaa
if ($action == 'edit') {
// wysiwyg editor
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%');
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%');
$doleditor->Create();
}
if ($action == 'edittxt') {
// wysiwyg editor
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, 0, 20, '90%');
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 0, 20, '90%');
$doleditor->Create();
}
if ($action == 'edithtml') {
// HTML source editor
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, 'ace', 20, '90%');
$doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 'ace', 20, '90%');
$doleditor->Create(0, '', false, 'HTML Source', 'php');
}

View File

@ -1983,8 +1983,8 @@ while ($i < $imaxinloop) {
}
// Country
if (!empty($arrayfields['country.code_iso']['checked'])) {
print '<td class="center">';
$tmparray = getCountry($obj->fk_pays, 'all');
print '<td class="center tdoverflowmax100" title="'.dolPrintHTML($tmparray['label']).'">';
print $tmparray['label'];
print '</td>';
if (!$i) {

View File

@ -691,4 +691,29 @@ class BankAccounts extends DolibarrApi
)
);
}
/**
* Get current account balance by ID
*
* @param int $id ID of account
* @return float $balance balance
* @url GET {id}/balance
*
* @throws RestException
*/
public function getBalance($id)
{
if (!DolibarrApiAccess::$user->hasRight('banque', 'lire')) {
throw new RestException(403);
}
$account = new Account($this->db);
$result = $account->fetch($id);
if (!$result) {
throw new RestException(404, 'account not found');
}
$balance = $account->solde(1); //1=Exclude future operation date (this is to exclude input made in advance and have real account sold)
return $balance;
}
}

View File

@ -834,6 +834,7 @@ class PaymentVarious extends CommonObject
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$bankline = ((empty($arraydata['bankline']) || empty($arraydata['bankline']->id)) ? 0 : $arraydata['bankline']);
$formatedaccountancycode = (empty($arraydata['formatedaccountancycode']) ? '' : $arraydata['formatedaccountancycode']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
@ -854,9 +855,14 @@ class PaymentVarious extends CommonObject
$return .= ' - <span class="info-box-label">'.$this->type_payment.'</span>';
}
}
if (property_exists($this, 'accountancy_code')) {
if (!empty($formatedaccountancycode)) {
$return .= '<br><span class="opacitymedium">'.$langs->trans("Account").'</span> : <span class="info-box-label" title="'.$this->accountancy_code.'">';
$return .= $formatedaccountancycode;
$return .= '</span>';
} elseif (property_exists($this, 'accountancy_code')) {
$return .= '<br><span class="opacitymedium">'.$langs->trans("Account").'</span> : <span class="info-box-label" title="'.$this->accountancy_code.'">'.$this->accountancy_code.'</span>';
}
if (property_exists($this, 'amount')) {
$return .= '<br><span class="opacitymedium">'.$langs->trans("Debit").'</span> : <span class="info-box-label amount">'.price($this->amount).'</span>';
}

View File

@ -33,7 +33,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
/**
* @var Conf $conf
@ -253,7 +255,7 @@ if ($arrayfields['bank']['checked'] && isModEnabled('accounting')) {
if ($arrayfields['bank']['checked']) {
$accountstatic = new Account($db);
}
if ($arrayfields['project']['checked']) {
if (isModEnabled('project') && $arrayfields['project']['checked']) {
$proj = new Project($db);
}
@ -548,7 +550,7 @@ if ($arrayfields['type']['checked']) {
}
// Project
if ($arrayfields['project']['checked']) {
if (isModEnabled('project') && $arrayfields['project']['checked']) {
print '<td class="liste_titre">';
// TODO
print '</td>';
@ -653,7 +655,7 @@ if ($arrayfields['type']['checked']) {
print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], 'type', '', $param, '', $sortfield, $sortorder, 'center ');
$totalarray['nbfield']++;
}
if ($arrayfields['project']['checked']) {
if (isModEnabled('project') && $arrayfields['project']['checked']) {
print_liste_field_titre($arrayfields['project']['label'], $_SERVER["PHP_SELF"], 'fk_project', '', $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
}
@ -716,25 +718,23 @@ while ($i < $imaxinloop) {
$variousstatic->label = $obj->label;
$variousstatic->datep = $obj->datep;
$variousstatic->type_payment = $obj->payment_code;
$variousstatic->accountancy_code = $obj->accountancy_code;
$variousstatic->amount = $obj->amount;
$accountingaccount->fetch(0, $obj->accountancy_code, 1);
$variousstatic->accountancy_code = $accountingaccount->getNomUrl(0, 0, 1, $obj->accountingaccount, 1);
if ($mode == 'kanban') {
if ($obj->fk_bank > 0) {
$bankline->fetch($obj->fk_bank);
} else {
$bankline->id = 0;
}
$accountingaccount->fetch(0, $obj->accountancy_code, 1);
if ($i == 0) {
print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
print '<div class="box-flex-container kanban">';
}
// Output Kanban
print $variousstatic->getKanbanView('', array('selected' => in_array($object->id, $arrayofselected), 'bankline' => $bankline));
print $variousstatic->getKanbanView('', array('selected' => in_array($object->id, $arrayofselected), 'bankline' => $bankline, 'formatedaccountancycode' => $accountingaccount->getNomUrl(0, 0, 1, $obj->accountancy_code, 1)));
if ($i == ($imaxinloop) - 1) {
print '</div>';
print '</td></tr>';
@ -805,7 +805,7 @@ while ($i < $imaxinloop) {
}
// Project
if ($arrayfields['project']['checked']) {
if (isModEnabled('project') && $arrayfields['project']['checked']) {
print '<td class="nowraponall">';
if ($obj->fk_project > 0 && is_object($proj)) {
$proj->fetch($obj->fk_project);

View File

@ -1108,7 +1108,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
// Special properties of replacement invoice
$object->fk_facture_source = GETPOSTINT('fac_replacement');
@ -1169,7 +1169,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
// Special properties of replacement invoice
$object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : '';
@ -1408,7 +1408,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
// Source facture
$object->fac_rec = GETPOSTINT('fac_rec');
@ -1495,7 +1495,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
if (GETPOST('type') == Facture::TYPE_SITUATION) {
$object->situation_counter = 1;
@ -2166,6 +2166,7 @@ if (empty($reshook)) {
$price_ht_devise = '';
$price_ttc = '';
$price_ttc_devise = '';
$price_min = '';
$price_min_ttc = '';
@ -2766,7 +2767,7 @@ if (empty($reshook)) {
// Invoice situation
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) {
$previousprogress = $line->getAllPrevProgress($line->fk_facture);
$fullprogress = price2num(GETPOST('progress', 'alpha'));
$fullprogress = price2num(GETPOST('progress', 'alpha'), 2);
if ($fullprogress < $previousprogress) {
$error++;
@ -5837,7 +5838,9 @@ if ($action == 'create') {
}
// Validate
if ($object->status == Facture::STATUS_DRAFT && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (getDolGlobalString('FACTURE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
if ($object->status == Facture::STATUS_DRAFT && count($object->lines) > 0
&& ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (getDolGlobalString('FACTURE_ENABLE_NEGATIVE') || $object->total_ttc >= 0))
|| ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
if ($usercanvalidate) {
unset($params['attr']['title']);
print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=valid&token='.newToken(), '', true, $params);

View File

@ -398,7 +398,7 @@ class FactureRec extends CommonInvoice
$sql .= ", '".$this->db->escape($facsrc->multicurrency_code)."'";
$sql .= ", ".((float) $facsrc->multicurrency_tx);
$sql .= ", ".((int) $this->suspended);
$sql .= ", ".((int) $this->fk_societe_rib);
$sql .= ", ".(!empty($this->fk_societe_rib) ? ((int) $this->fk_societe_rib) : 'NULL');
$sql .= ")";
if ($this->db->query($sql)) {
@ -571,7 +571,7 @@ class FactureRec extends CommonInvoice
$sql .= " localtax2 = ".((float) $this->total_localtax2).",";
$sql .= " total_ht = ".((float) $this->total_ht).",";
$sql .= " total_ttc = ".((float) $this->total_ttc).",";
$sql .= " fk_societe_rib = ".((int) $this->fk_societe_rib);
$sql .= " fk_societe_rib = ".(!empty($this->fk_societe_rib) ? ((int) $this->fk_societe_rib) : 'NULL');;
// TODO Add missing fields
$sql .= " WHERE rowid = ".((int) $this->id);
@ -975,14 +975,14 @@ class FactureRec extends CommonInvoice
if (empty($remise_percent)) {
$remise_percent = 0;
}
$qty = price2num($qty);
$pu_ht = price2num($pu_ht);
$pu_ttc = price2num($pu_ttc);
$qty = (float) price2num($qty);
$pu_ht = (float) price2num($pu_ht);
$pu_ttc = (float) price2num($pu_ttc);
if (!preg_match('/\((.*)\)/', $txtva)) {
$txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
}
$txlocaltax1 = price2num($txlocaltax1);
$txlocaltax2 = price2num($txlocaltax2);
$txlocaltax1 = (float) price2num($txlocaltax1);
$txlocaltax2 = (float) price2num($txlocaltax2);
if (empty($txtva)) {
$txtva = 0;
}
@ -1183,8 +1183,8 @@ class FactureRec extends CommonInvoice
if (!preg_match('/\((.*)\)/', (string) $txtva)) {
$txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
}
$txlocaltax1 = price2num($txlocaltax1);
$txlocaltax2 = price2num($txlocaltax2);
$txlocaltax1 = (float) price2num($txlocaltax1);
$txlocaltax2 = (float) price2num($txlocaltax2);
if (empty($txlocaltax1)) {
$txlocaltax1 = 0;
}

View File

@ -3946,16 +3946,16 @@ class Facture extends CommonInvoice
}
$remise_percent = (float) price2num($remise_percent);
$qty = price2num($qty);
$pu_ht = price2num($pu_ht);
$pu_ht_devise = price2num($pu_ht_devise);
$pu_ttc = price2num($pu_ttc);
$pa_ht = price2num($pa_ht);
$qty = (float) price2num($qty);
$pu_ht = (float) price2num($pu_ht);
$pu_ht_devise = (float) price2num($pu_ht_devise);
$pu_ttc = (float) price2num($pu_ttc);
$pa_ht = (float) price2num($pa_ht);
if (!preg_match('/\((.*)\)/', (string) $txtva)) {
$txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
}
$txlocaltax1 = price2num($txlocaltax1);
$txlocaltax2 = price2num($txlocaltax2);
$txlocaltax1 = (float) price2num($txlocaltax1);
$txlocaltax2 = (float) price2num($txlocaltax2);
if ($price_base_type == 'HT') {
$pu = $pu_ht;
@ -4208,15 +4208,15 @@ class Facture extends CommonInvoice
}
$remise_percent = (float) price2num($remise_percent);
$qty = price2num($qty);
$pu = price2num($pu);
$pu_ht_devise = price2num($pu_ht_devise);
$pa_ht = price2num($pa_ht);
$qty = (float) price2num($qty);
$pu = (float) price2num($pu);
$pu_ht_devise = (float) price2num($pu_ht_devise);
$pa_ht = (float) price2num($pa_ht);
if (!preg_match('/\((.*)\)/', (string) $txtva)) {
$txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5'
}
$txlocaltax1 = (float) price2num($txlocaltax1);
$txlocaltax2 = (float) price2num($txlocaltax2);
$txlocaltax1 = (float) price2num($txlocaltax1);
$txlocaltax2 = (float) price2num($txlocaltax2);
// Check parameters
if ($type < 0) {

View File

@ -300,7 +300,6 @@ if ($object->id > 0) {
if ($object->paid) {
$resteapayer = 0;
}
$resteapayeraffiche = $resteapayer;
if ($type == 'bank-transfer') {
if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { // Not recommended
@ -333,7 +332,7 @@ if ($object->id > 0) {
$author = new User($db);
if (!empty($object->user_creation_id)) {
$author->fetch($object->user_creation_id);
} elseif (!empty($object->fk_user_author)) {
} elseif (!empty($object->fk_user_author)) { // For backward compatibility
$author->fetch($object->fk_user_author);
}
@ -348,28 +347,8 @@ if ($object->id > 0) {
$numclosed = 0;
// How many Direct debit or Credit transfer open requests ?
$sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande";
$sql .= " , pfd.date_traite as date_traite";
$sql .= " , pfd.amount";
$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
if ($type == 'bank-transfer') {
$sql .= " WHERE fk_facture_fourn = ".((int) $object->id);
} else {
$sql .= " WHERE fk_facture = ".((int) $object->id);
}
$sql .= " AND pfd.traite = 0";
$sql .= " AND pfd.type = 'ban'";
$sql .= " ORDER BY pfd.date_demande DESC";
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$numopen = $num;
} else {
dol_print_error($db);
}
$listofopendirectdebitorcredittransfer = $object->getListOfOpenDirectDebitOrCreditTransfer($type);
$numopen = count($listofopendirectdebitorcredittransfer);
print dol_get_fiche_head($head, 'standingorders', $title, -1, ($type == 'bank-transfer' ? 'supplier_invoice' : 'bill'));
@ -795,11 +774,7 @@ if ($object->id > 0) {
print '<div class="center formconsumeproduce">';
//print '<table class="">';
//print '<tr><td class="left">'.
print $langs->trans('CustomerIBAN').' ';
//print '</td>';
//print '<td class="left nowraponall">';
// if societe rib in model invoice, we preselect it
$selectedRib = '';
@ -826,16 +801,16 @@ if ($object->id > 0) {
print img_warning($langs->trans("NoDefaultIBANFound"));
}
//print '</td></tr>';
// Bank Transfer Amount
//print '<tr><td class="nowrap left">';
print ' &nbsp; &nbsp; <label for="withdraw_request_amount">'.$langs->trans('BankTransferAmount').'</label>';
//print '</td><td class="left">';
print ' &nbsp; &nbsp; <label for="withdraw_request_amount">';
if ($type == 'bank-transfer') {
print $langs->trans('BankTransferAmount');
} else {
print $langs->trans("WithdrawRequestAmount");
}
print '</label> ';
print '<input type="text" class="right width75" id="withdraw_request_amount" name="withdraw_request_amount" value="'.$remaintopaylesspendingdebit.'">';
//print '</td></tr>';
//print '</table>';
// Button
print '<br><br>';
@ -849,7 +824,7 @@ if ($object->id > 0) {
if (getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT_SHOW_OLD_BUTTON')) { // This is hidden, prefer to use mode enabled with STRIPE_SEPA_DIRECT_DEBIT
// TODO Replace this with a checkbox for each payment mode: "Send request to XXX immediately..."
print "<br>";
//add stripe sepa button
// Add stripe sepa button
$buttonlabel = $langs->trans("MakeWithdrawRequestStripe");
print '<form method="POST" action="">';
print '<input type="hidden" name="token" value="'.newToken().'" />';
@ -1108,7 +1083,7 @@ if ($object->id > 0) {
}
// Date
print '<td class="nowraponall">'.dol_print_date($db->jdate($obj->date_demande), 'day')."</td>\n";
print '<td class="nowraponall">'.dol_print_date($db->jdate($obj->date_demande), 'day', 'tzuserrel')."</td>\n";
// User
print '<td class="tdoverflowmax125">';

View File

@ -312,7 +312,7 @@ print '</td></tr>';
// ThirdParty Type
print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>';
$sortparam_typent = (!getDolGlobalString('SOCIETE_SORT_ON_TYPEENT') ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label.
$sortparam_typent = getDolGlobalString('SOCIETE_SORT_ON_TYPEENT', 'ASC'); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label.
print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1);
if ($user->admin) {
print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
@ -342,7 +342,7 @@ if (isModEnabled('category')) {
// User
print '<tr><td>'.$langs->trans("CreatedBy").'</td><td>';
print img_picto('', 'user', 'class="pictofixedwidth"');
print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
print $form->select_dolusers($userid ? $userid : -1, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
print '</td></tr>';
// Status
print '<tr><td>'.$langs->trans("Status").'</td><td>';

View File

@ -455,7 +455,7 @@ while ((($y < $yend) || ($y == $yend && $m <= $mend)) && $mcursor < 1000) { // $
print '<tr class="oddeven">';
print '<td class="nowrap"><a href="'.DOL_URL_ROOT.'/compta/localtax/quadri_detail.php?leftmenu=tax_vat&month='.$m.'&year='.$y.'">'.dol_print_date(dol_mktime(0, 0, 0, (int) $m, 1, (int) $y), "%b %Y").'</a></td>';
print '<td class="nowrap"><a href="'.DOL_URL_ROOT.'/compta/localtax/quadri_detail.php?leftmenu=tax_vat&month='.$m.'&year='.$y.'&localTaxType='.$localTaxType.'">'.dol_print_date(dol_mktime(0, 0, 0, (int) $m, 1, (int) $y), "%b %Y").'</a></td>';
$x_coll_sum = 0;
foreach (array_keys($x_coll) as $rate) {

View File

@ -2,7 +2,7 @@
/* Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2016-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2017-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2017-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
*
@ -212,7 +212,7 @@ if (empty($reshook)) {
$object->periode = $dateperiod;
$object->period = $dateperiod;
$object->amount = $amount;
$object->fk_user = $fk_user;
$object->fk_user = $fk_user;
$object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
$object->fk_account = GETPOSTINT('fk_account');
$object->fk_project = GETPOSTINT('fk_project');
@ -250,7 +250,7 @@ if (empty($reshook)) {
$object->period = $dateperiod;
$object->periode = $dateperiod;
$object->amount = $amount;
$object->fk_user = $fk_user;
// $object->fk_user = $fk_user;
$result = $object->update($user);
if ($result <= 0) {

View File

@ -484,6 +484,10 @@ class Contact extends CommonObject
$error = 0;
$now = dol_now();
if (empty($this->date_creation)) {
$this->date_creation = $now;
}
$this->db->begin();
// Clean parameters

View File

@ -154,9 +154,13 @@ abstract class CommonInvoice extends CommonObject
*/
public $sumcreditnote_multicurrency;
/**
* @var string
* @var int|float|string May be used for status
*/
public $remaintopay;
/**
* @var int May be used for status
*/
public $nbofopendirectdebitorcredittransfer;
/**
* @var int
@ -486,6 +490,55 @@ abstract class CommonInvoice extends CommonObject
}
}
/**
* Return list of open direct debit or credit transfer
*
* @param string $type 'bank-transfer' or 'direct-debit'
* @return array<array{amount:int|float,date:int,num:string,ref:string,ref_ext?:string,fk_bank_line?:int,type:string}> Array with list of payments
*/
public function getListOfOpenDirectDebitOrCreditTransfer($type)
{
$listofopendirectdebitorcredittransfer = array();
// TODO Add a cache to store array of open requests for each invoice ID
$sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande, pfd.date_traite as date_traite, pfd.amount";
$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
if ($type == 'bank-transfer') {
$sql .= " WHERE fk_facture_fourn = ".((int) $this->id);
} else {
$sql .= " WHERE fk_facture = ".((int) $this->id);
}
$sql .= " AND pfd.traite = 0";
$sql .= " AND pfd.type = 'ban'";
$sql .= " ORDER BY pfd.date_demande DESC";
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
$i = 0;
while ($i < $num) {
$obj = $this->db->fetch_object($resql);
if ($obj) {
$listofopendirectdebitorcredittransfer[] = array(
'id' => $obj->rowid,
'invoiceid' => (int) $this->id,
'date' => $this->db->jdate($obj->date_demande),
'amount' => $obj->amount
);
}
$i++;
}
} else {
$this->error = $this->db->lasterror();
}
$this->nbofopendirectdebitorcredittransfer = $num;
return $listofopendirectdebitorcredittransfer;
}
/**
* Return list of payments
*
@ -849,7 +902,7 @@ abstract class CommonInvoice extends CommonObject
*/
public function getLibStatut($mode = 0, $alreadypaid = -1)
{
return $this->LibStatut($this->paye, $this->status, $mode, $alreadypaid, $this->type);
return $this->LibStatut($this->paye, $this->status, $mode, $alreadypaid, $this->type, $this->nbofopendirectdebitorcredittransfer);
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
@ -861,9 +914,10 @@ abstract class CommonInvoice extends CommonObject
* @param int $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 integer $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommend to put here 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
* @return string Label of status
*/
public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1)
public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1, $nbofopendirectdebitorcredittransfer = 0)
{
// phpcs:enable
global $langs, $hookmanager;
@ -892,7 +946,7 @@ abstract class CommonInvoice extends CommonObject
$labelStatus = $langs->transnoentitiesnoconv('BillStatusClosedPaidPartially');
$labelStatusShort = $langs->transnoentitiesnoconv('Bill'.$prefix.'StatusClosedPaidPartially');
$statusType = 'status9';
} elseif ($alreadypaid == 0) {
} elseif ($alreadypaid == 0 && $nbofopendirectdebitorcredittransfer == 0) {
$labelStatus = $langs->transnoentitiesnoconv('BillStatusNotPaid');
$labelStatusShort = $langs->transnoentitiesnoconv('Bill'.$prefix.'StatusNotPaid');
$statusType = 'status1';

View File

@ -1,22 +1,22 @@
<?php
/* Copyright (C) 2006-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2010-2020 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2011-2022 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2012-2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2012-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016 Bahfir abbes <bafbes@gmail.com>
* Copyright (C) 2017 ATM Consulting <support@atm-consulting.fr>
* Copyright (C) 2017-2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2017 Rui Strecht <rui.strecht@aliartalentos.com>
/* Copyright (C) 2006-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2013 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2010-2020 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2011-2022 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2012-2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2012-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016 Bahfir abbes <bafbes@gmail.com>
* Copyright (C) 2017 ATM Consulting <support@atm-consulting.fr>
* Copyright (C) 2017-2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2017 Rui Strecht <rui.strecht@aliartalentos.com>
* Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2018 Josep Lluís Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2021 Grégory Blémand <gregory.blemand@atm-consulting.fr>
* Copyright (C) 2023 Lenin Rivas <lenin.rivas777@gmail.com>
* Copyright (C) 2018 Josep Lluís Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2021 Grégory Blémand <gregory.blemand@atm-consulting.fr>
* Copyright (C) 2023 Lenin Rivas <lenin.rivas777@gmail.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
*
@ -4925,6 +4925,15 @@ abstract class CommonObject
$haschild = 0;
foreach ($arraytoscan as $table => $element) {
//print $id.'-'.$table.'-'.$elementname.'<br>';
// Check if module is enabled (to avoid error if tables of module not created)
if (isset($element['enabled']) && !empty($element['enabled'])) {
$enabled = (int) dol_eval($element['enabled'], 1);
if (empty($enabled)) {
continue;
}
}
// Check if element can be deleted
$sql = "SELECT COUNT(*) as nb";
$sql .= " FROM ".$this->db->prefix().$table." as c";
@ -10333,6 +10342,7 @@ abstract class CommonObject
if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) {
$fieldvalues['date_creation'] = $this->db->idate($now);
$this->date_creation = $this->db->idate($now);
}
if (array_key_exists('fk_user_creat', $fieldvalues) && !($fieldvalues['fk_user_creat'] > 0)) {
$fieldvalues['fk_user_creat'] = $user->id;

View File

@ -100,10 +100,10 @@ class DolEditor
* @param string $content Content of WYSIWYG field
* @param int|string $width Width in pixel of edit area (auto by default)
* @param int $height Height in pixel of edit area (200px by default)
* @param string $toolbarname Name of bar set to use ('Full', 'dolibarr_notes[_encoded]', 'dolibarr_details[_encoded]'=the less featured, 'dolibarr_mailings[_encoded]', 'dolibarr_readonly').
* @param string $toolbarname Name of the toolbar set to use ('dolibarr_details[_encoded]'=the less featured, 'dolibarr_notes[_encoded]' for notes content, 'dolibarr_mailings[_encoded]' for emailing content, 'dolibarr_readonly').
* @param string $toolbarlocation Deprecated. Not used
* @param bool $toolbarstartexpanded Bar is visible or not at start
* @param bool|int $uselocalbrowser Enabled to add links to local object with local browser. If false, only external images can be added in content.
* @param bool|int $uselocalbrowser Enabled to add links to local object with a local media filemanager. If false, only external images URL can be added into content, or images saved inline with src="data:..." with a cut/paste.
* @param bool|int|string $okforextendededitor 1 or True=Allow usage of extended editor tool if qualified (like ckeditor). If 'textarea', force use of simple textarea. If 'ace', force use of Ace.
* Warning: If you use 'ace', don't forget to also include ace.js in page header. Also, the button "save" must have class="buttonforacesave".
* @param int $rows Size of rows for textarea tool
@ -112,11 +112,16 @@ class DolEditor
* @param array{x?:string,y?:string,find?:string} $poscursor Array for initial cursor position array('x'=>x, 'y'=>y).
* array('find'=> 'word') can be used to go to line were the word has been found
*/
public function __construct($htmlname, $content, $width = '', $height = 200, $toolbarname = 'Basic', $toolbarlocation = 'In', $toolbarstartexpanded = false, $uselocalbrowser = 1, $okforextendededitor = true, $rows = 0, $cols = '', $readonly = 0, $poscursor = array())
public function __construct($htmlname, $content, $width = '', $height = 200, $toolbarname = 'Basic', $toolbarlocation = 'In', $toolbarstartexpanded = false, $uselocalbrowser = -1, $okforextendededitor = true, $rows = 0, $cols = '', $readonly = 0, $poscursor = array())
{
global $conf;
dol_syslog(get_class($this)."::DolEditor htmlname=".$htmlname." width=".$width." height=".$height." toolbarname=".$toolbarname);
dol_syslog(get_class($this)."::DolEditor htmlname=".$htmlname." width=".$width." height=".$height." toolbarname=".$toolbarname." uselocalbrowser=".$uselocalbrowser);
if ($uselocalbrowser === -1) {
// This may not be supported by new generation of WYSIWYG editors.
$uselocalbrowser = getDolGlobalInt("WYSIWYG_ALLOW_UPLOAD_MEDIA_FILES");
}
if (!$rows) {
$rows = round($height / 20);
@ -205,6 +210,8 @@ class DolEditor
$found = 0;
$out = '';
$this->content = ($this->content ?? ''); // to avoid htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated
if (in_array($this->tool, array('textarea', 'ckeditor'))) {
$found = 1;
//$out.= '<textarea id="'.$this->htmlname.'" name="'.$this->htmlname.'" '.($this->readonly?' disabled':'').' rows="'.$this->rows.'"'.(preg_match('/%/',$this->cols)?' style="margin-top: 5px; width: '.$this->cols.'"':' cols="'.$this->cols.'"').' class="flat">';
@ -394,9 +401,10 @@ class DolEditor
$out .= '<script nonce="'.getNonce().'" type="text/javascript">'."\n";
$out .= 'var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid");
aceEditor.session.setMode("ace/mode/'.$format.'");
aceEditor.session.setMode("ace/mode/'.$format.'");
aceEditor.setReadOnly('.($this->readonly ? 'true' : 'false').');
aceEditor.setOptions({
enableBasicAutocompletion: true, // the editor completes the statement when you hit Ctrl + Space. Need lib ext-language_tools.js
enableBasicAutocompletion: true, // the editor completes the statement when you hit Ctrl + Space. Need lib ext-language_tools.js
enableLiveAutocompletion: false, // the editor completes the statement while you are typing. Need lib ext-language_tools.js
//enableSnippets: true, // ???
showPrintMargin: false, // hides the vertical limiting strip
@ -450,7 +458,7 @@ class DolEditor
jQuery("#'.dol_escape_js($this->htmlname).'_x").val(cursorPos.column);
jQuery("#'.dol_escape_js($this->htmlname).'_y").val(cursorPos.row);
}
//console.log(aceEditor.getSession().getValue());
//console.log(aceEditor.getSession().getValue());
// Inject content of editor into the original HTML field.
jQuery("#'.dol_escape_js($this->htmlname).'").val(aceEditor.getSession().getValue());
/*if (jQuery("#'.dol_escape_js($this->htmlname).'").html().length > 0) return true;
@ -460,7 +468,7 @@ class DolEditor
console.log("Failed to retrieve js object ACE from its name");
return false;
}
});
});
})';
$out .= '</script>'."\n";
}

View File

@ -689,7 +689,7 @@ class Form
$paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribute to put on td text tag
}
if ($tooltipon == 1 || $tooltipon == 3) {
$paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" ';
$paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ($tag != 'td' ? ' inline-block' : '') . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" ';
if ($tooltiptrigger == '') {
$paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribute to put on td tag to store tooltip
} else {
@ -1149,15 +1149,16 @@ class Form
* Return list of types of lines (product or service)
* Example: 0=product, 1=service, 9=other (for external module)
*
* @param string $selected Preselected type
* @param string $htmlname Name of field in html form
* @param int<0,1>|string $showempty Add an empty field
* @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select)
* @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service')
* @param string $morecss More css
* @param string $selected Preselected type
* @param string $htmlname Name of field in html form
* @param int<0,1>|string $showempty Add an empty field
* @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select)
* @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service')
* @param string $morecss More css
* @param int $useajaxcombo 1=Use ajaxcombo
* @return void
*/
public function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0, $morecss = "")
public function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0, $morecss = "", $useajaxcombo = 1)
{
// phpcs:enable
global $langs;
@ -1166,11 +1167,11 @@ class Form
if ($forceall == 1 || (empty($forceall) && isModEnabled("product") && isModEnabled("service"))
|| (empty($forceall) && !isModEnabled('product') && !isModEnabled('service'))) {
if (empty($hidetext)) {
print $langs->trans("Type") . ': ';
print $langs->trans("Type").'...';
}
print '<select class="flat'.($morecss ? ' '.$morecss : '').'" id="select_' . $htmlname . '" name="' . $htmlname . '">';
if ($showempty) {
print '<option value="-1"';
print '<option value="-1" class="opacitymedium"'.($useajaxcombo ? '' : ' disabled="disabled"');
if ($selected == -1) {
print ' selected';
}
@ -1196,7 +1197,10 @@ class Form
print '>' . $langs->trans("Service");
print '</select>';
print ajax_combobox('select_' . $htmlname);
if ($useajaxcombo) {
print ajax_combobox('select_' . $htmlname);
}
//if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
}
if ((empty($forceall) && !isModEnabled('product') && isModEnabled("service")) || $forceall == 3) {
@ -1482,7 +1486,7 @@ class Form
* If you need parenthesis, use the Universal Filter Syntax, example: '(s.client:in:1,3)'
* Do not use a filter coming from input of users.
* @param string|int<0,1> $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
* @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier)
* @param int<0,1> $showtype Show third party nature in combolist (customer, prospect or supplier)
* @param int $forcecombo Force to use standard HTML select component without beautification
* @param array<array{method:string,url:string,htmlname:string,params:array<string,string>}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
* @param string $filterkey Filter on key value
@ -1502,6 +1506,8 @@ class Form
global $user, $langs;
global $hookmanager;
$langs->loadLangs(array("companies", "suppliers"));
$out = '';
$num = 0;
$outarray = array();
@ -2228,7 +2234,17 @@ class Form
$sql .= " AND u.fk_soc IS NULL";
}
if (!empty($morefilter)) {
$sql .= " " . $morefilter;
$errormessage = '';
$sql .= forgeSQLFromUniversalSearchCriteria($morefilter, $errormessage);
if ($errormessage) {
$this->errors[] = $errormessage;
dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
if ($outputmode == 0) {
return 'Error bad param $morefilter';
} else {
return array();
}
}
}
//Add hook to filter on user (for example on usergroup define in custom modules)
@ -2425,28 +2441,29 @@ class Form
* Return select list of users. Selected users are stored into session.
* List of users are provided into $_SESSION['assignedtouser'].
*
* @param string $action Value for $action
* @param string $htmlname Field name in form
* @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value
* @param int[] $exclude Array list of users id to exclude
* @param int<0,1> $disabled If select list must be disabled
* @param int[]|string $include Array list of users id to include or 'hierarchy' to have only supervised users
* @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled
* @param string $force_entity '0' or Ids of environment to force
* @param int $maxlength Maximum length of string into list (0=no limit)
* @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
* @param string $morefilter Add more filters into sql request
* @param int $showproperties Show properties of each attendees
* @param int[] $listofuserid Array with properties of each user
* @param int[] $listofcontactid Array with properties of each contact
* @param int[] $listofotherid Array with properties of each other contact
* @return string HTML select string
* @param string $action Value for $action
* @param string $htmlname Field name in form
* @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value
* @param int[] $exclude Array list of users id to exclude
* @param int<0,1> $disabled If select list must be disabled
* @param int[]|''|'hierarchy'|'hierarchyme' $include Array list of users id to include or 'hierarchy' to have only supervised users
* @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled
* @param string $force_entity '0' or Ids of environment to force
* @param int $maxlength Maximum length of string into list (0=no limit)
* @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status
* @param string $morefilter Add more filters into sql request (Example: '(employee:=:1)'). This value must not come from user input.
* @param int $showproperties Show properties of each attendees
* @param int[] $listofuserid Array with properties of each user
* @param int[] $listofcontactid Array with properties of each contact
* @param int[] $listofotherid Array with properties of each other contact
* @param int $canremoveowner 1 if we can remove owner, 0=no way
* @return string HTML select string
* @see select_dolgroups()
*/
public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array())
public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array(), $canremoveowner = 1)
{
// phpcs:enable
global $langs;
global $langs, $user;
$userstatic = new User($this->db);
$out = '';
@ -2479,8 +2496,25 @@ class Form
$ownerid = $value['id'];
$out .= ' (' . $langs->trans("Owner") . ')';
}
// Add picto to delete owner/assignee
if ($nbassignetouser > 1 && $action != 'view') {
$out .= ' <input type="image" style="border: 0px;" src="' . img_picto($langs->trans("Remove"), 'delete', '', 0, 1) . '" value="' . $userstatic->id . '" class="removedassigned reposition" id="removedassigned_' . $userstatic->id . '" name="removedassigned_' . $userstatic->id . '">';
$canremoveassignee = 1;
if ($i == 0) {
// We are on the owner of the event
if (!$canremoveowner) {
$canremoveassignee = 0;
}
if (!$user->hasRight('agenda', 'allactions', 'create')) {
$canremoveassignee = 0; // Can't remove the owner
}
} else {
// We are not on the owner of the event but on a secondary assignee
}
if ($canremoveassignee) {
// If user has all permission, he should be ableto remove a assignee.
// If user has not all permission, he can onlyremove assignee of other (he can't remove itself)
$out .= ' <input type="image" style="border: 0px;" src="' . img_picto($langs->trans("Remove"), 'delete', '', 0, 1) . '" value="' . $userstatic->id . '" class="removedassigned reposition" id="removedassigned_' . $userstatic->id . '" name="removedassigned_' . $userstatic->id . '">';
}
}
// Show my availability
if ($showproperties) {
@ -5096,7 +5130,7 @@ class Form
$resql = $this->db->query($sql);
if ($resql && $this->db->num_rows($resql) > 0) {
if ($showempty) {
$return .= '<option value="none"></option>';
$return .= '<option value="-1"></option>';
}
while ($res = $this->db->fetch_object($resql)) {
@ -5112,6 +5146,8 @@ class Form
}
}
$return .= '</select>';
$return .= ajax_combobox($htmlname);
}
return $return;
}
@ -7404,6 +7440,7 @@ class Form
$hourend = $hourstart;
}
}
// Show hour
$retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'hour' : '') . '" id="' . $prefix . 'hour" name="' . $prefix . 'hour">';
if ($emptyhours) {
@ -7426,7 +7463,7 @@ class Form
if ($m) {
// Show minutes
$retstring .= '<select' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'min' : '') . '" id="' . $prefix . 'min" name="' . $prefix . 'min">';
$retstring .= '<select ' . ($disabled ? ' disabled' : '') . ' class="flat valignmiddle maxwidth50 ' . ($fullday ? $fullday . 'min' : '') . '" id="' . $prefix . 'min" name="' . $prefix . 'min">';
if ($emptyhours) {
$retstring .= '<option value="-1">&nbsp;</option>';
}
@ -7444,7 +7481,7 @@ class Form
}
// Add a "Now" link
if (!empty($conf->use_javascript_ajax) && $addnowlink) {
if (!empty($conf->use_javascript_ajax) && $addnowlink && !$disabled) {
// Script which will be inserted in the onClick of the "Now" link
$reset_scripts = "";
if ($addnowlink == 2) { // local computer time
@ -7531,7 +7568,7 @@ class Form
}
// Add a "Plus one hour" link
if ($conf->use_javascript_ajax && $addplusone) {
if ($conf->use_javascript_ajax && $addplusone && !$disabled) {
// Script which will be inserted in the onClick of the "Add plusone" link
$reset_scripts = "";
@ -7569,7 +7606,7 @@ class Form
}
// Add a link to set data
if ($conf->use_javascript_ajax && !empty($adddateof)) {
if ($conf->use_javascript_ajax && !empty($adddateof) && !$disabled) {
if (!is_array($adddateof)) {
$arrayofdateof = array(array('adddateof' => $adddateof, 'labeladddateof' => $labeladddateof));
} else {

View File

@ -2436,7 +2436,10 @@ class ModelMail extends CommonObject
*/
public function fetch($id, $ref = null, $noextrafields = 0, $nolines = 0)
{
$result = $this->fetchCommon($id, $ref, '', $noextrafields);
// The table llx_c_email_templates has no field ref. The field ref was named "label" instead. So we change the call to fetchCommon.
//$result = $this->fetchCommon($id, $ref, '', $noextrafields);
$result = $this->fetchCommon($id, '', " AND t.label = '".$this->db->escape($ref)."'", $noextrafields);
if ($result > 0 && !empty($this->table_element_line) && empty($nolines)) {
$this->fetchLines($noextrafields);
}

View File

@ -102,7 +102,7 @@ class FormProjets extends Form
$placeholder = '';
if ($selected && empty($selected_input_value)) {
require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
$project = new Project($this->db);
$project->fetch($selected);
$selected_input_value = $project->ref;
@ -160,7 +160,7 @@ class FormProjets extends Form
// phpcs:enable
global $user, $conf, $langs;
require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
if (empty($htmlid)) {
$htmlid = $htmlname;
@ -350,7 +350,7 @@ class FormProjets extends Form
{
global $user, $conf, $langs;
require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
if (is_null($usertofilter)) {
$usertofilter = $user;
@ -796,10 +796,12 @@ class FormProjets extends Form
'2' => '2',
);
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
$tmpproject = new Project($this->db);
foreach ($statustohow as $key => $value) {
$tmpproject->statut = $key;
$tmpproject->statut = $key; // deprecated
$tmpproject->status = $key;
$options[$value] = $tmpproject->getLibStatut($short);
}

View File

@ -282,7 +282,7 @@ if (!class_exists('MenuManager')) {
$menufound = 0;
$dirmenus = array_merge(array("/core/menus/"), (array) $conf->modules_parts['menus']);
foreach ($dirmenus as $dirmenu) {
$menufound = dol_include_once($dirmenu."standard/".$file_menu);
$menufound = dol_include_once($dirmenu."standard/".dol_sanitizeFileName($file_menu));
if ($menufound) {
break;
}
@ -290,7 +290,7 @@ if (!class_exists('MenuManager')) {
if (!$menufound) { // If failed to include, we try with standard
dol_syslog("You define a menu manager '".$file_menu."' that can not be loaded.", LOG_WARNING);
$file_menu = 'eldy_menu.php';
include_once DOL_DOCUMENT_ROOT."/core/menus/standard/".$file_menu;
include_once DOL_DOCUMENT_ROOT."/core/menus/standard/".dol_sanitizeFileName($file_menu);
}
}
// @phan-suppress-next-line PhanRedefinedClassReference

View File

@ -1069,11 +1069,11 @@ function document_preview(file, type, title)
};
img.src = file;
}
/* This function is local to document_preview. Variables like file, type, title, object_width and object_height are global inside this function */
function show_preview(mode) {
/* console.log("mode="+mode+" file="+file+" type="+type+" width="+width+" height="+height); */
/* console.log("mode="+mode+" file="+file+" type="+type+" title=title+" width="+width+" height="+height); */
var newElem = '<object name="objectpreview" data="'+file+'" type="'+type+'" width="'+object_width+'" height="'+object_height+'" param="noparam"></object>';
optionsbuttons = {}
@ -1557,11 +1557,13 @@ if (!getDolGlobalString('MAIN_DISABLE_SELECT2_FOCUS_PROTECTION') && !defined('DI
* TODO: Recheck with the select2 GH issue and remove once this is fixed on their side
*/
$(document).on('select2:open', (e) => {
console.log("Execute the focus (click on combo or use space when on component");
console.log("Execute the focus (click on combo or use space when on component)");
const target = $(e.target);
if (target && target.length) {
let id = target[0].id || target[0].name;
if (id.substr(-2) == "[]") id = id.substr(0,id.length-2);
if (id.substr(-2) == "[]") {
id = id.substr(0,id.length-2);
}
document.querySelector('input[aria-controls*='+id+']').focus();
}
});

View File

@ -1429,7 +1429,7 @@ function dol_include_once($relpath, $classname = '')
* @param int $type 0=Used for a Filesystem path,
* 1=Used for an URL path (output relative),
* 2=Used for an URL path (output full path using same host that current url),
* 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file)
* 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file, for an access from internet)
* @param int $returnemptyifnotfound 0:If $type==0 and if file was not found into alternate dir, return default path into main dir (no test on it)
* 1:If $type==0 and if file was not found into alternate dir, return empty string
* 2:If $type==0 and if file was not found into alternate dir, test into main dir, return default path if found, empty string if not found
@ -1567,6 +1567,7 @@ function dol_get_object_properties($obj, $properties = [])
* @param T $object Object to clone
* @param int $native 0=Full isolation method, 1=Native PHP method, 2=Full isolation method keeping only scalar and array properties (recommended)
* @return T Clone object
*
* @see https://php.net/manual/language.oop5.cloning.php
* @phan-suppress PhanTypeExpectedObjectPropAccess
*/
@ -1902,6 +1903,20 @@ function dol_escape_js($stringtoescape, $mode = 0, $noescapebackslashn = 0)
return strtr($stringtoescape, $substitjs);
}
/**
* Returns text escaped by RFC 3986 for inclusion into a clicable link.
* This method can be used on the ...in links like href="javascript:..." because when clicking on such links, the browserfirst decode the strind
* and then interpret content that can be javascript.
* Usage of this escapement should be limited to links href="javascript:...". For common URL, use urlencode instead.
*
* @param string $stringtoescape String to escape
* @return string Escaped string.
*/
function dol_escape_uri($stringtoescape)
{
return rawurlencode($stringtoescape);
}
/**
* Returns text escaped for inclusion into javascript code
*
@ -10523,7 +10538,7 @@ function verifCond($strToEvaluate, $onlysimplestring = '1')
* @param int<0,1> $hideerrors 1=Hide errors
* @param string $onlysimplestring '0' (deprecated, do not use it anymore)=Accept all chars,
* '1' (most common use)=Accept only simple string with char 'a-z0-9\s^$_+-.*>&|=!?():"\',/@';',
* '2' (used for example for the compute property of extrafields)=Accept also '[]'
* '2' (used for example for the compute property of extrafields)=Accept also '<[]'
* @return void|string Nothing or return result of eval (even if type can be int, it is safer to assume string and find all potential typing issues as abs(dol_eval(...)).
* @see verifCond(), checkPHPCode() to see sanitizing rules that should be very close.
* @phan-suppress PhanPluginUnsafeEval
@ -10551,21 +10566,31 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1'
if ($onlysimplestring == '1' || $onlysimplestring == '2') {
// We must accept with 1: '1 && getDolGlobalInt("doesnotexist1") && getDolGlobalString("MAIN_FEATURES_LEVEL")'
// We must accept with 1: '$user->hasRight("cabinetmed", "read") && !$object->canvas=="patient@cabinetmed"'
// We must accept with 2: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found"
// We must accept with 2: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) <= 99) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found"
// Check if there is dynamic call (first we check chars are all into use a whitelist chars)
// Check if there is dynamic call (first we check chars are all into a whitelist chars)
$specialcharsallowed = '^$_+-.*>&|=!?():"\',/@';
if ($onlysimplestring == '2') {
$specialcharsallowed .= '[]';
$specialcharsallowed .= '<[]';
}
if (getDolGlobalString('MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL')) {
$specialcharsallowed .= getDolGlobalString('MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL');
}
if (preg_match('/[^a-z0-9\s'.preg_quote($specialcharsallowed, '/').']/i', $s)) {
if ($returnvalue) {
return 'Bad string syntax to evaluate (found chars that are not chars for a simple clean eval string): '.$s;
return 'Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string): '.$s;
} else {
dol_syslog('Bad string syntax to evaluate (found chars that are not chars for a simple clean eval string): '.$s, LOG_WARNING);
dol_syslog('Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string): '.$s, LOG_WARNING);
return '';
}
}
// Check if there is a < or <= without spaces before/after
if (preg_match('/<=?[^\s]/', $s)) {
if ($returnvalue) {
return 'Bad string syntax to evaluate (mode '.$onlysimplestring.', found a < or <= without space before and after): '.$s;
} else {
dol_syslog('Bad string syntax to evaluate (mode '.$onlysimplestring.', found a < or <= without space before and after): '.$s, LOG_WARNING);
return '';
}
}
@ -10580,14 +10605,17 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1'
}
}
// Now we check if we try dynamic call (by removing white list pattern of using parenthesis then testing if a parenthesis exists)
// Now we check if we try dynamic call
// First we remove white list pattern of using parenthesis then testing if one open parenthesis exists
$savescheck = '';
$scheck = $s;
while ($scheck && $savescheck != $scheck) {
$savescheck = $scheck;
$scheck = preg_replace('/->[a-zA-Z0-9_]+\(/', '->__METHOD__', $scheck); // accept parenthesis in '...->method(...'
$scheck = preg_replace('/^\(/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '(...'. Must replace with __PARENTHESIS__ with a space after to allow following substitutions
$scheck = preg_replace('/\s\(/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in 'if ($a == 1)'. Must replace with __PARENTHESIS__ with a space after to allow following substitutions
$scheck = preg_replace('/::[a-zA-Z0-9_]+\(/', '->__METHOD__', $scheck); // accept parenthesis in '...::method(...'
$scheck = preg_replace('/^\(+/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '(...'. Must replace with "__PARENTHESIS__ with a space after "to allow following substitutions
$scheck = preg_replace('/\&\&\s+\(/', '__ANDPARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in '&& (...'. Must replace with "__PARENTHESIS__ with a space after" to allow following substitutions
$scheck = preg_replace('/\|\|\s+\(/', '__ORPARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in '|| (...'. Must replace with "__PARENTHESIS__ with a space after" to allow following substitutions
$scheck = preg_replace('/^!?[a-zA-Z0-9_]+\(/', '__FUNCTION__', $scheck); // accept parenthesis in 'function(' and '!function('
$scheck = preg_replace('/\s!?[a-zA-Z0-9_]+\(/', '__FUNCTION__', $scheck); // accept parenthesis in '... function(' and '... !function('
$scheck = preg_replace('/^!\(/', '__NOTANDPARENTHESIS__', $scheck); // accept parenthesis in '!('
@ -10596,6 +10624,7 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1'
}
//print 'scheck='.$scheck." : ".strpos($scheck, '(')."<br>\n";
// Now test if it remains 1 one parenthesis.
if (strpos($scheck, '(') !== false) {
if ($returnvalue) {
return 'Bad string syntax to evaluate (mode '.$onlysimplestring.', found call of a function or method without using the direct name of the function): '.$s;
@ -10646,22 +10675,26 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1'
$forbiddenphpstrings = array('$$', '$_', '}[');
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction'));
// We list all forbidden function as keywords we don't want to see (we don't mind it if is "kewyord(" or just "keyword", we don't want "keyword" at all)
$forbiddenphpfunctions = array();
// @phpcs:ignore
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("base64"."_"."decode", "rawurl"."decode", "url"."decode", "str"."_rot13", "hex"."2bin")); // name of forbidden functions are split to avoid false positive
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func", "call_user_func_array"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_eval", "executeCLI", "verifCond")); // native dolibarr functions
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_compress_dir", "dol_decode", "dol_delete_file", "dol_delete_dir", "dol_delete_dir_recursive", "dol_copy", "archiveOrBackupFile")); // more dolibarr functions
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include"));
$forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function
$forbiddenphpregex = 'global\s+\$|\b('.implode('|', $forbiddenphpfunctions).')\b';
$forbiddenphpregex = 'global\s*\$';
$forbiddenphpregex .= '|';
$forbiddenphpregex .= '\b('.implode('|', $forbiddenphpfunctions).')\b';
$forbiddenphpmethodsregex = '->('.implode('|', $forbiddenphpmethods).')';
@ -11834,12 +11867,13 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata = 0, $param
if ($isAllowedForPreview) {
$tmpurl = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($modulepart).'&attachment=0&file='.urlencode($relativepath).($param ? '&'.$param : '');
$title = $langs->transnoentities("Preview");
//$title = '%27-alert(document.domain)-%27';
//$tmpurl = 'file='.urlencode("'-alert(document.domain)-'_small.jpg");
//$title = '%27-alert(document.domain)-%27'; // An example of js injection into a corrupted title string, that should be blocked by the dol_escape_uri().
//$tmpurl = 'file='.urlencode("'-alert(document.domain)-'_small.jpg"); // An example of tmpurl that should be blocked by the dol_escape_uri()
// We need to urlencode the parameter after the dol_escape_js($tmpurl) because $tmpurl may contain n url with param file=abc%27def if file has a ' inside.
// and when we click on href with this javascript string, a urlcode is done by browser, converted the %27 of file param
return 'javascript:document_preview(\''.urlencode(dol_escape_js($tmpurl)).'\', \''.urlencode(dol_mimetype($relativepath)).'\', \''.urlencode(dol_escape_js($title)).'\')';
// We need to do a dol_escape_uri() on the full string after the javascript: because such parts are the URI and when we click on such links, a RFC3986 decode is done,
// by the browser, converting the %27 (like when having param file=abc%27def), or when having a corrupted title), into a ', BEFORE interpreting the content that can be a js code.
// Using the dol_escape_uri guarantee that we encode for URI so decode retrieve original expected value.
return 'javascript:'.dol_escape_uri('document_preview(\''.dol_escape_js($tmpurl).'\', \''.dol_escape_js(dol_mimetype($relativepath)).'\', \''.dol_escape_js($title).'\')');
} else {
return '';
}

View File

@ -153,11 +153,12 @@ function dol_convertToWord($num, $langs, $currency = '', $centimes = false)
/**
* Function to return number or amount in text.
*
* @deprecated
* @param float $numero Number to convert
* @param Translate $langs Language
* @param string $numorcurrency 'number' or 'amount'
* @return string|int Text of the number or -1 in case TOO LONG (more than 1000000000000.99)
*
* @deprecated Use dol_convertToWord instead
*/
function dolNumberToWord($numero, $langs, $numorcurrency = 'number')
{

View File

@ -905,6 +905,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0)
$objectstatic->ref = $obj->ref;
$objectstatic->paye = $obj->paye;
$objectstatic->statut = $obj->status;
$objectstatic->status = $obj->status;
$objectstatic->total_ht = $obj->total_ht;
$objectstatic->total_tva = $obj->total_tva;
$objectstatic->total_ttc = $obj->total_ttc;
@ -938,7 +939,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0)
// Load amount of existing payment of invoice (needed for complete status)
$payment = $objectstatic->getSommePaiement();
$result .= '<td class="right">'.$objectstatic->getLibStatut(5, $payment).'</td>';
$result .= '<td class="right">'.$objectstatic->getLibStatut(3, $payment).'</td>';
$result .= '</tr>';
@ -1048,11 +1049,11 @@ function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0)
$result .= '<td class="tdoverflowmax150">'.$companystatic->getNomUrl(1, 'supplier').'</td>';
$result .= '<td>'.dol_print_date($db->jdate($obj->datec), 'day').'</td>';
$result .= '<td title="'.$langs->trans("DateModification").': '.dol_print_date($db->jdate($obj->datec), 'dayhour').'">'.dol_print_date($db->jdate($obj->datec), 'day').'</td>';
$result .= '<td class="amount right">'.price($obj->total_ttc).'</td>';
$result .= '<td class="right">'.$objectstatic->getLibStatut(5).'</td>';
$result .= '<td class="right">'.$objectstatic->getLibStatut(3).'</td>';
$result .= '</tr>';
@ -1305,8 +1306,6 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0)
$num = $db->num_rows($resql);
$othernb = 0;
$formfile = new FormFile($db);
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
@ -1326,7 +1325,9 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0)
print '<th class="right">'.$langs->trans("Paid").'</th>';
print '<th width="16">&nbsp;</th>';
print "</tr>\n";
$societestatic = new Societe($db);
if ($num) {
$i = 0;
$total = $total_ttc = $totalam = 0;

View File

@ -47,12 +47,63 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
* @param string $paymentbankid Only if payment on this bank account id
* @param int[] $thirdpartiesid List of thirdparties id when using filter=excludethirdpartiesid or filter=onlythirdpartiesid
* @param string $fileprefix Prefix to add into filename of generated PDF
* @param int $donotmerge 0=Default, 1=Disable the merge so do only the regeneration of PDFs.
* @param string $mode 'invoice' for invoices, 'proposal' for proposal, ...
* @return int Error code
*/
function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf')
function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf', $donotmerge = 0, $mode = 'invoice')
{
if ($mode == 'invoice') {
require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
require_once DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php";
$table = "facture";
$dir_output = $conf->facture->dir_output;
$date = "datef";
if ($diroutputpdf == 'auto') {
$diroutputpdf = $conf->invoice->dir_output.'/temp';
}
} elseif ($mode == 'order') {
require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php";
require_once DOL_DOCUMENT_ROOT."/core/modules/commande/modules_commande.php";
$table = "commande";
$dir_output = $conf->order->dir_output;
$date = "date";
if ($diroutputpdf == 'auto') {
$diroutputpdf = $conf->order->dir_output.'/temp';
}
} elseif ($mode == 'proposal') {
require_once DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php";
require_once DOL_DOCUMENT_ROOT."/core/modules/propale/modules_propale.php";
$table = "propal";
$dir_output = $conf->propal->dir_output;
$date = "datep";
if ($diroutputpdf == 'auto') {
$diroutputpdf = $conf->propal->dir_output.'/temp';
}
} elseif ($mode == 'shipment') {
require_once DOL_DOCUMENT_ROOT."/expedition/class/expedition.class.php";
require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/modules_expedition.php";
$table = "propal";
$dir_output = $conf->shipment->dir_output;
$date = "date";
if ($diroutputpdf == 'auto') {
$diroutputpdf = $conf->shipment->dir_output.'/temp';
}
} else {
print "Bad value for mode";
return -1;
}
$sql = "SELECT DISTINCT f.rowid, f.ref";
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
$sql .= " FROM ".MAIN_DB_PREFIX.$table." as f";
$sqlwhere = '';
$sqlorder = '';
if (in_array('all', $filter)) {
@ -65,10 +116,11 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
$sqlwhere .= " AND";
}
$sqlwhere .= " f.fk_statut > 0";
$sqlwhere .= " AND f.datef >= '".$db->idate($dateafterdate)."'";
$sqlwhere .= " AND f.datef <= '".$db->idate($datebeforedate)."'";
$sqlorder = " ORDER BY f.datef ASC";
$sqlwhere .= " AND f.".$db->sanitize($date)." >= '".$db->idate($dateafterdate)."'";
$sqlwhere .= " AND f.".$db->sanitize($date)." <= '".$db->idate($datebeforedate)."'";
$sqlorder = " ORDER BY ".$db->sanitize($date)." ASC";
}
// Filter for invoices only
if (in_array('nopayment', $filter)) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
if (empty($sqlwhere)) {
@ -79,6 +131,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
$sqlwhere .= " f.fk_statut > 0";
$sqlwhere .= " AND pf.fk_paiement IS NULL";
}
// Filter for invoices only
if (in_array('payments', $filter) || in_array('bank', $filter)) {
$sql .= ", ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
if (in_array('bank', $filter)) {
@ -102,6 +155,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
}
$sqlorder = " ORDER BY p.datep ASC";
}
// Filter for invoices only
if (in_array('nodeposit', $filter)) {
if (empty($sqlwhere)) {
$sqlwhere = ' WHERE ';
@ -110,6 +164,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
}
$sqlwhere .= ' type <> 3';
}
// Filter for invoices only
if (in_array('noreplacement', $filter)) {
if (empty($sqlwhere)) {
$sqlwhere = ' WHERE ';
@ -118,6 +173,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
}
$sqlwhere .= ' type <> 1';
}
// Filter for invoices only
if (in_array('nocreditnote', $filter)) {
if (empty($sqlwhere)) {
$sqlwhere = ' WHERE ';
@ -167,9 +223,6 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
if ($resql = $db->query($sql)) {
$num = $db->num_rows($resql);
$cpt = 0;
$oldemail = '';
$message = '';
$total = '';
if ($num) {
// First loop on each resultset to build PDF
@ -178,7 +231,17 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
while ($cpt < $num) {
$obj = $db->fetch_object($resql);
$fac = new Facture($db);
$fac = null;
if ($mode == 'invoice') {
$fac = new Facture($db);
} elseif ($mode == 'order') {
$fac = new Commande($db);
} elseif ($mode == 'proposal') {
$fac = new Propal($db);
} elseif ($mode == 'shipment') {
$fac = new Expedition($db);
}
$result = $fac->fetch($obj->rowid);
if ($result > 0) {
$outputlangs = $langs;
@ -188,15 +251,15 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
$outputlangs->setDefaultLang($newlangid);
}
}
$filename = $conf->facture->dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf';
$filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf';
if ($regenerate || !dol_is_file($filename)) {
if ($usestdout) {
print "Build PDF for invoice ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n";
print "Build PDF for document ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n";
}
$result = $fac->generateDocument($regenerate ? $regenerate : $fac->model_pdf, $outputlangs);
} else {
if ($usestdout) {
print "PDF for invoice ".$obj->ref." already exists\n";
print "PDF for document ".$obj->ref." already exists\n";
}
}
@ -207,15 +270,18 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte
if ($result <= 0) {
$error++;
if ($usestdout) {
print "Error: Failed to build PDF for invoice ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n";
print "Error: Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n";
} else {
dol_syslog("Failed to build PDF for invoice ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR);
dol_syslog("Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR);
}
}
$cpt++;
}
if ($donotmerge) {
return 1;
}
// Define format of output PDF
$formatarray = pdf_getFormat($langs);

View File

@ -63,10 +63,11 @@ $shmoffset = 1000; // Max number of entries found into a language file. If too l
* @param string $memoryid Memory id of shared area
* @param mixed $data Data to save. It must not be a null value.
* @param int $expire ttl in seconds, 0 never expire
* @param int $filecache 1 Enable file cache if no other session cache available, 0 Disabled (default)
* @return int Return integer <0 if KO, 0 if nothing is done, Nb of bytes written if OK
* @see dol_getcache()
*/
function dol_setcache($memoryid, $data, $expire = 0)
function dol_setcache($memoryid, $data, $expire = 0, $filecache = 0)
{
global $conf;
@ -124,6 +125,31 @@ function dol_setcache($memoryid, $data, $expire = 0)
} elseif (getDolGlobalInt('MAIN_OPTIMIZE_SPEED') & 0x02) { // This is a really not reliable cache ! Use Memcached instead.
// Using shmop
$result = dol_setshmop($memoryid, $data, $expire);
} elseif ($filecache > 0) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$now = dol_now();
$memoryid = session_name().'_'.$memoryid;
$dircache = 'dolcache';
$pathcache = DOL_DATA_ROOT.'/'.$dircache;
if (!dol_is_dir($pathcache)) {
$result = dol_mkdir($pathcache);
if ($result < 0) {
return $result;
}
}
if ($expire != 0) {
$expire = dol_time_plus_duree($now, $expire, 's');
}
$cachedata = array("expire" => $expire, "data" => $data);
$cachejson = dolEncrypt(json_encode($cachedata));
if (!dol_is_file($pathcache.'/'.$memoryid.'.cache')) {
$result = file_put_contents($pathcache.'/'.$memoryid.'.cache', $cachejson);
} else {
return 0;
}
} else {
// No intersession cache system available, we use at least the perpage cache
$conf->cache['cachememory_'.$memoryid] = $data;
@ -137,10 +163,11 @@ function dol_setcache($memoryid, $data, $expire = 0)
* Read a memory area shared by all users, all sessions on server
*
* @param string $memoryid Memory id of shared area
* @param int $filecache 1 Enable file cache if no other session cache available, 0 Disabled (default)
* @return int|mixed Return integer <0 if KO, data if OK, null if not found into cache or no caching feature enabled
* @see dol_setcache()
*/
function dol_getcache($memoryid)
function dol_getcache($memoryid, $filecache = 0)
{
global $conf;
@ -203,6 +230,31 @@ function dol_getcache($memoryid)
// Using shmop
$data = dol_getshmop($memoryid);
return $data;
} elseif ($filecache > 0) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$now = dol_now();
$memoryid = session_name().'_'.$memoryid;
$dircache = 'dolcache';
$pathcache = DOL_DATA_ROOT.'/'.$dircache;
if (!dol_is_file($pathcache.'/'.$memoryid.'.cache')) {
return null;
}
$data = file_get_contents($pathcache.'/'.$memoryid.'.cache');
if (!$data) {
return -1;
}
$json = json_decode(dolDecrypt($data));
if ($json->expire > $now) {
return $json->data;
} else {
$result = dol_delete_file($pathcache.'/'.$memoryid.'.cache');
if (!$result) {
return -2;
}
}
return null;
} else {
// No intersession cache system available, we use at least the perpage cache
if (isset($conf->cache['cachememory_'.$memoryid])) {

View File

@ -411,7 +411,7 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '
foreach ($object->fields as $key => $val) {
$i++;
if (!empty($val['index'])) {
$texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
$texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD ".($key == 'ref' ? "UNIQUE INDEX uk_" : "INDEX idx_").strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.($key == 'ref' && array_key_exists('entity', $object->fields) ? ", entity" : "").");";
$texttoinsert .= "\n";
}
if (!empty($val['foreignkey'])) {

View File

@ -2629,8 +2629,11 @@ function pdf_getLinkedObjects(&$object, $outputlangs)
if (is_object($hookmanager)) {
$parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs);
$action = '';
$hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if (!empty($hookmanager->resArray)) {
$reshook = $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if (empty($reshook)) {
$linkedobjects = array_replace($linkedobjects, $hookmanager->resArray); // array_replace is used to preserve keys
} elseif ($reshook>0) {
// The array must be reinserted even if it is empty because clearing the array could be one of the actions performed by the hook.
$linkedobjects = $hookmanager->resArray;
}
}

View File

@ -574,16 +574,9 @@ function showWebsiteTemplates(Website $website)
{
global $conf, $langs, $form, $user;
// We want only one directory for dir of website templates. If an external module need to provide a template, the template must be copied into this directory
// when module is enabled.
$dirthemes = array('/doctemplates/websites');
/*
if (!empty($conf->modules_parts['websitetemplates'])) {
foreach ($conf->modules_parts['websitetemplates'] as $reldir) {
$dirthemes = array_merge($dirthemes, (array) ($reldir.'doctemplates/websites'));
}
}
*/
$dirthemes = array_unique($dirthemes);
// Now dir_themes=array('/themes') or dir_themes=array('/theme','/mymodule/theme')
$colspan = 2;
@ -612,49 +605,47 @@ function showWebsiteTemplates(Website $website)
if (count($dirthemes)) {
$i = 0;
foreach ($dirthemes as $dir) {
if (preg_match('/^\/doctemplates\//', $dir)) {
$dirtheme = DOL_DATA_ROOT.$dir; // This include loop on $conf->file->dol_document_root
} else {
$dirtheme = dol_buildpath($dir); // This include loop on $conf->file->dol_document_root
}
$dirtheme = DOL_DATA_ROOT.$dir;
if (is_dir($dirtheme)) {
$handle = opendir($dirtheme);
if (is_resource($handle)) {
while (($subdir = readdir($handle)) !== false) {
//var_dump($dirtheme.'/'.$subdir);
if (is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) != '.' && substr($subdir, 0, 3) != 'CVS' && preg_match('/\.zip$/i', $subdir)) {
if (dol_is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) != '.' && substr($subdir, 0, 3) != 'CVS' && preg_match('/\.zip$/i', $subdir)) {
$subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir);
$subdirwithoutzipwithoutver = preg_replace('/(_exp|_dev)$/i', '', $subdirwithoutzip);
// Disable not stable themes (dir ends with _exp or _dev)
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2 && preg_match('/_dev$/i', $subdir)) {
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2 && preg_match('/_dev$/i', $subdirwithoutzip)) {
continue;
}
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1 && preg_match('/_exp$/i', $subdir)) {
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1 && preg_match('/_exp$/i', $subdirwithoutzip)) {
continue;
}
print '<div class="inline-block center flex-item" style="min-width: 250px; max-width: 400px; margin-top: 10px; margin-bottom: 10px; margin-right: 20px; margin-left: 20px;">';
$templatedir = $dirtheme."/".$subdir;
$file = $dirtheme."/".$subdirwithoutzip.".jpg";
$url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzip.".jpg";
$file = $dirtheme."/".$subdirwithoutzipwithoutver.".jpg";
$url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzipwithoutver.".jpg";
if (!file_exists($file)) {
$url = DOL_URL_ROOT.'/public/theme/common/nophoto.png';
}
$originalfile = basename($file);
$originalimgfile = basename($file);
$entity = $conf->entity;
$modulepart = 'doctemplateswebsite';
$cache = '';
$title = $file;
$ret = '';
$urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 1, '&entity='.$entity);
$urladvanced = getAdvancedPreviewUrl($modulepart, $originalimgfile, 1, '&entity='.$entity);
if (!empty($urladvanced)) {
$ret .= '<a class="'.$urladvanced['css'].'" target="'.$urladvanced['target'].'" mime="'.$urladvanced['mime'].'" href="'.$urladvanced['url'].'">';
} else {
$ret .= '<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.urlencode($modulepart).'&entity='.((int) $entity).'&file='.urlencode($originalfile).'&cache='.((int) $cache).'">';
$ret .= '<a href="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.urlencode($modulepart).'&entity='.((int) $entity).'&file='.urlencode($originalimgfile).'&cache='.((int) $cache).'">';
}
print $ret;
print '<img class="img-skinthumb shadow" src="'.$url.'" border="0" alt="'.$title.'" title="'.$title.'" style="margin-bottom: 5px;">';
@ -694,8 +685,8 @@ function showWebsiteTemplates(Website $website)
/**
* Check a new string containing only php code (including <php tag)
* - Block if bad code in the new string.
* - Block also if user has no permission to change PHP code.
* - Block if user has no permission to change PHP code.
* - Block also if bad code found in the new string.
*
* @param string $phpfullcodestringold PHP old string (before the change). For example "<?php echo 'a' ?><php echo 'b' ?>"
* @param string $phpfullcodestring PHP new string. For example "<?php echo 'a' ?><php echo 'c' ?>"
@ -720,15 +711,26 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
}
}
$phpfullcodestringnew = $phpfullcodestring;
// Then check forbidden commands
if (!$error) {
$forbiddenphpstrings = array('$$', '}[');
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('ReflectionFunction'));
if (getDolGlobalString("WEBSITE_DISALLOW_DOLLAR_UNDERSCORE")) {
$phpfullcodestring = preg_replace('/\$_COOKIE\[/', '__DOLLARCOOKIE__', $phpfullcodestring);
$phpfullcodestring = preg_replace('/\$_FILES\[/', '__DOLLARFILES__', $phpfullcodestring);
$phpfullcodestring = preg_replace('/\$_SESSION\[/', '__DOLLARSESSION__', $phpfullcodestring);
$forbiddenphpstrings = array('$$', '$_', '}[');
} else {
$forbiddenphpstrings = array('$$', '}[');
}
//$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_FILES', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction'));
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', 'ReflectionFunction'));
$forbiddenphpfunctions = array();
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("base64"."_"."decode", "rawurl"."decode", "url"."decode", "str"."_rot13", "hex"."2bin")); // name of forbidden functions are split to avoid false positive
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("call_user_func"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("call_user_func", "call_user_func_array"));
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once"));
if (!getDolGlobalString('WEBSITE_PHP_ALLOW_EXEC')) { // If option is not on, we disallow functions to execute commands
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen"));
@ -736,27 +738,38 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities
}
if (!getDolGlobalString('WEBSITE_PHP_ALLOW_WRITE')) { // If option is not on, we disallow functions to write files
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_compress_dir", "dol_decode", "dol_delete_file", "dol_delete_dir", "dol_delete_dir_recursive", "dol_copy", "archiveOrBackupFile")); // more dolibarr functions
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
}
//$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include"));
$forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function
foreach ($forbiddenphpstrings as $forbiddenphpstring) {
if (preg_match('/'.preg_quote($forbiddenphpstring, '/').'/ms', $phpfullcodestring)) {
if (preg_match('/'.preg_quote($forbiddenphpstring, '/').'/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpstring), null, 'errors');
break;
}
}
foreach ($forbiddenphpfunctions as $forbiddenphpcommand) {
if (preg_match('/'.$forbiddenphpcommand.'\s*\(/ms', $phpfullcodestring)) {
/* replaced with next block
foreach ($forbiddenphpfunctions as $forbiddenphpfunction) { // Check "function(" but also "'function'(" and "function ("
if (preg_match('/'.$forbiddenphpfunction.'[\'\s]*\(/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors');
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpfunction), null, 'errors');
break;
}
}*/
foreach ($forbiddenphpfunctions as $forbiddenphpfunction) { // Check "function" whatever is "function(" or "function'(" or "function (" or "function"
if (preg_match('/\b'.$forbiddenphpfunction.'\b/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpfunction), null, 'errors');
break;
}
}
foreach ($forbiddenphpmethods as $forbiddenphpmethod) {
if (preg_match('/->'.$forbiddenphpmethod.'/ms', $phpfullcodestring)) {
if (preg_match('/->'.$forbiddenphpmethod.'/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpmethod), null, 'errors');
break;
@ -764,14 +777,14 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
}
}
// This char can be used to execute RCE for example using with echo `ls`
// This char can be used to execute RCE for example by using echo `ls`
if (!$error) {
$forbiddenphpchars = array();
if (!getDolGlobalString('WEBSITE_PHP_ALLOW_DANGEROUS_CHARS')) { // If option is not on, we disallow functions to execute commands
$forbiddenphpchars = array("`");
}
foreach ($forbiddenphpchars as $forbiddenphpchar) {
if (preg_match('/'.$forbiddenphpchar.'/ms', $phpfullcodestring)) {
if (preg_match('/'.$forbiddenphpchar.'/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpchar), null, 'errors');
break;
@ -779,26 +792,34 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring)
}
}
// Deny dynamic functions '${a}(' or '$a[b](' => So we refuse '}(' and ']('
// Deny code to call a function obfuscated with comment, like "exec/*...*/ ('ls')";
if (!$error) {
if (preg_match('/[}\]]\(/ims', $phpfullcodestring)) {
if (preg_match('/\*\/\s*\(/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", "exec/*...*/ ('ls')"), null, 'errors');
}
}
// Deny dynamic functions '${a}(' or '$a[b](' => So we refuse '}(' and ']('
if (!$error) {
if (preg_match('/[}\]]\s*\(/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", ']('), null, 'errors');
}
}
// Deny dynamic functions '$xxx('
// Deny dynamic functions '$xxx(' or '$xxx (' or '$xxx" ('
if (!$error) {
if (preg_match('/\$[a-z0-9_\-\/\*]+\(/ims', $phpfullcodestring)) {
if (preg_match('/\$[a-z0-9_\-\/\*\"]+\s*\(/ims', $phpfullcodestring)) {
$error++;
setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors');
}
}
// No need to block $conf->global->aaa() because PHP try to run method aaa an not function into $conf->global->aaa.
// No need to block $conf->global->aaa() because PHP try to run the method aaa of $conf->global and not the function into $conf->global->aaa.
// Then check if installmodules does not block dynamic PHP code change.
if ($phpfullcodestringold != $phpfullcodestring) {
// Then check if installmodules.lock does not block dynamic PHP code change.
if ($phpfullcodestringold != $phpfullcodestringnew) {
if (!$error) {
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
$allowimportsite = true;

View File

@ -173,8 +173,9 @@ class pdf_standard_asset extends ModelePDFAsset
// Load translation files required by the page
$outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
global $outputlangsbis;
$outputlangsbis = null;
if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) {
global $outputlangsbis;
$outputlangsbis = new Translate('', $conf);
$outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE'));
$outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies"));

View File

@ -88,7 +88,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
$texte .= '<input type="hidden" name="action" value="setModuleOptions">';
$texte .= '<input type="hidden" name="param1" value="PRODUCT_ELEPHANT_MASK_PRODUCT">';
$texte .= '<input type="hidden" name="param2" value="PRODUCT_ELEPHANT_MASK_SERVICE">';
$texte .= '<table class="nobordernopadding" width="100%">';
$texte .= '<table class="nobordernopadding centpercent">';
$tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Product"), $langs->transnoentities("Product"));
$tooltip .= $langs->trans("GenericMaskCodes3");
@ -97,16 +97,16 @@ class mod_codeproduct_elephant extends ModeleProductCode
//$tooltip .= '<br>'.$langs->trans("GenericMaskCodes5b");
// Parametrage du prefix customers
$texte .= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("ProductCodeModel").'):</td>';
$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="value1" value="'.(getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT') ? $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT : '').'"'.$disabled.'>', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'</td>';
$texte .= '<tr><td>'.$langs->trans("ProductCodeModel").'</td>';
$texte .= '<td class="right nowraponall">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="value1" placeholder="'.$langs->trans("Mask").'" value="'.getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT').'"'.$disabled.'>', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'</td>';
$texte .= '<td class="left" rowspan="2">&nbsp; <input type="submit" class="button button-edit reposition smallpaddingimp" name="modify" value="'.$langs->trans("Modify").'"'.$disabled.'></td>';
$texte .= '</tr>';
// Parametrage du prefix suppliers
$texte .= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("ServiceCodeModel").'):</td>';
$texte .= '<td class="right">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="value2" value="'.(getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE') ? $conf->global->PRODUCT_ELEPHANT_MASK_SERVICE : '').'"'.$disabled.'>', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'</td>';
$texte .= '<tr><td>'.$langs->trans("ServiceCodeModel").'</td>';
$texte .= '<td class="right nowraponall">'.$form->textwithpicto('<input type="text" class="flat minwidth175" name="value2" placeholder="'.$langs->trans("Mask").'" value="'.getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE').'"'.$disabled.'>', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'</td>';
$texte .= '</tr>';
$texte .= '</table>';
@ -171,7 +171,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
*/
public function getNextValue($objproduct = null, $type = -1)
{
global $db, $conf;
global $db;
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
@ -203,7 +203,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
$now = dol_now();
if (getDolGlobalString('PRODUCT_ELEPHANT_ADD_WHERE')) {
$where = ' AND ('.dol_string_nospecial(dol_string_unaccent($conf->global->PRODUCT_ELEPHANT_ADD_WHERE), '_', array(',', '@', '"', "|", ";", ":")).')';
$where = ' AND ('.dol_string_nospecial(dol_string_unaccent(getDolGlobalString('PRODUCT_ELEPHANT_ADD_WHERE')), '_', array(',', '@', '"', "|", ";", ":")).')';
}
$numFinal = get_next_value($db, $mask, 'product', $field, $where, '', $now);
@ -268,10 +268,10 @@ class mod_codeproduct_elephant extends ModeleProductCode
// Get Mask value
$mask = '';
if ($type == 0) {
$mask = !getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT') ? '' : $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT;
$mask = getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT');
}
if ($type == 1) {
$mask = !getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE') ? '' : $conf->global->PRODUCT_ELEPHANT_MASK_SERVICE;
$mask = getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE');
}
if (!$mask) {
$this->error = 'NotConfigured';

View File

@ -3,6 +3,7 @@
* Copyright (C) 2011-2022 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Charlene Benke <charlene@patas-monkey.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -281,11 +282,12 @@ if ($disablenofollow) {
<div class="tagtable left centpercent" title="<?php echo $langs->trans("EnterLoginDetail"); ?>">
<!-- Login -->
<?php if (!isset($conf->file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
<div class="trinputlogin">
<div class="tagtd nowraponall center valignmiddle tdinputlogin">
<?php if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
?><label for="username" class="hidden"><?php echo $langs->trans("Login"); ?></label><?php
} ?>
<?php if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
?><label for="username" class="hidden"><?php echo $langs->trans("Login"); ?></label><?php
} ?>
<!-- <span class="span-icon-user">-->
<span class="fa fa-user"></span>
<input type="text" id="username" maxlength="255" placeholder="<?php echo $langs->trans("Login"); ?>" name="username" class="flat input-icon-user minwidth150" value="<?php echo dol_escape_htmltag($login); ?>" tabindex="1" autofocus="autofocus" autocapitalize="off" autocomplete="on" spellcheck="false" autocorrect="off" />
@ -293,7 +295,6 @@ if ($disablenofollow) {
</div>
<!-- Password -->
<?php if (!isset($conf->file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
<div class="trinputlogin">
<div class="tagtd nowraponall center valignmiddle tdinputlogin">
<?php if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
@ -317,7 +318,7 @@ if (!empty($captcha)) {
}
// List of directories where we can find captcha handlers
$dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array());
$dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), (isset($conf->modules_parts['captcha']) && is_array($conf->modules_parts['captcha'])) ? $conf->modules_parts['captcha'] : array());
$fullpathclassfile = '';
foreach ($dirModCaptcha as $dir) {
$fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2);
@ -334,7 +335,7 @@ if (!empty($captcha)) {
$classname = "modCaptcha".ucfirst($captcha);
if (class_exists($classname)) {
/** @var ModeleCaptcha $captchaobj */
$captchaobj = new $classname($db, $conf, $langs, $user);
$captchaobj = new $classname($db, $conf, $langs, null);
'@phan-var-force ModeleCaptcha $captchaobj';
if (is_object($captchaobj) && method_exists($captchaobj, 'getCaptchaCodeForForm')) {

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,8 @@
* @var Translate $langs
* @var User $user
*
* @var string $action
* @var int $i
* @var 0|1 $forceall
* @var int $num
* @var 0|1 $senderissupplier

View File

@ -224,7 +224,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
case 'ORDER_CLASSIFY_BILLED':
case 'ORDER_SETDRAFT':
case 'LINEORDER_INSERT':
case 'LINEORDER_UPDATE':
case 'LINEORDER_MODIFY':
case 'LINEORDER_DELETE':
break;
// Supplier orders
@ -239,7 +239,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// case 'ORDER_SUPPLIER_RECEIVE':
// case 'LINEORDER_SUPPLIER_DISPATCH':
// case 'LINEORDER_SUPPLIER_CREATE':
// case 'LINEORDER_SUPPLIER_UPDATE':
// case 'LINEORDER_SUPPLIER_MODIFY':
// Proposals
// case 'PROPAL_CREATE':
@ -251,7 +251,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// case 'PROPAL_CLOSE_REFUSED':
// case 'PROPAL_DELETE':
// case 'LINEPROPAL_INSERT':
// case 'LINEPROPAL_UPDATE':
// case 'LINEPROPAL_MODIFY':
// case 'LINEPROPAL_DELETE':
// SupplierProposal
@ -264,7 +264,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED':
// case 'SUPPLIER_PROPOSAL_DELETE':
// case 'LINESUPPLIER_PROPOSAL_INSERT':
// case 'LINESUPPLIER_PROPOSAL_UPDATE':
// case 'LINESUPPLIER_PROPOSAL_MODIFY':
// case 'LINESUPPLIER_PROPOSAL_DELETE':
// Contracts
@ -274,7 +274,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// case 'CONTRACT_CLOSE':
// case 'CONTRACT_DELETE':
// case 'LINECONTRACT_INSERT':
// case 'LINECONTRACT_UPDATE':
// case 'LINECONTRACT_MODIFY':
// case 'LINECONTRACT_DELETE':
// Bills
@ -288,19 +288,19 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// case 'BILL_DELETE':
// case 'BILL_PAYED':
// case 'LINEBILL_INSERT':
// case 'LINEBILL_UPDATE':
// case 'LINEBILL_MODIFY':
// case 'LINEBILL_DELETE':
//Supplier Bill
// case 'BILL_SUPPLIER_CREATE':
// case 'BILL_SUPPLIER_UPDATE':
// case 'BILL_SUPPLIER_MODIFY':
// case 'BILL_SUPPLIER_DELETE':
// case 'BILL_SUPPLIER_PAYED':
// case 'BILL_SUPPLIER_UNPAYED':
// case 'BILL_SUPPLIER_VALIDATE':
// case 'BILL_SUPPLIER_UNVALIDATE':
// case 'LINEBILL_SUPPLIER_CREATE':
// case 'LINEBILL_SUPPLIER_UPDATE':
// case 'LINEBILL_SUPPLIER_MODIFY':
// case 'LINEBILL_SUPPLIER_DELETE':
// Payments
@ -316,7 +316,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// Donation
// case 'DON_CREATE':
// case 'DON_UPDATE':
// case 'DON_MODIFY':
// case 'DON_DELETE':
// Interventions
@ -325,7 +325,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers
// case 'FICHINTER_VALIDATE':
// case 'FICHINTER_DELETE':
// case 'LINEFICHINTER_CREATE':
// case 'LINEFICHINTER_UPDATE':
// case 'LINEFICHINTER_MODIFY':
// case 'LINEFICHINTER_DELETE':
// Members

View File

@ -156,21 +156,37 @@ $head = datapolicyAdminPrepareHead();
print dol_get_fiche_head($head, 'settings', '', -1, '');
// Setup page goes here
print '<span class="opacitymedium">'.$langs->trans("datapolicySetupPage").'</span><br>';
// print $form->textwithpicto('', $langs->trans('DATAPOLICY_Tooltip_SETUP'));
print '<span class="opacitymedium">'.$langs->trans("datapolicySetupPage").'</span>';
print $form->textwithpicto('', $langs->trans('DATAPOLICY_Tooltip_SETUP', $langs->trans("DATAPOLICYJob"), $langs->transnoentities("CronList")));
print '<br>';
print '<br>';
print '<br>';
// TODO Show the last date of execution of the job DATAPOLICYJob
if ($action == 'edit') {
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
print '<table class="noborder centpercent">';
//print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td></td></tr>';
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="tagtable nobottomiftotal liste">';
print '<tr class="liste_titre"><td class="titlefield"></td>';
print '<td>'.$langs->trans("DelayForAnonymization").'</td>';
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
print '<td>'.$langs->trans("DelayForDeletion").'</td>';
}
print '</tr>';
foreach ($arrayofparameters as $title => $tab) {
print '<tr class="trforbreak"><td class="titlefield trforbreak" colspan="2">'.$langs->trans($title).'</td></tr>';
print '<tr class="trforbreak liste_titre"><td class="titlefield trforbreak">'.$langs->trans($title).'</td>';
print '<td></td>';
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
print '<td></td>';
}
print '</tr>';
foreach ($tab as $key => $val) {
print '<tr class="oddeven"><td>';
print $val['picto'];
@ -184,11 +200,19 @@ if ($action == 'edit') {
}
print '</select>';
print ajax_combobox($key);
print '</td></tr>';
print '</td>';
if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
print '<td>';
print $langs->trans("FeatureNotYetAvailable");
print '</td>';
}
print '</tr>';
}
}
print '</table>';
print '</div>';
print $form->buttonsSaveCancel("Save", '');
@ -196,7 +220,6 @@ if ($action == 'edit') {
print '<br>';
} else {
print '<table class="noborder centpercent">';
//print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td></td></tr>';
foreach ($arrayofparameters as $title => $tab) {
print '<tr class="trforbreak"><td class="titlefield trforbreak" colspan="2">'.$langs->trans($title).'</td></tr>';

View File

@ -21,6 +21,7 @@
* \file datapolicy/class/datapolicy.class.php
* \ingroup datapolicy
* \brief Class to manage feature of Data Policy module.
* This class file is not used.
*/
include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
@ -61,7 +62,7 @@ class DataPolicy
*/
public function getAllContactNotInformed()
{
global $langs, $conf, $db, $user;
global $langs, $conf, $db;
$langs->load("companies");
@ -69,9 +70,9 @@ class DataPolicy
$sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as spe ON spe.fk_object = c.rowid";
$sql .= " WHERE (c.statut=1 AND c.no_email=0 AND (spe.datapolicy_consentement=0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement=0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection=0 OR spe.datapolicy_opposition_prospection IS NULL))";
$sql .= " WHERE (c.statut = 1 AND c.no_email = 0 AND (spe.datapolicy_consentement = 0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement = 0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection = 0 OR spe.datapolicy_opposition_prospection IS NULL))";
$sql .= " AND spe.datapolicy_send IS NULL";
$sql .= " AND c.entity=".$conf->entity;
$sql .= " AND c.entity = ".((int) $conf->entity);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
@ -99,16 +100,16 @@ class DataPolicy
*/
public function getAllCompaniesNotInformed()
{
global $langs, $conf, $db, $user;
global $langs, $conf, $db;
$langs->load("companies");
$sql = "SELECT s.rowid";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields as se ON se.fk_object = s.rowid";
$sql .= " WHERE s.statut=0 AND (se.datapolicy_consentement=0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement=0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection=0 OR se.datapolicy_opposition_prospection IS NULL)";
$sql .= " WHERE s.statut = 0 AND (se.datapolicy_consentement = 0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement = 0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection = 0 OR se.datapolicy_opposition_prospection IS NULL)";
$sql .= " AND se.datapolicy_send IS NULL";
$sql .= " AND s.entity=".$conf->entity;
$sql .= " AND s.entity = ".((int) $conf->entity);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
@ -136,16 +137,16 @@ class DataPolicy
*/
public function getAllAdherentsNotInformed()
{
global $langs, $conf, $db, $user;
global $langs, $conf, $db;
$langs->load("adherent");
$sql = "SELECT a.rowid";
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as a";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent_extrafields as ae ON ae.fk_object = a.rowid";
$sql .= " WHERE a.statut=0 AND (ae.datapolicy_consentement=0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)";
$sql .= " WHERE a.statut = 0 AND (ae.datapolicy_consentement = 0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)";
$sql .= " AND ae.datapolicy_send IS NULL";
$sql .= " AND a.entity=".$conf->entity;
$sql .= " AND a.entity = ".((int) $conf->entity);
$resql = $this->db->query($sql);
if ($resql) {
$num = $this->db->num_rows($resql);
@ -174,7 +175,7 @@ class DataPolicy
*/
public static function sendMailDataPolicyContact($contact)
{
global $langs, $conf, $db, $user;
global $langs, $db, $user;
$error = 0;
@ -252,7 +253,7 @@ class DataPolicy
*/
public static function sendMailDataPolicyCompany($societe)
{
global $langs, $conf, $db, $user;
global $langs, $db, $user;
$error = 0;
@ -327,7 +328,7 @@ class DataPolicy
*/
public static function sendMailDataPolicyAdherent($adherent)
{
global $langs, $conf, $db, $user;
global $langs, $db, $user;
$error = 0;

View File

@ -468,6 +468,7 @@ class DataPolicyCron
$this->db->begin();
// Loop on each type of data
foreach ($arrayofparameters as $key => $params) {
if (getDolGlobalInt($key) > 0) {
// @phan-suppress-next-line PhanPluginPrintfVariableFormatString
@ -488,10 +489,12 @@ class DataPolicyCron
$object->fetch($obj->rowid);
$object->id = $obj->rowid;
$action = 'anonymize'; // TODO Offer also action "delete" in setup of module
$action = 'anonymize'; // TODO Offer also action "delete" in the setup of the module
// Manage action 'anonymize'
if ($action == 'anonymize') {
if ($object->isObjectUsed($obj->rowid) == 0) { // If object to clean is used
if ($object->isObjectUsed($obj->rowid) == 0) { // If object to clean is not used
// Loop on each field to anonymize
foreach ($params['fields_anonym'] as $field => $val) {
if ($val == 'MAKEANONYMOUS') {
$object->$field = $field.'-anonymous-'.$obj->rowid; // @phpstan-ignore-line
@ -499,7 +502,10 @@ class DataPolicyCron
$object->$field = $val;
}
}
// Update record
$result = $object->update($obj->rowid, $user);
if ($result > 0) {
$errormsg = $object->error;
$error++;
@ -508,6 +514,7 @@ class DataPolicyCron
}
}
// Manage action 'deletion'
if ($action == 'delete') { // If object to clean is not used
$result = $object->delete($user);
if ($result < 0) {

View File

@ -38,7 +38,7 @@ function datapolicyAdminPrepareHead()
$head = array();
$head[$h][0] = DOL_URL_ROOT."/datapolicy/admin/setup.php";
$head[$h][1] = $langs->trans("Deletion");
$head[$h][1] = $langs->trans("DataAnonymization");
$head[$h][2] = 'settings';
$h++;

View File

@ -129,7 +129,7 @@ $original_file = GETPOST('file', 'alphanohtml');
$hashp = GETPOST('hashp', 'aZ09');
$modulepart = GETPOST('modulepart', 'alpha');
$urlsource = GETPOST('urlsource', 'alpha');
$entity = GETPOSTINT('entity', $conf->entity);
$entity = GETPOSTINT('entity');
// Security check
if (empty($modulepart) && empty($hashp)) {

View File

@ -257,7 +257,7 @@ if ($resql) {
print '</td>';
// Date
print '<td class="center">'.dol_print_date($db->jdate($obj->datem), 'day').'</td>';
print '<td class="center" title="'.$langs->trans("DonationDate").': '.dol_print_date($db->jdate($obj->datem), 'day').'">'.dol_print_date($db->jdate($obj->datem), 'day').'</td>';
print '<td class="right">'.$donation_static->LibStatut($obj->fk_statut, 5).'</td>';

View File

@ -1875,7 +1875,7 @@ if ($action == 'create') {
print '</tr>';
}
if ($object->status == $object::STATUS_CLOSED) {
if ($object->status == ExpenseReport::STATUS_CLOSED) {
/* TODO this fields are not yet filled
print '<tr>';
print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
@ -2615,12 +2615,12 @@ if ($action == 'create') {
// Unit price net
print '<td class="right inputpricenet">';
print '<input type="text" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag((!empty($value_unit_ht) ? $value_unit_ht : 0)).'"'.$taxlessUnitPriceDisabled.' />';
print '<input type="text" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag((!empty($value_unit_ht) ? $value_unit_ht : "")).'"'.$taxlessUnitPriceDisabled.' />';
print '</td>';
// Unit price with tax
print '<td class="right inputtax">';
print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag((!empty($value_unit) ? $value_unit : 0)).'">';
print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag((!empty($value_unit) ? $value_unit : "")).'">';
print '</td>';
// Quantity

View File

@ -1943,7 +1943,7 @@ class ExpenseReport extends CommonObject
dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG);
if ($this->status == self::STATUS_DRAFT) {
if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) {
if (empty($qty)) {
$qty = 0;
}
@ -2037,7 +2037,7 @@ class ExpenseReport extends CommonObject
}
} else {
dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR);
$this->error = 'ErrorExpenseNotDraft';
$this->error = 'ErrorExpenseNotDraftAndNotRefused';
return -3;
}
}

View File

@ -474,7 +474,7 @@ if ($step == 1 || !$datatoexport) {
// Affiche les modules d'exports
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">';
print '<table class="noborder centpercent nomarginbottom">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Module").'</td>';
print '<td>'.$langs->trans("ExportableDatas").'</td>';
@ -486,16 +486,17 @@ if ($step == 1 || !$datatoexport) {
//var_dump($objexport->array_export_code_for_sort);
//$sortedarrayofmodules = dol_sort_array($objexport->array_export_module, 'module_position', 'asc', 0, 0, 1);
foreach ($objexport->array_export_code_for_sort as $key => $value) {
print '<tr class="oddeven"><td nospan="nospan">';
//print img_object($objexport->array_export_module[$key]->getName(),$export->array_export_module[$key]->picto).' ';
print $objexport->array_export_module[$key]->getName();
$titleofmodule = $objexport->array_export_module[$key]->getName();
print '<tr class="oddeven"><td class="tdoverflowmax200" title="'.dolPrintHTML($titleofmodule).'">';
print dolPrintHTML($titleofmodule);
print '</td><td>';
$entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[$key]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
$label = $objexport->array_export_label[$key];
//print $value.'-'.$icon.'-'.$label."<br>";
print img_object($objexport->array_export_module[$key]->getName(), $entityicon).' ';
print $label;
print '<div class="twolinesmax-normallineheight minwidth200onall">';
print img_object($objexport->array_export_module[$key]->getName(), $entityicon, 'class="pictofixedwidth"');
print dolPrintHTML($label);
print '</div>';
print '</td><td class="right">';
if ($objexport->array_export_perms[$key]) {
print '<a href="'.DOL_URL_ROOT.'/exports/export.php?step=2&module_position='.$objexport->array_export_module[$key]->module_position.'&datatoexport='.$objexport->array_export_code[$key].'">'.img_picto($langs->trans("NewExport"), 'next', 'class="fa-15"').'</a>';

View File

@ -1025,7 +1025,7 @@ class ProductFournisseur extends Product
}
}
if ($fourn_unitprice < $min || $min == -1) {
if ($fourn_unitprice_with_discount < $min || $min == -1) {
$this->id = $prodid;
$this->product_fourn_price_id = $record["product_fourn_price_id"];
$this->ref_supplier = $record["ref_fourn"];
@ -1050,7 +1050,7 @@ class ProductFournisseur extends Product
$this->fourn_multicurrency_id = $record["fk_multicurrency"];
$this->fourn_multicurrency_code = $record["multicurrency_code"];
$min = $fourn_unitprice;
$min = $fourn_unitprice_with_discount;
}
}
}
@ -1133,8 +1133,8 @@ class ProductFournisseur extends Product
$out = '';
$langs->load("suppliers");
if (count($productFournList) > 0) {
$out .= '<table class="nobordernopadding centpercent">';
$out .= '<tr><td class="liste_titre right">'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').'</td>';
$out .= '<table class="centpercent liste nomarginbottom">';
$out .= '<tr class="liste_titre"><td class="liste_titre right">'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').'</td>';
$out .= '<td class="liste_titre right">'.($showunitprice ? $langs->trans("QtyMin") : '').'</td>';
$out .= '<td class="liste_titre">'.$langs->trans("Supplier").'</td>';
$out .= '<td class="liste_titre">'.$langs->trans("SupplierRef").'</td></tr>';
@ -1142,7 +1142,7 @@ class ProductFournisseur extends Product
$out .= '<tr><td class="right">'.($showunitprice ? price($productFourn->fourn_unitprice * (1 - $productFourn->fourn_remise_percent / 100) - $productFourn->fourn_remise) : '').'</td>';
$out .= '<td class="right">'.($showunitprice ? $productFourn->fourn_qty : '').'</td>';
$out .= '<td>'.$productFourn->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).'</td>';
$out .= '<td>'.$productFourn->fourn_ref.'<td></tr>';
$out .= '<td>'.dolPrintHTML($productFourn->fourn_ref).'</td></tr>';
}
$out .= '</table>';
} else {

View File

@ -844,7 +844,7 @@ if (empty($reshook)) {
$object->fk_incoterms = GETPOSTINT('incoterm_id');
$object->location_incoterms = GETPOST('location_incoterms', 'alpha');
$object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
$object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx');
$object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
$object->transport_mode_id = GETPOSTINT('transport_mode_id');
// Proprietes particulieres a facture de replacement
@ -1591,12 +1591,26 @@ if (empty($reshook)) {
$idprod = GETPOSTINT('idprod');
}
$price_ht = '';
$price_ht_devise = '';
$price_ttc = '';
$price_ttc_devise = '';
if (GETPOST('price_ht') !== '') {
$price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
}
if (GETPOST('multicurrency_price_ht') !== '') {
$price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
}
if (GETPOST('price_ttc') !== '') {
$price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
}
if (GETPOST('multicurrency_price_ttc') !== '') {
$price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
}
$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
$price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
$price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
$price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
$price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
$remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
@ -1623,6 +1637,24 @@ if (empty($reshook)) {
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
$error++;
}
if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && (($price_ht < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht == '') && (($price_ht_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht_devise == '') && $price_ttc === '' && $price_ttc_devise === '' && $object->type != FactureFournisseur::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not ''
if (($price_ht < 0 || $price_ttc < 0) && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) {
$langs->load("errors");
if ($object->type == $object::TYPE_DEPOSIT) {
// Using negative lines on deposit lead to headach and blocking problems when you want to consume them.
setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors');
} else {
setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors');
}
$error++;
} else {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
$error++;
}
}
if ($prod_entry_mode == 'free' && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors');
$error++;
@ -4034,7 +4066,9 @@ if ($action == 'create') {
}
// Validate
if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT) {
if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT && count($object->lines) > 0
&& ((($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_PROFORMA || $object->type == FactureFournisseur::TYPE_SITUATION) && (getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE') || $object->total_ttc >= 0))
|| ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) {
if (count($object->lines)) {
if ($usercanvalidate) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'"';
@ -4063,7 +4097,7 @@ if ($action == 'create') {
}
// Reverse back money or convert to reduction
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) {
if ($object->status != FactureFournisseur::STATUS_DRAFT && ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD)) {
// For credit note only
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0) {
if ($resteapayer == 0) {

View File

@ -521,7 +521,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') {
$sql = 'SELECT u.rowid, u.lastname, u.firstname, u.login, u.photo FROM '.MAIN_DB_PREFIX.'user as u';
$sql .= ' WHERE 1 = 1';
$sql .= !empty($morefilter) ? $morefilter : '';
$sql .= empty($morefilter) ? '' : $morefilter;
$userlist = array();
$userstatic = new User($db);

View File

@ -351,7 +351,7 @@ if ($step == 1 || !$datatoimport) {
// Affiche les modules d'imports
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
print '<table class="noborder centpercent">';
print '<table class="noborder centpercent nomarginbottom">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Module").'</td>';
print '<td>'.$langs->trans("ImportableDatas").'</td>';
@ -362,18 +362,21 @@ if ($step == 1 || !$datatoimport) {
$sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1);
foreach ($sortedarrayofmodules as $key => $value) {
//var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]);
print '<tr class="oddeven"><td>';
$titleofmodule = $objimport->array_import_module[$key]['module']->getName();
print '<tr class="oddeven"><td class="tdoverflowmax200" title="'.dolPrintHTML($titleofmodule).'">';
// Special case for import common to module/services
if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print dolPrintHTML($titleofmodule);
print '</td><td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[$key];
$label = $objimport->array_import_label[$key];
print '<div class="twolinesmax-normallineheight minwidth200onall">';
print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"');
print dolPrintHTML($label);
print '</div>';
print '</td><td style="text-align: right">';
if ($objimport->array_import_perms[$key]) {
print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=2&datatoimport='.$objimport->array_import_code[$key].$param.'">'.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').'</a>';

View File

@ -3,4 +3,3 @@
<link rel="stylesheet" id="font-wasesome-css" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

Some files were not shown because too many files have changed in this diff Show More