First commit waiting for Budget Alert
This commit is contained in:
16
modules/axelor-open-suite/axelor-helpdesk/build.gradle
Normal file
16
modules/axelor-open-suite/axelor-helpdesk/build.gradle
Normal file
@ -0,0 +1,16 @@
|
||||
apply plugin: "com.axelor.app-module"
|
||||
|
||||
apply from: "../version.gradle"
|
||||
|
||||
apply {
|
||||
version = openSuiteVersion
|
||||
}
|
||||
|
||||
axelor {
|
||||
title "Axelor Helpdesk"
|
||||
description "Axelor Helpdesk Module"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":modules:axelor-base")
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.db.repo;
|
||||
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import com.axelor.apps.helpdesk.service.TicketService;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class TicketManagementRepository extends TicketRepository {
|
||||
|
||||
@Inject private TicketService ticketService;
|
||||
|
||||
@Override
|
||||
public Ticket save(Ticket ticket) {
|
||||
|
||||
ticketService.computeSeq(ticket);
|
||||
ticketService.computeSLA(ticket);
|
||||
ticketService.checkSLAcompleted(ticket);
|
||||
return super.save(ticket);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.exceptions;
|
||||
|
||||
public interface IExceptionMessage {
|
||||
|
||||
public static final String SELECT_TICKETS = /*$$(*/ "Please select tickets" /*)*/;
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.module;
|
||||
|
||||
import com.axelor.app.AxelorModule;
|
||||
import com.axelor.apps.base.service.MailServiceBaseImpl;
|
||||
import com.axelor.apps.helpdesk.db.repo.TicketManagementRepository;
|
||||
import com.axelor.apps.helpdesk.db.repo.TicketRepository;
|
||||
import com.axelor.apps.helpdesk.service.MailServiceHelpDeskImpl;
|
||||
import com.axelor.apps.helpdesk.service.TicketService;
|
||||
import com.axelor.apps.helpdesk.service.TicketServiceImpl;
|
||||
import com.axelor.apps.helpdesk.service.TimerTicketService;
|
||||
import com.axelor.apps.helpdesk.service.TimerTicketServiceImpl;
|
||||
|
||||
public class HelpdeskModule extends AxelorModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
bind(TicketRepository.class).to(TicketManagementRepository.class);
|
||||
bind(TicketService.class).to(TicketServiceImpl.class);
|
||||
bind(MailServiceBaseImpl.class).to(MailServiceHelpDeskImpl.class);
|
||||
bind(TimerTicketService.class).to(TimerTicketServiceImpl.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.service;
|
||||
|
||||
import com.axelor.apps.base.service.MailServiceBaseImpl;
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import com.axelor.db.Model;
|
||||
import com.axelor.mail.db.MailMessage;
|
||||
import com.google.common.base.Strings;
|
||||
import java.io.IOException;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
public class MailServiceHelpDeskImpl extends MailServiceBaseImpl {
|
||||
|
||||
@Override
|
||||
protected String getSubject(MailMessage message, Model entity) {
|
||||
if (!(Ticket.class.isInstance(entity))) {
|
||||
return super.getSubject(message, entity);
|
||||
}
|
||||
Ticket ticket = (Ticket) entity;
|
||||
if (!Strings.isNullOrEmpty(ticket.getMailSubject())) {
|
||||
return ticket.getMailSubject();
|
||||
}
|
||||
return super.getSubject(message, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MailMessage messageReceived(MimeMessage email) throws MessagingException, IOException {
|
||||
MailMessage message = super.messageReceived(email);
|
||||
|
||||
Document doc = Jsoup.parse(message.getBody());
|
||||
doc.select("div.gmail_extra").remove();
|
||||
message.setBody(doc.outerHtml());
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.service;
|
||||
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import java.util.List;
|
||||
|
||||
public interface TicketService {
|
||||
|
||||
public void computeSeq(Ticket ticket);
|
||||
|
||||
public void computeSLA(Ticket ticket);
|
||||
|
||||
public void checkSLAcompleted(Ticket ticket);
|
||||
|
||||
public void assignToMeTicket(Long id, List<?> ids);
|
||||
}
|
||||
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.service;
|
||||
|
||||
import com.axelor.apps.base.db.AppHelpdesk;
|
||||
import com.axelor.apps.base.db.Company;
|
||||
import com.axelor.apps.base.db.repo.AppHelpdeskRepository;
|
||||
import com.axelor.apps.base.db.repo.SequenceRepository;
|
||||
import com.axelor.apps.base.service.administration.SequenceService;
|
||||
import com.axelor.apps.base.service.publicHoliday.PublicHolidayService;
|
||||
import com.axelor.apps.base.service.weeklyplanning.WeeklyPlanningService;
|
||||
import com.axelor.apps.helpdesk.db.Sla;
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import com.axelor.apps.helpdesk.db.repo.SlaRepository;
|
||||
import com.axelor.apps.helpdesk.db.repo.TicketRepository;
|
||||
import com.axelor.auth.AuthUtils;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public class TicketServiceImpl implements TicketService {
|
||||
|
||||
@Inject private SequenceService sequenceService;
|
||||
|
||||
@Inject private AppHelpdeskRepository appHelpdeskRepo;
|
||||
|
||||
@Inject private TicketRepository ticketRepo;
|
||||
|
||||
@Inject private SlaRepository slaRepo;
|
||||
|
||||
@Inject private PublicHolidayService publicHolidayService;
|
||||
|
||||
@Inject private WeeklyPlanningService weeklyPlanningService;
|
||||
|
||||
private LocalDateTime toDate;
|
||||
|
||||
/** Generate sequence of the ticket. */
|
||||
@Override
|
||||
public void computeSeq(Ticket ticket) {
|
||||
|
||||
if (Strings.isNullOrEmpty(ticket.getTicketSeq())) {
|
||||
String ticketSeq = sequenceService.getSequenceNumber(SequenceRepository.TICKET, null);
|
||||
ticket.setTicketSeq(ticketSeq);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finding SLA, apply on ticket & Calculate the deadline of the ticket based on days & hours which
|
||||
* is defined in SLA.
|
||||
*/
|
||||
@Override
|
||||
public void computeSLA(Ticket ticket) {
|
||||
|
||||
AppHelpdesk helpdesk = appHelpdeskRepo.all().fetchOne();
|
||||
|
||||
if (helpdesk.getIsSla()) {
|
||||
|
||||
Sla sla =
|
||||
slaRepo
|
||||
.all()
|
||||
.filter(
|
||||
"self.team = ?1 AND self.prioritySelect = ?2 AND self.ticketType = ?3",
|
||||
ticket.getAssignedToUser() == null
|
||||
? null
|
||||
: ticket.getAssignedToUser().getActiveTeam(),
|
||||
ticket.getPrioritySelect(),
|
||||
ticket.getTicketType())
|
||||
.fetchOne();
|
||||
|
||||
if (sla == null) {
|
||||
sla =
|
||||
slaRepo
|
||||
.all()
|
||||
.filter(
|
||||
"self.team = ?1 AND self.prioritySelect = ?2 AND self.ticketType = null OR "
|
||||
+ "(self.team = null AND self.prioritySelect = ?2 AND self.ticketType = ?3) OR "
|
||||
+ "(self.team = ?1 AND self.prioritySelect = null AND self.ticketType = ?3)",
|
||||
ticket.getAssignedToUser() == null
|
||||
? null
|
||||
: ticket.getAssignedToUser().getActiveTeam(),
|
||||
ticket.getPrioritySelect(),
|
||||
ticket.getTicketType())
|
||||
.fetchOne();
|
||||
}
|
||||
if (sla == null) {
|
||||
sla =
|
||||
slaRepo
|
||||
.all()
|
||||
.filter(
|
||||
"self.team = ?1 AND self.prioritySelect = null AND self.ticketType = null OR "
|
||||
+ "(self.team = null AND self.prioritySelect = ?2 AND self.ticketType = null) OR "
|
||||
+ "(self.team = null AND self.prioritySelect = null AND self.ticketType = ?3)",
|
||||
ticket.getAssignedToUser() == null
|
||||
? null
|
||||
: ticket.getAssignedToUser().getActiveTeam(),
|
||||
ticket.getPrioritySelect(),
|
||||
ticket.getTicketType())
|
||||
.fetchOne();
|
||||
}
|
||||
if (sla == null) {
|
||||
sla =
|
||||
slaRepo
|
||||
.all()
|
||||
.filter(
|
||||
"self.team = null AND self.prioritySelect = null AND self.ticketType = null")
|
||||
.fetchOne();
|
||||
}
|
||||
if (sla != null) {
|
||||
ticket.setSlaPolicy(sla);
|
||||
try {
|
||||
this.computeDuration(ticket, sla);
|
||||
} catch (AxelorException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
|
||||
ticket.setSlaPolicy(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate deadline date & time of the ticket.
|
||||
*
|
||||
* @param ticket
|
||||
* @param sla
|
||||
* @throws AxelorException
|
||||
*/
|
||||
private void computeDuration(Ticket ticket, Sla sla) throws AxelorException {
|
||||
|
||||
if (sla.getIsWorkingDays()
|
||||
&& ticket.getAssignedToUser() != null
|
||||
&& ticket.getAssignedToUser().getActiveCompany() != null
|
||||
&& ticket.getAssignedToUser().getActiveCompany().getWeeklyPlanning() != null
|
||||
&& ticket.getAssignedToUser().getActiveCompany().getPublicHolidayEventsPlanning() != null) {
|
||||
|
||||
if (sla.getDays() > 0) {
|
||||
LocalDateTime fromDate = ticket.getStartDateT().plusDays(1);
|
||||
this.calculateWorkingDays(
|
||||
fromDate, ticket.getAssignedToUser().getActiveCompany(), sla.getDays());
|
||||
ticket.setDeadlineDateT(toDate.plusHours(sla.getHours()));
|
||||
|
||||
} else {
|
||||
ticket.setDeadlineDateT(ticket.getStartDateT().plusHours(sla.getHours()));
|
||||
}
|
||||
} else {
|
||||
this.calculateAllDays(ticket, sla);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate deadline date & time based on all days if workingDays field in SLA is not checked.
|
||||
*
|
||||
* @param ticket
|
||||
* @param sla
|
||||
*/
|
||||
private void calculateAllDays(Ticket ticket, Sla sla) {
|
||||
LocalDateTime localDateTime = ticket.getStartDateT().plusDays(sla.getDays());
|
||||
localDateTime = localDateTime.plusHours(sla.getHours());
|
||||
ticket.setDeadlineDateT(localDateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate deadline date & time based on only working days if workingDays field in SLA is
|
||||
* checked.
|
||||
*
|
||||
* @param fromDate
|
||||
* @param employee
|
||||
* @param days
|
||||
* @throws AxelorException
|
||||
*/
|
||||
private void calculateWorkingDays(LocalDateTime fromDate, Company company, int days)
|
||||
throws AxelorException {
|
||||
|
||||
if (weeklyPlanningService.getWorkingDayValueInDays(
|
||||
company.getWeeklyPlanning(), fromDate.toLocalDate())
|
||||
== 0
|
||||
|| publicHolidayService.checkPublicHolidayDay(
|
||||
fromDate.toLocalDate(), company.getPublicHolidayEventsPlanning())) {
|
||||
|
||||
fromDate = fromDate.plusDays(1);
|
||||
this.calculateWorkingDays(fromDate, company, days);
|
||||
|
||||
} else {
|
||||
toDate = fromDate;
|
||||
days--;
|
||||
if (days != 0) {
|
||||
fromDate = fromDate.plusDays(1);
|
||||
this.calculateWorkingDays(fromDate, company, days);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Check if SLA is completed or not. */
|
||||
@Override
|
||||
public void checkSLAcompleted(Ticket ticket) {
|
||||
|
||||
if (ticket.getSlaPolicy() != null) {
|
||||
LocalDateTime currentDate = LocalDateTime.now();
|
||||
LocalDateTime deadlineDateT = ticket.getDeadlineDateT();
|
||||
|
||||
ticket.setIsSlaCompleted(
|
||||
ticket.getStatusSelect() >= ticket.getSlaPolicy().getReachStageSelect()
|
||||
&& (currentDate.isBefore(deadlineDateT) || currentDate.isEqual(deadlineDateT)));
|
||||
}
|
||||
}
|
||||
|
||||
/** Ticket assign to the current user. */
|
||||
@Override
|
||||
@Transactional
|
||||
public void assignToMeTicket(Long id, List<?> ids) {
|
||||
|
||||
if (id != null) {
|
||||
Ticket ticket = ticketRepo.find(id);
|
||||
ticket.setAssignedToUser(AuthUtils.getUser());
|
||||
ticketRepo.save(ticket);
|
||||
|
||||
} else if (!ids.isEmpty()) {
|
||||
|
||||
for (Ticket ticket : ticketRepo.all().filter("id in ?1", ids).fetch()) {
|
||||
ticket.setAssignedToUser(AuthUtils.getUser());
|
||||
ticketRepo.save(ticket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.service;
|
||||
|
||||
import com.axelor.apps.base.db.Timer;
|
||||
import com.axelor.apps.base.db.TimerHistory;
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public interface TimerTicketService {
|
||||
|
||||
Timer find(Ticket ticket) throws AxelorException;
|
||||
|
||||
TimerHistory start(Ticket task, LocalDateTime dateTime) throws AxelorException;
|
||||
|
||||
TimerHistory stop(Ticket task, LocalDateTime dateTime) throws AxelorException;
|
||||
|
||||
void cancel(Ticket task) throws AxelorException;
|
||||
|
||||
Duration compute(Ticket task);
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.service;
|
||||
|
||||
import com.axelor.apps.base.db.Timer;
|
||||
import com.axelor.apps.base.db.TimerHistory;
|
||||
import com.axelor.apps.base.db.repo.TimerHistoryRepository;
|
||||
import com.axelor.apps.base.db.repo.TimerRepository;
|
||||
import com.axelor.apps.base.service.timer.AbstractTimerService;
|
||||
import com.axelor.apps.base.service.user.UserService;
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import com.axelor.apps.helpdesk.db.repo.TicketRepository;
|
||||
import com.axelor.auth.db.User;
|
||||
import com.axelor.db.Model;
|
||||
import com.axelor.exception.AxelorException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public class TimerTicketServiceImpl extends AbstractTimerService implements TimerTicketService {
|
||||
|
||||
protected TicketRepository repository;
|
||||
|
||||
@Inject
|
||||
public TimerTicketServiceImpl(
|
||||
TimerRepository timerRepository,
|
||||
TimerHistoryRepository timerHistoryRepository,
|
||||
UserService userService,
|
||||
TicketRepository repository) {
|
||||
super(timerRepository, timerHistoryRepository, userService);
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer find(Model model) throws AxelorException {
|
||||
User user = userService.getUser();
|
||||
Ticket ticket = (Ticket) model;
|
||||
List<Timer> timerList = ticket.getTimerList();
|
||||
if (timerList != null && !timerList.isEmpty()) {
|
||||
return timerList.stream().filter(t -> t.getAssignedToUser() == user).findFirst().orElse(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackOn = {Exception.class})
|
||||
public TimerHistory start(Model model, Timer timer, LocalDateTime dateTime)
|
||||
throws AxelorException {
|
||||
Ticket ticket = (Ticket) model;
|
||||
|
||||
boolean isNewTimer = timer == null;
|
||||
timer = tryStartOrCreate(timer);
|
||||
if (isNewTimer) {
|
||||
ticket.addTimerListItem(timer);
|
||||
}
|
||||
|
||||
TimerHistory history = new TimerHistory();
|
||||
history.setStartDateT(dateTime);
|
||||
history.setTimer(timer);
|
||||
timer.addTimerHistoryListItem(history);
|
||||
|
||||
return timerHistoryRepository.save(history);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer find(Ticket ticket) throws AxelorException {
|
||||
return find((Model) ticket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimerHistory start(Ticket task, LocalDateTime dateTime) throws AxelorException {
|
||||
Timer timer = find(task);
|
||||
return start(task, timer, dateTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimerHistory stop(Ticket task, LocalDateTime dateTime) throws AxelorException {
|
||||
Timer timer = find(task);
|
||||
if (timer != null) {
|
||||
return stop(task, timer, dateTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(Ticket task) throws AxelorException {
|
||||
Timer timer = find(task);
|
||||
cancel(timer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration compute(Ticket task) {
|
||||
Duration total = Duration.ZERO;
|
||||
if (task != null) {
|
||||
task = repository.find(task.getId());
|
||||
if (task.getTimerList() != null && !task.getTimerList().isEmpty()) {
|
||||
for (Timer timer : task.getTimerList()) {
|
||||
total = total.plus(compute(timer));
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.translation;
|
||||
|
||||
public interface ITranslation {
|
||||
|
||||
public static final String HELPDESK_APP_NAME = /*$$(*/ "value:Helpdesk"; /*)*/
|
||||
}
|
||||
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.axelor.apps.helpdesk.web;
|
||||
|
||||
import com.axelor.apps.base.db.Timer;
|
||||
import com.axelor.apps.base.db.repo.TimerRepository;
|
||||
import com.axelor.apps.base.service.app.AppBaseService;
|
||||
import com.axelor.apps.helpdesk.db.Ticket;
|
||||
import com.axelor.apps.helpdesk.db.repo.TicketRepository;
|
||||
import com.axelor.apps.helpdesk.exceptions.IExceptionMessage;
|
||||
import com.axelor.apps.helpdesk.service.TicketService;
|
||||
import com.axelor.apps.helpdesk.service.TimerTicketService;
|
||||
import com.axelor.apps.tool.date.DateTool;
|
||||
import com.axelor.apps.tool.date.DurationTool;
|
||||
import com.axelor.exception.ResponseMessageType;
|
||||
import com.axelor.exception.service.TraceBackService;
|
||||
import com.axelor.i18n.I18n;
|
||||
import com.axelor.inject.Beans;
|
||||
import com.axelor.rpc.ActionRequest;
|
||||
import com.axelor.rpc.ActionResponse;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.persist.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class TicketController {
|
||||
|
||||
private static final String HIDDEN_ATTR = "hidden";
|
||||
|
||||
/**
|
||||
* Ticket assign to the current user.
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void assignToMeTicket(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Long id = (Long) request.getContext().get("id");
|
||||
List<?> ids = (List<?>) request.getContext().get("_ids");
|
||||
|
||||
if (id == null && ids == null) {
|
||||
response.setAlert(I18n.get(IExceptionMessage.SELECT_TICKETS));
|
||||
} else {
|
||||
Beans.get(TicketService.class).assignToMeTicket(id, ids);
|
||||
response.setReload(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute duration or endDateTime from startDateTime
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void computeFromStartDateTime(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
|
||||
if (ticket.getStartDateT() != null) {
|
||||
if (ticket.getDuration() != null && ticket.getDuration() != 0) {
|
||||
response.setValue(
|
||||
"endDateT", DateTool.plusSeconds(ticket.getStartDateT(), ticket.getDuration()));
|
||||
|
||||
} else if (ticket.getEndDateT() != null
|
||||
&& ticket.getEndDateT().isAfter(ticket.getStartDateT())) {
|
||||
Duration duration =
|
||||
DurationTool.computeDuration(ticket.getStartDateT(), ticket.getEndDateT());
|
||||
response.setValue("duration", DurationTool.getSecondsDuration(duration));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute startDateTime or endDateTime from duration
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void computeFromDuration(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
|
||||
if (ticket.getDuration() != null) {
|
||||
if (ticket.getStartDateT() != null) {
|
||||
response.setValue(
|
||||
"endDateT", DateTool.plusSeconds(ticket.getStartDateT(), ticket.getDuration()));
|
||||
|
||||
} else if (ticket.getEndDateT() != null) {
|
||||
response.setValue(
|
||||
"startDateT", DateTool.minusSeconds(ticket.getEndDateT(), ticket.getDuration()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute duration or startDateTime from endDateTime
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
public void computeFromEndDateTime(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
|
||||
if (ticket.getEndDateT() != null) {
|
||||
|
||||
if (ticket.getStartDateT() != null
|
||||
&& ticket.getStartDateT().isBefore(ticket.getEndDateT())) {
|
||||
Duration duration =
|
||||
DurationTool.computeDuration(ticket.getStartDateT(), ticket.getEndDateT());
|
||||
response.setValue("duration", DurationTool.getSecondsDuration(duration));
|
||||
|
||||
} else if (ticket.getDuration() != null) {
|
||||
response.setValue(
|
||||
"startDateT", DateTool.minusSeconds(ticket.getEndDateT(), ticket.getDuration()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void manageTimerButtons(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
TimerTicketService service = Beans.get(TimerTicketService.class);
|
||||
|
||||
Timer timer = service.find(ticket);
|
||||
|
||||
boolean hideStart = false;
|
||||
boolean hideCancel = true;
|
||||
if (timer != null) {
|
||||
hideStart = timer.getStatusSelect() == TimerRepository.TIMER_STARTED;
|
||||
hideCancel =
|
||||
timer.getTimerHistoryList().isEmpty()
|
||||
|| timer.getStatusSelect().equals(TimerRepository.TIMER_STOPPED);
|
||||
}
|
||||
|
||||
response.setAttr("startTimerBtn", HIDDEN_ATTR, hideStart);
|
||||
response.setAttr("stopTimerBtn", HIDDEN_ATTR, !hideStart);
|
||||
response.setAttr("cancelTimerBtn", HIDDEN_ATTR, hideCancel);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void computeTotalTimerDuration(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
if (ticket.getId() != null) {
|
||||
Duration duration = Beans.get(TimerTicketService.class).compute(ticket);
|
||||
response.setValue("$_totalTimerDuration", duration.toMinutes() / 60F);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void startTimer(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
Beans.get(TimerTicketService.class)
|
||||
.start(ticket, Beans.get(AppBaseService.class).getTodayDateTime().toLocalDateTime());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e, ResponseMessageType.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopTimer(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
Beans.get(TimerTicketService.class)
|
||||
.stop(ticket, Beans.get(AppBaseService.class).getTodayDateTime().toLocalDateTime());
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelTimer(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
Beans.get(TimerTicketService.class).cancel(ticket);
|
||||
response.setReload(true);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void computeRealDuration(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
if (ticket.getId() != null && ticket.getRealTotalDuration().compareTo(BigDecimal.ZERO) == 0) {
|
||||
response.setValue(
|
||||
"realTotalDuration",
|
||||
Beans.get(TimerTicketService.class).compute(ticket).toMinutes() / 60F);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void timerStateOn(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
TicketRepository ticketRepo = Beans.get(TicketRepository.class);
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
ticket = ticketRepo.find(ticket.getId());
|
||||
ticket.setTimerState(true);
|
||||
ticketRepo.save(ticket);
|
||||
response.setReload(true);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void timerStateOff(ActionRequest request, ActionResponse response) {
|
||||
try {
|
||||
TicketRepository ticketRepo = Beans.get(TicketRepository.class);
|
||||
Ticket ticket = request.getContext().asType(Ticket.class);
|
||||
ticket = ticketRepo.find(ticket.getId());
|
||||
ticket.setTimerState(false);
|
||||
ticketRepo.save(ticket);
|
||||
response.setReload(true);
|
||||
} catch (Exception e) {
|
||||
TraceBackService.trace(response, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
"importId";"code";"name";"nextNum";"padding";"prefixe";"suffixe";"toBeAdded";"yearlyResetOk"
|
||||
99;"ticket";"Ticket";1;4;"TKT";;1;0
|
||||
|
@ -0,0 +1,2 @@
|
||||
"importId";"code";"name";"nextNum";"padding";"prefixe";"suffixe";"toBeAdded";"yearlyResetOk"
|
||||
99;"ticket";"Ticket";1;4;"TKT";;1;0
|
||||
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.2.xsd">
|
||||
|
||||
<input file="base_sequence.csv" separator=";" type="com.axelor.apps.base.db.Sequence" search="self.importId = :importId">
|
||||
<bind to="yearlyResetOk" column="yearlyResetOk" eval="yearlyResetOk == '1' ? true : false"/>
|
||||
<bind to="nextNum" column="nextNum" eval="nextNum?.empty ? '1' : nextNum"/>
|
||||
<bind to="padding" column="padding" eval="padding?.empty ? '1' : padding"/>
|
||||
<bind to="toBeAdded" column="toBeAdded" eval="toBeAdded?.empty ? '1' : toBeAdded"/>
|
||||
<bind to="resetDate" eval="call:com.axelor.apps.base.service.app.AppBaseService:getTodayDate()" />
|
||||
</input>
|
||||
|
||||
</csv-inputs>
|
||||
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.2.xsd">
|
||||
|
||||
<input file="auth_permission.csv" separator=";" type="com.axelor.auth.db.Permission" search="self.name = :name" call="com.axelor.csv.script.ImportPermission:importPermissionToRole">
|
||||
<bind to="canRead" eval="can_read == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canWrite" eval="can_write == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canCreate" eval="can_create == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canRemove" eval="can_remove == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canExport" eval="can_export == 'x' ? 'true' : 'false'"/>
|
||||
</input>
|
||||
|
||||
<input file="base_appHelpdesk.csv" separator=";" type="com.axelor.apps.base.db.AppHelpdesk" call="com.axelor.csv.script.ImportApp:importApp">
|
||||
<bind column="dependsOn" to="dependsOnSet" search="self.code in :dependsOn" eval="dependsOn.split(',') as List"/>
|
||||
</input>
|
||||
|
||||
<input file="meta_metaMenu.csv" separator=";" type="com.axelor.meta.db.MetaMenu" search="self.name = :name" update="true" />
|
||||
|
||||
</csv-inputs>
|
||||
@ -0,0 +1,2 @@
|
||||
"name";"object";"can_read";"can_write";"can_create";"can_remove";"can_export";"condition";"conditionParams";"roleName"
|
||||
"perm.helpdesk.all";"com.axelor.apps.helpdesk.db.*";"x";"x";"x";"x";"x";;;"Admin"
|
||||
|
@ -0,0 +1,2 @@
|
||||
"name";"code";"installOrder";"description";"imagePath";"modules";"dependsOn";"sequence"
|
||||
"Helpdesk";"helpdesk";29;"Helpdesk Management";"app-helpdesk.png";"axelor-helpdesk";"base";28
|
||||
|
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,14 @@
|
||||
"name";"roles.name"
|
||||
"helpdesk-root";"Admin"
|
||||
"helpdesk-ticket-current";"Admin"
|
||||
"helpdesk-my-ticket-all";"Admin"
|
||||
"helpdesk-my-team-ticket-all";"Admin"
|
||||
"helpdesk-not-assigned-ticket";"Admin"
|
||||
"helpdesk-late-ticket";"Admin"
|
||||
"helpdesk-ticket-all";"Admin"
|
||||
"helpdesk-reporting";"Admin"
|
||||
"helpdesk-report-ticket";"Admin"
|
||||
"helpdesk-report-sla";"Admin"
|
||||
"helpdesk-config";"Admin"
|
||||
"helpdesk-sla-policies-all";"Admin"
|
||||
"helpdesk-ticket-types-all";"Admin"
|
||||
|
@ -0,0 +1,2 @@
|
||||
"importId";"company.importId"
|
||||
99;1
|
||||
|
@ -0,0 +1,7 @@
|
||||
"ticketSeq";"subject";"ticketType.name";"startDateT";"endDateT";"assignedToUser.name";"prioritySelect";"statusSelect";"progressSelect"
|
||||
"TKT0001";"Where to download the ERP source code";"Technical Support";"26/02/18 18:30";"26/02/18 20:30";"Kevin DEMOERP";1;2;100
|
||||
"TKT0002";"How to access the technical documentation";"Technical Support";"27/02/18 13:30";"27/02/18 16:30";"Kevin DEMOERP";1;2;100
|
||||
"TKT0003";"Unable to log in with Admin user";"Technical Support";"27/02/18 14:30";"28/02/18 14:00";"Cyril MARCHAL";3;2;100
|
||||
"TKT0004";"How to attach a file";"Functionnal Support";"27/02/18 18:30";;"Charles DEMOCRM";2;1;10
|
||||
"TKT0005";"How to perform an advanced search";"Functionnal Support";"28/02/18 13:30";;"Charles DEMOCRM";3;0;
|
||||
"TKT0006";"How to mass update records";"Functionnal Support";"28/02/18 14:00";;"Kevin DEMOERP";4;0;
|
||||
|
@ -0,0 +1,8 @@
|
||||
importId;name
|
||||
1;Technical Support
|
||||
2;Functionnal Support
|
||||
3;Anomaly
|
||||
4;Failure
|
||||
5;Defect
|
||||
6;Updates
|
||||
7;Administration
|
||||
|
@ -0,0 +1,2 @@
|
||||
"importId";"company.importId"
|
||||
99;1
|
||||
|
@ -0,0 +1,7 @@
|
||||
"ticketSeq";"subject";"ticketType.name";"startDateT";"endDateT";"assignedToUser.name";"prioritySelect";"statusSelect";"progressSelect"
|
||||
"TKT0001";"Où télécharger les sources de l'ERP ?";"Support technique";"26/02/18 18:30";"26/02/18 20:30";"Kevin DEMOERP";1;2;100
|
||||
"TKT0002";"Comment accéder à la doc technique ? ";"Support technique";"27/02/18 13:30";"27/02/18 16:30";"Kevin DEMOERP";1;2;100
|
||||
"TKT0003";"Impossible de se connecter avec l’utilisateur Admin";"Support technique";"27/02/18 14:30";"28/02/18 14:00";"Cyril MARCHAL";3;2;100
|
||||
"TKT0004";"Comment joindre un fichier ?";"Support fonctionnel";"27/02/18 18:30";;"Charles DEMOCRM";2;1;10
|
||||
"TKT0005";"Comment effectuer une recherche avancée ? ";"Support fonctionnel";"28/02/18 13:30";;"Charles DEMOCRM";3;0;
|
||||
"TKT0006";"Comment effectuer une mise à jour en masse d'enregistrements ?";"Support fonctionnel";"28/02/18 14:00";;"Kevin DEMOERP";4;0;
|
||||
|
@ -0,0 +1,8 @@
|
||||
importId;name
|
||||
1;Support technique
|
||||
2;Support fonctionnel
|
||||
3;Anomalie
|
||||
4;Échec
|
||||
5;Défaut
|
||||
6;Mises à jour
|
||||
7;Administration
|
||||
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.2.xsd">
|
||||
|
||||
<adapter name="LocalDateTime" type="com.axelor.data.adapter.JavaTimeAdapter">
|
||||
<option name="type" value="LocalDateTime"/>
|
||||
<option name="format" value="dd/MM/yy HH:mm"/>
|
||||
</adapter>
|
||||
|
||||
<input file="helpdesk_ticketType.csv" separator=";" type="com.axelor.apps.helpdesk.db.TicketType" search="self.importId = :importId"/>
|
||||
|
||||
<input file="helpdesk_ticket.csv" separator=";" type="com.axelor.apps.helpdesk.db.Ticket" search="self.ticketSeq = :ticketSeq">
|
||||
<bind to="startDateT" column="startDateT" adapter="LocalDateTime" />
|
||||
<bind to="endDateT" column="endDateT" adapter="LocalDateTime"/>
|
||||
</input>
|
||||
|
||||
<input file="base_sequence.csv" separator=";" type="com.axelor.apps.base.db.Sequence" search="self.importId = :importId" call="com.axelor.csv.script.SequenceScript:computeFullname">
|
||||
<bind to="yearlyResetOk" column="yearlyResetOk" eval="yearlyResetOk == '1' ? true : false"/>
|
||||
<bind to="nextNum" column="nextNum" eval="nextNum?.empty ? '1' : nextNum"/>
|
||||
<bind to="padding" column="padding" eval="padding?.empty ? '1' : padding"/>
|
||||
<bind to="toBeAdded" column="toBeAdded" eval="toBeAdded?.empty ? '1' : toBeAdded"/>
|
||||
</input>
|
||||
|
||||
</csv-inputs>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="base" package="com.axelor.apps.base.db"/>
|
||||
|
||||
<entity name="AppHelpdesk" lang="java" cacheable="true" extends="App" >
|
||||
<boolean name="isSla" title="SLA" default="false"/>
|
||||
<boolean name="manageTimer" title="Manage Timer" default="false"/>
|
||||
|
||||
<track>
|
||||
<field name="isSla" on="UPDATE"/>
|
||||
<field name="manageTimer" on="UPDATE"/>
|
||||
</track>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="project" package="com.axelor.apps.project.db"/>
|
||||
|
||||
<entity name="Project">
|
||||
<string name="name" required="true"/>
|
||||
<string name="code" title="Code" />
|
||||
<string name="fullName" namecolumn="true" title="Name"/>
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="base" package="com.axelor.apps.base.db"/>
|
||||
|
||||
<entity name="Sequence" lang="java">
|
||||
|
||||
<extra-code><![CDATA[
|
||||
|
||||
//SEQUENCE SELECT
|
||||
public static final String TICKET = "ticket";
|
||||
|
||||
]]></extra-code>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="helpdesk" package="com.axelor.apps.helpdesk.db"/>
|
||||
|
||||
<entity name="Sla">
|
||||
|
||||
<string name="name" required="true" title="SLA policy name"/>
|
||||
<many-to-one name="team" ref="com.axelor.team.db.Team" title="Team"/>
|
||||
<integer name="prioritySelect" title="Minimum priority" selection="helpdesk.priority.select" default="2"/>
|
||||
<many-to-one name="ticketType" ref="com.axelor.apps.helpdesk.db.TicketType" title="Ticket type"/>
|
||||
<integer name="reachStageSelect" title="Reach stage" selection="helpdesk.status.select"/>
|
||||
<integer name="days" title="days" min="0"/>
|
||||
<integer name="hours" title="hours" min="0"/>
|
||||
<boolean name="isWorkingDays" title="Working Days"/>
|
||||
<string name="description" title="Description" large="true"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="helpdesk" package="com.axelor.apps.helpdesk.db"/>
|
||||
|
||||
<entity name="Ticket">
|
||||
|
||||
<string name="ticketSeq" title="Ticket Number" readonly="true" />
|
||||
<string name="subject" title="Subject" required="true"/>
|
||||
<many-to-one name="project" ref="com.axelor.apps.project.db.Project" title="Project"/>
|
||||
<many-to-one name="customer" ref="com.axelor.apps.base.db.Partner" title="Customer"/>
|
||||
<many-to-one name="contactPartner" ref="com.axelor.apps.base.db.Partner" title="Customer contact"/>
|
||||
<many-to-one name="slaPolicy" ref="com.axelor.apps.helpdesk.db.Sla" title="SLA Policy"/>
|
||||
<many-to-one name="assignedToUser" ref="com.axelor.auth.db.User" title="Assigned to"/>
|
||||
<many-to-one name="responsibleUser" ref="com.axelor.auth.db.User" title="User in charge of the issue"/>
|
||||
<integer name="statusSelect" selection="helpdesk.status.select" title="Status"/>
|
||||
<many-to-one name="ticketType" ref="com.axelor.apps.helpdesk.db.TicketType" title="Ticket type"/>
|
||||
<datetime name="startDateT" title="Start date"/>
|
||||
<datetime name="endDateT" title="End date"/>
|
||||
<datetime name="deadlineDateT" title="Deadline"/>
|
||||
<boolean name="isSlaCompleted" title="SLA completed" default="false"/>
|
||||
<long name="duration" title="Duration"/>
|
||||
<string name="description" title="Description" large="true"/>
|
||||
<integer name="progressSelect" title="Progress (%)" selection="helpdesk.ticket.progress.select"/>
|
||||
<integer name="prioritySelect" title="Priority" selection="helpdesk.priority.select" default="2"/>
|
||||
<string name="mailSubject"/>
|
||||
<one-to-many name="timerList" ref="com.axelor.apps.base.db.Timer"/>
|
||||
<decimal name="realTotalDuration" title="Real total duration (Hours)" min="0" default="0" />
|
||||
<boolean name="timerState" readonly="true"/>
|
||||
|
||||
<extra-code>
|
||||
<![CDATA[
|
||||
public static final int STATUS_NEW = 0;
|
||||
public static final int STATUS_IN_PROGRESS = 1;
|
||||
public static final int STATUS_RESOLVED = 2;
|
||||
public static final int STATUS_CLOSED = 3;
|
||||
]]>
|
||||
</extra-code>
|
||||
|
||||
<track>
|
||||
<field name="ticketSeq"/>
|
||||
<field name="subject" />
|
||||
<field name="statusSelect" on="UPDATE"/>
|
||||
<message if="true" on="CREATE">Ticket created</message>
|
||||
<message if="statusSelect == 1" tag="info">Ticket In Progress</message>
|
||||
<message if="statusSelect == 2" tag="success">Ticket In Resolved</message>
|
||||
<message if="statusSelect == 3" tag="info">Ticket Closed</message>
|
||||
</track>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" ?>
|
||||
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models http://axelor.com/xml/ns/domain-models/domain-models_5.2.xsd">
|
||||
|
||||
<module name="helpdesk" package="com.axelor.apps.helpdesk.db"/>
|
||||
|
||||
<entity name="TicketType">
|
||||
|
||||
<string name="name" required="true"/>
|
||||
|
||||
</entity>
|
||||
|
||||
</domain-models>
|
||||
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA",,,
|
||||
"All ticket types",,,
|
||||
"All tickets",,,
|
||||
"App helpdesk",,,
|
||||
"Apply on",,,
|
||||
"Assign to me",,,
|
||||
"Assigned to",,,
|
||||
"Cancel",,,
|
||||
"Characteristics",,,
|
||||
"Close",,,
|
||||
"Closed",,,
|
||||
"Code",,,
|
||||
"Configuration",,,
|
||||
"Current tickets",,,
|
||||
"Customer",,,
|
||||
"Customer contact",,,
|
||||
"Dates",,,
|
||||
"Deadline",,,
|
||||
"Description",,,
|
||||
"Duration",,,
|
||||
"End date",,,
|
||||
"Follow-up",,,
|
||||
"From Date",,,
|
||||
"Helpdesk",,,
|
||||
"High",,,
|
||||
"In progress",,,
|
||||
"Late tickets",,,
|
||||
"Low",,,
|
||||
"Mail subject",,,
|
||||
"Manage Timer",,,
|
||||
"Minimum priority",,,
|
||||
"My team tickets",,,
|
||||
"My tickets",,,
|
||||
"Name",,,
|
||||
"New",,,
|
||||
"Normal",,,
|
||||
"Not assigned tickets",,,
|
||||
"Number of tickets per SLA & per team",,,
|
||||
"Number of tickets per SLA & per user",,,
|
||||
"Overview",,,
|
||||
"Percentage",,,
|
||||
"Percentage of repartition tickets per state",,,
|
||||
"Percentage of tickets per SLA & per team",,,
|
||||
"Percentage of tickets per SLA & per user",,,
|
||||
"Please select tickets",,,
|
||||
"Priority",,,
|
||||
"Progress",,,
|
||||
"Progress (%)",,,
|
||||
"Project",,,
|
||||
"Projects",,,
|
||||
"Reach in",,,
|
||||
"Reach stage",,,
|
||||
"Real total duration (Hours)",,,
|
||||
"Reportings",,,
|
||||
"Resolve",,,
|
||||
"Resolved",,,
|
||||
"SLA",,,
|
||||
"SLA Details",,,
|
||||
"SLA Policy",,,
|
||||
"SLA completed",,,
|
||||
"SLA dashboard",,,
|
||||
"SLA policies",,,
|
||||
"SLA policy name",,,
|
||||
"Start",,,
|
||||
"Start date",,,
|
||||
"Status",,,
|
||||
"Stop",,,
|
||||
"Subject",,,
|
||||
"Take charge",,,
|
||||
"Target",,,
|
||||
"Team",,,
|
||||
"Ticket",,,
|
||||
"Ticket Closed",,,
|
||||
"Ticket Details",,,
|
||||
"Ticket In Progress",,,
|
||||
"Ticket In Resolved",,,
|
||||
"Ticket Number",,,
|
||||
"Ticket N°",,,
|
||||
"Ticket Type",,,
|
||||
"Ticket created",,,
|
||||
"Ticket dashboard",,,
|
||||
"Ticket type",,,
|
||||
"Ticket types",,,
|
||||
"Tickets",,,
|
||||
"Tickets by ticket type",,,
|
||||
"Timer",,,
|
||||
"Timer list",,,
|
||||
"Timer state",,,
|
||||
"To Date",,,
|
||||
"Total duration (Hours)",,,
|
||||
"Total tickets",,,
|
||||
"Urgent",,,
|
||||
"User",,,
|
||||
"User in charge of the issue",,,
|
||||
"Working Days",,,
|
||||
"days",,,
|
||||
"hours",,,
|
||||
"info",,,
|
||||
"success",,,
|
||||
"value:Helpdesk",,,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Alle SLA",,
|
||||
"All ticket types","Alle Tickettypen",,
|
||||
"All tickets","Alle Tickets",,
|
||||
"App helpdesk","App Helpdesk",,
|
||||
"Apply on","Bewerben auf",,
|
||||
"Assign to me","Mir zuweisen",,
|
||||
"Assigned to","Zugeordnet zu",,
|
||||
"Cancel","Abbrechen",,
|
||||
"Characteristics","Merkmale",,
|
||||
"Close","Schließen",,
|
||||
"Closed","Geschlossen",,
|
||||
"Code","Code",,
|
||||
"Configuration","Konfiguration",,
|
||||
"Current tickets","Aktuelle Tickets",,
|
||||
"Customer","Kunde",,
|
||||
"Customer contact","Kundenkontakt",,
|
||||
"Dates","Daten",,
|
||||
"Deadline","Deadline",,
|
||||
"Description","Beschreibung",,
|
||||
"Duration","Dauer",,
|
||||
"End date","Enddatum",,
|
||||
"Follow-up","Nachbereitung",,
|
||||
"From Date","Von-Datum",,
|
||||
"Helpdesk","Helpdesk",,
|
||||
"High","Hoch",,
|
||||
"In progress","In Bearbeitung",,
|
||||
"Late tickets","Verspätete Tickets",,
|
||||
"Low","Niedrig",,
|
||||
"Mail subject","Betreff der E-Mail",,
|
||||
"Manage Timer","Timer verwalten",,
|
||||
"Minimum priority","Minimale Priorität",,
|
||||
"My team tickets","Meine Teamtickets",,
|
||||
"My tickets","Meine Tickets",,
|
||||
"Name","Name",,
|
||||
"New","Neu",,
|
||||
"Normal","Normal",,
|
||||
"Not assigned tickets","Nicht zugeordnete Tickets",,
|
||||
"Number of tickets per SLA & per team","Anzahl der Tickets pro SLA & pro Team",,
|
||||
"Number of tickets per SLA & per user","Anzahl der Tickets pro SLA & pro Benutzer",,
|
||||
"Overview","Übersicht",,
|
||||
"Percentage","Prozentsatz",,
|
||||
"Percentage of repartition tickets per state","Prozentsatz der Repartitionstickets pro Status",,
|
||||
"Percentage of tickets per SLA & per team","Prozentsatz der Tickets pro SLA & pro Team",,
|
||||
"Percentage of tickets per SLA & per user","Prozentsatz der Tickets pro SLA & pro Benutzer",,
|
||||
"Please select tickets","Bitte wählen Sie Tickets aus",,
|
||||
"Priority","Priorität",,
|
||||
"Progress","Fortschritte",,
|
||||
"Progress (%)","Fortschritt (%)",,
|
||||
"Project","Projekt",,
|
||||
"Projects","Projekte",,
|
||||
"Reach in","Reichweite in",,
|
||||
"Reach stage","Erreichbarkeitsstufe",,
|
||||
"Real total duration (Hours)","Reale Gesamtdauer (Stunden)",,
|
||||
"Reportings","Berichte",,
|
||||
"Resolve","Lösen",,
|
||||
"Resolved","Gelöst",,
|
||||
"SLA","SLA",,
|
||||
"SLA Details","SLA-Details",,
|
||||
"SLA Policy","SLA-Richtlinie",,
|
||||
"SLA completed","SLA abgeschlossen",,
|
||||
"SLA dashboard","SLA Dashboard",,
|
||||
"SLA policies","SLA-Richtlinien",,
|
||||
"SLA policy name","Name der SLA-Richtlinie",,
|
||||
"Start","Start",,
|
||||
"Start date","Startdatum",,
|
||||
"Status","Status",,
|
||||
"Stop","Stopp",,
|
||||
"Subject","Betreff",,
|
||||
"Take charge","Übernehmen Sie die Verantwortung",,
|
||||
"Target","Ziel",,
|
||||
"Team","Team",,
|
||||
"Ticket","Ticket",,
|
||||
"Ticket Closed","Ticket geschlossen",,
|
||||
"Ticket Details","Ticket-Details",,
|
||||
"Ticket In Progress","Ticket in Bearbeitung",,
|
||||
"Ticket In Resolved","Ticket in gelöst",,
|
||||
"Ticket Number","Ticketnummer",,
|
||||
"Ticket N°","Ticket-Nr.",,
|
||||
"Ticket Type","Tickettyp",,
|
||||
"Ticket created","Ticket erstellt",,
|
||||
"Ticket dashboard","Ticket-Dashboard",,
|
||||
"Ticket type","Tickettyp",,
|
||||
"Ticket types","Tickettypen",,
|
||||
"Tickets","Tickets",,
|
||||
"Tickets by ticket type","Tickets nach Tickettyp",,
|
||||
"Timer","Timer",,
|
||||
"Timer list","Timerliste",,
|
||||
"Timer state","Timer-Status",,
|
||||
"To Date","Bis heute",,
|
||||
"Total duration (Hours)","Gesamtdauer (Stunden)",,
|
||||
"Total tickets","Gesamtzahl der Tickets",,
|
||||
"Urgent","Dringend",,
|
||||
"User","Benutzer",,
|
||||
"User in charge of the issue","Verantwortlicher Benutzer für das Problem",,
|
||||
"Working Days","Arbeitstage",,
|
||||
"days","Tage",,
|
||||
"hours","Stunden",,
|
||||
"info","Info",,
|
||||
"success","Erfolg",,
|
||||
"value:Helpdesk","Wert:Helpdesk",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA",,,
|
||||
"All ticket types",,,
|
||||
"All tickets",,,
|
||||
"App helpdesk",,,
|
||||
"Apply on",,,
|
||||
"Assign to me",,,
|
||||
"Assigned to",,,
|
||||
"Cancel",,,
|
||||
"Characteristics","Caractéristiques",,
|
||||
"Close",,,
|
||||
"Closed",,,
|
||||
"Code",,,
|
||||
"Configuration",,,
|
||||
"Current tickets",,,
|
||||
"Customer",,,
|
||||
"Customer contact",,,
|
||||
"Dates",,,
|
||||
"Deadline",,,
|
||||
"Description",,,
|
||||
"Duration",,,
|
||||
"End date",,,
|
||||
"Follow-up",,,
|
||||
"From Date",,,
|
||||
"Helpdesk",,,
|
||||
"High",,,
|
||||
"In progress",,,
|
||||
"Late tickets",,,
|
||||
"Low",,,
|
||||
"Mail subject",,,
|
||||
"Manage Timer",,,
|
||||
"Minimum priority",,,
|
||||
"My team tickets",,,
|
||||
"My tickets",,,
|
||||
"Name",,,
|
||||
"New",,,
|
||||
"Normal",,,
|
||||
"Not assigned tickets",,,
|
||||
"Number of tickets per SLA & per team",,,
|
||||
"Number of tickets per SLA & per user",,,
|
||||
"Overview",,,
|
||||
"Percentage",,,
|
||||
"Percentage of repartition tickets per state",,,
|
||||
"Percentage of tickets per SLA & per team",,,
|
||||
"Percentage of tickets per SLA & per user",,,
|
||||
"Please select tickets",,,
|
||||
"Priority",,,
|
||||
"Progress",,,
|
||||
"Progress (%)",,,
|
||||
"Project",,,
|
||||
"Projects",,,
|
||||
"Reach in",,,
|
||||
"Reach stage",,,
|
||||
"Real total duration (Hours)",,,
|
||||
"Reportings",,,
|
||||
"Resolve",,,
|
||||
"Resolved",,,
|
||||
"SLA",,,
|
||||
"SLA Details",,,
|
||||
"SLA Policy",,,
|
||||
"SLA completed",,,
|
||||
"SLA dashboard",,,
|
||||
"SLA policies",,,
|
||||
"SLA policy name",,,
|
||||
"Start",,,
|
||||
"Start date",,,
|
||||
"Status",,,
|
||||
"Stop",,,
|
||||
"Subject",,,
|
||||
"Take charge",,,
|
||||
"Target",,,
|
||||
"Team",,,
|
||||
"Ticket",,,
|
||||
"Ticket Closed",,,
|
||||
"Ticket Details",,,
|
||||
"Ticket In Progress",,,
|
||||
"Ticket In Resolved",,,
|
||||
"Ticket Number",,,
|
||||
"Ticket N°",,,
|
||||
"Ticket Type",,,
|
||||
"Ticket created",,,
|
||||
"Ticket dashboard",,,
|
||||
"Ticket type",,,
|
||||
"Ticket types",,,
|
||||
"Tickets",,,
|
||||
"Tickets by ticket type",,,
|
||||
"Timer",,,
|
||||
"Timer list",,,
|
||||
"Timer state",,,
|
||||
"To Date",,,
|
||||
"Total duration (Hours)",,,
|
||||
"Total tickets",,,
|
||||
"Urgent",,,
|
||||
"User",,,
|
||||
"User in charge of the issue",,,
|
||||
"Working Days",,,
|
||||
"days",,,
|
||||
"hours",,,
|
||||
"info",,,
|
||||
"success",,,
|
||||
"value:Helpdesk",,,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Todos los SLA",,
|
||||
"All ticket types","Todos los tipos de entradas",,
|
||||
"All tickets","Todos los billetes",,
|
||||
"App helpdesk","Servicio de asistencia de aplicaciones",,
|
||||
"Apply on","Aplicar en",,
|
||||
"Assign to me","Asignar a mí",,
|
||||
"Assigned to","Asignado a",,
|
||||
"Cancel","Cancelar",,
|
||||
"Characteristics","Características",,
|
||||
"Close","Cerrar",,
|
||||
"Closed","Cerrado",,
|
||||
"Code","Código",,
|
||||
"Configuration","Configuración",,
|
||||
"Current tickets","Billetes actuales",,
|
||||
"Customer","Cliente",,
|
||||
"Customer contact","Contacto con el cliente",,
|
||||
"Dates","Fechas",,
|
||||
"Deadline","Fecha límite",,
|
||||
"Description","Descripción",,
|
||||
"Duration","Duración",,
|
||||
"End date","Fecha de finalización",,
|
||||
"Follow-up","Seguimiento",,
|
||||
"From Date","Desde la fecha",,
|
||||
"Helpdesk","Servicio de asistencia técnica",,
|
||||
"High","Alto",,
|
||||
"In progress","En curso",,
|
||||
"Late tickets","Entradas atrasadas",,
|
||||
"Low","Baja",,
|
||||
"Mail subject","Asunto del correo",,
|
||||
"Manage Timer","Administrar temporizador",,
|
||||
"Minimum priority","Prioridad mínima",,
|
||||
"My team tickets","Mis entradas para el equipo",,
|
||||
"My tickets","Mis entradas",,
|
||||
"Name","Nombre",,
|
||||
"New","Nuevo",,
|
||||
"Normal","Normal",,
|
||||
"Not assigned tickets","Entradas no asignadas",,
|
||||
"Number of tickets per SLA & per team","Número de entradas por ANS y por equipo",,
|
||||
"Number of tickets per SLA & per user","Número de tickets por SLA y por usuario",,
|
||||
"Overview","Panorama general",,
|
||||
"Percentage","Porcentaje",,
|
||||
"Percentage of repartition tickets per state","Porcentaje de boletos de distribución por estado",,
|
||||
"Percentage of tickets per SLA & per team","Porcentaje de entradas por ANS y por equipo",,
|
||||
"Percentage of tickets per SLA & per user","Porcentaje de tickets por ANS y por usuario",,
|
||||
"Please select tickets","Por favor, seleccione las entradas",,
|
||||
"Priority","Prioridad",,
|
||||
"Progress","Progreso",,
|
||||
"Progress (%)","Progreso (%)",,
|
||||
"Project","Proyecto",,
|
||||
"Projects","Proyectos",,
|
||||
"Reach in","Alcance en",,
|
||||
"Reach stage","Etapa de alcance",,
|
||||
"Real total duration (Hours)","Duración total real (Horas)",,
|
||||
"Reportings","Reportajes",,
|
||||
"Resolve","Resolver",,
|
||||
"Resolved","Resuelto",,
|
||||
"SLA","ANS",,
|
||||
"SLA Details","Detalles del ANS",,
|
||||
"SLA Policy","Política de SLA",,
|
||||
"SLA completed","ANS completado",,
|
||||
"SLA dashboard","Panel de control SLA",,
|
||||
"SLA policies","Políticas de SLA",,
|
||||
"SLA policy name","Nombre de la política SLA",,
|
||||
"Start","Inicio",,
|
||||
"Start date","Fecha de inicio",,
|
||||
"Status","Estado",,
|
||||
"Stop","Parar",,
|
||||
"Subject","Tema",,
|
||||
"Take charge","Hágase cargo",,
|
||||
"Target","Objetivo",,
|
||||
"Team","Equipo",,
|
||||
"Ticket","Billete",,
|
||||
"Ticket Closed","Entrada Cerrada",,
|
||||
"Ticket Details","Detalles del billete",,
|
||||
"Ticket In Progress","Boleto en progreso",,
|
||||
"Ticket In Resolved","Ticket en resuelto",,
|
||||
"Ticket Number","Número de billete",,
|
||||
"Ticket N°","Ticket N°",,
|
||||
"Ticket Type","Tipo de billete",,
|
||||
"Ticket created","Billete creado",,
|
||||
"Ticket dashboard","Tablero de mandos",,
|
||||
"Ticket type","Tipo de billete",,
|
||||
"Ticket types","Tipos de tickets",,
|
||||
"Tickets","Billetes",,
|
||||
"Tickets by ticket type","Entradas por tipo de entrada",,
|
||||
"Timer","Temporizador",,
|
||||
"Timer list","Lista de temporizadores",,
|
||||
"Timer state","Estado del temporizador",,
|
||||
"To Date","Hasta la fecha",,
|
||||
"Total duration (Hours)","Duración total (Horas)",,
|
||||
"Total tickets","Total de billetes",,
|
||||
"Urgent","Urgente",,
|
||||
"User","Usuario",,
|
||||
"User in charge of the issue","Usuario a cargo de la emisión",,
|
||||
"Working Days","Días laborables",,
|
||||
"days","días",,
|
||||
"hours","horario",,
|
||||
"info","información",,
|
||||
"success","triunfo",,
|
||||
"value:Helpdesk","valor:Helpdesk",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA",,,
|
||||
"All ticket types",,,
|
||||
"All tickets","Tous les tickets",,
|
||||
"App helpdesk","App Support client",,
|
||||
"Apply on","S'applique sur",,
|
||||
"Assign to me",,,
|
||||
"Assigned to",,,
|
||||
"Cancel",,,
|
||||
"Characteristics","Caractéristiques",,
|
||||
"Close",,,
|
||||
"Closed",,,
|
||||
"Code",,,
|
||||
"Configuration",,,
|
||||
"Current tickets","Tickets en cours",,
|
||||
"Customer",,,
|
||||
"Customer contact",,,
|
||||
"Dates",,,
|
||||
"Deadline",,,
|
||||
"Description",,,
|
||||
"Duration",,,
|
||||
"End date",,,
|
||||
"Follow-up",,,
|
||||
"From Date",,,
|
||||
"Helpdesk","Support client",,
|
||||
"High",,,
|
||||
"In progress",,,
|
||||
"Late tickets","Tickets en retard",,
|
||||
"Low",,,
|
||||
"Mail subject","Sujet de mail",,
|
||||
"Manage Timer","Gérer le timer",,
|
||||
"Minimum priority","Priorité minimum",,
|
||||
"My team tickets","Les tickets de mon équipe",,
|
||||
"My tickets","Mes tickets",,
|
||||
"Name",,,
|
||||
"New",,,
|
||||
"Normal",,,
|
||||
"Not assigned tickets","Tickets non assignés",,
|
||||
"Number of tickets per SLA & per team","Nombre de tickets par SLA & par équipe",,
|
||||
"Number of tickets per SLA & per user","Nombre de tickets par SLA & par utilisateur",,
|
||||
"Overview",,,
|
||||
"Percentage",,,
|
||||
"Percentage of repartition tickets per state","Pourcentage de la répartition des tickets par état",,
|
||||
"Percentage of tickets per SLA & per team","Pourcentage des tickets par SLA & par équipe",,
|
||||
"Percentage of tickets per SLA & per user","Pourcentage des tickets par SLA & par utilisateur",,
|
||||
"Please select tickets",,,
|
||||
"Priority",,,
|
||||
"Progress",,,
|
||||
"Progress (%)",,,
|
||||
"Project","Projet",,
|
||||
"Projects",,,
|
||||
"Reach in","Atteint en",,
|
||||
"Reach stage","Etape atteinte",,
|
||||
"Real total duration (Hours)",,,
|
||||
"Reportings",,,
|
||||
"Resolve","Résoudre",,
|
||||
"Resolved","Résolu",,
|
||||
"SLA",,,
|
||||
"SLA Details",,,
|
||||
"SLA Policy","Charte SLA",,
|
||||
"SLA completed",,,
|
||||
"SLA dashboard",,,
|
||||
"SLA policies","Chartes SLA",,
|
||||
"SLA policy name","Nom de la charte SLA",,
|
||||
"Start",,,
|
||||
"Start date",,,
|
||||
"Status",,,
|
||||
"Stop",,,
|
||||
"Subject",,,
|
||||
"Take charge","Prendre en charge",,
|
||||
"Target",,,
|
||||
"Team",,,
|
||||
"Ticket",,,
|
||||
"Ticket Closed",,,
|
||||
"Ticket Details",,,
|
||||
"Ticket In Progress",,,
|
||||
"Ticket In Resolved",,,
|
||||
"Ticket Number","Ticket N°",,
|
||||
"Ticket N°",,,
|
||||
"Ticket Type",,,
|
||||
"Ticket created",,,
|
||||
"Ticket dashboard",,,
|
||||
"Ticket type","Type de tickets",,
|
||||
"Ticket types","Types de tickets",,
|
||||
"Tickets",,,
|
||||
"Tickets by ticket type","Tickets par type de ticket",,
|
||||
"Timer",,,
|
||||
"Timer list",,,
|
||||
"Timer state",,,
|
||||
"To Date",,,
|
||||
"Total duration (Hours)",,,
|
||||
"Total tickets",,,
|
||||
"Urgent",,,
|
||||
"User",,,
|
||||
"User in charge of the issue","Utilisateur en charge du problème",,
|
||||
"Working Days","Jours ouvrés",,
|
||||
"days",,,
|
||||
"hours","heures",,
|
||||
"info",,,
|
||||
"success",,,
|
||||
"value:Helpdesk","Support client",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Tutti gli SLA",,
|
||||
"All ticket types","Tutti i tipi di biglietti",,
|
||||
"All tickets","Tutti i biglietti",,
|
||||
"App helpdesk","Helpdesk per le applicazioni",,
|
||||
"Apply on","Applicare su",,
|
||||
"Assign to me","Assegnare a me",,
|
||||
"Assigned to","Assegnato a",,
|
||||
"Cancel","Annulla",,
|
||||
"Characteristics","Caratteristiche",,
|
||||
"Close","Chiudere",,
|
||||
"Closed","Chiuso",,
|
||||
"Code","Codice",,
|
||||
"Configuration","Configurazione",,
|
||||
"Current tickets","Biglietti attuali",,
|
||||
"Customer","Cliente",,
|
||||
"Customer contact","Contatto con il cliente",,
|
||||
"Dates","Le date",,
|
||||
"Deadline","Scadenza",,
|
||||
"Description","Descrizione",,
|
||||
"Duration","Durata",,
|
||||
"End date","Data di fine",,
|
||||
"Follow-up","Seguito",,
|
||||
"From Date","Da Data",,
|
||||
"Helpdesk","Helpdesk",,
|
||||
"High","Alto",,
|
||||
"In progress","In corso",,
|
||||
"Late tickets","Biglietti in ritardo",,
|
||||
"Low","Basso",,
|
||||
"Mail subject","Oggetto della posta",,
|
||||
"Manage Timer","Gestire il timer",,
|
||||
"Minimum priority","Priorità minima",,
|
||||
"My team tickets","Biglietti della mia squadra",,
|
||||
"My tickets","I miei biglietti",,
|
||||
"Name","Nome",,
|
||||
"New","Nuovo",,
|
||||
"Normal","Normale",,
|
||||
"Not assigned tickets","Biglietti non assegnati",,
|
||||
"Number of tickets per SLA & per team","Numero di biglietti per SLA e per squadra",,
|
||||
"Number of tickets per SLA & per user","Numero di biglietti per SLA e per utente",,
|
||||
"Overview","Panoramica",,
|
||||
"Percentage","Percentuale",,
|
||||
"Percentage of repartition tickets per state","Percentuale di biglietti di ripartizione per Stato",,
|
||||
"Percentage of tickets per SLA & per team","Percentuale di biglietti per SLA e per squadra",,
|
||||
"Percentage of tickets per SLA & per user","Percentuale di biglietti per SLA e per utente",,
|
||||
"Please select tickets","Selezionare i biglietti",,
|
||||
"Priority","Priorità",,
|
||||
"Progress","Progressi",,
|
||||
"Progress (%)","Progressi (%)",,
|
||||
"Project","Il progetto",,
|
||||
"Projects","Progetti",,
|
||||
"Reach in","Raggiungere in",,
|
||||
"Reach stage","Raggiungere la fase",,
|
||||
"Real total duration (Hours)","Durata totale reale (ore)",,
|
||||
"Reportings","Rapporti",,
|
||||
"Resolve","Risolvere",,
|
||||
"Resolved","Risolto",,
|
||||
"SLA","SLA",,
|
||||
"SLA Details","Dettagli SLA",,
|
||||
"SLA Policy","Politica SLA",,
|
||||
"SLA completed","SLA completato",,
|
||||
"SLA dashboard","Cruscotto SLA",,
|
||||
"SLA policies","Politiche SLA",,
|
||||
"SLA policy name","Nome della polizza SLA",,
|
||||
"Start","Inizio",,
|
||||
"Start date","Data d'inizio",,
|
||||
"Status","Stato",,
|
||||
"Stop","Fermo",,
|
||||
"Subject","Oggetto",,
|
||||
"Take charge","Prendere in carico",,
|
||||
"Target","Obiettivo",,
|
||||
"Team","Squadra",,
|
||||
"Ticket","Biglietto",,
|
||||
"Ticket Closed","Biglietto Chiuso",,
|
||||
"Ticket Details","Dettagli del biglietto",,
|
||||
"Ticket In Progress","Biglietto in corso",,
|
||||
"Ticket In Resolved","Biglietto In Risolto",,
|
||||
"Ticket Number","Numero del biglietto",,
|
||||
"Ticket N°","Numero del biglietto",,
|
||||
"Ticket Type","Tipo di biglietto",,
|
||||
"Ticket created","Biglietto creato",,
|
||||
"Ticket dashboard","Biglietto dashboard",,
|
||||
"Ticket type","Tipo di biglietto",,
|
||||
"Ticket types","Tipi di biglietti",,
|
||||
"Tickets","Biglietti",,
|
||||
"Tickets by ticket type","Biglietti per tipo di biglietto",,
|
||||
"Timer","Timer",,
|
||||
"Timer list","Elenco dei timer",,
|
||||
"Timer state","Stato del timer",,
|
||||
"To Date","Fino ad oggi",,
|
||||
"Total duration (Hours)","Durata totale (ore)",,
|
||||
"Total tickets","Totale biglietti",,
|
||||
"Urgent","Urgente",,
|
||||
"User","Utente",,
|
||||
"User in charge of the issue","Utente responsabile dell'emissione",,
|
||||
"Working Days","Giorni lavorativi",,
|
||||
"days","giornate",,
|
||||
"hours","orario",,
|
||||
"info","Info",,
|
||||
"success","riuscita",,
|
||||
"value:Helpdesk","valore:Helpdesk",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Alle SLA",,
|
||||
"All ticket types","Alle soorten tickets",,
|
||||
"All tickets","Alle tickets",,
|
||||
"App helpdesk","App helpdesk",,
|
||||
"Apply on","Solliciteer op",,
|
||||
"Assign to me","Aan mij toewijzen",,
|
||||
"Assigned to","Toegewezen aan",,
|
||||
"Cancel","Annuleren",,
|
||||
"Characteristics","Kenmerken",,
|
||||
"Close","Sluiten",,
|
||||
"Closed","Gesloten",,
|
||||
"Code","Code",,
|
||||
"Configuration","Configuratie",,
|
||||
"Current tickets","Huidige tickets",,
|
||||
"Customer","Klant",,
|
||||
"Customer contact","Klant contact",,
|
||||
"Dates","Data",,
|
||||
"Deadline","Uiterste datum",,
|
||||
"Description","Beschrijving",,
|
||||
"Duration","Duur",,
|
||||
"End date","Einddatum",,
|
||||
"Follow-up","Follow-up",,
|
||||
"From Date","Vanaf datum",,
|
||||
"Helpdesk","Helpdesk",,
|
||||
"High","Hoog",,
|
||||
"In progress","In uitvoering",,
|
||||
"Late tickets","Late tickets",,
|
||||
"Low","Laag",,
|
||||
"Mail subject","Onderwerp van de post",,
|
||||
"Manage Timer","Beheer timer",,
|
||||
"Minimum priority","Minimale prioriteit",,
|
||||
"My team tickets","Mijn team tickets",,
|
||||
"My tickets","Mijn tickets",,
|
||||
"Name","Naam",,
|
||||
"New","Nieuw",,
|
||||
"Normal","Normaal",,
|
||||
"Not assigned tickets","Niet toegewezen tickets",,
|
||||
"Number of tickets per SLA & per team","Aantal tickets per SLA & per team",,
|
||||
"Number of tickets per SLA & per user","Aantal tickets per SLA & per gebruiker",,
|
||||
"Overview","Overzicht",,
|
||||
"Percentage","Percentage",,
|
||||
"Percentage of repartition tickets per state","Percentage repartitiekaartjes per staat",,
|
||||
"Percentage of tickets per SLA & per team","Percentage tickets per SLA & per team",,
|
||||
"Percentage of tickets per SLA & per user","Percentage tickets per SLA & per gebruiker",,
|
||||
"Please select tickets","Selecteer tickets",,
|
||||
"Priority","Prioriteit",,
|
||||
"Progress","Vooruitgang",,
|
||||
"Progress (%)","Vooruitgang (%)",,
|
||||
"Project","Project",,
|
||||
"Projects","Projecten",,
|
||||
"Reach in","Bereik in",,
|
||||
"Reach stage","Bereik stadium",,
|
||||
"Real total duration (Hours)","Reële totale duur (uren)",,
|
||||
"Reportings","Meldingen",,
|
||||
"Resolve","Oplossen",,
|
||||
"Resolved","Opgelost",,
|
||||
"SLA","SLA",,
|
||||
"SLA Details","SLA Details",,
|
||||
"SLA Policy","SLA-beleid",,
|
||||
"SLA completed","SLA voltooid",,
|
||||
"SLA dashboard","SLA dashboard",,
|
||||
"SLA policies","SLA-beleid",,
|
||||
"SLA policy name","SLA-beleidsnaam",,
|
||||
"Start","Begin",,
|
||||
"Start date","Startdatum",,
|
||||
"Status","Status",,
|
||||
"Stop","Stoppen",,
|
||||
"Subject","Onderwerp",,
|
||||
"Take charge","Neem de leiding",,
|
||||
"Target","Doel",,
|
||||
"Team","Team",,
|
||||
"Ticket","Ticket",,
|
||||
"Ticket Closed","Ticket gesloten",,
|
||||
"Ticket Details","Kaartdetails",,
|
||||
"Ticket In Progress","Ticket in uitvoering",,
|
||||
"Ticket In Resolved","Ticket In Opgelost",,
|
||||
"Ticket Number","Kaartnummer",,
|
||||
"Ticket N°","Kaartnummer",,
|
||||
"Ticket Type","Type ticket",,
|
||||
"Ticket created","Ticket aangemaakt",,
|
||||
"Ticket dashboard","Ticket dashboard",,
|
||||
"Ticket type","Type ticket",,
|
||||
"Ticket types","Soorten tickets",,
|
||||
"Tickets","Tickets",,
|
||||
"Tickets by ticket type","Tickets per type ticket",,
|
||||
"Timer","Timer",,
|
||||
"Timer list","Timer lijst",,
|
||||
"Timer state","Timer staat",,
|
||||
"To Date","Tot op heden",,
|
||||
"Total duration (Hours)","Totale duur (uren)",,
|
||||
"Total tickets","Totaal aantal tickets",,
|
||||
"Urgent","Dringend",,
|
||||
"User","Gebruiker",,
|
||||
"User in charge of the issue","Verantwoordelijke gebruiker van de uitgifte",,
|
||||
"Working Days","Werkdagen",,
|
||||
"days","dagen",,
|
||||
"hours","uren",,
|
||||
"info","info",,
|
||||
"success","succes",,
|
||||
"value:Helpdesk","waarde: Helpdesk",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Wszystkie SLA",,
|
||||
"All ticket types","Wszystkie rodzaje biletów",,
|
||||
"All tickets","Wszystkie bilety",,
|
||||
"App helpdesk","App helpdesk",,
|
||||
"Apply on","Zastosuj się na",,
|
||||
"Assign to me","Przypisz do mnie",,
|
||||
"Assigned to","Przypisany do",,
|
||||
"Cancel","Anulowanie",,
|
||||
"Characteristics","Charakterystyka",,
|
||||
"Close","Zamknięty",,
|
||||
"Closed","Zamknięta",,
|
||||
"Code","Kod",,
|
||||
"Configuration","Konfiguracja",,
|
||||
"Current tickets","Bilety bieżące",,
|
||||
"Customer","Klient",,
|
||||
"Customer contact","Kontakt z klientem",,
|
||||
"Dates","Daty",,
|
||||
"Deadline","Ostateczny termin",,
|
||||
"Description","Opis",,
|
||||
"Duration","Czas trwania pomocy",,
|
||||
"End date","Data końcowa",,
|
||||
"Follow-up","Działania następcze",,
|
||||
"From Date","Od daty",,
|
||||
"Helpdesk","Helpdesk",,
|
||||
"High","Wysoki",,
|
||||
"In progress","W trakcie realizacji",,
|
||||
"Late tickets","Bilety późne",,
|
||||
"Low","Niskie",,
|
||||
"Mail subject","Temat poczty",,
|
||||
"Manage Timer","Zarządzaj czasomierzem",,
|
||||
"Minimum priority","Minimalny priorytet",,
|
||||
"My team tickets","Moje bilety drużynowe",,
|
||||
"My tickets","Moje bilety",,
|
||||
"Name","Nazwa",,
|
||||
"New","Nowy",,
|
||||
"Normal","Normalny",,
|
||||
"Not assigned tickets","Nieprzypisane bilety",,
|
||||
"Number of tickets per SLA & per team","Liczba biletów na SLA i na zespół",,
|
||||
"Number of tickets per SLA & per user","Liczba biletów na SLA i na użytkownika",,
|
||||
"Overview","Przegląd",,
|
||||
"Percentage","Odsetek",,
|
||||
"Percentage of repartition tickets per state","Odsetek biletów powtórnych na państwo",,
|
||||
"Percentage of tickets per SLA & per team","Odsetek biletów na SLA i na zespół",,
|
||||
"Percentage of tickets per SLA & per user","Odsetek biletów na SLA i na użytkownika",,
|
||||
"Please select tickets","Proszę wybrać bilety.",,
|
||||
"Priority","Priorytet",,
|
||||
"Progress","Postępy",,
|
||||
"Progress (%)","Postępy (%)",,
|
||||
"Project","Projekt",,
|
||||
"Projects","Projekty",,
|
||||
"Reach in","Dotarcie do",,
|
||||
"Reach stage","Etap zaawansowany",,
|
||||
"Real total duration (Hours)","Rzeczywisty całkowity czas trwania (godziny)",,
|
||||
"Reportings","Sprawozdania",,
|
||||
"Resolve","Rozwiązanie",,
|
||||
"Resolved","Rozwiązane",,
|
||||
"SLA","SLA",,
|
||||
"SLA Details","Szczegóły SLA",,
|
||||
"SLA Policy","Polityka SLA",,
|
||||
"SLA completed","Ukończone SLA",,
|
||||
"SLA dashboard","Tablica rozdzielcza SLA",,
|
||||
"SLA policies","Polityka SLA",,
|
||||
"SLA policy name","Nazwa polityki SLA",,
|
||||
"Start","Start",,
|
||||
"Start date","Data początkowa",,
|
||||
"Status","Status",,
|
||||
"Stop","Zatrzymanie",,
|
||||
"Subject","Przedmiot",,
|
||||
"Take charge","Przejmij obowiązki",,
|
||||
"Target","Cel",,
|
||||
"Team","Zespół",,
|
||||
"Ticket","Bilet",,
|
||||
"Ticket Closed","Bilet Zamknięty",,
|
||||
"Ticket Details","Szczegóły biletu",,
|
||||
"Ticket In Progress","Bilet w toku",,
|
||||
"Ticket In Resolved","Ticket In Resolved",,
|
||||
"Ticket Number","Numer biletu",,
|
||||
"Ticket N°","Bilet nr",,
|
||||
"Ticket Type","Typ biletu",,
|
||||
"Ticket created","Utworzony bilet",,
|
||||
"Ticket dashboard","Tablica rozdzielcza biletu",,
|
||||
"Ticket type","Typ biletu",,
|
||||
"Ticket types","Rodzaje biletów",,
|
||||
"Tickets","Bilety",,
|
||||
"Tickets by ticket type","Bilety według rodzaju biletu",,
|
||||
"Timer","Timer",,
|
||||
"Timer list","Lista timerów",,
|
||||
"Timer state","Stan timera",,
|
||||
"To Date","Do daty",,
|
||||
"Total duration (Hours)","Całkowity czas trwania (godziny)",,
|
||||
"Total tickets","Bilety ogółem",,
|
||||
"Urgent","Pilny",,
|
||||
"User","Użytkownik",,
|
||||
"User in charge of the issue","Użytkownik odpowiedzialny za wydanie",,
|
||||
"Working Days","Dni robocze",,
|
||||
"days","czasy",,
|
||||
"hours","godziny",,
|
||||
"info","informacja",,
|
||||
"success","powodzenie",,
|
||||
"value:Helpdesk","wartość: Helpdesk",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Todos os SLA",,
|
||||
"All ticket types","Todos os tipos de bilhetes",,
|
||||
"All tickets","Todos os bilhetes",,
|
||||
"App helpdesk","Serviço de assistência da App",,
|
||||
"Apply on","Aplicar em",,
|
||||
"Assign to me","Atribuir-me",,
|
||||
"Assigned to","Atribuído a",,
|
||||
"Cancel","Cancelar",,
|
||||
"Characteristics","Características",,
|
||||
"Close","Fechar",,
|
||||
"Closed","Fechado",,
|
||||
"Code","Código",,
|
||||
"Configuration","Configuração",,
|
||||
"Current tickets","Bilhetes actuais",,
|
||||
"Customer","Cliente",,
|
||||
"Customer contact","Contato com o cliente",,
|
||||
"Dates","Datas",,
|
||||
"Deadline","Prazo de entrega",,
|
||||
"Description","Descrição do produto",,
|
||||
"Duration","Duração",,
|
||||
"End date","Data final",,
|
||||
"Follow-up","Acompanhamento",,
|
||||
"From Date","Data de início",,
|
||||
"Helpdesk","Helpdesk",,
|
||||
"High","Alto",,
|
||||
"In progress","Em curso",,
|
||||
"Late tickets","Bilhetes atrasados",,
|
||||
"Low","Baixo",,
|
||||
"Mail subject","Assunto do correio",,
|
||||
"Manage Timer","Gerir o temporizador",,
|
||||
"Minimum priority","Prioridade mínima",,
|
||||
"My team tickets","Os meus bilhetes de equipa",,
|
||||
"My tickets","Os meus bilhetes",,
|
||||
"Name","Nome e Sobrenome",,
|
||||
"New","Novo",,
|
||||
"Normal","Normal",,
|
||||
"Not assigned tickets","Bilhetes não atribuídos",,
|
||||
"Number of tickets per SLA & per team","Número de bilhetes por SLA e por equipa",,
|
||||
"Number of tickets per SLA & per user","Número de bilhetes por SLA e por usuário",,
|
||||
"Overview","Visão Geral",,
|
||||
"Percentage","Porcentagem",,
|
||||
"Percentage of repartition tickets per state","Porcentagem de bilhetes de repartição por estado",,
|
||||
"Percentage of tickets per SLA & per team","Percentagem de bilhetes por SLA e por equipa",,
|
||||
"Percentage of tickets per SLA & per user","Porcentagem de ingressos por SLA e por usuário",,
|
||||
"Please select tickets","Por favor, selecione os bilhetes",,
|
||||
"Priority","Prioridade",,
|
||||
"Progress","Progresso",,
|
||||
"Progress (%)","Progresso (%)",,
|
||||
"Project","Projeto",,
|
||||
"Projects","Projetos",,
|
||||
"Reach in","Alcance em",,
|
||||
"Reach stage","Estágio de alcance",,
|
||||
"Real total duration (Hours)","Duração total real (horas)",,
|
||||
"Reportings","Relatórios",,
|
||||
"Resolve","Resolver",,
|
||||
"Resolved","Resolvido",,
|
||||
"SLA","SLA",,
|
||||
"SLA Details","Detalhes do SLA",,
|
||||
"SLA Policy","Política de SLA",,
|
||||
"SLA completed","SLA concluído",,
|
||||
"SLA dashboard","Painel SLA",,
|
||||
"SLA policies","Políticas de SLA",,
|
||||
"SLA policy name","Nome da política de SLA",,
|
||||
"Start","Início",,
|
||||
"Start date","Data de início",,
|
||||
"Status","Estado",,
|
||||
"Stop","Parar",,
|
||||
"Subject","Assunto",,
|
||||
"Take charge","Assumir o comando",,
|
||||
"Target","Alvo",,
|
||||
"Team","Equipe",,
|
||||
"Ticket","Bilhete",,
|
||||
"Ticket Closed","Bilhete Fechado",,
|
||||
"Ticket Details","Detalhes do Bilhete",,
|
||||
"Ticket In Progress","Bilhete em andamento",,
|
||||
"Ticket In Resolved","Bilhete resolvido",,
|
||||
"Ticket Number","Número do bilhete",,
|
||||
"Ticket N°","Bilhete N°",,
|
||||
"Ticket Type","Tipo de bilhete",,
|
||||
"Ticket created","Bilhete criado",,
|
||||
"Ticket dashboard","Painel de controlo dos bilhetes",,
|
||||
"Ticket type","Tipo de bilhete",,
|
||||
"Ticket types","Tipos de bilhetes",,
|
||||
"Tickets","Bilhetes",,
|
||||
"Tickets by ticket type","Bilhetes por tipo de bilhete",,
|
||||
"Timer","Temporizador",,
|
||||
"Timer list","Lista de Temporizadores",,
|
||||
"Timer state","Estado do temporizador",,
|
||||
"To Date","Até à data",,
|
||||
"Total duration (Hours)","Duração total (horas)",,
|
||||
"Total tickets","Total de bilhetes",,
|
||||
"Urgent","Urgente",,
|
||||
"User","Usuário",,
|
||||
"User in charge of the issue","Utilizador responsável pela emissão",,
|
||||
"Working Days","Dias úteis",,
|
||||
"days","dias",,
|
||||
"hours","horas",,
|
||||
"info","informação",,
|
||||
"success","êxito",,
|
||||
"value:Helpdesk","valor:Helpdesk",,
|
||||
|
@ -0,0 +1,112 @@
|
||||
"key","message","comment","context"
|
||||
"0 %",,,
|
||||
"10 %",,,
|
||||
"100 %",,,
|
||||
"20 %",,,
|
||||
"30 %",,,
|
||||
"40 %",,,
|
||||
"50 %",,,
|
||||
"60 %",,,
|
||||
"70 %",,,
|
||||
"80 %",,,
|
||||
"90 %",,,
|
||||
"All SLA","Все SLA",,
|
||||
"All ticket types","Все типы билетов",,
|
||||
"All tickets","Все билеты",,
|
||||
"App helpdesk","Служба поддержки приложений",,
|
||||
"Apply on","Применить на",,
|
||||
"Assign to me","Назначить мне",,
|
||||
"Assigned to","Назначенный",,
|
||||
"Cancel","Отмена",,
|
||||
"Characteristics","Характеристики",,
|
||||
"Close","Близко",,
|
||||
"Closed","Закрытый",,
|
||||
"Code","Код",,
|
||||
"Configuration","Конфигурация",,
|
||||
"Current tickets","Текущие билеты",,
|
||||
"Customer","Клиент",,
|
||||
"Customer contact","Контакт с клиентом",,
|
||||
"Dates","Даты",,
|
||||
"Deadline","Крайний срок",,
|
||||
"Description","Описание",,
|
||||
"Duration","Продолжительность",,
|
||||
"End date","Дата окончания",,
|
||||
"Follow-up","Последующая деятельность",,
|
||||
"From Date","С даты",,
|
||||
"Helpdesk","Служба поддержки",,
|
||||
"High","Высоко",,
|
||||
"In progress","В процессе выполнения",,
|
||||
"Late tickets","Поздние билеты",,
|
||||
"Low","Низкий",,
|
||||
"Mail subject","Тема письма",,
|
||||
"Manage Timer","Управление таймером",,
|
||||
"Minimum priority","Минимальный приоритет",,
|
||||
"My team tickets","Мои командные билеты",,
|
||||
"My tickets","Мои билеты",,
|
||||
"Name","Имя",,
|
||||
"New","Новый",,
|
||||
"Normal","Нормальный",,
|
||||
"Not assigned tickets","Назначенные билеты не предоставляются",,
|
||||
"Number of tickets per SLA & per team","Количество билетов на SLA и на команду",,
|
||||
"Number of tickets per SLA & per user","Количество билетов на SLA & на одного пользователя",,
|
||||
"Overview","Обзор",,
|
||||
"Percentage","Процент",,
|
||||
"Percentage of repartition tickets per state","Процентная доля передельных билетов в расчете на штат",,
|
||||
"Percentage of tickets per SLA & per team","Процентная доля билетов на SLA и на команду",,
|
||||
"Percentage of tickets per SLA & per user","Процентная доля билетов на SLA и на одного пользователя",,
|
||||
"Please select tickets","Пожалуйста, выберите билеты",,
|
||||
"Priority","Приоритет",,
|
||||
"Progress","Прогресс",,
|
||||
"Progress (%)","Прогресс (%)",,
|
||||
"Project","Проект",,
|
||||
"Projects","Проекты",,
|
||||
"Reach in","Дотянуться",,
|
||||
"Reach stage","Достичь стадии",,
|
||||
"Real total duration (Hours)","Общая реальная продолжительность (в часах)",,
|
||||
"Reportings","Отчеты",,
|
||||
"Resolve","Решить",,
|
||||
"Resolved","Решил",,
|
||||
"SLA","СОГЛАШЕНИЕ ОБ УРОВНЕ ОБСЛУЖИВАНИЯ",,
|
||||
"SLA Details","Детали SLA",,
|
||||
"SLA Policy","Политика SLA",,
|
||||
"SLA completed","SLA выполнено",,
|
||||
"SLA dashboard","приборная панель SLA",,
|
||||
"SLA policies","политики SLA",,
|
||||
"SLA policy name","Название политики SLA",,
|
||||
"Start","Начать",,
|
||||
"Start date","Дата начала",,
|
||||
"Status","Статус",,
|
||||
"Stop","Остановись",,
|
||||
"Subject","Предмет",,
|
||||
"Take charge","Возьмите на себя ответственность",,
|
||||
"Target","Цель",,
|
||||
"Team","Команда",,
|
||||
"Ticket","Билет",,
|
||||
"Ticket Closed","Билет закрыт",,
|
||||
"Ticket Details","Детали билетов",,
|
||||
"Ticket In Progress","Билет в процессе оформления",,
|
||||
"Ticket In Resolved","Билет в разрешенном состоянии",,
|
||||
"Ticket Number","Номер билета",,
|
||||
"Ticket N°","Билет N°",,
|
||||
"Ticket Type","Тип билета",,
|
||||
"Ticket created","Созданный билет",,
|
||||
"Ticket dashboard","Приборная панель билетов",,
|
||||
"Ticket type","Тип билета",,
|
||||
"Ticket types","Типы билетов",,
|
||||
"Tickets","Билеты",,
|
||||
"Tickets by ticket type","Билеты по типам билетов",,
|
||||
"Timer","Таймер",,
|
||||
"Timer list","Список таймеров",,
|
||||
"Timer state","Состояние таймера",,
|
||||
"To Date","На свидание",,
|
||||
"Total duration (Hours)","Общая продолжительность (в часах)",,
|
||||
"Total tickets","Всего билетов",,
|
||||
"Urgent","Срочно",,
|
||||
"User","Пользователь",,
|
||||
"User in charge of the issue","Пользователь, ответственный за выпуск",,
|
||||
"Working Days","Рабочие дни",,
|
||||
"days","дни",,
|
||||
"hours","часы",,
|
||||
"info","данные",,
|
||||
"success","преуспевание",,
|
||||
"value:Helpdesk","значение:Служба поддержки",,
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<csv-inputs xmlns="http://axelor.com/xml/ns/data-import"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/data-import http://axelor.com/xml/ns/data-import/data-import_5.2.xsd">
|
||||
|
||||
<input file="helpdesk_role.csv" separator=";" type="com.axelor.auth.db.Role" search="self.name = :name"/>
|
||||
|
||||
<input file="helpdesk_permission.csv" separator=";" type="com.axelor.auth.db.Permission" search="self.name = :name" call="com.axelor.csv.script.ImportPermission:importPermissionToRole">
|
||||
<bind to="canRead" eval="can_read == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canWrite" eval="can_write == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canCreate" eval="can_create == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canRemove" eval="can_remove == 'x' ? 'true' : 'false'"/>
|
||||
<bind to="canExport" eval="can_export == 'x' ? 'true' : 'false'"/>
|
||||
</input>
|
||||
|
||||
<input file="helpdesk_metaMenu.csv" separator=";" type="com.axelor.meta.db.MetaMenu" search="self.name = :name" update="true">
|
||||
<bind column="roles" to="roles" search="self.name in :roles" eval="roles.split('\\|') as List"/>
|
||||
</input>
|
||||
|
||||
</csv-inputs>
|
||||
@ -0,0 +1,14 @@
|
||||
"name";"roles"
|
||||
"helpdesk-root";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-ticket-current";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-my-ticket-all";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-my-team-ticket-all";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-not-assigned-ticket";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-late-ticket";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-ticket-all";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-reporting";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-report-ticket";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-report-sla";"Helpdesk Manager|Helpdesk User|Helpdesk Read"
|
||||
"helpdesk-config";"Helpdesk Manager"
|
||||
"helpdesk-sla-policies-all";"Helpdesk Manager"
|
||||
"helpdesk-ticket-types-all";"Helpdesk Manager"
|
||||
|
@ -0,0 +1,10 @@
|
||||
"name";"object";"can_read";"can_write";"can_create";"can_remove";"can_export";"condition";"conditionParams";"roleName"
|
||||
"perm.helpdesk.Ticket.r";"com.axelor.apps.helpdesk.db.Ticket";"x";;;;;;;"Helpdesk Read"
|
||||
"perm.helpdesk.TicketType.r";"com.axelor.apps.helpdesk.db.TicketType";"x";;;;;;;"Helpdesk Read"
|
||||
"perm.helpdesk.Sla.r";"com.axelor.apps.helpdesk.db.Sla";"x";;;;;;;"Helpdesk Read"
|
||||
"perm.helpdesk.Ticket.rwc";"com.axelor.apps.helpdesk.db.Ticket";"x";"x";"x";;;;;"Helpdesk User"
|
||||
"perm.helpdesk.TicketType.rwc";"com.axelor.apps.helpdesk.db.TicketType";"x";"x";"x";;;;;"Helpdesk User"
|
||||
"perm.helpdesk.Sla.rwc";"com.axelor.apps.helpdesk.db.Sla";"x";"x";"x";;;;;"Helpdesk User"
|
||||
"perm.helpdesk.Ticket.rwcde";"com.axelor.apps.helpdesk.db.Ticket";"x";"x";"x";"x";"x";;;"Helpdesk Manager"
|
||||
"perm.helpdesk.TicketType.rwcde";"com.axelor.apps.helpdesk.db.TicketType";"x";"x";"x";"x";"x";;;"Helpdesk Manager"
|
||||
"perm.helpdesk.Sla.rwcde";"com.axelor.apps.helpdesk.db.Sla";"x";"x";"x";"x";"x";;;"Helpdesk Manager"
|
||||
|
@ -0,0 +1,4 @@
|
||||
"name";"description"
|
||||
"Helpdesk Read";
|
||||
"Helpdesk User";
|
||||
"Helpdesk Manager";
|
||||
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
|
||||
<form name="app-helpdesk-config-form" title="App helpdesk" model="com.axelor.apps.base.db.AppHelpdesk" canDelete="false" canNew="false" width="large">
|
||||
<panel name="mainPanel">
|
||||
<field name="isSla" widget="boolean-switch" colSpan="3"/>
|
||||
<field name="manageTimer" widget="boolean-switch" colSpan="3"/>
|
||||
</panel>
|
||||
|
||||
<panel-mail name="mailPanel">
|
||||
<mail-messages limit="4" />
|
||||
<mail-followers />
|
||||
</panel-mail>
|
||||
</form>
|
||||
|
||||
</object-views>
|
||||
@ -0,0 +1,333 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
<chart name="chart.ticket.no.of.solved.my.ticket" title="My tickets" onInit="action.ticket.chart.set.date.1m">
|
||||
<search-fields>
|
||||
<field name="fromDate" title="From Date" type="date" x-required="true"/>
|
||||
<field name="toDate" title="To Date" type="date" x-required="true"/>
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) AS total_row,
|
||||
'ALL' as _status
|
||||
FROM
|
||||
helpdesk_ticket
|
||||
WHERE
|
||||
DATE(created_on) BETWEEN DATE(:fromDate) AND DATE(:toDate)
|
||||
AND assigned_to_user = :_user_id
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) AS total_row,
|
||||
'Resolved' as _status
|
||||
FROM
|
||||
helpdesk_ticket
|
||||
WHERE
|
||||
DATE(created_on) BETWEEN DATE(:fromDate) AND DATE(:toDate)
|
||||
AND assigned_to_user = :_user_id
|
||||
AND status_select = 2
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="total_row" type="bar" title="Total tickets"/>
|
||||
</chart>
|
||||
|
||||
<chart name="chart.ticket.no.of.solved.my.team.ticket" title="My team tickets" onInit="action.ticket.chart.set.date.1m">
|
||||
<search-fields>
|
||||
<field name="fromDate" title="From Date" type="date" x-required="true"/>
|
||||
<field name="toDate" title="To Date" type="date" x-required="true"/>
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) AS total_row,
|
||||
'ALL' as _status
|
||||
FROM
|
||||
helpdesk_ticket AS self
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = :_user_id
|
||||
JOIN
|
||||
team_team AS _team
|
||||
ON
|
||||
_user.active_team = _team.id
|
||||
WHERE
|
||||
DATE(self.created_on) BETWEEN DATE(:fromDate) AND DATE(:toDate)
|
||||
AND _team.id = :_myActiveTeam
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) AS total_row,
|
||||
'Resolved' as _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = :_user_id
|
||||
JOIN
|
||||
team_team AS _team
|
||||
ON
|
||||
_user.active_team = _team.id
|
||||
WHERE
|
||||
DATE(_ticket.created_on) BETWEEN DATE(:fromDate) AND DATE(:toDate)
|
||||
AND _team.id = :_myActiveTeam
|
||||
AND _ticket.status_select = 2
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="total_row" type="bar" title="Total tickets"/>
|
||||
</chart>
|
||||
|
||||
|
||||
<chart onInit="action.ticket.chart.set.date.1m" name="chart.ticket.no.of.solved.all.ticket" title="All tickets">
|
||||
<search-fields>
|
||||
<field type="date" name="fromDate" title="From Date" x-required="true" />
|
||||
<field type="date" name="toDate" title="To Date" x-required="true" />
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) AS total_row,
|
||||
'ALL' as _status
|
||||
FROM
|
||||
helpdesk_ticket
|
||||
WHERE
|
||||
DATE(created_on) BETWEEN DATE(:fromDate) AND DATE(:toDate)
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) AS total_row,
|
||||
'Resolved' as _status
|
||||
FROM
|
||||
helpdesk_ticket
|
||||
WHERE
|
||||
DATE(created_on) BETWEEN DATE(:fromDate) AND DATE(:toDate)
|
||||
AND status_select = 2
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="total_row" type="bar" title="Tickets"/>
|
||||
</chart>
|
||||
|
||||
<chart name="chart.SLA.percentage.ticket.solved.not.solved.in.time.per.SLA.per.team" title="Percentage of tickets per SLA & per team">
|
||||
<search-fields>
|
||||
<field name="sla" title="SLA" type="reference" target="com.axelor.apps.helpdesk.db.Sla" x-required="true"/>
|
||||
<field name="team" title="Team" type="reference" target="com.axelor.team.db.Team" x-required="true"/>
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) * 100 / (SELECT COUNT(*) FROM helpdesk_ticket) AS _percentage,
|
||||
'Solved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
team_team AS _team
|
||||
ON
|
||||
_team.id = _user.active_team
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = true
|
||||
AND _sla.id = :sla
|
||||
AND _team.id = :team
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) * 100 / (SELECT COUNT(*) FROM helpdesk_ticket) AS _percentage,
|
||||
'Unsolved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
team_team AS _team
|
||||
ON
|
||||
_team.id = _user.active_team
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = false
|
||||
AND _sla.id = :sla
|
||||
AND _team.id = :team
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="_percentage" type="pie" title="Percentage"/>
|
||||
<config name="percent" value="true"/>
|
||||
</chart>
|
||||
|
||||
<chart name="chart.SLA.percentage.ticket.solved.not.solved.in.time.per.SLA.per.user" title="Percentage of tickets per SLA & per user">
|
||||
<search-fields>
|
||||
<field name="sla" title="SLA" type="reference" target="com.axelor.apps.helpdesk.db.Sla" x-required="true"/>
|
||||
<field name="user" title="User" type="reference" target="com.axelor.auth.db.User" x-required="true"/>
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) * 100 / (SELECT COUNT(*) FROM helpdesk_ticket) AS _percentage,
|
||||
'Solved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = true
|
||||
AND _sla.id = :sla
|
||||
AND _user.id = :user
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) * 100 / (SELECT COUNT(*) FROM helpdesk_ticket) AS _percentage,
|
||||
'Unsolved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = false
|
||||
AND _sla.id = :sla
|
||||
AND _user.id = :user
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="_percentage" type="pie" title="Percentage"/>
|
||||
<config name="percent" value="true"/>
|
||||
</chart>
|
||||
|
||||
<chart name="chart.SLA.number.of.ticket.solved.not.solved.in.time.per.SLA.per.team" title="Number of tickets per SLA & per team">
|
||||
<search-fields>
|
||||
<field name="sla" title="SLA" type="reference" target="com.axelor.apps.helpdesk.db.Sla" x-required="true"/>
|
||||
<field name="team" title="Team" type="reference" target="com.axelor.team.db.Team" x-required="true"/>
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) AS _total,
|
||||
'Solved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
team_team AS _team
|
||||
ON
|
||||
_team.id = _user.active_team
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = true
|
||||
AND _sla.id = :sla
|
||||
AND _team.id = :team
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) AS _total,
|
||||
'Unsolved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
team_team AS _team
|
||||
ON
|
||||
_team.id = _user.active_team
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = false
|
||||
AND _sla.id = :sla
|
||||
AND _team.id = :team
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="_total" type="bar" title="Total tickets"/>
|
||||
</chart>
|
||||
|
||||
<chart name="chart.SLA.number.of.ticket.solved.not.solved.in.time.per.SLA.per.user" title="Number of tickets per SLA & per user">
|
||||
<search-fields>
|
||||
<field name="sla" title="SLA" type="reference" target="com.axelor.apps.helpdesk.db.Sla" x-required="true"/>
|
||||
<field name="user" title="User" type="reference" target="com.axelor.auth.db.User" x-required="true"/>
|
||||
</search-fields>
|
||||
<dataset type="sql">
|
||||
SELECT
|
||||
COUNT(*) AS _total,
|
||||
'Solved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = true
|
||||
AND _sla.id = :sla
|
||||
AND _user.id = :user
|
||||
UNION ALL
|
||||
SELECT
|
||||
COUNT(*) AS _total,
|
||||
'Unsolved' AS _status
|
||||
FROM
|
||||
helpdesk_ticket AS _ticket1
|
||||
JOIN
|
||||
auth_user AS _user
|
||||
ON
|
||||
_user.id = _ticket1.assigned_to_user
|
||||
JOIN
|
||||
helpdesk_sla AS _sla
|
||||
ON
|
||||
_sla.id = _ticket1.sla_policy
|
||||
WHERE
|
||||
_ticket1.is_sla_completed = false
|
||||
AND _sla.id = :sla
|
||||
AND _user.id = :user
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status"/>
|
||||
<series key="_total" type="bar" title="Total tickets"/>
|
||||
</chart>
|
||||
|
||||
<action-record model="com.axelor.apps.helpdesk.db.Ticket" name="action.ticket.chart.set.date.1m">
|
||||
<field name="toDate" expr="eval:__date__" />
|
||||
<field name="fromDate" expr="eval:__date__.minusMonths(1)" />
|
||||
</action-record>
|
||||
|
||||
|
||||
<chart name="chart.ticket.type.percentage.repartition.ticket.per.state"
|
||||
title="Percentage of repartition tickets per state">
|
||||
<dataset type="jpql">
|
||||
<![CDATA[
|
||||
SELECT COUNT(self.id) * 100. / (SELECT COUNT(self2.id) FROM Ticket self2 WHERE self2.ticketType = :id) AS _percentage,
|
||||
CASE self.statusSelect WHEN 0 THEN 'New' WHEN 1 THEN 'In progress' WHEN 2 THEN 'Resolved' ELSE 'Closed' END AS _status
|
||||
FROM Ticket self
|
||||
WHERE self.ticketType = :id
|
||||
GROUP BY self.statusSelect
|
||||
ORDER BY self.statusSelect
|
||||
]]>
|
||||
</dataset>
|
||||
<category key="_status" type="text" title="Status" />
|
||||
<series key="_percentage" groupBy="_status" type="pie" title="Percentage" />
|
||||
<config name="percent" value="true" />
|
||||
</chart>
|
||||
|
||||
</object-views>
|
||||
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
<dashboard title="Ticket dashboard" name="helpdesk.ticket.dashboard">
|
||||
<dashlet action="chart:chart.ticket.no.of.solved.my.ticket" colSpan="6" />
|
||||
<dashlet action="chart:chart.ticket.no.of.solved.my.team.ticket" colSpan="6"/>
|
||||
<dashlet action="chart:chart.ticket.no.of.solved.all.ticket" colSpan="12"/>
|
||||
</dashboard>
|
||||
|
||||
<dashboard name="helpdesk.sla.dashboard" title="SLA dashboard">
|
||||
<dashlet action="chart:chart.SLA.percentage.ticket.solved.not.solved.in.time.per.SLA.per.team" colSpan="6" />
|
||||
<dashlet action="chart:chart.SLA.percentage.ticket.solved.not.solved.in.time.per.SLA.per.user" colSpan="6" />
|
||||
<dashlet action="chart:chart.SLA.number.of.ticket.solved.not.solved.in.time.per.SLA.per.team" colSpan="6" />
|
||||
<dashlet action="chart:chart.SLA.number.of.ticket.solved.not.solved.in.time.per.SLA.per.user" colSpan="6" />
|
||||
</dashboard>
|
||||
|
||||
</object-views>
|
||||
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
<menuitem name="helpdesk-root" title="Helpdesk" order="-80" if="__config__.app.isApp('helpdesk')"
|
||||
icon="fa-life-ring" icon-background="#b6473f"/>
|
||||
|
||||
<menuitem title="Current tickets" name="helpdesk-ticket-current" action="helpdesk.ticket.current" order="-100" parent="helpdesk-root"/>
|
||||
|
||||
<action-view name="helpdesk.ticket.current" title="Tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="kanban" name="ticket-kanban"/>
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<view type="calendar" name="ticket-calendar"/>
|
||||
<domain>self.statusSelect in (0,1)</domain>
|
||||
<context name="_user" expr="eval: __user__"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="My tickets" name="helpdesk-my-ticket-all" action="helpdesk.my.ticket.all" order="-90" parent="helpdesk-root"/>
|
||||
|
||||
<action-view name="helpdesk.my.ticket.all" title="My tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="kanban" name="ticket-kanban"/>
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<view type="calendar" name="ticket-calendar"/>
|
||||
<domain>self.assignedToUser = :_user</domain>
|
||||
<context name="_user" expr="eval: __user__"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="My team tickets" name="helpdesk-my-team-ticket-all" action="helpdesk.my.team.ticket.all" order="-80" parent="helpdesk-root"/>
|
||||
|
||||
<action-view name="helpdesk.my.team.ticket.all" title="My team tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="kanban" name="ticket-kanban"/>
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<view type="calendar" name="ticket-calendar"/>
|
||||
<domain>self.assignedToUser.activeTeam = :_myActiveTeam</domain>
|
||||
<context name="_myActiveTeam" expr="call:com.axelor.apps.base.service.user.UserService:getUserActiveTeam()"/>
|
||||
<context name="_user" expr="eval: __user__"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="Not assigned tickets" name="helpdesk-not-assigned-ticket" action="helpdesk.not.assigned.ticket" order="-70" parent="helpdesk-root"/>
|
||||
|
||||
<action-view name="helpdesk.not.assigned.ticket" title="Not assigned tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="kanban" name="ticket-kanban"/>
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<view type="calendar" name="ticket-calendar"/>
|
||||
<domain>self.assignedToUser = null</domain>
|
||||
<context name="_user" expr="eval: __user__"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="Late tickets" name="helpdesk-late-ticket" action="helpdesk.late.ticket" order="-60" parent="helpdesk-root"/>
|
||||
|
||||
<action-view name="helpdesk.late.ticket" title="Late tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="kanban" name="ticket-kanban"/>
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<view type="calendar" name="ticket-calendar"/>
|
||||
<domain>(self.endDateT != null and self.endDateT > self.deadlineDateT) or (self.endDateT = null and self.deadlineDateT < :_date)</domain>
|
||||
<context name="_date" expr="eval: __datetime__"/>
|
||||
<context name="_user" expr="eval: __user__"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="All tickets" name="helpdesk-ticket-all" action="helpdesk.ticket.all" order="-50" parent="helpdesk-root"/>
|
||||
|
||||
<action-view name="helpdesk.ticket.all" title="All tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="kanban" name="ticket-kanban"/>
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<view type="calendar" name="ticket-calendar"/>
|
||||
<context name="_user" expr="eval: __user__"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="Reportings" name="helpdesk-reporting" order="-20" parent="helpdesk-root" icon="fa-bar-chart"/>
|
||||
|
||||
<menuitem title="Ticket" name="helpdesk-report-ticket" action="helpdesk.report.ticket" parent="helpdesk-reporting"/>
|
||||
|
||||
<action-view name="helpdesk.report.ticket" title="Ticket Details">
|
||||
<view type="dashboard" name="helpdesk.ticket.dashboard"/>
|
||||
<context name="_user_id" expr="eval:__user__.id" />
|
||||
<context name="_myActiveTeam" expr="eval:__user__.activeTeam != null ? __user__.activeTeam.id : 0"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="SLA" name="helpdesk-report-sla" action="helpdesk.report.sla" parent="helpdesk-reporting" if="__config__.app.getApp('helpdesk').getIsSla()"/>
|
||||
|
||||
<action-view name="helpdesk.report.sla" title="SLA Details">
|
||||
<view name="helpdesk.sla.dashboard" type="dashboard"/>
|
||||
<context name="_user_id" expr="eval:__user__.id"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="Configuration" name="helpdesk-config" order="-10" parent="helpdesk-root" icon="fa-cog"/>
|
||||
|
||||
<menuitem title="SLA policies" name="helpdesk-sla-policies-all" action="helpdesk.sla.policies.all" parent="helpdesk-config" if="__config__.app.getApp('helpdesk').getIsSla()"/>
|
||||
|
||||
<action-view name="helpdesk.sla.policies.all" title="SLA policies" model="com.axelor.apps.helpdesk.db.Sla">
|
||||
<view type="grid" name="sla-grid"/>
|
||||
<view type="form" name="sla-form"/>
|
||||
</action-view>
|
||||
|
||||
<menuitem title="Ticket types" name="helpdesk-ticket-types-all" action="helpdesk-ticket-types-all" parent="helpdesk-config"/>
|
||||
|
||||
<action-view name="helpdesk-ticket-types-all" title="Ticket types" model="com.axelor.apps.helpdesk.db.TicketType">
|
||||
<view type="grid" name="ticket-type-grid"/>
|
||||
<view type="form" name="ticket-type-form"/>
|
||||
</action-view>
|
||||
|
||||
</object-views>
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
|
||||
<grid name="helpdesk-project-grid" title="Projects" model="com.axelor.apps.project.db.Project">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
</grid>
|
||||
|
||||
<form name="helpdesk-project-form" title="Project" model="com.axelor.apps.project.db.Project">
|
||||
<panel name="overviewPanel" title="Overview">
|
||||
<field name="fullName" showTitle="false" colSpan="12" css="label-bold bold large">
|
||||
<editor x-show-titles="false">
|
||||
<field name="code" required="true" x-bind="{{code|unaccent|uppercase}}" showTitle="false" css="label-bold bold large" colSpan="3"/>
|
||||
<field name="name" required="true" showTitle="false" css="label-bold bold large" colSpan="9"/>
|
||||
</editor>
|
||||
</field>
|
||||
</panel>
|
||||
</form>
|
||||
|
||||
</object-views>
|
||||
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
<selection name="helpdesk.priority.select">
|
||||
<option value="1">Low</option>
|
||||
<option value="2">Normal</option>
|
||||
<option value="3">High</option>
|
||||
<option value="4">Urgent</option>
|
||||
</selection>
|
||||
|
||||
<selection name="helpdesk.status.select">
|
||||
<option value="0">New</option>
|
||||
<option value="1">In progress</option>
|
||||
<option value="2">Resolved</option>
|
||||
<option value="3">Closed</option>
|
||||
</selection>
|
||||
|
||||
<selection name="helpdesk.ticket.progress.select">
|
||||
<option value="0">0 %</option>
|
||||
<option value="10">10 %</option>
|
||||
<option value="20">20 %</option>
|
||||
<option value="30">30 %</option>
|
||||
<option value="40">40 %</option>
|
||||
<option value="50">50 %</option>
|
||||
<option value="60">60 %</option>
|
||||
<option value="70">70 %</option>
|
||||
<option value="80">80 %</option>
|
||||
<option value="90">90 %</option>
|
||||
<option value="100">100 %</option>
|
||||
</selection>
|
||||
|
||||
<selection name="sequence.generic.code.select" id="helpdesk.sequence.generic.code.select">
|
||||
<option value="ticket">Ticket</option>
|
||||
</selection>
|
||||
|
||||
</object-views>
|
||||
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
|
||||
<grid name="sla-grid" title="All SLA" model="com.axelor.apps.helpdesk.db.Sla">
|
||||
<field name="name"/>
|
||||
<field name="team"/>
|
||||
<field name="ticketType"/>
|
||||
<field name="reachStageSelect" />
|
||||
<field name="prioritySelect"/>
|
||||
</grid>
|
||||
|
||||
<form model="com.axelor.apps.helpdesk.db.Sla" title="SLA" name="sla-form">
|
||||
|
||||
<panel name="mainPanel">
|
||||
<field name="name" colSpan="12"/>
|
||||
|
||||
<panel name="applyOnPanel" title="Apply on" colSpan="12">
|
||||
<field name="team" form-view="team-form" grid-view="team-grid"/>
|
||||
<field name="prioritySelect"/>
|
||||
<field name="ticketType"/>
|
||||
</panel>
|
||||
|
||||
<panel name="targetPanel" title="Target" colSpan="12">
|
||||
<field name="reachStageSelect"/>
|
||||
<field name="reachIn" title="Reach in">
|
||||
<viewer>
|
||||
<![CDATA[
|
||||
<span>{{record.days}} <b>days</b></span><br />
|
||||
<span>{{record.hours}} <b>hours</b></span>
|
||||
]]>
|
||||
</viewer>
|
||||
<editor>
|
||||
<field name="days" colSpan="3"/>
|
||||
<field name="hours" colSpan="3"/>
|
||||
</editor>
|
||||
</field>
|
||||
<field name="isWorkingDays"/>
|
||||
</panel>
|
||||
</panel>
|
||||
|
||||
<panel name="descriptionPanel" title="Description">
|
||||
<field name="description" showTitle="false" widget="html" colSpan="12"/>
|
||||
</panel>
|
||||
|
||||
</form>
|
||||
</object-views>
|
||||
@ -0,0 +1,290 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
|
||||
<grid name="ticket-grid" title="All tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<toolbar>
|
||||
<button name="takeChargeBtn" title="Assign to me" icon="fa-suitcase" onClick="com.axelor.apps.helpdesk.web.TicketController:assignToMeTicket"/>
|
||||
</toolbar>
|
||||
<field name="ticketSeq" width="120"/>
|
||||
<field name="subject"/>
|
||||
<field name="ticketType"/>
|
||||
<field name="startDateT"/>
|
||||
<field name="endDateT"/>
|
||||
<field name="deadlineDateT"/>
|
||||
<field name="assignedToUser"/>
|
||||
<field name="prioritySelect"/>
|
||||
<field name="statusSelect"/>
|
||||
<field name="timerState" hidden="true"/>
|
||||
<field name="progressSelect" widget="SelectProgress"/>
|
||||
<button name="takeChargeBtn" icon="fa-suitcase" help="Take charge" onClick="com.axelor.apps.helpdesk.web.TicketController:assignToMeTicket" readonlyIf="statusSelect == 3"/>
|
||||
<button name="startTicketBtn" icon="fa-play" onClick="action-ticket-group-on-start" readonlyIf="timerState == true || statusSelect == 3"/>
|
||||
<button name="pauseBtn" icon="fa-pause" onClick="action-ticket-group-on-pause" readonlyIf="timerState == false || statusSelect == 3"/>
|
||||
<button name="validateTicketBtn" icon="fa-check" onClick="action-ticket-group-on-validate" readonlyIf="statusSelect == 3"/>
|
||||
<button name="finishTicketBtn" icon="fa-power-off" onClick="action-ticket-group-on-close" readonlyIf="statusSelect == 3"/>
|
||||
</grid>
|
||||
|
||||
<form model="com.axelor.apps.helpdesk.db.Ticket" title="Ticket" name="ticket-form" onNew="action-ticket-group-on-new" onLoad="action-ticket-group-timer-process">
|
||||
<panel name="mainPanel" colSpan="12">
|
||||
<field name="statusSelect" colSpan="12" readonly="true" widget="NavSelect" showTitle="false" onChange="action-record-to-set-progress-select"/>
|
||||
<field name="ticketSeq" showTitle="false">
|
||||
<viewer depends="ticketSeq">
|
||||
<![CDATA[
|
||||
<h3>
|
||||
<span style="margin: 5px 0 !important; display: inline-table; line-height: initial;"><span x-translate>Ticket N° </span>{{record.ticketSeq}}</span>
|
||||
</h3>
|
||||
]]>
|
||||
</viewer>
|
||||
</field>
|
||||
<panel name="progressPanel" colSpan="6" itemSpan="12">
|
||||
<field name="progressSelect" widget="SelectProgress">
|
||||
<editor>
|
||||
<field name="progressSelect" colSpan="6" showTitle="false"/>
|
||||
</editor>
|
||||
</field>
|
||||
</panel>
|
||||
<field name="subject" colSpan="12"/>
|
||||
<field name="mailSubject"/>
|
||||
|
||||
<field name="slaPolicy" showTitle="false" readonly="true" hideIf="statusSelect >= slaPolicy.reachStageSelect">
|
||||
<viewer><![CDATA[
|
||||
<h3>
|
||||
<span class="label label-important" ng-if="record.slaPolicy">{{record.slaPolicy.name}}</span>
|
||||
</h3>
|
||||
]]></viewer>
|
||||
</field>
|
||||
</panel>
|
||||
|
||||
<panel name="otherDetailsPanel" colSpan="12">
|
||||
<field name="project" if-module="axelor-project" onChange="action-ticket-record-value-on-customer-and-contact" form-view="helpdesk-project-form" grid-view="helpdesk-project-grid"/>
|
||||
<field name="customer" domain="self.isCustomer = true" form-view="partner-form" grid-view="partner-grid"/>
|
||||
<field name="contactPartner" onSelect="action-ticket-domain-on-contact-partner" form-view="partner-contact-form" grid-view="partner-contact-grid"/>
|
||||
</panel>
|
||||
|
||||
<panel-tabs name="mainPanelTab">
|
||||
<panel name="descriptionPanel" colSpan="12" title="Description">
|
||||
<field name="description" showTitle="false" colSpan="12" widget="html"/>
|
||||
</panel>
|
||||
|
||||
<panel name="timerPanel" title="Timer" showIf="id" hidden="true" sidebar="true" if="__config__.app.getApp('helpdesk').getManageTimer()">
|
||||
<button name="startTimerBtn" title="Start" icon="fa-play" colSpan="4" hidden="true"
|
||||
onClick="action-ticket-method-start-timer"/>
|
||||
<button name="stopTimerBtn" title="Stop" icon="fa-pause" colSpan="4" hidden="true"
|
||||
onClick="action-ticket-method-stop-timer"/>
|
||||
<button name="cancelTimerBtn" title="Cancel" icon="fa-times-circle" colSpan="4"
|
||||
hidden="true" onClick="action-ticket-method-cancel-timer" css="btn-danger"/>
|
||||
<field name="$_totalTimerDuration" type="decimal" readonly="true"
|
||||
title="Total duration (Hours)" colSpan="4"/>
|
||||
<field name="realTotalDuration" colSpan="4"/>
|
||||
<field name="timerState" hidden="true" colSpan="4"/>
|
||||
</panel>
|
||||
</panel-tabs>
|
||||
|
||||
<panel name="actionsPanel" sidebar="true">
|
||||
<button name="startTicketBtn" title="Start" icon="fa-play" hideIf="statusSelect > 0" onClick="save,action-ticket-group-on-start"/>
|
||||
<button name="validateTicketBtn" title="Resolve" icon="fa-check" hideIf="statusSelect > 1" onClick="save,action-ticket-group-on-validate"/>
|
||||
<button name="finishTicketBtn" title="Close" icon="fa-power-off" css="btn-danger" hideIf="statusSelect > 2" onClick="save,action-ticket-group-on-close"/>
|
||||
</panel>
|
||||
|
||||
<panel name="characteristicsPanel" title="Characteristics" sidebar="true" canCollapse="true">
|
||||
<field name="ticketType" colSpan="12"/>
|
||||
<field name="prioritySelect" colSpan="6"/>
|
||||
<field name="deadlineDateT" colSpan="6"/>
|
||||
<field name="isSlaCompleted" hidden="true"/>
|
||||
</panel>
|
||||
<panel name="followupPanel" title="Follow-up" sidebar="true" canCollapse="true">
|
||||
<field name="assignedToUser" colSpan="6" form-view="user-form" grid-view="user-grid"/>
|
||||
<field name="responsibleUser" colSpan="6" form-view="user-form" grid-view="user-grid"/>
|
||||
<field name="lead" colSpan="6" form-view="lead-form" grid-view="lead-grid" if-module="axelor-crm" if="__config__.app.isApp('crm')"/>
|
||||
</panel>
|
||||
<panel name="datesPanel" title="Dates" sidebar="true" canCollapse="true">
|
||||
<field name="startDateT" colSpan="6" onChange="action-ticket-method-compute-from-start-date-time"/>
|
||||
<field name="endDateT" colSpan="6" onChange="action-ticket-method-compute-from-end-date-time"/>
|
||||
<field name="duration" colSpan="6" widget="duration" x-big="true" onChange="action-ticket-method-compute-from-duration"/>
|
||||
</panel>
|
||||
<panel name="attrsPanel">
|
||||
<field name="attrs" hidden="true"/>
|
||||
</panel>
|
||||
<panel-mail name="mailPanel">
|
||||
<mail-messages limit="6"/>
|
||||
<mail-followers/>
|
||||
</panel-mail>
|
||||
</form>
|
||||
|
||||
<calendar name="ticket-calendar" model="com.axelor.apps.helpdesk.db.Ticket"
|
||||
eventStart="startDateT"
|
||||
eventStop="endDateT"
|
||||
title="All tickets"
|
||||
colorBy="assignedToUser">
|
||||
<field name="subject"/>
|
||||
<field name="statusSelect"/>
|
||||
</calendar>
|
||||
|
||||
<kanban columnBy="statusSelect" sequenceBy="prioritySelect" limit="10"
|
||||
name="ticket-kanban" title="Tickets" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="ticketSeq"/>
|
||||
<field name="subject"/>
|
||||
<field name="progressSelect"/>
|
||||
<field name="project.name"/>
|
||||
<field name="ticketType"/>
|
||||
<hilite color="primary" if="prioritySelect == 1"/>
|
||||
<hilite color="info" if="prioritySelect == 2"/>
|
||||
<hilite color="warning" if="prioritySelect == 3"/>
|
||||
<hilite color="danger" if="prioritySelect == 4"/>
|
||||
<template>
|
||||
<![CDATA[
|
||||
<h4>{{record.ticketSeq}}</h4>
|
||||
<div class="card-body">
|
||||
<p>{{record.subject}}</p>
|
||||
<dl>
|
||||
<dt ng-show="record.progressSelect" x-translate>Progress</dt>
|
||||
<dd ng-if="record.progressSelect == 80 || record.progressSelect == 90 || record.progressSelect == 100"><div class="progress progress-striped progress-success">
|
||||
<div class="bar" style="width: {{record.progressSelect}}%;"></div></div>
|
||||
</dd>
|
||||
<dd ng-if="record.progressSelect == 50 || record.progressSelect == 60 || record.progressSelect == 70"><div class="progress progress-striped progress-primary">
|
||||
<div class="bar" style="width: {{record.progressSelect}}%;"></div></div>
|
||||
</dd>
|
||||
<dd ng-if="record.progressSelect == 30 || record.progressSelect == 40"><div class="progress progress-striped progress-warning">
|
||||
<div class="bar" style="width: {{record.progressSelect}}%;"></div></div>
|
||||
</dd>
|
||||
<dd ng-if="record.progressSelect == 10 || record.progressSelect == 20"><div class="progress progress-striped progress-danger">
|
||||
<div class="bar" style="width: {{record.progressSelect}}%;"></div></div>
|
||||
</dd>
|
||||
<dt ng-show="record.project.name" x-translate>Project</dt><dd ng-show="record.project.name">{{record.project.name}}</dd>
|
||||
<dt ng-show="record.ticketType.name" x-translate>Ticket Type</dt><dd ng-show="record.ticketType.name">{{record.ticketType.name}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
]]>
|
||||
</template>
|
||||
</kanban>
|
||||
|
||||
<action-record name="action-ticket-record-value-on-customer-and-contact" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="customer" expr="eval: project.clientPartner"/>
|
||||
<field name="contactPartner" expr="eval: project.contactPartner"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-set-start-status" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="statusSelect" expr="1" if="statusSelect == 0"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-set-validate-status" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="statusSelect" expr="2" if="statusSelect <= 1"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-set-closed-status" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="statusSelect" expr="3" if="statusSelect <= 2"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-to-set-progress-select" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="progressSelect" expr="100" if="statusSelect == 2"/>
|
||||
<field name="progressSelect" expr="0" if="statusSelect != 2"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-to-fill-startDate" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="startDateT" expr="eval: __datetime__"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-to-fill-endDate" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="endDateT" expr="eval: __datetime__"/>
|
||||
</action-record>
|
||||
|
||||
<action-record name="action-ticket-record-set-customer" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<field name="customer" expr="eval: __user__?.partner" if="__user__?.partner?.isCustomer"/>
|
||||
</action-record>
|
||||
|
||||
<action-group name="action-ticket-group-on-new">
|
||||
<action name="action-ticket-record-to-fill-startDate"/>
|
||||
<action name="action-ticket-record-set-customer"/>
|
||||
</action-group>
|
||||
|
||||
<action-group name="action-ticket-group-on-start">
|
||||
<action name="action-ticket-method-start-timer"/>
|
||||
<action name="action-ticket-method-play"/>
|
||||
<action name="action-ticket-record-to-fill-startDate"/>
|
||||
<action name="action-ticket-method-compute-from-start-date-time"/>
|
||||
<action name="action-ticket-record-set-start-status"/>
|
||||
<action name="save"/>
|
||||
</action-group>
|
||||
|
||||
<action-group name="action-ticket-group-on-validate">
|
||||
<action name="action-ticket-method-stop-timer"/>
|
||||
<action name="action-ticket-method-pause"/>
|
||||
<action name="action-ticket-method-compute-real-total-duration"/>
|
||||
<action name="action-ticket-record-to-fill-endDate"/>
|
||||
<action name="action-ticket-method-compute-from-end-date-time"/>
|
||||
<action name="action-ticket-record-set-validate-status"/>
|
||||
<action name="action-ticket-record-to-set-progress-select"/>
|
||||
<action name="save"/>
|
||||
</action-group>
|
||||
|
||||
<action-group name="action-ticket-group-on-close">
|
||||
<action name="action-ticket-method-stop-timer"/>
|
||||
<action name="action-ticket-method-pause"/>
|
||||
<action name="action-ticket-method-compute-real-total-duration"/>
|
||||
<action name="action-ticket-record-set-closed-status"/>
|
||||
<action name="save"/>
|
||||
</action-group>
|
||||
|
||||
<action-group name="action-ticket-group-on-pause">
|
||||
<action name="action-ticket-method-stop-timer"/>
|
||||
<action name="action-ticket-method-pause"/>
|
||||
<action name="save"/>
|
||||
</action-group>
|
||||
|
||||
<action-method name="action-ticket-method-compute-from-start-date-time">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="computeFromStartDateTime"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-compute-from-duration">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="computeFromDuration"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-compute-from-end-date-time">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="computeFromEndDateTime"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-pause" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="timerStateOff"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-play" model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="timerStateOn"/>
|
||||
</action-method>
|
||||
|
||||
<action-attrs name="action-ticket-domain-on-contact-partner">
|
||||
<attribute for="contactPartner" if="customer != null && !customer.contactPartnerSet.empty" name="domain" expr="eval: "self.id IN (${customer.contactPartnerSet?.collect{it.id}.join(',')})""/>
|
||||
<attribute for="contactPartner" if="customer != null && customer.contactPartnerSet.empty" name="domain" expr="eval: "self.id IN (0)""/>
|
||||
<attribute for="contactPartner" if="customer == null" name="domain" expr="eval: "self.isContact = true""/>
|
||||
</action-attrs>
|
||||
|
||||
<action-method name="action-ticket-method-manage-timer-buttons">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="manageTimerButtons"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-compute-total-timer-duration">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController"
|
||||
method="computeTotalTimerDuration"/>
|
||||
</action-method>
|
||||
|
||||
<action-group name="action-ticket-group-timer-process">
|
||||
<action name="action-ticket-method-manage-timer-buttons" if="__config__.app.getApp('helpdesk').manageTimer"/>
|
||||
<action name="action-ticket-method-compute-total-timer-duration" if="__config__.app.getApp('helpdesk').manageTimer"/>
|
||||
</action-group>
|
||||
|
||||
<action-method name="action-ticket-method-start-timer">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="startTimer"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-stop-timer">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="stopTimer"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-cancel-timer">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="cancelTimer"/>
|
||||
</action-method>
|
||||
|
||||
<action-method name="action-ticket-method-compute-real-total-duration">
|
||||
<call class="com.axelor.apps.helpdesk.web.TicketController" method="computeRealDuration"/>
|
||||
</action-method>
|
||||
</object-views>
|
||||
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<object-views xmlns="http://axelor.com/xml/ns/object-views" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://axelor.com/xml/ns/object-views http://axelor.com/xml/ns/object-views/object-views_5.2.xsd">
|
||||
|
||||
|
||||
<grid name="ticket-type-grid" title="All ticket types" model="com.axelor.apps.helpdesk.db.TicketType">
|
||||
<field name="name"/>
|
||||
</grid>
|
||||
|
||||
<form model="com.axelor.apps.helpdesk.db.TicketType" title="Ticket type"
|
||||
name="ticket-type-form" width="large">
|
||||
<panel name="namePanel">
|
||||
<field name="name"/>
|
||||
</panel>
|
||||
|
||||
<panel-dashlet name="ticketByTicketTypePanel" action="dashlet.ticket.by.ticket.type" colSpan="12"/>
|
||||
|
||||
<panel-dashlet name="repartitionTicketPerStateDashletPanel"
|
||||
action="chart:chart.ticket.type.percentage.repartition.ticket.per.state"
|
||||
colSpan="12"/>
|
||||
</form>
|
||||
|
||||
<action-view name="dashlet.ticket.by.ticket.type" title="Tickets by ticket type"
|
||||
model="com.axelor.apps.helpdesk.db.Ticket">
|
||||
<view type="grid" name="ticket-grid"/>
|
||||
<view type="form" name="ticket-form"/>
|
||||
<domain>self.ticketType = :id </domain>
|
||||
</action-view>
|
||||
|
||||
</object-views>
|
||||
Reference in New Issue
Block a user