Bugfix: Validation consumption#225
Conversation
| ERROR, | ||
| ); | ||
| Html::back(); | ||
| if (!Session::haveRight('ticket', UPDATE) && !Session::haveRight(Entity::$rightname, UPDATE)) { |
There was a problem hiding this comment.
Why add a validation check when modifying an entity?
A technician updating a ticket (including data coming from the credit plugin) does not necessarily have the permissions required to update the associated entity.
| $ticket_id = filter_var( | ||
| $input['tickets_id'] ?? null, | ||
| FILTER_VALIDATE_INT, | ||
| ['options' => ['min_range' => 1]], | ||
| ); | ||
| if ($ticket_id === false) { | ||
| Session::addMessageAfterRedirect( | ||
| __s('Ticket is mandatory.', 'credit'), | ||
| true, | ||
| ERROR, | ||
| ); | ||
| return false; | ||
| } | ||
|
|
||
| $credit_id = filter_var( | ||
| $input['plugin_credit_entities_id'] ?? null, | ||
| FILTER_VALIDATE_INT, | ||
| ['options' => ['min_range' => 1]], | ||
| ); | ||
| if ($credit_id === false) { | ||
| Session::addMessageAfterRedirect( | ||
| __s('Credit voucher entity must be selected.', 'credit'), | ||
| true, | ||
| ERROR, | ||
| ); | ||
| return false; | ||
| } | ||
|
|
||
| $consumed = filter_var( | ||
| $input['consumed'] ?? null, | ||
| FILTER_VALIDATE_INT, | ||
| ['options' => ['min_range' => 1]], | ||
| ); | ||
| if ($consumed === false) { | ||
| Session::addMessageAfterRedirect( | ||
| __s('Credit voucher quantity must be greater than 0.', 'credit'), | ||
| true, | ||
| ERROR, | ||
| ); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Redundant code with prepareInputForUpdate
This logic duplicates functionality already present in prepareInputForUpdate.
It could be refactored into a dedicated checkInput function, or merged into getValidatedConsumptionInput, which should be renamed accordingly to better reflect its broader responsibility.
|
|
||
| - Improve consumed credits modal readability and open related tickets in a new tab | ||
| - Show credit vouchers list in entity tab for read-only users while keeping add/config forms restricted to editable contexts. | ||
| - Centralize credit consumption validation, prevent invalid voucher selections outside the validity window, and fix the ticket tab quantity field behavior. |
There was a problem hiding this comment.
| - Centralize credit consumption validation, prevent invalid voucher selections outside the validity window, and fix the ticket tab quantity field behavior. | |
| - Improve credit validation and voucher handling. |
|
|
||
| use Glpi\Exception\Http\BadRequestHttpException; | ||
|
|
||
| Session::haveRight("ticket", UPDATE); |
There was a problem hiding this comment.
| Session::haveRight("ticket", UPDATE); | |
| Session::checkRight(\Ticket::class, UPDATE); |
| if ($_REQUEST['plugin_credit_entities_id'] == 0) { | ||
| Session::addMessageAfterRedirect( | ||
| __s('Credit voucher entity must be selected.', 'credit'), | ||
| true, | ||
| ERROR, | ||
| ); | ||
| Html::back(); | ||
| } elseif ($_REQUEST['plugin_credit_quantity'] == 0) { | ||
| Session::addMessageAfterRedirect( | ||
| __s('Credit voucher quantity must be greater than 0.', 'credit'), | ||
| true, | ||
| ERROR, | ||
| ); | ||
| Html::back(); |
|
Hi @giovanny07 can you rebase ? |
373344a to
9f28a7f
Compare
|
Hi @stonebuzz, rebased on top of latest |
|
please fix CI |
|
Hi @giovanny07 could you resolve the requests and the CI ? |
|
Hi team! Sorry for the delay, I was on vacation. I've fixed it now. Regards |
|
Let me check tomorrow =) |
stonebuzz
left a comment
There was a problem hiding this comment.
The test checkbox is unchecked, and given that checkInput centralizes logic that was previously scattered and untested, it would be worth adding at least:
- a test for consumeVoucher on an already-solved ticket (this is the exact regression this PR introduces)
- a test for prepareInputForAdd with an out-of-window voucher (begin_date in the future, end_date in the past)
| && !in_array($ticket->fields['status'], array_merge(Ticket::getSolvedStatusArray(), Ticket::getClosedStatusArray())); | ||
| } | ||
|
|
||
| private static function checkInput(array $input, ?self $current_credit = null): array|false |
There was a problem hiding this comment.
| private static function checkInput(array $input, ?self $current_credit = null): array|false | |
| private static function checkInput(array $input, ?self $current_credit = null, bool $skip_status_check = false): array|false |
canUpdateCreditsForTicket returns false for non-entity-admins when the ticket is already solved or closed. consumeVoucher is registered on the item_add hook (setup.php line 74-76). For ITILSolution, GLPI sets the ticket status to "solved" inside ITILSolution::add(), before any item_add hooks fire.
| $ticket = new Ticket(); | ||
| if ( | ||
| !$ticket->getFromDB($ticket_id) | ||
| || !$ticket->can($ticket_id, READ) | ||
| || !self::canUpdateCreditsForTicket($ticket) | ||
| ) { |
There was a problem hiding this comment.
| $ticket = new Ticket(); | |
| if ( | |
| !$ticket->getFromDB($ticket_id) | |
| || !$ticket->can($ticket_id, READ) | |
| || !self::canUpdateCreditsForTicket($ticket) | |
| ) { | |
| $ticket = new Ticket(); | |
| if ( | |
| !$ticket->getFromDB($ticket_id) | |
| || !$ticket->can($ticket_id, READ) | |
| || (!$skip_status_check && !self::canUpdateCreditsForTicket($ticket)) | |
| ) { |
| use Glpi\Exception\Http\BadRequestHttpException; | ||
|
|
||
| Session::haveRight("ticket", UPDATE); | ||
| Session::checkRight(Ticket::class, UPDATE); |
There was a problem hiding this comment.
| Session::checkRight(Ticket::class, UPDATE); | |
| Session::checkRight(\Ticket::class, UPDATE); |
| } | ||
|
|
||
| $input = $validated_input + $input; | ||
| $input['users_id'] = (int) Session::getLoginUserID(); |
There was a problem hiding this comment.
| $input['users_id'] = (int) Session::getLoginUserID(); |
ALready set in front/ticket.form.php line 42
|
Hi @stonebuzz, thanks for the detailed review. Addressed in the latest pushed commit:
On the Local validation done:
I could not run PHPUnit locally because this checkout does not include the GLPI core |
| use Glpi\Exception\Http\BadRequestHttpException; | ||
|
|
||
| Session::haveRight("ticket", UPDATE); | ||
| Session::checkRight(Ticket::class, UPDATE); |
Checklist before requesting a review
Description
This PR centralizes credit consumption validation so both the manual ticket form and the hook-driven followup/task/solution flow
use the same server-side rules. It also prevents selecting vouchers outside their valid begin/end date window and fixes the
ticket-tab JavaScript that broke the quantity field when selecting a voucher.
Validation performed:
find inc front ajax -name '*.php' -print0 | xargs -0 -n1 php -lgit diff --check