diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 758b5ec8917..822b63e02ab 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -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",), diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 58cc45f3f80..800ac22cf92 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -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')); diff --git a/htdocs/adherents/stats/byproperties.php b/htdocs/adherents/stats/byproperties.php index 89c454c59bb..c0fee0b0d35 100644 --- a/htdocs/adherents/stats/byproperties.php +++ b/htdocs/adherents/stats/byproperties.php @@ -163,11 +163,11 @@ print dol_get_fiche_head($head, 'statsbyproperties', '', -1, ''); // Print title if (!count($data)) { print ''.$langs->trans("NoValidatedMemberYet").'
'; - print '
'; } else { print ''.$langs->trans("MembersByNature").'
'; - print '
'; } +print ''.$langs->trans("DraftMembersAreExcluded").'
'; +print '
'; // Print array print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table diff --git a/htdocs/adherents/stats/geo.php b/htdocs/adherents/stats/geo.php index 04f5d3f6f59..8449e366ee9 100644 --- a/htdocs/adherents/stats/geo.php +++ b/htdocs/adherents/stats/geo.php @@ -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 ''.$langs->trans("MembersByRegion").'
'; //+ } + print ''.$langs->trans("DraftMembersAreExcluded").'
'; print '
'; } diff --git a/htdocs/adherents/stats/index.php b/htdocs/adherents/stats/index.php index cf0a08bab99..7df8c1d6e73 100644 --- a/htdocs/adherents/stats/index.php +++ b/htdocs/adherents/stats/index.php @@ -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ó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, ''); diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 782883b7497..381bedc23bf 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -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 ''; $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'); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index fa1ded78592..02bbcfb62f0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -7451,8 +7451,12 @@ function print_barre_liste($title, $page, $file, $options = '', $sortfield = '', print ''; print '
'; print '' . $title . ''; // $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 '(' . $totalnboflines . ')'; + if (!empty($title) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') { + if (is_numeric($totalnboflines) && (int) $totalnboflines > 0) { + print '(' . $totalnboflines . ')'; + } else { + print '(' . $totalnboflines . ')'; + } } print '
'; if (!empty($subtitle)) { diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 08c3abfc313..95e16071bad 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -3293,7 +3293,7 @@ function validateZipFile(&$zip, $originalfilename, $zipfile) } } if ($error) { - $return['errormsg'].= $weblangs->trans("validationFail") . '
'; + $return['errormsg'].= $weblangs->trans("UnvalidZipFile") . '
'; $return['errormsg'].= $weblangs->trans("moduleContents") . '
'; $return['errormsg'].= $weblangs->trans("moduleDirectoryRule1") . '
'; $return['errormsg'].= $weblangs->trans("moduleDirectoryRule2") . '
'; @@ -3382,10 +3382,10 @@ function validateZipFile(&$zip, $originalfilename, $zipfile) dol_syslog("validateZipFile Error"); $link = 'Dolibarr wiki developer documentation'; - $return['errormsg'].= $weblangs->trans("invalidZipFile") .'
'; - $return['errormsg'].= $weblangs->trans("seeDocumentation", $link).'
'; + $return['errormsg'].= $weblangs->trans("UnvalidZipFile") .'
'; + $return['errormsg'].= $weblangs->trans("SeeDocumentation", $link).'
'; $return['errormsg'].= "
\n"; - $return['errormsg'].= $weblangs->trans("contactDolistore"); + $return['errormsg'].= $weblangs->trans("Contact"); $return['upload'] = -1; $error++; } else { diff --git a/htdocs/core/lib/member.lib.php b/htdocs/core/lib/member.lib.php index 836abcd0cb8..fe17563f027 100644 --- a/htdocs/core/lib/member.lib.php +++ b/htdocs/core/lib/member.lib.php @@ -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> 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 * diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 8c429beb101..4414adfbd0e 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -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')); diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index eb568062763..319f95574bf 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -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 diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 9416b02272c..ee8c7756112 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -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.
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. diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 9ff7f0fac11..18d1204047e 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -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:
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"