diff --git a/ChangeLog b/ChangeLog index 6ac794b974eba678666e5d954f03465d6f7bb328..15c1dc404f5e7bdfcb15a78b5b64f2d1e80419e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,26 @@ Following changes may create regression for some external modules, but were nece * Removed the trigger file of PAYPAL module that stored data that was not used by Dolibarr. The trigger event still exists, but if an external module need action on it, it must provides itself its trigger file. +***** ChangeLog for 5.0.3 compared to 5.0.2 ***** +FIX: #6677 Expired contracts dashboard box does not show the name of the thirdparty +FIX: #6813 +FIX: 6863 +FIX: #6877 +FIX: #6881 +FIX: Better sanitizing of search all parameter. +FIX: Correction with author and validator user on orders +FIX: dialog window with md theme must not be hidden by left menu part. +FIX: doactions hook missing in invoice model page +FIX: Fullname when member is a moral entity with no name. +FIX: Link to files on bank account tab broken with multicompany FIX: Link to preview on thirdparty broken with multicompany +FIX: New vat code not correctly implemented if "1 price per customer". +FIX: Pagination of invoices +FIX: pagination on resources +FIX: REST API not possible to add agendaevents +FIX: situation invoice broken due to the all percent application form inside addline form +FIX: SQL injection on user/index.php parameter search_statut. +FIX: XSS + ***** ChangeLog for 5.0.2 compared to 5.0.1 ***** FIX: #6468 + Fix missing translation FIX: #6517 #6525 Autocompletion of thirdparty after n chars not implemented diff --git a/build/debian/README.howto b/build/debian/README.howto index c94309ec2ef7ea21f44e3bbb9223911443ae8cfe..1632e95423785a656b677a60c3b0a61826b74bfc 100644 --- a/build/debian/README.howto +++ b/build/debian/README.howto @@ -444,3 +444,4 @@ Note that package 3.5.7 contains not only fixed for bugs reported to debian. It so it is a better solution to validate this maintenance release than applying a patch of the only CVE-2015-3935. After discussion with ..., it appears that security holes are enough to request this unblock request." +Note: If there is a response to ask more information, don't forget to remove the tag during answer. diff --git a/build/debian/source/lintian-overrides b/build/debian/source/lintian-overrides index b4c0956e90f896ac1d53d96549da222bdb5741b4..c878035b4821d8fa0a9d25c51e467e596c18426f 100644 --- a/build/debian/source/lintian-overrides +++ b/build/debian/source/lintian-overrides @@ -4,7 +4,12 @@ dolibarr: source-contains-prebuilt-javascript-object htdocs/includes/jsgantt/* dolibarr: source-contains-prebuilt-javascript-object htdocs/includes/jstz/* # Those are false positives, the files are their own sources since # they are not minified -source-is-missing htdocs/includes/jsgantt/jsgantt.js * -source-is-missing htdocs/includes/jquery/plugins/colorpicker/jquery.colorpicker.js * -source-is-missing htdocs/includes/jquery/plugins/select2/select2.js * -source-is-missing htdocs/includes/jquery/plugins/select2/select2_locale_ar.js * +source-is-missing htdocs/includes/ckeditor/ckeditor/plugins/a11yhelp/dialogs/lang/*.js +source-is-missing htdocs/includes/ckeditor/ckeditor/plugins/specialchar/dialogs/lang/*.js +source-is-missing htdocs/includes/ckeditor/ckeditor/lang/*.js +source-is-missing htdocs/includes/ckeditor/ckeditor/plugins/*/dialogs/*.js +source-is-missing htdocs/includes/ckeditor/ckeditor/plugins/*/filter/*.js +source-is-missing htdocs/includes/ckeditor/ckeditor/plugins/templates/templates/default.js +source-is-missing htdocs/includes/mobiledetect/mobiledetectlib/Mobile_Detect.json +source-is-missing htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/*.js + diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index bd9587a4440538f0f1ffec3b0353f9d02ec47963..44ec3ade8895a028f83b7ba3b2a01107c7acacc5 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -49,6 +49,8 @@ $type = 'action'; * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if (preg_match('/set_(.*)/',$action,$reg)) { $code=$reg[1]; @@ -77,21 +79,6 @@ if (preg_match('/del_(.*)/',$action,$reg)) dol_print_error($db); } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - if (! $error) - { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} if ($action == 'set') { dolibarr_set_const($db, 'AGENDA_USE_EVENT_TYPE_DEFAULT', GETPOST('AGENDA_USE_EVENT_TYPE_DEFAULT'), 'chaine', 0, '', $conf->entity); @@ -233,7 +220,7 @@ else if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { print load_fiche_titre($langs->trans("AgendaModelModule"),'',''); - + print '<table class="noborder" width="100%">'."\n"; print '<tr class="liste_titre">'."\n"; print '<td width="100">'.$langs->trans("Name").'</td>'."\n"; @@ -243,13 +230,13 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print '<td align="center" width="40">'.$langs->trans("ShortInfo").'</td>'; print '<td align="center" width="40">'.$langs->trans("Preview").'</td>'; print '</tr>'."\n"; - + clearstatcache(); - + foreach ($dirmodels as $reldir) { $dir = dol_buildpath($reldir."core/modules/action/doc/"); - + if (is_dir($dir)) { $handle=opendir($dir); @@ -261,10 +248,10 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { $name = substr($file, 4, dol_strlen($file) -16); $classname = substr($file, 0, dol_strlen($file) -12); - + require_once $dir.'/'.$file; - $module = new $classname($db, new ActionComm($db)); - + $module = new $classname($db, new ActionComm($db)); + print '<tr class="oddeven">'."\n"; print "<td>"; print (empty($module->name)?$name:$module->name); @@ -272,16 +259,16 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print "<td>\n"; require_once $dir.$file; $module = new $classname($db,$specimenthirdparty); - if (method_exists($module,'info')) + if (method_exists($module,'info')) print $module->info($langs); - else + else print $module->description; print "</td>\n"; - + // Active if (in_array($name, $def)) { - + print '<td align="center">'."\n"; if ($conf->global->ACTION_EVENT_ADDON_PDF != "$name") { @@ -301,7 +288,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmodel&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'&type=action">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>'; print "</td>"; } - + // Default print '<td align="center">'; if ($conf->global->ACTION_EVENT_ADDON_PDF == "$name") @@ -313,7 +300,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'&type=action"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; } print '</td>'; - + // Info $htmltooltip = ''.$langs->trans("Name").': '.$module->name; $htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); @@ -326,7 +313,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) print '<td align="center">'; print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'order').'</a>'; print '</td>'; - + print "</tr>\n"; } } @@ -366,7 +353,7 @@ print '</td></tr>'."\n"; if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) { - + print '<!-- AGENDA_USE_EVENT_TYPE_DEFAULT -->'; print '<tr class="oddeven">'."\n"; print '<td>'.$langs->trans("AGENDA_USE_EVENT_TYPE_DEFAULT").'</td>'."\n"; @@ -404,30 +391,30 @@ print '</td></tr>'."\n"; // AGENDA NOTIFICATION if ($conf->global->MAIN_FEATURES_LEVEL > 0) { - + print '<tr class="oddeven">'."\n"; print '<td>'.$langs->trans('AGENDA_NOTIFICATION').'</td>'."\n"; print '<td align="center"> </td>'."\n"; print '<td align="right">'."\n"; - + if (empty($conf->global->AGENDA_NOTIFICATION)) { print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_AGENDA_NOTIFICATION">'.img_picto($langs->trans('Disabled'),'switch_off').'</a>'; print '</td></tr>'."\n"; } else { print '<a href="'.$_SERVER['PHP_SELF'].'?action=del_AGENDA_NOTIFICATION">'.img_picto($langs->trans('Enabled'),'switch_on').'</a>'; print '</td></tr>'."\n"; - + print '<tr class="oddeven">'."\n"; print '<td>'.$langs->trans('AGENDA_NOTIFICATION_SOUND').'</td>'."\n"; print '<td align="center"> </td>'."\n"; print '<td align="right">'."\n"; - + if (empty($conf->global->AGENDA_NOTIFICATION_SOUND)) { print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_AGENDA_NOTIFICATION_SOUND">'.img_picto($langs->trans('Disabled'),'switch_off').'</a>'; } else { print '<a href="'.$_SERVER['PHP_SELF'].'?action=del_AGENDA_NOTIFICATION_SOUND">'.img_picto($langs->trans('Enabled'),'switch_on').'</a>'; } - + print '</td></tr>'."\n"; } } diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index db81c9a325f0cf99e8e0880d17d22fa6c47159b1..ba649fe92236e5d4d6633da0e3428cc72c83f944 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -39,6 +39,8 @@ $action = GETPOST('action','alpha'); * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'setbarcodeproducton') { $res=dolibarr_set_const($db, "BARCODE_PRODUCT_ADDON_NUM", GETPOST('value'), 'chaine', 0, '', $conf->entity); @@ -72,33 +74,7 @@ else if ($action == 'update') else if ($action == 'updateengine') { // TODO Update engines. - -} - -// define constants for models generator that need parameters -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - } - } - if (! $res > 0) $error++; - if (! $error) - { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - setEventMessages($langs->trans("Error"), null, 'errors'); - } } if ($action && $action != 'setcoder' && $action != 'setModuleOptions') @@ -276,7 +252,7 @@ if ($resql) print '<td align="center">'; print $formbarcode->setBarcodeEncoder($obj->coder,$barcodelist,$obj->rowid,'form'.$i); print "</td></tr>\n"; - + $i++; } } @@ -312,7 +288,7 @@ print '</tr>'; // Chemin du binaire genbarcode sous linux if (! isset($_SERVER['WINDIR'])) { - + print '<tr class="oddeven">'; print '<td>'.$langs->trans("GenbarcodeLocation").'</td>'; print '<td width="60" align="center">'; @@ -328,7 +304,7 @@ if (! isset($_SERVER['WINDIR'])) // Module products if (! empty($conf->product->enabled)) { - + print '<tr class="oddeven">'; print '<td>'.$langs->trans("SetDefaultBarcodeTypeProducts").'</td>'; print '<td width="60" align="right">'; @@ -339,7 +315,7 @@ if (! empty($conf->product->enabled)) // Module thirdparty if (! empty($conf->societe->enabled)) { - + print '<tr class="oddeven">'; print '<td>'.$langs->trans("SetDefaultBarcodeTypeThirdParties").'</td>'; print '<td width="60" align="right">'; diff --git a/htdocs/admin/chequereceipts.php b/htdocs/admin/chequereceipts.php index bc55eb4b9f648418476e02de3ff9e41c72788f93..f88dfc6f5a6784c05ffa21c8389d8cba036af5bb 100644 --- a/htdocs/admin/chequereceipts.php +++ b/htdocs/admin/chequereceipts.php @@ -77,7 +77,7 @@ if ($action == 'setmod') if ($action == 'set_BANK_CHEQUERECEIPT_FREE_TEXT') { - $freetext = GETPOST('BANK_CHEQUERECEIPT_FREE_TEXT'); // No alpha here, we want exact string + $freetext = GETPOST('BANK_CHEQUERECEIPT_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "BANK_CHEQUERECEIPT_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index 6d92ad21999b8d8dbbd70b5734a29f59c83b9817..f4104e2007fee609846e3cca775702771b017c48 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -54,6 +54,8 @@ $type = 'order'; * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconstorder=GETPOST('maskconstorder','alpha'); @@ -118,35 +120,6 @@ else if ($action == 'specimen') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -207,7 +180,7 @@ else if ($action == 'set_COMMANDE_DRAFT_WATERMARK') else if ($action == 'set_ORDER_FREE_TEXT') { - $freetext = GETPOST("ORDER_FREE_TEXT"); // No alpha here, we want exact string + $freetext = GETPOST("ORDER_FREE_TEXT",'none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "ORDER_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index 47e53a05048ce120e439bea895aa994de1f75576..e2f865f61f6006e31f58630b627350bce270207c 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -50,6 +50,8 @@ if (empty($conf->global->CONTRACT_ADDON)) * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconst = GETPOST('maskconstcontract','alpha'); @@ -113,35 +115,6 @@ else if ($action == 'specimen') // For contract } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -185,7 +158,7 @@ else if ($action == 'setmod') else if ($action == 'set_other') { - $freetext= GETPOST('CONTRACT_FREE_TEXT'); // No alpha here, we want exact string + $freetext= GETPOST('CONTRACT_FREE_TEXT','none'); // No alpha here, we want exact string $res1 = dolibarr_set_const($db, "CONTRACT_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); $draft= GETPOST('CONTRACT_DRAFT_WATERMARK','alpha'); @@ -501,7 +474,7 @@ print '<td align="center" width="60">'.$langs->trans("Value").'</td>'; print "</tr>\n"; $var=true; -$substitutionarray=pdf_getSubstitutionArray($langs); +$substitutionarray=pdf_getSubstitutionArray($langs, array('objectamount')); $substitutionarray['__(AnyTranslationKey)__']=$langs->trans("Translation"); $htmltext = '<i>'.$langs->trans("AvailableVariables").':<br>'; foreach($substitutionarray as $key => $val) $htmltext.=$key.'<br>'; diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index e9a9aaedb1878d06b86f2bff06996d11f4fd45f6..12d0b7951d5df55f88fc17811d5e9b9ed27fc050 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -57,6 +57,9 @@ if (empty($conf->global->EXPEDITION_ADDON_NUMBER)) /* * Actions */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconst=GETPOST('maskconstexpedition','alpha'); @@ -75,7 +78,7 @@ if ($action == 'updateMask') else if ($action == 'set_param') { - $freetext=GETPOST('SHIPPING_FREE_TEXT'); // No alpha here, we want exact string + $freetext=GETPOST('SHIPPING_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "SHIPPING_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); if ($res <= 0) { @@ -142,35 +145,6 @@ else if ($action == 'specimen') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -else if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php index 92ba93759270c8ca8475f988677df0aa2a29c62a..24aaeede5b49b446b7e6b153442f718ff1436150 100644 --- a/htdocs/admin/expensereport.php +++ b/htdocs/admin/expensereport.php @@ -51,6 +51,9 @@ $type='expensereport'; /* * Actions */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconst=GETPOST('maskconst','alpha'); @@ -116,35 +119,6 @@ else if ($action == 'specimen') // For fiche inter } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -194,7 +168,7 @@ else if ($action == 'setoptions') { $db->begin(); - $freetext= GETPOST('EXPENSEREPORT_FREE_TEXT'); // No alpha here, we want exact string + $freetext= GETPOST('EXPENSEREPORT_FREE_TEXT','none'); // No alpha here, we want exact string $res1 = dolibarr_set_const($db, "EXPENSEREPORT_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); $draft= GETPOST('EXPENSEREPORT_DRAFT_WATERMARK','alpha'); diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 64ae1abdde6d8fd992f8e7098cde157a33ab252b..df371639cde6d3dcb4c6d8cfdaf06b32840336c3 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -51,6 +51,8 @@ $type='invoice'; * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconstinvoice=GETPOST('maskconstinvoice','alpha'); @@ -123,31 +125,6 @@ if ($action == 'specimen') } } -// define constants for models generator that need parameters -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - } - } - if (! $res > 0) $error++; - - if (! $error) - { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -229,7 +206,7 @@ if ($action == 'set_FACTURE_DRAFT_WATERMARK') if ($action == 'set_INVOICE_FREE_TEXT') { - $freetext = GETPOST('INVOICE_FREE_TEXT'); // No alpha here, we want exact string + $freetext = GETPOST('INVOICE_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "INVOICE_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index e3000231c38a4f497baff7e3f72516a4304cff0f..43ad7ad8178163bc6ced6265b96f214667caa38f 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -51,6 +51,9 @@ $type='ficheinter'; /* * Actions */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconst=GETPOST('maskconst','alpha'); @@ -114,35 +117,6 @@ else if ($action == 'specimen') // For fiche inter } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -186,7 +160,7 @@ else if ($action == 'setmod') else if ($action == 'set_FICHINTER_FREE_TEXT') { - $freetext= GETPOST('FICHINTER_FREE_TEXT'); // No alpha here, we want exact string + $freetext= GETPOST('FICHINTER_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "FICHINTER_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; diff --git a/htdocs/admin/livraison.php b/htdocs/admin/livraison.php index cf97b397e444b7761528af3e7e3460949c16ca8a..0136f6cc9d93c5f02bec99fb3af46795bcb5974a 100644 --- a/htdocs/admin/livraison.php +++ b/htdocs/admin/livraison.php @@ -47,10 +47,13 @@ $label = GETPOST('label','alpha'); $scandir = GETPOST('scandir','alpha'); $type='delivery'; + /* * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconstdelivery=GETPOST('maskconstdelivery','alpha'); @@ -71,7 +74,7 @@ if ($action == 'updateMask') if ($action == 'set_DELIVERY_FREE_TEXT') { - $free=GETPOST('DELIVERY_FREE_TEXT'); // No alpha here, we want exact string + $free=GETPOST('DELIVERY_FREE_TEXT','none'); // No alpha here, we want exact string $res=dolibarr_set_const($db, "DELIVERY_FREE_TEXT",$free,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; @@ -131,35 +134,6 @@ if ($action == 'specimen') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - if ($action == 'set') { $ret = addDocumentModel($value, $type, $label, $scandir); diff --git a/htdocs/admin/payment.php b/htdocs/admin/payment.php index 88f2d8cd1c163963c19f336a9567f466b69bced4..061b9d50f6a877138b7dddc1307b8d3adb0af35e 100644 --- a/htdocs/admin/payment.php +++ b/htdocs/admin/payment.php @@ -71,7 +71,7 @@ if ($action == 'setmod') if ($action == 'setparams') { - $freetext = GETPOST('FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS'); // No alpha here, we want exact string + $freetext = GETPOST('FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS",$freetext,'chaine',0,'',$conf->entity); @@ -81,24 +81,11 @@ if ($action == 'setparams') { setEventMessages($langs->trans("Error"), null, 'errors'); } - - /* - $freetext = GETPOST('INVOICE_AUTO_FILLJS'); // No alpha here, we want exact string - - $res = dolibarr_set_const($db, "INVOICE_AUTO_FILLJS",$freetext,'chaine',0,'',$conf->entity); - - if (! $res > 0) $error++; - - if ($error) - { - setEventMessages($langs->trans("Error"), null, 'errors'); - }*/ - if (! $error) { setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } - + } diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index e0dc1d3b5b471c636fa55ac63c2ad217e4e03e49..8acbf19f939d509d0eb40284c84394b5a8ad1ba8 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -49,6 +49,9 @@ $type='propal'; /* * Actions */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + $error=0; if ($action == 'updateMask') { @@ -132,7 +135,7 @@ if ($action == 'set_PROPALE_DRAFT_WATERMARK') if ($action == 'set_PROPOSAL_FREE_TEXT') { - $freetext = GETPOST('PROPOSAL_FREE_TEXT'); // No alpha here, we want exact string + $freetext = GETPOST('PROPOSAL_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "PROPOSAL_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); @@ -180,35 +183,6 @@ if ($action == 'set_BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model if ($action == 'set') { diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index 549bb93809b165efe8768946df9705f3b9d74490..17501cdb4f910b1b0637d1ef178d4c151faf0c7a 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -172,7 +172,7 @@ if ($action == 'addcat') if ($action == 'set_SUPPLIER_INVOICE_FREE_TEXT') { - $freetext = GETPOST('SUPPLIER_INVOICE_FREE_TEXT'); // No alpha here, we want exact string + $freetext = GETPOST('SUPPLIER_INVOICE_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "SUPPLIER_INVOICE_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 55e4e4b3d07be8bcbb46fa48e1eb2dacb2c68bf4..13499af551a9ce13a3d2f4c78532e32882c62d2c 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -169,7 +169,7 @@ else if ($action == 'addcat') else if ($action == 'set_SUPPLIER_ORDER_OTHER') { - $freetext = GETPOST('SUPPLIER_ORDER_FREE_TEXT'); // No alpha here, we want exact string + $freetext = GETPOST('SUPPLIER_ORDER_FREE_TEXT','none'); // No alpha here, we want exact string $doubleapproval = GETPOST('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED','alpha'); $doubleapproval = price2num($doubleapproval ); diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index adaa114b1ca2d77830ba50cc174d2d70ae38145a..4227f4d42215ec86a9e08e7281cd34ac86029d86 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -47,6 +47,8 @@ $type='supplier_payment'; * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconstsupplierpayment=GETPOST('maskconstsupplierpayment','alpha'); @@ -68,31 +70,6 @@ if ($action == 'updateMask') dolibarr_set_const($db, "SUPPLIER_PAYMENT_ADDON", $value, 'chaine', 0, '', $conf->entity); } -// define constants for models generator that need parameters -else if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - } - } - if (! $res > 0) $error++; - - if (! $error) - { - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -195,7 +172,7 @@ dol_fiche_head($head, 'supplierpayment', $langs->trans("Suppliers"), -1, 'compan */ if (empty($conf->global->SUPPLIER_PAYMENT_ADDON)) $conf->global->SUPPLIER_PAYMENT_ADDON = 'mod_supplier_payment_bronan'; - + print load_fiche_titre($langs->trans("PaymentsNumberingModule"), '', ''); // Load array def with activated templates @@ -265,7 +242,7 @@ foreach ($dirmodels as $reldir) require_once $dir.$filebis; $module = new $classname($db); - + // Show modules according to features level if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; @@ -375,7 +352,7 @@ foreach ($dirmodels as $reldir) { while (($file = readdir($handle))!==false) { - if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) { $name = substr($file, 4, dol_strlen($file) -16); $classname = substr($file, 0, dol_strlen($file) -12); @@ -383,7 +360,7 @@ foreach ($dirmodels as $reldir) require_once $dir.'/'.$file; $module = new $classname($db, new PaiementFourn($db)); - + print "<tr class=\"oddeven\">\n"; print "<td>"; print (empty($module->name)?$name:$module->name); diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 82eeddd594c1bab5626598b5948d5e8ae5576e6f..8c52ee83dda5b0b563aeba024467f571d937e2d8 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -41,10 +41,15 @@ $label = GETPOST('label','alpha'); $scandir = GETPOST('scandir','alpha'); $type='supplier_proposal'; +$error=0; + + /* * Actions */ -$error=0; + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconstsupplier_proposal=GETPOST('maskconstsupplier_proposal','alpha'); @@ -127,7 +132,7 @@ if ($action == 'set_SUPPLIER_PROPOSAL_DRAFT_WATERMARK') if ($action == 'set_SUPPLIER_PROPOSAL_FREE_TEXT') { - $freetext = GETPOST('SUPPLIER_PROPOSAL_FREE_TEXT'); // No alpha here, we want exact string + $freetext = GETPOST('SUPPLIER_PROPOSAL_FREE_TEXT','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "SUPPLIER_PROPOSAL_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); @@ -159,35 +164,6 @@ if ($action == 'set_BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_PROPOSAL') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model if ($action == 'set') { diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 0c7574b7ec4da40ede76b99aed6e3736987a8a91..31efcb224741cba9eb2cfe1ea313b738e032f354 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -47,37 +47,9 @@ $type='user'; * Action */ -// Activate a model +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} -elseif ($action == 'set_default') +if ($action == 'set_default') { $ret = addDocumentModel($value, $type, $label, $scandir); $res = true; diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php index 4642e6d3183e3069620f87ef58fb6212c79e27ae..8d098ee6923398516133e1732f39ed874085b916 100644 --- a/htdocs/admin/usergroup.php +++ b/htdocs/admin/usergroup.php @@ -47,37 +47,9 @@ $type='group'; * Action */ -// Activate a model +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} -elseif ($action == 'set_default') +if ($action == 'set_default') { $ret = addDocumentModel($value, $type, $label, $scandir); $res = true; diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 02ee84dc2de91f49accbf0b1e7aac0548b87bf05..eb2eddb31979a7b011bdcdff88e0061484ee588d 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1208,7 +1208,7 @@ if ($id > 0) $out.=img_picto($langs->trans("ViewCal"),'object_calendar','class="hideonsmartphone pictoactionview"'); $out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_month&year='.dol_print_date($object->datep,'%Y').'&month='.dol_print_date($object->datep,'%m').'&day='.dol_print_date($object->datep,'%d').'">'.$langs->trans("ViewCal").'</a>'; $out.=img_picto($langs->trans("ViewWeek"),'object_calendarweek','class="hideonsmartphone pictoactionview"'); - $out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_day&year='.dol_print_date($object->datep,'%Y').'&month='.dol_print_date($object->datep,'%m').'&day='.dol_print_date($object->datep,'%d').'">'.$langs->trans("ViewWeek").'</a>'; + $out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_week&year='.dol_print_date($object->datep,'%Y').'&month='.dol_print_date($object->datep,'%m').'&day='.dol_print_date($object->datep,'%d').'">'.$langs->trans("ViewWeek").'</a>'; $out.=img_picto($langs->trans("ViewDay"),'object_calendarday','class="hideonsmartphone pictoactionview"'); $out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_day&year='.dol_print_date($object->datep,'%Y').'&month='.dol_print_date($object->datep,'%m').'&day='.dol_print_date($object->datep,'%d').'">'.$langs->trans("ViewDay").'</a>'; $linkback.=$out; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index e46b5718d22b18f841785af15e1ce20a884e6b2f..babeb241de042a708053c869c803d1460654d994 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -54,7 +54,7 @@ class Facture extends CommonInvoice public $fk_element = 'fk_facture'; protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='bill'; - + /** * {@inheritdoc} */ @@ -243,7 +243,7 @@ class Facture extends CommonInvoice if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; $this->brouillon = 1; if (empty($this->entity)) $this->entity = $conf->entity; - + // Multicurrency (test on $this->multicurrency_tx because we sould take the default rate only if not using origin rate) if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code); else $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code); @@ -280,7 +280,7 @@ class Facture extends CommonInvoice if ($this->fac_rec > 0) { $this->fk_fac_rec_source = $this->fac_rec; - + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; $_facrec = new FactureRec($this->db); $result=$_facrec->fetch($this->fac_rec); @@ -288,7 +288,7 @@ class Facture extends CommonInvoice $this->socid = $_facrec->socid; // Invoice created on same thirdparty than template $this->entity = $_facrec->entity; // Invoice created in same entity than template - + // Fields coming from GUI (priority on template). TODO Value of template should be used as default value on GUI so we can use here always value from GUI $this->fk_project = GETPOST('projectid','int') > 0 ? GETPOST('projectid','int') : $_facrec->fk_project; $this->note_public = GETPOST('note_public') ? GETPOST('note_public') : $_facrec->note_public; @@ -301,7 +301,7 @@ class Facture extends CommonInvoice // Set here to have this defined for substitution into notes, should be recalculated after adding lines to get same result $this->total_ht = $_facrec->total_ht; $this->total_ttc = $_facrec->total_ttc; - + // Fields always coming from template $this->remise_absolue = $_facrec->remise_absolue; $this->remise_percent = $_facrec->remise_percent; @@ -360,9 +360,10 @@ class Facture extends CommonInvoice '__INVOICE_YEAR__' => dol_print_date($this->date, '%Y'), '__INVOICE_NEXT_YEAR__' => dol_print_date(dol_time_plus_duree($this->date, 1, 'y'), '%Y'), ); - + + $substitutionisok=true; complete_substitutions_array($substitutionarray, $outputlangs); - + $this->note_public=make_substitutions($this->note_public,$substitutionarray); $this->note_private=make_substitutions($this->note_private,$substitutionarray); } @@ -472,7 +473,7 @@ class Facture extends CommonInvoice } } } - + if (! $error && $this->id && ! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && ! empty($this->origin) && ! empty($this->origin_id)) // Get contact from origin object { $originforcontact = $this->origin; @@ -483,7 +484,7 @@ class Facture extends CommonInvoice $exp = new Expedition($this->db); $exp->fetch($this->origin_id); $exp->fetchObjectLinked(); - if (count($exp->linkedObjectsIds['commande']) > 0) + if (count($exp->linkedObjectsIds['commande']) > 0) { foreach ($exp->linkedObjectsIds['commande'] as $key => $value) { @@ -493,10 +494,10 @@ class Facture extends CommonInvoice } } } - + $sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc"; $sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'"; - + $resqlcontact = $this->db->query($sqlcontact); if ($resqlcontact) { @@ -555,11 +556,11 @@ class Facture extends CommonInvoice foreach ($this->lines as $i => $val) { $line = $this->lines[$i]; - + // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array //if (! is_object($line)) $line=json_decode(json_encode($line), FALSE); // convert recursively array into object. if (! is_object($line)) $line = (object) $line; - + if (($line->info_bits & 0x01) == 0) // We keep only lines with first bit = 0 { // Reset fk_parent_line for no child products and special product @@ -1060,7 +1061,7 @@ class Facture extends CommonInvoice if ($this->type == self::TYPE_CREDIT_NOTE) $picto.='a'; // Credit note if ($this->type == self::TYPE_DEPOSIT) $picto.='d'; // Deposit invoice $label=''; - + if ($user->rights->facture->lire) { $label = '<u>' . $langs->trans("ShowInvoice") . '</u>'; if (! empty($this->ref)) @@ -1079,7 +1080,7 @@ class Facture extends CommonInvoice if ($this->type == self::TYPE_SITUATION) $label=$langs->transnoentitiesnoconv("ShowInvoiceSituation").': '.$this->ref; if ($moretitle) $label.=' - '.$moretitle; } - + $linkclose=''; if (empty($notooltip) && $user->rights->facture->lire) { @@ -1113,7 +1114,7 @@ class Facture extends CommonInvoice $result.='</span>'; } } - + return $result; } @@ -1321,7 +1322,7 @@ class Facture extends CommonInvoice $line->qty = $objp->qty; $line->subprice = $objp->subprice; - $line->vat_src_code = $objp->vat_src_code; + $line->vat_src_code = $objp->vat_src_code; $line->tva_tx = $objp->tva_tx; $line->localtax1_tx = $objp->localtax1_tx; $line->localtax2_tx = $objp->localtax2_tx; @@ -1574,7 +1575,7 @@ class Facture extends CommonInvoice $arraytmp=$formmargin->getMarginInfosArray($srcinvoice, false); $facligne->pa_ht = $arraytmp['pa_total']; } - + $facligne->total_ht = -$remise->amount_ht; $facligne->total_tva = -$remise->amount_tva; $facligne->total_ttc = -$remise->amount_ttc; @@ -1628,7 +1629,7 @@ class Facture extends CommonInvoice function set_ref_client($ref_client, $notrigger=0) { global $user; - + $error=0; $this->db->begin(); @@ -2457,7 +2458,7 @@ class Facture extends CommonInvoice if (! isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '') $situation_percent = 100; $localtaxes_type=getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc); - + // Clean vat code $vat_src_code=''; if (preg_match('/\((.*)\)/', $txtva, $reg)) @@ -2465,7 +2466,7 @@ class Facture extends CommonInvoice $vat_src_code = $reg[1]; $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. } - + $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu_ht=price2num($pu_ht); @@ -2650,7 +2651,7 @@ class Facture extends CommonInvoice * @param double $pu_ht_devise Unit price in currency * @return int < 0 if KO, > 0 if OK */ - function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type= self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $situation_percent=0, $fk_unit = null, $pu_ht_devise = 0) + function updateline($rowid, $desc, $pu, $qty, $remise_percent, $date_start, $date_end, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type= self::TYPE_STANDARD, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $situation_percent=100, $fk_unit = null, $pu_ht_devise = 0) { global $conf,$user; // Deprecation warning @@ -2770,14 +2771,14 @@ class Facture extends CommonInvoice $this->line->label = $label; $this->line->desc = $desc; $this->line->qty = ($this->type==self::TYPE_CREDIT_NOTE?abs($qty):$qty); // For credit note, quantity is always positive and unit price negative - + $this->line->vat_src_code = $vat_src_code; $this->line->tva_tx = $txtva; $this->line->localtax1_tx = $txlocaltax1; $this->line->localtax2_tx = $txlocaltax2; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; - + $this->line->remise_percent = $remise_percent; $this->line->subprice = ($this->type==2?-abs($pu_ht):$pu_ht); // For credit note, unit price always negative, always positive otherwise $this->line->date_start = $date_start; @@ -2896,7 +2897,7 @@ class Facture extends CommonInvoice function deleteline($rowid) { global $user; - + dol_syslog(get_class($this)."::deleteline rowid=".$rowid, LOG_DEBUG); if (! $this->brouillon) @@ -2922,13 +2923,13 @@ class Facture extends CommonInvoice } $line=new FactureLigne($this->db); - + $line->context = $this->context; // For triggers $result = $line->fetch($rowid); if (! ($result > 0)) dol_print_error($db, $line->error, $line->errors); - + if ($line->delete($user) > 0) { $result=$this->update_price(1); @@ -4292,7 +4293,7 @@ class FactureLigne extends CommonInvoiceLine $this->fk_unit = $objp->fk_unit; $this->fk_user_modif = $objp->fk_user_modif; $this->fk_user_author = $objp->fk_user_author; - + $this->situation_percent = $objp->situation_percent; $this->fk_prev_id = $objp->fk_prev_id; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 90ba6a2243126ec02118ac3f97f12061009aab91..ab04278ea846e6f21242cf0800073d2c7908b307 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -252,7 +252,7 @@ class BonPrelevement extends CommonObject function getErrorString($error) { global $langs; - + $errors = array(); $errors[1027] = $langs->trans("DateInvalid"); @@ -813,7 +813,7 @@ class BonPrelevement extends CommonObject dol_syslog(__METHOD__."::Read invoices error ".$this->db->error(), LOG_ERR); } } - + if (! $error) { require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php'; @@ -834,7 +834,7 @@ class BonPrelevement extends CommonObject { $bac = new CompanyBankAccount($this->db); $bac->fetch(0,$soc->id); - + if ($bac->verif() >= 1) //if (true) { @@ -867,7 +867,7 @@ class BonPrelevement extends CommonObject } $ok=0; - + // Withdraw invoices in factures_prev array $out=count($factures_prev)." invoices will be withdrawn."; //print $out."\n"; @@ -920,7 +920,7 @@ class BonPrelevement extends CommonObject $dir=$conf->prelevement->dir_output.'/receipts'; if (! is_dir($dir)) dol_mkdir($dir); - + $this->filename = $dir.'/'.$ref.'.xml'; // Create withdraw receipt in database @@ -1028,7 +1028,7 @@ class BonPrelevement extends CommonObject $this->emetteur_bic = $account->bic; $this->emetteur_ics = $conf->global->PRELEVEMENT_ICS; // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456"; - + $this->raison_sociale = $account->proprio; } @@ -1272,16 +1272,6 @@ class BonPrelevement extends CommonObject * section Debiteur (sepa Debiteurs bloc lines) */ - /*$tmp_invoices = array(); - - $sql = "SELECT f.facnumber as fac FROM ".MAIN_DB_PREFIX."prelevement_lignes as pl, ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."prelevement_facture as pf, ".MAIN_DB_PREFIX."societe as soc, ".MAIN_DB_PREFIX."c_country as p, ".MAIN_DB_PREFIX."societe_rib as rib WHERE pl.fk_prelevement_bons = ".$this->id." AND pl.rowid = pf.fk_prelevement_lignes AND pf.fk_facture = f.rowid AND soc.fk_pays = p.rowid AND soc.rowid = f.fk_soc AND rib.fk_soc = f.fk_soc AND rib.default_rib = 1"; - $resql=$this->db->query($sql); - if ($resql) { - while ($objfac = $this->db->fetch_object($resql)) { - $tmp_invoices[] = $objfac->fac; - } - }*/ - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; $sql.= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; $sql.= " f.facnumber as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum"; @@ -1365,35 +1355,6 @@ class BonPrelevement extends CommonObject fputs($this->file, ' </PmtInf>'.$CrLf); fputs($this->file, ' </CstmrDrctDbtInitn>'.$CrLf); fputs($this->file, '</Document>'.$CrLf); - - /*$sql = "SELECT pl.amount"; - $sql.= " FROM"; - $sql.= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql.= " ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; - $sql.= " WHERE pl.fk_prelevement_bons = ".$this->id; - $sql.= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql.= " AND pf.fk_facture = f.rowid"; - - //Lines - $i = 0; - $resql=$this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $this->total = $this->total + $obj->amount; - $i++; - } - } - else - { - $result = -2; - }*/ - } // Build file for Other Countries with unknow format @@ -1580,11 +1541,11 @@ class BonPrelevement extends CommonObject $XML_DEBITOR .=' </FinInstnId>'.$CrLf; $XML_DEBITOR .=' </DbtrAgt>'.$CrLf; $XML_DEBITOR .=' <Dbtr>'.$CrLf; - $XML_DEBITOR .=' <Nm>'.strtoupper(dol_string_unaccent($row_nom)).'</Nm>'.$CrLf; + $XML_DEBITOR .=' <Nm>'.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).'</Nm>'.$CrLf; $XML_DEBITOR .=' <PstlAdr>'.$CrLf; $XML_DEBITOR .=' <Ctry>'.$row_country_code.'</Ctry>'.$CrLf; - $XML_DEBITOR .=' <AdrLine>'.dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))).'</AdrLine>'.$CrLf; - $XML_DEBITOR .=' <AdrLine>'.dol_string_unaccent($row_zip.' '.$row_town).'</AdrLine>'.$CrLf; + $XML_DEBITOR .=' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))),70,'right','UTF-8',true)).'</AdrLine>'.$CrLf; + $XML_DEBITOR .=' <AdrLine>'.dolEscapeXML(dol_string_unaccent($row_zip.' '.$row_town)).'</AdrLine>'.$CrLf; $XML_DEBITOR .=' </PstlAdr>'.$CrLf; $XML_DEBITOR .=' </Dbtr>'.$CrLf; $XML_DEBITOR .=' <DbtrAcct>'.$CrLf; @@ -1679,7 +1640,7 @@ class BonPrelevement extends CommonObject * @return string String with SEPA Sender */ function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf='\n') - { + { // SEPA INITIALISATION global $conf; @@ -1698,12 +1659,12 @@ class BonPrelevement extends CommonObject $this->emetteur_number_key = $account->cle_rib; $this->emetteur_iban = $account->iban; $this->emetteur_bic = $account->bic; - + $this->emetteur_ics = $conf->global->PRELEVEMENT_ICS; // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456"; - + $this->raison_sociale = $account->proprio; } - + // Récupération info demandeur $sql = "SELECT rowid, ref"; $sql.= " FROM"; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index db6464edb6ae955474a8be8b9e6ddb4242d86db2..8b9b0dd0c7564d4053326343caa4b7a7050830cc 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -46,7 +46,7 @@ class Contrat extends CommonObject public $fk_element='fk_contrat'; protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $picto='contract'; - + /** * {@inheritdoc} */ @@ -530,7 +530,7 @@ class Contrat extends CommonObject $this->fin_validite = $this->db->jdate($result["fin_validite"]); $this->date_cloture = $this->db->jdate($result["date_cloture"]); - + $this->user_author_id = $result["fk_user_author"]; $this->commercial_signature_id = $result["fk_commercial_signature"]; @@ -613,7 +613,7 @@ class Contrat extends CommonObject $this->lines=array(); $pos = 0; - + // Selectionne les lignes contrats liees a un produit $sql = "SELECT p.label as product_label, p.description as product_desc, p.ref as product_ref,"; $sql.= " d.rowid, d.fk_contrat, d.statut, d.description, d.price_ht, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.remise_percent, d.subprice, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht,"; @@ -1858,7 +1858,7 @@ class Contrat extends CommonObject $url = DOL_URL_ROOT.'/contrat/card.php?id='.$this->id; $picto = 'contract'; $label = ''; - + if ($user->rights->contrat->lire) { $label = '<u>'.$langs->trans("ShowContract").'</u>'; $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref; @@ -1874,7 +1874,7 @@ class Contrat extends CommonObject $label .= '<br><b>'.$langs->trans('AmountTTC').':</b> '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); } } - + $linkclose=''; if (empty($notooltip) && $user->rights->contrat->lire) { @@ -1890,7 +1890,7 @@ class Contrat extends CommonObject $linkstart = '<a href="'.$url.'"'; $linkstart.=$linkclose.'>'; $linkend='</a>'; - + if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); if ($withpicto && $withpicto != 2) $result.=' '; $result.=$linkstart.$this->ref.$linkend; @@ -2225,7 +2225,11 @@ class Contrat extends CommonObject $line->total_ht=90; $line->total_ttc=107.64; // 90 * 1.196 $line->total_tva=17.64; - if ($num_prods > 0) + $line->date_ouverture = dol_now() - 200000; + $line->date_ouverture_prevue = dol_now() - 500000; + $line->date_fin_validite = dol_now() + 500000; + $line->date_cloture = dol_now() - 100000; + if ($num_prods > 0) { $prodid = mt_rand(1, $num_prods); $line->fk_product=$prodids[$prodid]; @@ -2233,11 +2237,6 @@ class Contrat extends CommonObject $this->lines[$xnbp]=$line; $xnbp++; } - - $this->amount_ht = $xnbp*100; - $this->total_ht = $xnbp*100; - $this->total_tva = $xnbp*19.6; - $this->total_ttc = $xnbp*119.6; } /** @@ -2750,6 +2749,8 @@ class ContratLigne extends CommonObjectLine if (empty($this->total_ht)) $this->total_ht = 0; if (empty($this->total_tva)) $this->total_tva = 0; if (empty($this->total_ttc)) $this->total_ttc = 0; + if (empty($this->localtax1_tx)) $this->localtax1_tx = 0; + if (empty($this->localtax2_tx)) $this->localtax2_tx = 0; // Check parameters // Put here code to add control on parameters values diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 92d1011b92350f3c97313402984a5e871b9bd44c..fde828fd6d498af48327111ebe4a2b3d6d591eef 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -24,20 +24,22 @@ // $massaction must be defined // $objectclass and $$objectlabel must be defined -// $uploaddir (example $conf->projet->dir_output . "/";) +// $parameters, $object, $action must be defined for the hook. + +// $uploaddir may be defined (example to $conf->projet->dir_output."/";) // $toselect may be defined // Protection -if (empty($objectclass) || empty($uploaddir)) +if (empty($objectclass) || empty($uploaddir)) { dol_print_error(null, 'include of actions_massactions.inc.php is done but var $massaction or $objectclass or $uploaddir was not defined'); exit; } -// Mass actions. Controls on number of lines checked -$maxformassaction=1000; +// Mass actions. Controls on number of lines checked. +$maxformassaction=(empty($conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS)?1000:$conf->global->MAIN_LIMIT_FOR_MASS_ACTIONS); if (! empty($massaction) && count($toselect) < 1) { $error++; @@ -87,7 +89,7 @@ if (! $error && $massaction == 'confirm_presend') } } //var_dump($listofobjectthirdparties);exit; - + foreach ($listofobjectthirdparties as $thirdpartyid) { $result = $thirdparty->fetch($thirdpartyid); @@ -144,7 +146,7 @@ if (! $error && $massaction == 'confirm_presend') { //var_dump($object); //var_dump($thirdpartyid.' - '.$objectid.' - '.$object->statut); - + if ($objectclass == 'Facture' && $object->statut != Facture::STATUS_VALIDATED) { $nbignored++; @@ -157,7 +159,7 @@ if (! $error && $massaction == 'confirm_presend') $resaction.='<div class="error">'.$langs->trans('ErrorOnlyOrderNotDraftCanBeSentInMassAction',$object->ref).'</div><br>'; continue; } - + // Read document // TODO Use future field $object->fullpathdoc to know where is stored default file // TODO If not defined, use $object->modelpdf (or defaut invoice config) to know what is template to use to regenerate doc. @@ -202,7 +204,7 @@ if (! $error && $massaction == 'confirm_presend') dol_syslog('Failed to read file: '.$file, LOG_WARNING); continue; } - + //var_dump($listofqualifiedref); } @@ -252,9 +254,9 @@ if (! $error && $massaction == 'confirm_presend') $filepath = $attachedfiles['paths']; $filename = $attachedfiles['names']; $mimetype = $attachedfiles['mimes']; - + //var_dump($filepath); - + // Send mail require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'); $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1); @@ -280,7 +282,7 @@ if (! $error && $massaction == 'confirm_presend') if ($objectclass == 'Supplier_Proposal') $actiontypecode='AC_SUP_PRO'; if ($objectclass == 'CommandeFournisseur') $actiontypecode='AC_SUP_ORD'; if ($objectclass == 'FactureFournisseur') $actiontypecode='AC_SUP_INV';*/ - + $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto; if ($message) { @@ -290,7 +292,7 @@ if (! $error && $massaction == 'confirm_presend') $actionmsg = dol_concatdesc($actionmsg, $message); } $actionmsg2=''; - + // Initialisation donnees $object->sendtoid = 0; $object->actionmsg = $actionmsg; // Long text @@ -335,7 +337,7 @@ if (! $error && $massaction == 'confirm_presend') $resaction.=$langs->trans("NbSelected").': '.count($toselect)."\n<br>"; $resaction.=$langs->trans("NbIgnored").': '.($nbignored?$nbignored:0)."\n<br>"; $resaction.=$langs->trans("NbSent").': '.($nbsent?$nbsent:0)."\n<br>"; - + if ($nbsent) { $action=''; // Do not show form post if there was at least one successfull sent @@ -359,7 +361,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - + $objecttmp=new $objectclass($db); $listofobjectid=array(); $listofobjectthirdparties=array(); @@ -425,21 +427,21 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se if (count($files)>0) { - + $now=dol_now(); $file=$diroutputmassaction.'/'.$filename.'_'.dol_print_date($now,'dayhourlog').'.pdf'; - + $input_files = ''; foreach($files as $f) { $input_files.=' '.escapeshellarg($f); } - + $cmd = 'pdftk '.$input_files.' cat output '.escapeshellarg($file); exec($cmd); - + if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); - + $langs->load("exports"); setEventMessages($langs->trans('FileSuccessfullyBuilt',$filename.'_'.dol_print_date($now,'dayhourlog')), null, 'mesgs'); } @@ -447,7 +449,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se { setEventMessages($langs->trans('NoPDFAvailableForDocGenAmongChecked'), null, 'errors'); } - + } else { // Create empty PDF @@ -481,7 +483,7 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se // Defined name of merged file $filename=strtolower(dol_sanitizeFileName($langs->transnoentities($objectlabel))); $filename=preg_replace('/\s/','_',$filename); - + // Save merged file if ($filter=='paye:0') { @@ -565,6 +567,11 @@ if (! $error && $massaction == 'delete' && $permtodelete) //var_dump($listofobjectthirdparties);exit; } +$parameters['toselect']=$toselect; +$parameters['uploaddir']=$uploaddir; + +$reshook=$hookmanager->executeHooks('doMassActions',$parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); diff --git a/htdocs/core/actions_setmoduleoptions.inc.php b/htdocs/core/actions_setmoduleoptions.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..03b33b19eb1d525d3da78db44c196cb4804b3be3 --- /dev/null +++ b/htdocs/core/actions_setmoduleoptions.inc.php @@ -0,0 +1,86 @@ +<?php +/* Copyright (C) 2014 Laurent Destailleur <eldy@users.sourceforge.net> + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/actions_setnotes.inc.php + * \brief Code for actions on setting notes of object page + */ + + +// $action must be defined +// $_FILES may be defined +// $nomessageinsetmoduleoptions can be set to 1 + +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') +{ + $db->begin(); + + // Process common param fields + foreach($_POST as $key => $val) + { + if (preg_match('/^param(\d*)$/', $key, $reg)) // Works for POST['param'], POST['param1'], POST['param2'], ... + { + $param=GETPOST("param".$reg[1],'alpha'); + $value=GETPOST("value".$reg[1],'alpha'); + if ($param) + { + $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + } + } + + // Process upload fields + if (GETPOST('upload','alpha') && GETPOST('keyforuploaddir','aZ09')) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $keyforuploaddir=GETPOST('keyforuploaddir','aZ09'); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->$keyforuploaddir))); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $upload_dir=$tmpdir; + } + } + if ($upload_dir) + { + $result = dol_add_file_process($upload_dir, 0, 1, 'uploadfile', ''); + if ($result <= 0) $error++; + } + } + + if (! $error) + { + $db->commit(); + if (empty($nomessageinsetmoduleoptions)) setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + $db->rollback(); + if (empty($nomessageinsetmoduleoptions)) setEventMessages($langs->trans("SetupNotSaved"), null, 'errors'); + } +} + diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index c89fc5937454e99385edaf59b0c77b3aaad9e1b2..bd1daca8886a7d042dde3dc556060d87dd865851 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1681,7 +1681,7 @@ class ExtraFields // Clean parameters $value_key=dol_mktime($_POST[$keysuffix."options_".$key.$keyprefix."hour"], $_POST[$keysuffix."options_".$key.$keyprefix."min"], 0, $_POST[$keysuffix."options_".$key.$keyprefix."month"], $_POST[$keysuffix."options_".$key.$keyprefix."day"], $_POST[$keysuffix."options_".$key.$keyprefix."year"]); } - else if (in_array($key_type,array('checkbox'))) + else if (in_array($key_type,array('checkbox', 'chkbxlst'))) { $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix); // Make sure we get an array even if there's only one checkbox diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 590f806029666983d9efd24dff7ca8bc54ce3fd6..40ed41530608e1f68f9654a89cd98502fb5186b0 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -133,11 +133,14 @@ class HookManager if (in_array( $method, array( - 'addMoreActionsButtons', + 'addCalendarChoice', + 'addMoreActionsButtons', + 'addMoreMassActions', 'addSearchEntry', 'addStatisticLine', - 'deleteFile', + 'deleteFile', 'doActions', + 'doMassActions', 'formCreateThirdpartyOptions', 'formObjectOptions', 'formattachOptions', @@ -169,7 +172,6 @@ class HookManager 'printSearchForm', 'printTabsHead', 'formatEvent', - 'addCalendarChoice', 'printObjectLine', 'printObjectSubLine', 'createDictionaryFieldList', @@ -181,14 +183,16 @@ class HookManager if ($method == 'insertExtraFields') { - $hooktype='returnvalue'; // deprecated. TODO Remove all code with "executeHooks('insertExtraFields'" as soon as there is a trigger available. + $hooktype='returnvalue'; // @deprecated. TODO Remove all code with "executeHooks('insertExtraFields'" as soon as there is a trigger available. dol_syslog("Warning: The hook 'insertExtraFields' is deprecated and must not be used. Use instead trigger on CRUD event (ask it to dev team if not implemented)", LOG_WARNING); } + // Init return properties + $this->resPrint=''; $this->resArray=array(); + // Loop on each hook to qualify modules that have declared context $modulealreadyexecuted=array(); $resaction=0; $error=0; $result=''; - $this->resPrint=''; $this->resArray=array(); foreach($this->hooks as $context => $modules) // $this->hooks is an array with context as key and value is an array of modules that handle this context { if (! empty($modules)) @@ -202,9 +206,9 @@ class HookManager // test to avoid running twice a hook, when a module implements several active contexts if (in_array($module,$modulealreadyexecuted)) continue; - + dol_syslog(get_class($this).'::executeHooks a qualified hook was found for method='.$method.' module='.$module." action=".$action." context=".$context); - + $modulealreadyexecuted[$module]=$module; // Use the $currentcontext in method to avoid running twice // Clean class (an error may have been set from a previous call of another method for same module/hook) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index cf6ae18f568e3c1d318f3b0da737b9219bc58998..b14f72a1b7bb5c011dcf5a22c82625b44f9eadc3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -545,11 +545,20 @@ class Form $disabled=0; $ret='<div class="centpercent center">'; $ret.='<select data-role="none" class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>'; - $ret.='<option value="0"'.($disabled?' disabled="disabled"':'').'>-- '.$langs->trans("SelectAction").' --</option>'; - foreach($arrayofaction as $code => $label) - { - $ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>'; - } + + // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks. + $parameters=array(); + $reshook=$hookmanager->executeHooks('addMoreMassActions',$parameters); // Note that $action and $object may have been modified by hook + if (empty($reshook)) + { + $ret.='<option value="0"'.($disabled?' disabled="disabled"':'').'>-- '.$langs->trans("SelectAction").' --</option>'; + foreach($arrayofaction as $code => $label) + { + $ret.='<option value="'.$code.'"'.($disabled?' disabled="disabled"':'').'>'.$label.'</option>'; + } + } + $ret.=$hookmanager->resPrint; + $ret.='</select>'; // Warning: if you set submit button to disabled, post using 'Enter' will no more work. $ret.='<input type="submit" data-role="none" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; @@ -1391,7 +1400,7 @@ class Form * @deprecated * @see select_dolusers() */ - function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude='',$disabled=0,$include='',$enableonly='',$force_entity=0) + function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity=0) { print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity); } @@ -1411,13 +1420,13 @@ class Form * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status * @param string $morefilter Add more filters into sql request * @param integer $show_every 0=default list, 1=add also a value "Everybody" at beginning of list - * @param string $enableonlytext If option $enableonly is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. + * @param string $enableonlytext If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. * @param string $morecss More css * @param int $noactive Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). * @return string HTML select string * @see select_dolgroups */ - function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0) + function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0) { global $conf,$user,$langs; @@ -1613,7 +1622,7 @@ class Form * @return string HTML select string * @see select_dolgroups */ - function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='') + function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity=0, $maxlength=0, $showstatus=0, $morefilter='') { global $conf,$user,$langs; diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index bcff0981a70627c96d949350a7b797f08fbb212b..88ebb816a315b0613a071cea750cbaf9e9927efd 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -358,7 +358,7 @@ class FormCompany * * @param string $selected Title preselected * @param string $htmlname Name of HTML select combo field - * @param string $morecss Add more css on SELECT element + * @param string $morecss Add more css on SELECT element * @return string String with HTML select */ function select_civility($selected='',$htmlname='civility_id',$morecss='maxwidth100') @@ -563,11 +563,11 @@ class FormCompany $events=array(); // Add an entry 'method' to say 'yes, we must execute url with param action = method'; // Add an entry 'url' to say which url to execute - // Add an entry htmlname to say which element we must change once url is called - // Add entry params => array('cssid' => 'attr') to say to remov or add attribute attr if answer of url return 0 or >0 lines + // Add an entry htmlname to say which element we must change once url is called + // Add entry params => array('cssid' => 'attr') to say to remov or add attribute attr if answer of url return 0 or >0 lines // To refresh contacts list on thirdparty list change $events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled')); - + if (count($events)) // If there is some ajax events to run once selection is done, we add code here to run events { print '<script type="text/javascript"> @@ -583,7 +583,7 @@ class FormCompany /* Clean contact */ $("div#s2id_contactid>a>span").html(\'\'); }); - + // Function used to execute events when search_htmlname change function runJsCodeForEvent'.$htmlname.'(obj) { var id = $("#'.$htmlname.'").val(); @@ -693,16 +693,17 @@ class FormCompany * @param string $source Source ('internal' or 'external') * @param string $sortorder Sort criteria ('position', 'code', ...) * @param int $showempty 1=Add en empty line + * @param string $morecss Add more css to select component * @return void */ - function selectTypeContact($object, $selected, $htmlname = 'type', $source='internal', $sortorder='position', $showempty=0) + function selectTypeContact($object, $selected, $htmlname = 'type', $source='internal', $sortorder='position', $showempty=0, $morecss='') { global $user, $langs; - + if (is_object($object) && method_exists($object, 'liste_type_contact')) { $lesTypes = $object->liste_type_contact($source, $sortorder, 0, 1); - print '<select class="flat valignmiddle" name="'.$htmlname.'" id="'.$htmlname.'">'; + print '<select class="flat valignmiddle'.($morecss?' '.$morecss:'').'" name="'.$htmlname.'" id="'.$htmlname.'">'; if ($showempty) print '<option value="0"></option>'; foreach($lesTypes as $key=>$value) { @@ -791,7 +792,7 @@ class FormCompany $maxlength=$formlength; if (empty($formlength)) { $formlength=24; $maxlength=128; } - + $out = '<input type="text" '.($morecss?'class="'.$morecss.'" ':'').'name="'.$htmlname.'" id="'.$htmlname.'" maxlength="'.$maxlength.'" value="'.$selected.'">'; return $out; diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index 304814971634777b66bd2644cb7dc6a08f7210c8..93ebbf71ddd18b4c32e713154656684891fac100 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -68,7 +68,7 @@ class FormProjets global $langs,$conf,$form; $out=''; - + if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_SEARCH_TO_SELECT)) { $placeholder=''; @@ -92,7 +92,7 @@ class FormProjets else { $out.=$this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, $discard_closed, $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid); - if ($discard_closed) + if ($discard_closed) { if (class_exists('Form')) { @@ -101,8 +101,8 @@ class FormProjets } } } - - if (empty($nooutput)) + + if (empty($nooutput)) { print $out; return ''; @@ -136,10 +136,10 @@ class FormProjets require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (empty($htmlid)) $htmlid = $htmlname; - + $out=''; $outarray=array(); - + $hideunselectables = false; if (! empty($conf->global->PROJECT_HIDE_UNSELECTABLES)) $hideunselectables = true; @@ -170,21 +170,19 @@ class FormProjets $resql=$this->db->query($sql); if ($resql) { - $minmax='maxwidth500'; + $morecss='maxwidth500'; // Use select2 selector - $nodatarole=''; if (! empty($conf->use_javascript_ajax)) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlid, array(), 0, $forcefocus); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); - $minmax='minwidth100 maxwidth300'; + $morecss='minwidth100 maxwidth300'; } if (empty($option_only)) { - $out.= '<select class="flat'.($minmax?' '.$minmax:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlid.'" name="'.$htmlname.'"'.$nodatarole.'>'; + $out.= '<select class="flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlid.'" name="'.$htmlname.'">'; } if (!empty($show_empty)) { $out.= '<option value="0"> </option>'; @@ -213,12 +211,12 @@ class FormProjets //if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')'; //else $labeltoshow.=' ('.$langs->trans("Private").')'; $labeltoshow.=', '.dol_trunc($obj->title, $maxlength); - if ($obj->name) + if ($obj->name) { $labeltoshow.=' - '.$obj->name; if ($obj->name_alias) $labeltoshow.=' ('.$obj->name_alias.')'; } - + $disabled=0; if ($obj->fk_statut == 0) { @@ -277,7 +275,7 @@ class FormProjets if (!$mode) { if (empty($option_only)) $out.= '</select>'; - if (empty($nooutput)) + if (empty($nooutput)) { print $out; return ''; @@ -302,13 +300,14 @@ class FormProjets * @param string $htmlname Name of HTML select * @param int $maxlength Maximum length of label * @param int $option_only Return only html options lines without the select tag - * @param int $show_empty Add an empty line + * @param string $show_empty Add an empty line ('1' or string to show for empty line) * @param int $discard_closed Discard closed projects (0=Keep,1=hide completely,2=Disable) * @param int $forcefocus Force focus on field (works with javascript only) * @param int $disabled Disabled + * @param string $morecss More css added to the select component * @return int Nbr of project if OK, <0 if KO */ - function selectTasks($socid=-1, $selected='', $htmlname='taskid', $maxlength=24, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0) + function selectTasks($socid=-1, $selected='', $htmlname='taskid', $maxlength=24, $option_only=0, $show_empty='1', $discard_closed=0, $forcefocus=0, $disabled=0, $morecss='maxwidth500') { global $user,$conf,$langs; @@ -339,28 +338,26 @@ class FormProjets if ($socid > 0) $sql.= " AND (p.fk_soc=".$socid." OR p.fk_soc IS NULL)"; $sql.= " ORDER BY p.ref, t.ref ASC"; - dol_syslog(__METHOD__, LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { - $minmax='maxwidth500'; - // Use select2 selector - $nodatarole=''; if (! empty($conf->use_javascript_ajax)) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname, '', 0, $forcefocus); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); - $minmax='minwidth200 maxwidth500'; + $morecss='minwidth200 maxwidth500'; } if (empty($option_only)) { - $out.= '<select class="valignmiddle flat'.($minmax?' '.$minmax:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlname.'" name="'.$htmlname.'"'.$nodatarole.'>'; + $out.= '<select class="valignmiddle flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled="disabled"':'').' id="'.$htmlname.'" name="'.$htmlname.'">'; } - if (!empty($show_empty)) { - $out.= '<option value="0"> </option>'; + if (! empty($show_empty)) { + $out.= '<option value="0" class="optiongrey">'; + if (! is_numeric($show_empty)) $out.=$show_empty; + else $out.=' '; + $out.= '</option>'; } $num = $this->db->num_rows($resql); $i = 0; @@ -370,7 +367,7 @@ class FormProjets { $obj = $this->db->fetch_object($resql); // If we ask to filter on a company and user has no permission to see all companies and project is linked to another company, we hide project. - if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && ! $user->rights->societe->lire) + if ($socid > 0 && (empty($obj->fk_soc) || $obj->fk_soc == $socid) && empty($user->rights->societe->lire)) { // Do nothing } @@ -382,7 +379,7 @@ class FormProjets continue; } - $labeltoshow=dol_trunc($obj->ref,18); + $labeltoshow=dol_trunc($obj->ref,18); // Project ref //if ($obj->public) $labeltoshow.=' ('.$langs->trans("SharedProject").')'; //else $labeltoshow.=' ('.$langs->trans("Private").')'; $labeltoshow.=' '.dol_trunc($obj->title,$maxlength); @@ -532,7 +529,6 @@ class FormProjets $sql.= " ORDER BY ref DESC"; dol_syslog(get_class($this).'::select_element', LOG_DEBUG); - $resql=$this->db->query($sql); if ($resql) { diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php index cd4a56f417430022266ffd8082af923ecb86acf1..625b30e3ac22a4fbcdbcbdd497aa14fd85a63124 100644 --- a/htdocs/core/class/interfaces.class.php +++ b/htdocs/core/class/interfaces.class.php @@ -76,14 +76,14 @@ class Interfaces global $db; $user = new User($db); } - + $nbfile = $nbtotal = $nbok = $nbko = 0; $files = array(); $modules = array(); $orders = array(); $i=0; - + $dirtriggers=array_merge(array('/core/triggers'),$conf->modules_parts['triggers']); foreach($dirtriggers as $reldir) { @@ -106,7 +106,7 @@ class Interfaces $part3=$reg[3]; $nbfile++; - + // Check if trigger file is disabled by name if (preg_match('/NORUN$/i',$file)) continue; // Check if trigger file is for a particular module @@ -132,7 +132,7 @@ class Interfaces dol_syslog(get_class($this)."::run_triggers action=".$action." ".$langs->trans("ErrorDuplicateTrigger", $newdir."/".$file, $fullpathfiles[$modName]), LOG_WARNING); continue; } - + try { //print 'Todo for '.$modName." : ".$newdir.'/'.$file."\n"; include_once $newdir.'/'.$file; @@ -142,7 +142,7 @@ class Interfaces { dol_syslog('ko for '.$modName." ".$e->getMessage()."\n", LOG_ERR); } - + $modules[$i] = $modName; $files[$i] = $file; $fullpathfiles[$modName] = $newdir.'/'.$file; @@ -155,7 +155,7 @@ class Interfaces } asort($orders); - + // Loop on each trigger foreach ($orders as $key => $value) { @@ -246,7 +246,7 @@ class Interfaces { $dirtriggers=$forcedirtriggers; } - + foreach($dirtriggers as $reldir) { $dir=dol_buildpath($reldir,0); diff --git a/htdocs/core/js/timesheet.js b/htdocs/core/js/timesheet.js index ea0e07827677cafa31a268f1a3ac359a928fd945..5541f348c9fb6699f1aaec0f4e6e2ae3f7d5e250 100644 --- a/htdocs/core/js/timesheet.js +++ b/htdocs/core/js/timesheet.js @@ -1,5 +1,5 @@ -/* Copyright (C) 2014 delcroip <delcroip@gmail.com> - * Laurent Destailleur 2015 <eldy@users.sourceforge.net> +/* Copyright (C) 2014 delcroip <delcroip@gmail.com> + * Copyright (C) 2015-2017 Laurent Destailleur <eldy@users.sourceforge.net> * * 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 diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 95fca68aa5d0ab91b6321e677e6a8d29541362b1..85aace9db0b4a597a09bd4afc1140b68e0640bc4 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -44,7 +44,7 @@ function dol_basename($pathfile) * @param string $path Starting path from which to search. This is a full path. * @param string $types Can be "directories", "files", or "all" * @param int $recursive Determines whether subdirectories are searched - * @param string $filter Regex filter to restrict list. This regex value must be escaped for '/' by doing preg_quote($var,'/'), since this char is used for preg_match function, + * @param string $filter Regex filter to restrict list. This regex value must be escaped for '/' by doing preg_quote($var,'/'), since this char is used for preg_match function, * but must not contains the start and end '/'. Filter is checked into basename only. * @param array $excludefilter Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). Exclude is checked into fullpath. * @param string $sortcriteria Sort criteria ("","fullname","name","date","size") @@ -71,9 +71,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil $reshook = 0; $file_list = array(); - + $hookmanager->resArray=array(); - + if (! $nohook) { $hookmanager->initHooks(array('fileslib')); @@ -196,9 +196,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil } } } - + $file_list = array_merge($file_list, $hookmanager->resArray); - + return $file_list; } @@ -219,7 +219,7 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0) { global $conf, $db; - + $sql=" SELECT rowid, label, entity, filename, filepath, fullpath_orig, keywords, cover, gen_or_uploaded, extraparams, date_c, date_m, fk_user_c, fk_user_m, acl, position"; if ($mode) $sql.=", description"; $sql.=" FROM ".MAIN_DB_PREFIX."ecm_files"; @@ -234,7 +234,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc $i = 0; while ($i < $num) { - $obj = $db->fetch_object($resql); + $obj = $db->fetch_object($resql); if ($obj) { preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); @@ -258,7 +258,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc } $i++; } - + // Obtain a list of columns if (! empty($sortcriteria)) { @@ -270,7 +270,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc // Sort the data if ($sortorder) array_multisort($myarray, $sortorder, $file_list); } - + return $file_list; } else @@ -279,7 +279,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc return array(); } } - + /** * Fast compare of 2 files identified by their properties ->name, ->date and ->size @@ -460,10 +460,10 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, if (empty($srcfile)) return -1; if (empty($destfile)) $destfile=$srcfile; - + $destexists=dol_is_file($destfile); if (($destfile != $srcfile) && $destexists) return 0; - + $tmpdestfile=$destfile.'.tmp'; $newpathofsrcfile=dol_osencode($srcfile); @@ -481,17 +481,17 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, dol_syslog("files.lib.php::dolReplaceInFile failed Permission denied to write into target directory ".$newdirdestfile, LOG_WARNING); return -2; } - + dol_delete_file($tmpdestfile); - + // Create $newpathoftmpdestfile from $newpathofsrcfile $content=file_get_contents($newpathofsrcfile, 'r'); - + $content = make_substitutions($content, $arrayreplacement, null); - + file_put_contents($newpathoftmpdestfile, $content); @chmod($newpathoftmpdestfile, octdec($newmask)); - + // Rename $result=dol_move($newpathoftmpdestfile, $newpathofdestfile, $newmask, (($destfile == $srcfile)?1:0), 0, $indexdatabase); if (! $result) @@ -589,7 +589,7 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep $destexists=dol_is_dir($destfile); //if (! $overwriteifexists && $destexists) return 0; // The overwriteifexists is for files only, so propagated to dol_copy only. - + if (! $destexists) { // We must set mask just before creating dir, becaause it can be set differently by dol_copy @@ -599,7 +599,7 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep $dirmaskdec |= octdec('0200'); // Set w bit required to be able to create content for recursive subdirs files dol_mkdir($destfile, '', decoct($dirmaskdec)); } - + $ossrcfile=dol_osencode($srcfile); $osdestfile=dol_osencode($destfile); @@ -639,7 +639,7 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep $result=$tmpresult; } if ($result < 0) break; - + } } closedir($dir_handle); @@ -656,10 +656,10 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep /** * Move a file into another name. - * Note: + * Note: * - This function differs from dol_move_uploaded_file, because it can be called in any context. * - Database of files is updated. - * - Test on antivirus is done only if param testvirus is provided and an antivirus was set. + * - Test on antivirus is done only if param testvirus is provided and an antivirus was set. * * @param string $srcfile Source file (can't be a directory. use native php @rename() to move a directory) * @param string $destfile Destination file (can't be a directory. use native php @rename() to move a directory) @@ -679,12 +679,12 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi $srcexists=dol_is_file($srcfile); $destexists=dol_is_file($destfile); - if (! $srcexists) + if (! $srcexists) { dol_syslog("files.lib.php::dol_move srcfile does not exists. we ignore the move request."); return false; } - + if ($overwriteifexists || ! $destexists) { $newpathofsrcfile=dol_osencode($srcfile); @@ -695,7 +695,7 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi if ($testvirus) { $testvirusarray=dolCheckVirus($newpathofsrcfile); - if (count($testvirusarray)) + if (count($testvirusarray)) { dol_syslog("files.lib.php::dol_move canceled because a virus was found into source file. we ignore the move request.", LOG_WARNING); return false; @@ -729,14 +729,14 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi dol_syslog("Try to rename also entries in database for full relative path before = ".$rel_filetorenamebefore." after = ".$rel_filetorenameafter, LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; - + $ecmfiletarget=new EcmFiles($db); $resultecmtarget = $ecmfiletarget->fetch(0, '', $rel_filetorenameafter); if ($resultecmtarget > 0) // An entry for target name already exists for target, we delete it, a new one will be created. { $ecmfiletarget->delete($user); } - + $ecmfile=new EcmFiles($db); $resultecm = $ecmfile->fetch(0, '', $rel_filetorenamebefore); if ($resultecm > 0) // If an entry was found for src file, we use it to move entry @@ -745,7 +745,7 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi $rel_dir = dirname($rel_filetorenameafter); $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); - + $ecmfile->filepath = $rel_dir; $ecmfile->filename = $filename; $resultecm = $ecmfile->update($user); @@ -756,7 +756,7 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi $rel_dir = dirname($rel_filetorenameafter); $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); - + $ecmfile->filepath = $rel_dir; $ecmfile->filename = $filename; $ecmfile->label = md5_file(dol_osencode($destfile)); // $destfile is a full path to file @@ -774,12 +774,12 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi { setEventMessages($ecmfile->error, $ecmfile->errors, 'warnings'); } - + if ($resultecm > 0) $result=true; else $result = false; - } + } } - + if (empty($newmask)) $newmask=empty($conf->global->MAIN_UMASK)?'0755':$conf->global->MAIN_UMASK; $newmaskdec=octdec($newmask); // Currently method is restricted to files (dol_delete_files previously used is for files, and mask usage if for files too) @@ -809,14 +809,14 @@ function dol_unescapefile($filename) /** * Check virus into a file - * + * * @param string $src_file Source file to check * @return array Array of errors or empty array if not virus found */ function dolCheckVirus($src_file) { global $conf; - + if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) { if (! class_exists('AntiVir')) { @@ -837,10 +837,10 @@ function dolCheckVirus($src_file) /** * Make control on an uploaded file from an GUI page and move it to final destination. * If there is errors (virus found, antivir in error, bad filename), file is not moved. - * Note: + * Note: * - This function can be used only into a HTML page context. Use dol_move if you are outside. - * - Database of files is not updated. * - Test on antivirus is always done (if antivirus set). + * - Database of files is NOT updated. * * @param string $src_file Source full path filename ($_FILES['field']['tmp_name']) * @param string $dest_file Target full path filename ($_FILES['field']['name']) @@ -867,7 +867,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable $parameters=array('dest_file' => $dest_file, 'src_file' => $src_file, 'file_name' => $file_name, 'varfiles' => $varfiles, 'allowoverwrite' => $allowoverwrite); $reshook=$hookmanager->executeHooks('moveUploadedFile', $parameters, $object); } - + if (empty($reshook)) { // If an upload error has been reported @@ -897,7 +897,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable break; } } - + // If we need to make a virus scan if (empty($disablevirusscan) && file_exists($src_file)) { @@ -908,7 +908,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray); } } - + // Security: // Disallow file with some extensions. We renamed them. // Car si on a mis le rep documents dans un rep de la racine web (pas bien), cela permet d'executer du code a la demande. @@ -916,7 +916,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable { $file_name.= '.noexe'; } - + // Security: // We refuse cache files/dirs, upload using .. and pipes into filenames. if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file)) @@ -924,7 +924,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); return -1; } - + // Security: // On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers. if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file)) @@ -933,7 +933,7 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable return -2; } } - + if ($reshook < 0) // At least one blocking error returned by one hook { $errmsg = join(',', $hookmanager->errors); @@ -1005,7 +1005,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n dol_syslog("Refused to delete file ".$file, LOG_WARNING); return False; } - + if (empty($nohook)) { $hookmanager->initHooks(array('fileslib')); @@ -1042,16 +1042,16 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n { if ($nophperrors) $ok=@unlink($filename); else $ok=unlink($filename); - if ($ok) + if ($ok) { dol_syslog("Removed file ".$filename, LOG_DEBUG); - + // Delete entry into ecm database $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file { $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); - + dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $ecmfile=new EcmFiles($db); @@ -1079,7 +1079,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n if ($nophperrors) $ok=@unlink($file_osencoded); else $ok=unlink($file_osencoded); if ($ok) dol_syslog("Removed file ".$file_osencoded, LOG_DEBUG); - else dol_syslog("Failed to remove file ".$file_osencoded, LOG_WARNING); + else dol_syslog("Failed to remove file ".$file_osencoded, LOG_WARNING); } return $ok; @@ -1104,7 +1104,7 @@ function dol_delete_dir($dir,$nophperrors=0) dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); return False; } - + $dir_osencoded=dol_osencode($dir); return ($nophperrors?@rmdir($dir_osencoded):rmdir($dir_osencoded)); } @@ -1340,7 +1340,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio global $db,$user,$conf,$langs; $res = 0; - + if (! empty($_FILES[$varfiles])) // For view $_FILES[$varfiles]['error'] { dol_syslog('dol_add_file_process upload_dir='.$upload_dir.' allowoverwrite='.$allowoverwrite.' donotupdatesession='.$donotupdatesession.' savingdocmask='.$savingdocmask, LOG_DEBUG); @@ -1354,17 +1354,17 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $val = array($val); } } - + $nbfile = count($TFile['name']); - + for ($i = 0; $i < $nbfile; $i++) { // Define $destfull (path to file including filename) and $destfile (only filename) $destfull=$upload_dir . "/" . $TFile['name'][$i]; $destfile=$TFile['name'][$i]; - + $savingdocmask = dol_sanitizeFileName($savingdocmask); - + if ($savingdocmask) { $destfull=$upload_dir . "/" . preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask); @@ -1378,26 +1378,26 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $destfile = $info['filename'].'.'.strtolower($info['extension']); $resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destfull, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles); - + if (is_numeric($resupload) && $resupload > 0) // $resupload can be 'ErrorFileAlreadyExists' { global $maxwidthsmall, $maxheightsmall, $maxwidthmini, $maxheightmini; - + include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; - + // Generate thumbs. if (image_format_supported($destfull) == 1) { // Create thumbs // We can't use $object->addThumbs here because there is no $object known - + // Used on logon for example $imgThumbSmall = vignette($destfull, $maxwidthsmall, $maxheightsmall, '_small', 50, "thumbs"); // Create mini thumbs for image (Ratio is near 16/9) // Used on menu or for setup page for example $imgThumbMini = vignette($destfull, $maxwidthmini, $maxheightmini, '_mini', 50, "thumbs"); } - + // Update session if (empty($donotupdatesession)) { @@ -1406,18 +1406,18 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $formmail->trackid = $trackid; $formmail->add_attached_files($destfull, $destfile, $TFile['type'][$i]); } - + // Update table of files - if ($donotupdatesession) + if ($donotupdatesession) { $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dir); - + if (! preg_match('/[\\/]temp[\\/]/', $rel_dir)) // If not a tmp dir { $filename = basename($destfile); $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); $rel_dir = preg_replace('/^[\\/]/', '', $rel_dir); - + include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $ecmfile=new EcmFiles($db); $ecmfile->filepath = $rel_dir; @@ -1455,7 +1455,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio } } } - + } } elseif ($link) { require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php'; @@ -1478,7 +1478,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio $langs->load("errors"); setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("File")), null, 'errors'); } - + return $res; } @@ -1718,11 +1718,11 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") if (class_exists('ZipArchive')) { $foundhandler=1; - + // Initialize archive object $zip = new ZipArchive(); $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); - + // Create recursive directory iterator /** @var SplFileInfo[] $files */ $files = new RecursiveIteratorIterator( @@ -1738,15 +1738,15 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") // Get real and relative path for current file $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($inputdir) + 1); - + // Add current file to archive $zip->addFile($filePath, $relativePath); } } - + // Zip archive will be created only after closing object - $zip->close(); - + $zip->close(); + return 1; } } @@ -1793,7 +1793,7 @@ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta * @param string $entity Restrict onto entity (0=no restriction) * @param User $fuser User object (forced) * @param string $refname Ref of object to check permission for external users (autodetect if not provided) - * @param string $mode Check permission for 'read' or 'write' + * @param string $mode Check permission for 'read' or 'write' * @return mixed Array with access information : 'accessallowed' & 'sqlprotectagainstexternals' & 'original_file' (as a full path name) * @see restrictedArea */ @@ -1801,7 +1801,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, { global $user, $conf, $db; global $dolibarr_main_data_root; - + if (! is_object($fuser)) $fuser=$user; if (empty($modulepart)) return 'ErrorBadParameter'; @@ -1823,7 +1823,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, { $lire='creer'; $read='write'; $download='upload'; } - + // Wrapping for some images if (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output)) { @@ -2022,7 +2022,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } $original_file=$conf->user->dir_output.'/'.$original_file; } - + // Wrapping for third parties else if (($modulepart == 'company' || $modulepart == 'societe') && !empty($conf->societe->dir_output)) { @@ -2119,7 +2119,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - + // Wrapping for interventions else if (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) { @@ -2185,7 +2185,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les commandes fournisseurs - else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) + else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) { if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) { @@ -2317,7 +2317,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } $original_file=$conf->resource->dir_output.'/'.$original_file; } - + // Wrapping pour les remises de cheques else if ($modulepart == 'remisecheque' && !empty($conf->banque->dir_output)) { @@ -2361,14 +2361,14 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $accessallowed=1; $original_file=$conf->fckeditor->dir_output.'/'.$original_file; } - + // Wrapping for miscellaneous medias files elseif ($modulepart == 'medias' && !empty($dolibarr_main_data_root)) { $accessallowed=1; $original_file=$dolibarr_main_data_root.'/medias/'.$original_file; } - + // Wrapping for backups else if ($modulepart == 'systemtools' && !empty($conf->admin->dir_output)) { @@ -2416,7 +2416,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart else { - if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. + if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. if ($fuser->admin) $accessallowed=1; // If user is admin // Define $accessallowed diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a18b9e1411027e5da26581ff0c80e0c91ed51d44..5113c9f1d9671707463743ff2f34df32d9f510e9 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -239,7 +239,7 @@ function dol_shutdown() /** * Return value of a param into GET or POST supervariable. * Use the property $user->default_values[path]['creatform'] and/or $user->default_values[path]['filters'] and/or $user->default_values[path]['sortorder'] - * Note: The property $user->default_values is loaded by the main when loading the user. + * Note: The property $user->default_values is loaded by main.php when loading the user. * * @param string $paramname Name of parameter to found * @param string $check Type of check @@ -359,32 +359,34 @@ function GETPOST($paramname, $check='', $method=0, $filter=NULL, $options=NULL) if (! empty($check)) { - // Replace vars like __DAY__, __MONTH__, __YEAR__, __MYCOUNTRYID__, __USERID__, __ENTITYID__, ... - if (! is_array($out)) + // Substitution variables for GETPOST (used to get final url with variable parameters or final default value with variable paramaters) + // Example of variables: __DAY__, __MONTH__, __YEAR__, __MYCOUNTRYID__, __USERID__, __ENTITYID__, ... + // We do this only if var is a GET. If it is a POST, may be we want to post the text with vars as the setup text. + if (! is_array($out) && empty($_POST[$paramname])) { $maxloop=20; $loopnb=0; // Protection against infinite loop while (preg_match('/__([A-Z0-9]+_?[A-Z0-9]+)__/i', $out, $reg) && ($loopnb < $maxloop)) // Detect '__ABCDEF__' as key 'ABCDEF' and '__ABC_DEF__' as key 'ABC_DEF'. Detection is also correct when 2 vars are side by side. { $loopnb++; $newout = ''; - if ($reg[1] == 'DAY') { $tmp=dol_getdate(dol_now(), true); $newout = $tmp['mday']; } - elseif ($reg[1] == 'MONTH') { $tmp=dol_getdate(dol_now(), true); $newout = $tmp['mon']; } - elseif ($reg[1] == 'YEAR') { $tmp=dol_getdate(dol_now(), true); $newout = $tmp['year']; } + if ($reg[1] == 'DAY') { $tmp=dol_getdate(dol_now(), true); $newout = $tmp['mday']; } + elseif ($reg[1] == 'MONTH') { $tmp=dol_getdate(dol_now(), true); $newout = $tmp['mon']; } + elseif ($reg[1] == 'YEAR') { $tmp=dol_getdate(dol_now(), true); $newout = $tmp['year']; } elseif ($reg[1] == 'PREVIOUS_DAY') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_prev_day($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['day']; } elseif ($reg[1] == 'PREVIOUS_MONTH') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_prev_month($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['month']; } elseif ($reg[1] == 'PREVIOUS_YEAR') { $tmp=dol_getdate(dol_now(), true); $newout = ($tmp['year'] - 1); } - elseif ($reg[1] == 'NEXT_DAY') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['day']; } - elseif ($reg[1] == 'NEXT_MONTH') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_next_month($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['month']; } - elseif ($reg[1] == 'NEXT_YEAR') { $tmp=dol_getdate(dol_now(), true); $newout = ($tmp['year'] + 1); } - elseif ($reg[1] == 'MYCOUNTRYID') + elseif ($reg[1] == 'NEXT_DAY') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['day']; } + elseif ($reg[1] == 'NEXT_MONTH') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_next_month($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['month']; } + elseif ($reg[1] == 'NEXT_YEAR') { $tmp=dol_getdate(dol_now(), true); $newout = ($tmp['year'] + 1); } + elseif ($reg[1] == 'MYCOUNTRY_ID' || $reg[1] == 'MYCOUNTRYID') { $newout = $mysoc->country_id; } - elseif ($reg[1] == 'USERID') + elseif ($reg[1] == 'USER_ID' || $reg[1] == 'USERID') { $newout = $user->id; } - elseif ($reg[1] == 'SUPERVISORID') + elseif ($reg[1] == 'SUPERVISOR_ID' || $reg[1] == 'SUPERVISORID') { $newout = $user->fk_user; } @@ -1586,7 +1588,8 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e if (preg_match('/__b__/i',$format)) { // Here ret is string in PHP setup language (strftime was used). Now we convert to $outputlangs. - $month=adodb_strftime('%m',$time+$offsettz+$offsetdst); // TODO Remove this + $month=adodb_strftime('%m',$time+$offsettz+$offsetdst); // TODO Replace this with function Date PHP. We also should not use anymore offsettz and offsetdst but only offsettzstring. + $month=sprintf("%02d", $month); // $month may be return with format '06' on some installation and '6' on other, so we force it to '06'. if ($encodetooutput) { $monthtext=$outputlangs->transnoentities('Month'.$month); @@ -2554,6 +2557,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ $picto = $regs[1]; $path = $regs[2]; // $path is $mymodule } + // Clean parameters if (! preg_match('/(\.png|\.gif)$/i',$picto)) $picto .= '.png'; // If alt path are defined, define url where img file is, according to physical path @@ -2792,7 +2796,7 @@ function img_printer($titlealt = "default", $other='') } /** - * Show delete logo + * Show split logo * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $other Add more attributes on img @@ -3233,15 +3237,19 @@ function dol_print_error($db='',$error='',$errors=null) * Show a public email and error code to contact if technical error * * @param string $prefixcode Prefix of public error code + * @param string $errormessage Complete error message * @return void */ -function dol_print_error_email($prefixcode) +function dol_print_error_email($prefixcode, $errormessage='') { global $langs,$conf; $langs->load("errors"); $now=dol_now(); - print '<br><div class="error">'.$langs->trans("ErrorContactEMail", $conf->global->MAIN_INFO_SOCIETE_MAIL, $prefixcode.dol_print_date($now,'%Y%m%d')).'</div>'; + print '<br><div class="center login_main_message"><div class="error">'; + print $langs->trans("ErrorContactEMail", $conf->global->MAIN_INFO_SOCIETE_MAIL, $prefixcode.dol_print_date($now,'%Y%m%d')); + if ($errormessage) print '<br><br>'.$errormessage; + print '</div></div>'; } /** @@ -5020,7 +5028,7 @@ function dol_concatdesc($text1,$text2,$forxml=false) * * @param Translate $outputlangs Output language * @param int $onlykey Do not calculate heavy values of keys (performance enhancement when we need only the keys) - * @param array $exclude Array of family keys we want to exclude. For example array('mycompany', 'object', 'date', 'user', ...) + * @param array $exclude Array of family keys we want to exclude. For example array('mycompany', 'objectamount', 'date', 'user', ...) * @param Object $object Object for keys on object * @return array Array of substitutions */ @@ -5045,7 +5053,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob '__MYCOMPANY_COUNTRY_ID__' => $mysoc->country_id )); } - if (empty($exclude) || ! in_array('object', $exclude)) + if (empty($exclude) || ! in_array('objectamount', $exclude)) { if (is_object($object)) // For backward compatibility { diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 8c48e2301e3953ff9e39e5a4fc8d53e8c20348a6..9220725dc8e97080cc9adf4212ff04bfedbf8cff 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -591,12 +591,13 @@ function pdf_pagehead(&$pdf,$outputlangs,$page_height) * Return array of possible substitutions for PDF content (without external module substitutions). * * @param Translate $outputlangs Output language + * @param array $exclude Array of family keys we want to exclude. For example array('mycompany', 'object', 'date', 'user', ...) * @param Object $object Object * @return array Array of substitutions */ -function pdf_getSubstitutionArray($outputlangs, $object=null) +function pdf_getSubstitutionArray($outputlangs, $exclude=null, $object=null) { - $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, $exclude, $object); $substitutionarray['__FROM_NAME__']='__FROM_NAME__'; $substitutionarray['__FROM_EMAIL__']='__FROM_EMAIL__'; return $substitutionarray; @@ -625,9 +626,9 @@ function pdf_watermark(&$pdf, $outputlangs, $h, $w, $unit, $text) elseif ($unit=='in') $k=72; // Make substitution - $substitutionarray=pdf_getSubstitutionArray($outputlangs,null); - complete_substitutions_array($substitutionarray,$outputlangs,null); - $text=make_substitutions($text,$substitutionarray,$outputlangs); + $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, null); + complete_substitutions_array($substitutionarray, $outputlangs, null); + $text=make_substitutions($text, $substitutionarray, $outputlangs); $text=$outputlangs->convToOutputCharset($text); $savx=$pdf->getX(); $savy=$pdf->getY(); @@ -854,12 +855,12 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass // Line of free text if (empty($hidefreetext) && ! empty($conf->global->$paramfreetext)) { - $substitutionarray=pdf_getSubstitutionArray($outputlangs, $object); + $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object); // More substitution keys $substitutionarray['__FROM_NAME__']=$fromcompany->name; $substitutionarray['__FROM_EMAIL__']=$fromcompany->email; - complete_substitutions_array($substitutionarray,$outputlangs,$object); - $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray,$outputlangs); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $newfreetext=make_substitutions($conf->global->$paramfreetext, $substitutionarray, $outputlangs); $line.=$outputlangs->convToOutputCharset($newfreetext); } diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 38f78dd8333b251a149060b88eac86cfa3ca076b..c3583e72ac8e7273f1f2c3ff6fcfc140af73dfa0 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; function project_prepare_head($object) { global $db, $langs, $conf, $user; - + $h = 0; $head = array(); @@ -119,7 +119,7 @@ function project_prepare_head($object) } $head[$h][2] = 'agenda'; $h++; - + complete_head_from_modules($conf,$langs,$object,$head,$h,'project','remove'); return $head; @@ -163,7 +163,7 @@ function task_prepare_head($object) if ($obj) $nbTimeSpent=1; } else dol_print_error($db); - + $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':''); $head[$h][1] = $langs->trans("TimeSpent"); if ($nbTimeSpent > 0) $head[$h][1].= ' <span class="badge">...</span>'; @@ -208,9 +208,10 @@ function task_prepare_head($object) * Prepare array with list of tabs * * @param string $mode Mode + * @param string $fuser Filter on user * @return array Array of tabs to show */ -function project_timesheet_prepare_head($mode) +function project_timesheet_prepare_head($mode, $fuser=null) { global $langs, $conf, $user; $h = 0; @@ -218,9 +219,13 @@ function project_timesheet_prepare_head($mode) $h = 0; + $param=''; + $param.=($mode?'&mode='.$mode:''); + if (is_object($fuser) && $fuser->id > 0 && $fuser->id != $user->id) $param.='&search_usertoprocessid='.$fuser->id; + if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERWEEK)) { - $head[$h][0] = DOL_URL_ROOT."/projet/activity/perweek.php".($mode?'?mode='.$mode:''); + $head[$h][0] = DOL_URL_ROOT."/projet/activity/perweek.php".($param?'?'.$param:''); $head[$h][1] = $langs->trans("InputPerWeek"); $head[$h][2] = 'inputperweek'; $h++; @@ -228,7 +233,7 @@ function project_timesheet_prepare_head($mode) if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERTIME)) { - $head[$h][0] = DOL_URL_ROOT."/projet/activity/perday.php".($mode?'?mode='.$mode:''); + $head[$h][0] = DOL_URL_ROOT."/projet/activity/perday.php".($param?'?'.$param:''); $head[$h][1] = $langs->trans("InputPerDay"); $head[$h][2] = 'inputperday'; $h++; @@ -507,7 +512,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick); $level--; } - + $total_projectlinesa_spent += $lines[$i]->duration; $total_projectlinesa_planned += $lines[$i]->planned_workload; if ($lines[$i]->planned_workload) $total_projectlinesa_spent_if_planned += $lines[$i]->duration; @@ -571,9 +576,9 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $lastprojectid=0; $workloadforid=array(); $lineswithoutlevel0=array(); - + $numlines=count($lines); - + // Create a smaller array with sublevels only to be used later. This increase dramatically performances. if ($parent == 0) // Always and only if at first level { @@ -581,7 +586,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr { if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; } - } + } //dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); for ($i = 0 ; $i < $numlines ; $i++) @@ -594,7 +599,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr if (empty($mine) || ! empty($tasksrole[$lines[$i]->id])) { //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); - + // Break on a new project if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) { @@ -604,7 +609,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $projectstatic->id = $lines[$i]->fk_project; } } - + if (empty($workloadforid[$projectstatic->id])) { if ($preselectedday) @@ -613,7 +618,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $workloadforid[$projectstatic->id]=1; } } - + $projectstatic->id=$lines[$i]->fk_project; $projectstatic->ref=$lines[$i]->projectref; $projectstatic->title=$lines[$i]->projectlabel; @@ -621,7 +626,12 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $taskstatic->id=$lines[$i]->id; - print "<tr ".$bc[$var].">\n"; + print '<tr class="oddeven">'."\n"; + + // User + print '<td class="nowrap">'; + print $fuser->getNomUrl(1, 'withproject', 'time'); + print '</td>'; // Ref print '<td>'; @@ -656,7 +666,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print $thirdpartystatic->getNomUrl(1, 'project', 10); print '</td>'; } - + // Planned Workload print '<td align="right">'; if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin'); @@ -707,7 +717,10 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print '<td class="nowrap" align="center">'; $tableCell=$form->select_date($preselectedday,$lines[$i]->id,1,1,2,"addtime",0,0,1,$disabledtask); print $tableCell; - print '</td><td align="right">'; + print '</td>'; + + // Duration + print '<td align="right">'; $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id]; $alreadyspent=''; @@ -723,24 +736,25 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print '</td>'; print '<td align="right">'; - if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("YouAreNotContactOfProject")); - else if ($disabledtask) print $form->textwithpicto('',$langs->trans("TaskIsNotAffectedToYou")); + print '<textarea name="'.$lines[$i]->id.'note" rows="'.ROWS_2.'" id="'.$lines[$i]->id.'note"'.($disabledtask?' disabled="disabled"':'').'>'; + print '</textarea>'; print '</td>'; + // Warning print '<td align="right">'; - print '<textarea name="'.$lines[$i]->id.'note" rows="2" id="note">'; - print '</textarea>'; + if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject")); + else if ($disabledtask) print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $langs->transnoentitiesnoconv("AssignTaskToUser", '...'))); print '</td>'; - + print "</tr>\n"; } $inc++; $level++; - if ($lines[$i]->id > 0) + if ($lines[$i]->id > 0) { if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); - else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); + else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $var); } $level--; } @@ -781,7 +795,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $lastprojectid=0; $workloadforid=array(); $lineswithoutlevel0=array(); - + // Create a smaller array with sublevels only to be used later. This increase dramatically performances. if ($parent == 0) // Always and only if at first level { @@ -792,18 +806,18 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ } //dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); - + for ($i = 0 ; $i < $numlines ; $i++) { if ($parent == 0) $level = 0; - + if ($lines[$i]->fk_task_parent == $parent) { // If we want all or we have a role on task, we show it if (empty($mine) || ! empty($tasksrole[$lines[$i]->id])) { //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); - + // Break on a new project if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) { @@ -811,14 +825,19 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $lastprojectid=$lines[$i]->fk_project; $projectstatic->id = $lines[$i]->fk_project; } - + if (empty($workloadforid[$projectstatic->id])) { $projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week $workloadforid[$projectstatic->id]=1; } - - print "<tr ".$bc[$var].">\n"; + + print '<tr class="oddeven">'."\n"; + + // User + print '<td class="nowrap">'; + print $fuser->getNomUrl(1, 'withproject', 'time'); + print '</td>'; // Ref print '<td class="nowrap">'; @@ -842,7 +861,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ print "</td>\n"; // Project - print '<td class="nowrap">'.$var; + print '<td class="nowrap">'; $projectstatic->id=$lines[$i]->fk_project; $projectstatic->ref=$lines[$i]->projectref; $projectstatic->title=$lines[$i]->projectlabel; @@ -860,7 +879,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ print $thirdpartystatic->getNomUrl(1, 'project'); print '</td>'; } - + // Planned Workload print '<td align="right">'; if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin'); @@ -908,7 +927,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ } //var_dump($projectstatic->weekWorkLoadPerTask); - + // Fields to show current time $tableCell=''; $modeinput='hours'; for ($idw = 0; $idw < 7; $idw++) @@ -919,7 +938,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $alreadyspent=''; if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); - + $tableCell ='<td align="center" class="hide'.$idw.'">'; if ($alreadyspent) { @@ -934,10 +953,11 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $tableCell.='</td>'; print $tableCell; } - + + // Warning print '<td align="right">'; - if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("YouAreNotContactOfProject")); - else if ($disabledtask) print $form->textwithpicto('',$langs->trans("TaskIsNotAffectedToYou")); + if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject")); + else if ($disabledtask) print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $langs->transnoentitiesnoconv("AssignTaskToUser", '...'))); print '</td>'; print "</tr>\n"; @@ -946,7 +966,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ // Call to show task with a lower level (task under the current task) $inc++; $level++; - if ($lines[$i]->id > 0) + if ($lines[$i]->id > 0) { if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $var); @@ -1020,7 +1040,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $projectstatic=new Project($db); $thirdpartystatic=new Societe($db); - + $sortfield=''; $sortorder=''; $project_year_filter=0; @@ -1029,7 +1049,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= if (strcmp($statut, '') && $statut >= 0) $title=$langs->trans("Projects").' '.$langs->trans($projectstatic->statuts_long[$statut]); $arrayidtypeofcontact=array(); - + print '<table class="noborder" width="100%">'; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; @@ -1072,11 +1092,11 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $sql.= " AND (p.datee IS NULL OR p.datee >= ".$db->idate(dol_get_first_day($project_year_filter,1,false)).")"; } } - + // Get id of project we must show tasks $arrayidofprojects=array(); $sql1 = "SELECT p.rowid as projectid"; - $sql1.= $sql; + $sql1.= $sql; $resql = $db->query($sql1); if ($resql) { @@ -1091,7 +1111,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= } else dol_print_error($db); if (empty($arrayidofprojects)) $arrayidofprojects[0]=-1; - + // Get list of project with calculation on tasks $sql2 = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, s.nom as socname, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_amount,"; $sql2.= " p.dateo, p.datee,"; @@ -1122,7 +1142,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= print_liste_field_titre($langs->trans("OpportunityAmount"),"","","","",'align="right"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("OpportunityStatus"),"","","","",'align="right"',$sortfield,$sortorder); } - if (empty($conf->global->PROJECT_HIDE_TASKS)) + if (empty($conf->global->PROJECT_HIDE_TASKS)) { print_liste_field_titre($langs->trans("Tasks"),"","","","",'align="right"',$sortfield,$sortorder); if (! in_array('plannedworkload', $hiddenfields)) print_liste_field_titre($langs->trans("PlannedWorkload"),"","","","",'align="right"',$sortfield,$sortorder); @@ -1130,7 +1150,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= } print_liste_field_titre($langs->trans("Status"),"","","","",'align="right"',$sortfield,$sortorder); print "</tr>\n"; - + while ($i < $num) { $objp = $db->fetch_object($resql); @@ -1148,8 +1168,8 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= $projectstatic->title = $objp->title; $projectstatic->datee = $db->jdate($objp->datee); $projectstatic->dateo = $db->jdate($objp->dateo); - - + + print '<tr class="oddeven">'; print '<td>'; print $projectstatic->getNomUrl(1); @@ -1174,17 +1194,17 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= if ($code) print $langs->trans("OppStatus".$code); print '</td>'; } - if (empty($conf->global->PROJECT_HIDE_TASKS)) + if (empty($conf->global->PROJECT_HIDE_TASKS)) { print '<td align="right">'.$objp->nb.'</td>'; - + $plannedworkload=$objp->planned_workload; $total_plannedworkload+=$plannedworkload; if (! in_array('plannedworkload', $hiddenfields)) { print '<td align="right">'.($plannedworkload?convertSecondToTime($plannedworkload):'').'</td>'; } - if (! in_array('declaredprogress', $hiddenfields)) + if (! in_array('declaredprogress', $hiddenfields)) { $declaredprogressworkload=$objp->declared_progess_workload; $total_declaredprogressworkload+=$declaredprogressworkload; @@ -1194,7 +1214,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= print '</td>'; } } - + print '<td align="right">'.$projectstatic->getLibStatut(3).'</td>'; print "</tr>\n"; @@ -1213,7 +1233,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= print '<td class="liste_total" align="right">'.price($total_opp_amount, 0, '', 1, -1, -1, $conf->currency).'</td>'; print '<td class="liste_total" align="right">'.$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmountDesc"), 1).'</td>'; } - if (empty($conf->global->PROJECT_HIDE_TASKS)) + if (empty($conf->global->PROJECT_HIDE_TASKS)) { print '<td class="liste_total" align="right">'.$total_task.'</td>'; if (! in_array('plannedworkload', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?convertSecondToTime($total_plannedworkload):'').'</td>'; @@ -1221,7 +1241,7 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks= } print '<td class="liste_total"></td>'; print '</tr>'; - + $db->free($resql); } else diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 6993ad496eae4d46808ce6c2b0c6d8f9cdf982fa..2a2b224194ffbf4709b4714fd6daf245d8280260 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -345,7 +345,7 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu * This function is also called by restrictedArea * * @param User $user User to check - * @param array $featuresarray Features/modules to check. Example: ('user','service') + * @param array $featuresarray Features/modules to check. Example: ('user','service','member','project','task',...) * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional). * @param string $feature2 Feature to check, second level of permission (optional). Can be or check with 'level1|level2'. @@ -369,11 +369,14 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh // For backward compatibility if ($feature == 'member') $feature='adherent'; + if ($feature == 'project') $feature='projet'; + if ($feature == 'task') $feature='projet_task'; $check = array('adherent','banque','user','usergroup','produit','service','produit|service','categorie'); // Test on entity only (Objects with no link to company) $checksoc = array('societe'); // Test for societe object $checkother = array('contact'); // Test on entity and link to societe. Allowed if link is empty (Ex: contacts...). - $checkproject = array('projet'); // Test for project object + $checkproject = array('projet','project'); // Test for project object + $checktask = array('projet_task'); $nocheck = array('barcode','stock','fournisseur'); // No test $checkdefault = 'all other not already defined'; // Test on entity and link to third party. Not allowed if link is empty (Ex: invoice, orders...). @@ -453,7 +456,7 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh } else if (in_array($feature,$checkproject)) { - if (! empty($conf->projet->enabled) && ! $user->rights->projet->all->lire) + if (! empty($conf->projet->enabled) && empty($user->rights->projet->all->lire)) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $projectstatic=new Project($db); @@ -469,6 +472,27 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; } } + else if (in_array($feature,$checktask)) + { + if (! empty($conf->projet->enabled) && empty($user->rights->projet->all->lire)) + { + $task = new Task($db); + $task->fetch($objectid); + + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + $projectstatic=new Project($db); + $tmps=$projectstatic->getProjectsAuthorizedForUser($user,0,1,0); + $tmparray=explode(',',$tmps); + if (! in_array($task->fk_project,$tmparray)) return false; + } + else + { + $sql = "SELECT dbt.".$dbt_select; + $sql.= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; + $sql.= " WHERE dbt.".$dbt_select." = ".$objectid; + $sql.= " AND dbt.entity IN (".getEntity($sharedelement, 1).")"; + } + } else if (! in_array($feature,$nocheck)) // By default we check with link to third party { // If external user: Check permission for external users diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 9106c345fdac8082542c931818915676ff8ed43c..7a60f330727914e9d4af73b543ce2a0e022cb7aa 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -288,6 +288,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3701__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/tasks.php?leftmenu=projects&action=create', 'NewTask', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3702__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/tasks/list.php?leftmenu=projects', 'List', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3703__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/activity/perweek.php?leftmenu=projects', 'NewTimeSpent', 1, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3704__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/tasks/stats/index.php?leftmenu=projects', 'Statistics', 1, 'projects', '$user->rights->projet->lire', '', 2, 4, __ENTITY__); -- Project - Categories insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 3804__+MAX_llx_menu__, 'project', 'cat', 3__+MAX_llx_menu__, '/categories/index.php?leftmenu=cat&type=6', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 9245a481aff631e019d70dab9ad1e0bf1344db8f..8b167e3a6f602333b89139946ec55555a7fd6286 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -52,7 +52,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode if (empty($noout)) print_start_menu_array(); $usemenuhider = (GETPOST('testmenuhider','int') || ! empty($conf->global->MAIN_TESTMENUHIDER)); - + // Show/Hide vertical menu if ($mode != 'jmobile' && $mode != 'topnb' && $usemenuhider && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { @@ -437,7 +437,7 @@ function print_end_menu_array() /** * Core function to output left menu eldy * Fill &$menu (example with $forcemainmenu='home' $forceleftmenu='all', return left menu tree of Home) - * + * * @param DoliDB $db Database handler * @param array $menu_array_before Table of menu entries to show before entries of menu handler (menu->liste filled with menu->add) * @param array $menu_array_after Table of menu entries to show after entries of menu handler (menu->liste filled with menu->add) @@ -445,7 +445,7 @@ function print_end_menu_array() * @param Menu $menu Object Menu to return back list of menu entries * @param int $noout Disable output (Initialise &$menu only). * @param string $forcemainmenu 'x'=Force mainmenu to mainmenu='x' - * @param string $forceleftmenu 'all'=Force leftmenu to '' (= all). If value come being '', we change it to value in session and 'none' if not efined in session. + * @param string $forceleftmenu 'all'=Force leftmenu to '' (= all). If value come being '', we change it to value in session and 'none' if not efined in session. * @param array $moredata An array with more data to output * @return int nb of menu entries */ @@ -459,7 +459,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $leftmenu=($forceleftmenu?'':(empty($_SESSION["leftmenu"])?'none':$_SESSION["leftmenu"])); $usemenuhider = (GETPOST('testmenuhider','int') || ! empty($conf->global->MAIN_TESTMENUHIDER)); - + // Show logo company if (empty($conf->global->MAIN_MENU_INVERT) && empty($noout) && ! empty($conf->global->MAIN_SHOW_LOGO) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { @@ -503,7 +503,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print '</div>'."\n"; print "<!-- End Bookmarks -->\n"; } - + /** * We update newmenu with entries found into database * -------------------------------------------------- @@ -605,7 +605,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/user/group/index.php?leftmenu=users", $langs->trans("ListOfGroups"), 2, ($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->read:$user->rights->user->user->lire) || $user->admin); } } - + } @@ -839,7 +839,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } $newmenu->add("/fourn/facture/paiement.php", $langs->trans("Payments"),1,$user->rights->fournisseur->facture->lire); - + $newmenu->add("/fourn/facture/rapport.php",$langs->trans("Reportings"),2,$user->rights->fournisseur->facture->lire); $newmenu->add("/compta/facture/stats/index.php?mode=supplier", $langs->trans("Statistics"),1,$user->rights->fournisseur->facture->lire); @@ -957,29 +957,29 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("Chartofaccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 30); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/categories_list.php?id=32&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("AccountingCategory"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_chart', 31); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/defaultaccounts.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDefaultAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 40); - if (! empty($conf->facture->enabled) || ! empty($conf->fournisseur->enabled)) + if (! empty($conf->facture->enabled) || ! empty($conf->fournisseur->enabled)) { if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=10&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuVatAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); } - if (! empty($conf->tax->enabled)) + if (! empty($conf->tax->enabled)) { if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=7&from=accountancy&search_country_id=".$mysoc->country_id."&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuTaxAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); } - if (! empty($conf->expensereport->enabled)) + if (! empty($conf->expensereport->enabled)) { if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/dict.php?id=17&from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuExpenseReportAccounts"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_default', 50); } /* not required yet, already supported by default account - if (! empty($conf->loan->enabled)) + if (! empty($conf->loan->enabled)) { if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/admin/loan.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuLoanAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_loan', 45); } - if (! empty($conf->don->enabled)) + if (! empty($conf->don->enabled)) { if (preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/don/admin/donation.php?from=accountancy&mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuDonationAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_donation', 47); }*/ if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/productaccount.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("MenuProductsAccounts"), 2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_product', 60); - + // Binding if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy/',$leftmenu)) $newmenu->add("/accountancy/customer/index.php?leftmenu=accountancy_dispatch_customer&mainmenu=accountancy",$langs->trans("CustomersVentilation"),1,$user->rights->accounting->bind->write, '', $mainmenu, 'dispatch_customer'); if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_dispatch_customer/',$leftmenu)) $newmenu->add("/accountancy/customer/list.php?mainmenu=accountancy&leftmenu=accountancy_dispatch_customer",$langs->trans("ToBind"),2,$user->rights->accounting->bind->write); @@ -1275,7 +1275,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/product/inventory/list.php", $langs->trans("List"), 1, $user->rights->stock->lire); } } - + // Expeditions if (! empty($conf->expedition->enabled)) { @@ -1299,9 +1299,9 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (! empty($conf->projet->enabled)) { $langs->load("projects"); - + $search_project_user = GETPOST('search_project_user','int'); - + // Project affected to user $newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("Projects"), 0, $user->rights->projet->lire, '', $mainmenu, 'projects'); $newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("NewProject"), 1, $user->rights->projet->creer); @@ -1314,7 +1314,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/projet/list.php?leftmenu=projects&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire); */ $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); - + if (empty($conf->global->PROJECT_HIDE_TASKS)) { // Project affected to user @@ -1322,6 +1322,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/projet/tasks.php?leftmenu=tasks&action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer); $newmenu->add("/projet/tasks/list.php?leftmenu=tasks".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("List"), 1, $user->rights->projet->lire); $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("NewTimeSpent"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire); // All project i have permission on /*$newmenu->add("/projet/activity/index.php", $langs->trans("Activities"), 0, $user->rights->projet->lire && $user->rights->projet->lire); @@ -1445,7 +1446,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/adherents/stats/index.php?leftmenu=members",$langs->trans("MenuMembersStats"),1,$user->rights->adherent->lire); if (! empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu=="export")) $newmenu->add("/adherents/htpasswd.php?leftmenu=export",$langs->trans("Filehtpasswd"),1,$user->rights->adherent->export); if ($usemenuhider || empty($leftmenu) || $leftmenu=="export") $newmenu->add("/adherents/cartes/carte.php?leftmenu=export",$langs->trans("MembersCards"),1,$user->rights->adherent->export); - + $newmenu->add("/adherents/index.php?leftmenu=members&mainmenu=members",$langs->trans("Subscriptions"),0,$user->rights->adherent->cotisation->lire); $newmenu->add("/adherents/list.php?leftmenu=members&statut=-1,1&mainmenu=members",$langs->trans("NewSubscription"),1,$user->rights->adherent->cotisation->creer); $newmenu->add("/adherents/subscription/list.php?leftmenu=members",$langs->trans("List"),1,$user->rights->adherent->cotisation->lire); diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 71de341a76996c9b59193395a4d02feea3096d35..a79f17b1fdc5b659cb385bda220ab4894dcb1b8a 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -50,13 +50,13 @@ class DolibarrModules // Can not be abstract, because we need to insta * @since 4.0.0 */ public $editor_name; - + /** * @var string URL of module at publisher site * @since 4.0.0 */ public $editor_url; - + /** * @var string Family * @see familyinfo @@ -80,13 +80,13 @@ class DolibarrModules // Can not be abstract, because we need to insta * */ public $familyinfo; - + /** * @var int Module position * @since 3.9.0 */ public $module_position=500; - + /** * @var string Module name * @@ -214,7 +214,7 @@ class DolibarrModules // Can not be abstract, because we need to insta * HTML content supported. */ public $descriptionlong; - + /** * @var string Module export code */ @@ -249,7 +249,7 @@ class DolibarrModules // Can not be abstract, because we need to insta * @var bool Module is enabled globally (Multicompany support) */ public $core_enabled; - + /** * @var string Relative path to module style sheet * @deprecated @@ -286,7 +286,7 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $config_page_url; - + /** * @var string[] List of module class names that must be enabled if this module is enabled. * @@ -309,22 +309,22 @@ class DolibarrModules // Can not be abstract, because we need to insta * @var string[] Module language files */ public $langfiles; - + /** * @var string[] Array of warnings to show when we activate the module - * + * * array('always'='text') or array('FR'='text') */ public $warnings_activation; - + /** * @var string[] Array of warnings to show when we activate an external module - * + * * array('always'='text') or array('FR'='text') */ public $warnings_activation_ext; - - + + /** * @var array() Minimum version of PHP required by module. * e.g.: PHP ≥ 5.3 = array(5, 3) @@ -342,7 +342,7 @@ class DolibarrModules // Can not be abstract, because we need to insta */ public $hidden = false; - + /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -538,8 +538,8 @@ class DolibarrModules // Can not be abstract, because we need to insta return $langs->trans("Module".$this->numero."Name"); } else - { - // If module name translation using it's unique id does not exists, we take use its name to find translation + { + // If module name translation using it's unique id does not exists, we try to use its name to find translation if (is_array($this->langfiles)) { foreach($this->langfiles as $val) @@ -547,6 +547,14 @@ class DolibarrModules // Can not be abstract, because we need to insta if ($val) $langs->load($val); } } + + if ($langs->trans("Module".$this->name."Name") != ("Module".$this->name."Name")) + { + // If module name translation exists + return $langs->trans("Module".$this->name."Name"); + } + + // Last change with simple product label return $langs->trans($this->name); } } @@ -591,13 +599,13 @@ class DolibarrModules // Can not be abstract, because we need to insta { global $langs; $langs->load("admin"); - + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; $filefound= false; - - // Define path to file README.md. + + // Define path to file README.md. // First check README-la_LA.md then README.md $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0); if (dol_is_file($pathoffile)) @@ -612,11 +620,11 @@ class DolibarrModules // Can not be abstract, because we need to insta $filefound = true; } } - + if ($filefound) // Mostly for external modules { $content = file_get_contents($pathoffile); - + if ((float) DOL_VERSION >= 6.0) { @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; @@ -638,14 +646,14 @@ class DolibarrModules // Can not be abstract, because we need to insta if ($val) $langs->load($val); } } - + $content = $langs->trans($this->descriptionlong); } } - + return $content; } - + /** * Gives the publisher name * @@ -655,7 +663,7 @@ class DolibarrModules // Can not be abstract, because we need to insta { return $this->editor_name; } - + /** * Gives the publisher url * @@ -665,7 +673,7 @@ class DolibarrModules // Can not be abstract, because we need to insta { return $this->editor_url; } - + /** * Gives module version (translated if param $translated is on) * For 'experimental' modules, gives 'experimental' translation @@ -768,7 +776,7 @@ class DolibarrModules // Can not be abstract, because we need to insta } } - + /** * Gives the last date of activation * @@ -777,11 +785,11 @@ class DolibarrModules // Can not be abstract, because we need to insta function getLastActivationDate() { global $conf; - + $sql = "SELECT tms FROM ".MAIN_DB_PREFIX."const"; $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; $sql.= " AND entity IN (0, ".$conf->entity.")"; - + dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG); $resql=$this->db->query($sql); if (! $resql) $err++; @@ -790,11 +798,11 @@ class DolibarrModules // Can not be abstract, because we need to insta $obj=$this->db->fetch_object($resql); if ($obj) return $this->db->jdate($obj->tms); } - + return ''; } - - + + /** * Gives the last author of activation * @@ -803,11 +811,11 @@ class DolibarrModules // Can not be abstract, because we need to insta function getLastActivationInfo() { global $conf; - + $sql = "SELECT tms, note FROM ".MAIN_DB_PREFIX."const"; $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->db->escape($this->const_name)."'"; $sql.= " AND entity IN (0, ".$conf->entity.")"; - + dol_syslog(get_class($this)."::getLastActiveDate", LOG_DEBUG); $resql=$this->db->query($sql); if (! $resql) $err++; @@ -821,11 +829,11 @@ class DolibarrModules // Can not be abstract, because we need to insta } if ($obj) return array('authorid'=>$tmp['authorid'], 'ip'=>$tmp['ip'], 'lastactivationdate'=>$this->db->jdate($obj->tms)); } - + return array(); } - - + + /** * Insert constants for module activation * @@ -929,7 +937,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -947,7 +955,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data') { @@ -965,7 +973,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data') { @@ -983,7 +991,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $files[] = $file; } sort($files); - foreach ($files as $file) + foreach ($files as $file) { if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update') { @@ -1123,19 +1131,19 @@ class DolibarrModules // Can not be abstract, because we need to insta //$titre = $this->boxes[$key][0]; $file = $this->boxes[$key]['file']; //$note = $this->boxes[$key][2]; - + // TODO If the box is also included by another module and the other module is still on, we should not remove it. // For the moment, we manage this with hard coded exception //print "Remove box ".$file.'<br>'; if ($file == 'box_graph_product_distribution.php') { - if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) + if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) { dol_syslog("We discard disabling of module ".$file." because another module still active require it."); continue; } } - + if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility if ($this->db->type == 'sqlite3') { @@ -1210,7 +1218,7 @@ class DolibarrModules // Can not be abstract, because we need to insta $status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:''; $priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:''; $test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:''; // Line must be visible - + // Search if boxes def already present $sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob"; $sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'"; @@ -1645,7 +1653,7 @@ class DolibarrModules // Can not be abstract, because we need to insta /** * Removes access rights - * + * * @return int Error count (0 if OK) */ function delete_permissions() @@ -1678,7 +1686,7 @@ class DolibarrModules // Can not be abstract, because we need to insta global $user; if (! is_array($this->menu) || empty($this->menu)) return 0; - + require_once DOL_DOCUMENT_ROOT . '/core/class/menubase.class.php'; $err=0; diff --git a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php index a58d00455e89874dd49f4025058fec896762169b..64d0da9b5fd911acaa26c2851a9ebec8204468cd 100644 --- a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php +++ b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php @@ -102,16 +102,10 @@ class doc_generic_contract_odt extends ModelePDFContract $form = new Form($this->db); $texte = $this->description.".<br>\n"; - $texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; + $texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" enctype="multipart/form-data">'; $texte.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; $texte.= '<input type="hidden" name="action" value="setModuleOptions">'; $texte.= '<input type="hidden" name="param1" value="CONTRACT_ADDON_PDF_ODT_PATH">'; - if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) - { - $texte.= '<input type="hidden" name="param2" value="CONTRACT_ADDON_PDF_ODT_DEFAULT">'; - $texte.= '<input type="hidden" name="param3" value="CONTRACT_ADDON_PDF_ODT_TOBILL">'; - $texte.= '<input type="hidden" name="param4" value="CONTRACT_ADDON_PDF_ODT_CLOSED">'; - } $texte.= '<table class="nobordernopadding" width="100%">'; // List of directories area @@ -144,40 +138,21 @@ class doc_generic_contract_odt extends ModelePDFContract $texte.=$conf->global->CONTRACT_ADDON_PDF_ODT_PATH; $texte.= '</textarea>'; $texte.= '</div><div style="display: inline-block; vertical-align: middle;">'; - $texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">'; + $texte.= '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Modify")).'" name="Button">'; $texte.= '<br></div></div>'; // Scan directories if (count($listofdir)) { $texte.=$langs->trans("NumberOfModelFilesFound").': <b>'.count($listoffiles).'</b>'; - - if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) - { - // Model for creation - $liste=ModelePDFContract::liste_modeles($this->db); - $texte.= '<table width="50%;">'; - $texte.= '<tr>'; - $texte.= '<td width="60%;">'.$langs->trans("DefaultModelPropalCreate").'</td>'; - $texte.= '<td colspan="">'; - $texte.= $form->selectarray('value2',$liste,$conf->global->CONTRACT_ADDON_PDF_ODT_DEFAULT); - $texte.= "</td></tr>"; - - $texte.= '<tr>'; - $texte.= '<td width="60%;">'.$langs->trans("DefaultModelPropalToBill").'</td>'; - $texte.= '<td colspan="">'; - $texte.= $form->selectarray('value3',$liste,$conf->global->CONTRACT_ADDON_PDF_ODT_TOBILL); - $texte.= "</td></tr>"; - $texte.= '<tr>'; - - $texte.= '<td width="60%;">'.$langs->trans("DefaultModelPropalClosed").'</td>'; - $texte.= '<td colspan="">'; - $texte.= $form->selectarray('value4',$liste,$conf->global->CONTRACT_ADDON_PDF_ODT_CLOSED); - $texte.= "</td></tr>"; - $texte.= '</table>'; - } } + // Add select to upload a new template file. TODO Copy this feature on other admin pages. + $texte.= '<div>'.$langs->trans("UploadNewTemplate").' <input type="file" name="uploadfile">'; + $texte.= '<input type="hidden" value="CONTRACT_ADDON_PDF_ODT_PATH" name="keyforuploaddir">'; + $texte.= '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Upload")).'" name="upload">'; + $texte.= '</div>'; + $texte.= '</td>'; $texte.= '<td valign="top" rowspan="2" class="hideonsmartphone">'; diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php index 411b3deadf37e8c625e9d8f41906ad2f39c70ca8..c06882fa1214ea5a4474df407ba02e34408966aa 100644 --- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php +++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php @@ -294,22 +294,25 @@ class pdf_strato extends ModelePDFContract } else { $datere = $langs->trans("Unknown"); } - + $txtpredefinedservice=''; - $txtpredefinedservice = $objectligne->product_ref; + $txtpredefinedservice = $objectligne->product_label; if ($objectligne->product_label) { $txtpredefinedservice .= ' - '; $txtpredefinedservice .= $objectligne->product_label; } - $txt='<strong>'.dol_htmlentitiesbr($outputlangs->transnoentities("DateStartPlannedShort")." : ".$datei." - ".$outputlangs->transnoentities("DateEndPlanned")." : ".$datee,1,$outputlangs->charset_output).'</strong>'; + $desc=dol_htmlentitiesbr($objectligne->desc,1); // Desc (not empty for free lines) + $txt=''; + $txt.=$outputlangs->transnoentities("Quantity").' : <strong>'.$objectligne->qty.'</strong> - '.$outputlangs->transnoentities("UnitPrice").' : <strong>'.price($objectligne->subprice).'</strong>'; // Desc (not empty for free lines) + $txt.='<br>'; + $txt.=$outputlangs->transnoentities("DateStartPlannedShort")." : <strong>".$datei."</strong> - ".$outputlangs->transnoentities("DateEndPlanned")." : <strong>".$datee.'</strong>'; $txt.='<br>'; - $txt.='<strong>'.dol_htmlentitiesbr($outputlangs->transnoentities("DateStartRealShort")." : ".$daters,1,$outputlangs->charset_output); - if ($objectligne->date_cloture) $txt.=dol_htmlentitiesbr(" - ".$outputlangs->transnoentities("DateEndRealShort")." : ".$datere,1,$outputlangs->charset_output).'</strong>'; - $desc=dol_htmlentitiesbr($objectligne->desc,1); + $txt.=$outputlangs->transnoentities("DateStartRealShort")." : <strong>".$daters.'</strong>'; + if ($objectligne->date_cloture) $txt.=" - ".$outputlangs->transnoentities("DateEndRealShort")." : '<strong>'".$datere.'</strong>'; - $pdf->writeHTMLCell(0, 0, $curX, $curY, dol_concatdesc($txt,dol_concatdesc($txtpredefinedservice,$desc)), 0, 1, 0); + $pdf->writeHTMLCell(0, 0, $curX, $curY, dol_concatdesc($txtpredefinedservice, dol_concatdesc($txt, $desc)), 0, 1, 0); $nexY = $pdf->GetY() + 2; $pageposafter=$pdf->getPage(); diff --git a/htdocs/don/admin/donation.php b/htdocs/don/admin/donation.php index c8d8be2461de9cdcf28b695199417df0c75236c2..2ca1cba1083932d090c20dfac151a47898aaeeb6 100644 --- a/htdocs/don/admin/donation.php +++ b/htdocs/don/admin/donation.php @@ -121,7 +121,7 @@ else if ($action == 'del') // Options if ($action == 'set_DONATION_ACCOUNTINGACCOUNT') { - $account = GETPOST('DONATION_ACCOUNTINGACCOUNT'); // No alpha here, we want exact string + $account = GETPOST('DONATION_ACCOUNTINGACCOUNT','alpha'); $res = dolibarr_set_const($db, "DONATION_ACCOUNTINGACCOUNT",$account,'chaine',0,'',$conf->entity); @@ -139,7 +139,7 @@ if ($action == 'set_DONATION_ACCOUNTINGACCOUNT') if ($action == 'set_DONATION_MESSAGE') { - $freemessage = GETPOST('DONATION_MESSAGE'); // No alpha here, we want exact string + $freemessage = GETPOST('DONATION_MESSAGE','none'); // No alpha here, we want exact string $res = dolibarr_set_const($db, "DONATION_MESSAGE",$freemessage,'chaine',0,'',$conf->entity); diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index c7268680f19adda88de437d5af6d7d6b6a042ac0..2bb2121411f6f527b7143bf0f111773bc4a4059a 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index f8b638b079a0508f25a02c98e78c5980b3d7b5b1..d7e683465110ee9b809d992735ea47ba1d00d8f6 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -159,6 +159,9 @@ CREATE TABLE llx_product_attribute_combination ALTER TABLE llx_bank_account drop foreign key bank_fk_accountancy_journal; +-- Fix missing entity column after init demo +ALTER TABLE llx_accounting_journal ADD COLUMN entity integer DEFAULT 1; + -- Add journal entries INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (1,'VT', 'Sale journal', 2, 1); INSERT INTO llx_accounting_journal (rowid, code, label, nature, active) VALUES (2,'AC', 'Purchase journal', 3, 1); @@ -348,5 +351,31 @@ ALTER TABLE llx_facture ADD COLUMN fk_fac_rec_source integer; DELETE from llx_c_actioncomm where code in ('AC_PROP','AC_COM','AC_FAC','AC_SHIP','AC_SUP_ORD','AC_SUP_INV') AND id NOT IN (SELECT DISTINCT fk_action FROM llx_actioncomm); +-- Fix: delete orphelin category. +delete from llx_categorie_product where fk_categorie not in (select rowid from llx_categorie where type = 0); +delete from llx_categorie_societe where fk_categorie not in (select rowid from llx_categorie where type in (1, 2)); +delete from llx_categorie_member where fk_categorie not in (select rowid from llx_categorie where type = 3); +delete from llx_categorie_contact where fk_categorie not in (select rowid from llx_categorie where type = 4); +delete from llx_categorie_project where fk_categorie not in (select rowid from llx_categorie where type = 5); + +ALTER TABLE llx_inventory ADD COLUMN ref varchar(48); + +create table llx_loan_schedule +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_loan integer, + datec datetime, + tms timestamp, + datep datetime, + amount_capital real DEFAULT 0, + amount_insurance real DEFAULT 0, + amount_interest real DEFAULT 0, + fk_typepayment integer NOT NULL, + num_payment varchar(50), + note_private text, + note_public text, + fk_bank integer NOT NULL, + fk_user_creat integer, + fk_user_modif integer +)ENGINE=innodb; -ALTER TABLE llx_inventory ADD COLUMN ref varchar(48); \ No newline at end of file diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 6ff7356847f8abcba7aafc84d05d112b79266c0c..c748f38acb3ec9f07d0a232cf74209b4b4895edc 100755 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -28,7 +28,7 @@ --- Requests to clean corrupted database +-- Requests to clean corrupted data UPDATE llx_user set api_key = null where api_key = ''; @@ -124,6 +124,7 @@ delete from llx_categorie_product where fk_categorie not in (select rowid from l delete from llx_categorie_societe where fk_categorie not in (select rowid from llx_categorie where type in (1, 2)); delete from llx_categorie_member where fk_categorie not in (select rowid from llx_categorie where type = 3); delete from llx_categorie_contact where fk_categorie not in (select rowid from llx_categorie where type = 4); +delete from llx_categorie_project where fk_categorie not in (select rowid from llx_categorie where type = 5); -- Fix: delete orphelin deliveries. Note: deliveries are linked to shipment by llx_element_element only. No other links. @@ -337,3 +338,8 @@ drop table tmp_c_shipment_mode; -- VMYSQL4.1 update llx_expensereport_det as ed set date = (select date_debut from llx_expensereport as e where ed.fk_expensereport = e.rowid) where DATE(STR_TO_DATE(date, '%Y-%m-%d')) < '1000-00-00'; -- VMYSQL4.1 SET sql_mode = 'NO_ZERO_DATE'; + +-- Backport a change of value into the hourly rate. +-- update llx_projet_task_time as ptt set ptt.thm = (SELECT thm from llx_user as u where ptt.fk_user = u.rowid) where (ptt.thm is null) + + \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_advtargetemailing.sql b/htdocs/install/mysql/tables/llx_advtargetemailing.sql index d22503bb54836e6a3ed0abe876d87c15506043c5..7e95f6b80976333b3b70dd6afbc3e32a6fd6a741 100644 --- a/htdocs/install/mysql/tables/llx_advtargetemailing.sql +++ b/htdocs/install/mysql/tables/llx_advtargetemailing.sql @@ -28,4 +28,4 @@ CREATE TABLE llx_advtargetemailing datec datetime NOT NULL, fk_user_mod integer NOT NULL, tms timestamp NOT NULL -)ENGINE=InnoDB; +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_loan_schedule.sql b/htdocs/install/mysql/tables/llx_loan_schedule.sql new file mode 100644 index 0000000000000000000000000000000000000000..c682b22f276150f132f13275976e0f11bd397d45 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_loan_schedule.sql @@ -0,0 +1,37 @@ +-- =================================================================== +-- Copyright (C) 2014 Alexandre Spangaro <aspangaro.dolibarr@gmail.com> +-- Copyright (C) 2015 Frederic France <frederic.france@free.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 +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- =================================================================== + +create table llx_loan_schedule +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_loan integer, + datec datetime, -- creation date + tms timestamp, + datep datetime, -- payment date + amount_capital real DEFAULT 0, + amount_insurance real DEFAULT 0, + amount_interest real DEFAULT 0, + fk_typepayment integer NOT NULL, + num_payment varchar(50), + note_private text, + note_public text, + fk_bank integer NOT NULL, + fk_user_creat integer, -- creation user + fk_user_modif integer -- last modification user +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_attribute.sql b/htdocs/install/mysql/tables/llx_product_attribute.sql index 77c045327b8d6d38f87417c00f8951219fab9aba..cb655508e89b553103f818aeaaef7ee7c0e6e5fb 100644 --- a/htdocs/install/mysql/tables/llx_product_attribute.sql +++ b/htdocs/install/mysql/tables/llx_product_attribute.sql @@ -23,4 +23,4 @@ CREATE TABLE llx_product_attribute label VARCHAR(255) NOT NULL, rang INT DEFAULT 0 NOT NULL, entity INT DEFAULT 1 NOT NULL -); +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_attribute_combination.sql b/htdocs/install/mysql/tables/llx_product_attribute_combination.sql index fae38f8403d9cdd4e4146010523f49e6c29a1dab..85c46706014a4399598e159f68846eb63f3928e1 100644 --- a/htdocs/install/mysql/tables/llx_product_attribute_combination.sql +++ b/htdocs/install/mysql/tables/llx_product_attribute_combination.sql @@ -25,4 +25,4 @@ CREATE TABLE llx_product_attribute_combination variation_price_percentage INT NULL, variation_weight FLOAT NOT NULL, entity INT DEFAULT 1 NOT NULL -); \ No newline at end of file +)ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_product_attribute_combination2val.sql b/htdocs/install/mysql/tables/llx_product_attribute_combination2val.sql index a64230923e60cbab732a77e65bb24436943e41b7..af0da7f710d504b313ae78c4ab26e8867aef6d84 100644 --- a/htdocs/install/mysql/tables/llx_product_attribute_combination2val.sql +++ b/htdocs/install/mysql/tables/llx_product_attribute_combination2val.sql @@ -22,4 +22,4 @@ CREATE TABLE llx_product_attribute_combination2val fk_prod_combination INT NOT NULL, fk_prod_attr INT NOT NULL, fk_prod_attr_val INT NOT NULL -); \ No newline at end of file +)ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_product_attribute_value.sql b/htdocs/install/mysql/tables/llx_product_attribute_value.sql index ebd2cf8bb4928c6e5c44851b56dbd6fb330cf1cc..8ca6888d91b7fef7c5b0b6b9b70403ca7295d7ba 100644 --- a/htdocs/install/mysql/tables/llx_product_attribute_value.sql +++ b/htdocs/install/mysql/tables/llx_product_attribute_value.sql @@ -23,4 +23,4 @@ CREATE TABLE llx_product_attribute_value ref VARCHAR(255) DEFAULT NULL, value VARCHAR(255) DEFAULT NULL, entity INT DEFAULT 1 NOT NULL -); \ No newline at end of file +)ENGINE=innodb; \ No newline at end of file diff --git a/htdocs/install/mysql/tables/llx_product_pricerules.sql b/htdocs/install/mysql/tables/llx_product_pricerules.sql index 3e3dfc02ed19394e610d68ec027761fe13e13e84..3cf58c9585f52152df4385e1b0e826019c41dc60 100644 --- a/htdocs/install/mysql/tables/llx_product_pricerules.sql +++ b/htdocs/install/mysql/tables/llx_product_pricerules.sql @@ -23,4 +23,4 @@ CREATE TABLE llx_product_pricerules fk_level INT NOT NULL, -- Price variations are made over price of X var_percent FLOAT NOT NULL, -- Price variation over based price var_min_percent FLOAT NOT NULL -- Min price discount over general price -); \ No newline at end of file +)ENGINE=innodb; diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index 264a45bca9146980bda0a8ff28dc4b1a88baf213..19195e170009f18ac2f3332306fa6a2e8fd85fd1 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -413,10 +413,10 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09 { // Migrate to add entity value into llx_societe_remise migrate_remise_entity($db,$langs,$conf); - + // Migrate to add entity value into llx_societe_remise_except migrate_remise_except_entity($db,$langs,$conf); - + // Reload modules (this must be always and only into last targeted version) $listofmodule=array( 'MAIN_MODULE_ACCOUNTING'=>'newboxdefonly', @@ -441,11 +441,11 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09 'MAIN_MODULE_USER'=>'newboxdefonly', ); migrate_reload_modules($db,$langs,$conf,$listofmodule); - + // Reload menus (this must be always and only into last targeted version) migrate_reload_menu($db,$langs,$conf,$versionto); } - + // Can force activation of some module during migration with third paramater = MAIN_MODULE_XXX,MAIN_MODULE_YYY,... if ($enablemodules) { @@ -471,8 +471,8 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09 // Actions for all versions (not in database) migrate_delete_old_files($db, $langs, $conf); migrate_delete_old_dir($db, $langs, $conf); - - + + dol_mkdir(DOL_DATA_ROOT.'/bank'); migrate_directories($db, $langs, $conf, '/banque/bordereau', '/bank/checkdeposits'); } @@ -3942,10 +3942,13 @@ function migrate_delete_old_files($db,$langs,$conf) DOL_DOCUMENT_ROOT.'/core/modules/mailings/kiwi.modules.php', DOL_DOCUMENT_ROOT.'/core/modules/facture/pdf_crabe.modules.php', DOL_DOCUMENT_ROOT.'/core/modules/facture/pdf_oursin.modules.php', - + DOL_DOCUMENT_ROOT.'/compta/facture/class/api_invoice.class.php', DOL_DOCUMENT_ROOT.'/commande/class/api_commande.class.php', - DOL_DOCUMENT_ROOT.'/user/class/api_user.class.php' + DOL_DOCUMENT_ROOT.'/user/class/api_user.class.php', + DOL_DOCUMENT_ROOT.'/product/class/api_product.class.php', + DOL_DOCUMENT_ROOT.'/societe/class/api_contact.class.php', + DOL_DOCUMENT_ROOT.'/societe/class/api_thirdparty.class.php' ); foreach ($filetodeletearray as $filetodelete) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index fe54793190808e189f571eca24b6e74b7689719e..fe292db145dade0150c9e2340125ee8dcf5c22d4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -48,6 +48,7 @@ InternalUsers=Internal users ExternalUsers=External users GUISetup=Display SetupArea=Setup area +UploadNewTemplate=Upload new template(s) FormToTestFileUploadForm=Form to test file upload (according to setup) IfModuleEnabled=Note: yes is effective only if module <b>%s</b> is enabled RemoveLock=Remove file <b>%s</b> if it exists to allow usage of the update tool. @@ -613,7 +614,7 @@ Permission32=Create/modify products Permission34=Delete products Permission36=See/manage hidden products Permission38=Export products -Permission41=Read projects and tasks (shared project and projects i'm contact for). Can also enter time consumed on assigned tasks (timesheet) +Permission41=Read projects and tasks (shared project and projects i'm contact for). Can also enter time consumed, for me or my hierarchy, on assigned tasks (Timesheet) Permission42=Create/modify projects (shared project and projects i'm contact for). Can also create tasks and assign users to project and tasks Permission44=Delete projects (shared project and projects i'm contact for) Permission45=Export projects @@ -873,6 +874,7 @@ DictionaryProspectStatus=Prospection status DictionaryHolidayTypes=Types of leaves DictionaryOpportunityStatus=Opportunity status for project/lead SetupSaved=Setup saved +SetupNotSaved=Setup not saved BackToModuleList=Back to modules list BackToDictionaryList=Back to dictionaries list VATManagement=VAT Management diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 740397a5044c9149340cba3ae8d7320f8b96b7f4..0f49bd832d6c6ea44473eb903eca8ef9214287f9 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -190,6 +190,7 @@ ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (<strong>%s</strong>) does not match expected name syntax: <strong>%s</strong> ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s. ErrorNoWarehouseDefined=Error, no warehouses defined. +ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' for payment is defined, but value for 'ref' is not valid. # Warnings WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/en_US/loan.lang b/htdocs/langs/en_US/loan.lang index 927aab2abf4a86ad3a97b04ed4c65202d99277f6..d00b11738be75484b24da384c4695e3211f8064c 100644 --- a/htdocs/langs/en_US/loan.lang +++ b/htdocs/langs/en_US/loan.lang @@ -50,3 +50,4 @@ ConfigLoan=Configuration of the module loan LOAN_ACCOUNTING_ACCOUNT_CAPITAL=Accounting account capital by default LOAN_ACCOUNTING_ACCOUNT_INTEREST=Accounting account interest by default LOAN_ACCOUNTING_ACCOUNT_INSURANCE=Accounting account insurance by default +CreateCalcSchedule=Créer / Modifier échéancier de pret diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index c98c2120e2198ca80f35e1652faa0742f56c801c..b3317df9c8efddb47bf33dc8796a34b1cc324231 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -41,6 +41,7 @@ ShowProject=Show project SetProject=Set project NoProject=No project defined or owned NbOfProjects=Nb of projects +NbOfTasks=Nb of tasks TimeSpent=Time spent TimeSpentByYou=Time spent by you TimeSpentByUser=Time spent by user @@ -53,7 +54,7 @@ TaskTimeNote=Note TaskTimeDate=Date TasksOnOpenedProject=Tasks on open projects WorkloadNotDefined=Workload not defined -NewTimeSpent=New time spent +NewTimeSpent=Time spent MyTimeSpent=My time spent Tasks=Tasks Task=Task @@ -107,6 +108,7 @@ ConfirmReOpenAProject=Are you sure you want to re-open this project? ProjectContact=Project contacts ActionsOnProject=Events on project YouAreNotContactOfProject=You are not a contact of this private project +UserIsNotContactOfProject=User is not a contact of this private project DeleteATimeSpent=Delete time spent ConfirmDeleteATimeSpent=Are you sure you want to delete this time spent? DoNotShowMyTasksOnly=See also tasks not assigned to me @@ -115,7 +117,7 @@ TaskRessourceLinks=Resources ProjectsDedicatedToThisThirdParty=Projects dedicated to this third party NoTasks=No tasks for this project LinkedToAnotherCompany=Linked to other third party -TaskIsNotAffectedToYou=Task not assigned to you +TaskIsNotAssignedToUser=Task not assigned to user. Use button '<strong>%s</strong>' to assign task now. ErrorTimeSpentIsEmpty=Time spent is empty ThisWillAlsoRemoveTasks=This action will also delete all tasks of project (<b>%s</b> tasks at the moment) and all inputs of time spent. IfNeedToUseOhterObjectKeepEmpty=If some objects (invoice, order, ...), belonging to another third party, must be linked to the project to create, keep this empty to have the project being multi third parties. @@ -166,26 +168,30 @@ FirstAddRessourceToAllocateTime=Assign a user resource to task to allocate time InputPerDay=Input per day InputPerWeek=Input per week InputPerAction=Input per action -TimeAlreadyRecorded=Time spent already recorded for this task/day and user %s +TimeAlreadyRecorded=This is time spent already recorded for this task/day and user %s ProjectsWithThisUserAsContact=Projects with this user as contact TasksWithThisUserAsContact=Tasks assigned to this user ResourceNotAssignedToProject=Not assigned to project ResourceNotAssignedToTheTask=Not assigned to the task TasksAssignedTo=Tasks assigned to AssignTaskToMe=Assign task to me +AssignTaskToUser=Assign task to %s +SelectTaskToAssign=Select task to assign... AssignTask=Assign ProjectOverview=Overview ManageTasks=Use projects to follow tasks and time ManageOpportunitiesStatus=Use projects to follow leads/opportinuties ProjectNbProjectByMonth=Nb of created projects by month +ProjectNbTaskByMonth=Nb of created tasks by month ProjectOppAmountOfProjectsByMonth=Amount of opportunities by month ProjectWeightedOppAmountOfProjectsByMonth=Weighted amount of opportunities by month ProjectOpenedProjectByOppStatus=Open project/lead by opportunity status ProjectsStatistics=Statistics on projects/leads +TasksStatistics=Statistics on project/lead tasks TaskAssignedToEnterTime=Task assigned. Entering time on this task should be possible. IdTaskTime=Id task time YouCanCompleteRef=If you want to complete the ref with some information (to use it as search filters), it is recommanded to add a - character to separate it, so the automatic numbering will still work correctly for next projects. For example %s-ABC. You may also prefer to add search keys into label. But best practice may be to add a dedicated field, also called complementary attributes. -OpenedProjectsByThirdparties=Open projects by thirdparties +OpenedProjectsByThirdparties=Open projects by third parties OnlyOpportunitiesShort=Only opportunities OpenedOpportunitiesShort=Open opportunities NotAnOpportunityShort=Not an opportunity diff --git a/htdocs/loan/calcmens.php b/htdocs/loan/calcmens.php new file mode 100644 index 0000000000000000000000000000000000000000..96c8b5204b88d402ed89c844d62d74b19791b9c6 --- /dev/null +++ b/htdocs/loan/calcmens.php @@ -0,0 +1,72 @@ +<?php +/* TVI + * Copyright (C) 2015 Florian HENRY <florian.henry@open-concept.pro> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/** + * \file tvi/ajax/list.php + * \brief File to return datables output + */ +if (! defined('NOTOKENRENEWAL')) + define('NOTOKENRENEWAL', '1'); // Disables token renewal +if (! defined('NOREQUIREMENU')) + define('NOREQUIREMENU', '1'); + // if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +if (! defined('NOREQUIREAJAX')) + define('NOREQUIREAJAX', '1'); + // if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); + // if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); + + +require '../main.inc.php'; +require DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php'; + +$mens=GETPOST('mens'); +$capital=GETPOST('capital'); +$rate=GETPOST('rate'); +$echance=GETPOST('echeance'); +$nbterm=GETPOST('nbterm'); + +top_httphead(); + +$output=array(); + +$object = new LoanSchedule($db); + +$int = ($capital*($rate/12)); +$int = round($int,2,PHP_ROUND_HALF_UP); +$cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP); +$output[$echance]=array('cap_rest'=>$cap_rest,'cap_rest_str'=>price($cap_rest),'interet'=>$int,'interet_str'=>price($int,0,'',1),'mens'=>$mens); + +$echance++; +$capital=$cap_rest; +while ($echance<=$nbterm) { + + $mens = round($object->calc_mens($capital,$rate,$nbterm-$echance+1),2,PHP_ROUND_HALF_UP); + + $int = ($capital*($rate/12)); + $int = round($int,2,PHP_ROUND_HALF_UP); + $cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP); + + $output[$echance]=array('cap_rest'=>$cap_rest,'cap_rest_str'=>price($cap_rest),'interet'=>$int,'interet_str'=>price($int,0,'',1),'mens'=>$mens); + + $capital=$cap_rest; + $echance++; +} + +echo json_encode($output); + diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 81d43e46ab0bcd0d78b0d42ac8ce92131ba72151..557d48be6802a2e1622ce7debd6eff2ca7f4881b 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -72,7 +72,7 @@ if (empty($reshook)) setEventMessages($loan->error, null, 'errors'); } } - + // Delete loan if ($action == 'confirm_delete' && $confirm == 'yes') { @@ -89,7 +89,7 @@ if (empty($reshook)) setEventMessages($loan->error, null, 'errors'); } } - + // Add loan if ($action == 'add' && $user->rights->loan->write) { @@ -99,7 +99,7 @@ if (empty($reshook)) $dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); $capital = price2num(GETPOST('capital')); $rate = GETPOST('rate'); - + if (! $capital) { $error++; $action = 'create'; @@ -120,7 +120,7 @@ if (empty($reshook)) $error++; $action = 'create'; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Rate")), null, 'errors'); } - + if (! $error) { $object->label = GETPOST('label'); @@ -133,15 +133,15 @@ if (empty($reshook)) $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); $object->fk_project = GETPOST('fk_project'); - + $accountancy_account_capital = GETPOST('accountancy_account_capital'); $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); $accountancy_account_interest = GETPOST('accountancy_account_interest'); - + if ($accountancy_account_capital <= 0) { $object->account_capital = ''; } else { $object->account_capital = $accountancy_account_capital; } if ($accountancy_account_insurance <= 0) { $object->account_insurance = ''; } else { $object->account_insurance = $accountancy_account_insurance; } if ($accountancy_account_interest <= 0) { $object->account_interest = ''; } else { $object->account_interest = $accountancy_account_interest; } - + $id=$object->create($user); if ($id <= 0) { @@ -157,7 +157,7 @@ if (empty($reshook)) exit(); } } - + // Update record else if ($action == 'update' && $user->rights->loan->write) { @@ -168,7 +168,7 @@ if (empty($reshook)) $datestart = dol_mktime(12, 0, 0, GETPOST('startmonth','int'), GETPOST('startday','int'), GETPOST('startyear','int')); $dateend = dol_mktime(12, 0, 0, GETPOST('endmonth','int'), GETPOST('endday','int'), GETPOST('endyear','int')); $capital = price2num(GETPOST('capital')); - + if (! $capital) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("LoanCapital")), null, 'errors'); @@ -185,14 +185,14 @@ if (empty($reshook)) $accountancy_account_capital = GETPOST('accountancy_account_capital'); $accountancy_account_insurance = GETPOST('accountancy_account_insurance'); $accountancy_account_interest = GETPOST('accountancy_account_interest'); - + if ($accountancy_account_capital <= 0) { $object->account_capital = ''; } else { $object->account_capital = $accountancy_account_capital; } if ($accountancy_account_insurance <= 0) { $object->account_insurance = ''; } else { $object->account_insurance = $accountancy_account_insurance; } if ($accountancy_account_interest <= 0) { $object->account_interest = ''; } else { $object->account_interest = $accountancy_account_interest; } } - + $result = $object->update($user); - + if ($result > 0) { header("Location: " . $_SERVER["PHP_SELF"] . "?id=" . $id); @@ -209,7 +209,7 @@ if (empty($reshook)) exit; } } - + // Link to a project if ($action == 'classin' && $user->rights->loan->write) { @@ -307,12 +307,12 @@ if ($action == 'create') $langs->load("projects"); print '<tr><td>'.$langs->trans("Project").'</td><td>'; - + $numproject=$formproject->select_projects(-1,GETPOST("fk_project"),'fk_project',16,0,1,1); - + print '</td></tr>'; } - + // Note Private print '<tr>'; print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>'; @@ -352,7 +352,7 @@ if ($action == 'create') print $formaccounting->select_account($object->accountancy_account_interest, 'accountancy_account_interest', 1, '', 0, 1); print '</td></tr>'; } - else // For external software + else // For external software { // Accountancy_account_capital print '<tr><td class="titlefieldcreate">'.$langs->trans("LoanAccountancyCapitalCode").'</td>'; @@ -417,10 +417,22 @@ if ($id > 0) dol_fiche_head($head, 'card', $langs->trans("Loan"), 0, 'bill'); + print '<script type="text/javascript">' . "\n"; + print ' function popEcheancier() {' . "\n"; + print ' $div = $(\'<div id="popCalendar"><iframe width="100%" height="100%" frameborder="0" src="createschedule.php?loanid=' . $object->id . '"></iframe></div>\');' . "\n"; + print ' $div.dialog({' . "\n"; + print ' modal:true' . "\n"; + print ' ,width:"90%"' . "\n"; + print ' ,height:$(window).height() - 150' . "\n"; + print ' });' . "\n"; + print ' }' . "\n"; + print '</script>'; + + // Loan card - + $linkback = '<a href="' . DOL_URL_ROOT . '/loan/index.php">' . $langs->trans("BackToList") . '</a>'; - + $morehtmlref='<div class="refidno">'; // Ref loan $morehtmlref.=$form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->loan->write, 'string', '', 0, 1); @@ -458,7 +470,7 @@ if ($id > 0) } } $morehtmlref.='</div>'; - + $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); @@ -652,7 +664,7 @@ if ($id > 0) while ($i < $num) { $objp = $db->fetch_object($resql); - + print '<tr class="oddeven">'; print '<td><a href="'.DOL_URL_ROOT.'/loan/payment/card.php?id='.$objp->rowid.'">'.img_object($langs->trans("Payment"),"payment").' '.$objp->rowid.'</a></td>'; print '<td>'.dol_print_date($db->jdate($objp->dp),'day')."</td>\n"; @@ -713,31 +725,33 @@ if ($id > 0) if (empty($reshook)) { print '<div class="tabsAction">'; - + // Edit if ($user->rights->loan->write) { + print '<a href="javascript:popEcheancier()" class="butAction">'.$langs->trans('CreateCalcSchedule').'</a>'; + print '<a class="butAction" href="'.DOL_URL_ROOT.'/loan/card.php?id='.$object->id.'&action=edit">'.$langs->trans("Modify").'</a>'; } - + // Emit payment if ($object->paid == 0 && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write) { print '<a class="butAction" href="'.DOL_URL_ROOT.'/loan/payment/payment.php?id='.$object->id.'&action=create">'.$langs->trans("DoPayment").'</a>'; } - + // Classify 'paid' if ($object->paid == 0 && round($staytopay) <=0 && $user->rights->loan->write) { print '<a class="butAction" href="'.DOL_URL_ROOT.'/loan/card.php?id='.$object->id.'&action=paid">'.$langs->trans("ClassifyPaid").'</a>'; } - + // Delete if ($user->rights->loan->delete) { print '<a class="butActionDelete" href="'.DOL_URL_ROOT.'/loan/card.php?id='.$object->id.'&action=delete">'.$langs->trans("Delete").'</a>'; } - + print "</div>"; } } diff --git a/htdocs/loan/class/loanschedule.class.php b/htdocs/loan/class/loanschedule.class.php new file mode 100644 index 0000000000000000000000000000000000000000..fb6df8fcb6c9116a58062c33362782177e6c6682 --- /dev/null +++ b/htdocs/loan/class/loanschedule.class.php @@ -0,0 +1,542 @@ +<?php +/* Copyright (C) 2017 Florian HENRY <florian.henry@atm-consulting.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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/loan/class/loanschedule.class.php + * \ingroup facture + * \brief File of class to manage schedule of loans + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + + +/** + * Class to manage Schedule of loans + */ +class LoanSchedule extends CommonObject +{ + public $element='loan_schedule'; //!< Id that identify managed objects + public $table_element='loan_schedule'; //!< Name of table without prefix where object is stored + + var $fk_loan; + var $datec=''; + var $tms=''; + var $datep=''; + var $amounts=array(); // Array of amounts + var $amount_capital; // Total amount of payment + var $amount_insurance; + var $amount_interest; + var $fk_typepayment; + var $num_payment; + var $fk_bank; + var $fk_user_creat; + var $fk_user_modif; + var $lines=array(); + + /** + * @deprecated + * @see amount, amounts + */ + var $total; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + /** + * Create payment of loan into database. + * Use this->amounts to have list of lines for the payment + * + * @param User $user User making payment + * @return int <0 if KO, id of payment if OK + */ + function create($user) + { + global $conf, $langs; + + $error=0; + + $now=dol_now(); + + // Validate parameters + if (! $this->datepaid) + { + $this->error='ErrorBadValueForParameter'; + return -1; + } + + // Clean parameters + if (isset($this->fk_loan)) $this->fk_loan = trim($this->fk_loan); + if (isset($this->amount_capital)) $this->amount_capital = trim($this->amount_capital?$this->amount_capital:0); + if (isset($this->amount_insurance)) $this->amount_insurance = trim($this->amount_insurance?$this->amount_insurance:0); + if (isset($this->amount_interest)) $this->amount_interest = trim($this->amount_interest?$this->amount_interest:0); + if (isset($this->fk_typepayment)) $this->fk_typepayment = trim($this->fk_typepayment); + if (isset($this->fk_bank)) $this->fk_bank = trim($this->fk_bank); + if (isset($this->fk_user_creat)) $this->fk_user_creat = trim($this->fk_user_creat); + if (isset($this->fk_user_modif)) $this->fk_user_modif = trim($this->fk_user_modif); + + $totalamount = $this->amount_capital + $this->amount_insurance + $this->amount_interest; + $totalamount = price2num($totalamount); + + // Check parameters + if ($totalamount == 0) { + $this->errors[]='step1'; + return -1; // Negative amounts are accepted for reject prelevement but not null + } + + + $this->db->begin(); + + if ($totalamount != 0) + { + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,"; + $sql.= " fk_typepayment, fk_user_creat, fk_bank)"; + $sql.= " VALUES (".$this->fk_loan.", '".$this->db->idate($now)."',"; + $sql.= " '".$this->db->idate($this->datepaid)."',"; + $sql.= " ".$this->amount_capital.","; + $sql.= " ".$this->amount_insurance.","; + $sql.= " ".$this->amount_interest.","; + $sql.= " ".$this->fk_typepayment.", "; + $sql.= " ".$user->id.","; + $sql.= " ".$this->fk_bank . ")"; + + dol_syslog(get_class($this)."::create", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."payment_loan"); + } + else + { + $this->error=$this->db->lasterror(); + $error++; + } + + } + + if ($totalamount != 0 && ! $error) + { + $this->amount_capital=$totalamount; + $this->total=$totalamount; // deprecated + $this->db->commit(); + return $this->id; + } + else + { + $this->errors[]=$this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from database + * + * @param int $id Id object + * @return int <0 if KO, >0 if OK + */ + function fetch($id) + { + global $langs; + $sql = "SELECT"; + $sql.= " t.rowid,"; + $sql.= " t.fk_loan,"; + $sql.= " t.datec,"; + $sql.= " t.tms,"; + $sql.= " t.datep,"; + $sql.= " t.amount_capital,"; + $sql.= " t.amount_insurance,"; + $sql.= " t.amount_interest,"; + $sql.= " t.fk_typepayment,"; + $sql.= " t.num_payment,"; + $sql.= " t.note_private,"; + $sql.= " t.note_public,"; + $sql.= " t.fk_bank,"; + $sql.= " t.fk_user_creat,"; + $sql.= " t.fk_user_modif,"; + $sql.= " pt.code as type_code, pt.libelle as type_libelle,"; + $sql.= ' b.fk_account'; + $sql.= " FROM (".MAIN_DB_PREFIX."c_paiement as pt, ".MAIN_DB_PREFIX.$this->table_element." as t)"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid'; + $sql.= " WHERE t.rowid = ".$id." AND t.fk_typepayment = pt.id"; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->rowid; + $this->ref = $obj->rowid; + + $this->fk_loan = $obj->fk_loan; + $this->datec = $this->db->jdate($obj->datec); + $this->tms = $this->db->jdate($obj->tms); + $this->datep = $this->db->jdate($obj->datep); + $this->amount_capital = $obj->amount_capital; + $this->amount_insurance = $obj->amount_insurance; + $this->amount_interest = $obj->amount_interest; + $this->fk_typepayment = $obj->fk_typepayment; + $this->num_payment = $obj->num_payment; + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; + $this->fk_bank = $obj->fk_bank; + $this->fk_user_creat = $obj->fk_user_creat; + $this->fk_user_modif = $obj->fk_user_modif; + + $this->type_code = $obj->type_code; + $this->type_libelle = $obj->type_libelle; + + $this->bank_account = $obj->fk_account; + $this->bank_line = $obj->fk_bank; + } + $this->db->free($resql); + + return 1; + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + + /** + * Update database + * + * @param User $user User that modify + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=0, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + if (isset($this->fk_loan)) $this->fk_loan=trim($this->fk_loan); + if (isset($this->amount_capital)) $this->amount_capital=trim($this->amount_capital); + if (isset($this->amount_insurance)) $this->amount_insurance=trim($this->amount_insurance); + if (isset($this->amount_interest)) $this->amount_interest=trim($this->amount_interest); + if (isset($this->fk_typepayment)) $this->fk_typepayment=trim($this->fk_typepayment); + if (isset($this->num_payment)) $this->num_payment=trim($this->num_payment); + if (isset($this->note_private)) $this->note_private=trim($this->note_private); + if (isset($this->note_public)) $this->note_public=trim($this->note_public); + if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank); + if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat); + if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif); + + // Check parameters + // Put here code to add control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + + $sql.= " fk_loan=".(isset($this->fk_loan)?$this->fk_loan:"null").","; + $sql.= " datec=".(dol_strlen($this->datec)!=0 ? "'".$this->db->idate($this->datec)."'" : 'null').","; + $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; + $sql.= " datep=".(dol_strlen($this->datep)!=0 ? "'".$this->db->idate($this->datep)."'" : 'null').","; + $sql.= " amount_capital=".(isset($this->amount_capital)?$this->amount_capital:"null").","; + $sql.= " amount_insurance=".(isset($this->amount_insurance)?$this->amount_insurance:"null").","; + $sql.= " amount_interest=".(isset($this->amount_interest)?$this->amount_interest:"null").","; + $sql.= " fk_typepayment=".(isset($this->fk_typepayment)?$this->fk_typepayment:"null").","; + $sql.= " num_payment=".(isset($this->num_payment)?"'".$this->db->escape($this->num_payment)."'":"null").","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; + $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; + $sql.= " fk_bank=".(isset($this->fk_bank)?$this->fk_bank:"null").","; + $sql.= " fk_user_creat=".(isset($this->fk_user_creat)?$this->fk_user_creat:"null").","; + $sql.= " fk_user_modif=".(isset($this->fk_user_modif)?$this->fk_user_modif:"null").""; + + $sql.= " WHERE rowid=".$this->id; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action call a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + // Commit or rollback + if ($error) + { + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Delete object in database + * + * @param User $user User that delete + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function delete($user, $notrigger=0) + { + global $conf, $langs; + $error=0; + + $this->db->begin(); + + if (! $error) + { + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql.= " WHERE rowid=".$this->id; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + if (! $error) + { + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action call a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + function calc_mens($capital,$rate,$nbterm) + { + $result=''; + + if (!empty($capital)&&!empty($rate)&&!empty($nbterm)) + { + $result=($capital*($rate/12))/(1-pow((1+($rate/12)),($nbterm*-1))); + } + + return $result; + } + + + /** + * Load all object in memory from database + * + * @param int $loanid Id object + * @return int <0 if KO, >0 if OK + */ + function fetchall($loanid) + { + global $langs; + + $sql = "SELECT"; + $sql.= " t.rowid,"; + $sql.= " t.fk_loan,"; + $sql.= " t.datec,"; + $sql.= " t.tms,"; + $sql.= " t.datep,"; + $sql.= " t.amount_capital,"; + $sql.= " t.amount_insurance,"; + $sql.= " t.amount_interest,"; + $sql.= " t.fk_typepayment,"; + $sql.= " t.num_payment,"; + $sql.= " t.note_private,"; + $sql.= " t.note_public,"; + $sql.= " t.fk_bank,"; + $sql.= " t.fk_user_creat,"; + $sql.= " t.fk_user_modif"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + $sql.= " WHERE t.fk_loan = ".$loanid; + + dol_syslog(get_class($this)."::fetchall", LOG_DEBUG); + $resql=$this->db->query($sql); + + if ($resql) + { + while($obj = $this->db->fetch_object($resql)) + { + $line = New LoanSchedule($this->db); + $line->id = $obj->rowid; + $line->ref = $obj->rowid; + + $line->fk_loan = $obj->fk_loan; + $line->datec = $this->db->jdate($obj->datec); + $line->tms = $this->db->jdate($obj->tms); + $line->datep = $this->db->jdate($obj->datep); + $line->amount_capital = $obj->amount_capital; + $line->amount_insurance = $obj->amount_insurance; + $line->amount_interest = $obj->amount_interest; + $line->fk_typepayment = $obj->fk_typepayment; + $line->num_payment = $obj->num_payment; + $line->note_private = $obj->note_private; + $line->note_public = $obj->note_public; + $line->fk_bank = $obj->fk_bank; + $line->fk_user_creat = $obj->fk_user_creat; + $line->fk_user_modif = $obj->fk_user_modif; + + $this->lines[] = $line; + } + $this->db->free($resql); + return 1; + } + else + { + $this->error="Error ".$this->db->lasterror(); + return -1; + } + } + + /** + * trans_paiment + * + * @return void + */ + function trans_paiment() + { + require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + + $toinsert = array(); + + $sql = "SELECT l.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."loan as l "; + $sql.= " WHERE l.paid = 0"; + $resql=$this->db->query($sql); + + if($resql){ + while($obj = $this->db->fetch_object($resql)){ + $lastrecorded = $this->lastpaiment($obj->rowid); + $toinsert = $this->paimenttorecord($obj->rowid, $lastrecorded); + if(count($toinsert)>0){ + foreach ($toinsert as $echid){ + $this->db->begin(); + $sql = "INSERT INTO " .MAIN_DB_PREFIX . "payment_loan "; + $sql.= "(fk_loan,datec,tms,datep,amount_capital,amount_insurance,amount_interest,fk_typepayment,num_payment,note_private,note_public,fk_bank,fk_user_creat,fk_user_modif) "; + $sql.= "SELECT fk_loan,datec,tms,datep,amount_capital,amount_insurance,amount_interest,fk_typepayment,num_payment,note_private,note_public,fk_bank,fk_user_creat,fk_user_modif FROM " . MAIN_DB_PREFIX . "loan_schedule WHERE rowid =" .$echid; + $res=$this->db->query($sql); + if($res){ + $this->db->commit(); + }else { + $this->db->rollback(); + } + } + } + } + } + } + + + /** + * trans_paiment + * + * @param int $loanid Loan id + * @return int < 0 if KO, Date > 0 if OK + */ + function lastpaiment($loanid) + { + $sql = "SELECT p.datep"; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p "; + $sql.= " WHERE p.fk_loan = " . $loanid; + $sql.= " ORDER BY p.datep DESC "; + $sql.= " LIMIT 1 "; + + $resql=$this->db->query($sql); + + if($resql){ + $obj = $this->db->fetch_object($resql); + return $this->db->jdate($obj->datep); + }else{ + return -1; + } + } + + /** + * paimenttorecord + * + * @param int $loanid Loan id + * @param int $datemax Date max + * @return array Array of id + */ + function paimenttorecord($loanid, $datemax) + { + $sql = "SELECT p.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p "; + $sql.= " WHERE p.fk_loan = " . $loanid; + if (!empty($datemax)) { $sql.= " AND p.datep > '" . $this->db->idate($datemax) ."'";} + $sql.= " AND p.datep <= '" . $this->db->idate(dol_now()). "'"; + + $resql=$this->db->query($sql); + + if($resql){ + while($obj = $this->db->fetch_object($resql)) + { + $result[] = $obj->rowid; + } + + } + + return $result; + } +} + diff --git a/htdocs/loan/createschedule.php b/htdocs/loan/createschedule.php new file mode 100644 index 0000000000000000000000000000000000000000..596cc9fd536865426ee4eed197c75f023ddd67d9 --- /dev/null +++ b/htdocs/loan/createschedule.php @@ -0,0 +1,208 @@ +<?php +/* Copyright (C) 2017 Franck Moreau <franck.moreau@theobald.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/loan/createecheancier.php + * \ingroup loan + * \brief Schedule card + */ + +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/loanschedule.class.php'; + +global $user; + +$loanid = GETPOST('loanid', 'int'); +$action = GETPOST('action'); + +$object = new Loan($db); +$object->fetch($loanid); + +$langs->load('loan'); + +if ($action == 'createecheancier') { + + $i=1; + while($i <$object->nbterm+1){ + + $date = GETPOST('hi_date'.$i,'int'); + $mens = GETPOST('mens'.$i); + $int = GETPOST('hi_interets'.$i); + + $echeance = new LoanSchedule($db); + + $echeance->fk_loan = $object->id; + $echeance->datec = dol_now(); + $echeance->tms = dol_now(); + $echeance->datepaid = $date; + $echeance->amount_capital = $mens-$int; + $echeance->amount_insurance = 0; + $echeance->amount_interest = $int; + $echeance->fk_typepayment = 3; + $echeance->fk_bank = 1; + $echeance->fk_user_creat = $user->id; + $echeance->fk_user_modif = $user->id; + $result=$echeance->create($user); + if ($result<0) { + setEventMessages(null, $echeance->errors,'errors'); + } + $i++; + } +} + +if ($action == 'updateecheancier') { + + $i=1; + while($i <$object->nbterm+1){ + + $mens = GETPOST('mens'.$i); + $int = GETPOST('hi_interets'.$i); + $id = GETPOST('hi_rowid'.$i); + $echeance = new LoanSchedule($db); + $echeance->fetch($id); + $echeance->tms = dol_now(); + $echeance->amount_capital = $mens-$int; + $echeance->amount_insurance = 0; + $echeance->amount_interest = $int; + $echeance->fk_user_modif = $user->id; + $result= $echeance->update($user,0); + if ($result<0) { + setEventMessages(null, $echeance->errors,'errors'); + } + $i++; + } +} + +$echeance = new LoanSchedule($db); +$echeance->fetchall($object->id); + +top_htmlhead('', ''); +$var = ! $var; + + +?> +<script type="text/javascript" language="javascript"> +$(document).ready(function() { + $('[name^="mens"]').focusout(function() { + var echeance=$(this).attr('ech'); + var mens=$(this).val(); + var idcap=echeance-1; + idcap = '#hi_capital'+idcap; + var capital=$(idcap).val(); + $.ajax({ + dataType: 'json', + url: 'calcmens.php', + data: { echeance: echeance, mens: mens, capital:capital, rate:<?php echo $object->rate/100;?> , nbterm : <?php echo $object->nbterm;?>}, + success: function(data) { + $.each(data, function(index, element) { + var idcap_res='#hi_capital'+index; + var idcap_res_srt='#capital'+index; + var interet_res='#hi_interets'+index; + var interet_res_str='#interets'+index; + var men_res='#mens'+index; + $(idcap_res).val(element.cap_rest); + $(idcap_res_srt).text(element.cap_rest_str+' €'); + $(interet_res).val(element.interet); + $(interet_res_str).text(element.interet_str+' €'); + $(men_res).val(element.mens); + }); + } + }); + }); +}); +</script> +<?php + + +print '<form name="createecheancier" action="' . $_SERVER["PHP_SELF"] . '" method="POST">'; +print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">'; +print '<input type="hidden" name="loanid" value="' . $loanid . '">'; +if(count($echeance->lines)>0){ + print '<input type="hidden" name="action" value="updateecheancier">'; +}else{ + print '<input type="hidden" name="action" value="createecheancier">'; +} +print '<table class="border" width="100%">'; +print '<tr class="liste_titre">'; +print '<th align="center" colspan="5">' . "Création d'échéancier</th>"; +print '</tr>'; + +print '<tr class="liste_titre">'; +Print '<th width="10%" align="center"> Echéance </th>'; +Print '<th width="10%" align="center"> Date </th>'; +Print '<th width="10%" align="center"> Montant </th>'; +Print '<th width="20%" align="center"> Intérêts </th>'; +Print '<th width="40%" align="center"> Capital restant du </th>'; +print '</tr>'; + +if ($object->nbterm > 0 && count($echeance->lines)==0) +{ + $i=1; + $capital = $object->capital; + while($i <$object->nbterm+1){ + $mens = round($echeance->calc_mens($capital, $object->rate/100, $object->nbterm-$i+1),2,PHP_ROUND_HALF_UP); + $int = ($capital*($object->rate/12))/100; + $int = round($int,2,PHP_ROUND_HALF_UP); + $cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP); + print '<tr>'; + print '<td align="center" id="n'.$i.'">' . $i .'</td>'; + print '<td align="center" id ="date' .$i .'"><input type="hidden" name="hi_date' .$i .'" id ="hi_date' .$i .'" value="' . dol_time_plus_duree($object->datestart, $i-1, 'm') . '">' . dol_print_date(dol_time_plus_duree($object->datestart, $i-1, 'm'),'day') . '</td>'; + print '<td align="center"><input name="mens'.$i.'" id="mens'.$i.'" size="5" value="'.$mens.'" ech="'.$i.'"> €</td>'; + print '<td align="center" id="interets'.$i.'">'.price($int,0,'',1).' €</td><input type="hidden" name="hi_interets' .$i .'" id ="hi_interets' .$i .'" value="' . $int . '">'; + print '<td align="center" id="capital'.$i.'">'.price($cap_rest).' €</td><input type="hidden" name="hi_capital' .$i .'" id ="hi_capital' .$i .'" value="' . $cap_rest . '">'; + print '</tr>'; + $i++; + $capital = $cap_rest; + } +}elseif(count($echeance->lines)>0){ + $i=1; + $capital = $object->capital; + foreach ($echeance->lines as $line){ + $mens = $line->amount_capital+$line->amount_insurance+$line->amount_interest; + $int = $line->amount_interest; + $cap_rest = round($capital - ($mens-$int),2,PHP_ROUND_HALF_UP); + print '<tr>'; + print '<td align="center" id="n'.$i.'"><input type="hidden" name="hi_rowid' .$i .'" id ="hi_rowid' .$i .'" value="' . $line->id . '">' . $i .'</td>'; + print '<td align="center" id ="date' .$i .'"><input type="hidden" name="hi_date' .$i .'" id ="hi_date' .$i .'" value="' . $line->datep . '">' . dol_print_date($line->datep,'day') . '</td>'; + if($line->datep > dol_now()){ + print '<td align="center"><input name="mens'.$i.'" id="mens'.$i.'" size="5" value="'.$mens.'" ech="'.$i.'"> €</td>'; + }else{ + print '<td align="center">' . price($mens) . ' €</td><input type="hidden" name="mens' .$i .'" id ="mens' .$i .'" value="' . $mens . '">'; + } + print '<td align="center" id="interets'.$i.'">'.price($int,0,'',1).' €</td><input type="hidden" name="hi_interets' .$i .'" id ="hi_interets' .$i .'" value="' . $int . '">'; + print '<td align="center" id="capital'.$i.'">'.price($cap_rest).' €</td><input type="hidden" name="hi_capital' .$i .'" id ="hi_capital' .$i .'" value="' . $cap_rest . '">'; + print '</tr>'; + $i++; + $capital = $cap_rest; + } +} + +print '</table>'; +print '</br>'; +print '</br>'; +print '<div align="center"><input class="button" type="submit" value="'.$langs->trans("Save").'"></div>'; +print '</form>'; + +llxFooter(); +$db->close(); + + + diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 63b92bc6468ddbd78fdaaf12f577545ab6540aa5..b3f2cc87d73af349a1eb3745456b2dc410c19769 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -39,20 +39,23 @@ require_once '../lib/mymodule.lib.php'; $langs->load("mymodule@mymodule"); // Access control -if (! $user->admin) { - accessforbidden(); -} +if (! $user->admin) accessforbidden(); // Parameters $action = GETPOST('action', 'alpha'); + /* * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + + /* * View */ + $page_name = "MyModuleSetup"; llxHeader('', $langs->trans($page_name)); diff --git a/htdocs/modulebuilder/template/class/actions_mymodule.class.php b/htdocs/modulebuilder/template/class/actions_mymodule.class.php index f3ce5963aa6193d5f62e68f6d4628133f836518a..7f1897c80ae021df7e1826d3260d4c1ba51ca0ad 100644 --- a/htdocs/modulebuilder/template/class/actions_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/actions_mymodule.class.php @@ -62,24 +62,101 @@ class ActionsMyModule */ public function doActions($parameters, &$object, &$action, $hookmanager) { + global $conf, $user, $langs; + $error = 0; // Error counter - $myvalue = 'test'; // A result value + /* print_r($parameters); - echo "action: " . $action; print_r($object); + echo "action: " . $action; + */ + + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) { // do something only for the context 'somecontext1' or 'somecontext2' + - if (in_array('somecontext', explode(':', $parameters['context']))) { - // do something only for the context 'somecontext' } if (! $error) { - $this->results = array('myreturn' => $myvalue); + $this->results = array('myreturn' => 999); $this->resprints = 'A text to show'; - return 0; // or return 1 to replace standard code + return 0; // or return 1 to replace standard code } else { $this->errors[] = 'Error message'; return -1; } } + + + /** + * Overloading the doActions function : replacing the parent's function with the one below + * + * @param array() $parameters Hook metadatas (context, etc...) + * @param CommonObject $object The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...) + * @param string $action Current action (if set). Generally create or edit or null + * @param HookManager $hookmanager Hook manager propagated to allow calling another hook + * @return int < 0 on error, 0 on success, 1 to replace standard code + */ + public function doMassActions($parameters, &$object, &$action, $hookmanager) + { + global $conf, $user, $langs; + + $error = 0; // Error counter + + /* + print_r($parameters); + print_r($object); + echo "action: " . $action; + */ + + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) { // do something only for the context 'somecontext1' or 'somecontext2' + + foreach($parameters['toselect'] as $objectid) + { + // Do action on each object id + + } + } + + if (! $error) { + $this->results = array('myreturn' => 999); + $this->resprints = 'A text to show'; + return 0; // or return 1 to replace standard code + } else { + $this->errors[] = 'Error message'; + return -1; + } + } + + + /** + * Overloading the addMoreMassActions function : replacing the parent's function with the one below + * + * @param array() $parameters Hook metadatas (context, etc...) + * @param CommonObject $object The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...) + * @param string $action Current action (if set). Generally create or edit or null + * @param HookManager $hookmanager Hook manager propagated to allow calling another hook + * @return int < 0 on error, 0 on success, 1 to replace standard code + */ + public function addMoreMassActions($parameters, &$object, &$action, $hookmanager) + { + global $conf, $user, $langs; + + $error = 0; // Error counter + + if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2'))) // do something only for the context 'somecontext' + { + $this->resprints = '<option value="0"'.($disabled?' disabled="disabled"':'').'>'.$langs->trans("MyModuleMassAction").'</option>'; + } + + if (! $error) { + return 0; // or return 1 to replace standard code + } else { + $this->errors[] = 'Error message'; + return -1; + } + } + + + } diff --git a/htdocs/modulebuilder/template/img/object_mytest.png b/htdocs/modulebuilder/template/img/object_mytest.png new file mode 100644 index 0000000000000000000000000000000000000000..5a307bfc62f85df909a3cf024f27ee87d44be275 Binary files /dev/null and b/htdocs/modulebuilder/template/img/object_mytest.png differ diff --git a/htdocs/modulebuilder/template/langs/en_US/mymodule.lang b/htdocs/modulebuilder/template/langs/en_US/mymodule.lang index 53c6205386c57379f07ed1d043ab16e75e2314ff..c33f2453fc43f54f527900793dc474738e20f3f1 100644 --- a/htdocs/modulebuilder/template/langs/en_US/mymodule.lang +++ b/htdocs/modulebuilder/template/langs/en_US/mymodule.lang @@ -18,12 +18,10 @@ # Generic # -# Module label 'ModuleXXXName' -# (where XXX is value of numeric property 'numero' of module) -Module500000Name = My module -# Module description 'ModuleXXXDesc' -# (where XXX is value of numeric property 'numero' of module) -Module500000Desc = My module description +# Module label 'ModuleMyModuleName' +ModuleMyModuleName = My module +# Module description 'ModuleMyModuleDesc' +ModuleMyModuleDesc = My module description # # Admin page diff --git a/htdocs/modulebuilder/template/langs/fr_FR/mymodule.lang b/htdocs/modulebuilder/template/langs/fr_FR/mymodule.lang index d15d37f0ebf1e60a1040c41f15b0e055f6296546..06e7ba3388524cc0cb9bedf5c5cc3b8fc80b4eb6 100644 --- a/htdocs/modulebuilder/template/langs/fr_FR/mymodule.lang +++ b/htdocs/modulebuilder/template/langs/fr_FR/mymodule.lang @@ -18,12 +18,10 @@ # Générique # -# Module label 'ModuleXXXName' -# (where XXX is value of numeric property 'numero' of module) -Module500000Name = Mon module -# Module description 'ModuleXXXDesc' -# (where XXX is value of numeric property 'numero' of module) -Module500000Desc = Description de mon module +# Module label 'ModuleMyModuleName' +ModuleMyModuleName = Mon module +# Module description 'ModuleMyModuleDesc' +ModuleMyModuleDesc = Description de mon module # # Page d'administration diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 5183eeb338282ddae61219880fc9184db5d34248..172bdd9354cce00328a9c28b45a8ff425b3d1145 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -74,6 +74,9 @@ $error = 0; * Actions */ +$nomessageinsetmoduleoptions=1; +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'setcodeproduct') { if (dolibarr_set_const($db, "PRODUCT_CODEPRODUCT_ADDON",$value,'chaine',0,'',$conf->entity) > 0) @@ -87,36 +90,6 @@ if ($action == 'setcodeproduct') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - //setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - // message yet present at the bottom if($action) - //setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - if ($action == 'other' && GETPOST('value_PRODUIT_LIMIT_SIZE') >= 0) { $res = dolibarr_set_const($db, "PRODUIT_LIMIT_SIZE", GETPOST('value_PRODUIT_LIMIT_SIZE'),'chaine',0,'',$conf->entity); @@ -278,7 +251,7 @@ if ($action) } else { - setEventMessages($langs->trans("Error"), null, 'errors'); + setEventMessages($langs->trans("SetupNotError"), null, 'errors'); } } @@ -543,7 +516,7 @@ foreach ($dirmodels as $reldir) print '</table>'; print "<br>"; - + /* * Other conf */ @@ -598,7 +571,7 @@ print '</tr>'; // multiprix nombre de prix a proposer if (! empty($conf->global->PRODUIT_MULTIPRICES)) { - + print '<tr class="oddeven">'; print '<td>'.$langs->trans("MultiPricesNumPrices").'</td>'; print '<td align="right"><input size="3" type="text" class="flat" name="value_PRODUIT_MULTIPRICES_LIMIT" value="'.$conf->global->PRODUIT_MULTIPRICES_LIMIT.'"></td>'; @@ -640,7 +613,7 @@ print '</tr>'; if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) { - + print '<tr class="oddeven">'; print '<td>'.$langs->trans("NumberOfProductShowInSelect").'</td>'; print '<td align="right"><input size="3" type="text" class="flat" name="value_PRODUIT_LIMIT_SIZE" value="'.$conf->global->PRODUIT_LIMIT_SIZE.'"></td>'; @@ -681,7 +654,7 @@ print '</tr>'; // View product description in thirdparty language if (! empty($conf->global->MAIN_MULTILANGS)) { - + print '<tr class="oddeven">'; print '<td>'.$langs->trans("ViewProductDescInThirdpartyLanguageAbility").'</td>'; print '<td width="60" align="right">'; @@ -723,7 +696,7 @@ if (! empty($conf->global->PRODUCT_CANVAS_ABILITY)) if ($conf->$module->enabled) { - + print "<tr ".$bc[$var]."><td>"; print $object->description; diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php index a2b3f1cc667e157aa7eadd62ac3ae73b728ac0b4..9cda69560d59c2f17826f0b742a167aa50596b77 100644 --- a/htdocs/projet/activity/perday.php +++ b/htdocs/projet/activity/perday.php @@ -34,6 +34,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; $langs->load('projects'); +$langs->load('users'); $action=GETPOST('action','aZ09'); $mode=GETPOST("mode"); @@ -62,6 +63,8 @@ $month=GETPOST('remonth')?GETPOST('remonth'):(GETPOST("month","int")?GETPOST("mo $day=GETPOST('reday')?GETPOST('reday'):(GETPOST("day","int")?GETPOST("day","int"):date("d")); $day = (int) $day; $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); + +$search_usertoprocessid=GETPOST('search_usertoprocessid', 'int'); $search_task_ref=GETPOST('search_task_ref', 'alpha'); $search_task_label=GETPOST('search_task_label', 'alpha'); $search_project_ref=GETPOST('search_project_ref', 'alpha'); @@ -75,6 +78,17 @@ $daytoparse = $now; if ($yearofday && $monthofday && $dayofday) $daytoparse=dol_mktime(0, 0, 0, $monthofday, $dayofday, $yearofday); // xxxofday is value of day after submit action 'addtime' else if ($year && $month && $day) $daytoparse=dol_mktime(0, 0, 0, $month, $day, $year); // this are value submited after submit of action 'submitdateselect' +if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) +{ + $usertoprocess=$user; +} +else +{ + $usertoprocess=new User($db); + $usertoprocess->fetch($search_usertoprocessid); +} +$search_usertoprocessid=$usertoprocess->id; + $object=new Task($db); @@ -83,9 +97,10 @@ $object=new Task($db); */ // Purge criteria -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers { $action = ''; + $search_usertoprocessid = ''; $search_task_ref = ''; $search_task_label = ''; $search_project_ref = ''; @@ -125,7 +140,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') } if (! $error) { - $idfortaskuser=$user->id; + $idfortaskuser=$usertoprocess->id; $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal'); if ($result >= 0 || $result == -2) // Contact add ok or already contact of task @@ -143,7 +158,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') $project->fetch($object->fk_project); // Get type $listofprojcontact=$project->liste_type_contact('internal'); - + if (count($listofprojcontact)) { $typeforprojectcontact=reset(array_keys($listofprojcontact)); @@ -151,7 +166,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') } } } - else + else { dol_print_error($db); } @@ -175,6 +190,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') if (! $error) { setEventMessages("TaskAssignedToEnterTime", null); + $taskid=0; } $action=''; @@ -247,12 +263,12 @@ if ($action == 'addtime' && $user->rights->projet->lire) setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); // Redirect to avoid submit twice on back - header('Location: '.$_SERVER["PHP_SELF"].($projectid?'?id='.$projectid:'?').($mode?'&mode='.$mode:'').'&year='.$yearofday.'&month='.$monthofday.'&day='.$dayofday); + header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($mode?'&mode='.$mode:'').'&year='.$yearofday.'&month='.$monthofday.'&day='.$dayofday); exit; } } - else - { + else + { setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors'); } } @@ -286,8 +302,6 @@ $next_day = $next['mday']; $title=$langs->trans("TimeSpent"); if ($mine) $title=$langs->trans("MyTimeSpent"); -$usertoprocess = $user; - $projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess,0,1); // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project if ($id) @@ -314,8 +328,9 @@ llxHeader("",$title,""); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); $param=''; -$param.=($mode?'&mode='.$mode:''); -$param.=($search_project_ref?'&search_project_ref='.$search_project_ref:''); +$param.=($mode?'&mode='.$mode:''); +$param.=($search_project_ref?'&search_project_ref='.$search_project_ref:''); +$param.=($search_userassignedid > 0?'&search_userassignedid='.$search_usertoprocessid:''); // Show navigation bar $nav ='<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n"; @@ -337,7 +352,7 @@ print '<input type="hidden" name="addtimeyear" value="'.$tmp['year'].'">'; print '<input type="hidden" name="addtimemonth" value="'.$tmp['mon'].'">'; print '<input type="hidden" name="addtimeday" value="'.$tmp['mday'].'">'; -$head=project_timesheet_prepare_head($mode); +$head=project_timesheet_prepare_head($mode, $usertoprocess); dol_fiche_head($head, 'inputperday', '', -1, 'task'); // Show description of content @@ -360,45 +375,17 @@ print '</div>'; dol_fiche_end(); - -// Filter on user -/* dol_fiche_head(''); - print '<table class="border" width="100%"><tr><td width="25%">'.$langs->trans("User").'</td>'; - print '<td>'; - if ($mine) print $user->getLoginUrl(1); - print '</td>'; - print '</tr></table>'; - dol_fiche_end(); -*/ - -// Filter on user -/* dol_fiche_head(''); - print '<table class="border" width="100%"><tr><td width="25%">'.$langs->trans("User").'</td>'; - print '<td>'; - if ($mine) print $user->getLoginUrl(1); - print '</td>'; - print '</tr></table>'; - dol_fiche_end(); -*/ - - -// Add a new project/task -//print '<br>'; -//print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; -//print '<input type="hidden" name="action" value="assigntask">'; -//print '<input type="hidden" name="mode" value="'.$mode.'">'; -//print '<input type="hidden" name="year" value="'.$year.'">'; -//print '<input type="hidden" name="month" value="'.$month.'">'; -//print '<input type="hidden" name="day" value="'.$day.'">'; - -print '<div class="floatright right">'.$nav.'</div>'; // We move this before the assign to components so, the default submit button is not the assign to. +print '<div class="floatright right'.($conf->dol_optimize_smallscreen?' centpercent':'').'">'.$nav.'</div>'; // We move this before the assign to components so, the default submit button is not the assign to. print '<div class="float valignmiddle">'; -print $langs->trans("AssignTaskToMe").'<br>'; +$titleassigntask = $langs->trans("AssignTaskToMe"); +if ($usertoprocess->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", $usertoprocess->getFullName($langs)); +print '<div class="taskiddiv inline-block">'; $formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1); -print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0); -print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.$langs->trans("AssignTask").'">'; -//print '</form>'; +print '</div>'; +print ' '; +print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0, 'maxwidth200'); +print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.dol_escape_htmltag($titleassigntask).'">'; print '</div>'; print '<div class="clearboth" style="padding-bottom: 8px;"></div>'; @@ -408,6 +395,11 @@ print '<div class="div-table-responsive">'; print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'" id="tablelines3">'."\n"; print '<tr class="liste_titre_filter">'; +print '<td class="liste_titre">'; +$usersettoshow='hierarchyme'; +if ($user->rights->projet->all->lire) $usersettoshow=''; +print $form->select_dolusers($usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $usersettoshow, 0, 0, 0, 1, '', 0, '', 'maxwidth150'); +print '</td>'; print '<td class="liste_titre"><input type="text" size="4" name="search_task_ref" value="'.dol_escape_htmltag($search_task_ref).'"></td>'; print '<td class="liste_titre"><input type="text" size="4" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>'; print '<td class="liste_titre"><input type="text" size="4" name="search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>'; @@ -427,6 +419,7 @@ print '</td>'; print "</tr>\n"; print '<tr class="liste_titre">'; +print '<td>'.$langs->trans("User").'</td>'; print '<td>'.$langs->trans("RefTask").'</td>'; print '<td>'.$langs->trans("LabelTask").'</td>'; print '<td>'.$langs->trans("ProjectRef").'</td>'; @@ -436,12 +429,15 @@ if (! empty($conf->global->PROJECT_LINES_PERDAY_SHOW_THIRDPARTY)) } print '<td align="right" class="maxwidth100">'.$langs->trans("PlannedWorkload").'</td>'; print '<td align="right" class="maxwidth100">'.$langs->trans("ProgressDeclared").'</td>'; -print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpent").'</td>'; +/*print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpent").'</td>'; if ($usertoprocess->id == $user->id) print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpentByYou").'</td>'; -else print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpentByUser").'</td>'; +else print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpentByUser").'</td>';*/ +print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpent").'<br>('.$langs->trans("Everybody").')</td>'; +print '<td align="right" class="maxwidth100">'.$langs->trans("TimeSpent").'</td>'; print '<td align="center">'.$langs->trans("HourStart").'</td>'; -print '<td align="center" colspan="2">'.$langs->trans("Duration").'</td>'; +print '<td align="center">'.$langs->trans("Duration").'</td>'; print '<td align="right">'.$langs->trans("Note").'</td>'; +print '<td align="center"></td>'; print "</tr>\n"; @@ -455,7 +451,7 @@ if (count($tasksarray) > 0) } else { - print '<tr><td colspan="10">'.$langs->trans("NoTasks").'</td></tr>'; + print '<tr><td colspan="14">'.$langs->trans("NoTasks").'</td></tr>'; } print "</table>"; print '</div>'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index da5303511ad76b9742e897ffed6db11d931a59a0..4a2156430af51940cb9388063f1fa7896d60c609 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -58,11 +58,14 @@ $nowtmp=dol_getdate($now); $nowday=$nowtmp['mday']; $nowmonth=$nowtmp['mon']; $nowyear=$nowtmp['year']; + $year=GETPOST('reyear')?GETPOST('reyear','int'):(GETPOST("year")?GETPOST("year","int"):date("Y")); $month=GETPOST('remonth')?GETPOST('remonth','int'):(GETPOST("month")?GETPOST("month","int"):date("m")); $day=GETPOST('reday')?GETPOST('reday','int'):(GETPOST("day")?GETPOST("day","int"):date("d")); $day = (int) $day; $week=GETPOST("week","int")?GETPOST("week","int"):date("W"); + +$search_usertoprocessid=GETPOST('search_usertoprocessid', 'int'); $search_task_ref=GETPOST('search_task_ref', 'alpha'); $search_task_label=GETPOST('search_task_label', 'alpha'); $search_project_ref=GETPOST('search_project_ref', 'alpha'); @@ -88,7 +91,16 @@ $next_day = $next['day']; $firstdaytoshow=dol_mktime(0,0,0,$first_month,$first_day,$first_year); $lastdaytoshow=dol_time_plus_duree($firstdaytoshow, 7, 'd'); -$usertoprocess=$user; +if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) +{ + $usertoprocess=$user; +} +else +{ + $usertoprocess=new User($db); + $usertoprocess->fetch($search_usertoprocessid); +} +$search_usertoprocessid=$usertoprocess->id; $object=new Task($db); @@ -98,9 +110,10 @@ $object=new Task($db); */ // Purge criteria -if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // Both test are required to be compatible with all browsers +if (GETPOST("button_removefilter_x") || GETPOST("button_removefilter.x") || GETPOST("button_removefilter")) // All tests are required to be compatible with all browsers { $action = ''; + $search_usertoprocessid = ''; $search_task_ref = ''; $search_task_label = ''; $search_project_ref = ''; @@ -137,13 +150,13 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors'); $error++; } - + if (! $error) { - $idfortaskuser=$user->id; + $idfortaskuser=$usertoprocess->id; $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal'); - if (! $result || $result == -2) // Contact add ok or already contact of task + if ($result >= 0 || $result == -2) // Contact add ok or already contact of task { // Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project) $sql='SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact'; @@ -158,7 +171,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') $project->fetch($object->fk_project); // Get type $listofprojcontact=$project->liste_type_contact('internal'); - + if (count($listofprojcontact)) { $typeforprojectcontact=reset(array_keys($listofprojcontact)); @@ -166,7 +179,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') } } } - else + else { dol_print_error($db); } @@ -190,6 +203,7 @@ if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') if (! $error) { setEventMessages("TaskAssignedToEnterTime", null); + $taskid=0; } $action=''; @@ -233,16 +247,16 @@ if ($action == 'addtime' && $user->rights->projet->lire) $error++; break; } - + $updateoftaskdone++; } } } - + if (! $updateoftaskdone) // Check to update progress if no update were done on task. { $object->fetch($taskid); - //var_dump($object->progress);var_dump(GETPOST($taskid . 'progress', 'int')); exit; + //var_dump($object->progress);var_dump(GETPOST($taskid . 'progress', 'int')); exit; if ($object->progress != GETPOST($taskid . 'progress', 'int')) { $object->progress = GETPOST($taskid . 'progress', 'int'); @@ -262,7 +276,7 @@ if ($action == 'addtime' && $user->rights->projet->lire) setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); // Redirect to avoid submit twice on back - header('Location: '.$_SERVER["PHP_SELF"].($projectid?'?id='.$projectid:'?').($mode?'&mode='.$mode:'').($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:'')); + header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($mode?'&mode='.$mode:'').($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:'')); exit; } } @@ -312,14 +326,15 @@ llxHeader("",$title,"",'','','',array('/core/js/timesheet.js')); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project'); $param=''; -$param.=($mode?'&mode='.$mode:''); -$param.=($search_project_ref?'&search_project_ref='.$search_project_ref:''); +$param.=($mode?'&mode='.$mode:''); +$param.=($search_project_ref?'&search_project_ref='.$search_project_ref:''); +$param.=($search_usertoprocessid > 0?'&search_usertoprocessid='.$search_usertoprocessid:''); // Show navigation bar -$nav ='<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n"; +$nav ='<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n"; $nav.=" <span id=\"month_name\">".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("WeekShort")." ".$week." </span>\n"; -$nav.='<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n"; -$nav.=" (<a href=\"?year=".$nowyear."&month=".$nowmonth."&day=".$nowday.$param."\">".$langs->trans("Today")."</a>)"; +$nav.='<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n"; +$nav.=" (<a href=\"?year=".$nowyear."&month=".$nowmonth."&day=".$nowday.$param."\">".$langs->trans("Today")."</a>)"; $nav.='<br>'.$form->select_date(-1,'',0,0,2,"addtime",1,0,1).' '; $nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">'; @@ -333,7 +348,7 @@ print '<input type="hidden" name="day" value="'.$day.'">'; print '<input type="hidden" name="month" value="'.$month.'">'; print '<input type="hidden" name="year" value="'.$year.'">'; -$head=project_timesheet_prepare_head($mode); +$head=project_timesheet_prepare_head($mode, $usertoprocess); dol_fiche_head($head, 'inputperweek', '', -1, 'task'); // Show description of content @@ -356,44 +371,17 @@ print '</div>'; dol_fiche_end(); -// Filter on user -/* dol_fiche_head(''); - print '<table class="border" width="100%"><tr><td width="25%">'.$langs->trans("User").'</td>'; - print '<td>'; - if ($mine) print $user->getLoginUrl(1); - print '</td>'; - print '</tr></table>'; - dol_fiche_end(); -*/ - -// Filter on user -/* dol_fiche_head(''); - print '<table class="border" width="100%"><tr><td width="25%">'.$langs->trans("User").'</td>'; - print '<td>'; - if ($mine) print $user->getLoginUrl(1); - print '</td>'; - print '</tr></table>'; - dol_fiche_end(); -*/ - - -// Add a new project/task -//print '<br>'; -//print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; -//print '<input type="hidden" name="action" value="assigntask">'; -//print '<input type="hidden" name="mode" value="'.$mode.'">'; -//print '<input type="hidden" name="year" value="'.$year.'">'; -//print '<input type="hidden" name="month" value="'.$month.'">'; -//print '<input type="hidden" name="day" value="'.$day.'">'; - -print '<div class="floatright right">'.$nav.'</div>'; // We move this before the assign to components so, the default submit button is not the assign to. +print '<div class="floatright right'.($conf->dol_optimize_smallscreen?' centpercent':'').'">'.$nav.'</div>'; // We move this before the assign to components so, the default submit button is not the assign to. print '<div class="float valignmiddle">'; -print $langs->trans("AssignTaskToMe").'<br>'; +$titleassigntask = $langs->trans("AssignTaskToMe"); +if ($usertoprocess->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", $usertoprocess->getFullName($langs)); +print '<div class="taskiddiv inline-block">'; $formproject->selectTasks($socid?$socid:-1, $taskid, 'taskid', 32, 0, 1, 1); -print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0); -print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.$langs->trans("AssignTask").'">'; -//print '</form>'; +print '</div>'; +print ' '; +print $formcompany->selectTypeContact($object, '', 'type','internal','rowid', 0, 'maxwidth200'); +print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.dol_escape_htmltag($titleassigntask).'">'; print '</div>'; print '<div class="clearboth" style="padding-bottom: 8px;"></div>'; @@ -403,6 +391,11 @@ print '<div class="div-table-responsive">'; print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'" id="tablelines3">'."\n"; print '<tr class="liste_titre_filter">'; +print '<td class="liste_titre">'; +$usersettoshow='hierarchyme'; +if ($user->rights->projet->all->lire) $usersettoshow=''; +print $form->select_dolusers($usertoprocess->id, 'search_usertoprocessid', 0, null, 0, $usersettoshow, 0, 0, 0, 1, '', 0, '', 'maxwidth150'); +print '</td>'; print '<td class="liste_titre"><input type="text" size="4" name="search_task_ref" value="'.dol_escape_htmltag($search_task_ref).'"></td>'; print '<td class="liste_titre"><input type="text" size="4" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>'; print '<td class="liste_titre"><input type="text" size="4" name="search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>'; @@ -423,6 +416,7 @@ print '</td>'; print "</tr>\n"; print '<tr class="liste_titre">'; +print '<td>'.$langs->trans("User").'</td>'; print '<td>'.$langs->trans("RefTask").'</td>'; print '<td>'.$langs->trans("LabelTask").'</td>'; print '<td>'.$langs->trans("ProjectRef").'</td>'; @@ -432,9 +426,11 @@ if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) } print '<td align="right" class="maxwidth75">'.$langs->trans("PlannedWorkload").'</td>'; print '<td align="right" class="maxwidth75">'.$langs->trans("ProgressDeclared").'</td>'; +/*print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'</td>'; + if ($usertoprocess->id == $user->id) print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByYou").'</td>'; + else print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByUser").'</td>';*/ +print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'<br>('.$langs->trans("Everybody").')</td>'; print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'</td>'; -if ($usertoprocess->id == $user->id) print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByYou").'</td>'; -else print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByUser").'</td>'; $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); @@ -452,16 +448,16 @@ if (count($tasksarray) > 0) { //var_dump($tasksarray); //var_dump($tasksrole); - + $j=0; $level=0; projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask); - $colspan=7; + $colspan=8; if (! empty($conf->global->PROJECT_LINES_PERWEEK_SHOW_THIRDPARTY)) $colspan++; - + print '<tr class="liste_total"> - <td class="liste_total" colspan="'.$colspan.'" align="right">'.$langs->trans("Total").'</td> + <td class="liste_total" colspan="'.$colspan.'">'.$langs->trans("Total").'</td> <td class="liste_total hide0" align="center"><div id="totalDay[0]"> </div></td> <td class="liste_total hide1" align="center"><div id="totalDay[1]"> </div></td> <td class="liste_total hide2" align="center"><div id="totalDay[2]"> </div></td> @@ -474,7 +470,7 @@ if (count($tasksarray) > 0) } else { - print '<tr><td colspan="11">'.$langs->trans("NoTasks").'</td></tr>'; + print '<tr><td colspan="16">'.$langs->trans("NoTasks").'</td></tr>'; } print "</table>"; print '</div>'; diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php index fbcecf032cf7f1be200aeaf9619c8d691f990b1f..9e35ea77e0bca38a898e812c709ef8ec705f6e6b 100644 --- a/htdocs/projet/admin/project.php +++ b/htdocs/projet/admin/project.php @@ -51,6 +51,8 @@ $type='project'; * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'setmainoptions') { if (GETPOST('PROJECT_USE_OPPORTUNITIES')) dolibarr_set_const($db, "PROJECT_USE_OPPORTUNITIES",GETPOST('PROJECT_USE_OPPORTUNITIES'),'chaine',0,'',$conf->entity); @@ -104,7 +106,7 @@ else if ($action == 'specimen') $project = new Project($db); $project->initAsSpecimen(); - + // Search template files $file=''; $classname=''; $filefound=0; $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); @@ -188,35 +190,6 @@ else if ($action == 'specimentask') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a model else if ($action == 'set') { @@ -414,7 +387,7 @@ foreach ($dirmodels as $reldir) if ($module->isEnabled()) { - + print '<tr class="oddeven"><td>'.$module->name."</td><td>\n"; print $module->info(); print '</td>'; @@ -518,7 +491,7 @@ if (empty($conf->global->PROJECT_HIDE_TASKS)) if ($module->isEnabled()) { - + print '<tr class="oddeven"><td>'.$module->name."</td><td>\n"; print $module->info(); print '</td>'; @@ -660,7 +633,7 @@ foreach ($dirmodels as $reldir) if ($modulequalified) { - + print '<tr class="oddeven"><td width="100">'; print (empty($module->name)?$name:$module->name); print "</td><td>\n"; diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index f6355ec556698199563d3d394a1a50d04a2e14df..0b45a0d0696b95fde1d53f56244d2215fa32ae39 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -134,7 +134,7 @@ if (empty($reshook)) $error++; setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors'); } - + if (! $error) { $error=0; @@ -308,8 +308,8 @@ if (empty($reshook)) setEventMessages($langs->trans("FailedToCloseProject").':'.$object->error, $object->errors, 'errors'); } } - - + + if ($error) { $db->rollback(); @@ -322,7 +322,7 @@ if (empty($reshook)) if (GETPOST('socid','int') > 0) $object->fetch_thirdparty(GETPOST('socid','int')); else unset($object->thirdparty); } - + } // Build doc @@ -623,7 +623,7 @@ if ($action == 'create' && $user->rights->projet->creer) { print ' '; print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">'; - } + } print '</div>'; print '</form>'; @@ -645,12 +645,12 @@ if ($action == 'create' && $user->rights->projet->creer) }); </script>'; } -elseif ($object->id > 0) +elseif ($object->id > 0) { /* * Show or edit */ - + $res=$object->fetch_optionals($object->id,$extralabels); // To verify role of users @@ -711,10 +711,11 @@ elseif ($object->id > 0) print '<input type="hidden" name="comefromclone" value="'.$comefromclone.'">'; $head=project_prepare_head($object); - dol_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); if ($action == 'edit' && $userWrite > 0) { + dol_fiche_head($head, 'project', $langs->trans("Project"), 0, ($object->public?'projectpub':'project')); + print '<table class="border" width="100%">'; // Ref @@ -835,27 +836,30 @@ elseif ($object->id > 0) } else { + dol_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public?'projectpub':'project')); + // Project card - + $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; - + $morehtmlref='<div class="refidno">'; // Title $morehtmlref.=$object->title; // Thirdparty - if ($object->thirdparty->id > 0) + $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : '; + if ($object->thirdparty->id > 0) { - $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project'); + $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project'); } $morehtmlref.='</div>'; - + // Define a complementary filter for search of next/prev ref. if (! $user->rights->projet->all->lire) { $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0); $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")"; } - + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); @@ -889,7 +893,7 @@ elseif ($object->id > 0) if (strcmp($object->opp_amount,'')) print price($object->opp_amount,0,$langs,1,0,0,$conf->currency); print '</td></tr>'; } - + // Date start - end print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>'; $start = dol_print_date($object->date_start,'dayhour'); @@ -899,7 +903,7 @@ elseif ($object->id > 0) print ($end?$end:'?'); if ($object->hasDelay()) print img_warning("Late"); print '</td></tr>'; - + // Budget print '<tr><td>'.$langs->trans("Budget").'</td><td>'; if (strcmp($object->budget_amount, '')) print price($object->budget_amount,0,$langs,1,0,0,$conf->currency); @@ -908,16 +912,16 @@ elseif ($object->id > 0) // Other attributes $cols = 2; include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - + print '</table>'; - + print '</div>'; print '<div class="fichehalfright">'; print '<div class="ficheaddleft">'; print '<div class="underbanner clearboth"></div>'; - + print '<table class="border" width="100%">'; - + // Description print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'; print nl2br($object->description); @@ -929,13 +933,13 @@ elseif ($object->id > 0) print $form->showCategories($object->id,'project',1); print "</td></tr>"; } - + print '</table>'; - + print '</div>'; print '</div>'; print '</div>'; - + print '<div class="clearboth"></div>'; } @@ -954,9 +958,10 @@ elseif ($object->id > 0) // Change probability from status if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + // Default value to close or not when we set opp to 'WON'. $defaultcheckedwhenoppclose=1; if (empty($conf->global->PROJECT_HIDE_TASKS)) $defaultcheckedwhenoppclose=0; - + print '<!-- Javascript to manage opportunity status change -->'; print '<script type="text/javascript" language="javascript"> jQuery(document).ready(function() { @@ -969,13 +974,17 @@ elseif ($object->id > 0) var oldpercent = \''.dol_escape_js($object->opp_percent).'\'; console.log("We select "+elemcode); - if (elemcode == \'LOST\') defaultcloseproject = 1; - jQuery("#divtocloseproject").show(); - if (defaultcloseproject) jQuery("#inputcloseproject").prop("checked", true); + + /* Define if checkbox to close is checked or not */ + var closeproject = 0; + if (elemcode == \'LOST\') closeproject = 1; + if (elemcode == \'WON\') closeproject = defaultcloseproject; + if (closeproject) jQuery("#inputcloseproject").prop("checked", true); else jQuery("#inputcloseproject").prop("checked", false); - - /* Make close project visible or not */ - if (elemcode == \'WON\' || elemcode == \'LOST\') + + /* Make the close project checkbox visible or not */ + console.log("closeproject="+closeproject); + if (elemcode == \'WON\' || elemcode == \'LOST\') { jQuery("#divtocloseproject").show(); } @@ -983,7 +992,7 @@ elseif ($object->id > 0) { jQuery("#divtocloseproject").hide(); } - + /* Change percent of default percent of new status is higher */ if (parseFloat(jQuery("#opp_percent").val()) != parseFloat(defaultpercent)) { @@ -1010,7 +1019,7 @@ elseif ($object->id > 0) { if ($action != "edit" ) { - + // Create event if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a // "workflow" action so should appears somewhere else on diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 0f4f85c05af0e470a8ac523f0f4c900e0e5a4e3d..8586f0c89ce9050c39dd7851b67a348fab87e98e 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -20,7 +20,7 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; - + /** * API class for projects * @@ -83,8 +83,8 @@ class Projects extends DolibarrApi return $this->_cleanObjectDatas($this->project); } - - + + /** * List projects * @@ -102,7 +102,7 @@ class Projects extends DolibarrApi global $db, $conf; $obj_ret = array(); - + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; @@ -126,7 +126,7 @@ class Projects extends DolibarrApi $sql .= " AND sc.fk_user = ".$search_sale; } // Add sql filters - if ($sqlfilters) + if ($sqlfilters) { if (! DolibarrApi::_checkFilters($sqlfilters)) { @@ -135,7 +135,7 @@ class Projects extends DolibarrApi $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - + $sql.= $db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) @@ -228,7 +228,7 @@ class Projects extends DolibarrApi } $this->project->getLinesArray(DolibarrApiAccess::$user); $result = array(); - foreach ($this->project->lines as $line) // $line is a task + foreach ($this->project->lines as $line) // $line is a task { if ($includetimespent == 1) { @@ -244,7 +244,7 @@ class Projects extends DolibarrApi return $result; } - + /** * Get roles a user is assigned to a project with * @@ -257,20 +257,20 @@ class Projects extends DolibarrApi */ function getRoles($id, $userid=0) { global $db; - + if(! DolibarrApiAccess::$user->rights->projet->lire) { throw new RestException(401); } - + $result = $this->project->fetch($id); if( ! $result ) { throw new RestException(404, 'Project not found'); } - + if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; $taskstatic=new Task($this->db); $userp = DolibarrApiAccess::$user; @@ -286,8 +286,8 @@ class Projects extends DolibarrApi } return $result; } - - + + /** * Add a task to given project * @@ -348,7 +348,7 @@ class Projects extends DolibarrApi return false; } */ - + /** * Update a task to given project * @@ -406,9 +406,9 @@ class Projects extends DolibarrApi } return false; }*/ - - + + /** * Update project general fields (won't touch lines of project) * @@ -483,7 +483,7 @@ class Projects extends DolibarrApi * Validate a project. * You can test this API with the following input message * { "notrigger": 0 } - * + * * @param int $id Project ID * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @@ -527,7 +527,7 @@ class Projects extends DolibarrApi ); } - + /** * Clean sensible object datas * @@ -535,9 +535,12 @@ class Projects extends DolibarrApi * @return array Array of cleaned object properties */ function _cleanObjectDatas($object) { - + $object = parent::_cleanObjectDatas($object); - + + unset($object->titre); + unset($object->datec); + unset($object->datem); unset($object->barcode_type); unset($object->barcode_type_code); unset($object->barcode_type_label); @@ -559,21 +562,21 @@ class Projects extends DolibarrApi unset($object->country); unset($object->country_id); unset($object->country_code); - + unset($object->weekWorkLoad); unset($object->weekWorkLoad); - + //unset($object->lines); // for task we use timespent_lines, but for project we use lines - + unset($object->total_ht); unset($object->total_tva); unset($object->total_localtax1); unset($object->total_localtax2); unset($object->total_ttc); - + return $object; } - + /** * Validate fields before create or update object * @@ -592,8 +595,8 @@ class Projects extends DolibarrApi } return $object; } - - + + // TODO // getSummaryOfTimeSpent } diff --git a/htdocs/projet/class/projectstats.class.php b/htdocs/projet/class/projectstats.class.php index 4485117fb0f0523a4a29ce5cb7e3359a3062ba7f..a47d28d1b43cb91795331abb2b013044aac4aa52 100644 --- a/htdocs/projet/class/projectstats.class.php +++ b/htdocs/projet/class/projectstats.class.php @@ -28,8 +28,8 @@ class ProjectStats extends Stats public $userid; public $socid; public $year; - - function __construct($db) + + function __construct($db) { global $conf, $user; @@ -41,7 +41,7 @@ class ProjectStats extends Stats /** - * Return all leads grouped by status. + * Return all leads grouped by opportunity status. * Warning: There is no filter on WON/LOST because we want this for statistics. * * @param int $limit Limit results @@ -56,7 +56,10 @@ class ProjectStats extends Stats $sql = "SELECT"; $sql .= " SUM(t.opp_amount), t.fk_opp_status, cls.code, cls.label"; - $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t, ".MAIN_DB_PREFIX."c_lead_status as cls"; + $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t"; + if (! $user->rights->societe->client->voir && ! $user->socid) + $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; + $sql .= ", ".MAIN_DB_PREFIX."c_lead_status as cls"; $sql .= $this->buildWhere(); $sql .= " AND t.fk_opp_status = cls.rowid"; $sql .= " AND t.fk_statut <> 0"; // We want historic also, so all projects not draft @@ -112,11 +115,11 @@ class ProjectStats extends Stats $datay = array (); $wonlostfilter=0; // No filter on status WON/LOST - + $sql = "SELECT date_format(t.datec,'%Y') as year, COUNT(t.rowid) as nb, SUM(t.opp_amount) as total, AVG(t.opp_amount) as avg,"; $sql.= " SUM(t.opp_amount * ".$this->db->ifsql("t.opp_percent IS NULL".($wonlostfilter?" OR cls.code IN ('WON','LOST')":""), '0', 't.opp_percent')." / 100) as weighted"; $sql.= " FROM " . MAIN_DB_PREFIX . "projet as t LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls ON cls.rowid = t.fk_opp_status"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) + if (! $user->rights->societe->client->voir && ! $user->soc_id) $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql.= $this->buildWhere(); $sql.= " GROUP BY year"; @@ -124,14 +127,14 @@ class ProjectStats extends Stats return $this->_getAllByYear($sql); } - - + + /** * Build the where part - * + * * @return string */ - public function buildWhere() + public function buildWhere() { $sqlwhere_str = ''; $sqlwhere = array(); @@ -163,7 +166,7 @@ class ProjectStats extends Stats * @param int $year scan * @return array of values */ - function getNbByMonth($year) + function getNbByMonth($year) { global $user; @@ -171,7 +174,7 @@ class ProjectStats extends Stats $sql = "SELECT date_format(t.datec,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) + if (! $user->rights->societe->client->voir && ! $user->soc_id) $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= $this->buildWhere(); $sql .= " GROUP BY dm"; @@ -190,7 +193,7 @@ class ProjectStats extends Stats * @param int $year scan * @return array with amount by month */ - function getAmountByMonth($year) + function getAmountByMonth($year) { global $user; @@ -198,7 +201,7 @@ class ProjectStats extends Stats $sql = "SELECT date_format(t.datec,'%m') as dm, SUM(t.opp_amount)"; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) + if (! $user->rights->societe->client->voir && ! $user->soc_id) $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= $this->buildWhere(); $sql .= " GROUP BY dm"; @@ -313,7 +316,7 @@ class ProjectStats extends Stats * @param int $wonlostfilter Add a filter on status won/lost * @return array Array with amount by month */ - function getWeightedAmountByMonth($year, $wonlostfilter=1) + function getWeightedAmountByMonth($year, $wonlostfilter=1) { global $user; @@ -321,7 +324,7 @@ class ProjectStats extends Stats $sql = "SELECT date_format(t.datec,'%m') as dm, SUM(t.opp_amount * ".$this->db->ifsql("t.opp_percent IS NULL".($wonlostfilter?" OR cls.code IN ('WON','LOST')":""), '0', 't.opp_percent')." / 100)"; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t LEFT JOIN ".MAIN_DB_PREFIX.'c_lead_status as cls ON t.fk_opp_status = cls.rowid'; - if (! $user->rights->societe->client->voir && ! $user->societe_id) + if (! $user->rights->societe->client->voir && ! $user->soc_id) $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= $this->buildWhere(); $sql .= " GROUP BY dm"; @@ -421,7 +424,7 @@ class ProjectStats extends Stats * @param int $year scan * @return array with amount by month */ - function getTransformRateByMonth($year) + function getTransformRateByMonth($year) { global $user; @@ -429,7 +432,7 @@ class ProjectStats extends Stats $sql = "SELECT date_format(t.datec,'%m') as dm, count(t.opp_amount)"; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) + if (! $user->rights->societe->client->voir && ! $user->soc_id) $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= $this->buildWhere(); $sql .= " GROUP BY dm"; @@ -441,7 +444,7 @@ class ProjectStats extends Stats $sql = "SELECT date_format(t.datec,'%m') as dm, count(t.opp_amount)"; $sql .= " FROM " . MAIN_DB_PREFIX . "projet as t"; - if (! $user->rights->societe->client->voir && ! $user->societe_id) + if (! $user->rights->societe->client->voir && ! $user->soc_id) $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; $sql .= $this->buildWhere(); $sql .= " GROUP BY dm"; diff --git a/htdocs/projet/class/taskstats.class.php b/htdocs/projet/class/taskstats.class.php new file mode 100644 index 0000000000000000000000000000000000000000..b71c88f3d6b6cc37919815b18929813fb834e0e7 --- /dev/null +++ b/htdocs/projet/class/taskstats.class.php @@ -0,0 +1,184 @@ +<?php +/* Lead + * Copyright (C) 2014-2015 Florian HENRY <florian.henry@open-concept.pro> + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php'; +include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + + +/** + * Class to manage statistics on project tasks + */ +class TaskStats extends Stats +{ + private $project; + public $userid; + public $socid; + public $year; + + function __construct($db) + { + global $conf, $user; + + $this->db = $db; + + require_once 'task.class.php'; + $this->task = new Task($this->db); + } + + + /** + * Return all tasks grouped by status. + * + * @param int $limit Limit results + * @return array|int Array with value or -1 if error + * @throws Exception + */ + function getAllTaskByStatus($limit = 5) + { + global $conf, $user, $langs; + + $datay = array(); + + $sql = "SELECT"; + $sql .= " COUNT(t.rowid), t.priority"; + $sql.= " FROM ". MAIN_DB_PREFIX . "projet_task as t INNER JOIN " . MAIN_DB_PREFIX . "projet as p ON p.rowid = t.fk_projet"; + if (! $user->rights->societe->client->voir && ! $user->soc_id) + $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; + $sql .= $this->buildWhere(); + //$sql .= " AND t.fk_statut <> 0"; // We want historic also, so all task not draft + $sql .= " GROUP BY t.priority"; + + $result = array (); + $res = array (); + + dol_syslog(get_class($this) . '::' . __METHOD__ . "", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + $other = 0; + while ( $i < $num ) { + $row = $this->db->fetch_row($resql); + if ($i < $limit || $num == $limit) + { + $result[$i] = array( + $row[1], + $row[0] + ); + } + else + $other += $row[1]; + $i++; + } + if ($num > $limit) + $result[$i] = array ( + $langs->transnoentitiesnoconv("Other"), + $other + ); + $this->db->free($resql); + } else { + $this->error = "Error " . $this->db->lasterror(); + dol_syslog(get_class($this) . '::' . __METHOD__ . ' ' . $this->error, LOG_ERR); + return -1; + } + + return $result; + } + + /** + * Return count, and sum of products + * + * @return array of values + */ + function getAllByYear() + { + global $conf, $user, $langs; + + $datay = array (); + + $wonlostfilter=0; // No filter on status WON/LOST + + $sql = "SELECT date_format(t.datec,'%Y') as year, COUNT(t.rowid) as nb"; + $sql.= " FROM ". MAIN_DB_PREFIX . "projet_task as t INNER JOIN " . MAIN_DB_PREFIX . "projet as p ON p.rowid = t.fk_projet"; + if (! $user->rights->societe->client->voir && ! $user->soc_id) + $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; + $sql.= $this->buildWhere(); + $sql.= " GROUP BY year"; + $sql.= $this->db->order('year', 'DESC'); + + return $this->_getAllByYear($sql); + } + + + /** + * Build the where part + * + * @return string + */ + public function buildWhere() + { + $sqlwhere_str = ''; + $sqlwhere = array(); + + $sqlwhere[] = ' t.entity IN (' . getEntity('project') . ')'; + + if (! empty($this->userid)) + $sqlwhere[] = ' t.fk_user_resp=' . $this->userid; + if (! empty($this->socid)) + $sqlwhere[] = ' t.fk_soc=' . $this->socid; + if (! empty($this->year) && empty($this->yearmonth)) + $sqlwhere[] = " date_format(t.datec,'%Y')='" . $this->db->escape($this->year) . "'"; + if (! empty($this->yearmonth)) + $sqlwhere[] = " t.datec BETWEEN '" . $this->db->idate(dol_get_first_day($this->yearmonth)) . "' AND '" . $this->db->idate(dol_get_last_day($this->yearmonth)) . "'"; + + if (! empty($this->status)) + $sqlwhere[] = " t.priority IN (" . $this->priority . ")"; + + if (count($sqlwhere) > 0) { + $sqlwhere_str = ' WHERE ' . implode(' AND ', $sqlwhere); + } + + return $sqlwhere_str; + } + + /** + * Return Task number by month for a year + * + * @param int $year scan + * @return array of values + */ + function getNbByMonth($year) + { + global $user; + + $this->yearmonth = $year; + + $sql = "SELECT date_format(t.datec,'%m') as dm, COUNT(t.rowid) as nb"; + $sql.= " FROM ". MAIN_DB_PREFIX . "projet_task as t INNER JOIN " . MAIN_DB_PREFIX . "projet as p ON p.rowid = t.fk_projet"; + if (! $user->rights->societe->client->voir && ! $user->soc_id) + $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "societe_commerciaux as sc ON sc.fk_soc=t.fk_soc AND sc.fk_user=" . $user->id; + $sql .= $this->buildWhere(); + $sql .= " GROUP BY dm"; + $sql .= $this->db->order('dm', 'DESC'); + + $this->yearmonth=0; + + $res = $this->_getNbByMonth($year, $sql); + // var_dump($res);print '<br>'; + return $res; + } +} diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 4e31434dbc4a797be5ef849530606f8695384500..4af874ce21ebe0aa715cdd6fbb22a6c77c1c3a1e 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -43,7 +43,7 @@ $id=GETPOST('id','int'); $search_all=GETPOST('search_all', 'alphanohtml'); $search_categ=GETPOST("search_categ",'alpha'); $search_project=GETPOST('search_project'); -if (! isset($_GET['search_projectstatus']) && ! isset($_POST['search_projectstatus'])) +if (! isset($_GET['search_projectstatus']) && ! isset($_POST['search_projectstatus'])) { if ($search_all != '') $search_projectstatus=-1; else $search_projectstatus=1; @@ -173,14 +173,14 @@ if (empty($reshook)) $toselect=''; $search_array_options=array(); } - + // Mass actions $objectclass='Task'; $objectlabel='Tasks'; $permtoread = $user->rights->projet->lire; $permtodelete = $user->rights->projet->supprimer; $uploaddir = $conf->projet->dir_output.'/tasks'; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } if (empty($search_projectstatus) && $search_projectstatus == '') $search_projectstatus=1; @@ -322,7 +322,7 @@ foreach ($search_array_options as $key => $val) $typ=$extrafields->attribute_type[$tmpkey]; $mode=0; if (in_array($typ, array('int','double'))) $mode=1; // Search on a numeric - if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) + if ($val && ( ($crit != '' && ! in_array($typ, array('select'))) || ! empty($crit))) { $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); } @@ -396,7 +396,7 @@ foreach ($search_array_options as $key => $val) $tmpkey=preg_replace('/search_options_/','',$key); if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); } - + // List of mass actions available $arrayofmassactions = array( // 'presend'=>$langs->trans("SendByMail"), @@ -544,7 +544,7 @@ if (! empty($arrayfields['t.progress']['checked'])) print '<td class="liste_titr // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { - foreach($extrafields->attribute_label as $key => $val) + foreach($extrafields->attribute_label as $key => $val) { if (! empty($arrayfields["ef.".$key]['checked'])) { @@ -649,7 +649,7 @@ while ($i < min($num,$limit)) $projectstatic->public = $obj->public; $projectstatic->statut = $obj->projectstatus; $projectstatic->datee = $db->jdate($obj->projectdatee); - + $userAccess = $projectstatic->restrictedProjectArea($user); // why this ? if ($userAccess >= 0) { @@ -663,7 +663,7 @@ while ($i < min($num,$limit)) if ($object->hasDelay()) print img_warning("Late"); print '</td>'; if (! $i) $totalarray['nbfield']++; - } + } // Label if (! empty($arrayfields['t.label']['checked'])) { @@ -730,7 +730,7 @@ while ($i < min($num,$limit)) print '</td>'; if (! $i) $totalarray['nbfield']++; } - + // Planned workload if (! empty($arrayfields['t.planned_workload']['checked'])) { @@ -764,7 +764,7 @@ while ($i < min($num,$limit)) if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totaldurationeffectivefield']=$totalarray['nbfield']; $totalarray['totaldurationeffective'] += $obj->duration_effective; - } + } // Calculated progress if (! empty($arrayfields['t.progress_calculated']['checked'])) { @@ -777,7 +777,7 @@ while ($i < min($num,$limit)) print '</td>'; if (! $i) $totalarray['nbfield']++; if (! $i) $totalarray['totalprogress_calculated']=$totalarray['nbfield']; - } + } // Declared progress if (! empty($arrayfields['t.progress']['checked'])) { @@ -843,13 +843,13 @@ while ($i < min($num,$limit)) } print '</td>'; if (! $i) $totalarray['nbfield']++; - + print "</tr>\n"; - + //print projectLinesa(); } - $i++; + $i++; } // Show total line diff --git a/htdocs/projet/tasks/stats/index.php b/htdocs/projet/tasks/stats/index.php new file mode 100644 index 0000000000000000000000000000000000000000..b03d01a80065c5ef017d44e8e084e24789e87e4a --- /dev/null +++ b/htdocs/projet/tasks/stats/index.php @@ -0,0 +1,218 @@ +<?php +/* Copyright (C) 2014-2015 Florian HENRY <florian.henry@open-concept.pro> + * Copyright (C) 2015 Laurent Destailleur <ldestailleur@users.sourceforge.net> + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/projet/tasks/stats/index.php + * \ingroup project + * \brief Page for tasks statistics + */ + +require '../../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/taskstats.class.php'; + +// Security check +if (! $user->rights->projet->lire) + accessforbidden(); + + +$WIDTH=DolGraph::getDefaultGraphSizeForStats('width'); +$HEIGHT=DolGraph::getDefaultGraphSizeForStats('height'); + +$userid=GETPOST('userid','int'); +$socid=GETPOST('socid','int'); +// Security check +if ($user->societe_id > 0) +{ + $action = ''; + $socid = $user->societe_id; +} +$nowyear=strftime("%Y", dol_now()); +$year = GETPOST('year')>0?GETPOST('year'):$nowyear; +//$startyear=$year-2; +$startyear=$year-1; +$endyear=$year; + +$langs->load('companies'); +$langs->load('projects'); + + +/* + * View + */ + +$form=new Form($db); + +$includeuserlist=array(); + + +llxHeader('', $langs->trans('Tasks')); + +$title=$langs->trans("TasksStatistics"); +$dir=$conf->projet->dir_output.'/temp'; + +print load_fiche_titre($title,'','title_project.png'); + +dol_mkdir($dir); + + +$stats_tasks= new TaskStats($db); +if (!empty($userid) && $userid!=-1) $stats_tasks->userid=$userid; +if (!empty($socid) && $socid!=-1) $stats_tasks->socid=$socid; +if (!empty($year)) $stats_tasks->year=$year; + + + +// Build graphic number of object +// $data = array(array('Lib',val1,val2,val3),...) +$data = $stats_tasks->getNbByMonthWithPrevYear($endyear,$startyear); +//var_dump($data); + +$filenamenb = $conf->project->dir_output . "/stats/tasknbprevyear-".$year.".png"; +$fileurlnb = DOL_URL_ROOT . '/viewimage.php?modulepart=taskstats&file=tasknbprevyear-'.$year.'.png'; + +$px1 = new DolGraph(); +$mesg = $px1->isGraphKo(); +if (! $mesg) +{ + $px1->SetData($data); + $px1->SetPrecisionY(0); + $i=$startyear;$legend=array(); + while ($i <= $endyear) + { + $legend[]=$i; + $i++; + } + $px1->SetLegend($legend); + $px1->SetMaxValue($px1->GetCeilMaxValue()); + $px1->SetWidth($WIDTH); + $px1->SetHeight($HEIGHT); + $px1->SetYLabel($langs->trans("ProjectNbTask")); + $px1->SetShading(3); + $px1->SetHorizTickIncrement(1); + $px1->SetPrecisionY(0); + $px1->mode='depth'; + $px1->SetTitle($langs->trans("ProjectNbTaskByMonth")); + + $px1->draw($filenamenb,$fileurlnb); +} + + +// Show array +$stats_tasks->year=0; +$data_all_year = $stats_tasks->getAllByYear(); + +if (!empty($year)) $stats_tasks->year=$year; +$arrayyears=array(); +foreach($data_all_year as $val) { + $arrayyears[$val['year']]=$val['year']; +} +if (! count($arrayyears)) $arrayyears[$nowyear]=$nowyear; + + +$h=0; +$head = array(); +$head[$h][0] = DOL_URL_ROOT . '/projet/tasks/stats/index.php?mode='.$mode; +$head[$h][1] = $langs->trans("ByMonthYear"); +$head[$h][2] = 'byyear'; +$h++; + +complete_head_from_modules($conf,$langs,null,$head,$h,$type); + +dol_fiche_head($head,'byyear',$langs->trans("Statistics"), -1, ''); + + +print '<div class="fichecenter"><div class="fichethirdleft">'; + +print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">'; + +print '<table class="noborder" width="100%">'; +print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>'; +// Company +/*print '<tr><td>'.$langs->trans("ThirdParty").'</td><td>'; +if ($mode == 'customer') $filter='s.client in (1,2,3)'; +if ($mode == 'supplier') $filter='s.fournisseur = 1'; +print $form->select_company($socid,'socid',$filter,1,0,0,array(),0,'','style="width: 95%"'); +print '</td></tr>'; +*/ +// User +/*print '<tr><td>'.$langs->trans("ProjectCommercial").'</td><td>'; +print $form->select_dolusers($userid, 'userid', 1, array(),0,$includeuserlist); +print '</td></tr>';*/ +// Year +print '<tr><td>'.$langs->trans("Year").'</td><td>'; +if (! in_array($year,$arrayyears)) $arrayyears[$year]=$year; +if (! in_array($nowyear,$arrayyears)) $arrayyears[$nowyear]=$nowyear; +arsort($arrayyears); +print $form->selectarray('year',$arrayyears,$year,0); +print '</td></tr>'; +print '<tr><td align="center" colspan="2"><input type="submit" name="submit" class="button" value="'.$langs->trans("Refresh").'"></td></tr>'; +print '</table>'; +print '</form>'; +print '<br><br>'; + +print '<table class="noborder" width="100%">'; +print '<tr class="liste_titre" height="24">'; +print '<td align="center">'.$langs->trans("Year").'</td>'; +print '<td align="right">'.$langs->trans("NbOfTasks").'</td>'; +print '</tr>'; + +$oldyear=0; +$var=true; +foreach ($data_all_year as $val) +{ + $year = $val['year']; + while ($year && $oldyear > $year+1) + { // If we have empty year + $oldyear--; + + print '<tr '.$bc[$var].' height="24">'; + print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$oldyear.'&mode='.$mode.($socid>0?'&socid='.$socid:'').($userid>0?'&userid='.$userid:'').'">'.$oldyear.'</a></td>'; + print '<td align="right">0</td>'; + print '</tr>'; + } + + print '<tr '.$bc[$var].' height="24">'; + print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&mode='.$mode.($socid>0?'&socid='.$socid:'').($userid>0?'&userid='.$userid:'').'">'.$year.'</a></td>'; + print '<td align="right">'.$val['nb'].'</td>'; + print '</tr>'; + $oldyear=$year; +} + +print '</table>'; + +print '</div><div class="fichetwothirdright"><div class="ficheaddleft">'; + +$stringtoshow.= '<table class="border" width="100%"><tr valign="top"><td align="center">'; +if ($mesg) { print $mesg; } +else { + $stringtoshow.= $px1->show(); + $stringtoshow.= "<br>\n"; +} +$stringtoshow.= '</td></tr></table>'; + +print $stringtoshow; + + +print '</div></div></div>'; +print '<div style="clear:both"></div>'; + + +llxFooter(); +$db->close(); diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php new file mode 100644 index 0000000000000000000000000000000000000000..73d9f41eab005c0b587e9ec87749b06439c2caee --- /dev/null +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -0,0 +1,640 @@ +<?php +/* Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org> + * Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@capnetworks.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * For paypal test: https://developer.paypal.com/ + * For paybox test: ??? + */ + +/** + * \file htdocs/public/onlinesign/newsign.php + * \ingroup core + * \brief File to offer a way to make an online signature for a particular Dolibarr entity + */ + +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. + +// For MultiCompany module. +// Do not use GETPOST here, function is not defined and define must be done before including main.inc.php +// TODO This should be useless. Because entity must be retreive from object ref and not from url. +$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1)); +if (is_numeric($entity)) define("DOLENTITY", $entity); + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + +// Security check +// No check on module enabled. Done later according to $validpaymentmethod + +$langs->load("main"); +$langs->load("other"); +$langs->load("dict"); +$langs->load("bills"); +$langs->load("companies"); +$langs->load("errors"); +$langs->load("paybox"); // File with generic data + +$action=GETPOST('action','alpha'); + +// Input are: +// type ('invoice','order','contractline'), +// id (object id), +// amount (required if id is empty), +// tag (a free text, required if type is empty) +// currency (iso code) + +$suffix=GETPOST("suffix",'alpha'); +$SOURCE=GETPOST("source",'alpha'); +$ref=$REF=GETPOST("ref",'alpha'); + +if (! $action) +{ + if ($source && ! $ref) + { + dol_print_error('',$langs->trans('ErrorBadParameters')." - ref"); + exit; + } +} + + +$paymentmethod=''; +$validpaymentmethod=array(); + + + + +// Define $urlwithroot +//$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +//$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. For Paypal payment, we can use internal URL like localhost. + + +// Complete urls for post treatment +$SECUREKEY=GETPOST("securekey"); // Secure key + +if (! empty($SOURCE)) +{ + $urlok.='source='.urlencode($SOURCE).'&'; + $urlko.='source='.urlencode($SOURCE).'&'; +} +if (! empty($REF)) +{ + $urlok.='ref='.urlencode($REF).'&'; + $urlko.='ref='.urlencode($REF).'&'; +} +if (! empty($SECUREKEY)) +{ + $urlok.='securekey='.urlencode($SECUREKEY).'&'; + $urlko.='securekey='.urlencode($SECUREKEY).'&'; +} +if (! empty($entity)) +{ + $urlok.='entity='.urlencode($entity).'&'; + $urlko.='entity='.urlencode($entity).'&'; +} +$urlok=preg_replace('/&$/','',$urlok); // Remove last & +$urlko=preg_replace('/&$/','',$urlko); // Remove last & + + + + +/* + * Actions + */ + + +if ($action == 'dosign') +{ + // TODO + +} + + +/* + * View + */ + +$head=''; +if (! empty($conf->global->MAIN_SIGN_CSS_URL)) $head='<link rel="stylesheet" type="text/css" href="'.$conf->global->MAIN_SIGN_CSS_URL.'?lang='.$langs->defaultlang.'">'."\n"; + +$conf->dol_hide_topmenu=1; +$conf->dol_hide_leftmenu=1; + +llxHeader($head, $langs->trans("OnlineSignature"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); + +// Check link validity +if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +{ + $langs->load("errors"); + dol_print_error_email('BADREFINONLINESIGNFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + llxFooter(); + $db->close(); + exit; +} + +print '<span id="dolpaymentspan"></span>'."\n"; +print '<div class="center">'."\n"; +print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n"; +print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n"; +print '<input type="hidden" name="action" value="dosign">'."\n"; +print '<input type="hidden" name="tag" value="'.GETPOST("tag",'alpha').'">'."\n"; +print '<input type="hidden" name="suffix" value="'.GETPOST("suffix",'alpha').'">'."\n"; +print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n"; +print '<input type="hidden" name="entity" value="'.$entity.'" />'; +print "\n"; +print '<!-- Form to sign -->'."\n"; + +print '<table id="dolpaymenttable" summary="Payment form" class="center">'."\n"; + +// Show logo (search order: logo defined by PAYBOX_LOGO_suffix, then PAYBOX_LOGO, then small company logo, large company logo, theme logo, common logo) +$width=0; +// Define logo and logosmall +$logosmall=$mysoc->logo_small; +$logo=$mysoc->logo; +$paramlogo='ONLINE_SIGN_LOGO_'.$suffix; +if (! empty($conf->global->$paramlogo)) $logosmall=$conf->global->$paramlogo; +else if (! empty($conf->global->ONLINE_SIGN_LOGO)) $logosmall=$conf->global->ONLINE_SIGN_LOGO; +//print '<!-- Show logo (logosmall='.$logosmall.' logo='.$logo.') -->'."\n"; +// Define urllogo +$urllogo=''; +if (! empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) +{ + $urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&file='.urlencode('thumbs/'.$logosmall); +} +elseif (! empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) +{ + $urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&file='.urlencode($logo); + $width=96; +} +// Output html code for logo +if ($urllogo) +{ + print '<tr>'; + print '<td align="center"><img id="dolpaymentlogo" title="'.$title.'" src="'.$urllogo.'"'; + if ($width) print ' width="'.$width.'"'; + print '></td>'; + print '</tr>'."\n"; +} + +// Output introduction text +$text=''; +if (! empty($conf->global->ONLINE_SIGN_NEWFORM_TEXT)) +{ + $langs->load("members"); + if (preg_match('/^\((.*)\)$/',$conf->global->ONLINE_SIGN_NEWFORM_TEXT,$reg)) $text.=$langs->trans($reg[1])."<br>\n"; + else $text.=$conf->global->ONLINE_SIGN_NEWFORM_TEXT."<br>\n"; + $text='<tr><td align="center"><br>'.$text.'<br></td></tr>'."\n"; +} +if (empty($text)) +{ + $text.='<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnOnlineSignaturePage").'</strong><br></td></tr>'."\n"; + $text.='<tr><td class="textpublicpayment"><br>'.$langs->trans("ThisScreenAllowsYouToSignDocFrom",$creditor).'<br><br></td></tr>'."\n"; +} +print $text; + +// Output payment summary form +print '<tr><td align="center">'; +print '<table with="100%" id="tablepublicpayment">'; +print '<tr class="liste_total"><td align="left" colspan="2">'.$langs->trans("ThisIsInformationOnDocumentToSign").' :</td></tr>'."\n"; + +$found=false; +$error=0; +$var=false; + +// Free payment +if (! GETPOST("source")) +{ + $found=true; + $tag=GETPOST("tag"); + $fulltag=$tag; + + // Creditor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; + print '<input type="hidden" name="creditor" value="'.$creditor.'">'; + print '</td></tr>'."\n"; + + + + // We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum + // as they don't exists (buyer is unknown, tag is free). +} + + +// Payment on customer order +if (GETPOST("source") == 'order') +{ + $found=true; + $langs->load("orders"); + + require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; + + $order=new Commande($db); + $result=$order->fetch('',$ref); + if ($result < 0) + { + $mesg=$order->error; + $error++; + } + else + { + $result=$order->fetch_thirdparty($order->socid); + } + + // Creditor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; + print '<input type="hidden" name="creditor" value="'.$creditor.'">'; + print '</td></tr>'."\n"; + + // Debitor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$order->thirdparty->name.'</b>'; + + // Object + + $text='<b>'.$langs->trans("PaymentOrderRef",$order->ref).'</b>'; + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); + print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; + print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">'; + print '<input type="hidden" name="ref" value="'.$order->ref.'">'; + print '</td></tr>'."\n"; + + +} + + +// Payment on customer invoice +if (GETPOST("source") == 'invoice') +{ + $found=true; + $langs->load("bills"); + + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + + $invoice=new Facture($db); + $result=$invoice->fetch('',$ref); + if ($result < 0) + { + $mesg=$invoice->error; + $error++; + } + else + { + $result=$invoice->fetch_thirdparty($invoice->socid); + } + + if ($action != 'dosign') // Do not change amount if we just click on first dosign + { + $amount=price2num($invoice->total_ttc - $invoice->getSommePaiement()); + if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); + $amount=price2num($amount); + } + + // Creditor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; + print '<input type="hidden" name="creditor" value="'.$creditor.'">'; + print '</td></tr>'."\n"; + + // Debitor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$invoice->thirdparty->name.'</b>'; + + // Object + + $text='<b>'.$langs->trans("PaymentInvoiceRef",$invoice->ref).'</b>'; + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); + print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; + print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">'; + print '<input type="hidden" name="ref" value="'.$invoice->ref.'">'; + print '</td></tr>'."\n"; + +} + +// Payment on contract line +if (GETPOST("source") == 'contractline') +{ + $found=true; + $langs->load("contracts"); + + require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; + + $contractline=new ContratLigne($db); + $result=$contractline->fetch('',$ref); + if ($result < 0) + { + $mesg=$contractline->error; + $error++; + } + else + { + if ($contractline->fk_contrat > 0) + { + $contract=new Contrat($db); + $result=$contract->fetch($contractline->fk_contrat); + if ($result > 0) + { + $result=$contract->fetch_thirdparty($contract->socid); + } + else + { + $mesg=$contract->error; + $error++; + } + } + else + { + $mesg='ErrorRecordNotFound'; + $error++; + } + } + + if ($action != 'dosign') // Do not change amount if we just click on first dosign + { + $amount=$contractline->total_ttc; + if ($contractline->fk_product) + { + $product=new Product($db); + $result=$product->fetch($contractline->fk_product); + + // We define price for product (TODO Put this in a method in product class) + if (! empty($conf->global->PRODUIT_MULTIPRICES)) + { + $pu_ht = $product->multiprices[$contract->thirdparty->price_level]; + $pu_ttc = $product->multiprices_ttc[$contract->thirdparty->price_level]; + $price_base_type = $product->multiprices_base_type[$contract->thirdparty->price_level]; + } + else + { + $pu_ht = $product->price; + $pu_ttc = $product->price_ttc; + $price_base_type = $product->price_base_type; + } + + $amount=$pu_ttc; + if (empty($amount)) + { + dol_print_error('','ErrorNoPriceDefinedForThisProduct'); + exit; + } + } + if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); + $amount=price2num($amount); + } + + $qty=1; + if (GETPOST('qty')) $qty=GETPOST('qty'); + + // Creditor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; + print '<input type="hidden" name="creditor" value="'.$creditor.'">'; + print '</td></tr>'."\n"; + + // Debitor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$contract->thirdparty->name.'</b>'; + + // Object + + $text='<b>'.$langs->trans("PaymentRenewContractId",$contract->ref,$contractline->ref).'</b>'; + if ($contractline->fk_product) + { + $text.='<br>'.$product->ref.($product->label?' - '.$product->label:''); + } + if ($contractline->description) $text.='<br>'.dol_htmlentitiesbr($contractline->description); + //if ($contractline->date_fin_validite) { + // $text.='<br>'.$langs->trans("DateEndPlanned").': '; + // $text.=dol_print_date($contractline->date_fin_validite); + //} + if ($contractline->date_fin_validite) + { + $text.='<br>'.$langs->trans("ExpiredSince").': '.dol_print_date($contractline->date_fin_validite); + } + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); + print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; + print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">'; + print '<input type="hidden" name="ref" value="'.$contractline->ref.'">'; + print '</td></tr>'."\n"; + + // Quantity + + $label=$langs->trans("Quantity"); + $qty=1; + $duration=''; + if ($contractline->fk_product) + { + if ($product->isService() && $product->duration_value > 0) + { + $label=$langs->trans("Duration"); + + // TODO Put this in a global method + if ($product->duration_value > 1) + { + $dur=array("h"=>$langs->trans("Hours"),"d"=>$langs->trans("DurationDays"),"w"=>$langs->trans("DurationWeeks"),"m"=>$langs->trans("DurationMonths"),"y"=>$langs->trans("DurationYears")); + } + else + { + $dur=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("DurationDay"),"w"=>$langs->trans("DurationWeek"),"m"=>$langs->trans("DurationMonth"),"y"=>$langs->trans("DurationYear")); + } + $duration=$product->duration_value.' '.$dur[$product->duration_unit]; + } + } + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$label.'</td>'; + print '<td class="CTableRow'.($var?'1':'2').'"><b>'.($duration?$duration:$qty).'</b>'; + print '<input type="hidden" name="newqty" value="'.dol_escape_htmltag($qty).'">'; + print '</b></td></tr>'."\n"; + + // Amount + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); + if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; + print '</td><td class="CTableRow'.($var?'1':'2').'">'; + if (empty($amount) || ! is_numeric($amount)) + { + print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">'; + print '<input class="flat" size=8 type="text" name="newamount" value="'.GETPOST("newamount","int").'">'; + } + else { + print '<b>'.price($amount).'</b>'; + print '<input type="hidden" name="amount" value="'.$amount.'">'; + print '<input type="hidden" name="newamount" value="'.$amount.'">'; + } + // Currency + print ' <b>'.$langs->trans("Currency".$currency).'</b>'; + print '<input type="hidden" name="currency" value="'.$currency.'">'; + print '</td></tr>'."\n"; + +} + +// Payment on member subscription +if (GETPOST("source") == 'membersubscription') +{ + $found=true; + $langs->load("members"); + + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; + + $member=new Adherent($db); + $result=$member->fetch('',$ref); + if ($result < 0) + { + $mesg=$member->error; + $error++; + } + else + { + $subscription=new Subscription($db); + } + + if ($action != 'dosign') // Do not change amount if we just click on first dosign + { + $amount=$subscription->total_ttc; + if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); + $amount=price2num($amount); + } + + $fulltag='MEM='.$member->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M'); + if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } + $fulltag=dol_string_unaccent($fulltag); + + // Creditor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; + print '<input type="hidden" name="creditor" value="'.$creditor.'">'; + print '</td></tr>'."\n"; + + // Debitor + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Member"); + print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'; + if ($member->morphy == 'mor' && ! empty($member->societe)) print $member->societe; + else print $member->getFullName($langs); + print '</b>'; + + // Object + + $text='<b>'.$langs->trans("PaymentSubscription").'</b>'; + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); + print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; + print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">'; + print '<input type="hidden" name="ref" value="'.$member->ref.'">'; + print '</td></tr>'."\n"; + + if ($member->last_subscription_date || $member->last_subscription_amount) + { + // Last subscription date + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionDate"); + print '</td><td class="CTableRow'.($var?'1':'2').'">'.dol_print_date($member->last_subscription_date,'day'); + print '</td></tr>'."\n"; + + // Last subscription amount + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionAmount"); + print '</td><td class="CTableRow'.($var?'1':'2').'">'.price($member->last_subscription_amount); + print '</td></tr>'."\n"; + + if (empty($amount) && ! GETPOST('newamount')) $_GET['newamount']=$member->last_subscription_amount; + } + + // Amount + + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); + if (empty($amount)) + { + print ' ('.$langs->trans("ToComplete"); + if (! empty($conf->global->MEMBER_EXT_URL_SUBSCRIPTION_INFO)) print ' - <a href="'.$conf->global->MEMBER_EXT_URL_SUBSCRIPTION_INFO.'" rel="external" target="_blank">'.$langs->trans("SeeHere").'</a>'; + print ')'; + } + print '</td><td class="CTableRow'.($var?'1':'2').'">'; + if (empty($amount) || ! is_numeric($amount)) + { + $valtoshow=GETPOST("newamount",'int'); + if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow); + print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">'; + print '<input class="flat" size="8" type="text" name="newamount" value="'.$valtoshow.'">'; + } + else { + $valtoshow=$amount; + if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow); + print '<b>'.price($valtoshow).'</b>'; + print '<input type="hidden" name="amount" value="'.$valtoshow.'">'; + print '<input type="hidden" name="newamount" value="'.$valtoshow.'">'; + } + // Currency + print ' <b>'.$langs->trans("Currency".$currency).'</b>'; + print '<input type="hidden" name="currency" value="'.$currency.'">'; + print '</td></tr>'."\n"; + +} + + + + +if (! $found && ! $mesg) $mesg=$langs->trans("ErrorBadParameters"); + +if ($mesg) print '<tr><td align="center" colspan="2"><br><div class="warning">'.$mesg.'</div></td></tr>'."\n"; + +print '</table>'."\n"; +print "\n"; + +if ($action != 'dosign') +{ + if ($found && ! $error) // We are in a management option and no error + { + + + } + else + { + dol_print_error_email('ERRORNEWONLINESIGNPAYPAL'); + } +} +else +{ + // Print +} + +print '</td></tr>'."\n"; + +print '</table>'."\n"; +print '</form>'."\n"; +print '</div>'."\n"; +print '<br>'; + + +htmlPrintOnlinePaymentFooter($mysoc,$langs); + +llxFooter('', 'public'); + +$db->close(); diff --git a/htdocs/public/paybox/newpayment.php b/htdocs/public/paybox/newpayment.php index c3aff6341cc389c60ea60f87e6cc0d84c74a30a7..97a4c5452ff9c6e7799580c4af41ba2bcf14192f 100644 --- a/htdocs/public/paybox/newpayment.php +++ b/htdocs/public/paybox/newpayment.php @@ -135,7 +135,7 @@ if (GETPOST('action','aZ09') == 'dopayment') $email=GETPOST("email"); $origfulltag=GETPOST("fulltag",'alpha'); - + $mesg=''; if (empty($PRICE) || ! is_numeric($PRICE)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Amount")); elseif (empty($email)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail")); @@ -143,7 +143,7 @@ if (GETPOST('action','aZ09') == 'dopayment') elseif (! $origfulltag) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("PaymentCode")); elseif (dol_strlen($urlok) > 150) $mesg='Error urlok too long '.$urlok; elseif (dol_strlen($urlko) > 150) $mesg='Error urlko too long '.$urlko; - + if (empty($mesg)) { dol_syslog("newpayment.php call paybox api and do redirect", LOG_DEBUG); @@ -169,13 +169,22 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); - // Common variables $creditor=$mysoc->name; $paramcreditor='PAYBOX_CREDITOR_'.$suffix; if (! empty($conf->global->$paramcreditor)) $creditor=$conf->global->$paramcreditor; else if (! empty($conf->global->PAYBOX_CREDITOR)) $creditor=$conf->global->PAYBOX_CREDITOR; +// Check link validity +if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +{ + $langs->load("errors"); + dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + llxFooter(); + $db->close(); + exit; +} + print '<span id="dolpaymentspan"></span>'."\n"; print '<div class="center">'; print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'; @@ -258,14 +267,14 @@ if (! GETPOST("source") && $valid) $fulltag=$tag; // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -286,7 +295,7 @@ if (! GETPOST("source") && $valid) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -294,7 +303,7 @@ if (! GETPOST("source") && $valid) print '</td></tr>'."\n"; // EMail - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("YourEMail"); print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'"><input class="flat" type="text" name="email" size="48" value="'.GETPOST("email").'"></td></tr>'."\n"; @@ -331,19 +340,19 @@ if (GETPOST("source") == 'order' && $valid) $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$order->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentOrderRef",$order->ref).'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -352,7 +361,7 @@ if (GETPOST("source") == 'order' && $valid) print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -372,7 +381,7 @@ if (GETPOST("source") == 'order' && $valid) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -380,7 +389,7 @@ if (GETPOST("source") == 'order' && $valid) print '</td></tr>'."\n"; // EMail - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("YourEMail"); print ' ('.$langs->trans("ToComplete").')'; $email=$order->thirdparty->email; @@ -419,19 +428,19 @@ if (GETPOST("source") == 'invoice' && $valid) $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$invoice->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentInvoiceRef",$invoice->ref).'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -440,7 +449,7 @@ if (GETPOST("source") == 'invoice' && $valid) print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -460,7 +469,7 @@ if (GETPOST("source") == 'invoice' && $valid) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -468,7 +477,7 @@ if (GETPOST("source") == 'invoice' && $valid) print '</td></tr>'."\n"; // EMail - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("YourEMail"); print ' ('.$langs->trans("ToComplete").')'; $email=$invoice->thirdparty->email; @@ -553,19 +562,19 @@ if (GETPOST("source") == 'contractline' && $valid) if (GETPOST('qty')) $qty=GETPOST('qty'); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$contract->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentRenewContractId",$contract->ref,$contractline->ref).'</b>'; if ($contractline->fk_product) { @@ -588,7 +597,7 @@ if (GETPOST("source") == 'contractline' && $valid) print '</td></tr>'."\n"; // Quantity - + $label=$langs->trans("Quantity"); $qty=1; $duration=''; @@ -616,7 +625,7 @@ if (GETPOST("source") == 'contractline' && $valid) print '</b></td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -636,7 +645,7 @@ if (GETPOST("source") == 'contractline' && $valid) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -644,7 +653,7 @@ if (GETPOST("source") == 'contractline' && $valid) print '</td></tr>'."\n"; // EMail - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("YourEMail"); print ' ('.$langs->trans("ToComplete").')'; $email=$contract->thirdparty->email; @@ -684,14 +693,14 @@ if (GETPOST("source") == 'membersubscription' && $valid) $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Member"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'; if ($member->morphy == 'mor' && ! empty($member->societe)) print $member->societe; @@ -699,7 +708,7 @@ if (GETPOST("source") == 'membersubscription' && $valid) print '</b>'; // Object - + $text='<b>'.$langs->trans("PaymentSubscription").'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -710,13 +719,13 @@ if (GETPOST("source") == 'membersubscription' && $valid) if ($member->last_subscription_date || $member->last_subscription_amount) { // Last subscription date - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionDate"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.dol_print_date($member->last_subscription_date,'day'); print '</td></tr>'."\n"; // Last subscription amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionAmount"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.price($member->last_subscription_amount); print '</td></tr>'."\n"; @@ -725,7 +734,7 @@ if (GETPOST("source") == 'membersubscription' && $valid) } // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -749,7 +758,7 @@ if (GETPOST("source") == 'membersubscription' && $valid) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -757,7 +766,7 @@ if (GETPOST("source") == 'membersubscription' && $valid) print '</td></tr>'."\n"; // EMail - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("YourEMail"); $email=$member->email; $email=(GETPOST("email")?GETPOST("email"):(isValidEmail($email)?$email:'')); diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 788321b62120c014169ec00b6ba8578180b4eac0..cdfaaa2afc683cbfa21f0f765544c04c3ee9703c 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -156,10 +156,10 @@ $urlko=preg_replace('/&$/','',$urlko); // Remove last & if (! empty($conf->paypal->enabled)) { $langs->load("paypal"); - + require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php'; - + $PAYPAL_API_OK=""; if ($urlok) $PAYPAL_API_OK=$urlok; $PAYPAL_API_KO=""; @@ -194,7 +194,7 @@ if (! empty($conf->paypal->enabled)) $token = $conf->global->PAYPAL_SECURITY_TOKEN; } if ($SECUREKEY != $token) $valid=false; - + if (! $valid) { print '<div class="error">Bad value for key.</div>'; @@ -202,16 +202,16 @@ if (! empty($conf->paypal->enabled)) exit; } } - + $validpaymentmethod['paypal']='valid'; } if (! empty($conf->paybox->enabled)) { $langs->load("paybox"); - + // TODO - + $validpaymentmethod['paybox']='valid'; } @@ -256,10 +256,10 @@ if (empty($validpaymentmethod)) accessforbidden('', 0, 0, 1); if ($action == 'dopayment') { if ($paymentmethod == 'paypal') - { + { $PAYPAL_API_PRICE=price2num(GETPOST("newamount"),'MT'); $PAYPAL_PAYMENT_TYPE='Sale'; - + $origfulltag=GETPOST("fulltag",'alpha'); $shipToName=GETPOST("shipToName"); $shipToStreet=GETPOST("shipToStreet"); @@ -271,24 +271,24 @@ if ($action == 'dopayment') $phoneNum=GETPOST("phoneNum"); $email=GETPOST("email"); $desc=GETPOST("desc"); - + $mesg=''; if (empty($PAYPAL_API_PRICE) || ! is_numeric($PAYPAL_API_PRICE)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Amount")); //elseif (empty($EMAIL)) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail")); //elseif (! isValidEMail($EMAIL)) $mesg=$langs->trans("ErrorBadEMail",$EMAIL); elseif (! $origfulltag) $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("PaymentCode")); - + //var_dump($_POST); if (empty($mesg)) { dol_syslog("newpayment.php call paypal api and do redirect", LOG_DEBUG); - + // Other $PAYPAL_API_DEVISE="USD"; //if ($currency == 'EUR') $PAYPAL_API_DEVISE="EUR"; //if ($currency == 'USD') $PAYPAL_API_DEVISE="USD"; if (! empty($currency)) $PAYPAL_API_DEVISE=$currency; - + dol_syslog("Submit Paypal form", LOG_DEBUG); dol_syslog("PAYPAL_API_USER: $PAYPAL_API_USER", LOG_DEBUG); //dol_syslog("PAYPAL_API_PASSWORD: $PAYPAL_API_PASSWORD", LOG_DEBUG); // No password into log files @@ -308,15 +308,15 @@ if ($action == 'dopayment') dol_syslog("phoneNum: $phoneNum", LOG_DEBUG); dol_syslog("email: $email", LOG_DEBUG); dol_syslog("desc: $desc", LOG_DEBUG); - + dol_syslog("SCRIPT_URI: ".(empty($_SERVER["SCRIPT_URI"])?'':$_SERVER["SCRIPT_URI"]), LOG_DEBUG); // If defined script uri must match domain of PAYPAL_API_OK and PAYPAL_API_KO //$_SESSION["PaymentType"]=$PAYPAL_PAYMENT_TYPE; //$_SESSION["currencyCodeType"]=$PAYPAL_API_DEVISE; //$_SESSION["Payment_Amount"]=$PAYPAL_API_PRICE; - + // A redirect is added if API call successfull print_paypal_redirect($PAYPAL_API_PRICE,$PAYPAL_API_DEVISE,$PAYPAL_PAYMENT_TYPE,$PAYPAL_API_OK,$PAYPAL_API_KO, $FULLTAG); - + exit; } } @@ -335,19 +335,28 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); +// Check link validity +if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +{ + $langs->load("errors"); + dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + llxFooter(); + $db->close(); + exit; +} if (! empty($conf->paypal->enabled)) { - if (! empty($PAYPAL_API_SANDBOX)) - { - dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode'),'','warning'); - } - // Common variables $creditor=$mysoc->name; $paramcreditor='PAYPAL_CREDITOR_'.$suffix; if (! empty($conf->global->$paramcreditor)) $creditor=$conf->global->$paramcreditor; else if (! empty($conf->global->PAYPAL_CREDITOR)) $creditor=$conf->global->PAYPAL_CREDITOR; + + if (! empty($PAYPAL_API_SANDBOX)) + { + dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode'),'','warning'); + } } print '<span id="dolpaymentspan"></span>'."\n"; @@ -442,14 +451,14 @@ if (! GETPOST("source")) $fulltag=$tag; // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -469,7 +478,7 @@ if (! GETPOST("source")) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -507,26 +516,26 @@ if (GETPOST("source") == 'order') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='ORD='.$order->ref.'.CUS='.$order->thirdparty->id; //$fulltag.='.NAM='.strtr($order->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$order->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentOrderRef",$order->ref).'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -535,7 +544,7 @@ if (GETPOST("source") == 'order') print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -555,7 +564,7 @@ if (GETPOST("source") == 'order') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -617,26 +626,26 @@ if (GETPOST("source") == 'invoice') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='INV='.$invoice->ref.'.CUS='.$invoice->thirdparty->id; //$fulltag.='.NAM='.strtr($invoice->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$invoice->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentInvoiceRef",$invoice->ref).'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -645,7 +654,7 @@ if (GETPOST("source") == 'invoice') print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -665,7 +674,7 @@ if (GETPOST("source") == 'invoice') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -745,7 +754,7 @@ if (GETPOST("source") == 'contractline') { $product=new Product($db); $result=$product->fetch($contractline->fk_product); - + // We define price for product (TODO Put this in a method in product class) if (! empty($conf->global->PRODUIT_MULTIPRICES)) { @@ -759,7 +768,7 @@ if (GETPOST("source") == 'contractline') $pu_ttc = $product->price_ttc; $price_base_type = $product->price_base_type; } - + $amount=$pu_ttc; if (empty($amount)) { @@ -780,19 +789,19 @@ if (GETPOST("source") == 'contractline') if (GETPOST('qty')) $qty=GETPOST('qty'); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$contract->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentRenewContractId",$contract->ref,$contractline->ref).'</b>'; if ($contractline->fk_product) { @@ -815,7 +824,7 @@ if (GETPOST("source") == 'contractline') print '</td></tr>'."\n"; // Quantity - + $label=$langs->trans("Quantity"); $qty=1; $duration=''; @@ -843,7 +852,7 @@ if (GETPOST("source") == 'contractline') print '</b></td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -863,7 +872,7 @@ if (GETPOST("source") == 'contractline') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -925,20 +934,20 @@ if (GETPOST("source") == 'membersubscription') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='MEM='.$member->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M'); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Member"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'; if ($member->morphy == 'mor' && ! empty($member->societe)) print $member->societe; @@ -946,7 +955,7 @@ if (GETPOST("source") == 'membersubscription') print '</b>'; // Object - + $text='<b>'.$langs->trans("PaymentSubscription").'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -957,13 +966,13 @@ if (GETPOST("source") == 'membersubscription') if ($member->last_subscription_date || $member->last_subscription_amount) { // Last subscription date - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionDate"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.dol_print_date($member->last_subscription_date,'day'); print '</td></tr>'."\n"; // Last subscription amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionAmount"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.price($member->last_subscription_amount); print '</td></tr>'."\n"; @@ -972,7 +981,7 @@ if (GETPOST("source") == 'membersubscription') } // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) { @@ -1001,7 +1010,7 @@ if (GETPOST("source") == 'membersubscription') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -1051,11 +1060,11 @@ if ($action != 'dopayment') if ($found && ! $error) // We are in a management option and no error { // Buttons for all payments registration methods - + if (! empty($conf->paypal->enabled)) { if (empty($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY)) $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY='integral'; - + if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'integral') { print '<br><input class="button" type="submit" name="dopayment_paypal" value="'.$langs->trans("PaypalOrCBDoPayment").'">'; @@ -1065,13 +1074,13 @@ if ($action != 'dopayment') print '<br><input class="button" type="submit" name="dopayment_paypal" value="'.$langs->trans("PaypalDoPayment").'">'; } } - + if (! empty($conf->paybox->enabled)) { - - + + } - + // TODO Other methods } else diff --git a/htdocs/public/paypal/newpayment.php b/htdocs/public/paypal/newpayment.php index 6de2cb8a4415c0766a3d58ec6859354f8cf98eed..65fbfbd38a7a59446ca066eefa347a9979879685 100644 --- a/htdocs/public/paypal/newpayment.php +++ b/htdocs/public/paypal/newpayment.php @@ -265,17 +265,27 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); -if (! empty($conf->global->PAYPAL_API_SANDBOX)) -{ - dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode'),'','warning'); -} - // Common variables $creditor=$mysoc->name; $paramcreditor='PAYPAL_CREDITOR_'.$suffix; if (! empty($conf->global->$paramcreditor)) $creditor=$conf->global->$paramcreditor; else if (! empty($conf->global->PAYPAL_CREDITOR)) $creditor=$conf->global->PAYPAL_CREDITOR; +// Check link validity +if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +{ + $langs->load("errors"); + dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + llxFooter(); + $db->close(); + exit; +} + +if (! empty($conf->global->PAYPAL_API_SANDBOX)) +{ + dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode'),'','warning'); +} + print '<span id="dopaymentspan"></span>'."\n"; print '<div class="center">'."\n"; print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n"; @@ -359,14 +369,14 @@ if (! GETPOST("source")) $fulltag=$tag; // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -386,7 +396,7 @@ if (! GETPOST("source")) print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -424,26 +434,26 @@ if (GETPOST("source") == 'order') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='ORD='.$order->ref.'.CUS='.$order->thirdparty->id; //$fulltag.='.NAM='.strtr($order->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$order->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentOrderRef",$order->ref).'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -452,7 +462,7 @@ if (GETPOST("source") == 'order') print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -472,7 +482,7 @@ if (GETPOST("source") == 'order') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -534,26 +544,26 @@ if (GETPOST("source") == 'invoice') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='INV='.$invoice->ref.'.CUS='.$invoice->thirdparty->id; //$fulltag.='.NAM='.strtr($invoice->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$invoice->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentInvoiceRef",$invoice->ref).'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -562,7 +572,7 @@ if (GETPOST("source") == 'invoice') print '</td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -582,7 +592,7 @@ if (GETPOST("source") == 'invoice') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -662,7 +672,7 @@ if (GETPOST("source") == 'contractline') { $product=new Product($db); $result=$product->fetch($contractline->fk_product); - + // We define price for product (TODO Put this in a method in product class) if (! empty($conf->global->PRODUIT_MULTIPRICES)) { @@ -676,7 +686,7 @@ if (GETPOST("source") == 'contractline') $pu_ttc = $product->price_ttc; $price_base_type = $product->price_base_type; } - + $amount=$pu_ttc; if (empty($amount)) { @@ -697,19 +707,19 @@ if (GETPOST("source") == 'contractline') if (GETPOST('qty')) $qty=GETPOST('qty'); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$contract->thirdparty->name.'</b>'; // Object - + $text='<b>'.$langs->trans("PaymentRenewContractId",$contract->ref,$contractline->ref).'</b>'; if ($contractline->fk_product) { @@ -732,7 +742,7 @@ if (GETPOST("source") == 'contractline') print '</td></tr>'."\n"; // Quantity - + $label=$langs->trans("Quantity"); $qty=1; $duration=''; @@ -760,7 +770,7 @@ if (GETPOST("source") == 'contractline') print '</b></td></tr>'."\n"; // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) print ' ('.$langs->trans("ToComplete").')'; print '</td><td class="CTableRow'.($var?'1':'2').'">'; @@ -780,7 +790,7 @@ if (GETPOST("source") == 'contractline') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; @@ -824,6 +834,7 @@ if (GETPOST("source") == 'membersubscription') require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; + $member=new Adherent($db); $result=$member->fetch('',$ref); if ($result < 0) @@ -842,20 +853,20 @@ if (GETPOST("source") == 'membersubscription') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='MEM='.$member->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M'); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); // Creditor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; print '<input type="hidden" name="creditor" value="'.$creditor.'">'; print '</td></tr>'."\n"; // Debitor - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Member"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'; if ($member->morphy == 'mor' && ! empty($member->societe)) print $member->societe; @@ -863,7 +874,7 @@ if (GETPOST("source") == 'membersubscription') print '</b>'; // Object - + $text='<b>'.$langs->trans("PaymentSubscription").'</b>'; print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text; @@ -874,13 +885,13 @@ if (GETPOST("source") == 'membersubscription') if ($member->last_subscription_date || $member->last_subscription_amount) { // Last subscription date - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionDate"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.dol_print_date($member->last_subscription_date,'day'); print '</td></tr>'."\n"; // Last subscription amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionAmount"); print '</td><td class="CTableRow'.($var?'1':'2').'">'.price($member->last_subscription_amount); print '</td></tr>'."\n"; @@ -889,7 +900,7 @@ if (GETPOST("source") == 'membersubscription') } // Amount - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount"); if (empty($amount)) { @@ -918,7 +929,7 @@ if (GETPOST("source") == 'membersubscription') print '</td></tr>'."\n"; // Tag - + print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>'; print '<input type="hidden" name="tag" value="'.$tag.'">'; diff --git a/htdocs/public/stripe/newpayment.php b/htdocs/public/stripe/newpayment.php index 01ae19c703217aa0421d714e0d99c387216abf1a..af0c880d3c8f42e0a865856bccc42ad1572d228d 100644 --- a/htdocs/public/stripe/newpayment.php +++ b/htdocs/public/stripe/newpayment.php @@ -196,7 +196,7 @@ else if (! empty($conf->global->STRIPE_CREDITOR)) $creditor=$conf->global->STRIP if ($action == 'dopayment') // We click on button Create payment { if (GETPOST('newamount')) $amount = GETPOST('newamount'); - else + else { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")), null, 'errors'); $action = ''; @@ -209,18 +209,18 @@ if ($action == 'charge') // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support $arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); if (! in_array($currency, $arrayzerounitcurrency)) $amount=$amount * 100; - + dol_syslog("POST keys : ".join(',', array_keys($_POST)), LOG_DEBUG, 0, '_stripe'); dol_syslog("POST values: ".join(',', $_POST), LOG_DEBUG, 0, '_stripe'); - + $stripeToken = GETPOST("stripeToken",'alpha'); $email = GETPOST("stripeEmail",'alpha'); dol_syslog("stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe'); dol_syslog("stripeEmail = ".$stripeEmail, LOG_DEBUG, 0, '_stripe'); - + $error = 0; - + try { dol_syslog("Create customer", LOG_DEBUG, 0, '_stripe'); $customer = \Stripe\Customer::create(array( @@ -230,7 +230,7 @@ if ($action == 'charge') 'source' => $stripeToken // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?) )); // TODO Add 'business_vat_id' ? - + dol_syslog("Create charge", LOG_DEBUG, 0, '_stripe'); $charge = \Stripe\Charge::create(array( 'customer' => $customer->id, @@ -244,14 +244,14 @@ if ($action == 'charge') // Since it's a decline, \Stripe\Error\Card will be caught $body = $e->getJsonBody(); $err = $body['error']; - + print('Status is:' . $e->getHttpStatus() . "\n"); print('Type is:' . $err['type'] . "\n"); print('Code is:' . $err['code'] . "\n"); // param is '' in this case print('Param is:' . $err['param'] . "\n"); print('Message is:' . $err['message'] . "\n"); - + $error++; setEventMessages($e->getMessage(), null, 'errors'); dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe'); @@ -295,7 +295,7 @@ if ($action == 'charge') setEventMessages($e->getMessage(), null, 'errors'); $action=''; } - + $_SESSION["onlinetoken"] = $stripeToken; $_SESSION["FinalPaymentAmt"] = $amount; $_SESSION["currencyCodeType"] = $currency; @@ -303,12 +303,12 @@ if ($action == 'charge') $_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR']; // Payer ip $_SESSION['payerID'] = is_object($customer)?$customer->id:''; $_SESSION['TRANSACTIONID'] = is_object($charge)?$charge->id:''; - + dol_syslog("Action charge stripe result=".$error." ip=".$_SESSION['ipaddress'], LOG_DEBUG, 0, '_stripe'); dol_syslog("onlinetoken=".$_SESSION["onlinetoken"]." FinalPaymentAmt=".$_SESSION["FinalPaymentAmt"]." currencyCodeType=".$_SESSION["currencyCodeType"]." payerID=".$_SESSION['payerID']." TRANSACTIONID=".$_SESSION['TRANSACTIONID'], LOG_DEBUG, 0, '_stripe'); dol_syslog("FULLTAG=".$FULLTAG, LOG_DEBUG, 0, '_stripe'); dol_syslog("Now call the redirect to paymentok or paymentko", LOG_DEBUG, 0, '_stripe'); - + if ($error) { header("Location: ".$urlko); @@ -319,7 +319,7 @@ if ($action == 'charge') header("Location: ".$urlok); exit; } - + } @@ -335,6 +335,16 @@ $conf->dol_hide_leftmenu=1; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'); +// Check link validity +if (! empty($SOURCE) && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', ''))) +{ + $langs->load("errors"); + dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $SOURCE, $ref)); + llxFooter(); + $db->close(); + exit; +} + if (empty($conf->global->STRIPE_LIVE)) { dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode'),'','warning'); @@ -420,7 +430,7 @@ if (! GETPOST("source")) $found=true; $tag=GETPOST("tag"); $fulltag=$tag; - + // Creditor print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>'; @@ -485,7 +495,7 @@ if (GETPOST("source") == 'order') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='ORD='.$order->ref.'.CUS='.$order->thirdparty->id; //$fulltag.='.NAM='.strtr($order->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } @@ -600,7 +610,7 @@ if (GETPOST("source") == 'invoice') //$fulltag.='.NAM='.strtr($invoice->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); - + // Creditor print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor"); @@ -723,7 +733,7 @@ if (GETPOST("source") == 'contractline') { $product=new Product($db); $result=$product->fetch($contractline->fk_product); - + // We define price for product (TODO Put this in a method in product class) if (! empty($conf->global->PRODUIT_MULTIPRICES)) { @@ -737,7 +747,7 @@ if (GETPOST("source") == 'contractline') $pu_ttc = $product->price_ttc; $price_base_type = $product->price_base_type; } - + $amount=$pu_ttc; if (empty($amount)) { @@ -749,7 +759,7 @@ if (GETPOST("source") == 'contractline') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='COL='.$contractline->ref.'.CON='.$contract->ref.'.CUS='.$contract->thirdparty->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M'); //$fulltag.='.NAM='.strtr($contract->thirdparty->name,"-"," "); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } @@ -904,7 +914,7 @@ if (GETPOST("source") == 'membersubscription') if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int'); $amount=price2num($amount); } - + $fulltag='MEM='.$member->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M'); if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; } $fulltag=dol_string_unaccent($fulltag); @@ -1059,7 +1069,7 @@ if (preg_match('/^dopayment/',$action)) data-description="'.$ref.'"> </script>'; */ - + // Personalized checkout print '<style> /** @@ -1075,22 +1085,22 @@ if (preg_match('/^dopayment/',$action)) -webkit-transition: box-shadow 150ms ease; transition: box-shadow 150ms ease; } - + .StripeElement--focus { box-shadow: 0 1px 3px 0 #cfd7df; } - + .StripeElement--invalid { border-color: #fa755a; } - + .StripeElement--webkit-autofill { background-color: #fefde5 !important; } </style>'; - + print ' - + <br> <form action="'.$_SERVER['REQUEST_URI'].'" method="POST" id="payment-form">'; @@ -1106,11 +1116,11 @@ if (preg_match('/^dopayment/',$action)) print '<input type="hidden" name="entity" value="'.$entity.'" />'; print '<input type="hidden" name="amount" value="'.$amount.'">'."\n"; print '<input type="hidden" name="currency" value="'.$currency.'">'."\n"; - + print ' <table id="dolpaymenttable" summary="Payment form" class="center"> <tbody><tr><td class="textpublicpayment"> - + <div class="form-row left"> <label for="card-element"> Credit or debit card @@ -1118,7 +1128,7 @@ if (preg_match('/^dopayment/',$action)) <div id="card-element"> <!-- a Stripe Element will be inserted here. --> </div> - + <!-- Used to display form errors --> <div id="card-errors" role="alert"></div> </div> @@ -1126,22 +1136,22 @@ if (preg_match('/^dopayment/',$action)) <button class="button" id="buttontopay">'.$langs->trans("ToPay").'</button> <img id="hourglasstopay" class="hidden" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/working.gif'.'"> </td></tr></tbody></table> - + </form> - + <script src="https://js.stripe.com/v2/"></script> <script src="https://js.stripe.com/v3/"></script> - + <script type="text/javascript" language="javascript">'; ?> // Create a Stripe client var stripe = Stripe('<?php echo $stripe['publishable_key']; ?>'); - + // Create an instance of Elements var elements = stripe.elements(); - + // Custom styling can be passed to options when creating an Element. // (Note that this demo uses a wider set of styles than the guide below.) var style = { @@ -1160,13 +1170,13 @@ if (preg_match('/^dopayment/',$action)) iconColor: '#fa755a' } }; - + // Create an instance of the card Element var card = elements.create('card', {style: style}); - + // Add an instance of the card Element into the `card-element` <div> card.mount('#card-element'); - + // Handle real-time validation errors from the card Element. card.addEventListener('change', function(event) { var displayError = document.getElementById('card-errors'); @@ -1176,13 +1186,13 @@ if (preg_match('/^dopayment/',$action)) displayError.textContent = ''; } }); - + // Handle form submission var form = document.getElementById('payment-form'); console.log(form); form.addEventListener('submit', function(event) { event.preventDefault(); - + stripe.createToken(card).then(function(result) { if (result.error) { // Inform the user if there was an error @@ -1194,7 +1204,7 @@ if (preg_match('/^dopayment/',$action)) } }); }); - + function stripeTokenHandler(token) { // Insert the token ID into the form so it gets submitted to the server var form = document.getElementById('payment-form'); @@ -1203,16 +1213,16 @@ if (preg_match('/^dopayment/',$action)) hiddenInput.setAttribute('name', 'stripeToken'); hiddenInput.setAttribute('value', token.id); form.appendChild(hiddenInput); - + // Submit the form jQuery('#buttontopay').hide(); jQuery('#hourglasstopay').show(); console.log("submit"); form.submit(); - } - + } + <?php - print '</script>'; + print '</script>'; } diff --git a/htdocs/societe/admin/societe.php b/htdocs/societe/admin/societe.php index 63ba12197fddaa32967425566930404b41eaeffe..5c84be25521cc67315e1d9cbe8b882b15dbb218d 100644 --- a/htdocs/societe/admin/societe.php +++ b/htdocs/societe/admin/societe.php @@ -42,6 +42,9 @@ if (!$user->admin) accessforbidden(); /* * Actions */ + +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'setcodeclient') { if (dolibarr_set_const($db, "SOCIETE_CODECLIENT_ADDON",$value,'chaine',0,'',$conf->entity) > 0) @@ -101,35 +104,6 @@ if ($action == 'updateoptions') } } -// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) -if ($action == 'setModuleOptions') -{ - $post_size=count($_POST); - - $db->begin(); - - for($i=0;$i < $post_size;$i++) - { - if (array_key_exists('param'.$i,$_POST)) - { - $param=GETPOST("param".$i,'alpha'); - $value=GETPOST("value".$i,'alpha'); - if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); - if (! $res > 0) $error++; - } - } - if (! $error) - { - $db->commit(); - setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { - $db->rollback(); - setEventMessages($langs->trans("Error"), null, 'errors'); - } -} - // Activate a document generator module if ($action == 'set') { diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 7019933fb9cb2cf7996c847516c8f73d19dcef72..20323136017f27729e0d01d913ba6aa6a71e3efe 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -356,11 +356,13 @@ class SupplierProposal extends CommonObject * @param array $array_option extrafields array * @param string $ref_fourn Supplier price reference * @param int $fk_unit Id of the unit to use. + * @param string $origin 'order', 'supplier_proposal', ... + * @param int $origin_id Id of origin line * @return int >0 if OK, <0 if KO * * @see add_product */ - function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$array_option=0, $ref_fourn='', $fk_unit='') + function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='',$array_option=0, $ref_fourn='', $fk_unit='', $origin='', $origin_id=0) { global $mysoc; @@ -462,7 +464,8 @@ class SupplierProposal extends CommonObject $this->line->special_code=$special_code; $this->line->fk_parent_line=$fk_parent_line; $this->line->fk_unit=$fk_unit; - + $this->line->origin=$origin; + $this->line->origin_id=$origin_id; $this->line->ref_fourn = $this->db->escape($ref_fourn); // infos marge @@ -880,7 +883,10 @@ class SupplierProposal extends CommonObject $this->lines[$i]->pa_ht, $this->lines[$i]->label, $this->lines[$i]->array_options, - $this->lines[$i]->ref_fourn + $this->lines[$i]->ref_fourn, + $this->lines[$i]->fk_unit, + 'supplier_proposal', + $this->lines[$i]->rowid ); if ($result < 0) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 33bba8f1404cfe024486bc4692a9cc83bc728c18..3912a9b80fff44d49930b18be5c9a21d1aff12e5 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -39,7 +39,7 @@ if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); $colorbackhmenu1='80,90,120'; // topmenu $colorbackvmenu1='255,255,255'; // vmenu $colortopbordertitle1='120,120,120'; // top border of title -$colorbacktitle1='230,230,230'; // title of tables,list +$colorbacktitle1='230,230,233'; // title of tables,list $colorbacktabcard1='255,255,255'; // card $colorbacktabactive='234,234,234'; $colorbacklineimpair1='255,255,255'; // line impair @@ -56,7 +56,7 @@ $fontsize='13'; $fontsizesmaller='12'; if (defined('THEME_ONLY_CONSTANT')) return; - + session_cache_limiter(FALSE); require_once '../../main.inc.php'; @@ -272,8 +272,8 @@ input[type=submit] { margin-left: 5px; } input, input.flat, form.flat select, select, select.flat, .dataTables_length label select { - <?php if (empty($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)) - print "border: none;" + <?php if (empty($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)) + print "border: none;" ?> } input, input.flat, textarea, textarea.flat, form.flat select, select, select.flat, .dataTables_length label select { @@ -340,9 +340,9 @@ input.buttongen { vertical-align: middle; } span.timesheetalreadyrecorded input { - /*font-size: smaller;*/ border: none; - /*background: transparent;*/ + border-bottom: solid 1px rgba(0,0,0,0.4); + margin-right: 1px !important; } select.flat, form.flat select { @@ -363,8 +363,10 @@ select.flat, form.flat select { .opacitytransp { opacity: 0; } -select:invalid { color: gray; } - input:disabled { +select:invalid { + color: gray; +} +input:disabled { background:#ddd; } @@ -712,6 +714,7 @@ div.fiche>form>div.div-table-responsive { align-self: flex-start; } + /* ============================================================================== */ /* Styles to hide objects */ /* ============================================================================== */ @@ -901,7 +904,7 @@ td.showDragHandle { #id-right, #id-left { padding-top: 16px; padding-bottom: 16px; - + display: table-cell; /* DOL_XXX Empeche fonctionnement correct du scroll horizontal sur tableau, avec datatable ou CSS */ float: none; vertical-align: top; @@ -987,7 +990,7 @@ div.fiche { div.fiche { margin-<?php print $left; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?6:($dol_hide_leftmenu?'6':'26')); ?>px; - margin-<?php print $right; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?8:(empty($conf->dol_optimize_smallscreen)?'16':'6')); ?>px; + margin-<?php print $right; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?8:(empty($conf->dol_optimize_smallscreen)?'16':'12')); ?>px; <?php if (! empty($conf->dol_hide_leftmenu) && ! empty($conf->dol_hide_topmenu)) print 'margin-top: 4px;'."\n"; ?> <?php if (! empty($conf->dol_hide_leftmenu)) print 'margin-bottom: 12px;'."\n"; ?> } @@ -1529,7 +1532,7 @@ foreach($mainmenuusedarray as $val) display: table; position: absolute; height: 100%; - width: 100%; + width: 100%; } .login_center { display: table-cell; @@ -1754,12 +1757,12 @@ div.vmenu, td.vmenu { <?php } ?> } -/* Force vmenusearchselectcombo with type=text differently than without because beautify with select2 affect vmenusearchselectcombo differently */ +/* Force vmenusearchselectcombo with type=text differently than without because beautify with select2 affect vmenusearchselectcombo differently */ input.vmenusearchselectcombo[type=text] { width: 180px !important; } .vmenusearchselectcombo { - width: 188px; + width: 188px; } .menu_contenu { @@ -1926,7 +1929,7 @@ td.ecmroot { background-image: -webkit-linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important; background-image: -ms-linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important; background-image: linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important; - + background: #FFF; background-repeat: repeat-x !important; */ @@ -1939,7 +1942,7 @@ td.ecmroot { -webkit-box-shadow: 2px 2px 4px #DDD; box-shadow: 2px 2px 4px #DDD; */ - + padding: 10px 4px 14px 4px !important; min-height: 32px; } @@ -1969,7 +1972,7 @@ div.tabs { padding-right: 6px !important; clear:both; height:100%; - /* background-image: linear-gradient(to top,#f6f6f6 0,#fff 8px); */ + /* background-image: linear-gradient(to top,#f6f6f6 0,#fff 8px); */ } div.tabsElem { margin-top: 1px; @@ -1987,12 +1990,12 @@ div.tabBar { background: rgb(<?php echo $colorbacktabcard1; ?>); } div.tabBar div.titre { - padding-top: 10px; + padding-top: 10px; } div.tabBarWithBottom { padding-bottom: 18px; - border-bottom: 1px solid #aaa; + border-bottom: 1px solid #aaa; } div.tabBar table.tableforservicepart2:last-child { border-bottom: 1px solid #aaa; @@ -2623,7 +2626,7 @@ div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_se background: rgb(<?php echo $colorbacktitle1; ?>); font-weight: <?php echo $useboldtitle?'bold':'normal'; ?>; border-bottom: 1px solid #ddd; - + color: rgb(<?php echo $colortexttitle; ?>); font-family: <?php print $fontlist ?>; text-align: <?php echo $left; ?>; @@ -2682,7 +2685,7 @@ input.liste_titre { } .noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total { - /* background: #F0F0F0; */ + height: 32px; } .noborder tr.liste_total td, tr.liste_total td, form.liste_total div { color: #552266; @@ -2734,7 +2737,7 @@ div.tabBar .noborder { /* Prepare to remove class pair - impair */ -.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) { +.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) { background: linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%); background: -o-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%); background: -moz-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%); @@ -2761,7 +2764,7 @@ div.tabBar .noborder { /* * Boxes */ - + .ficheaddleft div.boxstats { border: none; } @@ -2775,19 +2778,19 @@ div.tabBar .noborder { text-align: center; border-radius: 2px; } -.boxstats, .boxstats130, .boxstatscontent { +.boxstats, .boxstats130, .boxstatscontent { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .boxstats { padding: 3px; - width: 105px; + width: 105px; } .boxstats130 { - width: 160px; + width: 160px; height: 48px; - padding: 3px + padding: 3px } .boxstatscontent { padding: 3px; @@ -2795,13 +2798,16 @@ div.tabBar .noborder { @media only screen and (max-width: 767px) { + .thumbstat { + flex: 1 1 110px; + } .thumbstat150 { flex: 1 1 110px; } .boxstats, .boxstats130 { - width: 90px; + width: 90px; } - .dashboardlineindicator { + .dashboardlineindicator { float: left; padding-left: 5px; } @@ -2833,7 +2839,7 @@ span.dashboardlineko { color: #FFF; /*color: #8c4446 ! important; padding-left: 1px;*/ - + font-size: 80%; } .dashboardlinelatecoin { @@ -2842,9 +2848,9 @@ span.dashboardlineko { text-align: right; top: -24px; padding: 1px 2px 1px 2px; - border-radius: .25em; + border-radius: .25em; - background-color: #af4705; + background-color: #9f4705; padding: 0px 5px 0px 5px; top: -26px; } @@ -2854,7 +2860,7 @@ span.dashboardlineko { margin-right: 2px; background-color: #8c4446; color: #FFFFFF ! important; - border-radius: .25em; + border-radius: .25em; display: inline-block; vertical-align: middle; } @@ -3955,7 +3961,7 @@ div.dataTables_length select { border-top: 1px solid #ccc; border-bottom: solid 1px rgba(0,0,0,.2); } -.select2-container-active .select2-choice, .select2-container-active .select2-choices +.select2-container-active .select2-choice, .select2-container-active .select2-choices { outline: none; border-top: none; @@ -4039,7 +4045,7 @@ a span.select2-chosen border-right: none; border-top: none; border-left: none; - + } @@ -4593,7 +4599,12 @@ div.tabsElem a.tab { z-index: 201; background: #FFF; } - + + .login_vertical_align { + padding-left: 20px; + padding-right: 20px; + } + /* Reduce login top right info */ .help { <?php if ($disableimages) { ?> @@ -4628,7 +4639,7 @@ div.tabsElem a.tab { vertical-align: middle; background: #FFF; height: 42px; - + z-index: 202; min-width: 190px; max-width: 190px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index a1851dc4a764659eaf8e92494e47412f1cd59d74..d3f822bcca218e04ca6e6d1aa991bc3fcb6483c5 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -317,7 +317,7 @@ textarea { border-left:solid 1px rgba(0,0,0,.1); border-right:solid 1px rgba(0,0,0,.1); border-bottom:solid 1px rgba(0,0,0,.2); - + background-color: #FFF; padding:4px; margin-left:1px; @@ -337,9 +337,9 @@ input.buttongen { vertical-align: middle; } span.timesheetalreadyrecorded input { - /*font-size: smaller;*/ border: none; - /*background: transparent;*/ + border-bottom: solid 1px rgba(0,0,0,0.1); + margin-right: 1px !important; } select.flat, form.flat select { @@ -867,10 +867,10 @@ div.fiche>form>div.div-table-responsive { width: 20px; object-fit: contain; } - + div.statusref { padding-right: 10px; - } + } } .linkobject { cursor: pointer; } <?php if (GETPOST('optioncss','aZ09') == 'print') { ?> @@ -1027,7 +1027,7 @@ div.fiche { div.fiche { margin-<?php print $left; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?6:($dol_hide_leftmenu?'4':'20')); ?>px; - margin-<?php print $right; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?8:(empty($conf->dol_optimize_smallscreen)?'16':'4')); ?>px; + margin-<?php print $right; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?8:(empty($conf->dol_optimize_smallscreen)?'16':'12')); ?>px; <?php if (! empty($conf->dol_hide_leftmenu) && ! empty($conf->dol_hide_topmenu)) print 'margin-top: 4px;'; ?> margin-bottom: 15px; } @@ -1557,12 +1557,12 @@ foreach($mainmenuusedarray as $val) display: table; position: absolute; height: 100%; - width: 100%; + width: 100%; } .login_center { display: table-cell; vertical-align: middle; -} +} .login_vertical_align { padding: 10px; padding-bottom: 80px; @@ -1992,14 +1992,14 @@ div.tabBar { border-top: 1px solid #CCC; width: auto; background: rgb(<?php echo $colorbacktabcard1; ?>); - border-bottom: 1px solid #aaa; + border-bottom: 1px solid #aaa; } div.tabBar div.titre { - padding-top: 10px; + padding-top: 10px; } div.tabBarWithBottom { padding-bottom: 18px; - border-bottom: 1px solid #aaa; + border-bottom: 1px solid #aaa; } div.tabBar table.tableforservicepart2:last-child { border-bottom: 1px solid #aaa; @@ -2720,7 +2720,7 @@ tr.liste_titre th, tr.liste_titre td, th.liste_titre, form.liste_titre div, div. { border-bottom: 1px solid #<?php echo ($colorbacktitle1 == '255,255,255'?'BBBBBB':'FDFFFF'); ?>; } -/* TODO Once title line is moved under title search, make border bottom of all th black and force to whit when it's first tr */ +/* TODO Once title line is moved under title search, make border bottom of all th black and force to whit when it's first tr */ tr:first-child th.liste_titre { border-bottom: 1px solid #FFF ! important; } @@ -2769,7 +2769,7 @@ input.liste_titre { } .noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total { - /* background: #F0F0F0; */ + height: 32px; } .noborder tr.liste_total td, tr.liste_total td, form.liste_total div { /* border-top: 1px solid #f4f4f4; */ @@ -2777,7 +2777,6 @@ input.liste_titre { font-weight: normal; white-space: nowrap; padding: 4px; - height: 20px; } tr.liste_sub_total, tr.liste_sub_total td { border-bottom: 2px solid #aaa; @@ -2826,7 +2825,7 @@ div .tdtop { /* Prepare to remove class pair - impair */ -.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) { +.noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) { background: linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%); background: -o-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%); background: -moz-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%); @@ -2852,7 +2851,7 @@ div .tdtop { /* * Boxes */ - + .ficheaddleft div.boxstats { border: none; } @@ -2866,29 +2865,32 @@ div .tdtop { text-align: center; border-radius: 2px; } -.boxstats, .boxstats130, .boxstatscontent { +.boxstats, .boxstats130, .boxstatscontent { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .boxstats { padding: 3px; - width: 105px; + width: 105px; } .boxstats130 { - width: 135px; + width: 135px; height: 48px; - padding: 3px + padding: 3px } @media only screen and (max-width: 767px) { + .thumbstat { + flex: 1 1 110px; + } .thumbstat150 { flex: 1 1 110px; } .boxstats, .boxstats130 { - width: 90px; + width: 90px; } - .dashboardlineindicator { + .dashboardlineindicator { float: left; padding-left: 5px; } @@ -2927,7 +2929,7 @@ span.dashboardlineko { padding: 1px 6px 1px 6px; background-color: #8c4446; color: #FFFFFF ! important; - border-radius: .25em; + border-radius: .25em; } .boxtable { margin-bottom: 8px !important; @@ -4047,7 +4049,7 @@ div.dataTables_length select { border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; } -.select2-container-active .select2-choice, .select2-container-active .select2-choices +.select2-container-active .select2-choice, .select2-container-active .select2-choices { outline: none; border-top: none; diff --git a/test/phpunit/CodingSqlTest.php b/test/phpunit/CodingSqlTest.php index c6123df3e778dc2c5de8a1e25b95c75d978c6f7a..c56f76af246a488a36d158d61efeff54f0070911 100644 --- a/test/phpunit/CodingSqlTest.php +++ b/test/phpunit/CodingSqlTest.php @@ -143,16 +143,16 @@ class CodingSqlTest extends PHPUnit_Framework_TestCase $listofsqldir = array(DOL_DOCUMENT_ROOT.'/install/mysql/tables', DOL_DOCUMENT_ROOT.'/install/mysql/migration'); - foreach ($listofsqldir as $dir) + foreach ($listofsqldir as $dir) { print 'Process dir '.$dir."\n"; $filesarray = scandir($dir); - - foreach($filesarray as $key => $file) + + foreach($filesarray as $key => $file) { if (! preg_match('/\.sql$/',$file)) continue; - + print 'Check sql file '.$file."\n"; $filecontent=file_get_contents($dir.'/'.$file); @@ -167,7 +167,7 @@ class CodingSqlTest extends PHPUnit_Framework_TestCase $result=strpos($filecontent,'ON DELETE CASCADE'); print __METHOD__." Result for checking we don't have 'ON DELETE CASCADE' = ".$result."\n"; $this->assertTrue($result===false, 'Found ON DELETE CASCADE into '.$file.'. Bad.'); - + if ($dir == DOL_DOCUMENT_ROOT.'/install/mysql/migration') { // Test for migration files only @@ -176,16 +176,20 @@ class CodingSqlTest extends PHPUnit_Framework_TestCase else { if (preg_match('/\.key\.sql$/',$file)) - { - // Test for files key files only - + { + // Test for key files only + } else { - // Test for files non key files only + // Test for non key files only $result=(strpos($filecontent,'KEY ') && strpos($filecontent,'PRIMARY KEY ') == 0); print __METHOD__." Result for checking we don't have ' KEY ' instead of a sql file to create index = ".$result."\n"; $this->assertTrue($result===false, 'Found KEY into '.$file.'. Bad.'); + + $result=stripos($filecontent,'ENGINE=innodb'); + print __METHOD__." Result for checking we have the ENGINE=innodb string = ".$result."\n"; + $this->assertGreaterThan(0, $result, 'The ENGINE=innodb was not found into '.$file.'. Add it or just fix syntax to match case.'); } } } diff --git a/test/phpunit/DateLibTest.php b/test/phpunit/DateLibTest.php index 02d85164d79b26771ef089b7b52995c9298250d0..645993d86593bbb798fc27506819cb208335ff6d 100644 --- a/test/phpunit/DateLibTest.php +++ b/test/phpunit/DateLibTest.php @@ -179,32 +179,32 @@ class DateLibTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + // With same hours - Tuesday/Wednesday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 1, 2013); $date2=dol_mktime(0, 0, 0, 1, 2, 2013); - + $result=num_public_holiday($date1,$date2,'FR',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumPublicHoliday for Tuesday/Wednesday jan 2013 for FR'); // 1 closed days - + $result=num_public_holiday($date1,$date2,'XX',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(0,$result,'NumPublicHoliday for Tuesday/Wednesday jan 2013 for XX'); // no closed days (country unknown) - + // With same hours - Friday/Sunday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 4, 2013); $date2=dol_mktime(0, 0, 0, 1, 6, 2013); - + $result=num_public_holiday($date1,$date2,'FR',1); print __METHOD__." result=".$result."\n"; - $this->assertEquals(2,$result,'NumPublicHoliday for FR'); // 1 opened day, 2 closed days - + $this->assertEquals(2,$result,'NumPublicHoliday for FR'); // 1 opened day, 2 closed days + $result=num_public_holiday($date1,$date2,'XX',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(2,$result,'NumPublicHoliday for XX'); // 1 opened day, 2 closed days (even if country unknown) } - + /** * testNumOpenDay * @@ -217,32 +217,32 @@ class DateLibTest extends PHPUnit_Framework_TestCase $user=$this->savuser; $langs=$this->savlangs; $db=$this->savdb; - + // With same hours - Tuesday/Wednesday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 1, 2013); $date2=dol_mktime(0, 0, 0, 1, 2, 2013); - + $result=num_open_day($date1,$date2,0,1,0,'FR'); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumOpenDay Tuesday/Wednesday jan 2013 for FR'); // 1 opened days - + $result=num_open_day($date1,$date2,0,1,0,'XX'); print __METHOD__." result=".$result."\n"; $this->assertEquals(2,$result,'NumOpenDay Tuesday/Wednesday jan 2013 for XX'); // 2 opened days (country unknown) - + // With same hours - Friday/Sunday jan 2013 $date1=dol_mktime(0, 0, 0, 1, 4, 2013); $date2=dol_mktime(0, 0, 0, 1, 6, 2013); - + $result=num_open_day($date1,$date2,0,1,0,'FR'); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumOpenDay for FR'); // 1 opened day, 2 closed - + $result=num_open_day($date1,$date2,'XX',1); print __METHOD__." result=".$result."\n"; $this->assertEquals(1,$result,'NumOpenDay for XX'); // 1 opened day, 2 closes (even if country unknown) } - + /** * testConvertTime2Seconds * @@ -335,6 +335,11 @@ class DateLibTest extends PHPUnit_Framework_TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals('02/01/1970 00:00',$result); + // Check %a and %b format for fr_FR + $result=dol_print_date(0,'%a %b %B',true,$outputlangs); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('Jeu Jan. Janvier',$result); + // Check day format for en_US $outputlangs=new Translate('',$conf); $outputlangs->setDefaultLang('en_US'); @@ -345,9 +350,9 @@ class DateLibTest extends PHPUnit_Framework_TestCase $this->assertEquals('01/02/1970',$result); // Check %a and %b format for en_US - $result=dol_print_date(0,'%a %b',true,$outputlangs); + $result=dol_print_date(0,'%a %b %B',true,$outputlangs); print __METHOD__." result=".$result."\n"; - $this->assertEquals('Thu Jan',$result); + $this->assertEquals('Thu Jan January',$result); return $result; }