diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 23851b5e789..d10cd2d2f02 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -1287,6 +1287,7 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == '
$objecttmp = new $objectclass($db);
$nbok = 0;
+ $TMsg = array();
foreach ($toselect as $toselectid) {
$result = $objecttmp->fetch($toselectid);
if ($result > 0) {
@@ -1314,7 +1315,9 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == '
$result = $objecttmp->delete($user);
}
- if ($result <= 0) {
+ if (empty($result)) { // if delete returns 0, there is at least one object linked
+ $TMsg = array_merge($objecttmp->errors, $TMsg);
+ } elseif ($result < 0) { // if delete returns is < 0, there is an error, we break and rollback later
setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
$error++;
break;
@@ -1328,16 +1331,25 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == '
}
}
- if (!$error) {
+ if (empty($error)) {
+ // Message for elements well deleted
if ($nbok > 1) {
setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
- } else {
+ } elseif ($nbok == 1) {
setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
}
+
+ // Message for elements which can't be deleted
+ if (!empty($TMsg)) {
+ sort($TMsg);
+ setEventMessages('', array_unique($TMsg), 'warnings');
+ }
+
$db->commit();
} else {
$db->rollback();
}
+
//var_dump($listofobjectthirdparties);exit;
}
diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php
index 95518cbbf66..ce6bd3d4d60 100644
--- a/htdocs/core/ajax/row.php
+++ b/htdocs/core/ajax/row.php
@@ -89,7 +89,7 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3)
$perm = 1;
} elseif ($table_element_line == 'mrp_production' && $user->rights->mrp->write) {
$perm = 1;
- } elseif ($table_element_line == 'supplier_proposaldet' && $user->rights->supplier_proposal->write) {
+ } elseif ($table_element_line == 'supplier_proposaldet' && $user->rights->supplier_proposal->creer) {
$perm = 1;
} elseif ($table_element_line == 'commande_fournisseurdet' && $user->rights->fournisseur->commande->creer) {
$perm = 1;
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index ad4ad76a0f2..462a3bd5c44 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -4297,10 +4297,10 @@ abstract class CommonObject
//print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild;
$haschild += $obj->nb;
if (is_numeric($elementname)) { // old usage
- $this->errors[] = $langs->trans("ErrorRecordHasAtLeastOneChildOfType", $table);
+ $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $table);
} else // new usage: $elementname=Translation key
{
- $this->errors[] = $langs->trans("ErrorRecordHasAtLeastOneChildOfType", $langs->transnoentitiesnoconv($elementname));
+ $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($elementname));
}
break; // We found at least one, we stop here
}
@@ -8966,7 +8966,7 @@ abstract class CommonObject
* @param User $user User that deletes
* @param bool $notrigger false=launch triggers after, true=disable triggers
* @param int $forcechilddeletion 0=no, 1=Force deletion of children
- * @return int <=0 if KO, >0 if OK
+ * @return int <=0 if KO, 0=Nothing done because object has child, >0 if OK
*/
public function deleteCommon(User $user, $notrigger = false, $forcechilddeletion = 0)
{
diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php
index 4ceea8fde2c..26888851d45 100644
--- a/htdocs/fourn/commande/list.php
+++ b/htdocs/fourn/commande/list.php
@@ -134,10 +134,6 @@ if (!$sortorder) {
$sortorder = 'DESC';
}
-if ($search_status == '') {
- $search_status = -1;
-}
-
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$object = new CommandeFournisseur($db);
$hookmanager->initHooks(array('supplierorderlist'));
@@ -245,7 +241,7 @@ if (empty($reshook)) {
$search_multicurrency_montant_tva = '';
$search_multicurrency_montant_ttc = '';
$search_project_ref = '';
- $search_status = -1;
+ $search_status = '';
$search_date_order_startday = '';
$search_date_order_startmonth = '';
$search_date_order_startyear = '';
@@ -277,9 +273,42 @@ if (empty($reshook)) {
$objectlabel = 'SupplierOrders';
$permissiontoread = $user->rights->fournisseur->commande->lire;
$permissiontodelete = $user->rights->fournisseur->commande->supprimer;
+ $permissiontovalidate = $user->rights->fournisseur->commande->creer;
$uploaddir = $conf->fournisseur->commande->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
+ if ($action == 'validate' && $permissiontovalidate) {
+ if (GETPOST('confirm') == 'yes') {
+ $objecttmp = new CommandeFournisseur($db);
+ $db->begin();
+ $error = 0;
+
+ foreach ($toselect as $checked) {
+ if ($objecttmp->fetch($checked)) {
+ if ($objecttmp->statut == 0) {
+ $objecttmp->date_commande = dol_now();
+ $result = $objecttmp->valid($user);
+ if ($result >= 0) {
+ // If we have permission, and if we don't need to provide the idwarehouse, we go directly on approved step
+ if (empty($conf->global->SUPPLIER_ORDER_NO_DIRECT_APPROVE) && $user->rights->fournisseur->commande->approuver && !(!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) && $objecttmp->hasProductsOrServices(1))) {
+ $result = $objecttmp->approve($user);
+ setEventMessages($langs->trans("SupplierOrderValidatedAndApproved"), array($objecttmp->ref));
+ } else {
+ setEventMessages($langs->trans("SupplierOrderValidated"), array($objecttmp->ref));
+ }
+ } else {
+ setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
+ $error++;
+ }
+ }
+ }
+ }
+
+ if (!$error) $db->commit();
+ else $db->rollback();
+ }
+ }
+
// Mass action to generate vendor bills
if ($massaction == 'confirm_createsupplierbills') {
$orders = GETPOST('toselect', 'array');
@@ -947,6 +976,15 @@ if ($resql) {
'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
);
+
+ if ($permissiontovalidate) {
+ if ($user->rights->fournisseur->commande->approuver && empty($conf->global->SUPPLIER_ORDER_NO_DIRECT_APPROVE)) {
+ $arrayofmassactions['prevalidate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ValidateAndApprove");
+ } else {
+ $arrayofmassactions['prevalidate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate");
+ }
+ }
+
if ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer) {
$arrayofmassactions['createbills'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("CreateInvoiceForThisSupplier");
}
@@ -986,6 +1024,10 @@ if ($resql) {
$trackid = 'sord'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
+ if ($massaction == 'prevalidate') {
+ print $form->formconfirm($_SERVER["PHP_SELF"].$fieldstosearchall, $langs->trans("ConfirmMassValidation"), $langs->trans("ConfirmMassValidationQuestion"), "validate", null, '', 0, 200, 500, 1);
+ }
+
if ($massaction == 'createbills') {
//var_dump($_REQUEST);
print '';
diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql
index c76be4edbde..1b1023b31b7 100644
--- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql
+++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql
@@ -40,6 +40,12 @@
ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_project integer NOT NULL;
+UPDATE llx_extrafields SET elementtype = 'salary' WHERE elementtype = 'payment_salary';
+ALTER TABLE llx_payment_salary_extrafields RENAME TO llx_salary_extrafields;
+-- VMYSQL4.1 DROP INDEX idx_payment_salary_extrafields on llx_salary_extrafields
+-- VPGSQL8.2 DROP INDEX idx_payment_salary_extrafields
+ALTER TABLE llx_salary_extrafields ADD INDEX idx_salary_extrafields (fk_object);
+
-- v15
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index 89a3ec36af5..303df972340 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -83,7 +83,7 @@ ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "status not s
ErrorRefAlreadyExists=Ref used for creation already exists.
ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD)
ErrorRecordHasChildren=Failed to delete record since it has some child records.
-ErrorRecordHasAtLeastOneChildOfType=Object has at least one child of type %s
+ErrorRecordHasAtLeastOneChildOfType=Object %s has at least one child of type %s
ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into another object.
ErrorModuleRequireJavascript=Javascript must not be disabled to have this feature working. To enable/disable Javascript, go to menu Home->Setup->Display.
ErrorPasswordsMustMatch=Both typed passwords must match each other
diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang
index aad0010b4af..11220633d61 100644
--- a/htdocs/langs/en_US/orders.lang
+++ b/htdocs/langs/en_US/orders.lang
@@ -124,6 +124,8 @@ SupplierOrderReceivedInDolibarr=Purchase Order %s received %s
SupplierOrderSubmitedInDolibarr=Purchase Order %s submitted
SupplierOrderClassifiedBilled=Purchase Order %s set billed
OtherOrders=Other orders
+SupplierOrderValidatedAndApproved=Supplier order is validated and approved : %s
+SupplierOrderValidated=Supplier order is validated : %s
##### Types de contacts #####
TypeContact_commande_internal_SALESREPFOLL=Representative following-up sales order
TypeContact_commande_internal_SHIPPING=Representative following-up shipping
diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang
index 504f0fbcc16..d4dc53f42ed 100644
--- a/htdocs/langs/en_US/salaries.lang
+++ b/htdocs/langs/en_US/salaries.lang
@@ -21,4 +21,5 @@ LastSalaries=Latest %s salaries
AllSalaries=All salaries
SalariesStatistics=Salary statistics
SalariesAndPayments=Salaries and payments
-ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ?
\ No newline at end of file
+ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ?
+FillFieldFirst=Fill employee field first
diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang
index d7955df97e6..32090a13126 100644
--- a/htdocs/langs/fr_FR/errors.lang
+++ b/htdocs/langs/fr_FR/errors.lang
@@ -83,7 +83,7 @@ ErrorCantSaveADoneUserWithZeroPercentage=Impossible de sauver une action à l'é
ErrorRefAlreadyExists=Le référence %s existe déjà.
ErrorPleaseTypeBankTransactionReportName=Choisissez le nom du relevé bancaire sur lequel la ligne est rapportées (Format AAAAMM ou AAAAMMJJ)
ErrorRecordHasChildren=Impossible de supprimer l'enregistrement car il possède des enregistrements fils.
-ErrorRecordHasAtLeastOneChildOfType=L'objet a au moins un enfant de type %s
+ErrorRecordHasAtLeastOneChildOfType=L'objet %s a au moins un enfant de type %s
ErrorRecordIsUsedCantDelete=Ne peut effacer l'enregistrement. Ce dernier est déjà utilisé ou inclut dans un autre élément.
ErrorModuleRequireJavascript=Le javascript ne doit pas être désactivé pour que cette fonctionnalité soit utilisable. Pour activer/désactiver l'utilisation de javascript, allez dans le menu Accueil->Configuration->Affichage.
ErrorPasswordsMustMatch=Les 2 mots de passe saisis doivent correspondre
diff --git a/htdocs/langs/fr_FR/salaries.lang b/htdocs/langs/fr_FR/salaries.lang
index cdabb1c9f35..0dcf1a6d869 100644
--- a/htdocs/langs/fr_FR/salaries.lang
+++ b/htdocs/langs/fr_FR/salaries.lang
@@ -22,3 +22,4 @@ AllSalaries=Tous les salaires
SalariesStatistics=Statistiques
SalariesAndPayments=Salaires et paiements
ConfirmDeleteSalaryPayment=Voulez-vous supprimer ce paiement de salaire ?
+FillFieldFirst=Remplisez d'abord le champ salarié
diff --git a/htdocs/salaries/ajax/ajaxsalaries.php b/htdocs/salaries/ajax/ajaxsalaries.php
new file mode 100644
index 00000000000..28605ea5d83
--- /dev/null
+++ b/htdocs/salaries/ajax/ajaxsalaries.php
@@ -0,0 +1,73 @@
+
+ * Copyright (C) 2005-2009 Regis Houssin
+ * Copyright (C) 2007-2010 Laurent Destailleur
+ * Copyright (C) 2010 Cyrille de Lambert
+ *
+ * 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/salaries/ajax/ajaxsalaries.php
+ * \brief File to return Ajax response on salary request
+ */
+
+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('NOCSRFCHECK')) {
+ define('NOCSRFCHECK', '1');
+}
+
+require '../../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
+
+restrictedArea($user, 'salaries');
+
+$fk_user = GETPOST('fk_user', 'int');
+$return_arr = array();
+if (!empty(GETPOST('fk_user', 'int'))) {
+ $sql = "SELECT s.amount, s.rowid FROM ".MAIN_DB_PREFIX."salary as s";
+ $sql .= " WHERE s.fk_user = ".$fk_user;
+ $sql .= " AND s.paye = 1";
+ $sql .= $db->order("s.dateep", "DESC");
+
+ $resql = $db->query($sql);
+ if ($resql) {
+ $obj = $db->fetch_object($resql);
+ $label = "Salary amount";
+ $row_array['label'] = $label;
+ $row_array['value'] = $obj->amount;
+ $row_array['key'] = "Amount";
+
+ array_push($return_arr, $row_array);
+ echo json_encode($return_arr);
+ } else {
+ echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
+ }
+} else {
+ echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
+}
diff --git a/htdocs/salaries/card.php b/htdocs/salaries/card.php
index ca111adf4d1..9b46008fe09 100755
--- a/htdocs/salaries/card.php
+++ b/htdocs/salaries/card.php
@@ -466,8 +466,10 @@ if ($action == 'create') {
// Amount
print '