';
foreach ($modules as $module => $delays) {
if (!empty($conf->$module->enabled)) {
@@ -276,7 +277,7 @@ if ($action == 'edit') {
// Show if meteo is enabled
print '
';
if (!empty($newlangfileonly->tab_translate[$key])) {
if ($val != $newlangfileonly->tab_translate[$key]) {
// retrieve rowid
diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
index c1735d56e50..9c7cc01630d 100644
--- a/htdocs/api/class/api_setup.class.php
+++ b/htdocs/api/class/api_setup.class.php
@@ -239,7 +239,6 @@ class Setup extends DolibarrApi
return $list;
}
-
/**
* Get the list of states/provinces.
*
@@ -252,22 +251,29 @@ class Setup extends DolibarrApi
* @param string $sortorder Sort order
* @param int $limit Number of items per page
* @param int $page Page number (starting from zero)
- * @param string $filter To filter the countries by name
+ * @param int $country To filter on country
+ * @param string $filter To filter the states by name
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
- * @return array List of countries
+ * @return array List of states
*
* @url GET dictionary/states
*
* @throws RestException
*/
- public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $sqlfilters = '')
+ public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '')
{
$list = array();
// Note: The filter is not applied in the SQL request because it must
// be applied to the translated names, not to the names in database.
- $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_departements as t";
+ $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_departements as t";
+ if ($country) {
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as d ON t.fk_region = d.code_region";
+ }
$sql .= " WHERE 1 = 1";
+ if ($country) {
+ $sql .= " AND d.fk_pays = ".((int) $country);
+ }
// Add sql filters
if ($sqlfilters) {
$errormessage = '';
@@ -1053,7 +1059,7 @@ class Setup extends DolibarrApi
* @param int $page Page number (starting from zero)
* @param string $zipcode To filter on zipcode
* @param string $town To filter on city name
- * @param int $active Payment term is active or not {@min 0} {@max 1}
+ * @param int $active Town is active or not {@min 0} {@max 1}
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return array List of towns
*
@@ -1067,7 +1073,7 @@ class Setup extends DolibarrApi
$sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country";
$sql .= " FROM ".MAIN_DB_PREFIX."c_ziptown as t";
- $sql .= " AND t.active = ".((int) $active);
+ $sql .= " WHERE t.active = ".((int) $active);
if ($zipcode) {
$sql .= " AND t.zip LIKE '%".$this->db->escape($zipcode)."%'";
}
@@ -1301,7 +1307,7 @@ class Setup extends DolibarrApi
* @param string $sortorder Sort order
* @param int $limit Number of items per page
* @param int $page Page number (starting from zero)
- * @param string $country To filter on country
+ * @param int $country To filter on country
* @param int $active Lega form is active or not {@min 0} {@max 1}
* @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
* @return array List of legal form
@@ -1310,7 +1316,7 @@ class Setup extends DolibarrApi
*
* @throws RestException
*/
- public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = '', $active = 1, $sqlfilters = '')
+ public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $active = 1, $sqlfilters = '')
{
$list = array();
@@ -1318,7 +1324,7 @@ class Setup extends DolibarrApi
$sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t";
$sql .= " WHERE t.active = ".((int) $active);
if ($country) {
- $sql .= " AND t.fk_pays = '".$this->db->escape($country)."'";
+ $sql .= " AND t.fk_pays = ".((int) $country);
}
// Add sql filters
if ($sqlfilters) {
@@ -1774,7 +1780,7 @@ class Setup extends DolibarrApi
$result = $establishment->fetch($id);
if ($result < 0) {
- throw new RestException(503, 'Error when retrieving state : '.$establishment->error);
+ throw new RestException(503, 'Error when retrieving establishment : '.$establishment->error);
} elseif ($result == 0) {
throw new RestException(404, 'Establishment not found');
}
diff --git a/htdocs/api/index.php b/htdocs/api/index.php
index 420338f2a9d..d5bc7e273e2 100644
--- a/htdocs/api/index.php
+++ b/htdocs/api/index.php
@@ -77,7 +77,6 @@ if (preg_match('/\/api\/index\.php/', $_SERVER["PHP_SELF"])) {
header('Access-Control-Allow-Headers: Content-Type, Authorization, api_key, DOLAPIKEY');
}
-
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
$res = include '../main.inc.php';
diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php
index e5ec21bfa6d..916fb376526 100644
--- a/htdocs/asset/class/asset.class.php
+++ b/htdocs/asset/class/asset.class.php
@@ -305,7 +305,7 @@ class Asset extends CommonObject
*/
public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
{
- global $db, $conf, $langs;
+ global $db, $conf, $langs, $hookmanager;
global $dolibarr_main_authentication, $dolibarr_main_demo;
global $menumanager;
@@ -360,7 +360,15 @@ class Asset extends CommonObject
}
$result .= $linkend;
//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
-
+ global $action;
+ $hookmanager->initHooks(array($this->element . 'dao'));
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
+ $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
+ if ($reshook > 0) {
+ $result = $hookmanager->resPrint;
+ } else {
+ $result .= $hookmanager->resPrint;
+ }
return $result;
}
diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php
index cbd730e5d23..f6e40b511f1 100644
--- a/htdocs/bom/bom_card.php
+++ b/htdocs/bom/bom_card.php
@@ -518,7 +518,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// Common attributes
$keyforbreak = 'duration';
include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
-
+ $object->calculateCosts();
print '
';
+}
+
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
@@ -547,6 +607,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) {
// Show here line of result
print '
';
+ $totalarray['nbfield'] = 0;
foreach ($object->fields as $key => $val) {
$cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']);
if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) {
diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
index 8bc4b54a090..a44c819aa78 100644
--- a/htdocs/langs/en_US/accountancy.lang
+++ b/htdocs/langs/en_US/accountancy.lang
@@ -62,24 +62,24 @@ MainAccountForSubscriptionPaymentNotDefined=Main accounting account for subscrip
AccountancyArea=Accounting area
AccountancyAreaDescIntro=Usage of the accountancy module is done in several step:
AccountancyAreaDescActionOnce=The following actions are usually executed one time only, or once per year...
-AccountancyAreaDescActionOnceBis=Next steps should be done to save you time in future by suggesting you the correct default accounting account when making the journalization (writing record in Journals and General ledger)
+AccountancyAreaDescActionOnceBis=Next steps should be done to save you time in future by suggesting you automaticaly the correct default accounting account when transferring data in accounting
AccountancyAreaDescActionFreq=The following actions are usually executed every month, week or day for very large companies...
-AccountancyAreaDescJournalSetup=STEP %s: Create or check content of your journal list from menu %s
+AccountancyAreaDescJournalSetup=STEP %s: Check content of your journal list from menu %s
AccountancyAreaDescChartModel=STEP %s: Check that a model of chart of account exists or create one from menu %s
AccountancyAreaDescChart=STEP %s: Select and|or complete your chart of account from menu %s
AccountancyAreaDescVat=STEP %s: Define accounting accounts for each VAT Rates. For this, use the menu entry %s.
AccountancyAreaDescDefault=STEP %s: Define default accounting accounts. For this, use the menu entry %s.
-AccountancyAreaDescExpenseReport=STEP %s: Define default accounting accounts for each type of expense report. For this, use the menu entry %s.
+AccountancyAreaDescExpenseReport=STEP %s: Define default accounting accounts for each type of Expense report. For this, use the menu entry %s.
AccountancyAreaDescSal=STEP %s: Define default accounting accounts for payment of salaries. For this, use the menu entry %s.
-AccountancyAreaDescContrib=STEP %s: Define default accounting accounts for special expenses (miscellaneous taxes). For this, use the menu entry %s.
+AccountancyAreaDescContrib=STEP %s: Define default accounting accounts for Taxes (special expenses). For this, use the menu entry %s.
AccountancyAreaDescDonation=STEP %s: Define default accounting accounts for donation. For this, use the menu entry %s.
AccountancyAreaDescSubscription=STEP %s: Define default accounting accounts for member subscription. For this, use the menu entry %s.
AccountancyAreaDescMisc=STEP %s: Define mandatory default account and default accounting accounts for miscellaneous transactions. For this, use the menu entry %s.
AccountancyAreaDescLoan=STEP %s: Define default accounting accounts for loans. For this, use the menu entry %s.
AccountancyAreaDescBank=STEP %s: Define accounting accounts and journal code for each bank and financial accounts. For this, use the menu entry %s.
-AccountancyAreaDescProd=STEP %s: Define accounting accounts on your products/services. For this, use the menu entry %s.
+AccountancyAreaDescProd=STEP %s: Define accounting accounts on your Products/Services. For this, use the menu entry %s.
AccountancyAreaDescBind=STEP %s: Check the binding between existing %s lines and accounting account is done, so application will be able to journalize transactions in Ledger in one click. Complete missing bindings. For this, use the menu entry %s.
AccountancyAreaDescWriteRecords=STEP %s: Write transactions into the Ledger. For this, go into menu %s, and click into button %s.
@@ -112,7 +112,7 @@ MenuAccountancyClosure=Closure
MenuAccountancyValidationMovements=Validate movements
ProductsBinding=Products accounts
TransferInAccounting=Transfer in accounting
-RegistrationInAccounting=Registration in accounting
+RegistrationInAccounting=Recording in accounting
Binding=Binding to accounts
CustomersVentilation=Customer invoice binding
SuppliersVentilation=Vendor invoice binding
@@ -120,7 +120,7 @@ ExpenseReportsVentilation=Expense report binding
CreateMvts=Create new transaction
UpdateMvts=Modification of a transaction
ValidTransaction=Validate transaction
-WriteBookKeeping=Register transactions in accounting
+WriteBookKeeping=Record transactions in accounting
Bookkeeping=Ledger
BookkeepingSubAccount=Subledger
AccountBalance=Account balance
@@ -294,7 +294,7 @@ Balancing=Balancing
FicheVentilation=Binding card
GeneralLedgerIsWritten=Transactions are written in the Ledger
GeneralLedgerSomeRecordWasNotRecorded=Some of the transactions could not be journalized. If there is no other error message, this is probably because they were already journalized.
-NoNewRecordSaved=No more record to journalize
+NoNewRecordSaved=No more record to transfer
ListOfProductsWithoutAccountingAccount=List of products not bound to any accounting account
ChangeBinding=Change the binding
Accounted=Accounted in ledger
diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
index 74cda5437e1..426e1186868 100644
--- a/htdocs/langs/en_US/admin.lang
+++ b/htdocs/langs/en_US/admin.lang
@@ -1187,7 +1187,7 @@ BankModuleNotActive=Bank accounts module not enabled
ShowBugTrackLink=Show the link "%s"
ShowBugTrackLinkDesc=Keep empty to not display this link, use value 'github' for the link to the Dolibarr project or define directly an url 'https://...'
Alerts=Alerts
-DelaysOfToleranceBeforeWarning=Delay before displaying a warning alert for:
+DelaysOfToleranceBeforeWarning=Displaying a warning alert for...
DelaysOfToleranceDesc=Set the delay before an alert icon %s is shown onscreen for the late element.
Delays_MAIN_DELAY_ACTIONS_TODO=Planned events (agenda events) not completed
Delays_MAIN_DELAY_PROJECT_TO_CLOSE=Project not closed in time
@@ -2220,4 +2220,7 @@ NoDeployedModulesFoundWithThisSearchCriteria=No modules found for these search c
API_DISABLE_COMPRESSION=Disable compression of API responses
EachTerminalHasItsOwnCounter=Each terminal use its own counter.
FillAndSaveAccountIdAndSecret=Fill and save account ID and secret first
-PreviousHash=Previous hash
\ No newline at end of file
+PreviousHash=Previous hash
+LateWarningAfter="Late" warning after
+TemplateforBusinessCards=Template for a business card in different size
+InventorySetup= Inventory Setup
diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang
index 710d49bfab6..2ace1eb97e1 100644
--- a/htdocs/langs/en_US/boxes.lang
+++ b/htdocs/langs/en_US/boxes.lang
@@ -23,7 +23,7 @@ BoxLastMembersSubscriptions=Latest member subscriptions
BoxFicheInter=Latest interventions
BoxCurrentAccounts=Open accounts balance
BoxTitleMemberNextBirthdays=Birthdays of this month (members)
-BoxTitleMembersByType=Members by type
+BoxTitleMembersByType=Members by type and status
BoxTitleMembersSubscriptionsByYear=Members Subscriptions by year
BoxTitleLastRssInfos=Latest %s news from %s
BoxTitleLastProducts=Products/Services: last %s modified
diff --git a/htdocs/langs/en_US/hrm.lang b/htdocs/langs/en_US/hrm.lang
index c571ec6ca8a..ab3628026c5 100644
--- a/htdocs/langs/en_US/hrm.lang
+++ b/htdocs/langs/en_US/hrm.lang
@@ -79,3 +79,6 @@ NoEval=No evaluation done for this employee
HowManyUserWithThisMaxNote=Number of users with this rank
HighestRank=Highest rank
SkillComparison=Skill comparison
+ActionsOnJob=Events on this job
+VacantPosition=job vacancy
+VacantCheckboxHelper=Checking this option will show unfilled positions (job vacancy)
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index 2d850927782..2867c7b853b 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -517,6 +517,7 @@ or=or
Other=Other
Others=Others
OtherInformations=Other information
+Workflow=Workflow
Quantity=Quantity
Qty=Qty
ChangedBy=Changed by
diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang
index 9605e7a8df7..8646c40b98f 100644
--- a/htdocs/langs/en_US/members.lang
+++ b/htdocs/langs/en_US/members.lang
@@ -159,7 +159,7 @@ HTPasswordExport=htpassword file generation
NoThirdPartyAssociatedToMember=No third party associated with this member
MembersAndSubscriptions=Members and Contributions
MoreActions=Complementary action on recording
-MoreActionsOnSubscription=Complementary action, suggested by default when recording a contribution
+MoreActionsOnSubscription=Complementary action suggested by default when recording a contribution, also done automatially on online payment of a contribution
MoreActionBankDirect=Create a direct entry on bank account
MoreActionBankViaInvoice=Create an invoice, and a payment on bank account
MoreActionInvoiceOnly=Create an invoice with no payment
diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang
index 74bed0d9186..4dc74122ea9 100644
--- a/htdocs/langs/en_US/mrp.lang
+++ b/htdocs/langs/en_US/mrp.lang
@@ -107,3 +107,6 @@ THMEstimatedHelp=This rate makes it possible to define a forecast cost of the it
BOM=Bill Of Materials
CollapseBOMHelp=You can define the default display of the details of the nomenclature in the configuration of the BOM module
MOAndLines=Manufacturing Orders and lines
+BOMNetNeeds=Net Needs
+TreeStructure=Tree structure
+GroupByProduct=Group by product
\ No newline at end of file
diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang
index dd1e0ea4027..4bd64f44577 100644
--- a/htdocs/langs/en_US/productbatch.lang
+++ b/htdocs/langs/en_US/productbatch.lang
@@ -42,4 +42,5 @@ HideLots=Hide lots
#Traceability - qc status
OutOfOrder=Out of order
InWorkingOrder=In working order
-ToReplace=Replace
\ No newline at end of file
+ToReplace=Replace
+CantMoveNonExistantSerial=Error. You ask a move on a record for a serial that does not exists anymore. May be you take the same serial on same warehouse several times in same shipment or it was used by another shipment. Remove this shipment and prepare another one.
diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
index c28addf0e76..10f75a1ea52 100644
--- a/htdocs/langs/en_US/products.lang
+++ b/htdocs/langs/en_US/products.lang
@@ -415,4 +415,5 @@ ProductsMergeSuccess=Products have been merged
ErrorsProductsMerge=Errors in products merge
SwitchOnSaleStatus=Switch on sale status
SwitchOnPurchaseStatus=Switch on purchase status
-StockMouvementExtraFields=Extra Fields (stock mouvement)
+StockMouvementExtraFields= Extra Fields (stock mouvement)
+InventoryExtraFields= Extra Fields (inventory)
diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang
index d38358eb74d..9dfc4874cc5 100644
--- a/htdocs/langs/en_US/ticket.lang
+++ b/htdocs/langs/en_US/ticket.lang
@@ -136,6 +136,13 @@ TicketsPublicNotificationNewMessage=Send email(s) when a new message/comment is
TicketsPublicNotificationNewMessageHelp=Send email(s) when a new message is added from public interface (to assigned user or the notifications email to (update) and/or the notifications email to)
TicketPublicNotificationNewMessageDefaultEmail=Notifications email to (update)
TicketPublicNotificationNewMessageDefaultEmailHelp=Send an email to this address for each new message notifications if the ticket doesn't have a user assigned to it or if the user doesn't have any known email.
+TicketsAutoReadTicket=Automatically mark the ticket as read (when created from backoffice)
+TicketsAutoReadTicketHelp=Automatically mark the ticket as read when created from backoffice. When ticket is create from the public interface, ticket remains with the status "Not Read".
+TicketsDelayBeforeFirstAnswer=A new ticket should receive a first answer before (hours):
+TicketsDelayBeforeFirstAnswerHelp=If a new ticket has not received an answer after this time period (in hours), an important warning icon will be displayed in the list view.
+TicketsDelayBetweenAnswers=An unresolved ticket should not be unactive during (hours):
+TicketsDelayBetweenAnswersHelp=If an unresolved ticket that has already received an answer has not had further interaction after this time period (in hours), a warning icon will be displayed in the list view.
+
#
# Index & list page
#
@@ -241,6 +248,8 @@ TicketNotNotifyTiersAtCreate=Not notify company at create
Unread=Unread
TicketNotCreatedFromPublicInterface=Not available. Ticket was not created from public interface.
ErrorTicketRefRequired=Ticket reference name is required
+TicketsDelayForFirstResponseTooLong=Too much time elapsed since ticket opening without any answer.
+TicketsDelayFromLastResponseTooLong=Too much time elapsed since last answer on this ticket.
#
# Logs
diff --git a/htdocs/langs/fr_FR/hrm.lang b/htdocs/langs/fr_FR/hrm.lang
index d47596fe95e..dca9ca4deb6 100644
--- a/htdocs/langs/fr_FR/hrm.lang
+++ b/htdocs/langs/fr_FR/hrm.lang
@@ -79,3 +79,6 @@ NoEval=Aucune évaluation effectuée pour cet employé
HowManyUserWithThisMaxNote=Nombre d'employés avec ce niveau
HighestRank=Plus haut niveau
SkillComparison=Comparaison des compétences
+ActionsOnJob=Événements sur cet emploi
+VacantPosition=Poste vacant
+VacantCheckboxHelper=Cocher cette option affichera le(s) poste(s) comme non pourvu(s)
diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang
index 63c5192a01f..12778f337dd 100644
--- a/htdocs/langs/fr_FR/main.lang
+++ b/htdocs/langs/fr_FR/main.lang
@@ -517,6 +517,7 @@ or=ou
Other=Autre
Others=Autres
OtherInformations=Autre information
+Workflow=Processus de travail
Quantity=Quantité
Qty=Qté
ChangedBy=Modifié par
diff --git a/htdocs/langs/fr_FR/productbatch.lang b/htdocs/langs/fr_FR/productbatch.lang
index e1883f5bba0..68b5e928084 100644
--- a/htdocs/langs/fr_FR/productbatch.lang
+++ b/htdocs/langs/fr_FR/productbatch.lang
@@ -43,3 +43,4 @@ HideLots=Masquer les lots
OutOfOrder=Hors d'usage
InWorkingOrder=En état de marche
ToReplace=Remplacer
+CantMoveNonExistantSerial=Erreur : Vous avez demandé un mouvement sur un numéro de série qui n’existe plus. Peut-être avez-vous requis le même numéro de série plusieurs fois dans une même expédition, ou il a déjà servi dans une autre expédition. Supprimez cette expédition et préparez-en une autre.
diff --git a/htdocs/langs/fr_FR/ticket.lang b/htdocs/langs/fr_FR/ticket.lang
index 91850194533..bc51a7627fd 100644
--- a/htdocs/langs/fr_FR/ticket.lang
+++ b/htdocs/langs/fr_FR/ticket.lang
@@ -136,6 +136,9 @@ TicketsPublicNotificationNewMessage=Envoyer un ou des emails lorsqu’un nouveau
TicketsPublicNotificationNewMessageHelp=Envoyer un (des) courriel(s) lorsqu’un nouveau message est ajouté à partir de l’interface publique (à l’utilisateur désigné ou au courriel de notification (mise à jour) et/ou au courriel de notification)
TicketPublicNotificationNewMessageDefaultEmail=Emails de notifications à (mise à jour)
TicketPublicNotificationNewMessageDefaultEmailHelp=Envoyez un email à cette adresse email pour chaque nouveau message de notifications si le ticket n'a pas d'utilisateur assigné ou si l'utilisateur n'a pas d'email connu.
+TicketsAutoReadTicket=Automatiquement marquer le ticket comme lu
+TicketsAutoReadTicketHelp=Automatiquement marquer le ticket comme lu s'il est créé depuis le backoffice.
+
#
# Index & list page
#
diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php
index 88701e35166..4bc539c1ff0 100644
--- a/htdocs/loan/card.php
+++ b/htdocs/loan/card.php
@@ -618,6 +618,11 @@ if ($id > 0) {
}
print '
';
+ // Other attributes
+ $parameters = array();
+ $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
+ print $hookmanager->resPrint;
+
print '';
print '
';
diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php
index ec9ce00b7e9..7edaefb45b2 100644
--- a/htdocs/loan/class/loan.class.php
+++ b/htdocs/loan/class/loan.class.php
@@ -556,7 +556,7 @@ class Loan extends CommonObject
*/
public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
{
- global $conf, $langs;
+ global $conf, $langs, $hookmanager;
$result = '';
@@ -606,6 +606,15 @@ class Loan extends CommonObject
}
$result .= $linkend;
+ global $action;
+ $hookmanager->initHooks(array($this->element . 'dao'));
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
+ $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
+ if ($reshook > 0) {
+ $result = $hookmanager->resPrint;
+ } else {
+ $result .= $hookmanager->resPrint;
+ }
return $result;
}
diff --git a/htdocs/loan/class/paymentloan.class.php b/htdocs/loan/class/paymentloan.class.php
index 841ffa7b373..ae31a8314aa 100644
--- a/htdocs/loan/class/paymentloan.class.php
+++ b/htdocs/loan/class/paymentloan.class.php
@@ -617,7 +617,7 @@ class PaymentLoan extends CommonObject
*/
public function getNomUrl($withpicto = 0, $maxlen = 0, $notooltip = 0, $moretitle = '', $save_lastsearch_value = -1)
{
- global $langs, $conf;
+ global $langs, $conf, $hookmanager;
if (!empty($conf->dol_no_mouse_hover)) {
$notooltip = 1; // Force disable tooltips
@@ -654,6 +654,15 @@ class PaymentLoan extends CommonObject
}
$result .= $linkend;
+ global $action;
+ $hookmanager->initHooks(array($this->element . 'dao'));
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
+ $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
+ if ($reshook > 0) {
+ $result = $hookmanager->resPrint;
+ } else {
+ $result .= $hookmanager->resPrint;
+ }
return $result;
}
}
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 8dd5c45642f..093813f5776 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -282,7 +282,7 @@ if (!empty($php_session_save_handler) && $php_session_save_handler == 'db') {
// Init session. Name of session is specific to Dolibarr instance.
// Must be done after the include of filefunc.inc.php so global variables of conf file are defined (like $dolibarr_main_instance_unique_id or $dolibarr_main_force_https).
-// Note: the function dol_getprefix is defined into functions.lib.php but may have been defined to return a different key to manage another area to protect.
+// Note: the function dol_getprefix() is defined into functions.lib.php but may have been defined to return a different key to manage another area to protect.
$prefix = dol_getprefix('');
$sessionname = 'DOLSESSID_'.$prefix;
$sessiontimeout = 'DOLSESSTIMEOUT_'.$prefix;
@@ -290,7 +290,6 @@ if (!empty($_COOKIE[$sessiontimeout])) {
ini_set('session.gc_maxlifetime', $_COOKIE[$sessiontimeout]);
}
-
// This create lock, released by session_write_close() or end of page.
// We need this lock as long as we read/write $_SESSION ['vars']. We can remove lock when finished.
if (!defined('NOSESSION')) {
@@ -510,6 +509,7 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && getDolGlobalInt(
print $langs->trans("ErrorGoBackAndCorrectParameters");
die;
} else {
+ http_response_code(403);
if (defined('CSRFCHECK_WITH_TOKEN')) {
dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (CSRFCHECK_WITH_TOKEN protection) in main.inc.php. Token not provided.", LOG_WARNING);
print "Access to a page that needs a token (constant CSRFCHECK_WITH_TOKEN is defined) is refused by CSRF protection in main.inc.php. Token not provided.\n";
@@ -3233,6 +3233,7 @@ if (!function_exists("llxFooter")) {
id:id; ?>
, element:'element ?>'
, action:'DOC_PREVIEW'
+ , token: ''
}
);
});
@@ -3242,6 +3243,7 @@ if (!function_exists("llxFooter")) {
id:id; ?>
, element:'element ?>'
, action:'DOC_DOWNLOAD'
+ , token: ''
}
);
});
@@ -3260,7 +3262,7 @@ if (!function_exists("llxFooter")) {
$forceping = GETPOST('forceping', 'alpha');
if (($_SERVER["PHP_SELF"] == DOL_URL_ROOT.'/index.php') || $forceping) {
//print '';
- $hash_unique_id = md5('dolibarr'.$conf->file->instance_unique_id);
+ $hash_unique_id = md5('dolibarr'.$conf->file->instance_unique_id); // Do not use dol_hash(), must not change if salt changes.
if (empty($conf->global->MAIN_FIRST_PING_OK_DATE)
|| (!empty($conf->file->instance_unique_id) && ($hash_unique_id != $conf->global->MAIN_FIRST_PING_OK_ID) && ($conf->global->MAIN_FIRST_PING_OK_ID != 'disabled'))
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index 4e66e655f5e..60f23cbee1a 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -46,6 +46,9 @@ $action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
+$sortfield=GETPOST('sortfield', 'alpha');
+$sortorder=GETPOST('sortorder', 'alpha');
+
$module = GETPOST('module', 'alpha');
$tab = GETPOST('tab', 'aZ09');
$tabobj = GETPOST('tabobj', 'alpha');
@@ -2296,7 +2299,7 @@ if ($module == 'initmodule') {
print_liste_field_titre("Condition", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder);
print "\n";
- if (is_array($dicts) && is_array($dicts['tabname'])) {
+ if (!empty($dicts) && is_array($dicts) && !empty($dicts['tabname']) && is_array($dicts['tabname'])) {
$i = 0;
$maxi = count($dicts['tabname']);
while ($i < $maxi) {
@@ -2778,25 +2781,25 @@ if ($module == 'initmodule') {
$propname = $propkey;
$proplabel = $propval['label'];
$proptype = $propval['type'];
- $proparrayofkeyval = $propval['arrayofkeyval'];
+ $proparrayofkeyval = !empty($propval['arrayofkeyval'])?$propval['arrayofkeyval']:'';
$propnotnull = $propval['notnull'];
- $propdefault = $propval['default'];
- $propindex = $propval['index'];
- $propforeignkey = $propval['foreignkey'];
+ $propdefault = !empty($propval['default'])?$propval['default']:'';
+ $propindex = !empty($propval['index'])?$propval['index']:'';
+ $propforeignkey = !empty($propval['foreignkey'])?$propval['foreignkey']:'';
$propposition = $propval['position'];
$propenabled = $propval['enabled'];
$propvisible = $propval['visible'];
- $propnoteditable = $propval['noteditable'];
- $propsearchall = $propval['searchall'];
- $propisameasure = $propval['isameasure'];
- $propcss = $propval['css'];
- $propcssview = $propval['cssview'];
- $propcsslist = $propval['csslist'];
- $prophelp = $propval['help'];
- $propshowoncombobox = $propval['showoncombobox'];
+ $propnoteditable = !empty($propval['noteditable'])?$propval['noteditable']:0;
+ $propsearchall = !empty($propval['searchall'])?$propval['searchall']:0;
+ $propisameasure = !empty($propval['isameasure'])?$propval['isameasure']:0;
+ $propcss = !empty($propval['css'])?$propval['css']:'';
+ $propcssview = !empty($propval['cssview'])?$propval['cssview']:'';
+ $propcsslist = !empty($propval['csslist'])?$propval['csslist']:'';
+ $prophelp = !empty($propval['help'])?$propval['help']:'';
+ $propshowoncombobox = !empty($propval['showoncombobox'])?$propval['showoncombobox']:0;
//$propdisabled=$propval['disabled'];
- $propvalidate = $propval['validate'];
- $propcomment = $propval['comment'];
+ $propvalidate = !empty($propval['validate'])?$propval['validate']:0;
+ $propcomment = !empty($propval['comment'])?$propval['comment']:'';
print '
';
diff --git a/htdocs/modulebuilder/template/README.md b/htdocs/modulebuilder/template/README.md
index 45c5e4b51eb..03cf25d74f4 100644
--- a/htdocs/modulebuilder/template/README.md
+++ b/htdocs/modulebuilder/template/README.md
@@ -28,10 +28,10 @@ There is a [Transifex project](https://transifex.com/projects/p/dolibarr-module-
### From the ZIP file and GUI interface
-- If you get the module in a zip file (like when downloading it from the market place [Dolistore](https://www.dolistore.com)), go into
-menu ```Home - Setup - Modules - Deploy external module``` and upload the zip file.
+If the module is a ready to deploy zip file, so with a name module_xxx-version.zip (like when downloading it from a market place like [Dolistore](https://www.dolistore.com)),
+go into menu ```Home - Setup - Modules - Deploy external module``` and upload the zip file.
-Note: If this screen tell you there is no custom directory, check your setup is correct:
+Note: If this screen tell you that there is no "custom" directory, check that your setup is correct:
- In your Dolibarr installation directory, edit the ```htdocs/conf/conf.php``` file and check that following lines are not commented:
@@ -58,7 +58,7 @@ Note: If this screen tell you there is no custom directory, check your setup is
### From a GIT repository
-- Clone the repository in ```$dolibarr_main_document_root_alt/mymodule```
+Clone the repository in ```$dolibarr_main_document_root_alt/mymodule```
```sh
cd ....../custom
diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
index ca9de1cc5ab..ac934439934 100644
--- a/htdocs/modulebuilder/template/class/myobject.class.php
+++ b/htdocs/modulebuilder/template/class/myobject.class.php
@@ -836,7 +836,7 @@ class MyObject extends CommonObject
global $action, $hookmanager;
$hookmanager->initHooks(array('myobjectdao'));
- $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php
index 8040c13d606..689503f0dee 100644
--- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php
+++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php
@@ -159,7 +159,7 @@ class doc_generic_myobject_odt extends ModelePDFMyObject
$texte .= $conf->global->MYMODULE_MYOBJECT_ADDON_PDF_ODT_PATH;
$texte .= '';
$texte .= '
';
- $texte .= '';
+ $texte .= '';
$texte .= '
';
// Scan directories
diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php
index f1ca7ce2747..531d463eea1 100644
--- a/htdocs/modulebuilder/template/myobject_card.php
+++ b/htdocs/modulebuilder/template/myobject_card.php
@@ -42,6 +42,7 @@
//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies
//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification
+//if (! defined('NOSESSION')) define('NOSESSION', '1'); // Disable session
// Load Dolibarr environment
$res = 0;
diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php
index 29db4bcb669..2da1672e089 100644
--- a/htdocs/mrp/class/mo.class.php
+++ b/htdocs/mrp/class/mo.class.php
@@ -1072,7 +1072,7 @@ class Mo extends CommonObject
global $action, $hookmanager;
$hookmanager->initHooks(array('modao'));
- $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
diff --git a/htdocs/opensurvey/card.php b/htdocs/opensurvey/card.php
index 773571b7b1c..3f822679350 100644
--- a/htdocs/opensurvey/card.php
+++ b/htdocs/opensurvey/card.php
@@ -54,6 +54,9 @@ if ($result <= 0) {
exit;
}
+// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
+$hookmanager->initHooks(array('surveycard', 'globalcard'));
+
$expiredate = dol_mktime(0, 0, 0, GETPOST('expiremonth'), GETPOST('expireday'), GETPOST('expireyear'));
@@ -338,6 +341,11 @@ if ($action != 'edit') {
print '
';
+// Other attributes
+$parameters = array();
+$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
+print $hookmanager->resPrint;
+
print '';
print '
';
diff --git a/htdocs/partnership/class/partnership.class.php b/htdocs/partnership/class/partnership.class.php
index 39cf2da2b2f..b938b3b250f 100644
--- a/htdocs/partnership/class/partnership.class.php
+++ b/htdocs/partnership/class/partnership.class.php
@@ -1045,7 +1045,7 @@ class Partnership extends CommonObject
global $action, $hookmanager;
$hookmanager->initHooks(array('partnershipdao'));
- $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
diff --git a/htdocs/partnership/class/partnership_type.class.php b/htdocs/partnership/class/partnership_type.class.php
index 6916d95e4f3..5b6ed5e5378 100644
--- a/htdocs/partnership/class/partnership_type.class.php
+++ b/htdocs/partnership/class/partnership_type.class.php
@@ -434,7 +434,7 @@ class PartnershipType extends CommonObject
global $action, $hookmanager;
$hookmanager->initHooks(array('myobjectdao'));
- $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
diff --git a/htdocs/product/admin/inventory_extrafields.php b/htdocs/product/admin/inventory_extrafields.php
new file mode 100644
index 00000000000..d21328da336
--- /dev/null
+++ b/htdocs/product/admin/inventory_extrafields.php
@@ -0,0 +1,123 @@
+
+ * Copyright (C) 2003 Jean-Louis Bergamo
+ * Copyright (C) 2004-2011 Laurent Destailleur
+ * Copyright (C) 2012 Regis Houssin
+ * Copyright (C) 2014 Florian Henry
+ * Copyright (C) 2015 Jean-François Ferry
+ *
+ * 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 .
+ */
+
+/**
+ * \file htdocs/product/admin/inventory_extrafields.php
+ * \ingroup stock
+ * \brief Page to setup extra fields of inventory
+ */
+
+// Load Dolibarr environment
+$res = 0;
+// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
+if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
+// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
+$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
+while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; }
+if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
+if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
+// Try main.inc.php using relative path
+if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
+if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
+if (!$res) die("Include of main fails");
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/stock.lib.php';
+
+// Load translation files required by the page
+$langs->loadLangs(array('stock@stock', 'admin'));
+
+$extrafields = new ExtraFields($db);
+$form = new Form($db);
+
+// List of supported format
+$tmptype2label = ExtraFields::$type2label;
+$type2label = array('');
+foreach ($tmptype2label as $key => $val) $type2label[$key] = $langs->transnoentitiesnoconv($val);
+
+$action = GETPOST('action', 'aZ09');
+$attrname = GETPOST('attrname', 'alpha');
+$elementtype = 'inventory'; //Must be the $table_element of the class that manage extrafield
+
+if (!$user->admin) accessforbidden();
+
+
+/*
+ * Actions
+ */
+
+require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php';
+
+
+
+/*
+ * View
+ */
+
+
+llxHeader('', $langs->trans("InventorySetup"), $help_url);
+
+
+$linkback = ''.$langs->trans("BackToModuleList").'';
+print load_fiche_titre($langs->trans("InventorySetup"), $linkback, 'title_setup');
+
+
+$head = stock_admin_prepare_head();
+
+print dol_get_fiche_head($head, 'inventoryAttributes', $langs->trans("InventoryExtraFields"), -1, 'account');
+
+require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php';
+
+print dol_get_fiche_end();
+
+
+// Buttons
+if ($action != 'create' && $action != 'edit') {
+ print '
";
+}
+
+
+/*
+ * Creation of an optional field
+ */
+if ($action == 'create') {
+ print ' ';
+ print load_fiche_titre($langs->trans('NewAttribute'));
+
+ require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
+}
+
+/*
+ * Edition of an optional field
+ */
+if ($action == 'edit' && !empty($attrname)) {
+ print " ";
+ print load_fiche_titre($langs->trans("FieldEdition", $attrname));
+
+ require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
+}
+
+// End of page
+llxFooter();
+$db->close();
diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php
index 32c4c83378c..74fa53dccb8 100644
--- a/htdocs/product/ajax/products.php
+++ b/htdocs/product/ajax/products.php
@@ -51,7 +51,8 @@ $htmlname = GETPOST('htmlname', 'aZ09');
$socid = GETPOST('socid', 'int');
$type = GETPOST('type', 'int');
$mode = GETPOST('mode', 'int');
-$status = ((GETPOST('status', 'int') >= 0) ? GETPOST('status', 'int') : - 1);
+$status = ((GETPOST('status', 'int') >= 0) ? GETPOST('status', 'int') : - 1); // status buy when mode = customer , status purchase when mode = supplier
+$status_purchase = ((GETPOST('status_purchase', 'int') >= 0) ? GETPOST('status_purchase', 'int') : - 1); // status purchase when mode = customer
$outjson = (GETPOST('outjson', 'int') ? GETPOST('outjson', 'int') : 0);
$price_level = GETPOST('price_level', 'int');
$action = GETPOST('action', 'aZ09');
@@ -260,7 +261,7 @@ if ($action == 'fetch' && !empty($id)) {
}
if (empty($mode) || $mode == 1) { // mode=1: customer
- $arrayresult = $form->select_produits_list("", $htmlname, $type, 0, $price_level, $searchkey, $status, $finished, $outjson, $socid, '1', 0, '', $hidepriceinlabel, $warehouseStatus);
+ $arrayresult = $form->select_produits_list("", $htmlname, $type, 0, $price_level, $searchkey, $status, $finished, $outjson, $socid, '1', 0, '', $hidepriceinlabel, $warehouseStatus, $status_purchase);
} elseif ($mode == 2) { // mode=2: supplier
$arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson, 0, $alsoproductwithnosupplierprice);
}
diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php
index bac6c958d24..4ede9e1e297 100644
--- a/htdocs/product/class/html.formproduct.class.php
+++ b/htdocs/product/class/html.formproduct.class.php
@@ -202,7 +202,7 @@ class FormProduct
/**
* Return list of warehouses
*
- * @param string|int $selected Id of preselected warehouse ('' or '-1' for no value, 'ifone'=select value if one value otherwise no value, '-2' to use the default value from setup)
+ * @param string|int $selected Id of preselected warehouse ('' or '-1' for no value, 'ifone' and 'ifonenodefault' = select value if one value otherwise no value, '-2' to use the default value from setup)
* @param string $htmlname Name of html select html
* @param string $filterstatus warehouse status filter, following comma separated filter options can be used
* 'warehouseopen' = select products from open warehouses,
@@ -279,7 +279,7 @@ class FormProduct
}
$out .= '
';
diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php
index 8423ebdea6f..155c525de8c 100644
--- a/htdocs/product/stock/class/entrepot.class.php
+++ b/htdocs/product/stock/class/entrepot.class.php
@@ -760,7 +760,7 @@ class Entrepot extends CommonObject
global $action;
$hookmanager->initHooks(array('warehousedao'));
- $parameters = array('id'=>$this->id, 'getnomurl'=>$result, 'withpicto' => $withpicto, 'option' => $option, 'showfullpath' => $showfullpath, 'notooltip'=> $notooltip);
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result, 'withpicto' => $withpicto, 'option' => $option, 'showfullpath' => $showfullpath, 'notooltip'=> $notooltip);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
index b53d67f1bd2..67119ff6839 100644
--- a/htdocs/product/stock/class/mouvementstock.class.php
+++ b/htdocs/product/stock/class/mouvementstock.class.php
@@ -851,7 +851,9 @@ class MouvementStock extends CommonObject
*/
private function createBatch($dluo, $qty)
{
- global $user;
+ global $user, $langs;
+
+ $langs->load('productbatch');
$pdluo = new Productbatch($this->db);
@@ -862,7 +864,7 @@ class MouvementStock extends CommonObject
$result = $pdluo->fetch($dluo);
if (empty($pdluo->id)) {
// We didn't find the line. May be it was deleted before by a previous move in same transaction.
- $this->error = 'Error. You ask a move on a record for a serial that does not exists anymore. May be you take the same serial on same warehouse several times in same shipment or it was used by another shipment. Remove this shipment and prepare another one.';
+ $this->error = $langs->trans('CantMoveNonExistantSerial');
$this->errors[] = $this->error;
$result = -2;
}
diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php
index ffcf5dd2f00..340fd7dc0df 100644
--- a/htdocs/product/stock/stockatdate.php
+++ b/htdocs/product/stock/stockatdate.php
@@ -363,7 +363,7 @@ print $form->select_produits($productid, 'productid', '', 0, 0, -1, 2, '', 0, ar
print ' ';
print img_picto('', 'stock', 'class="pictofiwedwidth"');
print ' ';
-print $formproduct->selectWarehouses((GETPOSTISSET('fk_warehouse') ? $fk_warehouse : 'ifone'), 'fk_warehouse', '', 1, 0, 0, $langs->trans('Warehouse'), 0, 0, null, '', null, 1, false, 'e.ref');
+print $formproduct->selectWarehouses((GETPOSTISSET('fk_warehouse') ? $fk_warehouse : 'ifonenodefault'), 'fk_warehouse', '', 1, 0, 0, $langs->trans('Warehouse'), 0, 0, null, '', null, 1, false, 'e.ref');
print '
';
-}
-*/
print dol_get_fiche_end();
diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
index f531d221aff..8aa25154111 100644
--- a/htdocs/projet/class/project.class.php
+++ b/htdocs/projet/class/project.class.php
@@ -1264,7 +1264,7 @@ class Project extends CommonObject
global $action;
$hookmanager->initHooks(array('projectdao'));
- $parameters = array('id'=>$this->id, 'getnomurl'=>$result);
+ $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
diff --git a/htdocs/public/eventorganization/attendee_new.php b/htdocs/public/eventorganization/attendee_new.php
index b350ece39f4..a7cdd1ceda8 100644
--- a/htdocs/public/eventorganization/attendee_new.php
+++ b/htdocs/public/eventorganization/attendee_new.php
@@ -19,16 +19,6 @@
* \file htdocs/public/eventorganization/attendee_new.php
* \ingroup project
* \brief Example of form to subscribe to an event
- *
- * Note that you can add following constant to change behaviour of page
- * MEMBER_NEWFORM_AMOUNT Default amount for auto-subscribe form
- * MEMBER_NEWFORM_EDITAMOUNT 0 or 1 = Amount can be edited
- * MEMBER_NEWFORM_PAYONLINE Suggest payment with paypal, paybox or stripe
- * MEMBER_NEWFORM_DOLIBARRTURNOVER Show field turnover (specific for dolibarr foundation)
- * MEMBER_URL_REDIRECT_SUBSCRIPTION Url to redirect once subscribe submitted
- * MEMBER_NEWFORM_FORCETYPE Force type of member
- * MEMBER_NEWFORM_FORCEMORPHY Force nature of member (mor/phy)
- * MEMBER_NEWFORM_FORCECOUNTRYCODE Force country
*/
if (!defined('NOLOGIN')) {
@@ -66,7 +56,6 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
-global $dolibarr_main_instance_unique_id;
global $dolibarr_main_url_root;
// Init vars
diff --git a/htdocs/public/eventorganization/subscriptionok.php b/htdocs/public/eventorganization/subscriptionok.php
index 4a81084223d..8acf3daba78 100644
--- a/htdocs/public/eventorganization/subscriptionok.php
+++ b/htdocs/public/eventorganization/subscriptionok.php
@@ -57,7 +57,7 @@ if (!empty($conf->paypal->enabled)) {
require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php';
}
-global $dolibarr_main_instance_unique_id, $dolibarr_main_url_root, $mysoc;
+global $dolibarr_main_url_root, $mysoc;
$langs->loadLangs(array("main", "companies", "install", "other", "eventorganization"));
diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php
index 6589f2a17d0..055ffec56f9 100644
--- a/htdocs/public/members/new.php
+++ b/htdocs/public/members/new.php
@@ -30,6 +30,7 @@
* Note that you can add following constant to change behaviour of page
* MEMBER_NEWFORM_AMOUNT Default amount for auto-subscribe form
* MEMBER_NEWFORM_EDITAMOUNT 0 or 1 = Amount can be edited
+ * MEMBER_MIN_AMOUNT Minimum amount
* MEMBER_NEWFORM_PAYONLINE Suggest payment with paypal, paybox or stripe
* MEMBER_NEWFORM_DOLIBARRTURNOVER Show field turnover (specific for dolibarr foundation)
* MEMBER_URL_REDIRECT_SUBSCRIPTION Url to redirect once subscribe submitted
diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php
index 5158e294fb2..7bb61a708c5 100644
--- a/htdocs/public/payment/newpayment.php
+++ b/htdocs/public/payment/newpayment.php
@@ -70,9 +70,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
$hookmanager = new HookManager($db);
$hookmanager->initHooks(array('newpayment'));
-// For encryption
-global $dolibarr_main_instance_unique_id;
-
// Load translation files
$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "paybox", "paypal", "stripe")); // File with generic data
@@ -481,7 +478,7 @@ if ($action == 'dopayment') {
// Called when choosing Stripe mode.
-// When using the Charge API architecture, this code is called after clicking the 'dopayment' with the Charge API architecture.
+// When using the old Charge API architecture, this code is called after clicking the 'dopayment' with the Charge API architecture.
// When using the PaymentIntent API architecture, the Stripe customer was already created when creating PaymentIntent when showing payment page, and the payment is already ok when action=charge.
if ($action == 'charge' && !empty($conf->stripe->enabled)) {
$amountstripe = $amount;
@@ -728,7 +725,7 @@ if ($action == 'charge' && !empty($conf->stripe->enabled)) {
}
}
- // When using the PaymentIntent API architecture
+ // When using the PaymentIntent API architecture (mode set on by default into conf.class.php)
if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) {
$service = 'StripeTest';
$servicestatus = 0;
@@ -793,8 +790,8 @@ if ($action == 'charge' && !empty($conf->stripe->enabled)) {
$remoteip = getUserRemoteIP();
$_SESSION["onlinetoken"] = $stripeToken;
- $_SESSION["FinalPaymentAmt"] = $amount;
- $_SESSION["currencyCodeType"] = $currency;
+ $_SESSION["FinalPaymentAmt"] = $amount; // amount really paid (coming from Stripe). Will be used for check in paymentok.php.
+ $_SESSION["currencyCodeType"] = $currency; // currency really used for payment (coming from Stripe). Will be used for check in paymentok.php.
$_SESSION["paymentType"] = '';
$_SESSION['ipaddress'] = ($remoteip ? $remoteip : 'unknown'); // Payer ip
$_SESSION['payerID'] = is_object($customer) ? $customer->id : '';
diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php
index c822bfcdf96..9765af89f7e 100644
--- a/htdocs/public/payment/paymentok.php
+++ b/htdocs/public/payment/paymentok.php
@@ -61,8 +61,6 @@ if (!empty($conf->paypal->enabled)) {
require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php';
}
-global $dolibarr_main_instance_unique_id;
-
$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal"));
// Clean parameters
@@ -412,12 +410,12 @@ if ($ispaymentok) {
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
- dol_syslog("FinalPaymentAmt=".$FinalPaymentAmt." paymentTypeId=".$paymentTypeId." currencyCodeType=".$currencyCodeType, LOG_DEBUG, 0, '_payment');
+ dol_syslog("FinalPaymentAmt=".$FinalPaymentAmt." paymentTypeId=".$paymentTypeId." paymentType=".$paymentType." currencyCodeType=".$currencyCodeType, LOG_DEBUG, 0, '_payment');
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) {
// Security protection:
- if (empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT)) { // If we didn't allow members to choose their membership amount
+ if (empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT)) { // If we didn't allow members to choose their membership amount (if free amount is allowed, no need to check)
if ($object->status == $object::STATUS_DRAFT) { // If the member is not yet validated, we check that the amount is the same as expected.
$typeid = $object->typeid;
@@ -440,6 +438,17 @@ if ($ispaymentok) {
}
}
+ // Security protection:
+ if (!empty($conf->global->MEMBER_MIN_AMOUNT)) {
+ if ($FinalPaymentAmt < $conf->global->MEMBER_MIN_AMOUNT) {
+ $error++;
+ $errmsg = 'Value of FinalPayment ('.$FinalPaymentAmt.') is lower than the minimum allowed ('.$conf->global->MEMBER_MIN_AMOUNT.'). May be a hack to try to pay a different amount ?';
+ $postactionmessages[] = $errmsg;
+ $ispostactionok = -1;
+ dol_syslog("Failed to validate member (amount lower than minimum): ".$errmsg, LOG_ERR, 0, '_payment');
+ }
+ }
+
// Security protection:
if ($currencyCodeType && $currencyCodeType != $conf->currency) { // Check that currency is the good one
$error++;
diff --git a/htdocs/public/project/index.php b/htdocs/public/project/index.php
index 5f450a6c557..0add64bb700 100644
--- a/htdocs/public/project/index.php
+++ b/htdocs/public/project/index.php
@@ -54,9 +54,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
$hookmanager = new HookManager($db);
$hookmanager->initHooks(array('newpayment'));
-// For encryption
-global $dolibarr_main_instance_unique_id;
-
// Load translation files
$langs->loadLangs(array("other", "dict", "bills", "companies", "errors", "paybox", "paypal", "stripe")); // File with generic data
diff --git a/htdocs/public/project/suggestbooth.php b/htdocs/public/project/suggestbooth.php
index c0bcdc751c6..cb1b1089b0c 100644
--- a/htdocs/public/project/suggestbooth.php
+++ b/htdocs/public/project/suggestbooth.php
@@ -19,16 +19,6 @@
* \file htdocs/public/project/suggestbooth.php
* \ingroup member
* \brief Example of form to suggest a booth
- *
- * Note that you can add following constant to change behaviour of page
- * MEMBER_NEWFORM_AMOUNT Default amount for auto-subscribe form
- * MEMBER_NEWFORM_EDITAMOUNT 0 or 1 = Amount can be edited
- * MEMBER_NEWFORM_PAYONLINE Suggest payment with paypal, paybox or stripe
- * MEMBER_NEWFORM_DOLIBARRTURNOVER Show field turnover (specific for dolibarr foundation)
- * MEMBER_URL_REDIRECT_SUBSCRIPTION Url to redirect once subscribe submitted
- * MEMBER_NEWFORM_FORCETYPE Force type of member
- * MEMBER_NEWFORM_FORCEMORPHY Force nature of member (mor/phy)
- * MEMBER_NEWFORM_FORCECOUNTRYCODE Force country
*/
if (!defined('NOLOGIN')) {
@@ -66,7 +56,6 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-global $dolibarr_main_instance_unique_id;
global $dolibarr_main_url_root;
// Init vars
diff --git a/htdocs/public/project/suggestconference.php b/htdocs/public/project/suggestconference.php
index f2a919c0aa2..22589c941d2 100644
--- a/htdocs/public/project/suggestconference.php
+++ b/htdocs/public/project/suggestconference.php
@@ -19,16 +19,6 @@
* \file htdocs/public/project/suggestconference.php
* \ingroup member
* \brief Example of form to suggest a conference
- *
- * Note that you can add following constant to change behaviour of page
- * MEMBER_NEWFORM_AMOUNT Default amount for auto-subscribe form
- * MEMBER_NEWFORM_EDITAMOUNT 0 or 1 = Amount can be edited
- * MEMBER_NEWFORM_PAYONLINE Suggest payment with paypal, paybox or stripe
- * MEMBER_NEWFORM_DOLIBARRTURNOVER Show field turnover (specific for dolibarr foundation)
- * MEMBER_URL_REDIRECT_SUBSCRIPTION Url to redirect once subscribe submitted
- * MEMBER_NEWFORM_FORCETYPE Force type of member
- * MEMBER_NEWFORM_FORCEMORPHY Force nature of member (mor/phy)
- * MEMBER_NEWFORM_FORCECOUNTRYCODE Force country
*/
if (!defined('NOLOGIN')) {
@@ -66,7 +56,6 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/paymentterm.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
-global $dolibarr_main_instance_unique_id;
global $dolibarr_main_url_root;
// Init vars
diff --git a/htdocs/public/project/viewandvote.php b/htdocs/public/project/viewandvote.php
index e680df15a1c..805eb8cfdd1 100644
--- a/htdocs/public/project/viewandvote.php
+++ b/htdocs/public/project/viewandvote.php
@@ -56,7 +56,7 @@ $hookmanager = new HookManager($db);
$hookmanager->initHooks(array('newpayment'));
// For encryption
-global $dolibarr_main_instance_unique_id, $dolibarr_main_url_root;
+global $dolibarr_main_url_root;
// Load translation files
$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "paybox", "paypal", "stripe")); // File with generic data
diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php
index 6a3fd1aa688..f2b72693a13 100644
--- a/htdocs/public/ticket/create_ticket.php
+++ b/htdocs/public/ticket/create_ticket.php
@@ -259,7 +259,7 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('save', 'alpha')) {
$message = ($conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->transnoentities('TicketNewEmailBody')).'