Compare commits

...

89 Commits

Author SHA1 Message Date
Laurent Destailleur
dff6319ffd Merge pull request #36503 from atm-florianm/FIX/155/DA027405/situation-percent-two-modes
FIX: when INVOICE_USE_SITUATION === 2, some libs still use the old algorithms
2025-12-04 22:13:47 +01:00
Laurent Destailleur
8b51ff85fd Fix CI 2025-12-04 21:58:10 +01:00
Laurent Destailleur
810ac047dc Fix CI 2025-12-04 21:08:17 +01:00
Laurent Destailleur
757e01eaaa Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-12-04 20:58:00 +01:00
Laurent Destailleur
1cd7de6e21 Better compatibility 2025-12-04 20:57:43 +01:00
Laurent Destailleur
e49f907cdc Merge pull request #36511 from lelex86/lelex86-patch-1
FIX: use suspended status in FactureFournisseurRec::updateline()
2025-12-04 20:57:04 +01:00
Laurent Destailleur
e350886c15 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into develop 2025-12-04 20:38:22 +01:00
Laurent Destailleur
78316a577d Merge branch '21.0' of git@github.com:Dolibarr/dolibarr.git into 22.0 2025-12-04 20:26:59 +01:00
Laurent Destailleur
3068a778da Merge branch '20.0' of git@github.com:Dolibarr/dolibarr.git into 21.0 2025-12-04 19:51:48 +01:00
Laurent Destailleur
9d307a4238 Merge branch '19.0' of git@github.com:Dolibarr/dolibarr.git into 20.0 2025-12-04 19:07:33 +01:00
Laurent Destailleur
193a42cd47 Fix #36520 2025-12-04 19:02:57 +01:00
Laurent Destailleur
222cd76799 Merge branch '18.0' of git@github.com:Dolibarr/dolibarr.git into 19.0 2025-12-04 18:53:04 +01:00
Laurent Destailleur
47799b88cf Merge branch '17.0' of git@github.com:Dolibarr/dolibarr.git into 18.0 2025-12-04 18:40:23 +01:00
Laurent Destailleur
78ca968db6 Merge pull request #36517 from atm-florianm/SEC/commented-out-restrictedArea
SEC: FIX #36430 permissions not checked on other tabs of HRM evaluation card
2025-12-04 18:37:46 +01:00
Laurent Destailleur
880eaa4592 Merge pull request #36530 from W1W1-M/fix-propal-update-shipping-availability
FIX propal shipping and availability update
2025-12-04 18:35:57 +01:00
Laurent Destailleur
e6f9741987 Merge pull request #36521 from JonBendtsen/BUG_35655_API_Contract_Creation_Fails_for_Non-Admin_Users_in_Version_22.0.2
FIX #35655 API Contract Creation Fails for Non-Admin Users in Version 22.0.2
2025-12-04 18:32:46 +01:00
Laurent Destailleur
46e509448d Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2025-12-04 18:31:52 +01:00
Laurent Destailleur
bb9f381e9f Fix CI 2025-12-04 18:31:31 +01:00
Laurent Destailleur
50db4e6499 Merge pull request #36518 from JonBendtsen/fix_36507_commit_9801f02
Fix broken commit 9801f02 mentioned in issue #36507
2025-12-04 18:15:43 +01:00
Laurent Destailleur
b4309adb23 Merge pull request #36534 from JonBendtsen/BUG__API_POST_contact_to_a_non-existing_socid_gives_DB_error__36407
FIX #36407 BUG: API POST contact to a non-existing socid gives DB error
2025-12-04 18:09:59 +01:00
Laurent Destailleur
c2902827a9 Fix CI 2025-12-04 18:09:43 +01:00
Laurent Destailleur
0235e86f64 Merge pull request #36484 from Hystepik/fix-#36475
Fix #36475 bad value for project  gantt start
2025-12-04 17:43:03 +01:00
Laurent Destailleur
c0bb5d2d77 Merge pull request #36499 from frederic34/patch-8
clean code
2025-12-04 17:42:16 +01:00
William Mead
7f68370536 Merge branch 'develop' into fix-propal-update-shipping-availability 2025-12-04 17:37:37 +01:00
Frédéric FRANCE
50c27b304e Update blockedlog.php 2025-12-04 17:27:15 +01:00
Jon Bendtsen
3d2a826865 FIX #36407 BUG: API POST contact to a non-existing socid gives DB error 2025-12-04 17:09:59 +01:00
Laurent Destailleur
adf3ca572c Merge pull request #36509 from defrance/patch-781201
Fix permission check from 'lire' to 'read'
2025-12-04 16:53:43 +01:00
Laurent Destailleur
bdb4a66088 Merge branch 'develop' into patch-781201 2025-12-04 16:53:26 +01:00
Laurent Destailleur
a578757389 Merge branch 'develop' into patch-8 2025-12-04 16:38:03 +01:00
Laurent Destailleur
526da8e5a7 Merge pull request #36505 from otcesar/22.0
Fix translation for import error
2025-12-04 16:37:31 +01:00
Jon Bendtsen
8deec3f918 it returns an Object, but it can not be TimeSpent because that creates a infinite loop 2025-12-04 16:23:13 +01:00
William Mead
8be39d4f5a Fixed shipping and availability updating. Updated contributor details. 2025-12-04 15:05:10 +01:00
Laurent Destailleur
23db225ec3 Merge pull request #36523 from FHenry/22_fix_subtotal_feature
FIX: subtotal feature button availablity according setup
2025-12-04 14:30:43 +01:00
Laurent Destailleur
d647a95de8 Merge pull request #36525 from BenjaminFlr/issue36514
FIX(propal): Incorrect HT/TTC recalculation when editing proposal lines #36514
2025-12-04 14:24:08 +01:00
Laurent Destailleur
aa8fac1deb Merge pull request #36429 from atm-adrien/FIX/MulticompanyStockCompatibility
FIX : Implementation of multi-company compatibility with inventory/warehouse management
2025-12-04 10:42:35 +01:00
Benjamin Falière
68004a4009 FIX(propal): Incorrect HT/TTC recalculation when editing proposal lines 2025-12-04 10:35:42 +01:00
Florian HENRY
a38ffa02ac fix: subtotal feature button availablity according setup 2025-12-04 10:18:01 +01:00
Eric - CAP-REL
2ebdcfda5c Merge pull request #35788 from Easya-Solutions/18_allow_credit_invoice_on_situation
FIX : remove useless condition to create credit on situation invoice …
2025-12-04 09:56:30 +01:00
Eric - CAP-REL
70431043af Merge pull request #36398 from Easya-Solutions/18.0_fix-invoice-card-variables
FIX undefined variables on create invoice from shipment card (backport from v20)
2025-12-04 09:30:56 +01:00
lvessiller-opendsi
ad37ece7bc Merge pull request #36494 from atm-florianm/FIX/155/date/minute-second-vs-min-sec
FIX 18.0: `GETPOSTDATE()` and `buildParamDate()` assumed wrong HTTP param names
2025-12-04 09:27:44 +01:00
Frédéric FRANCE
23694d67f1 Update blockedlog.php 2025-12-04 08:48:01 +01:00
Frédéric FRANCE
5701aa4b35 Merge branch 'develop' into patch-8 2025-12-04 08:36:15 +01:00
Jon Bendtsen
11cd186e9a remove debugging dol_syslog 2025-12-03 21:54:33 +01:00
Jon Bendtsen
8dc2eb0fe4 Checking for access to both new and old socid 2025-12-03 21:52:35 +01:00
Jon Bendtsen
66d3df4cc6 Fix broken commit 9801f02 mentioned in issue #36507 2025-12-03 21:06:13 +01:00
atm-florian
a1476fd221 SEC: permissions not checked on other tabs of HRM evaluation card 2025-12-03 17:11:14 +01:00
atm-florian
a49047b0d8 phpdoc: wrong return type 2025-12-03 16:57:09 +01:00
atm-florian
c464150b4b FIX bad ratio calculation 2025-12-03 16:43:11 +01:00
atm-florian
a2b1d1ed02 FIX missing space before cast 2025-12-03 16:01:11 +01:00
atm-florian
9737acc75a FIX wrong indentation 2025-12-03 15:34:12 +01:00
atm-florian
0c4fbc5270 Merge branch 'FIX/155/DA027405/situation-percent-two-modes' of github.com:atm-florianm/dolibarr into FIX/155/DA027405/situation-percent-two-modes 2025-12-03 15:14:38 +01:00
atm-florian
c5b0c1c318 FIX: INVOICE_USE_SITUATION (1 = legacy, 2 = new): some functions still use only the legacy algorithm 2025-12-03 15:13:39 +01:00
lelex86
f6e667da1a FIX: use suspended status in FactureFournisseurRec::updateline()
- The method checks `$this->status == self::STATUS_SUSPENDED`.
- For recurring **supplier** invoices, `$this->status` is not populated (it is always `null`).
- The real field used to store the suspended flag of the template is `$this->suspended`.
2025-12-03 09:59:03 +01:00
Lucas Marcouiller
59ccde0087 Merge branch '22.0' into fix-#36475 2025-12-03 09:49:23 +01:00
Charlène Benke
dc6c593187 Fix permission check from 'lire' to 'read' 2025-12-03 09:29:48 +01:00
Frédéric FRANCE
0c6b16060f Merge branch 'develop' into patch-8 2025-12-02 20:59:27 +01:00
Jon Bendtsen
268996c672 testing for access to the thirdpartytmp 2025-12-02 17:26:53 +01:00
Jon Bendtsen
ddd2927e31 This commit has errors, if you use PUT in the API with a new socid that the user does not have permission to, then it STILL updates the contract, and then it gets the contract after update and tells me I do not have access 2025-12-02 17:23:26 +01:00
Jon Bendtsen
b48fed1719 PUT now checks both existing socid and any potentially updated socid for access 2025-12-02 17:23:26 +01:00
Jon Bendtsen
26a39d1cc8 creating Thirdparties object takes no arguments 2025-12-02 17:23:26 +01:00
Jon Bendtsen
6f18235bab both socid exists and access to is checked in api_thirdparty GET :-) 2025-12-02 17:23:26 +01:00
Jon Bendtsen
1c697607b1 default deny access, allow access if user has the right combination of permissions and/or is the sales representative for the thirdparty 2025-12-02 17:23:26 +01:00
Jon Bendtsen
36415f1fd2 giving a slight better error message 2025-12-02 17:23:26 +01:00
Jon Bendtsen
9941a20fa8 Check if API user has rights to see all thirdparties
Check if API user has rights to see all thirdparties - though perhaps we should check if the user has rights to this particular thirdparty in this contract?
2025-12-02 17:23:26 +01:00
tcesar
6545957cbd Fix traduction for import error 2025-12-02 16:37:30 +01:00
atm-florian
c48b719473 FIX: now there are two values for INVOICE_USE_SITUATION (1 = legacy, 2 = new), leading to two interpretations of situation_percent; in some algorithms, only the old algorithm was applied even when the new mode was on 2025-12-02 15:10:43 +01:00
atm-florian
c27146f44c FIX: now there are two values for INVOICE_USE_SITUATION (1 = legacy, 2 = new), leading to two interpretations of situation_percent; in some algorithms, only the old algorithm was applied even when the new mode was on 2025-12-02 14:42:15 +01:00
Frédéric FRANCE
a560d4f886 clean code 2025-12-02 09:11:56 +01:00
Lucas Marcouiller
894bbd5786 Merge branch '22.0' into fix-#36475 2025-12-02 08:36:25 +01:00
Lucas Marcouiller
55977d16f1 fix warning 2025-12-02 08:35:53 +01:00
Lucas Marcouiller
792070b5f5 fix a potential warning 2025-12-02 08:34:41 +01:00
Laurent Destailleur
64bab261a9 Merge pull request #36495 from mapiolca/patch-67
Backport: fix intervention “Signed” confirmation when no status is selected
2025-12-01 16:47:51 +01:00
Pierre Ardoin
1c94462405 Update copyright year for Pierre Ardoin 2025-12-01 14:03:40 +01:00
Pierre Ardoin
dad4bbddd2 Report fix on 21.0
Fix an issue that have been fixed by Charlene Benke on v22
2025-12-01 14:00:38 +01:00
atm-florian
0e1c580f11 FIX 18.0: GETPOSTDATE and buildParamDate assumed HTTP param names 'minute' and 'second' instead of 'min' and 'sec' 2025-12-01 13:47:50 +01:00
Laurent Destailleur
4223ff08ce Merge pull request #36491 from Easya-Solutions/18.0_fix-update-extras
FIX not remove value of others extra-fields on update extras action
2025-12-01 13:10:08 +01:00
VESSILLER
d16f8b68db FIX not remove value of others extra-fields on update extras action 2025-12-01 11:14:16 +01:00
Lucas Marcouiller
8664f74154 Fix #36475 bad value for project gantt start 2025-11-29 21:55:45 +01:00
Laurent Destailleur
f4bcf47008 Merge pull request #36467 from emheyarssi/35061
FIX #35061
2025-11-29 11:28:03 +01:00
marc
5c6b4f62c8 FIX #35061
Signed-off-by: marc <marc.baur@ptmsoft.fr>
2025-11-28 18:25:00 +01:00
Laurent Destailleur
d8891130f5 Merge pull request #36463 from vold-lu/18.0
NEW: Automatically release docker image for each GitHub release
2025-11-28 18:13:47 +01:00
Aloïs Micard
b2f9de7489 Add new workflow to trigger Docker build 2025-11-28 17:27:32 +01:00
Laurent Destailleur
63cc9127ba Merge pull request #36434 from atm-lucasmantegari/FIX/ErrorFieldFilterInEvaluation
FIX - Missing AND on fields filter on evaluation class
2025-11-26 22:27:03 +01:00
Laurent Destailleur
097168cb05 Merge branch '21.0' into FIX/ErrorFieldFilterInEvaluation 2025-11-26 22:12:22 +01:00
Laurent Destailleur
f3b467a9ba Merge branch '21.0' into FIX/ErrorFieldFilterInEvaluation 2025-11-26 22:03:40 +01:00
ATM-Lucas
4585facfcc Missing AND on fields filter on evaluation class 2025-11-26 16:47:32 +01:00
Adrien Raze
c1c2358e75 FIX : Implementation of multi-company compatibility with inventory/warehouse management 2025-11-26 12:30:22 +01:00
VESSILLER
1cd3ca3222 FIX undefined variables on create invoice from shipment card (backport from v20) 2025-11-24 10:30:08 +01:00
tnegre
8ddf9f6075 FIX : remove useless condition to create credit on situation invoice (#35786) 2025-10-16 11:57:49 +02:00
32 changed files with 236 additions and 105 deletions

24
.github/workflows/ci-on-release.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: "CI-RELEASE"
on:
release:
types: [published]
jobs:
trigger-docker:
runs-on: ubuntu-latest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.RELEASE_DOCKER_ID }}
private-key: ${{ secrets.RELEASE_DOCKER_SECRET }}
- uses: peter-evans/repository-dispatch@v4
with:
token: ${{ steps.generate-token.outputs.token }}
repository: Dolibarr/dolibarr-docker
event-type: new-release
client-payload: '{"version": "${{ github.event.release.tag_name }}"}'

View File

@@ -1048,7 +1048,7 @@ class Setup extends DolibarrApi
global $langs;
$langs->loadLangs(array('holiday'));
if (!DolibarrApiAccess::$user->hasRight('holiday', 'lire')) {
if (!DolibarrApiAccess::$user->hasRight('holiday', 'read')) {
throw new RestException(403);
}

View File

@@ -19,6 +19,7 @@
* Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2025 Benjamin Falière <benjamin@faliere.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
@@ -1956,6 +1957,12 @@ if (empty($reshook)) {
$type = $product->type;
$price_base_type = $product->price_base_type;
// If base type TTc, we change pu value to define the TTC one
if ($price_base_type == 'TTC') {
$pu = $pu_ttc;
}
$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
$price_min = $product->price_min;
@@ -3521,14 +3528,15 @@ if ($action == 'create') {
if (empty($reshook)) {
if ($action != 'editline') {
// Subtotal
if ($object->status == Propal::STATUS_DRAFT && isModEnabled('subtotals') && getDolGlobalString('SUBTOTAL_TITLE_' . strtoupper($object->element))) {
if ($object->status == Propal::STATUS_DRAFT && isModEnabled('subtotals')
&& (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)))) {
$langs->load('subtotals');
$url_button = array();
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('propal') && $object->status == Propal::STATUS_DRAFT),
'enabled' => (isModEnabled('propal') && $object->status == Propal::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddTitleLine'),
'url' => '/comm/propal/card.php?id=' . $object->id . '&action=add_title_line&token=' . newToken()
@@ -3536,7 +3544,7 @@ if ($action == 'create') {
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('propal') && $object->status == Propal::STATUS_DRAFT),
'enabled' => (isModEnabled('propal') && $object->status == Propal::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddSubtotalLine'),
'url' => '/comm/propal/card.php?id=' . $object->id . '&action=add_subtotal_line&token=' . newToken()

View File

@@ -18,7 +18,7 @@
* Copyright (C) 2022 ATM Consulting <contact@atm-consulting.fr>
* Copyright (C) 2022 OpenDSI <support@open-dsi.fr>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2023 William Mead <william@m34d.com>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -1879,6 +1879,8 @@ class Propal extends CommonObject
$sql .= " deposit_percent = ".(!empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null").",";
$sql .= " fk_mode_reglement = ".(!empty($this->mode_reglement_id) ? (int) $this->mode_reglement_id : "null").",";
$sql .= " fk_input_reason = ".(!empty($this->demand_reason_id) ? (int) $this->demand_reason_id : "null").",";
$sql .= " fk_shipping_method = ".(isset($this->shipping_method_id) ? (int) $this->shipping_method_id : "null").",";
$sql .= " fk_availability = ".(!empty($this->availability_id) ? (int) $this->availability_id : "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 .= " model_pdf = ".(isset($this->model_pdf) ? "'".$this->db->escape($this->model_pdf)."'" : "null").",";

View File

@@ -3450,14 +3450,15 @@ if ($action == 'create' && $usercancreate) {
}
// Subtotal
if ($object->status == Commande::STATUS_DRAFT && isModEnabled('subtotals') && getDolGlobalString('SUBTOTAL_TITLE_' . strtoupper($object->element))) {
if ($object->status == Commande::STATUS_DRAFT && isModEnabled('subtotals')
&& (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)))) {
$langs->load('subtotals');
$url_button = array();
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT),
'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddTitleLine'),
'url' => '/commande/card.php?id=' . $object->id . '&action=add_title_line&token=' . newToken()
@@ -3465,7 +3466,7 @@ if ($action == 'create' && $usercancreate) {
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT),
'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddSubtotalLine'),
'url' => '/commande/card.php?id=' . $object->id . '&action=add_subtotal_line&token=' . newToken()

View File

@@ -2076,14 +2076,15 @@ if ($action == 'create') {
);
// Subtotal
if (empty($object->suspended) && isModEnabled('subtotals') && getDolGlobalString('SUBTOTAL_TITLE_'.strtoupper($object->element))) {
if (empty($object->suspended) && isModEnabled('subtotals')
&& (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)))) {
$langs->load("subtotals");
$url_button = array();
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT),
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddTitleLine'),
'url' => '/compta/facture/card-rec.php?id='.$object->id.'&action=add_title_line&token='.newToken()
@@ -2091,7 +2092,7 @@ if ($action == 'create') {
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT),
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddSubtotalLine'),
'url' => '/compta/facture/card-rec.php?id='.$object->id.'&action=add_subtotal_line&token='.newToken()

View File

@@ -6560,14 +6560,15 @@ if ($action == 'create') {
}
// Subtotal
if ($object->status == Facture::STATUS_DRAFT && isModEnabled('subtotals') && getDolGlobalString('SUBTOTAL_TITLE_'.strtoupper($object->element))) {
if ($object->status == Facture::STATUS_DRAFT && isModEnabled('subtotals')
&& (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)))) {
$langs->load("subtotals");
$url_button = array();
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT),
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddTitleLine'),
'url' => '/compta/facture/card.php?facid='.$object->id.'&action=add_title_line&token='.newToken()
@@ -6575,7 +6576,7 @@ if ($action == 'create') {
$url_button[] = array(
'lang' => 'subtotals',
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT),
'enabled' => (isModEnabled('invoice') && $object->status == Facture::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
'perm' => (bool) $usercancreate,
'label' => $langs->trans('AddSubtotalLine'),
'url' => '/compta/facture/card.php?facid='.$object->id.'&action=add_subtotal_line&token='.newToken()

View File

@@ -1070,4 +1070,38 @@ class FactureLigne extends CommonInvoiceLine
return $cumulated_percent;
}
}
/**
* Determines if we are using situation invoices.
* If so, determines if we are using the new mode (2) or legacy mode (1).
*
* Legacy mode means invoice line fields store the state of the cycle at the current
* situation (a cumulative value) rather than the delta between the previous situation
* and the current one. In that case, we need a ratio to convert those values.
*
* New mode = the values on the line already represent the delta between the previous
* state and the current state, so we don't need a conversion (we return 1).
*
* @return float
*/
public function getSituationRatio()
{
if (getDolGlobalInt('INVOICE_USE_SITUATION') === 1) {
// in legacy mode, the situation invoice line stores the (cumulative) state of the
// cycle at the current situation. To get the delta, we need to subtract the
// state at the previous situation (if applicable).
$prevProgress = $this->get_prev_progress($this->fk_facture);
if ($this->situation_percent == 0) {
// should not happen
return 0;
}
return ($this->situation_percent - $prevProgress) / $this->situation_percent;
}
// new mode (INVOICE_USE_SITUATION == 2):
// no ratio needed (data stored on line is already a delta)
// or not a situation invoice: no ratio needed either
return 1;
}
}

View File

@@ -203,12 +203,22 @@ if ($result) {
$line->fetch($obj->id); // id of line
$prev_progress = 0;
if ($obj->situation_cycle_ref > 0) { // It is a situation invoice
$prev_progress = $line->get_prev_progress($obj->rowid); // id on invoice
if (getDolGlobalInt('INVOICE_USE_SITUATION') === 1) {
// backward compat: old behavior => line's situation_percent was cumulative
// (it reflected the line's progress state, not the line progress delta)
$progressDelta = $obj->situation_percent - $prev_progress;
$progressState = $obj->situation_percent;
} else {
$progressDelta = $obj->situation_percent;
$progressState = $prev_progress + $progressDelta;
}
// Avoid divide by 0
if ($obj->situation_percent == 0) {
if ($progressState == 0) {
$situation_ratio = 0;
} else {
$prev_progress = $line->get_prev_progress($obj->rowid); // id on invoice
$situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
$situation_ratio = $progressDelta / $progressState;
}
} else {
$situation_ratio = 1;

View File

@@ -84,7 +84,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$this->contract->fetchObjectLinked();
@@ -175,7 +175,6 @@ class Contracts extends DolibarrApi
$sql .= $this->db->plimit($limit + 1, $offset);
}
dol_syslog("API Rest request");
$result = $this->db->query($sql);
if ($result) {
@@ -234,8 +233,19 @@ class Contracts extends DolibarrApi
{
global $conf;
if (!DolibarrApiAccess::$user->hasRight('contrat', 'creer')) {
throw new RestException(403, "Insufficient rights");
throw new RestException(403, "Missing permission: Create/modify contracts/subscriptions");
}
$socid = (int) $request_data['socid'];
$thirdpartytmp = new Societe($this->db);
$thirdparty_result = $thirdpartytmp->fetch($socid);
if ($thirdparty_result < 1) {
throw new RestException(404, 'Thirdparty with id='.$socid.' not found or not allowed');
}
if (!DolibarrApi::_checkAccessToResource('societe', $thirdpartytmp->id)) {
throw new RestException(404, 'Thirdparty with id='.$thirdpartytmp->id.' not found or not allowed');
}
// Check mandatory fields
$result = $this->_validate($request_data);
@@ -308,7 +318,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$obj_ret = [];
@@ -340,7 +350,6 @@ class Contracts extends DolibarrApi
$sql .= $this->db->plimit($limit + 1, $offset);
}
dol_syslog("API Rest request");
$result = $this->db->query($sql);
if ($result) {
$num = $this->db->num_rows($result);
@@ -400,7 +409,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$request_data = (object) $request_data;
@@ -460,7 +469,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$request_data = (object) $request_data;
@@ -611,7 +620,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$updateRes = $this->contract->active_line(DolibarrApiAccess::$user, $lineid, (int) $datestart, $dateend, $comment);
@@ -652,7 +661,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$updateRes = $this->contract->close_line(DolibarrApiAccess::$user, $lineid, (int) $datestart, $comment);
@@ -692,7 +701,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
// TODO Check the lineid $lineid is a line of object
@@ -727,13 +736,24 @@ class Contracts extends DolibarrApi
if ($id == 0) {
throw new RestException(400, 'No contract with id=0 can exist');
}
$result = $this->contract->fetch($id);
if (!$result) {
throw new RestException(404, 'Contrat not found');
}
$old_socid = $this->contract->socid;
$oldthirdpartytmp = new Societe($this->db);
$old_thirdparty_result = $oldthirdpartytmp->fetch($old_socid);
if ($old_thirdparty_result < 1) {
throw new RestException(404, 'Thirdparty with id='.$old_socid.' not found or not allowed');
}
if (!DolibarrApi::_checkAccessToResource('societe', $old_socid)) {
throw new RestException(403, 'Access to old thirdparty='.$old_socid.' is not allowed for login '.DolibarrApiAccess::$user->login);
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
foreach ($request_data as $field => $value) {
if ($field == 'id') {
@@ -763,6 +783,18 @@ class Contracts extends DolibarrApi
continue;
}
if ($field == 'socid') {
$new_socid = (int) $value;
$loopthirdpartytmp = new Societe($this->db);
$new_thirdparty_result = $loopthirdpartytmp->fetch($new_socid);
if ($new_thirdparty_result < 1) {
throw new RestException(404, 'Thirdparty with id='.$new_socid.' not found or not allowed');
}
if (!DolibarrApi::_checkAccessToResource('societe', $new_socid)) {
throw new RestException(403, 'Access to new thirdparty='.$new_socid.' is not allowed for login '.DolibarrApiAccess::$user->login);
}
}
$this->contract->$field = $this->_checkValForAPI($field, $value, $this->contract);
}
@@ -790,7 +822,7 @@ class Contracts extends DolibarrApi
public function delete($id)
{
if (!DolibarrApiAccess::$user->hasRight('contrat', 'supprimer')) {
throw new RestException(403);
throw new RestException(403, 'Missing permission: Delete contracts/subscriptions');
}
if ($id == 0) {
throw new RestException(400, 'No contract with id=0 can exist');
@@ -801,7 +833,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
if (!$this->contract->delete(DolibarrApiAccess::$user)) {
@@ -854,7 +886,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$result = $this->contract->validate(DolibarrApiAccess::$user, '', $notrigger);
@@ -911,7 +943,7 @@ class Contracts extends DolibarrApi
}
if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
throw new RestException(403, 'Access to this contract is not allowed for login '.DolibarrApiAccess::$user->login);
}
$result = $this->contract->closeAll(DolibarrApiAccess::$user, $notrigger);

View File

@@ -1261,7 +1261,7 @@ function GETPOSTDATE($prefix, $hourTime = '', $gm = 'auto', $saverestore = '')
if ($hourTime === 'getpost' || $hourTime === 'getpostend') {
$hour = (GETPOSTISSET($prefix . 'hour') && GETPOSTINT($prefix . 'hour') >= 0) ? GETPOSTINT($prefix . 'hour') : ($hourTime === 'getpostend' ? 23 : 0);
$minute = (GETPOSTISSET($prefix . 'min') && GETPOSTINT($prefix . 'min') >= 0) ? GETPOSTINT($prefix . 'min') : ($hourTime === 'getpostend' ? 59 : 0);
$second = (GETPOSTISSET($prefix . 'second') && GETPOSTINT($prefix . 'second') >= 0) ? GETPOSTINT($prefix . 'second') : ($hourTime === 'getpostend' ? 59 : 0);
$second = (GETPOSTISSET($prefix . 'sec') && GETPOSTINT($prefix . 'sec') >= 0) ? GETPOSTINT($prefix . 'sec') : ($hourTime === 'getpostend' ? 59 : 0);
} elseif (preg_match('/^(\d\d):(\d\d):(\d\d)$/', $hourTime, $m)) {
$hour = intval($m[1]);
$minute = intval($m[2]);
@@ -12713,6 +12713,7 @@ function printCommonFooter($zone = 'private')
$parameters = array('zone' => $zone);
$tmpobject = null;
// @phan-suppress-next-line PhanPluginConstantVariableNull
$reshook = $hookmanager->executeHooks('printCommonFooter', $parameters, $tmpobject, $action); // Note that $action and $object may have been modified by some hooks
if (empty($reshook)) {
if (getDolGlobalString('MAIN_HTML_FOOTER')) {
@@ -16827,8 +16828,8 @@ function buildParamDate($prefix, $timestamp = null, $hourTime = '', $gm = 'auto'
if ($hourTime === 'getpost' || ($timestamp !== null && dol_print_date($timestamp, '%H:%M:%S') !== '00:00:00')) {
$TParam = array_merge($TParam, array(
$prefix . 'hour' => intval(dol_print_date($timestamp, '%H')),
$prefix . 'minute' => intval(dol_print_date($timestamp, '%M')),
$prefix . 'second' => intval(dol_print_date($timestamp, '%S'))
$prefix . 'min' => intval(dol_print_date($timestamp, '%M')),
$prefix . 'sec' => intval(dol_print_date($timestamp, '%S'))
));
}

View File

@@ -2456,15 +2456,31 @@ function pdf_getlineprogress($object, $i, $outputlangs, $hidedetails = 0, $hookm
return '';
}
if (empty($hidedetails) || $hidedetails > 1) {
if (getDolGlobalString('SITUATION_DISPLAY_DIFF_ON_PDF')) {
// 2 = situation_percent is non-cumulative (delta of current situation)
// 1 = (old mode): situation_percent is cumulative (state at situation)
$isCumulative = getDolGlobalInt('INVOICE_USE_SITUATION') === 1;
$showDelta = (bool) getDolGlobalInt('SITUATION_DISPLAY_DIFF_ON_PDF');
if ($isCumulative xor $showDelta) {
// Either:
// - old mode and we want to show a total or
// - new mode and we want to show a delta
$result = $object->lines[$i]->situation_percent;
} else {
// Either:
// - old mode but we want to show a delta or
// - new mode but we want to show a total
$prev_progress = 0;
if (method_exists($object->lines[$i], 'get_prev_progress')) {
$prev_progress = $object->lines[$i]->get_prev_progress($object->id);
}
$result = round($object->lines[$i]->situation_percent - $prev_progress, 1).'%';
} else {
$result = round($object->lines[$i]->situation_percent, 1).'%';
$result = $isCumulative ?
// old mode: we need to compute the delta (total - sum of previous)
$object->lines[$i]->situation_percent - $prev_progress :
// new mode: we need to compute the total (sum of previous + delta)
$prev_progress + $object->lines[$i]->situation_percent;
}
$result = round($result, 1).'%';
}
}
return $result;
@@ -2510,17 +2526,9 @@ function pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails = 0)
} elseif (empty($hidedetails) || $hidedetails > 1) {
$total_ht = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ht : $object->lines[$i]->total_ht);
if (!empty($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
// TODO Remove this. The total should be saved correctly in database instead of being modified here.
$prev_progress = 0;
$progress = 1;
if (method_exists($object->lines[$i], 'get_prev_progress')) {
$prev_progress = $object->lines[$i]->get_prev_progress($object->id);
$progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
}
$result .= price($sign * ($total_ht / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
} else {
$result .= price($sign * $total_ht, 0, $outputlangs);
$total_ht *= $object->lines[$i]->getSituationRatio();
}
$result .= price($sign * $total_ht, 0, $outputlangs);
}
}
return $result;
@@ -2566,17 +2574,9 @@ function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0)
} elseif (empty($hidedetails) || $hidedetails > 1) {
$total_ttc = (isModEnabled("multicurrency") && $object->multicurrency_tx != 1 ? $object->lines[$i]->multicurrency_total_ttc : $object->lines[$i]->total_ttc);
if (isset($object->lines[$i]->situation_percent) && $object->lines[$i]->situation_percent > 0) {
// TODO Remove this. The total should be saved correctly in database instead of being modified here.
$prev_progress = 0;
$progress = 1;
if (method_exists($object->lines[$i], 'get_prev_progress')) {
$prev_progress = $object->lines[$i]->get_prev_progress($object->id);
$progress = ($object->lines[$i]->situation_percent - $prev_progress) / 100;
}
$result .= price($sign * ($total_ttc / ($object->lines[$i]->situation_percent / 100)) * $progress, 0, $outputlangs);
} else {
$result .= price($sign * $total_ttc, 0, $outputlangs);
$total_ttc *= $object->lines[$i]->getSituationRatio();
}
$result .= price($sign * $total_ttc, 0, $outputlangs);
}
}
return $result;

View File

@@ -458,7 +458,8 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt
// Allow an external module to bypass the calculation of prices
$parameters = array('result' => $result);
$tmpobject = null; $tmpaction = '';
$tmpobject = null;
$tmpaction = '';
// @phan-suppress-next-line PhanPluginConstantVariableNull
$reshook = $hookmanager->executeHooks('calcul_price_total', $parameters, $tmpobject, $tmpaction); // @phan-suppress-current-line PhanPluginConstantVariableNull
if ($reshook > 0 && !empty($hookmanager->resArray['result'])) {

View File

@@ -1021,14 +1021,14 @@ function checkUserAccessToObject($user, array $featuresarray, $object = 0, $tabl
$checkonentitydone = 0;
// Array to define rules of checks to do
$check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'payment_sc', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website', 'recruitment', 'chargesociales', 'knowledgemanagement'); // Test on entity only (Objects with no link to company)
$check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'payment_sc', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website', 'recruitment', 'chargesociales', 'knowledgemanagement', 'stock'); // Test on entity only (Objects with no link to company)
$checksoc = array('societe'); // Test for object Societe
$checkparentsoc = array('agenda', 'contact', 'contrat'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
$checkproject = array('projet', 'project'); // Test for project object
$checktask = array('projet_task', 'project_task'); // Test for task object
$checkhierarchy = array('expensereport', 'holiday', 'hrm'); // check permission among the hierarchy of user
$checkuser = array('bookmark'); // check permission among the fk_user (must be myself or null)
$nocheck = array('barcode', 'stock', 'webhook'); // No test
$nocheck = array('barcode', 'webhook'); // No test
//$checkdefault = 'all other not already defined'; // Test on entity + link to third party on field $dbt_keyfield. Not allowed if link is empty (Ex: invoice, orders...).

View File

@@ -329,7 +329,7 @@ if (empty($reshook)) {
$object->date_shipping = $date_shipping; // Sending date
$object->shipping_method_id = GETPOSTINT('shipping_method_id');
$object->tracking_number = GETPOST('tracking_number', 'alpha');
$object->note = GETPOST('note', 'restricthtml'); // deprecated
$object->note = GETPOST('note_private', 'restricthtml'); // deprecated
$object->note_private = GETPOST('note_private', 'restricthtml');
$object->note_public = GETPOST('note_public', 'restricthtml');
$object->fk_incoterms = GETPOSTINT('incoterm_id');
@@ -337,8 +337,6 @@ if (empty($reshook)) {
$product = new Product($db);
// Fill array 'array_options' with data from add form
$ret = $extrafields->setOptionalsFromPost(null, $object);
if ($ret < 0) {
@@ -371,7 +369,7 @@ if (empty($reshook)) {
$object->date_shipping = $date_shipping; // Sending date
$object->shipping_method_id = GETPOSTINT('shipping_method_id');
$object->tracking_number = GETPOST('tracking_number', 'alpha');
$object->note = GETPOST('note', 'restricthtml'); // deprecated
$object->note = GETPOST('note_private', 'restricthtml'); // deprecated
$object->note_private = GETPOST('note_private', 'restricthtml');
$object->note_public = GETPOST('note_public', 'restricthtml');
$object->fk_incoterms = GETPOSTINT('incoterm_id');

View File

@@ -13,6 +13,7 @@
* Copyright (C) 2023-2024 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2025 Pierre Ardoin <developpeur@lesmetiersdubatiment.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

View File

@@ -707,6 +707,7 @@ class FactureFournisseurRec extends CommonInvoice
$this->socid = $obj->fk_soc;
$this->date_creation = $obj->datec;
$this->date_modification = $obj->tms;
$this->status = $obj->suspended;
$this->suspended = $obj->suspended;
$this->libelle = $obj->label;
$this->label = $obj->label;
@@ -1186,7 +1187,7 @@ class FactureFournisseurRec extends CommonInvoice
return -1;
}
if ($this->status == self::STATUS_SUSPENDED) {
if ($this->suspended == self::STATUS_SUSPENDED) {
// Clean parameters
$fk_product = empty($fk_product) ? 0 : $fk_product;
$label = empty($label) ? '' : $label;

View File

@@ -359,8 +359,8 @@ class CommandeFournisseurLigne extends CommonOrderLine
} else {
$sql .= "null,";
}
$sql .= "'".$this->db->escape((string) $this->product_type)."',";
$sql .= ((int) $this->special_code) . ",";
$sql .= ((int) $this->product_type).",";
$sql .= ((int) $this->special_code).",";
$sql .= "'".$this->db->escape((string) $this->rang)."',";
$sql .= "'".$this->db->escape((string) $this->qty)."', ";
$sql .= " ".(empty($this->vat_src_code) ? "''" : "'".$this->db->escape((string) $this->vat_src_code)."'").",";

View File

@@ -217,7 +217,7 @@ class Evaluation extends CommonObject
}
if (!$user->hasRight('hrm', 'evaluation', 'readall')) {
$this->fields['fk_user']['type'] .= ':t.rowid:IN:'.$this->db->sanitize(implode(",", $user->getAllChildIds(1)));
$this->fields['fk_user']['type'] .= ' AND (t.rowid:IN:'.$this->db->sanitize(implode(",", $user->getAllChildIds(1))) .')';
}
$this->date_eval = dol_now();

View File

@@ -105,8 +105,9 @@ $permissiontoread = $user->hasRight('hrm', 'evaluation', 'read'); // Used by the
// Security check (enable the most restrictive one)
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->module, $object->id, $object->table_element, $object->element, 'fk_soc', 'rowid', $isdraft);
$isdraft = $object->status == Evaluation::STATUS_DRAFT ? 1 : 0;
restrictedArea($user, $object->element, $object, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled('hrm')) {
accessforbidden();
}

View File

@@ -71,10 +71,8 @@ $permission = $user->hasRight('hrm', 'evaluation', 'write');
// Security check (enable the most restrictive one)
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//if (empty($conf->hrm->enabled)) accessforbidden();
//if (!$permissiontoread) accessforbidden();
$isdraft = $object->status == Evaluation::STATUS_DRAFT ? 1 : 0;
restrictedArea($user, $object->element, $object, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);

View File

@@ -95,16 +95,12 @@ $permissiontoadd = $user->hasRight('hrm', 'evaluation', 'write'); // Used by th
$permissiontoread = $user->hasRight('hrm', 'evaluation', 'read');
// Security check (enable the most restrictive one)
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
if (empty($conf->hrm->enabled)) {
accessforbidden();
}
if (!$permissiontoread) {
accessforbidden();
}
$isdraft = $object->status == Evaluation::STATUS_DRAFT ? 1 : 0;
restrictedArea($user, $object->element, $object, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
if (!isModEnabled('hrm')) accessforbidden();
if (!$permissiontoread) accessforbidden();
/*

View File

@@ -75,10 +75,10 @@ $permissiontoread = $user->hasRight('hrm', 'evaluation', 'read'); // Used by th
// Security check (enable the most restrictive one)
//if ($user->socid > 0) accessforbidden();
//if ($user->socid > 0) $socid = $user->socid;
//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
//if (empty($conf->hrm->enabled)) accessforbidden();
//if (!$permissiontoread) accessforbidden();
$isdraft = (($object->status == Evaluation::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, $object->element, $object, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
if (empty($conf->hrm->enabled)) accessforbidden();
if (!$permissiontoread) accessforbidden();
/*

View File

@@ -1898,7 +1898,7 @@ if ($step == 5 && $datatoimport) {
//dol_syslog("line ".$sourcelinenb.' - '.$nboflines.' - '.$excludefirstline.' - '.$endatlinenb);
$arrayrecord = $obj->import_read_record();
if ($arrayrecord === false) {
$arrayofwarnings[$sourcelinenb][0] = array('lib' => 'File has '.$nboflines.' lines. However we reach the end of file or an empty line at record '.$sourcelinenb.'. This may occurs when some records are split onto several lines and not correctly delimited by the "Char delimiter", or if there is line with no data on all fields.', 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
$arrayofwarnings[$sourcelinenb][0] = array('lib' => $langs->trans('ErrorFileLinesReachEOF', $nboflines, $sourcelinenb), 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
$endoffile++;
continue;
}
@@ -2321,7 +2321,7 @@ if ($step == 6 && $datatoimport) {
$sourcelinenb++;
$arrayrecord = $obj->import_read_record();
if ($arrayrecord === false) {
$arrayofwarnings[$sourcelinenb][0] = array('lib' => 'File has '.$nboflines.' lines. However we reach the end of file or an empty line at record '.$sourcelinenb.'. This may occurs when some records are split onto several lines and not correctly delimited by the "Char delimiter", or if there is line with no data on all fields.', 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
$arrayofwarnings[$sourcelinenb][0] = array('lib' => $langs->trans('ErrorFileLinesReachEOF', $nboflines, $sourcelinenb), 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
$endoffile++;
continue;
}

View File

@@ -152,3 +152,4 @@ MandatoryTargetFieldsNotMapped=Some mandatory target fields are not mapped
AllTargetMandatoryFieldsAreMapped=All target fields that need a mandatory value are mapped
ResultOfSimulationNoError=Result of simulation: No error
NumberOfLinesLimited=Number of lines limited
ErrorFileLinesReachEOF=File has %s lines. However we reach the end of file or an empty line at record %s. This may occurs when some records are split onto several lines and not correctly delimited by the "Char delimiter", or if there is line with no data on all fields.

View File

@@ -55,9 +55,9 @@ $include_sub_warehouse = !empty(GETPOST('include_sub_warehouse')) ? GETPOST('inc
$hookmanager->initHooks(array('inventorycard', 'globalcard')); // Note that conf->hooks_modules contains array
if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
$result = restrictedArea($user, 'stock', $id);
$result = restrictedArea($user, 'stock', $id, 'inventory&stock');
} else {
$result = restrictedArea($user, 'stock', $id, '', 'inventory_advance');
$result = restrictedArea($user, 'stock', $id, 'inventory&stock', 'inventory_advance');
}
// Initialize a technical objects

View File

@@ -72,9 +72,9 @@ $totalExpectedValuation = 0;
$totalRealValuation = 0;
$hookmanager->initHooks(array('inventorycard')); // Note that conf->hooks_modules contains array
if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) {
$result = restrictedArea($user, 'stock', $id);
$result = restrictedArea($user, 'stock', $id, 'inventory&stock');
} else {
$result = restrictedArea($user, 'stock', $id, '', 'inventory_advance');
$result = restrictedArea($user, 'stock', $id, 'inventory&stock', 'inventory_advance');
}
// Initialize a technical objects

View File

@@ -85,8 +85,7 @@ if (!$sortorder) {
$hookmanager->initHooks(array('warehousecard', 'stocklist', 'globalcard'));
// Security check
//$result=restrictedArea($user,'stock', $id, 'entrepot&stock');
$result = restrictedArea($user, 'stock');
$result=restrictedArea($user, 'stock', $id, 'entrepot&stock');
$object = new Entrepot($db);
$extrafields = new ExtraFields($db);

View File

@@ -572,7 +572,7 @@ class Tasks extends DolibarrApi
*
* @url GET {id}/getTimeSpent/{timespent_id}
*
* @return TimeSpent
* @return Object data without useless information
*
* @throws RestException
*/
@@ -1113,7 +1113,4 @@ class Tasks extends DolibarrApi
return $this->_cleanObjectDatas($this->task);
}
// \todo
// getSummaryOfTimeSpent
}

View File

@@ -141,7 +141,7 @@ if (g.getDivId() != null)
'task_name' => $projecttmp->ref.' '.$projecttmp->title,
'task_resources' => '',
'task_start_date' => $projecttmp->date_start,
'task_end_date' => $projecttmp->date_end,
'task_end_date' => (!empty($projecttmp->date_end) ? $projecttmp->date_end : 0),
'task_is_group' => 1, 'task_position' => 0, 'task_css' => 'ggroupblack', 'task_milestone' => 0, 'task_parent' => 0, 'task_parent_alternate_id' => 0,
'note' => '',
'task_planned_workload' => 0

View File

@@ -88,7 +88,7 @@ if (!empty($project_ref) && !empty($withproject)) {
$id = $tasksarray[0]->id;
$object->fetch($id);
} else {
header("Location: ".DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.($withproject ? '&withproject=1' : '').(empty($mode) ? '' : '&mode='.$mode));
header("Location: ".DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.'&withproject=1');
exit;
}
}
@@ -145,7 +145,8 @@ if ($object->id > 0) {
$head = project_prepare_head($projectstatic);
print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public ? 'projectpub' : 'project'));
$param = (isset($mode) && $mode == 'mine' ? '&mode=mine' : '');
$param = '';
// Project card
$linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';

View File

@@ -22,6 +22,7 @@ use Luracast\Restler\RestException;
//require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
//require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
/**
@@ -365,6 +366,17 @@ class Contacts extends DolibarrApi
}
continue;
}
if ($field == 'socid') {
$new_socid = (int) $value;
$loopthirdpartytmp = new Societe($this->db);
$new_thirdparty_result = $loopthirdpartytmp->fetch($new_socid);
if ($new_thirdparty_result < 1) {
throw new RestException(404, 'Thirdparty with id='.$new_socid.' not found or not allowed');
}
if (!DolibarrApi::_checkAccessToResource('societe', $new_socid)) {
throw new RestException(403, 'Access to socid/thirdparty='.$new_socid.' is not allowed for login '.DolibarrApiAccess::$user->login);
}
}
$this->contact->$field = $this->_checkValForAPI($field, $value, $this->contact);
}
@@ -422,6 +434,17 @@ class Contacts extends DolibarrApi
}
continue;
}
if ($field == 'socid') {
$new_socid = (int) $value;
$loopthirdpartytmp = new Societe($this->db);
$new_thirdparty_result = $loopthirdpartytmp->fetch($new_socid);
if ($new_thirdparty_result < 1) {
throw new RestException(404, 'Thirdparty with id='.$new_socid.' not found or not allowed');
}
if (!DolibarrApi::_checkAccessToResource('societe', $new_socid)) {
throw new RestException(403, 'Access to socid/thirdparty='.$new_socid.' is not allowed for login '.DolibarrApiAccess::$user->login);
}
}
$this->contact->$field = $this->_checkValForAPI($field, $value, $this->contact);
}