Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into dev_EventOrganizer

This commit is contained in:
Dorian Vabre 2021-04-09 16:23:42 +02:00
commit b3415f9031
328 changed files with 3189 additions and 1405 deletions

View File

@ -23,7 +23,7 @@ PEAR Mail_MIME 1.8.9 BSD Yes
ParseDown 1.6 MIT License Yes Markdown parser
PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files
PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers
PHPSpreadSheet ? LGPL-2.1+ Yes Read/Write XLS files, read ODS files
PHPSpreadSheet 1.8.2 LGPL-2.1+ Yes Read/Write XLS files, read ODS files
php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service
PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests

View File

@ -29,6 +29,7 @@
"ckeditor/ckeditor" : "4.12.1",
"mike42/escpos-php" : "2.2",
"mobiledetect/mobiledetectlib" : "2.8.34",
"phpoffice/phpexcel" : "1.8.2",
"restler/framework" : "3.0.0-RC6",
"tecnickcom/tcpdf" : "6.3.2",
"nnnick/chartjs" : "^2.9",

57
composer.lock generated
View File

@ -328,6 +328,63 @@
},
"time": "2020-03-23T09:12:05+00:00"
},
{
"name": "phpoffice/phpexcel",
"version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PHPExcel.git",
"reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/1441011fb7ecdd8cc689878f54f8b58a6805f870",
"reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"php": "^5.2|^7.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "2.*"
},
"type": "library",
"autoload": {
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Maarten Balliauw",
"homepage": "http://blog.maartenballiauw.be"
},
{
"name": "Erik Tilt"
},
{
"name": "Franck Lefevre",
"homepage": "http://rootslabs.net"
},
{
"name": "Mark Baker",
"homepage": "http://markbakeruk.net"
}
],
"description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PHPExcel",
"keywords": [
"OpenXML",
"excel",
"xlsx"
],
"abandoned": "phpoffice/phpspreadsheet",
"time": "2018-11-22T23:07:24+00:00"
},
{
"name": "restler/framework",
"version": "3.0.0-RC6",

View File

@ -8,7 +8,8 @@
* Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2012 J. Fernando Lagrange <fernando@demo-tic.org>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2020-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2020-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2021 Waël Almoman <info@almoman.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
@ -33,6 +34,7 @@
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
// Load translation files required by the page
$langs->loadLangs(array("admin", "members"));
@ -101,11 +103,12 @@ if ($action == 'set_default') {
}
} elseif ($action == 'updateall') {
$db->begin();
$res1 = $res2 = $res3 = $res4 = $res5 = $res6 = 0;
$res1 = $res2 = $res3 = $res4 = $res5 = $res6 = $res7 = 0;
$res1 = dolibarr_set_const($db, 'ADHERENT_LOGIN_NOT_REQUIRED', GETPOST('ADHERENT_LOGIN_NOT_REQUIRED', 'alpha') ? 0 : 1, 'chaine', 0, '', $conf->entity);
$res2 = dolibarr_set_const($db, 'ADHERENT_MAIL_REQUIRED', GETPOST('ADHERENT_MAIL_REQUIRED', 'alpha'), 'chaine', 0, '', $conf->entity);
$res3 = dolibarr_set_const($db, 'ADHERENT_DEFAULT_SENDINFOBYMAIL', GETPOST('ADHERENT_DEFAULT_SENDINFOBYMAIL', 'alpha'), 'chaine', 0, '', $conf->entity);
$res4 = dolibarr_set_const($db, 'ADHERENT_BANK_USE', GETPOST('ADHERENT_BANK_USE', 'alpha'), 'chaine', 0, '', $conf->entity);
$res7 = dolibarr_set_const($db, "MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE", json_encode(GETPOST('MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE')), 'array', 0, '', $conf->entity);
// Use vat for invoice creation
if ($conf->facture->enabled) {
$res4 = dolibarr_set_const($db, 'ADHERENT_VAT_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_VAT_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity);
@ -217,6 +220,18 @@ print '<tr class="oddeven"><td>'.$langs->trans("MemberSendInformationByMailByDef
print $form->selectyesno('ADHERENT_DEFAULT_SENDINFOBYMAIL', (!empty($conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL) ? $conf->global->ADHERENT_DEFAULT_SENDINFOBYMAIL : 0), 1);
print "</td></tr>\n";
// Amount by member type
$adht = new AdherentType($db);
$amountbytype = empty($conf->global->MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE) ? -1 : json_decode($conf->global->MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE, true);
print '<tr class="oddeven"><td>'.$langs->trans("DefineAmountMemberType").'</td><td>';
foreach ($adht->liste_array(1) as $typeid => $type) {
print $type .' : ';
print '<input type="text" id="MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE['.$typeid.']" name="MEMBER_SUBSCRIPTION_AMOUNT_BY_TYPE['.$typeid.']" " size="5" value="'.(!empty($amountbytype[$typeid]) ? $amountbytype[$typeid] : '').'">';
print '<br>';
}
print "</td></tr>\n";
// Insert subscription into bank account
print '<tr class="oddeven"><td>'.$langs->trans("MoreActionsOnSubscription").'</td>';
$arraychoices = array('0'=>$langs->trans("None"));

View File

@ -177,7 +177,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print $langs->trans("ForceMemberType");
print '</td><td class="right">';
$listofval = array();
$listofval += $adht->liste_array();
$listofval += $adht->liste_array(1);
$forcetype = empty($conf->global->MEMBER_NEWFORM_FORCETYPE) ? -1 : $conf->global->MEMBER_NEWFORM_FORCETYPE;
print $form->selectarray("MEMBER_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval) > 1 ? 1 : 0);
print "</td></tr>\n";

View File

@ -13,7 +13,7 @@
* Copyright (C) 2018-2019 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2020 Josep Lluís Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2021 Waël Almoman <info@almoman.com>
* Copyright (C) 2021 Waël Almoman <info@almoman.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
@ -1490,9 +1490,10 @@ class Adherent extends CommonObject
* @param string $emetteur_nom Name of cheque writer
* @param string $emetteur_banque Name of bank of cheque
* @param int $datesubend Date end subscription
* @param int $fk_type Member type id
* @return int rowid of record added, <0 if KO
*/
public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0)
public function subscription($date, $amount, $accountid = 0, $operation = '', $label = '', $num_chq = '', $emetteur_nom = '', $emetteur_banque = '', $datesubend = 0, $fk_type = null)
{
global $conf, $langs, $user;
@ -1523,6 +1524,7 @@ class Adherent extends CommonObject
$subscription->amount = $amount;
$subscription->note = $label; // deprecated
$subscription->note_public = $label;
$subscription->fk_type = $fk_type;
$rowid = $subscription->create($user);
if ($rowid > 0) {

View File

@ -60,7 +60,7 @@ $arrayofparameters = array(
'EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
'EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES'=>array('type'=>'emailtemplate:eventorganization_send', 'enabled'=>1),
'EVENTORGANIZATION_SECUREKEY'=>array('type'=>'securekey', 'enabled'=>1),
'EVENTORGANIZATION_SECUREKEY'=>array('type'=>'securekey', 'enabled'=>1),
);
$error = 0;
@ -75,7 +75,6 @@ if ((float) DOL_VERSION >= 6) {
include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
}
if ($action == 'updateMask') {
$maskconstorder = GETPOST('maskconstorder', 'alpha');
$maskorder = GETPOST('maskorder', 'alpha');
@ -198,6 +197,7 @@ print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, 'even
// Setup page goes here
echo '<span class="opacitymedium">'.$langs->trans("EventOrganizationSetupPage").'</span><br><br>';
if ($action == 'edit') {
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
@ -208,13 +208,11 @@ if ($action == 'edit') {
foreach ($arrayofparameters as $constname => $val) {
if ($val['enabled']==1) {
//if ($val['type'] != 'securekey'){
$setupnotempty++;
print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : '');
print '<span id="helplink'.$constname.'" class="spanforparamtooltip">'.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).'</span>';
print '</td><td>';
//}
$setupnotempty++;
print '<tr class="oddeven"><td>';
$tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : '');
print '<span id="helplink'.$constname.'" class="spanforparamtooltip">'.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).'</span>';
print '</td><td>';
if ($val['type'] == 'textarea') {
print '<textarea class="flat" name="'.$constname.'" id="'.$constname.'" cols="50" rows="5" wrap="soft">' . "\n";
@ -414,7 +412,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
}
if ($module->isEnabled()) {
generate_tokendol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php');
print '<tr class="oddeven"><td>'.$module->name."</td><td>\n";
print $module->info();

View File

@ -99,6 +99,10 @@ class Boms extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->bom->read) {
throw new RestException(401);
}
$obj_ret = array();
$tmpobject = new BOM($this->db);

View File

@ -67,7 +67,7 @@ function printDropdownBookmarksList()
// Url to list bookmark
$listbtn = '<a class="top-menu-dropdown-link" title="'.$langs->trans('AddThisPageToBookmarks').'" href="'.DOL_URL_ROOT.'/bookmarks/list.php" >';
$listbtn .= '<span class="fa fa-list paddingright"></span>'.$langs->trans('Bookmarks').'</a>';
$listbtn .= img_picto('', 'bookmark', 'class="paddingright"').$langs->trans('Bookmarks').'</a>';
// Url to go on create new bookmark page
$newbtn = '';
@ -75,7 +75,7 @@ function printDropdownBookmarksList()
//$urltoadd=DOL_URL_ROOT.'/bookmarks/card.php?action=create&amp;urlsource='.urlencode($url).'&amp;url='.urlencode($url);
$urltoadd = DOL_URL_ROOT.'/bookmarks/card.php?action=create&amp;url='.urlencode($url);
$newbtn .= '<a class="top-menu-dropdown-link" title="'.$langs->trans('AddThisPageToBookmarks').'" href="'.dol_escape_htmltag($urltoadd).'" >';
$newbtn .= img_picto('', 'bookmark', '', false, 0, 0, '', 'paddingright').dol_escape_htmltag($langs->trans('AddThisPageToBookmarks')).'</a>';
$newbtn .= img_picto('', 'add', '', false, 0, 0, '', 'paddingright').dol_escape_htmltag($langs->trans('AddThisPageToBookmarks')).'</a>';
}
// Menu with list of bookmarks

View File

@ -82,16 +82,19 @@ class ActionComm extends CommonObject
/**
* @var int Id into parent table llx_c_actioncomm (used only if option to use type is set)
* This field is stored info fk_action. It contains the id into table llx_ac_actioncomm.
*/
public $type_id;
/**
* @var string Calendar of event (Type of type of event). 'system'=Default calendar, 'systemauto'=Auto calendar, 'birthdate', 'holiday', 'module'=Calendar specific to a module
* This field contains the type into table llx_ac_actioncomm ('system', 'systemauto', ...). It should be named 'type_type'.
*/
public $type;
/**
* @var string Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH.
* This field contains the code into table llx_ac_actioncomm.
*/
public $type_code;
@ -112,6 +115,7 @@ class ActionComm extends CommonObject
/**
* @var string Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...)
* This field is stored into field 'code' into llx_actioncomm.
*/
public $code;

View File

@ -984,6 +984,7 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) {
$orderstatic->id = $obj->commandeid;
$orderstatic->ref = $obj->ref;
$orderstatic->ref_client = $obj->ref_client;
$orderstatic->statut = $obj->fk_statut;
$orderstatic->total_ht = $obj->total_ht;
$orderstatic->total_tva = $obj->total_tva;
$orderstatic->total_ttc = $obj->total_ttc;

View File

@ -155,6 +155,10 @@ class Proposals extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->propal->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -158,6 +158,10 @@ class Orders extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->commande->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -165,6 +165,10 @@ class Invoices extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->facture->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -235,17 +235,26 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->tax->char
$object->label = $langs->trans("CopyOf").' '.$object->label;
}
if (GETPOST('clone_for_next_month', 'int')) {
if (GETPOST('clone_for_next_month', 'int')) { // This can be true only if TAX_ADD_CLONE_FOR_NEXT_MONTH_CHECKBOX has been set
$object->periode = dol_time_plus_duree($object->periode, 1, 'm');
$object->date_ech = dol_time_plus_duree($object->date_ech, 1, 'm');
} else {
// Note dateech is often a little bit higher than dateperiod
$newdateperiod = dol_mktime(0, 0, 0, GETPOST('clone_periodmonth', 'int'), GETPOST('clone_periodday', 'int'), GETPOST('clone_periodyear', 'int'));
$newdateech = dol_mktime(0, 0, 0, GETPOST('clone_date_echmonth', 'int'), GETPOST('clone_date_echday', 'int'), GETPOST('clone_date_echyear', 'int'));
if ($newdateperiod) {
$object->periode = $newdateperiod;
if (empty($newdateech)) {
$object->date_ech = $object->periode;
}
}
if ($newdateech) {
$object->date_ech = $newdateech;
if (empty($newdateperiod)) {
// TODO We can here get dol_get_last_day of previous month:
// $object->periode = dol_get_last_day(year of $object->date_ech - 1m, month or $object->date_ech -1m)
$object->periode = $object->date_ech;
}
}
}
@ -410,9 +419,9 @@ if ($id > 0) {
// Clone confirmation
if ($action === 'clone') {
$formquestion = array(
array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf").' '.$object->label),
array('type' => 'text', 'name' => 'clone_label', 'label' => $langs->trans("Label"), 'value' => $langs->trans("CopyOf").' '.$object->label, 'tdclass'=>'fieldrequired'),
);
if (!empty($conf->global->TAX_ADD_CLON_FOR_NEXT_MONTH_CHECKBOX)) {
if (!empty($conf->global->TAX_ADD_CLONE_FOR_NEXT_MONTH_CHECKBOX)) {
$formquestion[] = array('type' => 'checkbox', 'name' => 'clone_for_next_month', 'label' => $langs->trans("CloneTaxForNextMonth"), 'value' => 1);
} else {
$formquestion[] = array('type' => 'date', 'name' => 'clone_date_ech', 'label' => $langs->trans("Date"), 'value' => -1);

View File

@ -197,7 +197,7 @@ class ChargeSociales extends CommonObject
{
$newamount = price2num($this->amount, 'MT');
// Validation parametres
// Validation of parameters
if (!$newamount > 0 || empty($this->date_ech) || empty($this->periode)) {
return false;
}

View File

@ -106,6 +106,10 @@ class Contracts extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->contrat->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -461,7 +461,7 @@ abstract class CommonDocGenerator
$array_key.'_total_localtax2'=>price2num($object->total_localtax2),
$array_key.'_total_ttc'=>price2num($object->total_ttc),
$array_key.'_multicurrency_code' => price2num($object->multicurrency_code),
$array_key.'_multicurrency_code' => $object->multicurrency_code,
$array_key.'_multicurrency_tx' => price2num($object->multicurrency_tx),
$array_key.'_multicurrency_total_ht' => price2num($object->multicurrency_total_ht),
$array_key.'_multicurrency_total_tva' => price2num($object->multicurrency_total_tva),

View File

@ -1,9 +1,9 @@
<?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2019 Eric Seigne <eric.seigne@cap-rel.fr>
* Copyright (C) 2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2019 Eric Seigne <eric.seigne@cap-rel.fr>
* Copyright (C) 2021 Frédéric France <frederic.france@netlogic.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
@ -277,8 +277,8 @@ function getDefaultDatesForTransfer()
// Period by default on transfer (0: previous month | 1: current month | 2: fiscal year)
$periodbydefaultontransfer = (empty($conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER) ? 0 : $conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER);
if ($periodbydefaultontransfer == 2) {
$sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear ";
$sql .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."'";
$sql = "SELECT date_start, date_end FROM ".MAIN_DB_PREFIX."accounting_fiscalyear ";
$sql .= " WHERE date_start < '".$db->idate(dol_now())."' AND date_end > '".$db->idate(dol_now())."'";
$sql .= $db->plimit(1);
$res = $db->query($sql);
if ($res->num_rows > 0) {
@ -288,6 +288,9 @@ function getDefaultDatesForTransfer()
} else {
$month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
$year_start = dol_print_date(dol_now(), '%Y');
if ($conf->global->SOCIETE_FISCAL_MONTH_START > dol_print_date(dol_now(), '%m')) {
$year_start = $year_start - 1;
}
$year_end = $year_start + 1;
$month_end = $month_start - 1;
if ($month_end < 1) {

View File

@ -3511,7 +3511,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
'bank_account', 'barcode', 'bank', 'bill', 'billa', 'billr', 'billd', 'bookmark', 'bom', 'building',
'cash-register', 'category', 'chart', 'check', 'clock', 'close_title', 'cog', 'collab', 'company', 'contact', 'country', 'contract', 'cron', 'cubes',
'delete', 'dolly', 'dollyrevert', 'donation', 'download', 'edit', 'ellipsis-h', 'email', 'eraser', 'establishment', 'external-link-alt', 'external-link-square-alt',
'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'folder', 'folder-open', 'globe', 'globe-americas', 'grip', 'grip_title', 'group',
'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'autofill', 'folder', 'folder-open', 'globe', 'globe-americas', 'grip', 'grip_title', 'group',
'help', 'holiday',
'info', 'intervention', 'inventory', 'intracommreport',
'label', 'language', 'link', 'list', 'listlight', 'loan', 'lot', 'long-arrow-alt-right',
@ -3558,7 +3558,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
}
$arrayconvpictotofa = array(
'account'=>'university', 'accountline'=>'receipt', 'accountancy'=>'search-dollar', 'action'=>'calendar-alt', 'add'=>'plus-circle', 'address'=> 'address-book', 'asset'=>'money-check-alt',
'account'=>'university', 'accountline'=>'receipt', 'accountancy'=>'search-dollar', 'action'=>'calendar-alt', 'add'=>'plus-circle', 'address'=> 'address-book', 'asset'=>'money-check-alt', 'autofill'=>'fill',
'bank_account'=>'university', 'bill'=>'file-invoice-dollar', 'billa'=>'file-excel', 'billr'=>'file-invoice-dollar', 'supplier_invoicea'=>'file-excel', 'billd'=>'file-medical', 'supplier_invoiced'=>'file-medical',
'bom'=>'shapes',
'chart'=>'chart-line', 'company'=>'building', 'contact'=>'address-book', 'contract'=>'suitcase', 'collab'=>'people-arrows', 'conversation'=>'comments', 'country'=>'globe-americas', 'cron'=>'business-time',

View File

@ -104,10 +104,12 @@ function dolSavePageAlias($filealias, $object, $objectpage)
}
} elseif (empty($objectpage->lang) || !in_array($objectpage->lang, explode(',', $object->otherlang))) {
// Save also alias into all language subdirectories if it is a main language
if (empty($conf->global->WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR)) {
if (empty($conf->global->WEBSITE_DISABLE_MAIN_LANGUAGE_INTO_LANGSUBDIR) && !empty($object->otherlang)) {
$dirname = dirname($filealias);
$filename = basename($filealias);
foreach (explode(',', $object->otherlang) as $sublang) {
// Avoid to erase main alias file if $sublang is empty string
if (empty(trim($sublang))) continue;
$filealiassub = $dirname.'/'.$sublang.'/'.$filename;
$aliascontent = '<?php'."\n";

View File

@ -193,7 +193,7 @@ class ExportExcel2007 extends ModeleExports
$outputlangs->load("exports");
require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/autoloader.php';
require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
require_once PHPEXCELNEW_PATH.'Spreadsheet.php';

View File

@ -112,9 +112,9 @@ class ImportXlsx extends ModeleImports
$this->picto = 'mime/xls'; // Picto (This is not used by the example file code as Mime type, too bad ...)
$this->version = '1.0'; // Driver version
// If driver use an external library, put its name here
require_once DOL_DOCUMENT_ROOT . '/includes/phpoffice/autoloader.php';
require_once DOL_DOCUMENT_ROOT . '/includes/Psr/autoloader.php';
require_once PHPEXCELNEW_PATH . 'Spreadsheet.php';
require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
$this->workbook = new Spreadsheet();
//if ($this->id == 'excel2007new')

View File

@ -942,6 +942,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
$societeforaction->fetch($object->socid);
} elseif (isset($object->fk_soc) && $object->fk_soc > 0) {
$societeforaction->fetch($object->fk_soc);
} elseif (isset($object->thirdparty) && isset($object->thirdparty->id) && $object->thirdparty->id > 0) {
$societeforaction = $object->thirdparty;
}
$projectid = isset($object->fk_project) ? $object->fk_project : 0;

View File

@ -103,6 +103,10 @@ class Donations extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->don->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
@ -179,6 +183,7 @@ class Donations extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->don->creer) {
throw new RestException(401, "Insuffisant rights");
}
// Check mandatory fields
$result = $this->_validate($request_data);
@ -247,6 +252,7 @@ class Donations extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->don->supprimer) {
throw new RestException(401);
}
$result = $this->don->fetch($id);
if (!$result) {
throw new RestException(404, 'Donation not found');
@ -295,6 +301,7 @@ class Donations extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->don->creer) {
throw new RestException(401);
}
$result = $this->don->fetch($id);
if (!$result) {
throw new RestException(404, 'Donation not found');

View File

@ -130,6 +130,7 @@ $date_delivery = dol_mktime(GETPOST('date_deliveryhour', 'int'), GETPOST('date_d
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');
@ -1035,7 +1036,7 @@ if ($action == 'create') {
print '<td class="center">'.$langs->trans("QtyShipped").'</td>';
print '<td class="center">'.$langs->trans("QtyToShip");
if (empty($conf->productbatch->enabled)) {
print '<br><a href="#" id="autofill" class="opacitymedium link cursor cursorpointer">'.$langs->trans("Fill").'</a>';
print '<br><a href="#" id="autofill" class="opacitymedium link cursor cursorpointer">'.img_picto($langs->trans("Autofill"), 'autofill', 'class="paddingrightonly"').$langs->trans("Fill").'</a>';
print ' / ';
} else {
print '<br>';

View File

@ -103,6 +103,10 @@ class Shipments extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->expedition->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -65,6 +65,7 @@ if (!empty($user->socid)) {
$result = restrictedArea($user, 'commande', $id);
$object = new Commande($db);
$shipment = new Expedition($db);
$extrafields = new ExtraFields($db);
// fetch optionals attributes and labels
@ -77,7 +78,8 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'expedition', $object->id, '');
$result = restrictedArea($user, 'expedition', 0, ''); // We use 0 for id, because there is no particular shipment on this tab, only id of order is known
@ -94,13 +96,11 @@ if ($reshook < 0) {
if (empty($reshook)) {
// Categorisation dans projet
if ($action == 'classin') {
$object = new Commande($db);
$object->fetch($id);
$object->setProject(GETPOST('projectid', 'int'));
}
if ($action == 'confirm_cloture' && GETPOST('confirm', 'alpha') == 'yes') {
$object = new Commande($db);
$object->fetch($id);
$result = $object->cloture($user);
} elseif ($action == 'setref_client' && $user->rights->commande->creer) {
@ -132,7 +132,6 @@ if (empty($reshook)) {
}
*/
if ($action == 'setmode' && $user->rights->commande->creer) {
$object = new Commande($db);
$object->fetch($id);
$result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
if ($result < 0) {
@ -141,7 +140,6 @@ if (empty($reshook)) {
}
if ($action == 'setavailability' && $user->rights->commande->creer) {
$object = new Commande($db);
$object->fetch($id);
$result = $object->availability(GETPOST('availability_id'));
if ($result < 0) {
@ -150,7 +148,6 @@ if (empty($reshook)) {
}
if ($action == 'setdemandreason' && $user->rights->commande->creer) {
$object = new Commande($db);
$object->fetch($id);
$result = $object->demand_reason(GETPOST('demand_reason_id'));
if ($result < 0) {
@ -159,7 +156,6 @@ if (empty($reshook)) {
}
if ($action == 'setconditions' && $user->rights->commande->creer) {
$object = new Commande($db);
$object->fetch($id);
$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
if ($result < 0) {
@ -175,7 +171,6 @@ if (empty($reshook)) {
// shipping method
if ($action == 'setshippingmethod' && $user->rights->commande->creer) {
$object = new Commande($db);
$object->fetch($id);
$result = $object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
if ($result < 0) {
@ -185,7 +180,6 @@ if (empty($reshook)) {
// warehouse
if ($action == 'setwarehouse' && $user->rights->commande->creer) {
$object = new Commande($db);
$object->fetch($id);
$result = $object->setWarehouse(GETPOST('warehouse_id', 'int'));
if ($result < 0) {

View File

@ -99,6 +99,10 @@ class ExpenseReports extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->expensereport->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $societe param is ignored and replaced by user's socid
@ -164,6 +168,7 @@ class ExpenseReports extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->expensereport->creer) {
throw new RestException(401, "Insuffisant rights");
}
// Check mandatory fields
$result = $this->_validate($request_data);
@ -427,6 +432,7 @@ class ExpenseReports extends DolibarrApi
if (!DolibarrApiAccess::$user->rights->expensereport->supprimer) {
throw new RestException(401);
}
$result = $this->expensereport->fetch($id);
if (!$result) {
throw new RestException(404, 'Expense Report not found');
@ -469,6 +475,7 @@ class ExpenseReports extends DolibarrApi
if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
throw new RestException(401);
}
$result = $this->expensereport->fetch($id);
if( ! $result ) {
throw new RestException(404, 'expensereport not found');

View File

@ -110,6 +110,10 @@ class Interventions extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->ficheinter->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -298,7 +298,7 @@ if (!defined('NUSOAP_PATH')) {
define('NUSOAP_PATH', (!isset($dolibarr_lib_NUSOAP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/nusoap/lib/' : (empty($dolibarr_lib_NUSOAP_PATH) ? '' : $dolibarr_lib_NUSOAP_PATH.'/'));
}
if (!defined('PHPEXCELNEW_PATH')) {
define('PHPEXCELNEW_PATH', (!isset($dolibarr_lib_PHPEXCELNEW_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/phpoffice/PhpSpreadsheet/' : (empty($dolibarr_lib_PHPEXCELNEW_PATH) ? '' : $dolibarr_lib_PHPEXCELNEW_PATH.'/'));
define('PHPEXCELNEW_PATH', (!isset($dolibarr_lib_PHPEXCELNEW_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/PhpSpreadsheet/' : (empty($dolibarr_lib_PHPEXCELNEW_PATH) ? '' : $dolibarr_lib_PHPEXCELNEW_PATH.'/'));
}
if (!defined('ODTPHP_PATH')) {
define('ODTPHP_PATH', (!isset($dolibarr_lib_ODTPHP_PATH)) ?DOL_DOCUMENT_ROOT.'/includes/odtphp/' : (empty($dolibarr_lib_ODTPHP_PATH) ? '' : $dolibarr_lib_ODTPHP_PATH.'/'));

View File

@ -102,6 +102,10 @@ class SupplierInvoices extends DolibarrApi
{
global $db;
if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid

View File

@ -72,7 +72,7 @@ class SupplierOrders extends DolibarrApi
throw new RestException(404, 'Supplier order not found');
}
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, '', 'commande')) {
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@ -101,6 +101,10 @@ class SupplierOrders extends DolibarrApi
{
global $db, $conf;
if (!DolibarrApiAccess::$user->rights->fournisseur->commande->lire) {
throw new RestException(401);
}
$obj_ret = array();
// case of external user, $thirdparty_ids param is ignored and replaced by user's socid
@ -265,7 +269,7 @@ class SupplierOrders extends DolibarrApi
throw new RestException(404, 'Supplier order not found');
}
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, '', 'commande')) {
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@ -299,7 +303,7 @@ class SupplierOrders extends DolibarrApi
throw new RestException(404, 'Supplier order not found');
}
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, '', 'commande')) {
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
@ -344,7 +348,7 @@ class SupplierOrders extends DolibarrApi
throw new RestException(404, 'Order not found');
}
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, '', 'commande')) {
if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}

View File

@ -2708,7 +2708,7 @@ class CommandeFournisseur extends CommonOrder
if ($qty < $this->line->packaging) {
$qty = $this->line->packaging;
} else {
if (($qty % $this->line->packaging) > 0) {
if (! empty($this->line->packaging) && ($qty % $this->line->packaging) > 0) {
$coeff = intval($qty / $this->line->packaging) + 1;
$qty = $this->line->packaging * $coeff;
setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs');

View File

@ -634,9 +634,10 @@ class ProductFournisseur extends Product
* @param string $sortorder Sort order
* @param int $limit Limit
* @param int $offset Offset
* @param int $socid Filter on a third party id
* @return array Array of Products with new properties to define supplier price
*/
public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0)
public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0, $socid = 0)
{
// phpcs:enable
global $conf;
@ -652,7 +653,8 @@ class ProductFournisseur extends Product
$sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."product as p, ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")";
$sql .= " AND pfp.fk_soc = s.rowid AND pfp.fk_product = p.rowid";
$sql .= " AND s.status=1"; // only enabled company selected
$sql .= ($socid > 0 ? ' AND pfp.fk_soc = '.((int) $socid) : '');
$sql .= " AND s.status = 1"; // only enabled company selected
$sql .= " AND pfp.fk_product = ".((int) $prodid);
if (empty($sortfield)) {
$sql .= " ORDER BY s.nom, pfp.quantity, pfp.price";

View File

@ -83,7 +83,7 @@ class PaiementFourn extends Paiement
* Load payment object
*
* @param int $id Id if payment to get
* @param string $ref Ref of payment to get (currently ref = id but this may change in future)
* @param string $ref Ref of payment to get
* @param int $fk_bank Id of bank line associated to payment
* @return int <0 if KO, -2 if not found, >0 if OK
*/
@ -101,9 +101,9 @@ class PaiementFourn extends Paiement
if ($id > 0) {
$sql .= ' AND p.rowid = '.((int) $id);
} elseif ($ref) {
$sql .= ' AND p.rowid = '.$ref;
} elseif ($fk_bank) {
$sql .= ' AND p.fk_bank = '.$fk_bank;
$sql .= " AND p.ref = '".$this->db->escape($ref)."'";
} elseif ($fk_bank > 0) {
$sql .= ' AND p.fk_bank = '.((int) $fk_bank);
}
//print $sql;

View File

@ -524,6 +524,10 @@ if ($search_user > 0) {
$sql .= ", ".MAIN_DB_PREFIX."element_contact as ec";
$sql .= ", ".MAIN_DB_PREFIX."c_type_contact as tc";
}
// Add table from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql .= ' WHERE f.fk_soc = s.rowid';
$sql .= ' AND f.entity IN ('.getEntity('facture_fourn').')';
if (!$user->rights->societe->client->voir && !$socid) {
@ -686,10 +690,19 @@ if (!$search_all) {
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ",ef.".$key : '');
}
}
// Add GroupBy from hooks
$parameters = array('all' => $all, 'fieldstosearchall' => $fieldstosearchall);
$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
} else {
$sql .= natural_search(array_keys($fieldstosearchall), $search_all);
}
// Add HAVING from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= !empty($hookmanager->resPrint) ? (' HAVING 1=1 ' . $hookmanager->resPrint) : '';
$sql .= $db->order($sortfield, $sortorder);
$nbtotalofrecords = '';
@ -832,6 +845,10 @@ if ($resql) {
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
// Add $param from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
$param .= $hookmanager->resPrint;
// List of mass actions available
$arrayofmassactions = array(

View File

@ -492,12 +492,16 @@ if ($step == 2 && $datatoimport) {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="max_file_size" value="'.$conf->maxfilesize.'">';
print '<br>';
print '<span class="opacitymedium">';
$s = $langs->trans("ChooseFormatOfFileToImport", '{s1}');
$s = str_replace('{s1}', img_picto('', 'next'), $s);
print $s;
print '</span><br><br>';
print '<br>';
print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
print '<table class="noborder" width="100%" cellspacing="0" cellpadding="4">';
@ -513,7 +517,9 @@ if ($step == 2 && $datatoimport) {
print '<td width="16">'.img_picto_common($key, $objmodelimport->getPictoForKey($key)).'</td>';
$text = $objmodelimport->getDriverDescForKey($key);
print '<td>'.$form->textwithpicto($objmodelimport->getDriverLabelForKey($key), $text).'</td>';
print '<td style="text-align:center"><a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a></td>';
print '<td style="text-align:center">';
print img_picto('', 'download', 'class="paddingright opacitymedium"').'<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>';
print '</td>';
// Action button
print '<td style="text-align:right">';
print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=3&format='.$key.$param.'">'.img_picto($langs->trans("SelectFormat"), 'next', 'class="fa-15x"').'</a>';
@ -587,7 +593,7 @@ if ($step == 3 && $datatoimport) {
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', '');
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
@ -598,8 +604,8 @@ if ($step == 3 && $datatoimport) {
print '<td>';
$text = $objmodelimport->getDriverDescForKey($format);
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
print '</td><td style="text-align:right" class="nowrap"><a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>';
print '</td><td style="text-align:right" class="nowrap">';
print img_picto('', 'download', 'class="paddingright opacitymedium"').'<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>';
print '</td></tr>';
print '</table>';
@ -890,7 +896,7 @@ if ($step == 4 && $datatoimport) {
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', '');
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
@ -1374,7 +1380,7 @@ if ($step == 5 && $datatoimport) {
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', '');
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
@ -1468,7 +1474,7 @@ if ($step == 5 && $datatoimport) {
print '</div>';
print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', '');
print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', 'file-import');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
@ -1812,7 +1818,7 @@ if ($step == 6 && $datatoimport) {
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', '');
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
@ -1875,8 +1881,7 @@ if ($step == 6 && $datatoimport) {
print '<b>'.$langs->trans("InformationOnTargetTables").'</b>';
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border">';
//print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnTargetTables").'</b></td></tr>';
print '<table class="border centpercent">';
// Tables imported
print '<tr><td width="25%">';

View File

@ -1,31 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Reader;
interface IReader
{
/**
* IReader constructor.
*/
public function __construct();
/**
* Can the current IReader read the file?
*
* @param string $pFilename
*
* @return bool
*/
public function canRead($pFilename);
/**
* Loads PhpSpreadsheet from file.
*
* @param string $pFilename
*
* @throws Exception
*
* @return \PhpOffice\PhpSpreadsheet\Spreadsheet
*/
public function load($pFilename);
}

View File

@ -1,24 +0,0 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Writer;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
interface IWriter
{
/**
* IWriter constructor.
*
* @param Spreadsheet $spreadsheet
*/
public function __construct(Spreadsheet $spreadsheet);
/**
* Save PhpSpreadsheet to file.
*
* @param string $pFilename Name of the file to save
*
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public function save($pFilename);
}

View File

@ -117,7 +117,7 @@ class Calculation
/**
* An array of the nested cell references accessed by the calculation engine, used for the debug log.
*
* @var array of string
* @var CyclicReferenceStack
*/
private $cyclicReferenceStack;
@ -1945,6 +1945,11 @@ class Calculation
'functionCall' => [MathTrig::class, 'SUMXMY2'],
'argumentCount' => '2',
],
'SWITCH' => [
'category' => Category::CATEGORY_LOGICAL,
'functionCall' => [Logical::class, 'statementSwitch'],
'argumentCount' => '3+',
],
'SYD' => [
'category' => Category::CATEGORY_FINANCIAL,
'functionCall' => [Financial::class, 'SYD'],
@ -2207,8 +2212,8 @@ class Calculation
private static function loadLocales()
{
$localeFileDirectory = __DIR__ . '/locale/';
foreach (glob($localeFileDirectory . '/*', GLOB_ONLYDIR) as $filename) {
$filename = substr($filename, strlen($localeFileDirectory) + 1);
foreach (glob($localeFileDirectory . '*', GLOB_ONLYDIR) as $filename) {
$filename = substr($filename, strlen($localeFileDirectory));
if ($filename != 'en') {
self::$validLocaleLanguages[] = $filename;
}
@ -2413,7 +2418,6 @@ class Calculation
if (strpos($locale, '_') !== false) {
list($language) = explode('_', $locale);
}
if (count(self::$validLocaleLanguages) == 1) {
self::loadLocales();
}
@ -2704,7 +2708,7 @@ class Calculation
* @param Cell $pCell Cell to calculate
* @param bool $resetLog Flag indicating whether the debug log should be reset or not
*
* @throws Exception
* @throws \PhpOffice\PhpSpreadsheet\Exception
*
* @return mixed
*/
@ -2808,7 +2812,7 @@ class Calculation
* @param string $cellID Address of the cell to calculate
* @param Cell $pCell Cell to calculate
*
* @throws Exception
* @throws \PhpOffice\PhpSpreadsheet\Exception
*
* @return mixed
*/
@ -2892,6 +2896,15 @@ class Calculation
{
$cellValue = null;
// Quote-Prefixed cell values cannot be formulae, but are treated as strings
if ($pCell !== null && $pCell->getStyle()->getQuotePrefix() === true) {
return self::wrapResult((string) $formula);
}
if (preg_match('/^=\s*cmd\s*\|/miu', $formula) !== 0) {
return self::wrapResult($formula);
}
// Basic validation that this is indeed a formula
// We simply return the cell value if not
$formula = trim($formula);

View File

@ -273,6 +273,60 @@ class Logical
return ($condition) ? $returnIfTrue : $returnIfFalse;
}
/**
* STATEMENT_SWITCH.
*
* Returns corresponding with first match (any data type such as a string, numeric, date, etc).
*
* Excel Function:
* =SWITCH (expression, value1, result1, value2, result2, ... value_n, result_n [, default])
*
* Expression
* The expression to compare to a list of values.
* value1, value2, ... value_n
* A list of values that are compared to expression. The SWITCH function is looking for the first value that matches the expression.
* result1, result2, ... result_n
* A list of results. The SWITCH function returns the corresponding result when a value matches expression.
* default
* Optional. It is the default to return if expression does not match any of the values (value1, value2, ... value_n).
*
* @category Logical Functions
*
* @param mixed $arguments Statement arguments
*
* @return mixed The value of matched expression
*/
public static function statementSwitch(...$arguments)
{
$result = Functions::VALUE();
if (count($arguments) > 0) {
$targetValue = Functions::flattenSingleValue($arguments[0]);
$argc = count($arguments) - 1;
$switchCount = floor($argc / 2);
$switchSatisfied = false;
$hasDefaultClause = $argc % 2 !== 0;
$defaultClause = $argc % 2 === 0 ? null : $arguments[count($arguments) - 1];
if ($switchCount) {
for ($index = 0; $index < $switchCount; ++$index) {
if ($targetValue == $arguments[$index * 2 + 1]) {
$result = $arguments[$index * 2 + 2];
$switchSatisfied = true;
break;
}
}
}
if (!$switchSatisfied) {
$result = $hasDefaultClause ? $defaultClause : Functions::NA();
}
}
return $result;
}
/**
* IFERROR.
*

View File

@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
class LookupRef
@ -473,8 +474,9 @@ class LookupRef
$lookupValue = Functions::flattenSingleValue($lookupValue);
$matchType = ($matchType === null) ? 1 : (int) Functions::flattenSingleValue($matchType);
$initialLookupValue = $lookupValue;
// MATCH is not case sensitive
$lookupValue = strtolower($lookupValue);
$lookupValue = StringHelper::strToLower($lookupValue);
// Lookup_value type has to be number, text, or logical values
if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) {
@ -502,7 +504,7 @@ class LookupRef
}
// Convert strings to lowercase for case-insensitive testing
if (is_string($lookupArrayValue)) {
$lookupArray[$i] = strtolower($lookupArrayValue);
$lookupArray[$i] = StringHelper::strToLower($lookupArrayValue);
}
if (($lookupArrayValue === null) && (($matchType == 1) || ($matchType == -1))) {
$lookupArray = array_slice($lookupArray, 0, $i - 1);
@ -522,9 +524,13 @@ class LookupRef
if ($matchType == 0 || $matchType == 1) {
foreach ($lookupArray as $i => $lookupArrayValue) {
if (($matchType == 0) && ($lookupArrayValue == $lookupValue)) {
$onlyNumeric = is_numeric($lookupArrayValue) && is_numeric($lookupValue);
$onlyNumericExactMatch = $onlyNumeric && $lookupArrayValue == $lookupValue;
$nonOnlyNumericExactMatch = !$onlyNumeric && $lookupArrayValue === $lookupValue;
$exactMatch = $onlyNumericExactMatch || $nonOnlyNumericExactMatch;
if (($matchType == 0) && $exactMatch) {
// exact match
return ++$i;
return $i + 1;
} elseif (($matchType == 1) && ($lookupArrayValue <= $lookupValue)) {
$i = array_search($i, $keySet);
@ -661,7 +667,9 @@ class LookupRef
{
reset($a);
$firstColumn = key($a);
if (($aLower = strtolower($a[$firstColumn])) == ($bLower = strtolower($b[$firstColumn]))) {
$aLower = StringHelper::strToLower($a[$firstColumn]);
$bLower = StringHelper::strToLower($b[$firstColumn]);
if ($aLower == $bLower) {
return 0;
}
@ -707,11 +715,14 @@ class LookupRef
uasort($lookup_array, ['self', 'vlookupSort']);
}
$lookupLower = StringHelper::strToLower($lookup_value);
$rowNumber = $rowValue = false;
foreach ($lookup_array as $rowKey => $rowData) {
$firstLower = StringHelper::strToLower($rowData[$firstColumn]);
// break if we have passed possible keys
if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) ||
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) {
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && ($firstLower > $lookupLower))) {
break;
}
// remember the last key, but only if datatypes match
@ -719,17 +730,15 @@ class LookupRef
(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]))) {
if ($not_exact_match) {
$rowNumber = $rowKey;
$rowValue = $rowData[$firstColumn];
continue;
} elseif ((strtolower($rowData[$firstColumn]) == strtolower($lookup_value))
} elseif (($firstLower == $lookupLower)
// Spreadsheets software returns first exact match,
// we have sorted and we might have broken key orders
// we want the first one (by its initial index)
&& (($rowNumber == false) || ($rowKey < $rowNumber))
) {
$rowNumber = $rowKey;
$rowValue = $rowData[$firstColumn];
}
}
}
@ -782,8 +791,11 @@ class LookupRef
// break if we have passed possible keys
$bothNumeric = is_numeric($lookup_value) && is_numeric($rowData);
$bothNotNumeric = !is_numeric($lookup_value) && !is_numeric($rowData);
$lookupLower = StringHelper::strToLower($lookup_value);
$rowDataLower = StringHelper::strToLower($rowData);
if (($bothNumeric && $rowData > $lookup_value) ||
($bothNotNumeric && strtolower($rowData) > strtolower($lookup_value))) {
($bothNotNumeric && $rowDataLower > $lookupLower)) {
break;
}
@ -793,7 +805,7 @@ class LookupRef
$rowNumber = $rowKey;
continue;
} elseif (strtolower($rowData) === strtolower($lookup_value)
} elseif ($rowDataLower === $lookupLower
&& ($rowNumber === null || $rowKey < $rowNumber)
) {
$rowNumber = $rowKey;

View File

@ -1224,11 +1224,12 @@ class MathTrig
}
$testCondition = '=' . $arg . $condition;
$sumValue = array_key_exists($key, $sumArgs) ? $sumArgs[$key] : 0;
if (is_numeric($sumArgs[$key]) &&
if (is_numeric($sumValue) &&
Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
// Is it a value within our criteria and only numeric can be added to the result
$returnValue += $sumArgs[$key];
$returnValue += $sumValue;
}
}

View File

@ -16,6 +16,8 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder
* @param Cell $cell Cell to bind value to
* @param mixed $value Value to bind in cell
*
* @throws \PhpOffice\PhpSpreadsheet\Exception
*
* @return bool
*/
public function bindValue(Cell $cell, $value = null)

View File

@ -523,7 +523,7 @@ class Cell
/**
* If this cell is in a merge range, then return the range.
*
* @return string
* @return false|string
*/
public function getMergeRange()
{

View File

@ -157,14 +157,12 @@ abstract class Coordinate
}
// Build range
$imploded = [];
$counter = count($pRange);
for ($i = 0; $i < $counter; ++$i) {
$pRange[$i] = implode(':', $pRange[$i]);
}
$imploded = implode(',', $pRange);
return $imploded;
return implode(',', $pRange);
}
/**

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