Merge remote-tracking branch 'upstream/develop' into ajaxtooltip

This commit is contained in:
Frédéric FRANCE 2023-02-09 15:26:40 +01:00
commit 1fa1d11500
57 changed files with 698 additions and 319 deletions

View File

@ -30,20 +30,20 @@ NEW: #21000 Added columns 'alias_name' on project, supplier invoice, supplier or
NEW: #21780 Add pid field to Cronjob class and store PID on job execution
NEW: #21395 Added option for dark theme mode in display - color and theme
NEW: #21397 added option to auto define barcode numbers for third-parties in barcode module setup
NEW: #21399
NEW: #21399 add image for event_array
NEW: #21442 Enhancement of module builder init
NEW: #21654 add bank account number used on invoices for debit
NEW: #22048 Added notes to productlot module
NEW: #22048 added notes to productlot module
NEW: #22298 Bank - Add salaries & vat in the tab of planned entries of a bank account
NEW: #22328
NEW: #22424
NEW: #22328 OAuth admin
NEW: #22424 online signature for contracts
NEW: #22500 member module set up made easier
NEW: #22527 projects and thirdparties can be viewed as conversation ("Message" view), like events/agenda.
NEW: #22546 can now set user supervisors using mass action in htdocs/user
NEW: #22594 can chose if VAT ID is unique or not for third parties
NEW: #22622 all partnerships displayed on tab partnership of a thirdparty and member
NEW: #22676 massaction for updating product prices
NEW: #22735 Massaction to affect users on projects
NEW: #22735 massaction to affect users on projects
NEW: #25594 can chose if VAT ID is unique or not for third parties
NEW: #4482 adding js to hide/show advanced option on the export data page
@ -57,27 +57,17 @@ NEW: Add max size send for "backup and link to mail" option
NEW: Add method httponly_accessforbidden()
NEW: Add more advices into the Setup security page
NEW: Add new global variable for keeping the previous signature information on proposale (case of reopen a proposale)
NEW: Add objectLink on expedition
NEW: Add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
NEW: Add option --force on CLI cron_run_jobs.php
NEW: Add option "Show price on the generated documents for receptions"
NEW: invoice export : add accounting affectation
NEW: label on products categories filter
NEW: manage no email with thirdparties (better for GDPR)
NEW: Manage VAT on all lines on purchases cycle
NEW: On a bank reconciled line, we can modify the bank receipt
NEW: parent company column and filter in invoice and order list
NEW: possibility to select scopes with checkbox for Oauth tokens
NEW: private and public note on user, thirdparty and contact list
NEW: private and public note columns on user, thirdparty and contact lists
NEW: Public counters feature
NEW: Saved token of OAUTH module are now encrypted into llx_oauth_token
NEW: Save one click to select on delivery ack, on emails.
NEW: scheduled job to send unpaid invoice reminder can now use the cc and bcc from email template
NEW: experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP)
NEW: can substitue project title in mail template
NEW: The purge of files can purge only if older than a number of seconds
NEW: Update ActionComm type_code on email message ticket
NEW: Finance - VAT - Admin - Add information on deadline day for submission of VAT declaration
NEW: Add the target to select attendees of event for emailings
NEW: add redirect on action confirm addconsumedline and addproduceline
NEW: Add the referrer-policy to "same-origin" by default on all public pages.
@ -87,17 +77,18 @@ NEW: Can enter the unit price including the VAT
NEW: Can invoice task time per different services
NEW: Can set a commercial discount by entering amount including VAT
NEW: Can set start and end dates and comment on button "Activate all services"
NEW: can sort and preselected best supplier price
NEW: show date delivery planned on orders linked to company and product
NEW: filter on reception dates (from / to) in cheque paiement card
NEW: Accountancy - Add a graphic option to enable lettering function - FPC21
NEW: Accountancy - Add a way to clean some words when you generate thirdparty accounting account
NEW: Accountancy - Added an option during export to export or not the lettering FPC21
NEW: Accountancy - add a graphic option to enable lettering function - FPC21
NEW: Accountancy - add a way to clean some words when you generate thirdparty accounting account
NEW: Accountancy - added an option during export to export or not the lettering FPC21
NEW: Accountancy - Invoice export : add accounting affectation
NEW: Accountancy - Manage supplier deposit with specific account
NEW: Accountancy - Model Digitaria - Add a way to clean some words when you generate thirdparty accounting account FPC22
NEW: Agenda - start a simple support of recurrent events on agenda
NEW: Bank - add salaries & VAT in tab planned entries
NEW: Bank - on a bank reconciled line, we can modify the bank receipt
NEW: Contracts - add a method doAutoRenewContracts that can be used as a cron task
NEW: Contracts - default template of contract is not mandatory
NEW: Contracts - Manage Position (Rank) on Contract Lines
@ -108,22 +99,29 @@ NEW: EMail - can send an email on scheduled job error
NEW: EMail - on a form to send an email, we show all emails of all contacts of object
NEW: EMail - add the SMTP header References on ticket email created by email
NEW: EMail - add substitution key __SENDEREMAIL_SIGNATURE__
NEW: EMail - experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP)
NEW: EMail-Collector - add IMAP port setting
NEW: EMail-Collector - add a button "Test collect"
NEW: Export - Add " as enclosure by default for CSV export. Keep removing CR/LF.
NEW: Event-Organization - add date event (!= date project) and location on event organization
NEW: Expedition - add objectLink on expedition
NEW: Export - Add " as enclosure by default for CSV export. Keep removing CR/LF.
NEW: Extrafields - add badge in admin extrafields setup
NEW: Extrafields - can edit property css, cssview, csslist on extrafields
NEW: Extrafields - default values in extrafields are not more limited to 255 char.
NEW: Extrafields - field price with currency
NEW: Extrafields - support IP type to store IP addresses
NEW: Finance - VAT - Admin - Add information on deadline day for submission of VAT declaration
NEW: Interventions - enable online signature for interventions
NEW: Invoice - Add french mention on pdf when vat debit option is on
NEW: Invoice - add french mention on PDF when VAT debit option is on
NEW: Members - default_lang for members
NEW: Members - Table of membership types
NEW: Members - table of membership types
NEW: Members - add free membership amounts at the membership type level
NEW: OAuth - possibility to select scopes with checkbox for OAuth tokens
NEW: OAuth - saved token of OAUTH module are now encrypted into llx_oauth_token
NEW: Orders - resize parent company column in order list
NEW: Products supplier price - autofill default supplier VAT
NEW: Products - Categories - label on products categories filter
NEW: Products - Supplier price - autofill default supplier VAT
NEW: Products - Supplier price - can sort and preselected best supplier price
NEW: Projects - add author on list
NEW: Projects - add thirdparty column to the time list (projet/tasks/time.php)
NEW: Proposals - show delivery mode on PDF for proposals
@ -144,8 +142,10 @@ NEW: TakePOS - display currency in TakePOS menu
NEW: TakePOS - Header Scroll in TakePOS
NEW: TakePOS - Receipt preview in TakePOS setup
NEW: TakePOS - support of Stripe Terminal with TakePOS
NEW: Thirdparty - manage no email with thirdparties (better for GDPR)
NEW: Thirdparty - set thirdparty type with company modify trigger
NEW: Tickets - change filter type on tickets list into a multiselect combo
NEW: Tickets - add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
NEW: Website - can delete a whole website if disabled
NEW: Website - can remove a website template
NEW: Website - can set header "Strict-Transport-Security" in web sites.
@ -176,11 +176,16 @@ NEW: Security: add fail2ban rules examples to limit access to /public pages
Option / Const for System:
NEW: FICHINTER_ALLOW_EXTERNAL_DOWNLOAD
NEW: MAIN_CHECKBOX_LEFT_COLUMN
NEW: MAIN_EMAIL_SUPPORT_ACK
NEW: MAIN_IMAP_USE_PHPIMAP
NEW: MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS - const to show category customer filter
NEW: PRODUCT_ALLOW_EXTERNAL_DOWNLOAD
NEW: PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT - showing warehouse on PDF
NEW: PRODUIT_DESC_IN_FORM accept - desktop only or +smartphone
NEW: PROPAL_BYPASS_VALIDATED_STATUS
NEW: PROPAL_NEW_AS_SIGNED
NEW: PROPAL_SKIP_ACCEPT_REFUSE
NEW: TIMESPENT_ALWAYS_UPDATE_THM - when it's on we always check current thm of user to update it in task time line
Localisation:
@ -238,25 +243,38 @@ Following changes may create regressions for some external modules, but were nec
* Rename the substitution for project label instead of project title in substitution variables
***** ChangeLog for 16.0.4 compared to 16.0.2 *****
***** ChangeLog for 16.0.4 compared to 16.0.3 *****
FIX: Amount of localtax1 and 2 not correctly save on purchase order (the rate was saved instead)
FIX: #20415
FIX: #21280
FIX: #23008
FIX: #22271
FIX: #22524
FIX: #22837
FIX: #22964
FIX: #23012
FIX: #23019 Impossible to add task times to an existing draft invoice
FIX: #23072
FIX: #23087
FIX: #23115
FIX: #23116
FIX: #23281
FIX: #23420 : wrong check on $search_categ value causing FATAL ERROR
FIX: Accountancy - Quadra export
FIX: add border left on image product when conf activated
FIX: Add missing token when deleting template inn order_supplier admin menu
FIX: Amount of localtax1 and 2 not correctly save on purchase order (the
FIX: API access for deactivated users
FIX: bad selection of barcode numbering module
FIX: Can't see all time spent by all user
FIX: CI
FIX: CommonObject - showOptionals - Display blank td when MAIN_VIEW_LINE_NUMBER is enabled and action is confirm_valid
FIX: Documents API inconsistency
FIX: Empty FormSetup emailTemplate type IF empty fieldvalue
FIX: Errors Handling for CreateFrom Hooks
FIX: error with dol_banner_tab, ref is needed
FIX: ExpenseReport card was not reloaded after addline
FIX: #23075
FIX: #23117
FIX: get multicurrency infos of propal when create order from propal with "WORKFLOW_PROPAL_AUTOCREATE_ORDER" conf
@ -264,12 +282,16 @@ FIX: Give predictable order to inventory lines
FIX: include class multicurrency
FIX: methods declaration (backport fix 67b9a7dc07d708231d12b5e58800334d4a01ef98)
FIX: multicurrency_tx and not currency_tx
FIX: PGSQL Integer type does not have a free length
FIX: on public ticket list, only the page 1 was accessible. Other pages were 404 error.
FIX: PGSQL Integer type does not have a free lenght
FIX: PGSQL Int type does not have a free lenght
FIX: Product list in setup.php in new Module
FIX: propal and order stats broken on Tag+User(retricted customer list)
FIX: saving of numbering module for jobs
FIX: Stickler
FIX: travis
FIX: wrong check on $search_categ value causing fatal error
FIX: wrong stock list with multicompany and without stock sharing
***** ChangeLog for 16.0.3 compared to 16.0.2 *****

View File

@ -674,7 +674,7 @@ if (empty($reshook)) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
if ($result < 0) {
$error++;
setEventMessages($object->error, $object->errors, 'errors');
@ -745,7 +745,7 @@ if (empty($reshook)) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
if ($result < 0) {
$error++;
setEventMessages($object->error, $object->errors, 'errors');
@ -816,7 +816,7 @@ if (empty($reshook)) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
if ($result < 0) {
$error++;
setEventMessages($object->error, $object->errors, 'errors');

View File

@ -440,11 +440,37 @@ class Adherent extends CommonObject
* @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
* @param string $errors_to erros to
* @param string $moreinheader Add more html headers
* @deprecated since V18
* @see sendEmail
* @return int <0 if KO, >0 if OK
*/
public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
{
// phpcs:enable
dol_syslog('Warning using deprecated Adherent::send_an_email', LOG_WARNING);
return $this->sendEmail($text, $subject, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml, $errors_to, $moreinheader);
}
/**
* Function sending an email to the current member with the text supplied in parameter.
*
* @param string $text Content of message (not html entities encoded)
* @param string $subject Subject of message
* @param array $filename_list Array of attached files
* @param array $mimetype_list Array of mime types of attached files
* @param array $mimefilename_list Array of public names of attached files
* @param string $addr_cc Email cc
* @param string $addr_bcc Email bcc
* @param int $deliveryreceipt Ask a delivery receipt
* @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
* @param string $errors_to erros to
* @param string $moreinheader Add more html headers
* @since V18
* @return int <0 if KO, >0 if OK
*/
public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
{
global $conf, $langs;
// Detect if message is HTML

View File

@ -405,7 +405,7 @@ if ($user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscripti
$moreinheader = 'X-Dolibarr-Info: send_an_email by adherents/subscription.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, '', $moreinheader);
if ($result < 0) {
$errmsg = $object->error;
setEventMessages($object->error, $object->errors, 'errors');

View File

@ -105,10 +105,15 @@ print '<br>';
print '<section class="setupsection">';
$nbmodulesnotautoenabled = count($conf->modules);
if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--;
// Show info setup module
print img_picto('', 'cog', 'class="paddingright valignmiddle double"').' '.$langs->trans("SetupDescriptionLink", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentities("Setup"), $langs->transnoentities("Modules"));
print '<br><br>'.$langs->trans("SetupDescription4b");
if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled
if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled
$langs->load("errors");
$warnpicto = img_warning($langs->trans("WarningEnableYourModulesApplications"), 'style="padding-right: 6px;"');
print '<br><div class="warning"><a href="'.DOL_URL_ROOT.'/admin/modules.php?mainmenu=home">'.$warnpicto.$langs->trans("WarningEnableYourModulesApplications").'</a></div>';

View File

@ -379,99 +379,95 @@ foreach ($modulesdir as $dir) {
try {
$res = include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error.
if (class_exists($modName)) {
try {
$objMod = new $modName($db);
$modNameLoaded[$modName] = $dir;
if (!$objMod->numero > 0 && $modName != 'modUser') {
dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR);
}
$j = $objMod->numero;
$objMod = new $modName($db);
$modNameLoaded[$modName] = $dir;
if (!$objMod->numero > 0 && $modName != 'modUser') {
dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR);
}
$j = $objMod->numero;
$modulequalified = 1;
$modulequalified = 1;
// We discard modules according to features level (PS: if module is activated we always show it)
$const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod)));
if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) {
$modulequalified = 0;
}
if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) {
$modulequalified = 0;
}
if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) {
$modulequalified = 0;
}
// We discard modules according to features level (PS: if module is activated we always show it)
$const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($objMod)));
if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) {
$modulequalified = 0;
}
if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) {
$modulequalified = 0;
}
if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) {
$modulequalified = 0;
}
// We discard modules according to property ->hidden
if (!empty($objMod->hidden)) {
$modulequalified = 0;
}
// We discard modules according to property ->hidden
if (!empty($objMod->hidden)) {
$modulequalified = 0;
}
if ($modulequalified > 0) {
$publisher = dol_escape_htmltag($objMod->getPublisher());
$external = ($objMod->isCoreOrExternalModule() == 'external');
if ($external) {
if ($publisher) {
$arrayofnatures['external_'.$publisher] = $langs->trans("External").' - '.$publisher;
} else {
$arrayofnatures['external_'] = $langs->trans("External").' - '.$langs->trans("UnknownPublishers");
}
}
ksort($arrayofnatures);
// Define array $categ with categ with at least one qualified module
$filename[$i] = $modName;
$modules[$modName] = $objMod;
// Gives the possibility to the module, to provide his own family info and position of this family
if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
$familyinfo = array_merge($familyinfo, $objMod->familyinfo);
$familykey = key($objMod->familyinfo);
if ($modulequalified > 0) {
$publisher = dol_escape_htmltag($objMod->getPublisher());
$external = ($objMod->isCoreOrExternalModule() == 'external');
if ($external) {
if ($publisher) {
$arrayofnatures['external_'.$publisher] = $langs->trans("External").' - '.$publisher;
} else {
$familykey = $objMod->family;
$arrayofnatures['external_'] = $langs->trans("External").' - '.$langs->trans("UnknownPublishers");
}
}
ksort($arrayofnatures);
$moduleposition = ($objMod->module_position ? $objMod->module_position : '50');
if ($objMod->isCoreOrExternalModule() == 'external' && $moduleposition < 100000) {
// an external module should never return a value lower than '80'.
$moduleposition = '80'; // External modules at end by default
}
// Define array $categ with categ with at least one qualified module
$filename[$i] = $modName;
$modules[$modName] = $objMod;
// Add list of warnings to show into arrayofwarnings and arrayofwarningsext
if (!empty($objMod->warnings_activation)) {
$arrayofwarnings[$modName] = $objMod->warnings_activation;
}
if (!empty($objMod->warnings_activation_ext)) {
$arrayofwarningsext[$modName] = $objMod->warnings_activation_ext;
}
$familyposition = (empty($familyinfo[$familykey]['position']) ? 0 : $familyinfo[$familykey]['position']);
$listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other');
if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) {
// If module is extern and into a custom group (not into an official predefined one), it must appear at end (custom groups should not be before official groups).
if (is_numeric($familyposition)) {
$familyposition = sprintf("%03d", (int) $familyposition + 100);
}
}
$orders[$i] = $familyposition."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number
// Set categ[$i]
$specialstring = 'unknown';
if ($objMod->version == 'development' || $objMod->version == 'experimental') {
$specialstring = 'expdev';
}
if (isset($categ[$specialstring])) {
$categ[$specialstring]++; // Array of all different modules categories
} else {
$categ[$specialstring] = 1;
}
$j++;
$i++;
// Gives the possibility to the module, to provide his own family info and position of this family
if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
$familyinfo = array_merge($familyinfo, $objMod->familyinfo);
$familykey = key($objMod->familyinfo);
} else {
dol_syslog("Module ".get_class($objMod)." not qualified");
$familykey = $objMod->family;
}
} catch (Exception $e) {
dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
$moduleposition = ($objMod->module_position ? $objMod->module_position : '50');
if ($objMod->isCoreOrExternalModule() == 'external' && $moduleposition < 100000) {
// an external module should never return a value lower than '80'.
$moduleposition = '80'; // External modules at end by default
}
// Add list of warnings to show into arrayofwarnings and arrayofwarningsext
if (!empty($objMod->warnings_activation)) {
$arrayofwarnings[$modName] = $objMod->warnings_activation;
}
if (!empty($objMod->warnings_activation_ext)) {
$arrayofwarningsext[$modName] = $objMod->warnings_activation_ext;
}
$familyposition = (empty($familyinfo[$familykey]['position']) ? 0 : $familyinfo[$familykey]['position']);
$listOfOfficialModuleGroups = array('hr', 'technic', 'interface', 'technic', 'portal', 'financial', 'crm', 'base', 'products', 'srm', 'ecm', 'projects', 'other');
if ($external && !in_array($familykey, $listOfOfficialModuleGroups)) {
// If module is extern and into a custom group (not into an official predefined one), it must appear at end (custom groups should not be before official groups).
if (is_numeric($familyposition)) {
$familyposition = sprintf("%03d", (int) $familyposition + 100);
}
}
$orders[$i] = $familyposition."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number
// Set categ[$i]
$specialstring = 'unknown';
if ($objMod->version == 'development' || $objMod->version == 'experimental') {
$specialstring = 'expdev';
}
if (isset($categ[$specialstring])) {
$categ[$specialstring]++; // Array of all different modules categories
} else {
$categ[$specialstring] = 1;
}
$j++;
$i++;
} else {
dol_syslog("Module ".get_class($objMod)." not qualified");
}
} else {
print "Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)<br>";
@ -523,12 +519,10 @@ asort($orders);
$nbofactivatedmodules = count($conf->modules);
//$conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING = 1000;
/*$moreinfo = $langs->trans("TitleNumberOfActivatedModules");
$moreinfo2 = '<b class="largenumber">'.($nbofactivatedmodules - 1).'</b> / <b class="largenumber">'.count($modules).'</b>';
if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) {
$moreinfo2 .= ' '.img_warning($langs->trans("YouMustEnableOneModule"));
}*/
$nbmodulesnotautoenabled = count($conf->modules);
if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--;
print load_fiche_titre($langs->trans("ModulesSetup"), '', 'title_setup');
@ -539,7 +533,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
$desc .= ' '.$langs->trans("ModulesDesc2", '{picto2}');
$desc = str_replace('{picto}', img_picto('', 'switch_off', 'class="size15x"'), $desc);
$desc = str_replace('{picto2}', img_picto('', 'setup', 'class="size15x"'), $desc);
if (!count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled
if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled
$deschelp = '<div class="info hideonsmartphone">'.$desc."<br></div><br>\n";
}
}
@ -553,7 +547,7 @@ if ($mode == 'develop') {
$deschelp = '<div class="info hideonsmartphone">'.$langs->trans("ModulesDevelopDesc")."<br></div><br>\n";
}
$head = modules_prepare_head($nbofactivatedmodules, count($modules));
$head = modules_prepare_head($nbofactivatedmodules, count($modules), $nbmodulesnotautoenabled);
if ($mode == 'common' || $mode == 'commonkanban') {

View File

@ -370,7 +370,7 @@ class Boms extends DolibarrApi
*
* @url PUT {id}/lines/{lineid}
*
* @return array|bool
* @return object|bool
*/
public function putLine($id, $lineid, $request_data = null)
{

View File

@ -924,6 +924,10 @@ while ($currentdaytoshow < $lastdaytoshow) {
if ($usergroup > 0) {
$sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
}
if ($user->socid > 0) {
// External users should see only contacts of their company
$sql .= " AND u.fk_soc = ".((int) $user->socid);
}
//print $sql;
$resql = $db->query($sql);

View File

@ -61,25 +61,17 @@ if (isset($user->socid) && $user->socid > 0) {
$socid = $user->socid;
}
$max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT;
$maxofloop = (empty($conf->global->MAIN_MAXLIST_OVERLOAD) ? 500 : $conf->global->MAIN_MAXLIST_OVERLOAD);
$now = dol_now();
// Security check
//$socid = GETPOST("socid", 'int');
if ($user->socid > 0) {
$action = '';
$id = $user->socid;
} else {
$id = 0;
}
//restrictedArea($user, 'societe', $id, '&societe', '', 'fk_soc', 'rowid', 0);
//restrictedArea($user, 'societe', $socid, '&societe', '', 'fk_soc', 'rowid', 0);
if (!$user->hasRight('propal', 'read') && !$user->hasRight('supplier_proposal', 'read') && !$user->hasRight('commande', 'read') && !$user->hasRight('fournisseur', 'commande', 'read')
&& !$user->hasRight('supplier_order', 'read') && !$user->hasRight('fichinter', 'read')) {
accessforbidden();
}
$maxofloop = (empty($conf->global->MAIN_MAXLIST_OVERLOAD) ? 500 : $conf->global->MAIN_MAXLIST_OVERLOAD);
/*

View File

@ -14,6 +14,7 @@
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.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
@ -1841,25 +1842,25 @@ if ($action == 'create' && $usercancreate) {
// Delivery delay
print '<tr class="fielddeliverydelay"><td>'.$langs->trans('AvailabilityPeriod').'</td><td>';
print img_picto('', 'clock', 'class="pictofixedwidth"');
$form->selectAvailabilityDelay($availability_id, 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
$form->selectAvailabilityDelay((GETPOSTISSET('availability_id')?GETPOST('availability_id'):$availability_id), 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
print '</td></tr>';
// Terms of payment
print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
print img_picto('', 'payment', 'class="pictofixedwidth"');
print $form->getSelectConditionsPaiements($cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id')?GETPOST('cond_reglement_id'):$cond_reglement_id), 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
print '</td></tr>';
// Payment mode
print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
print img_picto('', 'bank', 'class="pictofixedwidth"');
print $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
print $form->select_types_paiements((GETPOSTISSET('mode_reglement_id')?GETPOST('mode_reglement_id'):$mode_reglement_id), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
print '</td></tr>';
// Bank Account
if (!empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_ORDER) && isModEnabled("banque")) {
print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes((GETPOSTISSET('fk_account')?GETPOST('fk_account'):$fk_account), 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
print '</td></tr>';
}
@ -1867,7 +1868,7 @@ if ($action == 'create' && $usercancreate) {
if (isModEnabled('expedition')) {
print '<tr><td>'.$langs->trans('SendingMethod').'</td><td>';
print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
$form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
$form->selectShippingMethod((GETPOSTISSET('shipping_method_id')?GETPOST('shipping_method_id'):$shipping_method_id), 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
print '</td></tr>';
}
@ -1876,14 +1877,14 @@ if ($action == 'create' && $usercancreate) {
require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
$formproduct = new FormProduct($db);
print '<tr><td>'.$langs->trans('Warehouse').'</td><td>';
print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($warehouse_id, 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses((GETPOSTISSET('warehouse_id')?GETPOST('warehouse_id'):$warehouse_id), 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
print '</td></tr>';
}
// Source / Channel - What trigger creation
print '<tr><td>'.$langs->trans('Channel').'</td><td>';
print img_picto('', 'question', 'class="pictofixedwidth"');
$form->selectInputReason($demand_reason_id, 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
$form->selectInputReason((GETPOSTISSET('demand_reason_id')?GETPOST('demand_reason_id'):$demand_reason_id), 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
print '</td></tr>';
// TODO How record was recorded OrderMode (llx_c_input_method)
@ -1893,7 +1894,7 @@ if ($action == 'create' && $usercancreate) {
$langs->load("projects");
print '<tr>';
print '<td>'.$langs->trans("Project").'</td><td>';
print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), (GETPOSTISSET('projectid')?GETPOST('projectid'):$projectid), 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
print '</td>';
print '</tr>';
@ -1952,7 +1953,7 @@ if ($action == 'create' && $usercancreate) {
print '<tr>';
print '<td>'.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).'</td>';
print '<td class="maxwidthonsmartphone">';
print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency($currency_code, 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx');
print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency((GETPOSTISSET('multicurrency_code')?GETPOST('multicurrency_code'):$currency_code), 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx');
print '</td></tr>';
}

View File

@ -1053,6 +1053,7 @@ class Orders extends DolibarrApi
}
$shipment = new Expedition($this->db);
$shipment->socid = $this->commande->socid;
$shipment->origin_id = $this->commande->id;
$result = $shipment->create(DolibarrApiAccess::$user);
if ($result <= 0) {
throw new RestException(500, 'Error on creating expedition :'.$this->db->lasterror());

View File

@ -249,9 +249,9 @@ if ($modecompta == 'CREANCES-DETTES') {
$sql .= " sum(f.total_ht) as amount, sum(f.total_ttc) as amount_ttc";
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s";
if ($selected_cat === -2) { // Without any category
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc";
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc";
} elseif ($selected_cat) { // Into a specific category
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_societe as cs";
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
}
$sql .= " WHERE f.fk_statut in (1,2)";
$sql .= " AND f.type IN (0,2)";
@ -276,9 +276,9 @@ if ($modecompta == 'CREANCES-DETTES') {
$sql .= ", ".MAIN_DB_PREFIX."paiementfourn as p";
$sql .= ", ".MAIN_DB_PREFIX."societe as s";
if ($selected_cat === -2) { // Without any category
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc";
$sql .= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc";
} elseif ($selected_cat) { // Into a specific category
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_societe as cs";
$sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_fournisseur as cs";
}
$sql .= " WHERE p.rowid = pf.fk_paiementfourn";
$sql .= " AND pf.fk_facturefourn = f.rowid";

View File

@ -302,7 +302,7 @@ $dolibarr_main_restrict_ip='';
// This might be required if you access Dolibarr behind a proxy that make bad URL rewriting, to avoid false alarms.
// In most cases, you should always keep this to 0.
// Default value: 0
// Possible values: 0 or 1
// Possible values: 0 or 1 (no strict CSRF test, only test on referer) or 2 (no CSRF test at all)
// Examples:
// $dolibarr_nocsrfcheck='0';
//

View File

@ -82,6 +82,8 @@ class CGenericDic
$fieldlabel = 'label';
if ($this->table_element == 'c_stcomm') {
$fieldlabel = 'libelle';
} elseif ($this->table_element == 'c_type_fees') {
$fieldrowid = 'id';
}
$error = 0;
@ -162,6 +164,8 @@ class CGenericDic
if ($this->table_element == 'c_stcomm') {
$fieldrowid = 'id';
$fieldlabel = 'libelle';
} elseif ($this->table_element == 'c_type_fees') {
$fieldrowid = 'id';
}
$sql = "SELECT";
@ -233,6 +237,8 @@ class CGenericDic
if ($this->table_element == 'c_stcomm') {
$fieldrowid = 'id';
$fieldlabel = 'libelle';
} elseif ($this->table_element == 'c_type_fees') {
$fieldrowid = 'id';
}
$sql = "SELECT";
@ -303,6 +309,8 @@ class CGenericDic
if ($this->table_element == 'c_stcomm') {
$fieldrowid = 'id';
$fieldlabel = 'libelle';
} elseif ($this->table_element == 'c_type_fees') {
$fieldrowid = 'id';
}
// Clean parameters

View File

@ -553,6 +553,12 @@ abstract class CommonDocGenerator
$resarray[$array_key.'_project_description'] = $object->project->description;
$resarray[$array_key.'_project_date_start'] = dol_print_date($object->project->date_start, 'day');
$resarray[$array_key.'_project_date_end'] = dol_print_date($object->project->date_end, 'day');
} else { // empty replacement
$resarray[$array_key.'_project_ref'] ='';
$resarray[$array_key.'_project_title'] = '';
$resarray[$array_key.'_project_description'] = '';
$resarray[$array_key.'_project_date_start'] = '';
$resarray[$array_key.'_project_date_end'] = '';
}
// Add vat by rates
@ -716,6 +722,14 @@ abstract class CommonDocGenerator
foreach ($tmpproduct->array_options as $key => $label) {
$resarray["line_product_".$key] = $label;
}
} else {
// Set unused placeholders as blank
$extrafields->fetch_name_optionals_label("product");
$extralabels = $extrafields->attributes["product"]['label'];
foreach ($extralabels as $key => $label) {
$resarray['line_product_options_'.$key] = '';
}
}
return $resarray;

View File

@ -4320,7 +4320,7 @@ abstract class CommonObject
* @param string $field_select name of field we need to get a list
* @param string $field_where name of field of object we need to get linked items
* @param string $table_element name of association table
* @return array Array of record
* @return array|int Array of record, -1 if empty
*/
public static function getAllItemsLinkedByObjectID($fk_object_where, $field_select, $field_where, $table_element)
{
@ -6114,6 +6114,8 @@ abstract class CommonObject
if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) {
//var_dump($conf->disable_compute);
if (empty($conf->disable_compute)) {
global $objectoffield; // We set a global variable to $objectoffield so
$objectoffield = $this; // we can use it inside computed formula
$this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, '');
}
}

View File

@ -202,9 +202,10 @@ class Form
* @param string $paramid Key of parameter for id ('id', 'socid')
* @param string $gm 'auto' or 'tzuser' or 'tzuserrel' or 'tzserver' (when $typeofdata is a date)
* @param array $moreoptions Array with more options. For example array('addnowlink'=>1), array('valuealreadyhtmlescaped'=>1)
* @param string $editaction [=''] use GETPOST default action or set action to edit mode
* @return string HTML edit field
*/
public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 1, $formatfunc = '', $paramid = 'id', $gm = 'auto', $moreoptions = array())
public function editfieldval($text, $htmlname, $value, $object, $perm, $typeofdata = 'string', $editvalue = '', $extObject = null, $custommsg = null, $moreparam = '', $notabletag = 1, $formatfunc = '', $paramid = 'id', $gm = 'auto', $moreoptions = array(), $editaction = '')
{
global $conf, $langs;
@ -233,7 +234,10 @@ class Form
if (!empty($conf->global->MAIN_USE_JQUERY_JEDITABLE) && !preg_match('/^select;|day|datepicker|dayhour|datehourpicker/', $typeofdata)) { // TODO add jquery timepicker and support select
$ret .= $this->editInPlace($object, $value, $htmlname, $perm, $typeofdata, $editvalue, $extObject, $custommsg);
} else {
$editmode = (GETPOST('action', 'aZ09') == 'edit'.$htmlname);
if ($editaction == '') {
$editaction = GETPOST('action', 'aZ09');
}
$editmode = ($editaction == 'edit'.$htmlname);
if ($editmode) {
$ret .= "\n";
$ret .= '<form method="post" action="'.$_SERVER["PHP_SELF"].($moreparam ? '?'.$moreparam : '').'">';

View File

@ -316,7 +316,7 @@ class DoliDBSqlite3 extends DoliDB
* @param string $passwd password
* @param string $name name of database (not used for mysql, used for pgsql)
* @param integer $port Port of database server
* @return SQLite3 Database access handler
* @return SQLite3|string Database access handler
* @see close()
*/
public function connect($host, $login, $passwd, $name, $port = 0)

View File

@ -696,11 +696,12 @@ function dolibarr_set_const($db, $name, $value, $type = 'chaine', $visible = 0,
/**
* Prepare array with list of tabs
*
* @param int $nbofactivatedmodules Number if activated modules
* @param int $nboftotalmodules Nb of total modules
* @return array Array of tabs to show
* @param int $nbofactivatedmodules Number if activated modules
* @param int $nboftotalmodules Nb of total modules
* @param int $nbmodulesnotautoenabled Nb of modules not auto enabled that are activated
* @return array Array of tabs to show
*/
function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules)
function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules, $nbmodulesnotautoenabled)
{
global $langs, $conf, $user, $form;
@ -711,7 +712,7 @@ function modules_prepare_head($nbofactivatedmodules, $nboftotalmodules)
$head = array();
$mode = empty($conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT) ? 'commonkanban' : $conf->global->MAIN_MODULE_SETUP_ON_LIST_BY_DEFAULT;
$head[$h][0] = DOL_URL_ROOT."/admin/modules.php?mode=".$mode;
if ($nbofactivatedmodules <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled)
if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled)
//$head[$h][1] = $form->textwithpicto($langs->trans("AvailableModules"), $desc);
$head[$h][1] = $langs->trans("AvailableModules");
$head[$h][1] .= $form->textwithpicto('', $langs->trans("YouMustEnableOneModule").'.<br><br><span class="opacitymedium">'.$desc.'</span>', 1, 'warning');

View File

@ -8959,10 +8959,12 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
// Only global variables can be changed by eval function and returned to caller
global $db, $langs, $user, $conf, $website, $websitepage;
global $action, $mainmenu, $leftmenu;
global $mysoc;
global $objectoffield;
// Old variables used
global $rights;
global $object;
global $mysoc;
global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object
global $soc; // For backward compatibility

View File

@ -52,15 +52,15 @@ function establishment_prepare_head($object)
$head[$h][2] = 'info';
$h++;
$head[$h][0] = dol_buildpath("/hrm/admin/setup.php", 1);
$head[$h][1] = $langs->trans("Settings");
$head[$h][2] = 'settings';
$h++;
// $head[$h][0] = dol_buildpath("/hrm/admin/setup.php", 1);
// $head[$h][1] = $langs->trans("Settings");
// $head[$h][2] = 'settings';
// $h++;
$head[$h][0] = dol_buildpath("/hrm/admin/about.php", 1);
$head[$h][1] = $langs->trans("About");
$head[$h][2] = 'about';
$h++;
// $head[$h][0] = dol_buildpath("/hrm/admin/about.php", 1);
// $head[$h][1] = $langs->trans("About");
// $head[$h][2] = 'about';
// $h++;
complete_head_from_modules($conf, $langs, null, $head, $h, 'hrm');

View File

@ -1,7 +1,8 @@
<?php
/* Module to manage locations, buildings, floors and rooms into Dolibarr ERP/CRM
* Copyright (C) 2013 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2016 Gilles Poirier <glgpoirier@gmail.com>
* Copyright (C) 2013 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2016 Gilles Poirier <gilles.poirier@netlogic.fr>
* Copyright (C) 2023 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
@ -26,7 +27,7 @@
/**
* Prepare head for tabs
*
* @param Object $object Object
* @param Dolresource $object Object
* @return array Array of head entries
*/
function resource_prepare_head($object)
@ -114,7 +115,10 @@ function resource_prepare_head($object)
function resource_admin_prepare_head()
{
global $langs, $conf, $user;
global $conf, $db, $langs, $user;
$extrafields = new ExtraFields($db);
$extrafields->fetch_name_optionals_label('resource');
$h = 0;
$head = array();
@ -132,6 +136,10 @@ function resource_admin_prepare_head()
$head[$h][0] = DOL_URL_ROOT.'/admin/resource_extrafields.php';
$head[$h][1] = $langs->trans("ExtraFields");
$nbExtrafields = $extrafields->attributes['resource']['count'];
if ($nbExtrafields > 0) {
$head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbExtrafields.'</span>';
}
$head[$h][2] = 'attributes';
$h++;

View File

@ -1087,18 +1087,21 @@ function get_left_menu_home($mainmenu, &$newmenu, $usemenuhider = 1, $leftmenu =
$newmenu->add("/admin/index.php?mainmenu=home&amp;leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup', 0, '', '', '', '<i class="fa fa-tools fa-fw paddingright pictofixedwidth"></i>');
if ($usemenuhider || empty($leftmenu) || $leftmenu == "setup") {
$nbmodulesnotautoenabled = count($conf->modules);
if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--;
// Load translation files required by the page
$langs->loadLangs(array("admin", "help"));
$warnpicto = '';
if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) {
$langs->load("errors");
$warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete"));
}
$newmenu->add("/admin/company.php?mainmenu=home", $langs->trans("MenuCompanySetup").$warnpicto, 1);
$warnpicto = '';
if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled
if ($nbmodulesnotautoenabled <= getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only user module enabled
$langs->load("errors");
$warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete"));
}

View File

@ -365,12 +365,16 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
*/
public $phpmin;
public $phpmax;
/**
* @var array Minimum version of Dolibarr required by module.
* e.g.: Dolibarr 3.6 = array(3, 6)
*/
public $need_dolibarr_version;
public $enabled_bydefault;
/**
* @var bool Whether to hide the module.
*/

View File

@ -336,15 +336,19 @@ class doc_generic_invoice_odt extends ModelePDFFactures
$object->fetchObjectLinked('', '', '', '');
//print_r($object->linkedObjects['propal']); exit;
$propal_object = $object->linkedObjects['propal'][0];
if (isset($object->linkedObjects['propal'][0])) {
$propal_object = $object->linkedObjects['propal'][0];
} else {
$propal_object = null;
}
// Make substitution
$substitutionarray = array(
'__FROM_NAME__' => $this->emetteur->name,
'__FROM_EMAIL__' => $this->emetteur->email,
'__TOTAL_TTC__' => $object->total_ttc,
'__TOTAL_HT__' => $object->total_ht,
'__TOTAL_VAT__' => $object->total_tva
'__FROM_NAME__' => $this->emetteur->name,
'__FROM_EMAIL__' => $this->emetteur->email,
'__TOTAL_TTC__' => $object->total_ttc,
'__TOTAL_HT__' => $object->total_ht,
'__TOTAL_VAT__' => $object->total_tva
);
complete_substitutions_array($substitutionarray, $langs, $object);
// Call the ODTSubstitution hook
@ -435,8 +439,8 @@ class doc_generic_invoice_odt extends ModelePDFFactures
} else {
$odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
}
} else // Text
{
} else {
// Text
$odfHandler->setVars($key, $value, true, 'UTF-8');
}
} catch (OdfException $e) {

View File

@ -63,7 +63,7 @@ class modFckeditor extends DolibarrModules
$this->config_page_url = array("fckeditor.php");
// Dependencies
$this->disabled = in_array(constant('JS_CKEDITOR'), array('disabled', 'disabled/'));
$this->disabled = (defined('JS_CKEDITOR') && in_array(constant('JS_CKEDITOR'), array('disabled', 'disabled/')));
$this->depends = array();
$this->requiredby = array('modWebsites');
$this->enabled_bydefault = true; // Will be enabled during install

View File

@ -295,7 +295,7 @@ class Donations extends DolibarrApi
* @throws RestException 404
* @throws RestException 500 System error
*
* @return array
* @return object
*/
public function validate($id, $idwarehouse = 0, $notrigger = 0)
{

View File

@ -633,7 +633,7 @@ class EcmDirectory extends CommonObject
* level Level of line (Added by buildPathFromId call)
*
* @param int $force Force reload of full arbo even if already loaded in cache $this->cats
* @return array Tableau de array
* @return array|int Tableau de array if OK, -1 if KO
*/
public function get_full_arbo($force = 0)
{

View File

@ -502,7 +502,7 @@ class Shipments extends DolibarrApi
*
* @url POST {id}/validate
*
* @return array
* @return object
* \todo An error 403 is returned if the request has an empty body.
* Error message: "Forbidden: Content type `text/plain` is not supported."
* Workaround: send this in the body
@ -630,7 +630,7 @@ class Shipments extends DolibarrApi
*
* @url POST {id}/close
*
* @return int
* @return object
*/
public function close($id, $notrigger = 0)
{

View File

@ -2763,6 +2763,11 @@ class ExpenseReportLine extends CommonObjectLine
*/
public $db;
/**
* @var string Name of table without prefix where object is stored
*/
public $table_element = 'expensereport_det';
/**
* @var string Error code (or message)
*/

View File

@ -336,9 +336,10 @@ class Interventions extends DolibarrApi
*
* @param int $id Intervention ID
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
* @return Object Object with cleaned properties
*
* @url POST {id}/validate
*
* @return Object
*/
public function validate($id, $notrigger = 0)
{
@ -371,9 +372,10 @@ class Interventions extends DolibarrApi
* Close an intervention
*
* @param int $id Intervention ID
* @return Object Object with cleaned properties
*
* @url POST {id}/close
*
* @return Object
*/
public function closeFichinter($id)
{

View File

@ -206,7 +206,7 @@ include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
// when we post forms (we allow GET and HEAD to accept direct link from a particular page).
// Note about $_SERVER[HTTP_HOST/SERVER_NAME]: http://shiflett.org/blog/2006/mar/server-name-versus-http-host
// See also CSRF protections done into main.inc.php
if (!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck)) {
if (!defined('NOCSRFCHECK') && isset($dolibarr_nocsrfcheck) && $dolibarr_nocsrfcheck == 1) { // If $dolibarr_nocsrfcheck is 0, there is a strict CSRF test with token in main
if (!empty($_SERVER['REQUEST_METHOD']) && !in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) && !empty($_SERVER['HTTP_HOST'])) {
$csrfattack = false;
if (empty($_SERVER['HTTP_REFERER'])) {

View File

@ -673,7 +673,7 @@ class ProductFournisseur extends Product
* @param int $limit Limit
* @param int $offset Offset
* @param int $socid Filter on a third party id
* @return array Array of ProductFournisseur with new properties to define supplier price
* @return array|int Array of ProductFournisseur with new properties to define supplier price
*/
public function list_product_fournisseur_price($prodid, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0, $socid = 0)
{
@ -1042,7 +1042,7 @@ class ProductFournisseur extends Product
* @param string $sortorder Sort order
* @param int $limit Limit
* @param int $offset Offset
* @return array Array of Log prices
* @return array|int Array of Log prices
*/
public function listProductFournisseurPriceLog($product_fourn_price_id, $sortfield = '', $sortorder = '', $limit = 0, $offset = 0)
{

View File

@ -138,7 +138,7 @@ if ($object->id > 0) {
// Object card
// ------------------------------------------------------------
$linkback = '<a href="'.DOL_URL_ROOT.'/hrm/hrm/myobject_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$linkback = '<a href="'.DOL_URL_ROOT.'/hrm/admin/admin_establishment.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
/*

View File

@ -42,12 +42,17 @@ $hookmanager->initHooks(array('index'));
* Actions
*/
$nbmodulesnotautoenabled = count($conf->modules);
if (in_array('fckeditor', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('export', $conf->modules)) $nbmodulesnotautoenabled--;
if (in_array('import', $conf->modules)) $nbmodulesnotautoenabled--;
// Check if company name is defined (first install)
if (!isset($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_NOM)) {
header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete");
exit;
}
if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only user module enabled
if ($nbmodulesnotautoenabled <= getDolGlobalString('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only user module enabled
header("Location: ".DOL_URL_ROOT."/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete");
exit;
}

View File

@ -33,6 +33,11 @@
--
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_NOW', 'Immediate', null, 0, 1, 10);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_1D', '1 day', 'd', 1, 1, 11);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_2D', '2 days', 'd', 2, 1, 12);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_3D', '3 days', 'd', 3, 1, 13);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_4D', '4 days', 'd', 4, 1, 14);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_5D', '5 days', 'd', 5, 1, 15);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_1W', '1 week', 'w', 1, 1, 20);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_2W', '2 weeks', 'w', 2, 1, 30);
INSERT INTO llx_c_availability (code, label, type_duration, qty, active, position) VALUES ('AV_3W', '3 weeks', 'w', 3, 1, 40);

View File

@ -29,6 +29,7 @@
* For installation:
* It creates the login admin and set the MAIN_SECURITY_SALT to a random value.
* It set the value for MAIN_VERSION_LAST_INSTALL
* It activates some modules
* It creates the install.lock and shows the final message.
* For upgrade:
* It updates the value for MAIN_VERSION_LAST_UPGRADE.
@ -42,6 +43,7 @@ if (file_exists($conffile)) {
}
require_once $dolibarr_main_document_root.'/core/lib/admin.lib.php';
require_once $dolibarr_main_document_root.'/core/lib/security.lib.php'; // for dol_hash
require_once $dolibarr_main_document_root.'/core/lib/functions2.lib.php';
global $langs;
@ -287,6 +289,9 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i', $action)) {
*/
}
// List of modules to enable
$tmparray = array();
// If we ask to force some modules to be enabled
if (!empty($force_install_module)) {
if (!defined('DOL_DOCUMENT_ROOT') && !empty($dolibarr_main_document_root)) {
@ -294,9 +299,53 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i', $action)) {
}
$tmparray = explode(',', $force_install_module);
}
$modNameLoaded = array();
// Search modules dirs
$modulesdir[] = $dolibarr_main_document_root.'/core/modules/';
foreach ($modulesdir as $dir) {
// Load modules attributes in arrays (name, numero, orders) from dir directory
//print $dir."\n<br>";
dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)");
$handle = @opendir($dir);
if (is_resource($handle)) {
while (($file = readdir($handle)) !== false) {
if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') {
$modName = substr($file, 0, dol_strlen($file) - 10);
if ($modName) {
if (!empty($modNameLoaded[$modName])) { // In cache of already loaded modules ?
$mesg = "Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.<br>";
setEventMessages($mesg, null, 'warnings');
dol_syslog($mesg, LOG_ERR);
continue;
}
try {
$res = include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error.
if (class_exists($modName)) {
$objMod = new $modName($db);
$modNameLoaded[$modName] = $dir;
if (!empty($objMod->enabled_bydefault) && !in_array($file, $tmparray)) {
$tmparray[] = $file;
}
}
} catch (Exception $e) {
dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
}
}
}
}
}
}
// Loop on each modules to activate it
if (!empty($tmparray)) {
foreach ($tmparray as $modtoactivate) {
$modtoactivatenew = preg_replace('/\.class\.php$/i', '', $modtoactivate);
print $langs->trans("ActivateModule", $modtoactivatenew).'<br>';
//print $langs->trans("ActivateModule", $modtoactivatenew).'<br>';
$file = $modtoactivatenew.'.class.php';
dolibarr_install_syslog('step5: activate module file='.$file);
@ -307,8 +356,10 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i', $action)) {
print 'ERROR: failed to activateModule() file='.$file;
}
}
//print '<br>';
}
// Now delete the flag to say install is complete
dolibarr_install_syslog('step5: remove MAIN_NOT_INSTALLED const');
$resql = $db->query("DELETE FROM ".MAIN_DB_PREFIX."const WHERE ".$db->decrypt('name')." = 'MAIN_NOT_INSTALLED'");
if (!$resql) {

View File

@ -1234,7 +1234,7 @@ SetupDescription4=<a href="%s">%s -> %s</a><br><br>This software is a suite of m
SetupDescription5=Other Setup menu entries manage optional parameters.
SetupDescriptionLink=<a href="%s">%s - %s</a>
SetupDescription3b=Basic parameters used to customize the default behavior of your application (e.g for country-related features).
SetupDescription4b=This software is a suite of many modules/applications. The modules related to your needs must be enabled and configured. Menu entries will appears with the activation of these modules.
SetupDescription4b=This software is a suite of many modules/applications. The modules related to your needs must be activated. Menu entries will appears with the activation of these modules.
AuditedSecurityEvents=Security events that are audited
NoSecurityEventsAreAduited=No security events are audited. You can enable them from menu %s
Audit=Security events

View File

@ -1223,5 +1223,5 @@ AddToContacts=Add address to my contacts
LastAccess=Last access
UploadAnImageToSeeAPhotoHere=Upload an image from the tab %s to see a photo here
LastPasswordChangeDate=Last password change date
PublicVirtualCardUrl=Public virtual user card
PublicVirtualCardUrl=Virtual business card page
TreeView=Tree view

View File

@ -169,4 +169,7 @@ GeneratePermissions=I want to add the rights for this object
GeneratePermissionsHelp=generate default rights for this object
PermissionDeletedSuccesfuly=Permission has been successfully removed
PermissionUpdatedSuccesfuly=Permission has been successfully updated
PermissionAddedSuccesfuly=Permission has been successfully added
PermissionAddedSuccesfuly=Permission has been successfully added
MenuDeletedSuccessfuly=Menu has been successfully deleted
MenuAddedSuccessfuly=Menu has been successfully added
MenuUpdatedSuccessfuly=Menu has been successfully updated

View File

@ -169,4 +169,7 @@ GeneratePermissions=Je souhaite ajouter les droits pour cet objet
GeneratePermissionsHelp=générer les droits par défault pour cet objet
PermissionDeletedSuccesfuly=La permission a été supprimée avec succès
PermissionUpdatedSuccesfuly=La permission a été mise à jour avec succès
PermissionAddedSuccesfuly= La permission a été ajoutée avec succès
PermissionAddedSuccesfuly= La permission a été ajoutée avec succès
MenuDeletedSuccessfuly=Menu a été supprimé avec succès
MenuAddedSuccessfuly=Menu a été ajouté avec succès
MenuUpdatedSuccessfuly=Menu a été mise à jour avec succès

View File

@ -896,6 +896,17 @@ if ($dirins && $action == 'confirm_removefile' && !empty($module)) {
// Init an object
if ($dirins && $action == 'initobject' && $module && $objectname) {
// check if module is enabled
if (isModEnabled(strtolower($module))) {
$result = unActivateModule(strtolower($module));
dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
if ($result) {
setEventMessages($result, null, 'errors');
}
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings');
}
$objectname = ucfirst($objectname);
$dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath'];
@ -1341,43 +1352,31 @@ if ($dirins && $action == 'initobject' && $module && $objectname) {
// Regenerate left menu entry in descriptor for $objectname
$stringtoadd = "
\$this->menu[\$r++]=array(
// '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'fk_menu'=>'fk_mainmenu=mymodule',
// This is a Left menu entry
'type'=>'left',
'titre'=>'List MyObject',
'mainmenu'=>'mymodule',
'leftmenu'=>'mymodule_myobject',
'url'=>'/mymodule/myobject_list.php',
// Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'langs'=>'mymodule@mymodule',
'position'=>1100+\$r,
// Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected.
'enabled'=>'\$conf->mymodule->enabled',
// Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
'perms'=>'1',
'target'=>'',
// 0=Menu for internal users, 1=external users, 2=both
'user'=>2,
);
\$this->menu[\$r++]=array(
// '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=mymodule_myobject',
// This is a Left menu entry
'type'=>'left',
'titre'=>'New MyObject',
'mainmenu'=>'mymodule',
'leftmenu'=>'mymodule_myobject',
'url'=>'/mymodule/myobject_card.php?action=create',
// Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'langs'=>'mymodule@mymodule',
'position'=>1100+\$r,
// Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected.
'enabled'=>'\$conf->mymodule->enabled',
// Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules
'perms'=>'1',
'target'=>'',
// 0=Menu for internal users, 1=external users, 2=both
'user'=>2
);\n";
$stringtoadd = preg_replace('/MyObject/', $objectname, $stringtoadd);
@ -1389,8 +1388,28 @@ if ($dirins && $action == 'initobject' && $module && $objectname) {
// TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1
// TODO Avoid duplicate addition
dolReplaceInFile($moduledescriptorfile, array('END MODULEBUILDER LEFTMENU MYOBJECT */' => '*/'."\n".$stringtoadd."\n\t\t/* END MODULEBUILDER LEFTMENU MYOBJECT */"));
// load class and check if menu exist with same object name
$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
dol_include_once($pathtofile);
$class = 'mod'.$module;
if (class_exists($class)) {
try {
$moduleobj = new $class($db);
} catch (Exception $e) {
$error++;
dol_print_error($db, $e->getMessage());
}
}
$menus = $moduleobj->menu;
$counter = 0 ;
foreach ($menus as $menu) {
if ($menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) {
$counter++;
}
}
if (!$counter) {
dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER LEFTMENU MYOBJECT */' => '/*LEFTMENU '.strtoupper($objectname).'*/'.$stringtoadd."\n\t\t".'/*END LEFTMENU '.strtoupper($objectname).'*/'."\n\t\t".'/* END MODULEBUILDER LEFTMENU MYOBJECT */'));
}
// Add module descriptor to list of files to replace "MyObject' string with real name of object.
$filetogenerate[] = 'core/modules/mod'.$module.'.class.php';
}
@ -1728,6 +1747,16 @@ if ($dirins && $action == 'confirm_deletemodule') {
}
if ($dirins && $action == 'confirm_deleteobject' && $objectname) {
// check if module is enabled (if it's disabled and send msg event)
if (isModEnabled(strtolower($module))) {
$result = unActivateModule(strtolower($module));
dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
if ($result) {
setEventMessages($result, null, 'errors');
}
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings');
}
if (preg_match('/[^a-z0-9_]/i', $objectname)) {
$error++;
setEventMessages($langs->trans("SpaceOrSpecialCharAreNotAllowed"), null, 'errors');
@ -1766,53 +1795,43 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) {
);
//menu for the object selected
$stringtoedit = "\$this->menu[\$r++]=array(
// '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'fk_menu'=>'fk_mainmenu=".strtolower($module)."',
// This is a Left menu entry
'type'=>'left',
'titre'=>'List ".ucfirst($objectname)."',
'mainmenu'=>'".strtolower($module)."',
'leftmenu'=>'".strtolower($module)."_".strtolower($objectname)."',
'url'=>'/".strtolower($module)."/".strtolower($objectname)."_list.php',
// Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'langs'=>'".strtolower($module)."@".strtolower($module)."',
'position'=>1100+\$r,
// Define condition to show or hide menu entry. Use '\$conf->".strtolower($module)."->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected.
'enabled'=>'\$conf->".strtolower($module)."->enabled',
// Use 'perms'=>'\$user->rights->".strtolower($module)."->level1->level2' if you want your menu with a permission rules
'perms'=>'1',
'target'=>'',
// 0=Menu for internal users, 1=external users, 2=both
'user'=>2,
);
\$this->menu[\$r++]=array(
// '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'fk_menu'=>'fk_mainmenu=".strtolower($module).",fk_leftmenu=".strtolower($module)."_".strtolower($objectname)."',
// This is a Left menu entry
'type'=>'left',
'titre'=>'New ".ucfirst($objectname)."',
'mainmenu'=>'".strtolower($module)."',
'leftmenu'=>'".strtolower($module)."_".strtolower($objectname)."',
'url'=>'/".strtolower($module)."/".strtolower($objectname)."_card.php?action=create',
// Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'langs'=>'".strtolower($module)."@".strtolower($module)."',
'position'=>1100+\$r,
// Define condition to show or hide menu entry. Use '\$conf->".strtolower($module)."->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected.
'enabled'=>'\$conf->".strtolower($module)."->enabled',
// Use 'perms'=>'\$user->rights->".strtolower($module)."->level1->level2' if you want your menu with a permission rules
'perms'=>'1',
'target'=>'',
// 0=Menu for internal users, 1=external users, 2=both
'user'=>2
);";
// load class and check if menu exist for this object
$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
dol_include_once($pathtofile);
$class = 'mod'.$module;
if (class_exists($class)) {
try {
$moduleobj = new $class($db);
} catch (Exception $e) {
$error++;
dol_print_error($db, $e->getMessage());
}
}
$menus = $moduleobj->menu;
$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
$check = dolReplaceInFile($moduledescriptorfile, array($stringtoedit => ''));
if ($check > 0) {
dolReplaceInFile($moduledescriptorfile, array('/*'.strtoupper($objectname).'*/' => ''));
foreach ($menus as $menu) {
if ($menu['type'] == 'left' && $menu['leftmenu'] == strtolower($module).'_'.strtolower($objectname)) {
$left="\$this->menu[\$r++]=array(
'fk_menu'=>'".$menu['fk_menu']."',
'type'=>'".$menu['type']."',
'titre'=>'".$menu['titre']."',
'mainmenu'=>'".$menu['mainmenu']."',
'leftmenu'=>'".$menu['leftmenu']."',
'url'=>'".$menu['url']."',
'langs'=>'".$menu['langs']."',
'position'=>1100+\$r,
'enabled'=>'".$menu['enabled']."',
'perms'=>'".$menu['perms']."',
'target'=>'".$menu['target']."',
'user'=>".$menu['user'].",
);";
dolReplaceInFile($moduledescriptorfile, array($left => ''));
}
}
// Remarque : "\n" not handling yet
$check = dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($objectname).'*/'."\n" => '',"\t\t".'/*END LEFTMENU '.strtoupper($objectname).'*/'."\n" => ''));
// regenerate permissions and delete them
$rights = "
@ -1994,8 +2013,9 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) {
$existRight = 0;
$allObject = array();
$nbOfPermissions = count($permissions);
for ($i =0; $i<$nbOfPermissions; $i++) {
$countPerms = count($permissions);
for ($i =0; $i<$countPerms; $i++) {
if ($permissions[$i][4] == $objectForPerms) {
$counter++;
if (count($permsForObject) < 3) {
@ -2004,9 +2024,10 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) {
}
$allObject[] = $permissions[$i][4];
}
$nbOfpermsInObj = count($permsForObject);
// check if label of object already exists
for ($j = 0; $j<$nbOfpermsInObj; $j++) {
$countPermsObj = count($permsForObject);
for ($j = 0; $j<$countPermsObj; $j++) {
if (in_array($label, $permsForObject[$j])) {
$existRight++;
setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($label), $langs->transnoentities($objectForPerms)), null, 'errors');
@ -2037,6 +2058,7 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) {
";
$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
if (!$existRight) {
//var_dump(1);exit;
dolReplaceInFile($moduledescriptorfile, array('/*END '.strtoupper($objectForPerms).'*/' => $rightToAdd.'/*END '.strtoupper($objectForPerms).'*/'));
setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null);
}
@ -2099,13 +2121,18 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e
$x1 = $permissions[$r-1][1];
$x2 = $permissions[$r-1][4];
$x3 = $permissions[$r-1][5];
//check existing object permission
$permsForObject =array();
//check existing object permission
$counter = 0;
$permsForObject =array();
$permissions = $moduleobj->rights;
$firstRight = 0;
$existRight = 0;
$allObject = array();
$allObject = array();
$nbOfPermissions = count($permissions);
for ($i =0; $i<$nbOfPermissions; $i++) {
$countPerms = count($permissions);
for ($i =0; $i<$countPerms; $i++) {
if ($permissions[$i][4] == $objectForPerms) {
$counter++;
if (count($permsForObject) < 3) {
$permsForObject[] = $permissions[$i];
}
@ -2114,8 +2141,8 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e
}
if ($label != $x1 && $crud != $x3) {
$x = count($permsForObject);
for ($j = 0; $j<$x; $j++) {
$countPermsObj = count($permsForObject);
for ($j = 0; $j<$countPermsObj; $j++) {
if (in_array($label, $permsForObject[$j])) {
$error++;
setEventMessages($langs->trans("ErrorExistingPermission", $langs->transnoentities($label), $langs->transnoentities($objectForPerms)), null, 'errors');
@ -2158,6 +2185,70 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e
exit;
}
}
// Delete permission
if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOST('permskey', 'int')) {
$error = 0;
// load class and check if right exist
$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
dol_include_once($pathtofile);
$class = 'mod'.$module;
if (class_exists($class)) {
try {
$moduleobj = new $class($db);
} catch (Exception $e) {
$error++;
dol_print_error($db, $e->getMessage());
}
}
$permissions = $moduleobj->rights;
$key = (int) GETPOST('permskey', 'int')-1;
//get permission want to delete from permissions array
$x1 = $permissions[$key][1];
$x2 = $permissions[$key][4];
$x3 = $permissions[$key][5];
//prepare right want to delete
$rightTodelete = "
\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1);
\$this->rights[\$r][1] = '$x1';
\$this->rights[\$r][4] = '$x2';
\$this->rights[\$r][5] = '$x3';
\$r++;
";
$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
$check = dolReplaceInFile($moduledescriptorfile, array($rightTodelete => ''."\n\t\t"));
if ($check > 0) {
//check if all permissions of object was deleted
$permsForObj = array();
foreach ($permissions as $perms) {
$permsForObj[] = $perms[4];
}
$permsForObj = array_count_values($permsForObj);
if ($permsForObj[$permissions[$key][4]] == 1) {
$delObjStart = dolReplaceInFile($moduledescriptorfile, array('/*'.strtoupper($permissions[$key][4].'*/') => '','/*END '.strtoupper($permissions[$key][4].'*/') => ''));
}
}
if (!$error) {
// check if module is enabled
if (isModEnabled(strtolower($module))) {
$result = unActivateModule(strtolower($module));
dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
if ($result) {
setEventMessages($result, null, 'errors');
}
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null);
setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings');
exit;
} else {
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null);
exit;
}
}
}
// Save file
if ($action == 'savefile' && empty($cancel)) {
$relofcustom = basename($dirins);
@ -2269,6 +2360,91 @@ if ($action == 'reset' && $user->admin) {
exit;
}
// delete menu
if ($dirins && $action == 'confirm_deletemenu' && GETPOST('menukey', 'int')) {
// check if module is enabled
if (isModEnabled(strtolower($module))) {
$result = unActivateModule(strtolower($module));
dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity);
if ($result) {
setEventMessages($result, null, 'errors');
}
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module);
setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings');
}
// load class and check if menu exist
$pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath'];
dol_include_once($pathtofile);
$class = 'mod'.$module;
if (class_exists($class)) {
try {
$moduleobj = new $class($db);
} catch (Exception $e) {
$error++;
dol_print_error($db, $e->getMessage());
}
}
$menus = $moduleobj->menu;
$key = (int) GETPOST('menukey', 'int');
$moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php';
if ($menus[$key]['type'] == 'top') {
$menuTop = "
\$this->menu[\$r++] = array(
'fk_menu'=>'".$menus[$key]['fk_menu']."',
'type'=>'".$menus[$key]['type']."',
'titre'=>'".$menus[$key]['titre']."',
'prefix' => img_picto('', \$this->picto, 'class=\"paddingright pictofixedwidth valignmiddle\"'),
'mainmenu'=>'".$menus[$key]['mainmenu']."',
'leftmenu'=> '',
'url'=>'".$menus[$key]['url']."',
'langs'=>'".$menus[$key]['langs']."',
'position'=>1000 + \$r,
'enabled'=>'isModEnabled(\"".strtolower($module)."\")',
'perms' =>'".$menus[$key]['perms']."',
'target'=>'".$menus[$key]['target']."',
'user'=>".$menus[$key]['user'].",
);";
$check = dolReplaceInFile($moduledescriptorfile, array($menuTop => '',"\t\t".'/*TOPMENU '.strtolower($menus[$key]['titre']).'*/'."\n" => '', '/*END TOPMENU '.strtolower($menus[$key]['titre']).'*/'."\n\t\t" => ''));
}
if ($menus[$key]['type'] == 'left') {
$left="\$this->menu[\$r++]=array(
'fk_menu'=>'".$menus[$key]['fk_menu']."',
'type'=>'".$menus[$key]['type']."',
'titre'=>'".$menus[$key]['titre']."',
'mainmenu'=>'".$menus[$key]['mainmenu']."',
'leftmenu'=>'".$menus[$key]['leftmenu']."',
'url'=>'".$menus[$key]['url']."',
'langs'=>'".$menus[$key]['langs']."',
'position'=>1100+\$r,
'enabled'=>'".$menus[$key]['enabled']."',
'perms'=>'".$menus[$key]['perms']."',
'target'=>'".$menus[$key]['target']."',
'user'=>".$menus[$key]['user'].",
);";
$check = dolReplaceInFile($moduledescriptorfile, array($left => ''));
// check if still had menu created when initial object
// if not we delete the comments from file
$menuForObj = 0;
foreach ($menus as $menu) {
if ($menu['leftmenu'] == $menus[$key]['leftmenu']) {
$menuForObj++;
}
}
if ($menuForObj == 1) {
$extractObjName = explode("_", $menus[$key]['leftmenu']);
dolReplaceInFile($moduledescriptorfile, array('/*LEFTMENU '.strtoupper($extractObjName[1]).'*/'."\n" => '','/*END LEFTMENU '.strtoupper($extractObjName[1]).'*/' => ''));
}
}
setEventMessages($langs->trans('MenuDeletedSuccessfuly'), null);
header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=menus&module='.$module);
exit;
}
/*

View File

@ -1854,7 +1854,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if ($object->isService()) {
$type = $langs->trans('Service');
}
//print load_fiche_titre($langs->trans('Modify').' '.$type.' : '.(is_object($object->oldcopy)?$object->oldcopy->ref:$object->ref), "");
// print load_fiche_titre($langs->trans('Modify').' '.$type.' : '.(is_object($object->oldcopy)?$object->oldcopy->ref:$object->ref), "");
// Main official, simple, and not duplicated code
print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST" name="formprod">'."\n";
@ -1873,19 +1873,18 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Ref
if (empty($conf->global->MAIN_PRODUCT_REF_NOT_EDITABLE)) {
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag($object->ref).'"></td></tr>';
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag(GETPOSTISSET('ref') ? GETPOST('ref') : $object->ref).'"></td></tr>';
} else {
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Ref").'</td><td colspan="3"><input name="ref" class="maxwidth200" maxlength="128" value="'.dol_escape_htmltag($object->ref).'" readonly="true"></td></tr>';
}
// Label
print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="3"><input name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.dol_escape_htmltag($object->label).'"></td></tr>';
print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td colspan="3"><input name="label" class="minwidth300 maxwidth400onsmartphone" maxlength="255" value="'.dol_escape_htmltag(GETPOSTISSET('label') ? GETPOST('label') : $object->label).'"></td></tr>';
// Status To sell
print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Sell").')</td><td colspan="3">';
print '<select class="flat" name="statut">';
if ($object->status) {
if ((GETPOSTISSET('statut') && GETPOST('statut')) || (!GETPOSTISSET('statut') && $object->status)) {
print '<option value="1" selected>'.$langs->trans("OnSell").'</option>';
print '<option value="0">'.$langs->trans("NotOnSell").'</option>';
} else {
@ -1898,7 +1897,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Status To Buy
print '<tr><td class="fieldrequired">'.$langs->trans("Status").' ('.$langs->trans("Buy").')</td><td colspan="3">';
print '<select class="flat" name="statut_buy">';
if ($object->status_buy) {
if ((GETPOSTISSET('statut_buy') && GETPOST('statut_buy')) || (!GETPOSTISSET('statut_buy') && $object->status_buy)) {
print '<option value="1" selected>'.$langs->trans("ProductStatusOnBuy").'</option>';
print '<option value="0">'.$langs->trans("ProductStatusNotOnBuy").'</option>';
} else {
@ -1913,7 +1912,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if ($object->isProduct() || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
print '<tr><td>'.$langs->trans("ManageLotSerial").'</td><td>';
$statutarray = array('0' => $langs->trans("ProductStatusNotOnBatch"), '1' => $langs->trans("ProductStatusOnBatch"), '2' => $langs->trans("ProductStatusOnSerial"));
print $form->selectarray('status_batch', $statutarray, $object->status_batch);
print $form->selectarray('status_batch', $statutarray, (GETPOSTISSET('status_batch') ? GETPOST('status_batch') : $object->status_batch));
print '</td></tr>';
if (!empty($object->status_batch) || !empty($conf->use_javascript_ajax)) {
$langs->load("admin");
@ -2032,7 +2031,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Default warehouse
print '<tr><td>'.$langs->trans("DefaultWarehouse").'</td><td>';
print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"');
print $formproduct->selectWarehouses($object->fk_default_warehouse, 'fk_default_warehouse', 'warehouseopen', 1);
print $formproduct->selectWarehouses((GETPOSTISSET('fk_default_warehouse') ? GETPOST('fk_default_warehouse') : $object->fk_default_warehouse), 'fk_default_warehouse', 'warehouseopen', 1);
print ' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create&amp;backtopage='.urlencode($_SERVER['PHP_SELF'].'?action=create&type='.GETPOST('type', 'int')).'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddWarehouse").'"></span></a>';
print '</td></tr>';
/*
@ -2080,7 +2079,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if (empty($conf->global->PRODUCT_DISABLE_NATURE)) {
// Nature
print '<tr><td>'.$form->textwithpicto($langs->trans("NatureOfProductShort"), $langs->trans("NatureOfProductDesc")).'</td><td>';
print $formproduct->selectProductNature('finished', $object->finished);
print $formproduct->selectProductNature('finished', (GETPOSTISSET('finished') ? GETPOST('finished') : $object->finished));
print '</td></tr>';
}
}
@ -2088,7 +2087,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
if (!$object->isService() && isModEnabled('bom')) {
print '<tr><td>'.$form->textwithpicto($langs->trans("DefaultBOM"), $langs->trans("DefaultBOMDesc", $langs->transnoentitiesnoconv("Finished"))).'</td><td>';
$bomkey = "Bom:bom/class/bom.class.php:0:t.status=1 AND t.fk_product=".((int) $object->id);
print $form->selectForForms($bomkey, 'fk_default_bom', $object->fk_default_bom, 1);
print $form->selectForForms($bomkey, 'fk_default_bom', (GETPOSTISSET('fk_default_bom') ? GETPOST('fk_default_bom') : $object->fk_default_bom), 1);
print '</td></tr>';
}
@ -2143,7 +2142,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Custom code
if (!$object->isService() && empty($conf->global->PRODUCT_DISABLE_CUSTOM_INFO)) {
print '<tr><td class="wordbreak">'.$langs->trans("CustomCode").'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.$object->customcode.'"></td></tr>';
print '<tr><td class="wordbreak">'.$langs->trans("CustomCode").'</td><td><input name="customcode" class="maxwidth100onsmartphone" value="'.(GETPOSTISSET('customcode') ? GETPOST('customcode') : $object->customcode).'"></td></tr>';
// Origin country
print '<tr><td>'.$langs->trans("CountryOrigin").'</td>';
print '<td>';
@ -2196,6 +2195,11 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
$arrayselected[] = $cat->id;
}
}
if (GETPOSTISSET('categories', 'array')) {
foreach (GETPOST('categories', 'array') as $cat) {
$arrayselected[] = $cat;
}
}
print img_picto('', 'category').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
print "</td></tr>";
}
@ -2221,76 +2225,76 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
// Accountancy_code_sell
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellCode").'</td>';
print '<td>';
print $formaccounting->select_account($object->accountancy_code_sell, 'accountancy_code_sell', 1, '', 1, 1, 'minwidth150 maxwidth300');
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_sell') ? GETPOST('accountancy_code_sell') : $object->accountancy_code_sell), 'accountancy_code_sell', 1, '', 1, 1, 'minwidth150 maxwidth300');
print '</td></tr>';
// Accountancy_code_sell_intra
if ($mysoc->isInEEC()) {
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellIntraCode").'</td>';
print '<td>';
print $formaccounting->select_account($object->accountancy_code_sell_intra, 'accountancy_code_sell_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_sell_intra') ? GETPOST('accountancy_code_sell_intra') : $object->accountancy_code_sell_intra), 'accountancy_code_sell_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
print '</td></tr>';
}
// Accountancy_code_sell_export
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellExportCode").'</td>';
print '<td>';
print $formaccounting->select_account($object->accountancy_code_sell_export, 'accountancy_code_sell_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_sell_export') ? GETPOST('accountancy_code_sell_export') : $object->accountancy_code_sell_export), 'accountancy_code_sell_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
print '</td></tr>';
// Accountancy_code_buy
print '<tr><td>'.$langs->trans("ProductAccountancyBuyCode").'</td>';
print '<td>';
print $formaccounting->select_account($object->accountancy_code_buy, 'accountancy_code_buy', 1, '', 1, 1, 'minwidth150 maxwidth300');
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_buy') ? GETPOST('accountancy_code_buy') : $object->accountancy_code_buy), 'accountancy_code_buy', 1, '', 1, 1, 'minwidth150 maxwidth300');
print '</td></tr>';
// Accountancy_code_buy_intra
if ($mysoc->isInEEC()) {
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyIntraCode").'</td>';
print '<td>';
print $formaccounting->select_account($object->accountancy_code_buy_intra, 'accountancy_code_buy_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_buy_intra') ? GETPOST('accountancy_code_buy_intra') : $object->accountancy_code_buy_intra), 'accountancy_code_buy_intra', 1, '', 1, 1, 'minwidth150 maxwidth300');
print '</td></tr>';
}
// Accountancy_code_buy_export
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyExportCode").'</td>';
print '<td>';
print $formaccounting->select_account($object->accountancy_code_buy_export, 'accountancy_code_buy_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
print $formaccounting->select_account((GETPOSTISSET('accountancy_code_buy_export') ? GETPOST('accountancy_code_buy_export') : $object->accountancy_code_buy_export), 'accountancy_code_buy_export', 1, '', 1, 1, 'minwidth150 maxwidth300');
print '</td></tr>';
} else {
// For external software
// Accountancy_code_sell
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellCode").'</td>';
print '<td><input name="accountancy_code_sell" class="maxwidth200" value="'.$object->accountancy_code_sell.'">';
print '<td><input name="accountancy_code_sell" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_sell') ? GETPOST('accountancy_code_sell') : $object->accountancy_code_sell).'">';
print '</td></tr>';
// Accountancy_code_sell_intra
if ($mysoc->isInEEC()) {
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellIntraCode").'</td>';
print '<td><input name="accountancy_code_sell_intra" class="maxwidth200" value="'.$object->accountancy_code_sell_intra.'">';
print '<td><input name="accountancy_code_sell_intra" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_sell_intra') ? GETPOST('accountancy_code_sell_intra') : $object->accountancy_code_sell_intra).'">';
print '</td></tr>';
}
// Accountancy_code_sell_export
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancySellExportCode").'</td>';
print '<td><input name="accountancy_code_sell_export" class="maxwidth200" value="'.$object->accountancy_code_sell_export.'">';
print '<td><input name="accountancy_code_sell_export" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_sell_export') ? GETPOST('accountancy_code_sell_export') : $object->accountancy_code_sell_export).'">';
print '</td></tr>';
// Accountancy_code_buy
print '<tr><td>'.$langs->trans("ProductAccountancyBuyCode").'</td>';
print '<td><input name="accountancy_code_buy" class="maxwidth200" value="'.$object->accountancy_code_buy.'">';
print '<td><input name="accountancy_code_buy" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_buy') ? GETPOST('accountancy_code_buy') : $object->accountancy_code_buy).'">';
print '</td></tr>';
// Accountancy_code_buy_intra
if ($mysoc->isInEEC()) {
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyIntraCode").'</td>';
print '<td><input name="accountancy_code_buy_intra" class="maxwidth200" value="'.$object->accountancy_code_buy_intra.'">';
print '<td><input name="accountancy_code_buy_intra" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_buy_intra') ? GETPOST('accountancy_code_buy_intra') : $object->accountancy_code_buy_intra).'">';
print '</td></tr>';
}
// Accountancy_code_buy_export
print '<tr><td class="titlefieldcreate">'.$langs->trans("ProductAccountancyBuyExportCode").'</td>';
print '<td><input name="accountancy_code_buy_export" class="maxwidth200" value="'.$object->accountancy_code_buy_export.'">';
print '<td><input name="accountancy_code_buy_export" class="maxwidth200" value="'.(GETPOSTISSET('accountancy_code_buy_export') ? GETPOST('accountancy_code_buy_export') : $object->accountancy_code_buy_export).'">';
print '</td></tr>';
}
}

View File

@ -14,7 +14,7 @@
* Copyright (C) 2014 Ion agorria <ion@agorria.com>
* Copyright (C) 2016-2018 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2017 Gustavo Novaro
* Copyright (C) 2019-2022 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2019-2023 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
@ -1566,7 +1566,7 @@ class Product extends CommonObject
}
} elseif (isset($this->multilangs[$key])) {
if (empty($this->multilangs["$key"]["label"])) {
$this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label"));
$this->errors[] = $key . ' : ' . $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label"));
return -1;
}
@ -4869,7 +4869,7 @@ class Product extends CommonObject
/**
* Return all parent products for current product (first level only)
*
* @return array Array of product
* @return array|int Array of product
* @see hasFatherOrChild()
*/
public function getFather()
@ -4911,7 +4911,7 @@ class Product extends CommonObject
* @param int $firstlevelonly Return only direct child
* @param int $level Level of recursing call (start to 1)
* @param array $parents Array of all parents of $id
* @return array Return array(prodid=>array(0=prodid, 1=>qty, 2=>product type, 3=>label, 4=>incdec, 5=>product ref)
* @return array|int Return array(prodid=>array(0=prodid, 1=>qty, 2=>product type, 3=>label, 4=>incdec, 5=>product ref)
*/
public function getChildsArbo($id, $firstlevelonly = 0, $level = 1, $parents = array())
{

View File

@ -367,7 +367,7 @@ class PriceGlobalVariableUpdater
/**
* List all price global variables
*
* @return array Array of price global variable updaters
* @return array|int Array of price global variable updaters
*/
public function listUpdaters()
{
@ -404,7 +404,7 @@ class PriceGlobalVariableUpdater
/**
* List all updaters which need to be processed
*
* @return array Array of price global variable updaters
* @return array|int Array of price global variable updaters
*/
public function listPendingUpdaters()
{

View File

@ -577,7 +577,7 @@ class Entrepot extends CommonObject
/**
* Return number of unique different product into a warehouse
*
* @return Array Array('nb'=>Nb, 'value'=>Value)
* @return array|int Array('nb'=>Nb, 'value'=>Value)
*/
public function nb_different_products()
{
@ -608,7 +608,7 @@ class Entrepot extends CommonObject
/**
* Return stock and value of warehosue
*
* @return Array Array('nb'=>Nb, 'value'=>Value)
* @return array|int Array('nb'=>Nb, 'value'=>Value)
*/
public function nb_products()
{

View File

@ -469,7 +469,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '<tr><td>';
print $form->editfieldkey($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker');
print '</td><td>';
print $form->editfieldval($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker');
print $form->editfieldval($langs->trans('SellByDate'), 'sellby', $object->sellby, $object, $user->rights->stock->creer, 'datepicker', '', null, null, '', 1, '', 'id', 'auto', array(), $action);
print '</td>';
print '</tr>';
}
@ -479,7 +479,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '<tr><td>';
print $form->editfieldkey($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker');
print '</td><td>';
print $form->editfieldval($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker');
print $form->editfieldval($langs->trans('EatByDate'), 'eatby', $object->eatby, $object, $user->rights->stock->creer, 'datepicker', '', null, null, '', 1, '', 'id', 'auto', array(), $action);
print '</td>';
print '</tr>';
}

View File

@ -2345,4 +2345,29 @@ class Project extends CommonObject
$this->lines = $taskstatic->getTasksArray(0, $user, $this->id, 0, 0, '', '-1', '', 0, 0, array(), 0, array(), 0, $loadRoleMode);
}
/**
* Function sending an email to the current member with the text supplied in parameter.
*
* @param string $text Content of message (not html entities encoded)
* @param string $subject Subject of message
* @param array $filename_list Array of attached files
* @param array $mimetype_list Array of mime types of attached files
* @param array $mimefilename_list Array of public names of attached files
* @param string $addr_cc Email cc
* @param string $addr_bcc Email bcc
* @param int $deliveryreceipt Ask a delivery receipt
* @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
* @param string $errors_to erros to
* @param string $moreinheader Add more html headers
* @since V18
* @return int <0 if KO, >0 if OK
*/
public function sendEmail($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
{
global $conf, $langs;
// TODO EMAIL
return 1;
}
}

View File

@ -372,7 +372,7 @@ if (empty($reshook) && $action == 'add') {
if ($subjecttosend && $texttosend) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
}
/*if ($result < 0) {
$error++;

View File

@ -360,7 +360,7 @@ if (empty($reshook) && $action == 'add') {
if ($subjecttosend && $texttosend) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by public/members/new.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
}
}

View File

@ -775,7 +775,7 @@ if ($ispaymentok) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by public/payment/paymentok.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, "", $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, $listofpaths, $listofmimes, $listofnames, "", "", 0, -1, "", $moreinheader);
if ($result < 0) {
$errmsg = $object->error;

View File

@ -368,11 +368,10 @@ if (empty($reshook) && $action == 'add') {
complete_substitutions_array($substitutionarray, $outputlangs, $object);
$subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs);
$texttosend = make_substitutions($msg, $substitutionarray, $outputlangs);
if ($subjecttosend && $texttosend) {
$moreinheader = 'X-Dolibarr-Info: send_an_email by public/lead/new.php'."\r\n";
$result = $object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
$result = $object->sendEmail($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader);
}
/*if ($result < 0) {
$error++;

View File

@ -499,10 +499,10 @@ class Receptions extends DolibarrApi
*
* @param int $id Reception ID
* @param int $notrigger 1=Does not execute triggers, 0= execute triggers
* @return Object Object with cleaned properties
*
* @url POST {id}/validate
*
* @return Object
* \todo An error 403 is returned if the request has an empty body.
* Error message: "Forbidden: Content type `text/plain` is not supported."
* Workaround: send this in the body
@ -627,9 +627,10 @@ class Receptions extends DolibarrApi
*
* @param int $id Reception ID
* @param int $notrigger Disabled triggers
* @return Object Object with cleaned properties
*
* @url POST {id}/close
*
* @return Object
*/
public function close($id, $notrigger = 0)
{

View File

@ -11,7 +11,7 @@
* Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
* Copyright (C) 2016-2022 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2018 Quentin Vial-Gouteyron <quentin.vial-gouteyron@atm-consulting.fr>
* Copyright (C) 2022 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2022-2023 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
@ -97,6 +97,12 @@ class Reception extends CommonObject
public $date_delivery; // Date delivery planed
/**
* @var integer|string Effective delivery date
* @deprecated
* @see $date_reception
*/
public $date;
/**
* @var integer|string Effective delivery date
@ -396,8 +402,7 @@ class Reception extends CommonObject
$this->statut = $obj->fk_statut;
$this->user_author_id = $obj->fk_user_author;
$this->date_creation = $this->db->jdate($obj->date_creation);
$this->date = $this->db->jdate($obj->date_reception); // TODO deprecated
$this->date_reception = $this->db->jdate($obj->date_reception); // TODO deprecated
$this->date = $this->db->jdate($obj->date_reception); // TODO deprecated
$this->date_reception = $this->db->jdate($obj->date_reception); // Date real
$this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed
$this->model_pdf = $obj->model_pdf;

View File

@ -523,8 +523,8 @@ class Thirdparties extends DolibarrApi
/**
* Delete thirdparty
*
* @param int $id Thirdparty ID
* @return array
* @param int $id Thirdparty ID
* @return array
*/
public function delete($id)
{
@ -1351,10 +1351,10 @@ class Thirdparties extends DolibarrApi
/**
* Generate a Document from a bank account record (like SEPA mandate)
*
* @param int $id Thirdparty id
* @param int $companybankid Companybank id
* @param string $model Model of document to generate
* @return array
* @param int $id Thirdparty id
* @param int $companybankid Companybank id
* @param string $model Model of document to generate
* @return array
*
* @url GET {id}/generateBankAccountDocument/{companybankid}/{model}
*/

View File

@ -1459,7 +1459,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
print '<tr class="oddeven">';
// Label
print '<td>'.dol_escape_htmltag($rib->label).'</td>';
print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($rib->label).'">'.dol_escape_htmltag($rib->label).'</td>';
// Stripe ID
print '<td class="tdoverflowmax150">';
if ($rib->stripe_card_ref) {

View File

@ -1944,7 +1944,7 @@ class SupplierProposal extends CommonObject
* @param int $offset For pagination
* @param string $sortfield Sort criteria
* @param string $sortorder Sort order
* @return int -1 if KO, array with result if OK
* @return array|int -1 if KO, array with result if OK
*/
public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield = 'p.datec', $sortorder = 'DESC')
{
@ -2225,7 +2225,7 @@ class SupplierProposal extends CommonObject
*
* @param User $user Object user
* @param int $mode "opened" for askprice to close, "signed" for proposal to invoice
* @return int <0 if KO, >0 if OK
* @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
*/
public function load_board($user, $mode)
{