Merge branch 'develop' of https://github.com/Dolibarr/dolibarr into NEX---List-product-in-orders

This commit is contained in:
Anthony Berton 2022-07-27 15:35:58 +02:00
commit c2715d1469
21 changed files with 397 additions and 302 deletions

View File

@ -30,25 +30,23 @@ For users:
NEW: PHP 8.1 compatibility
NEW: Support for recurring purchase invoices.
NEW: #20292 Include German public holidays
NEW: Can show ZATCA QRCode on PDFs
NEW: Can show Swiss QR Code on PDFs
NEW: Can show ZATCA QR-Code on PDFs
NEW: Can show Swiss QR-Code on PDFs
NEW: #17123 added ExtraFields for Stock Mouvement
NEW: #20609 : new massaction to assign a sale representatives on a selection of thirdparties
NEW: #20609 new massaction to assign a sale representatives on a selection of thirdparties
NEW: #20653 edit discount pourcentage for all lines in one shot
NEW: Accept 'auto' for ref of object on import of purchase order/proposal
NEW: Accountancy - Add more filters and info on page to bind accounting accounts
NEW: Accountancy - Add subledger account when we generate a transaction with a deposit invoice
NEW: Accountancy - Add subledger account when generate a transaction with a deposit invoice
NEW: Accountancy - Add a massaction to preselect an account (customer and supplier list)
NEW: ACE Editor is restored at same cursor position after a save.
NEW: Add "addMoreActionsButtons" hook to subscription form
NEW: Add an option in GUI to show a Quick add button into top menu bar
NEW: Module Recruitment - Add a public page with all list of open job positions.
NEW: Module Recruitment - Add a tab with list of application on the jobposition file.
NEW: Add a workflow to auto link contract on a ticket
NEW: Add column date of Signature on proposal list
NEW: Add column template invoice in invoice list
NEW: Add column "Total HT" to products array on document creation card
NEW: ADD configuration for text color of button action
NEW: Add configuration for text color of button action
NEW: Add constant to hide categories in TakePos
NEW: Add constant to show category description in TakePos
NEW: Add constant to show only the products in stock in TakePos
@ -56,7 +54,7 @@ NEW: Add entity filter in exports
NEW: Show the event block on recurring invoices #20870
NEW: Add filter "opportunity status" on statistics of projects.
NEW: Add firstname, lastname and max number of attendees for module "Event Organization"
NEW: add margin info in proposal and order list
NEW: Add margin info in proposal and order list
NEW: Add massaction "Edit Extrafield" for Product
NEW: Add more fields to detect duplicate during import of thirdparties
NEW: Add option to foce delivery on email for purchase order receipt to yes
@ -67,14 +65,12 @@ NEW: Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad
NEW: Add private and public notes on tax files.
NEW: Add status "Obsolete" to KM articles
NEW: Add substitutions "user numbers"
NEW: Add the possibility to add sub-BOMs to BOM
NEW: allow a ticket to be automatically marked as read when created from backend.
NEW: allow cut&paste as real numeric value to excel
NEW: A public form to send a message and create a lead is available
NEW: automatically set totally received status in reception
NEW: Auto set invoice paid when adding credit not and remain to pay is 0
NEW: Availibility dictionnary has a new column unit and number
NEW: barcode rule to insert product in takepos
NEW: Can change value of AWP during the inventory
NEW: Can enter price with tax for predefined products on purchase objects
NEW: Can filter on a thirdparty on product statistics
@ -90,7 +86,7 @@ NEW: create third-party with contact if not found on public ticket
NEW: Default value for MAIN_SECURITY_CSRF_WITH_TOKEN is now 2 (GET are also protected agains CSRF attacks)
NEW: deposit payment terms: add field into dictionary admin page to define default percentage of deposit.
NEW: Dictionaries - add possibility to manage countries in EEC
NEW: display errors in a message box after generating documents
NEW: Display errors in a message box after generating documents
NEW: Display physical and virtual stock of the products when creating OF from a BOM
NEW: Display product ref in "Object link" product tab for BOM
NEW: Enhance the import. Can use 'auto' for the ref (import of orders)
@ -102,10 +98,13 @@ NEW: leave requests: add field into type dictionary to block request if balance
NEW: MAIN_MAIL_AUTOCOPY_TO can accept several email and special keys
NEW: MAIN_SEARCH_CAT_OR_BY_DEFAULT const for search by category
NEW: Mass action "Close shipments"
NEW: Module BOM - Add tabs for nets Bom
NEW: Module BOM - Add the possibility to add sub-BOMs to BOM
NEW: Module Recruitment - Add a public page with all list of open job positions.
NEW: Module Recruitment - Add a tab with list of application on the jobposition file.
NEW: Module website now supports the multicompany module
NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...)
NEW: Add option to move checkbox column as first column on Thirdparty list (only few screens)
NEW: Add tabs for nets Bom
NEW: on redirect of page in website module, GET parameters are kept.
NEW: optional display warning icons on ticket list
NEW: option to default check "notify tier at creation" in ticket module
@ -117,15 +116,15 @@ NEW: Send email to the supplier order contact
NEW: New permission to report time on timesheet.
NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level
NEW: Show number of votes into the label of tab "Results" of a survey
NEW: Show product reference in Takepos
NEW: Some core tables are created only at module activation
NEW: split consumption line on MO
NEW: stock filter in reassort lists
NEW: stock limit in stock export CSV
NEW: Sub-bom are availables
NEW: Supplier order - Show ref supplier of reception in linked object block
NEW: support user_modif in order
NEW: TakePos - pagination on search results
NEW: TakePOS - barcode rule to insert product in TakePOS
NEW: TakePOS - pagination on search results
NEW: TakePOS - show product reference
NEW: The backup tools has an "lowmemory" option for mysqldump on large database
NEW: The 'reposition' class works on ajax constantonoff that make redirects
NEW: Thirdparty - Add rules "customer accountancy code" is mandatory to validate invoice
@ -140,7 +139,7 @@ NEW: Added MMK currency (Myanmar Kyat)
Modules
NEW: Module Partnership Management
NEW: Experimental module Event Organization Management
NEW: Experimental Module Event Organization Management
For developers or integrators:
@ -155,7 +154,6 @@ NEW: Suggest a way to run upgrade per entities.
NEW: Support html content for multiselect component.
NEW: ModuleBuilder - Add tabs view in module builder
NEW: ModuleBuilder - More feature that can be modifed after module generation
NEW: Hook getNomUrl available everywhere in tooltip of ref links
NEW: Identification of tr is possible with by attribute data-id on some pages
NEW: Import with select boxes V2
NEW: Can update rank of invoice, proposal and order lines with API update
@ -182,6 +180,9 @@ NEW: Add a protection into PHPunit to avoid to forget a var_dump
NEW: Add datem and type parameters to API to create movements
NEW: Add hidden option on contract PDF line to hide qty and price
NEW: Option MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND to send last document in mass mailing action
Hooks:
NEW: Hook getNomUrl available everywhere in tooltip of ref links
NEW: Add hooks: selectContactListWhere hook, selectThirdpartyListWhere hook
NEW: TakePos - add hooks complete product display
NEW: TakePos - add hooks for cart display

View File

@ -207,21 +207,11 @@ $message .= $langs->trans("AgendaUrlOptionsIncludeHolidays", '1', '1').'<br>';
print info_admin($message);
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#MAIN_AGENDA_XCAL_EXPORTKEY").val(token);
});
});
});';
print '</script>';
}
$constname = 'MAIN_AGENDA_XCAL_EXPORTKEY';
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname);
// End of page
llxFooter();

View File

@ -188,22 +188,10 @@ if (!empty($conf->global->CLICKTODIAL_URL)) {
}
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token").click(function() {
console.log("Click done");
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#CLICKTODIAL_KEY_FOR_CIDLOOKUP").val(token);
});
});
});';
print '</script>';
}
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword('CLICKTODIAL_KEY_FOR_CIDLOOKUP');
// End of page
llxFooter();

View File

@ -273,21 +273,10 @@ if ($action == 'edit') {
if (!empty($conf->use_javascript_ajax)) {
print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"');
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token'.$constname.'").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#'.$constname.'").val(token);
});
});
});';
print '</script>';
}
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname, 'generate_token'.$constname);
} elseif ($val['type'] == 'product') {
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
$selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname);

View File

@ -540,21 +540,10 @@ if ($action == 'edit') {
if (!empty($conf->use_javascript_ajax)) {
print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"');
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token'.$constname.'").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#'.$constname.'").val(token);
});
});
});';
print '</script>';
}
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname, 'generate_token'.$constname);
} elseif ($val['type'] == 'product') {
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
$selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname);

View File

@ -107,21 +107,11 @@ llxHeader('', $langs->trans("MailingSetup"));
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("MailingSetup"), $linkback, 'title_setup');
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#MAILING_EMAIL_UNSUBSCRIBE_KEY").val(token);
});
});
});';
print '</script>';
}
$constname = 'MAILING_EMAIL_UNSUBSCRIBE_KEY';
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname);
print '<br>';
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';

View File

@ -338,21 +338,10 @@ if ($action == 'edit') {
if (!empty($conf->use_javascript_ajax)) {
print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"');
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token'.$constname.'").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#'.$constname.'").val(token);
});
});
});';
print '</script>';
}
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname, 'generate_token'.$constname);
} elseif ($val['type'] == 'product') {
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
$selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname);

View File

@ -519,21 +519,10 @@ if ($action == 'edit') {
if (!empty($conf->use_javascript_ajax)) {
print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"');
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token'.$constname.'").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#'.$constname.'").val(token);
});
});
});';
print '</script>';
}
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname, 'generate_token'.$constname);
} elseif ($val['type'] == 'product') {
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
$selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname);

View File

@ -409,9 +409,13 @@ if (empty($reshook) && $action == 'add') {
$error++;
}
if (!$error) {
$db->begin();
// Creation of action/event
$idaction = $object->create($user);
@ -474,15 +478,15 @@ if (empty($reshook) && $action == 'add') {
$db->commit();
}
if (!empty($backtopage)) {
dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
} elseif ($idaction) {
header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
} else {
header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
}
exit;
// if (!empty($backtopage)) {
// dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
// header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
// } elseif ($idaction) {
// header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
// } else {
// header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
// }
// exit;
} else {
// If error
$db->rollback();
@ -496,6 +500,151 @@ if (empty($reshook) && $action == 'add') {
setEventMessages($object->error, $object->errors, 'errors');
$action = 'create'; $donotclearsession = 1;
}
$selectedrecurrulefreq = 'no';
$selectedrecurrulebymonthday = '';
$selectedrecurrulebyday = '';
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) {
$selectedrecurrulefreq = $reg1[1];
}
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) {
$selectedrecurrulebymonthday = $reg2[1];
}
if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg3)) {
$selectedrecurrulebyday = $reg3[1];
}
// If event is recurrent
$userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);
if ($userepeatevent && !empty($selectedrecurrulefreq) && $selectedrecurrulefreq != 'no') {
// We set first date of recurrence and offsets
if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) {
$firstdatearray = dol_get_first_day_week(GETPOST("apday", 'int'), GETPOST("apmonth", 'int'), GETPOST("apyear", 'int'));
$datep = dol_mktime($fulldayevent ? '00' : GETPOST("aphour", 'int'), $fulldayevent ? '00' : GETPOST("apmin", 'int'), $fulldayevent ? '00' : GETPOST("apsec", 'int'), $firstdatearray['month'], $firstdatearray['first_day'], $firstdatearray['year'], $tzforfullday ? $tzforfullday : 'tzuser');
$datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after
$dayoffset = 7;
$monthoffset = 0;
} elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) {
$firstday = $selectedrecurrulebymonthday;
$firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOST("apmonth", 'int') + 1 : GETPOST("apmonth", 'int');//We begin the week after
$datep = dol_mktime($fulldayevent ? '00' : GETPOST("aphour", 'int'), $fulldayevent ? '00' : GETPOST("apmin", 'int'), $fulldayevent ? '00' : GETPOST("apsec", 'int'), $firstmonth, $firstday, GETPOST("apyear", 'int'), $tzforfullday ? $tzforfullday : 'tzuser');
$dayoffset = 0;
$monthoffset = 1;
} else {
$error++;
}
// End date
$repeateventlimitdate = dol_mktime('23', '59', '59', GETPOSTISSET("limitmonth", 'int') ? GETPOST("limitmonth", 'int') : 01, GETPOSTISSET("limitday", 'int') ? GETPOST("limitday", 'int') : 01, GETPOSTISSET("limityear", 'int') && GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser');
// Set date of end of event
$deltatime = num_between_day($object->datep, $datep);
$datef = dol_time_plus_duree($datef, $deltatime, 'd');
while ($datep <= $repeateventlimitdate && !$error) {
$finalobject = clone $object;
$finalobject->datep = $datep;
$finalobject->datef = $datef;
// Creation of action/event
$idaction = $finalobject->create($user);
if ($idaction > 0) {
if (!$finalobject->error) {
// Category association
$categories = GETPOST('categories', 'array');
$finalobject->setCategories($categories);
unset($_SESSION['assignedtouser']);
$moreparam = '';
if ($user->id != $finalobject->userownerid) {
$moreparam = "filtert=-1"; // We force to remove filter so created record is visible when going back to per user view.
}
// Create reminders
if ($addreminder == 'on') {
$actionCommReminder = new ActionCommReminder($db);
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, $offsetunit);
$actionCommReminder->dateremind = $dateremind;
$actionCommReminder->typeremind = $remindertype;
$actionCommReminder->offsetunit = $offsetunit;
$actionCommReminder->offsetvalue = $offsetvalue;
$actionCommReminder->status = $actionCommReminder::STATUS_TODO;
$actionCommReminder->fk_actioncomm = $finalobject->id;
if ($remindertype == 'email') {
$actionCommReminder->fk_email_template = $modelmail;
}
// the notification must be created for every user assigned to the event
foreach ($finalobject->userassigned as $userassigned) {
$actionCommReminder->fk_user = $userassigned['id'];
$res = $actionCommReminder->create($user);
if ($res <= 0) {
// If error
$db->rollback();
$langs->load("errors");
$error = $langs->trans('ErrorReminderActionCommCreation');
setEventMessages($error, null, 'errors');
$action = 'create'; $donotclearsession = 1;
break;
}
}
}
// Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page.
/*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0';
$moreparam .= ($moreparam ? '&' : '').'search_status=-1';
$moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
*/
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
if ($error) {
$db->rollback();
} else {
$db->commit();
}
} else {
// If error
$db->rollback();
$langs->load("errors");
$error = $langs->trans($finalobject->error);
setEventMessages($error, null, 'errors');
$action = 'create'; $donotclearsession = 1;
}
} else {
$db->rollback();
setEventMessages($finalobject->error, $finalobject->errors, 'errors');
$action = 'create'; $donotclearsession = 1;
}
// If event is not recurrent, we stop here
if (!($userepeatevent && GETPOSTISSET('recurrulefreq') && GETPOST('recurrulefreq') != 'no' && GETPOSTISSET("limityear") && GETPOSTISSET("limitmonth") && GETPOSTISSET("limitday"))) {
break;
}
// increment date for recurrent events
$datep = dol_time_plus_duree($datep, $dayoffset, 'd');
$datep = dol_time_plus_duree($datep, $monthoffset, 'm');
$datef = dol_time_plus_duree($datef, $dayoffset, 'd');
$datef = dol_time_plus_duree($datef, $monthoffset, 'm');
}
}
if (!empty($backtopage) && !$error) {
dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
} elseif ($idaction) {
header("Location: ".DOL_URL_ROOT.'/comm/action/card.php?id='.$idaction.($moreparam ? '&'.$moreparam : ''));
} else {
header("Location: ".DOL_URL_ROOT.'/comm/action/index.php'.($moreparam ? '?'.$moreparam : ''));
}
exit;
}
}
@ -916,10 +1065,11 @@ $formproject = new FormProjets($db);
$arrayrecurrulefreq = array(
'no'=>$langs->trans("OnceOnly"),
'MONTHLY'=>$langs->trans("EveryMonth"),
'WEEKLY'=>$langs->trans("EveryWeek"),
//'DAYLY'=>$langs->trans("EveryDay")
'WEEKLY'=>$langs->trans("EveryWeek")
// 'DAILY'=>$langs->trans("EveryDay")
);
$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda';
llxHeader('', $langs->trans("Agenda"), $help_url);
@ -1037,20 +1187,31 @@ if ($action == 'create') {
print ' &nbsp; &nbsp; &nbsp; &nbsp; <div class="opacitymedium inline-block">';
print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"');
print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">';
$selectedrecurrulefreq = 'no';
$selectedrecurrulebymonthday = '';
$selectedrecurrulebyday = '';
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
$object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
$reg = array();
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
$selectedrecurrulefreq = $reg[1];
}
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) {
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
$selectedrecurrulebymonthday = $reg[1];
}
if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
$selectedrecurrulebyday = $reg[1];
}
print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly');
// print '<script>console.log("recurrule: " +'.$object->recurrule.')</script>';
// For recursive event
// If recurrulefreq is MONTHLY
print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
@ -1059,32 +1220,47 @@ if ($action == 'create') {
print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
print '</div>';
// limit date
$repeateventlimitdate = $repeateventlimitdate ? $repeateventlimitdate : '';
print '<div class="hidden marginrightonly inline-block repeateventlimitdate">';
print $langs->trans("Until")." ";
print $form->selectDate($repeateventlimitdate, 'limit', 0, 0, 0, "action", 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel');
print '</div>';
print '<script type="text/javascript">
jQuery(document).ready(function() {
function init_repeat()
jQuery(document).ready(function() {
function init_repeat()
{
console.log("recurrule: " + "'.$object->recurrule.'");
console.log("reg1: " + "'.$selectedrecurrulefreq.'");
console.log("reg2: " + "'.$selectedrecurrulebymonthday.'");
console.log("reg3: " + "'.$selectedrecurrulebyday.'");
console.log("selectedrulefreq: " + "'.$selectedrecurrulefreq.'");
if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
{
if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
{
jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventBYDAY").hide();
}
else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
{
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
}
else
{
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").hide();
}
jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventlimitdate").css("display", "inline-block");
jQuery(".repeateventBYDAY").hide();
}
else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
{
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventlimitdate").css("display", "inline-block");
}
else
{
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").hide();
jQuery(".repeateventlimitdate").hide();
}
}
init_repeat();
jQuery("#recurrulefreq").change(function() {
init_repeat();
jQuery("#recurrulefreq").change(function() {
init_repeat();
});
});
</script>';
});
</script>';
print '</div>';
//print '</td></tr>';
}
@ -1545,64 +1721,64 @@ if ($id > 0) {
print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td colspan="3" class="valignmiddle height30 small"><input type="checkbox" id="fullday" name="fullday" '.($object->fulldayevent ? ' checked' : '').'>';
print '<label for="fullday">'.$langs->trans("EventOnFullDay").'</label>';
// Recurring event
$userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);
if ($userepeatevent) {
// Repeat
//print '<tr><td></td><td colspan="3">';
print ' &nbsp; &nbsp; &nbsp; &nbsp; <div class="opacitymedium inline-block">';
print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"');
print '<input type="hidden" name="recurid" value="'.$object->recurid.'">';
$selectedrecurrulefreq = 'no';
$selectedrecurrulebymonthday = '';
$selectedrecurrulebyday = '';
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
$selectedrecurrulefreq = $reg[1];
}
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) {
$selectedrecurrulebymonthday = $reg[1];
}
if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
$selectedrecurrulebyday = $reg[1];
}
print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly');
// If recurrulefreq is MONTHLY
print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
print '</div>';
// If recurrulefreq is WEEKLY
print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
print '</div>';
print '<script type="text/javascript">
jQuery(document).ready(function() {
function init_repeat()
{
if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
{
jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
jQuery(".repeateventBYDAY").hide();
}
else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
{
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
}
else
{
jQuery(".repeateventBYMONTHDAY").hide();
jQuery(".repeateventBYDAY").hide();
}
}
init_repeat();
jQuery("#recurrulefreq").change(function() {
init_repeat();
});
});
</script>';
print '</div>';
//print '</td></tr>';
}
// // Recurring event
// $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);
// if ($userepeatevent) {
// // Repeat
// //print '<tr><td></td><td colspan="3">';
// print ' &nbsp; &nbsp; &nbsp; &nbsp; <div class="opacitymedium inline-block">';
// print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"');
// print '<input type="hidden" name="recurid" value="'.$object->recurid.'">';
// $selectedrecurrulefreq = 'no';
// $selectedrecurrulebymonthday = '';
// $selectedrecurrulebyday = '';
// if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
// $selectedrecurrulefreq = $reg[1];
// }
// if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i', $object->recurrule, $reg)) {
// $selectedrecurrulebymonthday = $reg[1];
// }
// if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i', $object->recurrule, $reg)) {
// $selectedrecurrulebyday = $reg[1];
// }
// print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly');
// // If recurrulefreq is MONTHLY
// print '<div class="hidden marginrightonly inline-block repeateventBYMONTHDAY">';
// print $langs->trans("DayOfMonth").': <input type="input" size="2" name="BYMONTHDAY" value="'.$selectedrecurrulebymonthday.'">';
// print '</div>';
// // If recurrulefreq is WEEKLY
// print '<div class="hidden marginrightonly inline-block repeateventBYDAY">';
// print $langs->trans("DayOfWeek").': <input type="input" size="4" name="BYDAY" value="'.$selectedrecurrulebyday.'">';
// print '</div>';
// print '<script type="text/javascript">
// jQuery(document).ready(function() {
// function init_repeat()
// {
// if (jQuery("#recurrulefreq").val() == \'MONTHLY\')
// {
// jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
// jQuery(".repeateventBYDAY").hide();
// }
// else if (jQuery("#recurrulefreq").val() == \'WEEKLY\')
// {
// jQuery(".repeateventBYMONTHDAY").hide();
// jQuery(".repeateventBYDAY").css("display", "inline-block"); /* use this instead of show because we want inline-block and not block */
// }
// else
// {
// jQuery(".repeateventBYMONTHDAY").hide();
// jQuery(".repeateventBYDAY").hide();
// }
// }
// init_repeat();
// jQuery("#recurrulefreq").change(function() {
// init_repeat();
// });
// });
// </script>';
// print '</div>';
// //print '</td></tr>';
// }
print '</td></tr>';
// Date start - end

View File

@ -42,6 +42,9 @@ if (!defined('NOREQUIRETRAN')) {
require '../../main.inc.php';
$action = GETPOST('action');
/*
* View
*/
@ -52,10 +55,10 @@ top_httphead();
//print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
// Registering the location of boxes
if (isset($_GET['action']) && !empty($_GET['action'])) {
if ($_GET['action'] == 'getrandompassword' && ($user->admin || $user->rights->api->apikey->generate)) {
if ($action) {
if ($action == 'getrandompassword' && ($user->admin || $user->rights->api->apikey->generate)) {
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
$generic = $_GET['generic'] ? true : false;
$generic = GETPOST('generic') ? true : false;
echo getRandomPassword($generic);
}
}

View File

@ -952,21 +952,11 @@ class FormSetupItem
if (!empty($conf->use_javascript_ajax)) {
$out.= '&nbsp;'.img_picto($this->langs->trans('Generate'), 'refresh', 'id="generate_token'.$this->confKey.'" class="linkobject"');
}
if (!empty($conf->use_javascript_ajax)) {
$out .= "\n" . '<script type="text/javascript">';
$out .= '$(document).ready(function () {
$("#generate_token' . $this->confKey . '").click(function() {
$.get( "' . DOL_URL_ROOT . '/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#' . $this->confKey . '").val(token);
});
});
});';
$out .= '</script>';
}
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
$out .= dolJSToSetRandomPassword($this->confKey, 'generate_token'.$this->confKey);
return $out;
}

View File

@ -449,7 +449,7 @@ function encodedecode_dbpassconf($level = 0)
* @param array $replaceambiguouschars Discard ambigous characters. For example array('I').
* @param int $length Length of random string (Used only if $generic is true)
* @return string New value for password
* @see dol_hash()
* @see dol_hash(), dolJSToSetRandomPassword()
*/
function getRandomPassword($generic = false, $replaceambiguouschars = null, $length = 32)
{
@ -527,3 +527,34 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len
return $generated_password;
}
/**
* Ouput javacript to autoset a generated password using default module into a HTML element.
*
* @param string $htmlname HTML name of element to insert key into
* @param string $htmlnameofbutton HTML name of button
* @return string HTML javascript code to set a password
* @see getRandomPassword()
*/
function dolJSToSetRandomPassword($htmlname, $htmlnameofbutton = 'generate_token')
{
global $conf;
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<!-- Js code to suggest a security key --><script type="text/javascript">';
print '$(document).ready(function () {
$("#'.dol_escape_js($htmlnameofbutton).'").click(function() {
console.log("We click on the button to suggest a key");
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true,
token: \''.dol_escape_js(newToken()).'\'
},
function(result) {
$("#'.dol_escape_js($htmlname).'").val(result);
});
});
});'."\n";
print '</script>';
}
}

View File

@ -141,21 +141,11 @@ if (!empty($conf->don->enabled)) {
print '<br>';
}
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script>';
print '$(document).ready(function () {
$("#generate_token").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#PAYMENT_SECURITY_TOKEN").val(token);
});
});
});';
print '</script>';
}
$constname = 'PAYMENT_SECURITY_TOKEN';
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname);
print info_admin($langs->trans("YouCanAddTagOnUrl"));

View File

@ -129,22 +129,11 @@ dol_print_cron_urls();
print '<br>';
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token").click(function() {
console.log("Click done");
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#CRON_KEY").val(token);
});
});
});';
print '</script>';
}
$constname = 'CRON_KEY';
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname);
llxFooter();
$db->close();

View File

@ -41,12 +41,14 @@ ALTER TABLE llx_c_email_templates ADD COLUMN email_from varchar(255);
ALTER TABLE llx_c_email_templates ADD COLUMN email_to varchar(255);
ALTER TABLE llx_c_email_templates ADD COLUMN email_tocc varchar(255);
ALTER TABLE llx_c_email_templates ADD COLUMN email_tobcc varchar(255);
ALTER TABLE llx_c_email_templates ADD COLUMN content_lines text;
ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0;
ALTER TABLE llx_accounting_system MODIFY COLUMN pcg_version varchar(32) NOT NULL;
-- v17
ALTER TABLE llx_facture ADD COLUMN close_missing_amount double(24, 8) after close_code;

View File

@ -4116,6 +4116,7 @@ function migrate_delete_old_files($db, $langs, $conf)
'/core/boxes/box_members.php',
'/api/class/api_generic.class.php',
'/asterisk/cidlookup.php',
'/categories/class/api_category.class.php',
'/categories/class/api_deprecated_category.class.php',
'/compta/facture/class/api_invoice.class.php',

View File

@ -136,7 +136,7 @@ AgendaUrlOptionsNotAdmin=<b>logina=!%s</b> to restrict output to actions not own
AgendaUrlOptions4=<b>logint=%s</b> to restrict output to actions assigned to user <b>%s</b> (owner and others).
AgendaUrlOptionsProject=<b>project=__PROJECT_ID__</b> to restrict output to actions linked to project <b>__PROJECT_ID__</b>.
AgendaUrlOptionsNotAutoEvent=<b>notactiontype=systemauto</b> to exclude automatic events.
AgendaUrlOptionsIncludeHolidays=<b>includeholidays=1</b> to include events of holidays.
AgendaUrlOptionsIncludeHolidays=<b>includeholidays=1</b> to include events of holidays.
AgendaShowBirthdayEvents=Birthdays of contacts
AgendaHideBirthdayEvents=Hide birthdays of contacts
Busy=Busy
@ -160,6 +160,7 @@ DateActionBegin=Start event date
ConfirmCloneEvent=Are you sure you want to clone the event <b>%s</b>?
RepeatEvent=Repeat event
OnceOnly=Once only
EveryDay=Every day
EveryWeek=Every week
EveryMonth=Every month
DayOfMonth=Day of month
@ -175,3 +176,4 @@ AddReminder=Create an automatic reminder notification for this event
ErrorReminderActionCommCreation=Error creating the reminder notification for this event
BrowserPush=Browser Popup Notification
ActiveByDefault=Enabled by default
Until=until

View File

@ -96,7 +96,7 @@ PRODUCT_MODIFYInDolibarr=Produit %s modifié
PRODUCT_DELETEInDolibarr=Produit%ssupprimé
HOLIDAY_CREATEInDolibarr=Demande de congé %s créée
HOLIDAY_MODIFYInDolibarr=Demande de congé %s modifiée
HOLIDAY_APPROVEInDolibarr=Demande de congé %s approuvée
HOLIDAY_APPROVEInDolibarr=Demande de congé %s approuvée
HOLIDAY_VALIDATEInDolibarr=Demande de congé %s validée
HOLIDAY_DELETEInDolibarr=Demande de congé %s supprimée
EXPENSE_REPORT_CREATEInDolibarr=Note de frais %s créée
@ -157,6 +157,7 @@ DateActionBegin=Date début événément
ConfirmCloneEvent=Êtes-vous sûr de vouloir cloner cet événement <b>%s</b> ?
RepeatEvent=Evénement répétitif
OnceOnly=Une seule fois
EveryDay=Chaque jour
EveryWeek=Chaque semaine
EveryMonth=Chaque mois
DayOfMonth=Jour du mois
@ -172,3 +173,4 @@ AddReminder=Créer une notification de rappel automatique pour cet événement
ErrorReminderActionCommCreation=Erreur lors de la création de la notification de rappel pour cet événement
BrowserPush=Notification par Popup navigateur
ActiveByDefault=Activé par défaut
Until=jusqu'à

View File

@ -139,12 +139,12 @@ print dol_get_fiche_end();
print '</form>';
/*
if (!empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) {
print '<br>';
//print $langs->trans('FollowingLinksArePublic').'<br>';
print img_picto('', 'globe').' '.$langs->trans('BlankSubscriptionForm').':<br>';
if ($conf->multicompany->enabled) {
print img_picto('', 'globe').' <span class="opacitymedium">'.$langs->trans('BlankSubscriptionForm').'</span><br>';
if (!empty($conf->multicompany->enabled)) {
$entity_qr = '?entity='.$conf->entity;
} else {
$entity_qr = '';
@ -155,9 +155,12 @@ if (!empty($conf->global->RECRUITMENT_ENABLE_PUBLIC_INTERFACE)) {
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
print '<a target="_blank" rel="noopener noreferrer" href="'.$urlwithroot.'/public/members/new.php'.$entity_qr.'">'.$urlwithroot.'/public/members/new.php'.$entity_qr.'</a>';
print '<div class="urllink">';
print '<input type="text" id="publicurlmember" class="quatrevingtpercentminusx" value="'.$urlwithroot.'/public/recruitment/index.php'.$entity_qr.'">';
print '<a target="_blank" rel="noopener noreferrer" href="'.$urlwithroot.'/public/recruitment/index.php'.$entity_qr.'">'.img_picto('', 'globe', 'class="paddingleft"').'</a>';
print '</div>';
print ajax_autoselect('publicurlmember');
}
*/
// End of page
llxFooter();

View File

@ -833,7 +833,7 @@ if ($action == 'create' || $action == 'adduserldap') {
print '<table class="border centpercent">';
// Civility
print '<tr><td><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td colspan="3">';
print '<tr><td><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td>';
print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'aZ09') : $object->civility_code, 'civility_code');
print '</td></tr>';
@ -2077,7 +2077,7 @@ if ($action == 'create' || $action == 'adduserldap') {
}
// Civility
print '<tr><td class="titlefieldcreate"><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td colspan="3">';
print '<tr><td class="titlefieldcreate"><label for="civility_code">'.$langs->trans("UserTitle").'</label></td><td>';
if ($caneditfield && !$object->ldap_sid) {
print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'aZ09') : $object->civility_code, 'civility_code');
} elseif ($object->civility_code) {
@ -2834,20 +2834,12 @@ if ($action == 'create' || $action == 'adduserldap') {
}
}
if (!empty($conf->api->enabled) && !empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_api_key").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#api_key").val(token);
});
});
});';
print '</script>';
if (!empty($conf->api->enabled)) {
$constname = 'api_key';
// Add button to autosuggest a key
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
print dolJSToSetRandomPassword($constname, 'generate_api_key');
}
// End of page

View File

@ -140,21 +140,10 @@ print '<br>';
print '<br>';
print $langs->trans("OnlyActiveElementsAreShown", DOL_URL_ROOT.'/admin/modules.php');
if (!empty($conf->use_javascript_ajax)) {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#generate_token").click(function() {
$.get( "'.DOL_URL_ROOT.'/core/ajax/security.php", {
action: \'getrandompassword\',
generic: true
},
function(token) {
$("#WEBSERVICES_KEY").val(token);
});
});
});';
print '</script>';
}
$constname = 'WEBSERVICES_KEY';
print dolJSToSetRandomPassword($constname);
// End of page
llxFooter();