This commit is contained in:
Guillermo 2018-10-18 22:30:06 -03:00
parent 4111401518
commit ceb2717bd2
19 changed files with 121 additions and 8 deletions

View File

@ -34,6 +34,7 @@ class TicketViewer extends React.Component {
userId: React.PropTypes.number,
userStaff: React.PropTypes.bool,
userDepartments: React.PropTypes.array,
userLevel: React.PropTypes.number
};
static defaultProps = {
@ -77,7 +78,7 @@ class TicketViewer extends React.Component {
<div className="ticket-viewer__comments">
{ticket.events && ticket.events.map(this.renderTicketEvent.bind(this))}
</div>
{(!this.props.ticket.closed && (this.props.editable || !this.props.assignmentAllowed)) ? this.renderResponseField() : null}
{(!this.props.ticket.closed && (this.props.editable || !this.props.assignmentAllowed)) ? this.renderResponseField() : (this.showDeleteButton())? <Button size="medium" onClick={this.onDeleteTicketClick.bind(this)}>'delete ticket'</Button> : null}
</div>
);
}
@ -226,7 +227,11 @@ class TicketViewer extends React.Component {
{(this.props.allowAttachments) ? <FormField name="file" field="file"/> : null}
<div className="ticket-viewer__response-buttons">
<SubmitButton type="secondary">{i18n('RESPOND_TICKET')}</SubmitButton>
<Button size="medium" onClick={this.onCloseTicketClick.bind(this)}>{i18n('CLOSE_TICKET')}</Button>
<div className="ticket-viewer__response-buttons-secondary">
<Button size="medium" onClick={this.onCloseTicketClick.bind(this)}>{i18n('CLOSE_TICKET')}</Button>
<div></div>
{(this.showDeleteButton())? <Button size="medium" onClick={this.onDeleteTicketClick.bind(this)}>{i18n('DELETE_TICKET')}</Button> : null}
</div>
</div>
</div>
{(this.state.commentError) ? this.renderCommentError() : null}
@ -339,6 +344,10 @@ class TicketViewer extends React.Component {
event.preventDefault();
AreYouSure.openModal(null, this.closeTicket.bind(this));
}
onDeleteTicketClick(event) {
event.preventDefault();
AreYouSure.openModal(null, this.deleteTicket.bind(this));
}
reopenTicket() {
API.call({
@ -357,6 +366,14 @@ class TicketViewer extends React.Component {
}
}).then(this.onTicketModification.bind(this));
}
deleteTicket() {
API.call({
path: '/ticket/delete',
data: {
ticketNumber: this.props.ticket.ticketNumber
}
})
}
changeDepartment(index) {
API.call({
@ -459,6 +476,18 @@ class TicketViewer extends React.Component {
return staffAssignmentItems;
}
showDeleteButton() {
if(!this.props.ticket.owner) {
if(this.props.userLevel == 3) return true;
if(this.props.userId == this.props.ticket.author.id) {
if((this.props.userStaff && this.props.ticket.author.staff) || (!this.props.userStaff && !this.props.ticket.author.staff)){
return true;
}
}
}
return false;
}
}
export default connect((store) => {
@ -469,6 +498,7 @@ export default connect((store) => {
staffMembers: store.adminData.staffMembers,
staffMembersLoaded: store.adminData.staffMembersLoaded,
allowAttachments: store.config['allow-attachments'],
userSystemEnabled: store.config['user-system-enabled']
userSystemEnabled: store.config['user-system-enabled'],
userLevel: store.session.userLevel
};
})(TicketViewer);

View File

@ -94,6 +94,12 @@
display: flex;
justify-content: space-between;
align-items: center;
background-color:blue;
&-secondary {
background-color:blue;
display: flex;
justify-content: space-between;
}
}
}

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Responder',
'RESPOND_TICKET': 'Responder chamado',
'CLOSE_TICKET': 'Fechar ticket',
'DELETE_TICKET': 'Apagar ticket',
'NO_ATTACHMENT': 'Nenhum anexo',
'STAFF': 'Equipe',
'CUSTOMER': 'Cliente',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': '響應',
'RESPOND_TICKET': '響應故障單',
'CLOSE_TICKET': '關門票',
'DELETE_TICKET': '删除票证',
'NO_ATTACHMENT': '沒有文件附件',
'STAFF': '員工',
'CUSTOMER': '顧客',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Antworten',
'RESPOND_TICKET': 'Ticket beantworten',
'CLOSE_TICKET': 'Ticket schließen',
'DELETE_TICKET': 'Ticket löschen',
'NO_ATTACHMENT': 'Keine Dateianlage',
'STAFF': 'Personal',
'CUSTOMER': 'Kunde',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Respond',
'RESPOND_TICKET': 'Respond Ticket',
'CLOSE_TICKET': 'Close ticket',
'DELETE_TICKET': 'Delete ticket',
'NO_ATTACHMENT': 'No file attachment',
'STAFF': 'Staff',
'CUSTOMER': 'Customer',

View File

@ -21,15 +21,16 @@ export default {
'VIEW_ARTICLES': 'Ver Artículos',
'EDIT_PROFILE': 'Editar Perfil',
'CLOSE_SESSION': 'Cerrar sesión',
'CREATE_TICKET': 'Crear Ticket',
'TICKET_LIST': 'Lista de Tickets',
'CREATE_TICKET': 'Crear ticket',
'TICKET_LIST': 'Lista de tickets',
'SUPPORT_CENTER': 'Centro de Soporte',
'DEPARTMENT': 'Departamento',
'AUTHOR': 'Autor',
'DATE': 'Fecha',
'RESPOND': 'Responder',
'RESPOND_TICKET': 'Responder Ticket',
'CLOSE_TICKET': 'Cerrar Ticket',
'RESPOND_TICKET': 'Responder ticket',
'CLOSE_TICKET': 'Cerrar ticket',
'DELETE_TICKET': 'Borrar ticket',
'NO_ATTACHMENT': 'No hay archivo adjunto',
'STAFF': 'Staff',
'CUSTOMER': 'Cliente',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Répondre',
'RESPOND_TICKET': 'Répondre au ticket',
'CLOSE_TICKET': 'Fermer ticket',
'DELETE_TICKET': 'Supprimer le ticket',
'NO_ATTACHMENT': 'Aucune pièce jointe',
'STAFF': 'Administrateur',
'CUSTOMER': 'Client',

View File

@ -30,6 +30,7 @@
'RESPOND': 'Απάντηση',
'RESPOND_TICKET': 'Απάντηση Εισιτηρίου',
'CLOSE_TICKET': 'κλειστό εισιτήριο',
'DELETE_TICKET': 'Διαγραφή εισιτηρίου',
'NO_ATTACHMENT': 'Χωρίς Συνημμένα Αρχεία',
'STAFF': 'Προσωπικό',
'CUSTOMER': 'Πελάτης',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'प्रतिक्रिया',
'RESPOND_TICKET': 'प्रतिक्रिया टिकट',
'CLOSE_TICKET': 'करीबी टिकट',
'DELETE_TICKET': 'टिकट हटाएं',
'NO_ATTACHMENT': 'कोई फ़ाइल अनुलग्नक नहीं',
'STAFF': 'कर्मचारी',
'CUSTOMER': 'ग्राहक',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Rispondi',
'RESPOND_TICKET': 'Rispondi al ticket',
'CLOSE_TICKET': 'Ticket vicino',
'DELETE_TICKET': 'Elimina ticket',
'NO_ATTACHMENT': 'Nessun file allegato',
'STAFF': 'Staff',
'CUSTOMER': 'Customer',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': '応答する',
'RESPOND_TICKET': 'チケット応答',
'CLOSE_TICKET': 'クローズチケット',
'DELETE_TICKET': 'チケットを削除する',
'NO_ATTACHMENT': '添付ファイルがありません',
'STAFF': 'スタッフ',
'CUSTOMER': '顧客',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Actie',
'RESPOND_TICKET': 'Reageren',
'CLOSE_TICKET': 'Sluit ticket',
'DELETE_TICKET': 'Ticket verwijderen',
'NO_ATTACHMENT': 'Geen bijlage',
'STAFF': 'Management',
'CUSTOMER': 'Klant',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Responder',
'RESPOND_TICKET': 'Respond Ticket',
'CLOSE_TICKET': 'Fechar passagem',
'DELETE_TICKET': 'Apagar ticket',
'NO_ATTACHMENT': 'Nenhum anexo de arquivo',
'STAFF': 'Funcionários',
'CUSTOMER': 'Cliente',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Отвечать',
'RESPOND_TICKET': 'Ответить билет',
'CLOSE_TICKET': 'закрыть билет',
'DELETE_TICKET': 'Удалить билет',
'NO_ATTACHMENT': 'Нет вложений файлов',
'STAFF': 'Сотрудники',
'CUSTOMER': 'Клиент',

View File

@ -30,6 +30,7 @@ export default {
'RESPOND': 'Yanıtla',
'RESPOND_TICKET': 'Bilete Gider',
'CLOSE_TICKET': 'Yakın bilet',
'DELETE_TICKET': 'Bilet sil',
'NO_ATTACHMENT': 'Dosya eki yok',
'STAFF': 'Personel',
'CUSTOMER': 'Müşteri',

View File

@ -12,6 +12,7 @@ include 'ticket/close.php';
include 'ticket/re-open.php';
include 'ticket/change-priority.php';
include 'ticket/seen.php';
include 'ticket/delete.php';
$ticketControllers = new ControllerGroup();
$ticketControllers->setGroupPath('/ticket');
@ -29,5 +30,6 @@ $ticketControllers->addController(new CloseController);
$ticketControllers->addController(new ReOpenController);
$ticketControllers->addController(new ChangePriorityController);
$ticketControllers->addController(new SeenController);
$ticketControllers->addController(new DeleteController);
$ticketControllers->finalize();
$ticketControllers->finalize();

View File

@ -0,0 +1,57 @@
<?php
use Respect\Validation\Validator as DataValidator;
DataValidator::with('CustomValidations', true);
/**
* @api {post} /ticket/delete Delete a ticket
* @apiVersion 4.3.0
*
* @apiName Delete ticket
*
* @apiGroup Ticket
*
* @apiDescription This path deletes a ticket.
*
* @apiPermission user
*
* @apiParam {Number} ticketNumber The number of the ticket to delete.
*
* @apiUse NO_PERMISSION
* @apiUse INVALID_TICKET
*
* @apiSuccess {Object} data Empty object
*
*/
class DeleteController extends Controller {
const PATH = '/delete';
const METHOD = 'POST';
public function validations() {
return [
'permission' => 'user',
'requestData' => [
'ticketNumber' => [
'validation' => DataValidator::validTicketNumber(),
'error' => ERRORS::INVALID_TICKET
]
]
];
}
public function handler() {
$user = Controller::getLoggedUser();
$ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
if(Controller::isStaffLogged() && (!$user->level ==3 || $ticket->owner)) {
throw new Exception(ERRORS::NO_PERMISSION);
}
if(!Controller::isStaffLogged() && ($user->name !== $ticket->author->name || $ticket->owner) ) {
throw new Exception(ERRORS::NO_PERMISSION);
}
$ticket->delete();
Response::respondSuccess();
}
}

View File

@ -90,6 +90,10 @@ class Ticket extends DataStore {
parent::store();
}
public function delete() {
parent::delete();
}
public function generateUniqueTicketNumber() {
$linearCongruentialGenerator = new LinearCongruentialGenerator();
$ticketQuantity = Ticket::count();