Look and feel v24

This commit is contained in:
Laurent Destailleur 2026-05-10 21:44:30 +02:00
parent 33da2de776
commit 079c2b4b6e
13 changed files with 81 additions and 34 deletions

View file

@ -114,7 +114,7 @@ class AdherentType extends CommonObject
"caneditamount" => array("type" => "integer", "label" => "Caneditamount", "enabled" => "1", 'position' => 40, 'notnull' => 0, "visible" => "1",),
"minimumamount" => array("type" => "double(24,8)", "label" => "MinimumAmount", "enabled" => "1", 'position' => 42, 'notnull' => 0, "visible" => "1",),
"amount" => array("type" => "double(24,8)", "label" => "Amount", "enabled" => "1", 'position' => 45, 'notnull' => 0, "visible" => "1",),
"amountformuladescription" => array("type" => "longtext", "label" => "AmountFormulaDescription", "enabled" => "1", 'position' => 46, 'notnull' => 0, "visible" => "1",),
"amountformuladescription" => array("type" => "longtext", "label" => "AmountFormulaDescription", "enabled" => "1", 'position' => 46, 'notnull' => 0, "visible" => "-1",),
"vote" => array("type" => "varchar(3)", "label" => "Vote", "enabled" => "1", 'position' => 50, 'notnull' => 1, "visible" => "-1",),
"mail_valid" => array("type" => "longtext", "label" => "MailValidation", "enabled" => "1", 'position' => 60, 'notnull' => 0, "visible" => "-3",),
"morphy" => array("type" => "varchar(3)", "label" => "MembersNature", "enabled" => "1", 'position' => 65, 'notnull' => 0, "visible" => "1",),

View file

@ -796,7 +796,7 @@ $queryforbutton['mode'] = 'common';
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', dolBuildUrl($_SERVER["PHP_SELF"], $queryforbutton), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
$queryforbutton['mode'] = 'kanban';
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', dolBuildUrl($_SERVER["PHP_SELF"], $queryforbutton), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', dol_buildpath('/adherents/stats/index.php', 1).'?objecttype=adherent@adherent'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ($mode == 'statistics' ? 2 : 1), array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', dol_buildpath('/adherents/stats/geo.php', 1).'?mode=memberbycountry&objecttype=adherent@adherent'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ($mode == 'statistics' ? 2 : 1), array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitleSeparator();
$newcardbutton .= dolGetButtonTitle($langs->trans('NewMember'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/adherents/card.php', ['action' => 'create']), '', $user->hasRight('adherent', 'creer'));

View file

@ -163,11 +163,11 @@ print dol_get_fiche_head($head, 'statsbyproperties', '', -1, '');
// Print title
if (!count($data)) {
print '<span class="opacitymedium">'.$langs->trans("NoValidatedMemberYet").'</span><br>';
print '<br>';
} else {
print '<span class="opacitymedium">'.$langs->trans("MembersByNature").'</span><br>';
print '<br>';
}
print '<span class="opacitymedium">'.$langs->trans("DraftMembersAreExcluded").'</span><br>';
print '<br>';
// Print array
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table

View file

@ -43,7 +43,9 @@ $mapratio = 0.5;
$graphheight = round($graphwidth * $mapratio);
$mode = GETPOST('mode');
if (empty($mode)) {
$mode = 'memberbycountry';
}
// Security check
if ($user->socid > 0) {
@ -255,6 +257,7 @@ if ($mode && !count($data)) {
} elseif ($mode == 'memberbyregion') {
print '<span class="opacitymedium">'.$langs->trans("MembersByRegion").'</span><br>'; //+
}
print '<span class="opacitymedium">'.$langs->trans("DraftMembersAreExcluded").'</span><br>';
print '<br>';
}

View file

@ -27,11 +27,6 @@
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherentstats.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
/**
* @var Conf $conf
* @var DoliDB $db
@ -39,6 +34,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherentstats.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
$WIDTH = DolGraph::getDefaultGraphSizeForStats('width');
$HEIGHT = DolGraph::getDefaultGraphSizeForStats('height');
@ -75,10 +74,10 @@ $langs->loadLangs(array("companies", "members"));
*/
$memberstatic = new Adherent($db);
$membershipstatic = new Subscription($db);
$form = new Form($db);
$title = $langs->trans("Members");
$title = $langs->trans("Subscriptions");
$help_url = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios|DE:Modul_Mitglieder';
llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-member page-stats');
@ -88,14 +87,14 @@ $param = '';
$newcardbutton = '';
$queryforbutton = array();
$queryforbutton['mode'] = 'common';
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', dolBuildUrl(DOL_URL_ROOT.'/adherents/list.php', $queryforbutton), '', 1, array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', dolBuildUrl(DOL_URL_ROOT.'/adherents/subscription/list.php', $queryforbutton), '', 1, array('morecss' => 'reposition'));
$queryforbutton['mode'] = 'kanban';
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', dolBuildUrl(DOL_URL_ROOT.'/adherents/list.php', $queryforbutton), '', 1, array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', dolBuildUrl(DOL_URL_ROOT.'/adherents/subscription/list.php', $queryforbutton), '', 1, array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', dol_buildpath('/adherents/stats/index.php', 1).'?objecttype=adherent@adherent'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', 2, array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitleSeparator();
$newcardbutton .= dolGetButtonTitle($langs->trans('NewMember'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/adherents/card.php', ['action' => 'create']), '', $user->hasRight('adherent', 'creer'));
$newcardbutton .= dolGetButtonTitle($langs->trans('NewSubscription'), '', 'fa fa-plus-circle', dolBuildUrl(DOL_URL_ROOT.'/adherents/list.php', ['statut' => '-1,1']), '', $user->hasRight('adherent', 'creer'));
print_barre_liste($title, 0, $_SERVER["PHP_SELF"], $param, '', '', '', 0, $langs->trans("Statistics"), $memberstatic->picto, 0, $newcardbutton, '', 0, 0, 0, 1);
print_barre_liste($title, 0, $_SERVER["PHP_SELF"], $param, '', '', '', 0, $langs->trans("Statistics"), $membershipstatic->picto, 0, $newcardbutton, '', 0, 0, 0, 1);
$dir = $conf->member->dir_temp;
@ -170,7 +169,7 @@ if (!$mesg) {
}
$head = member_stats_prepare_head($memberstatic);
$head = membership_stats_prepare_head($memberstatic);
print dol_get_fiche_head($head, 'statssubscription', '', -1, '');

View file

@ -42,6 +42,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
// Load translation files required by the page
$langs->loadLangs(array("members", "companies", "banks"));
$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'create'/'add', 'edit'/'update', 'view', ...
@ -185,7 +186,8 @@ $accountstatic = new Account($db);
$now = dol_now();
// List of subscriptions
// Build and execute select
// --------------------------------------------------------------------
$sql = "SELECT d.rowid, d.login, d.firstname, d.lastname, d.societe, d.photo, d.statut as status,";
$sql .= " d.gender, d.email, d.morphy,";
$sql .= " c.rowid as crowid, c.fk_type, c.subscription,";
@ -195,7 +197,7 @@ $sql .= " b.fk_account";
// Add fields from extrafields
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : "");
}
}
// Add fields from hooks
@ -382,6 +384,7 @@ print '<input type="hidden" name="mode" value="'.$mode.'">';
$newcardbutton = '';
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition'));
$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', dol_buildpath('/adherents/stats/index.php', 1).'?objecttype=adherent@adherent'.preg_replace('/(&|\?)*(mode|groupby)=[^&]+/', '', $param), '', ($mode == 'statistics' ? 2 : 1), array('morecss' => 'reposition'));
if ($user->hasRight('adherent', 'cotisation', 'creer')) {
$newcardbutton .= dolGetButtonTitleSeparator();
$newcardbutton .= dolGetButtonTitle($langs->trans('NewSubscription'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/list.php?status=-1,1');

View file

@ -7451,8 +7451,12 @@ function print_barre_liste($title, $page, $file, $options = '', $sortfield = '',
print '<td class="nobordernopadding valignmiddle col-title">';
print '<div class="titre inline-block nowrap">';
print '<span class="inline-block valignmiddle print-barre-liste">' . $title . '</span>'; // $title may contains HTML like a combo list from page consumption.php, so we do not use dolPrintLabel here()
if (!empty($title) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '' && $totalnboflines > 0) {
print '<span class="opacitymedium colorblack marginleftonly totalnboflines valignmiddle" title="' . $langs->trans("NbRecordQualified") . '">(' . $totalnboflines . ')</span>';
if (!empty($title) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') {
if (is_numeric($totalnboflines) && (int) $totalnboflines > 0) {
print '<span class="opacitymedium colorblack marginleftonly totalnboflines valignmiddle" title="' . $langs->trans("NbRecordQualified") . '">(' . $totalnboflines . ')</span>';
} else {
print '<span class="opacitymedium colorblack marginleftonly totalnboflines valignmiddle">(' . $totalnboflines . ')</span>';
}
}
print '</div>';
if (!empty($subtitle)) {

View file

@ -3293,7 +3293,7 @@ function validateZipFile(&$zip, $originalfilename, $zipfile)
}
}
if ($error) {
$return['errormsg'].= $weblangs->trans("validationFail") . '<br>';
$return['errormsg'].= $weblangs->trans("UnvalidZipFile") . '<br>';
$return['errormsg'].= $weblangs->trans("moduleContents") . '<br>';
$return['errormsg'].= $weblangs->trans("moduleDirectoryRule1") . '<br>';
$return['errormsg'].= $weblangs->trans("moduleDirectoryRule2") . '<br>';
@ -3382,10 +3382,10 @@ function validateZipFile(&$zip, $originalfilename, $zipfile)
dol_syslog("validateZipFile Error");
$link = '<a target="_blank" class="linktowiki" href="https://wiki.dolibarr.org/index.php/Modules - Packaging rules and Dolistore validation rules">Dolibarr wiki developer documentation</a>';
$return['errormsg'].= $weblangs->trans("invalidZipFile") .'<br>';
$return['errormsg'].= $weblangs->trans("seeDocumentation", $link).'<br>';
$return['errormsg'].= $weblangs->trans("UnvalidZipFile") .'<br>';
$return['errormsg'].= $weblangs->trans("SeeDocumentation", $link).'<br>';
$return['errormsg'].= "<br>\n";
$return['errormsg'].= $weblangs->trans("contactDolistore");
$return['errormsg'].= $weblangs->trans("Contact");
$return['upload'] = -1;
$error++;
} else {

View file

@ -284,16 +284,10 @@ function member_admin_prepare_head()
*/
function member_stats_prepare_head($object)
{
global $langs, $conf, $user;
global $conf, $langs;
$h = 0;
$head = array();
$head[$h][0] = dolBuildUrl(DOL_URL_ROOT . '/adherents/stats/index.php');
$head[$h][1] = $langs->trans("Subscriptions");
$head[$h][2] = 'statssubscription';
$h++;
$head[$h][0] = dolBuildUrl(DOL_URL_ROOT . '/adherents/stats/geo.php', ['mode' => 'memberbycountry']);
$head[$h][1] = $langs->trans("Country");
$head[$h][2] = 'statscountry';
@ -319,6 +313,7 @@ function member_stats_prepare_head($object)
$head[$h][2] = 'statsbyproperties';
$h++;
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
@ -330,6 +325,37 @@ function member_stats_prepare_head($object)
return $head;
}
/**
* Return array head with list of tabs to view object stats information
*
* @param Adherent $object Member or null
* @return array<int,array<int,string>> head links
*/
function membership_stats_prepare_head($object)
{
global $langs, $conf;
$h = 0;
$head = array();
$head[$h][0] = dolBuildUrl(DOL_URL_ROOT . '/adherents/stats/index.php');
$head[$h][1] = $langs->trans("Subscriptions");
$head[$h][2] = 'statssubscription';
$h++;
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
// $this->tabs = array('entity:-tabname); to remove a tab
complete_head_from_modules($conf, $langs, $object, $head, $h, 'membership_stats');
complete_head_from_modules($conf, $langs, $object, $head, $h, 'memberships_stats', 'remove');
return $head;
}
/**
* Return array head with list of tabs to view object information
*

View file

@ -2647,7 +2647,7 @@ function get_left_menu_members($mainmenu, &$newmenu, $usemenuhider = 1, $leftmen
$newmenu->add(dolBuildUrl('/adherents/list.php', ['leftmenu' => 'members', 'statut' => 1, 'filter' => 'outofdate']), $langs->trans("OutOfDate"), 3, $user->hasRight('adherent', 'read'));
$newmenu->add(dolBuildUrl('/adherents/list.php', ['leftmenu' => 'members', 'statut' => 0]), $langs->trans("MenuMembersResiliated"), 2, $user->hasRight('adherent', 'read'));
$newmenu->add(dolBuildUrl('/adherents/list.php', ['leftmenu' => 'members', 'statut' => -2]), $langs->trans("MenuMembersExcluded"), 2, $user->hasRight('adherent', 'read'));
$newmenu->add(dolBuildUrl('/adherents/stats/index.php', ['leftmenu' => 'members']), $langs->trans("MenuMembersStats"), 1, $user->hasRight('adherent', 'read'));
$newmenu->add(dolBuildUrl('/adherents/stats/geo.php', ['leftmenu' => 'members']), $langs->trans("MenuMembersStats"), 1, $user->hasRight('adherent', 'read'));
$newmenu->add(dolBuildUrl('/adherents/cartes/carte.php', ['leftmenu' => 'export']), $langs->trans("MembersCards"), 1, $user->hasRight('adherent', 'export'));

View file

@ -1435,3 +1435,4 @@ History=History
Delay=Delay
RefOfOnCustomerSide=Reference of %s on customer side
RefOfOnVendorSide=Reference of %s on vendor side
SeeDocumentation=See documentation

View file

@ -212,7 +212,7 @@ DefaultAmount=Default amount of membership payment (used only if no amount is de
MinimumAmount=Minimum amount of membership payment (has priority on any default amounts that is lower)
MinimumAmountShort=Minimum amount
RecommendedAmount=(Recommended) Amount
AmountFormulaDescription=Describe the subscription amount formula
AmountFormulaDescription=Information on the membership price
CanEditAmount=Membership amount can be defined by the member
CanEditAmountDetail=Visitor can choose/edit amount of its contribution regardless of the member type
AmountIsLowerToMinimumNotice=The amount is lower than the minimum %s
@ -265,3 +265,4 @@ CorrespondingMemberFound=Corresponding member found
CorrespondingMemberFoundQuestion=A member has been found with the given information.<br>Do you want to renew your membership? (if not nothing will be recorded)
MEMBER_SEARCH_MEMBER_PUBLIC_FORM_CREATE=Suggest to just record the subscription (without creating a new member) if an existing member is found
MEMBER_SEARCH_MEMBER_PUBLIC_FORM_CREATEDesc=A search is done on login, company name + email (for legal entity), or full name + email (for individual). If a member is already found, the form suggest to record a renewal of subscription.
DraftMembersAreExcluded=Draft members are excluded.

View file

@ -432,3 +432,13 @@ TypeYourQuestion=Type your question...
SendPrompt=Send
ConfirmAiAction=Are you sure you want to %1$s using the %2$s tool?
YourInstallIsOldThanksToUpgrade=Your Dolibarr version seems to be an old version. Thanks to request an upgrade from your customer dashboard.
moduleDirectoryRule1=- only 1 directory matching your module or theme name (recommended),
moduleDirectoryRule2=- or several directories matching following names: ./htdocs/yourmodulename, ./docs, ./scripts, ./test or ./build.
moduleContents=Sorry, a module file can only contain into zip root:
UnvalidZipFile=Unvalid zip file
mainIncludeError=The call of main.inc.php or master.inc.php in the file "%s" in module "%s" does not follow good practices. You must have at least (minimum) 2 tries to include the main.inc.php or master.inc.php file:<br>1 if module is inside the dolibarr root directory, and 1 to support when module is inside "the custom" directory. Best is to read the file modulebuilder/template/mymoduleindex.php for an example of sequence to load the main/master.inc.php.
directoryFound=But we found a directory or file with name:
docRootError=The call of your module class should not be done with DOL_DOCUMENT_ROOT, the file "%s" of module "%s" is wrong, you must correct the line below with "dol_include_once":
dolIncludeError=The call of dol_include_once of the file "%s" in module "%s" is wrong, you must correct the line below:
moduleNameMismatch=Warning, the module file contains a directory in root called "%s" but this does not match the name of module used as file name that is "%s".
rootDirWarning=Warning, a module file can contain only 1 root directory with the same name as the module (into the root of zip or into the htdocs directory). We found %s files/directories into the root of module. If this module is a meta-package (a module embedding several other modules), you must include a file metapackage.conf with list of all embedded module names in directory "%s"