From 96868abd9289fae4a15d88d3aa325b3757d462fe Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Tue, 17 Jul 2018 01:17:49 -0300 Subject: [PATCH 1/4] Allow tickets to be created by staff members #175 --- server/controllers/ticket/close.php | 19 ++++------ server/controllers/ticket/comment.php | 51 ++++++++++++++------------- server/controllers/ticket/create.php | 7 ++-- server/models/Ticket.php | 36 ++++++++++++++++--- tests/ticket/close.rb | 29 +++++++++++++++ 5 files changed, 97 insertions(+), 45 deletions(-) diff --git a/server/controllers/ticket/close.php b/server/controllers/ticket/close.php index 840654e1..5ba0331c 100755 --- a/server/controllers/ticket/close.php +++ b/server/controllers/ticket/close.php @@ -62,9 +62,12 @@ class CloseController extends Controller { public function handler() { $this->ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber')); - if($this->shouldDenyPermission()) { - Response::respondError(ERRORS::NO_PERMISSION); - return; + if( + (Controller::isUserSystemEnabled() || Controller::isStaffLogged()) && + !$this->ticket->isOwner(Controller::getLoggedUser()) && + !$this->ticket->isAuthor(Controller::getLoggedUser()) + ) { + throw new Exception(ERRORS::NO_PERMISSION); } $this->markAsUnread(); @@ -79,16 +82,6 @@ class CloseController extends Controller { Response::respondSuccess(); } - private function shouldDenyPermission() { - if(Controller::isStaffLogged()) { - return $this->ticket->owner && $this->ticket->owner->id !== Controller::getLoggedUser()->id; - } else if(Controller::isUserSystemEnabled()) { - return $this->ticket->author->id !== Controller::getLoggedUser()->id; - } else { - return false; - } - } - private function markAsUnread() { if(Controller::isStaffLogged()) { $this->ticket->unread = true; diff --git a/server/controllers/ticket/comment.php b/server/controllers/ticket/comment.php index 4319cceb..26e6d623 100755 --- a/server/controllers/ticket/comment.php +++ b/server/controllers/ticket/comment.php @@ -65,7 +65,6 @@ class CommentController extends Controller { 'csrf_token' => [ 'validation' => DataValidator::equals($session->getToken()), 'error' => ERRORS::INVALID_TOKEN - ] ] ]; @@ -73,24 +72,30 @@ class CommentController extends Controller { } public function handler() { - $session = Session::getInstance(); $this->requestData(); + $ticketAuthor = $this->ticket->authorToArray(); + $isAuthor = $this->ticket->isAuthor(Controller::getLoggedUser()); + $isOwner = $this->ticket->isOwner(Controller::getLoggedUser()); - if ((!Controller::isUserSystemEnabled() && !Controller::isStaffLogged()) || - (!Controller::isStaffLogged() && $session->isLoggedWithId(($this->ticket->author) ? $this->ticket->author->id : 0)) || - (Controller::isStaffLogged() && $session->isLoggedWithId(($this->ticket->owner) ? $this->ticket->owner->id : 0))) { - $this->storeComment(); - - if(Controller::isStaffLogged() || $this->ticket->owner) { - $this->sendMail(); - } - - Log::createLog('COMMENT', $this->ticket->ticketNumber); - - Response::respondSuccess(); - } else { - Response::respondError(ERRORS::NO_PERMISSION); + if((Controller::isUserSystemEnabled() || Controller::isStaffLogged()) && !$isOwner && !$isAuthor) { + throw new Exception(ERRORS::NO_PERMISSION); } + + $this->storeComment(); + + if($isAuthor && $this->ticket->owner) { + $this->sendMail([ + 'email' => $this->ticket->owner->email, + 'name' => $this->ticket->owner->name, + 'staff' => true + ]); + } else { + $this->sendMail($ticketAuthor); + } + + Log::createLog('COMMENT', $this->ticket->ticketNumber); + + Response::respondSuccess(); } private function requestData() { @@ -121,20 +126,16 @@ class CommentController extends Controller { $this->ticket->store(); } - private function sendMail() { + private function sendMail($recipient) { $mailSender = MailSender::getInstance(); - $email = ($this->ticket->author) ? $this->ticket->author->email : $this->ticket->authorEmail; - $name = ($this->ticket->author) ? $this->ticket->author->name : $this->ticket->authorName; - - if(!Controller::isStaffLogged() && $this->ticket->owner) { - $email = $this->ticket->owner->email; - $name = $this->ticket->owner->name; - } + $email = $recipient['email']; + $name = $recipient['name']; + $isStaff = $recipient['staff']; $url = Setting::getSetting('url')->getValue(); - if(!Controller::isUserSystemEnabled()) { + if(!Controller::isUserSystemEnabled() && !$isStaff) { $url .= '/check-ticket/' . $this->ticket->ticketNumber; $url .= '/' . $email; } diff --git a/server/controllers/ticket/create.php b/server/controllers/ticket/create.php index 34f252a9..eda86b42 100755 --- a/server/controllers/ticket/create.php +++ b/server/controllers/ticket/create.php @@ -122,7 +122,6 @@ class CreateController extends Controller { 'title' => $this->title, 'content' => $this->content, 'language' => $this->language, - 'author' => $author, 'department' => $department, 'file' => ($fileUploader instanceof FileUploader) ? $fileUploader->getFileName() : null, 'date' => Date::getCurrentDate(), @@ -130,10 +129,12 @@ class CreateController extends Controller { 'unreadStaff' => true, 'closed' => false, 'authorName' => $this->name, - 'authorEmail' => $this->email + 'authorEmail' => $this->email, )); - if(Controller::isUserSystemEnabled()) { + $ticket->setAuthor($author); + + if(Controller::isUserSystemEnabled() && !Controller::isStaffLogged()) { $author->sharedTicketList->add($ticket); $author->tickets++; diff --git a/server/models/Ticket.php b/server/models/Ticket.php index 26993e6b..2c86a2cf 100755 --- a/server/models/Ticket.php +++ b/server/models/Ticket.php @@ -43,6 +43,7 @@ class Ticket extends DataStore { 'closed', 'priority', 'author', + 'authorStaff', 'owner', 'ownTicketeventList', 'unreadStaff', @@ -60,6 +61,22 @@ class Ticket extends DataStore { return Ticket::getTicket($value, 'ticketNumber'); } + public function setAuthor($author) { + if($author instanceof User) { + $this->author = $author; + } else if($author instanceof Staff) { + $this->authorStaff = $author; + } + } + + public function getAuthor() { + if($this->author && !$this->author->isNull()) { + return $this->author; + } else { + return $this->authorStaff; + } + } + public function getDefaultProps() { return array( 'priority' => 'low', @@ -112,18 +129,20 @@ class Ticket extends DataStore { } public function authorToArray() { - $author = $this->author; + $author = $this->getAuthor(); if ($author && !$author->isNull()) { return [ 'id' => $author->id, 'name' => $author->name, + 'staff' => $author instanceof Staff, + 'profilePic' => ($author instanceof Staff) ? $author->profilePic : null, 'email' => $author->email ]; } else { return [ - 'name' => $this->authorName, - 'email' => $this->authorEmail + 'name' => $this->authorName, + 'email' => $this->authorEmail ]; } } @@ -155,7 +174,7 @@ class Ticket extends DataStore { ]; $author = $ticketEvent->getAuthor(); - if(!$author->isNull()) { + if($author && !$author->isNull()) { $event['author'] = [ 'id'=> $author->id, 'name' => $author->name, @@ -174,4 +193,13 @@ class Ticket extends DataStore { public function addEvent(Ticketevent $event) { $this->ownTicketeventList->add($event); } + + public function isAuthor($user) { + $ticketAuthor = $this->authorToArray(); + return $user->id == $ticketAuthor['id'] && ($user instanceof Staff) == $ticketAuthor['staff']; + } + + public function isOwner($user) { + return $this->owner && $user->id == $this->owner->id && ($user instanceof Staff); + } } diff --git a/tests/ticket/close.rb b/tests/ticket/close.rb index 6c7d219d..a8057d6d 100644 --- a/tests/ticket/close.rb +++ b/tests/ticket/close.rb @@ -4,9 +4,32 @@ describe '/ticket/close' do #TODO: DO THINGS + it 'should not close ticket if not assigned' do + ticket = $database.getRow('ticket', 1 , 'id') + request('/staff/un-assign-ticket', { + ticketNumber: ticket['ticket_number'], + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + + result = request('/ticket/close', { + ticketNumber: ticket['ticket_number'], + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + + (result['status']).should.equal('fail') + end + it 'should close a ticket if everything is okey' do ticket = $database.getRow('ticket', 1 , 'id') + request('/staff/assign-ticket', { + ticketNumber: ticket['ticket_number'], + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + result = request('/ticket/close', { ticketNumber: ticket['ticket_number'], csrf_userid: $csrf_userid, @@ -21,5 +44,11 @@ describe '/ticket/close' do lastLog = $database.getLastRow('log') (lastLog['type']).should.equal('CLOSE') + + request('/staff/un-assign-ticket', { + ticketNumber: ticket['ticket_number'], + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) end end From 0a5d444186fb9dd354164b6c47071582c16fedbc Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Tue, 17 Jul 2018 02:04:00 -0300 Subject: [PATCH 2/4] Mark as unread if author is not making the change --- server/controllers/staff/assign-ticket.php | 2 +- server/controllers/staff/un-assign-ticket.php | 2 +- .../controllers/ticket/change-department.php | 2 +- server/controllers/ticket/change-priority.php | 10 +++----- server/controllers/ticket/close.php | 7 ++---- server/controllers/ticket/comment.php | 3 ++- tests/staff/get-new-tickets.rb | 2 +- tests/system/disable-user-system.rb | 2 +- tests/ticket/close.rb | 1 + tests/ticket/comment.rb | 25 +++++++++++++++++++ tests/ticket/create.rb | 20 +++++++++++++++ 11 files changed, 59 insertions(+), 17 deletions(-) diff --git a/server/controllers/staff/assign-ticket.php b/server/controllers/staff/assign-ticket.php index 93af3332..6343a769 100755 --- a/server/controllers/staff/assign-ticket.php +++ b/server/controllers/staff/assign-ticket.php @@ -59,7 +59,7 @@ class AssignStaffController extends Controller { } else { $this->user->sharedTicketList->add($this->ticket); $this->ticket->owner = $this->user; - $this->ticket->unread = true; + $this->ticket->unread = !$this->ticket->isAuthor($this->user); $event = Ticketevent::getEvent(Ticketevent::ASSIGN); $event->setProperties(array( 'authorStaff' => Controller::getLoggedUser(), diff --git a/server/controllers/staff/un-assign-ticket.php b/server/controllers/staff/un-assign-ticket.php index ac1ee06c..95a1b1e9 100755 --- a/server/controllers/staff/un-assign-ticket.php +++ b/server/controllers/staff/un-assign-ticket.php @@ -50,7 +50,7 @@ class UnAssignStaffController extends Controller { $owner->store(); $ticket->owner = null; - $ticket->unread = true; + $ticket->unread = !$ticket->isAuthor($user); $event = Ticketevent::getEvent(Ticketevent::UN_ASSIGN); $event->setProperties(array( diff --git a/server/controllers/ticket/change-department.php b/server/controllers/ticket/change-department.php index 18f83109..7c327466 100755 --- a/server/controllers/ticket/change-department.php +++ b/server/controllers/ticket/change-department.php @@ -64,7 +64,7 @@ class ChangeDepartmentController extends Controller { )); $ticket->addEvent($event); $ticket->department = $department; - $ticket->unread = true; + $ticket->unread = !$ticket->isAuthor($user); $ticket->store(); if(!$user->sharedDepartmentList->includesId($department->id)) { diff --git a/server/controllers/ticket/change-priority.php b/server/controllers/ticket/change-priority.php index cbd2dbc9..3ab57d62 100755 --- a/server/controllers/ticket/change-priority.php +++ b/server/controllers/ticket/change-priority.php @@ -18,9 +18,9 @@ use Respect\Validation\Validator as DataValidator; * * @apiUse NO_PERMISSION * @apiUse INVALID_TICKET - * @apiUse INVALID_PRIORITY + * @apiUse INVALID_PRIORITY * - * @apiSuccess {Object} data Empty object + * @apiSuccess {Object} data Empty object * */ @@ -52,10 +52,10 @@ class ChangePriorityController extends Controller { if($ticket->owner && $user->id === $ticket->owner->id) { $ticket->priority = $priority; - $ticket->unread = true; + $ticket->unread = !$ticket->isAuthor($user); $event = Ticketevent::getEvent(Ticketevent::PRIORITY_CHANGED); $event->setProperties(array( - 'authorStaff' => Controller::getLoggedUser(), + 'authorStaff' => Controller::getLoggedUser(), 'content' => $ticket->priority, 'date' => Date::getCurrentDate() )); @@ -70,5 +70,3 @@ class ChangePriorityController extends Controller { } } - - diff --git a/server/controllers/ticket/close.php b/server/controllers/ticket/close.php index 5ba0331c..c65e5105 100755 --- a/server/controllers/ticket/close.php +++ b/server/controllers/ticket/close.php @@ -83,11 +83,8 @@ class CloseController extends Controller { } private function markAsUnread() { - if(Controller::isStaffLogged()) { - $this->ticket->unread = true; - } else { - $this->ticket->unreadStaff = true; - } + $this->ticket->unread = !$this->ticket->isAuthor(Controller::getLoggedUser()); + $this->ticket->unreadStaff = !$this->ticket->isOwner(Controller::getLoggedUser()); } private function addCloseEvent() { diff --git a/server/controllers/ticket/comment.php b/server/controllers/ticket/comment.php index 26e6d623..3c106f40 100755 --- a/server/controllers/ticket/comment.php +++ b/server/controllers/ticket/comment.php @@ -115,7 +115,8 @@ class CommentController extends Controller { )); if(Controller::isStaffLogged()) { - $this->ticket->unread = true; + $this->ticket->unread = !$this->ticket->isAuthor(Controller::getLoggedUser()); + $this->ticket->unreadStaff = !$this->ticket->isOwner(Controller::getLoggedUser()); $comment->authorStaff = Controller::getLoggedUser(); } else if(Controller::isUserSystemEnabled()) { $this->ticket->unreadStaff = true; diff --git a/tests/staff/get-new-tickets.rb b/tests/staff/get-new-tickets.rb index 1d7caa1f..be095a41 100644 --- a/tests/staff/get-new-tickets.rb +++ b/tests/staff/get-new-tickets.rb @@ -10,6 +10,6 @@ describe '/staff/get-new-tickets' do }) (result['status']).should.equal('success') - (result['data'].size).should.equal(9) + (result['data'].size).should.equal(10) end end diff --git a/tests/system/disable-user-system.rb b/tests/system/disable-user-system.rb index b43a28da..0e13120a 100644 --- a/tests/system/disable-user-system.rb +++ b/tests/system/disable-user-system.rb @@ -92,7 +92,7 @@ describe'system/disable-user-system' do numberOftickets= $database.query("SELECT * FROM ticket WHERE author_email IS NULL AND author_name IS NULL AND author_id IS NOT NULL" ) - (numberOftickets.num_rows).should.equal(39) + (numberOftickets.num_rows).should.equal(40) end diff --git a/tests/ticket/close.rb b/tests/ticket/close.rb index f010ac7d..e8ea1a0f 100644 --- a/tests/ticket/close.rb +++ b/tests/ticket/close.rb @@ -34,6 +34,7 @@ describe '/ticket/close' do csrf_token: $csrf_token }) + puts result (result['status']).should.equal('success') ticket = $database.getRow('ticket', 1 , 'id') diff --git a/tests/ticket/comment.rb b/tests/ticket/comment.rb index fe1dfb97..d522198f 100644 --- a/tests/ticket/comment.rb +++ b/tests/ticket/comment.rb @@ -78,6 +78,31 @@ describe '/ticket/comment/' do (lastLog['type']).should.equal('COMMENT') end + it 'should add comment to ticket created by staff' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + result = request('/ticket/comment', { + content: 'some comment content', + ticketNumber: $ticketNumberByStaff, + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + + (result['status']).should.equal('success') + + ticket = $database.getRow('ticket', $ticketNumberByStaff, 'ticket_number') + comment = $database.getRow('ticketevent', ticket['id'], 'ticket_id') + (comment['content']).should.equal('some comment content') + (comment['type']).should.equal('COMMENT') + (comment['author_staff_id']).should.equal($csrf_userid) + (ticket['unread_staff']).should.equal('1') + + lastLog = $database.getLastRow('log') + (lastLog['type']).should.equal('COMMENT') + + request('/user/logout') + end + it 'should fail if user is not the author nor owner' do Scripts.createUser('no_commenter@comment.com', 'no_commenter', 'No Commenter') Scripts.login('no_commenter@comment.com', 'no_commenter') diff --git a/tests/ticket/create.rb b/tests/ticket/create.rb index 61054a29..8d090586 100644 --- a/tests/ticket/create.rb +++ b/tests/ticket/create.rb @@ -144,4 +144,24 @@ describe '/ticket/create' do (ticket2).should.equal((ticket0 - 100000 + 2 * ticket_number_gap) % 900000 + 100000) (ticket3).should.equal((ticket0 - 100000 + 3 * ticket_number_gap) % 900000 + 100000) end + + it 'should be able to create a ticket while being staff' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + result = request('/ticket/create', { + title: 'created by staff', + content: 'The staff created it', + departmentId: 1, + language: 'en', + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + (result['status']).should.equal('success') + ticket = $database.getRow('ticket', result['data']['ticketNumber'], 'ticket_number') + (ticket['author_id']).should.equal(nil) + (ticket['author_staff_id']).should.equal('1') + + $ticketNumberByStaff = result['data']['ticketNumber'] + request('/user/logout') + end end From cd2e1cd3df0910a198b34b908cbe7a910e61100a Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Tue, 17 Jul 2018 23:18:51 -0300 Subject: [PATCH 3/4] Add create ticket option for staff members --- client/src/app-components/ticket-list.js | 11 ++++++- client/src/app-components/ticket-viewer.js | 24 ++++++++++++--- .../src/app/admin/panel/staff/staff-editor.js | 1 + .../panel/tickets/admin-panel-all-tickets.js | 3 ++ .../panel/tickets/admin-panel-my-tickets.js | 30 ++++++++++++++++++- .../panel/tickets/admin-panel-new-tickets.js | 3 ++ .../panel/tickets/admin-panel-view-ticket.js | 9 ++++-- .../create-ticket-form.js | 16 ++++------ .../dashboard-create-ticket-page.js | 15 +++++++++- server/controllers/staff/get-new-tickets.php | 8 ++--- server/controllers/staff/un-assign-ticket.php | 8 +++-- server/controllers/ticket/create.php | 8 +++-- server/controllers/ticket/seen.php | 26 ++++++++-------- 13 files changed, 119 insertions(+), 43 deletions(-) diff --git a/client/src/app-components/ticket-list.js b/client/src/app-components/ticket-list.js index 18293252..c3d95be4 100644 --- a/client/src/app-components/ticket-list.js +++ b/client/src/app-components/ticket-list.js @@ -17,6 +17,7 @@ class TicketList extends React.Component { ticketPath: React.PropTypes.string, showDepartmentDropdown: React.PropTypes.bool, tickets: React.PropTypes.arrayOf(React.PropTypes.object), + userId: React.PropTypes.number, type: React.PropTypes.oneOf([ 'primary', 'secondary' @@ -233,7 +234,15 @@ class TicketList extends React.Component { } isTicketUnread(ticket) { - return (this.props.type === 'primary' && ticket.unread) || (this.props.type === 'secondary' && ticket.unreadStaff); + if(this.props.type === 'primary') { + return ticket.unread; + } else if(this.props.type === 'secondary') { + if(ticket.author.id == this.props.userId && ticket.author.staff) { + return ticket.unread; + } else { + return ticket.unreadStaff; + } + } } } diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 14476b21..65cd7aa9 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -99,7 +99,7 @@ class TicketViewer extends React.Component {
{i18n('PRIORITY')}
-
{i18n('OWNED')}
+
{i18n('OWNER')}
{i18n('STATUS')}
@@ -107,9 +107,7 @@ class TicketViewer extends React.Component {
- + {this.renderEditableOwnerNode()}
+ ); + } else { + ownerNode = (this.props.ticket.owner) ? this.props.ticket.owner.name : i18n('NONE') + } + + return ownerNode; + } + renderOwnerNode() { let ownerNode = null; @@ -358,6 +373,7 @@ class TicketViewer extends React.Component { export default connect((store) => { return { + userId: store.session.userId, allowAttachments: store.config['allow-attachments'], userSystemEnabled: store.config['user-system-enabled'] }; diff --git a/client/src/app/admin/panel/staff/staff-editor.js b/client/src/app/admin/panel/staff/staff-editor.js index 4bcc171a..65b65d01 100644 --- a/client/src/app/admin/panel/staff/staff-editor.js +++ b/client/src/app/admin/panel/staff/staff-editor.js @@ -235,6 +235,7 @@ class StaffEditor extends React.Component { getTicketListProps() { return { type: 'secondary', + userId: this.props.staffId, tickets: this.props.tickets, departments: this.props.departments, ticketPath: '/admin/panel/tickets/view-ticket/' diff --git a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js index 1f7f6cc2..e6eec7d0 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js @@ -13,6 +13,7 @@ import Message from 'core-components/message'; class AdminPanelAllTickets extends React.Component { static defaultProps = { + userId: 0, departments: [], tickets: [] }; @@ -40,6 +41,7 @@ class AdminPanelAllTickets extends React.Component { getTicketListProps() { return { + userId: this.props.userId, showDepartmentDropdown: false, departments: this.props.departments, tickets: this.props.tickets, @@ -75,6 +77,7 @@ class AdminPanelAllTickets extends React.Component { export default connect((store) => { return { + userId: store.session.userId, departments: store.session.userDepartments, tickets: store.adminData.allTickets, pages: store.adminData.allTicketsPages, diff --git a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js index e90847ec..caed8aaf 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js @@ -5,13 +5,18 @@ import i18n from 'lib-app/i18n'; import AdminDataAction from 'actions/admin-data-actions'; import TicketList from 'app-components/ticket-list'; +import ModalContainer from 'app-components/modal-container'; +import CreateTicketForm from 'app/main/dashboard/dashboard-create-ticket/create-ticket-form'; +import Button from 'core-components/button'; +import Icon from 'core-components/icon'; import Header from 'core-components/header'; import Message from 'core-components/message'; class AdminPanelMyTickets extends React.Component { static defaultProps = { + userId: 0, departments: [], tickets: [] }; @@ -19,18 +24,24 @@ class AdminPanelMyTickets extends React.Component { componentDidMount() { this.props.dispatch(AdminDataAction.retrieveMyTickets()); } - + render() { return (
{(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : } +
+ +
); } getProps() { return { + userId: this.props.userId, departments: this.props.departments, tickets: this.props.tickets, type: 'secondary', @@ -38,10 +49,27 @@ class AdminPanelMyTickets extends React.Component { ticketPath: '/admin/panel/tickets/view-ticket/' }; } + + onCreateTicket() { + ModalContainer.openModal( +
+ +
+ +
+
+ ); + } + + onCreateTicketSuccess() { + ModalContainer.closeModal(); + this.props.dispatch(AdminDataAction.retrieveMyTickets()); + } } export default connect((store) => { return { + userId: store.session.userId, departments: store.session.userDepartments, tickets: store.adminData.myTickets, loading: !store.adminData.myTicketsLoaded, diff --git a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js index bb3240cb..185a3656 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js @@ -12,6 +12,7 @@ import Message from 'core-components/message'; class AdminPanelNewTickets extends React.Component { static defaultProps = { + userId: 0, departments: [], tickets: [] }; @@ -31,6 +32,7 @@ class AdminPanelNewTickets extends React.Component { getProps() { return { + userId: this.props.userId, departments: this.props.departments, tickets: this.props.tickets, type: 'secondary', @@ -42,6 +44,7 @@ class AdminPanelNewTickets extends React.Component { export default connect((store) => { return { + userId: store.session.userId, departments: store.session.userDepartments, tickets: store.adminData.newTickets, loading: !store.adminData.newTicketsLoaded, diff --git a/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js index 320c1809..83566c0c 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js +++ b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js @@ -75,7 +75,10 @@ class AdminPanelViewTicket extends React.Component { onChange: this.retrieveTicket.bind(this), assignmentAllowed: this.props.assignmentAllowed, customResponses: this.props.customResponses, - editable: this.state.ticket.owner && this.state.ticket.owner.id == SessionStore.getSessionData().userId + editable: ( + (this.state.ticket.owner && this.state.ticket.owner.id == SessionStore.getSessionData().userId) || + (this.state.ticket.author && this.state.ticket.author.staff && this.state.ticket.author.id == SessionStore.getSessionData().userId) + ) }; } @@ -94,7 +97,7 @@ class AdminPanelViewTicket extends React.Component { ticket: result.data }); - if(!this.props.avoidSeen && result.data.unreadStaff) { + if(!this.props.avoidSeen) { API.call({ path: '/ticket/seen', data: { @@ -109,7 +112,7 @@ class AdminPanelViewTicket extends React.Component { loading: false, ticket: {} }); - + if(this.props.onRetrieveFail) { this.props.onRetrieveFail(); } diff --git a/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js b/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js index aa8f2d68..d4859a08 100644 --- a/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js +++ b/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js @@ -6,8 +6,6 @@ import history from 'lib-app/history'; import i18n from 'lib-app/i18n'; import API from 'lib-app/api-call'; import SessionStore from 'lib-app/session-store'; -import store from 'app/store'; -import SessionActions from 'actions/session-actions'; import LanguageSelector from 'app-components/language-selector'; import Captcha from 'app/main/captcha'; @@ -21,7 +19,8 @@ import Message from 'core-components/message'; class CreateTicketForm extends React.Component { static propTypes = { - userLogged: React.PropTypes.bool + userLogged: React.PropTypes.bool, + onSuccess: React.PropTypes.func, }; static defaultProps = { @@ -138,14 +137,11 @@ class CreateTicketForm extends React.Component { this.setState({ loading: false, message: 'success' + }, () => { + if(this.props.onSuccess) { + this.props.onSuccess(); + } }); - - if(this.props.userLogged) { - store.dispatch(SessionActions.getUserData()); - setTimeout(() => {history.push('/dashboard')}, 2000); - } else { - setTimeout(() => {history.push('/check-ticket/' + result.data.ticketNumber + '/' + email)}, 1000); - } } onTicketFail() { diff --git a/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js b/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js index 81c4d6e8..817ff25f 100644 --- a/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js +++ b/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js @@ -2,7 +2,9 @@ import React from 'react'; import classNames from 'classnames'; import {connect} from 'react-redux'; +import SessionActions from 'actions/session-actions'; import CreateTicketForm from 'app/main/dashboard/dashboard-create-ticket/create-ticket-form'; + import Widget from 'core-components/widget'; class DashboardCreateTicketPage extends React.Component { @@ -21,12 +23,23 @@ class DashboardCreateTicketPage extends React.Component { return (
- +
); } + onCreateTicketSuccess() { + if((this.props.location.pathname !== '/create-ticket')) { + this.props.dispatch(SessionActions.getUserData()); + setTimeout(() => {history.push('/dashboard')}, 2000); + } else { + setTimeout(() => {history.push('/check-ticket/' + result.data.ticketNumber + '/' + email)}, 1000); + } + } + getClass() { let classes = { 'dashboard-create-ticket-page': true, diff --git a/server/controllers/staff/get-new-tickets.php b/server/controllers/staff/get-new-tickets.php index b0e2e6e2..5289edd3 100755 --- a/server/controllers/staff/get-new-tickets.php +++ b/server/controllers/staff/get-new-tickets.php @@ -15,7 +15,7 @@ use Respect\Validation\Validator as DataValidator; * @apiPermission staff1 * * @apiUse NO_PERMISSION - * + * * @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data Array of new tickets. * */ @@ -41,13 +41,13 @@ class GetNewTicketsStaffController extends Controller { foreach ($user->sharedDepartmentList as $department) { $query .= 'department_id=' . $department->id . ' OR '; } - $query = substr($query,0,-3); + $ownerExists = RedBean::exec('SHOW COLUMNS FROM ticket LIKE \'owner_id\''); if($ownerExists != 0) { - $query .= ') AND owner_id IS NULL'; + $query .= 'FALSE) AND owner_id IS NULL'; } else { - $query .= ')'; + $query .= 'FALSE)'; } $ticketList = Ticket::find($query); diff --git a/server/controllers/staff/un-assign-ticket.php b/server/controllers/staff/un-assign-ticket.php index 95a1b1e9..070c8db9 100755 --- a/server/controllers/staff/un-assign-ticket.php +++ b/server/controllers/staff/un-assign-ticket.php @@ -45,9 +45,11 @@ class UnAssignStaffController extends Controller { $ticket = Ticket::getByTicketNumber($ticketNumber); $owner = $ticket->owner; - if(($owner && $owner->id === $user->id) || $user->level > 1) { - $owner->sharedTicketList->remove($ticket); - $owner->store(); + if($ticket->isOwner($user) || $user->level > 1) { + if(!$ticket->isAuthor($user)) { + $owner->sharedTicketList->remove($ticket); + $owner->store(); + } $ticket->owner = null; $ticket->unread = !$ticket->isAuthor($user); diff --git a/server/controllers/ticket/create.php b/server/controllers/ticket/create.php index eda86b42..5e6e9600 100755 --- a/server/controllers/ticket/create.php +++ b/server/controllers/ticket/create.php @@ -134,16 +134,18 @@ class CreateController extends Controller { $ticket->setAuthor($author); - if(Controller::isUserSystemEnabled() && !Controller::isStaffLogged()) { + if(Controller::isUserSystemEnabled() || Controller::isStaffLogged()) { $author->sharedTicketList->add($ticket); + } + + if(Controller::isUserSystemEnabled() && !Controller::isStaffLogged()) { $author->tickets++; $this->email = $author->email; $this->name = $author->name; - - $author->store(); } + $author->store(); $ticket->store(); $this->ticketNumber = $ticket->ticketNumber; diff --git a/server/controllers/ticket/seen.php b/server/controllers/ticket/seen.php index c5693141..0f79d1c3 100755 --- a/server/controllers/ticket/seen.php +++ b/server/controllers/ticket/seen.php @@ -43,20 +43,20 @@ class SeenController extends Controller { $ticketnumber = Controller::request('ticketNumber'); $user = Controller::getLoggedUser(); $ticket = Ticket::getByTicketNumber($ticketnumber); - - if (Controller::isStaffLogged() && $ticket->owner && $ticket->owner->id === $user->id) { + + if(!$ticket->isOwner($user) && !$ticket->isAuthor($user)) { + throw new Exception(ERRORS::NO_PERMISSION); + } + + if ($ticket->isOwner($user)) { $ticket->unreadStaff = false; - $ticket->store(); - Response::respondSuccess(); - return; } - if (!Controller::isStaffLogged() && $ticket->author && $user->id === $ticket->author->id) { - $ticket->unread = false; - $ticket->store(); - Response::respondSuccess(); - return; + if ($ticket->isAuthor($user)) { + $ticket->unread = false; } - Response::respondError(ERRORS::NO_PERMISSION); - + + $ticket->store(); + + Response::respondSuccess(); } -} \ No newline at end of file +} From 0b38addd581f76806af4f6111d5ef0cb100fdeda Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 19 Jul 2018 18:09:54 -0300 Subject: [PATCH 4/4] Update ruby tests --- tests/staff/get-all.rb | 2 +- tests/staff/get-tickets.rb | 4 ++-- tests/staff/un-assign-ticket.rb | 4 ++-- tests/ticket/close.rb | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/staff/get-all.rb b/tests/staff/get-all.rb index 07f76825..03aae0d3 100644 --- a/tests/staff/get-all.rb +++ b/tests/staff/get-all.rb @@ -20,7 +20,7 @@ describe'/staff/get-all' do (result['data'][0]['departments'][1]['name']).should.equal('Suggestions') (result['data'][0]['departments'][2]['id']).should.equal('3') (result['data'][0]['departments'][2]['name']).should.equal('Tech support') - (result['data'][0]['assignedTickets']).should.equal(3) + (result['data'][0]['assignedTickets']).should.equal(4) (result['data'][0]['closedTickets']).should.equal(0) (result['data'][2]['name']).should.equal('Arya Stark') diff --git a/tests/staff/get-tickets.rb b/tests/staff/get-tickets.rb index e06d214e..cd896a6b 100644 --- a/tests/staff/get-tickets.rb +++ b/tests/staff/get-tickets.rb @@ -22,6 +22,6 @@ describe '/staff/get-tickets' do }) (result['status']).should.equal('success') - (result['data'].size).should.equal(2) + (result['data'].size).should.equal(3) end -end \ No newline at end of file +end diff --git a/tests/staff/un-assign-ticket.rb b/tests/staff/un-assign-ticket.rb index 4685d7ae..91f1b436 100644 --- a/tests/staff/un-assign-ticket.rb +++ b/tests/staff/un-assign-ticket.rb @@ -23,7 +23,7 @@ describe '/staff/un-assign-ticket' do (ticket['owner_id']).should.equal(nil) (ticket['unread']).should.equal('1') - staff_ticket = $database.getRow('staff_ticket', 1 , 'id') + staff_ticket = $database.getRow('staff_ticket', 1 , 'ticket_id') (staff_ticket).should.equal(nil) end @@ -75,7 +75,7 @@ describe '/staff/un-assign-ticket' do (ticket['owner_id']).should.equal(nil) (ticket['unread']).should.equal('1') - staff_ticket = $database.getRow('staff_ticket', 1 , 'id') + staff_ticket = $database.getRow('staff_ticket', 1 , 'ticket_id') (staff_ticket).should.equal(nil) end diff --git a/tests/ticket/close.rb b/tests/ticket/close.rb index e8ea1a0f..f010ac7d 100644 --- a/tests/ticket/close.rb +++ b/tests/ticket/close.rb @@ -34,7 +34,6 @@ describe '/ticket/close' do csrf_token: $csrf_token }) - puts result (result['status']).should.equal('success') ticket = $database.getRow('ticket', 1 , 'id')