com.aoindustries.aoserv.client.ticket.Ticket Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aoserv-client Show documentation
Show all versions of aoserv-client Show documentation
Java client for the AOServ Platform.
/*
* aoserv-client - Java client for the AOServ Platform.
* Copyright (C) 2000-2013, 2016, 2017, 2018, 2019, 2020 AO Industries, Inc.
* [email protected]
* 7262 Bull Pen Cir
* Mobile, AL 36695
*
* This file is part of aoserv-client.
*
* aoserv-client is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* aoserv-client 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with aoserv-client. If not, see .
*/
package com.aoindustries.aoserv.client.ticket;
import com.aoindustries.aoserv.client.AOServConnector;
import com.aoindustries.aoserv.client.CachedObjectIntegerKey;
import com.aoindustries.aoserv.client.account.Account;
import com.aoindustries.aoserv.client.account.Administrator;
import com.aoindustries.aoserv.client.account.Profile;
import com.aoindustries.aoserv.client.account.User;
import com.aoindustries.aoserv.client.reseller.Brand;
import com.aoindustries.aoserv.client.reseller.Category;
import com.aoindustries.aoserv.client.reseller.Reseller;
import com.aoindustries.aoserv.client.schema.AoservProtocol;
import com.aoindustries.aoserv.client.schema.Table;
import com.aoindustries.collections.AoCollections;
import com.aoindustries.collections.IntList;
import com.aoindustries.io.stream.StreamableInput;
import com.aoindustries.io.stream.StreamableOutput;
import com.aoindustries.lang.Strings;
import com.aoindustries.net.Email;
import com.aoindustries.sql.UnmodifiableTimestamp;
import com.aoindustries.util.InternUtils;
import com.aoindustries.validation.ValidationException;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* The Ticket
system allows clients to submit support
* requests and monitor the progress of the work.
*
* @see Action
* @see Priority
* @see TicketType
*
* @author AO Industries, Inc.
*/
final public class Ticket extends CachedObjectIntegerKey {
//
private Account.Name brand;
private Account.Name reseller;
private Account.Name accounting;
private String language;
private User.Name created_by;
private int category;
private String ticket_type;
private Email from_address;
private String summary;
private boolean detailsLoaded;
private String details;
private boolean rawEmailLoaded;
private String raw_email;
private UnmodifiableTimestamp open_date;
private String client_priority;
private String admin_priority;
private String status;
private UnmodifiableTimestamp status_timeout;
private Set contact_emails;
private String contact_phone_numbers;
private boolean internalNotesLoaded;
private String internal_notes;
//
//
@Override
public String toStringImpl() {
if(reseller != null) {
return pkey+"|"+brand+'/'+accounting+'|'+status+"->"+reseller;
} else {
return pkey+"|"+brand+'/'+accounting+'|'+status;
}
}
//
//
static final int COLUMN_PKEY = 0;
static final int COLUMN_ACCOUNTING = 3;
static final int COLUMN_CREATED_BY = 5;
static final int COLUMN_OPEN_DATE = 12;
static final String COLUMN_PKEY_name = "pkey";
static final String COLUMN_OPEN_DATE_name = "open_date";
@Override
protected Object getColumnImpl(int i) throws IOException, SQLException {
switch(i) {
case COLUMN_PKEY: return pkey;
case 1: return brand;
case 2: return reseller;
case COLUMN_ACCOUNTING: return accounting;
case 4: return language;
case COLUMN_CREATED_BY: return created_by;
case 6: return category==-1 ? null : category;
case 7: return ticket_type;
case 8: return from_address;
case 9: return summary;
case 10: return getDetails();
case 11: return getRawEmail();
case COLUMN_OPEN_DATE: return open_date;
case 13: return client_priority;
case 14: return admin_priority;
case 15: return status;
case 16: return status_timeout;
// TODO: Support array types
case 17: return Strings.join(contact_emails, ", ");
case 18: return contact_phone_numbers;
case 19: return getInternalNotes();
default: throw new IllegalArgumentException("Invalid index: " + i);
}
}
@Override
public Table.TableID getTableID() {
return Table.TableID.TICKETS;
}
@Override
public void init(ResultSet result) throws SQLException {
try {
int pos = 1;
pkey = result.getInt(pos++);
brand = Account.Name.valueOf(result.getString(pos++));
reseller = Account.Name.valueOf(result.getString(pos++));
accounting = Account.Name.valueOf(result.getString(pos++));
language = result.getString(pos++);
created_by = User.Name.valueOf(result.getString(pos++));
category = result.getInt(pos++); if(result.wasNull()) category = -1;
ticket_type = result.getString(pos++);
from_address = Email.valueOf(result.getString(pos++));
summary = result.getString(pos++);
open_date = UnmodifiableTimestamp.valueOf(result.getTimestamp(pos++));
client_priority = result.getString(pos++);
admin_priority = result.getString(pos++);
status = result.getString(pos++);
status_timeout = UnmodifiableTimestamp.valueOf(result.getTimestamp(pos++));
// TODO: Array in PostgreSQL
String str = result.getString(pos++);
try {
contact_emails = Profile.splitEmails(str);
} catch(ValidationException e) {
throw new SQLException("contact_emails = " + str, e);
}
contact_phone_numbers = result.getString(pos++);
} catch(ValidationException e) {
throw new SQLException(e);
}
}
@Override
public void read(StreamableInput in, AoservProtocol.Version protocolVersion) throws IOException {
try {
pkey = in.readCompressedInt();
brand = Account.Name.valueOf(in.readUTF()).intern();
String resellerStr = in.readUTF();
if(AoservProtocol.FILTERED.equals(resellerStr)) {
reseller = null;
} else {
reseller = Account.Name.valueOf(resellerStr).intern();
}
accounting = InternUtils.intern(Account.Name.valueOf(in.readNullUTF()));
language = in.readUTF().intern();
created_by = InternUtils.intern(User.Name.valueOf(in.readNullUTF()));
category = in.readCompressedInt();
ticket_type = in.readUTF().intern();
from_address = Email.valueOf(in.readNullUTF());
summary = in.readUTF();
open_date = in.readUnmodifiableTimestamp();
client_priority = in.readUTF().intern();
admin_priority = InternUtils.intern(in.readNullUTF());
status = in.readUTF().intern();
status_timeout = in.readNullUnmodifiableTimestamp();
{
int size = in.readCompressedInt();
Set emails = new LinkedHashSet<>(size*4/3+1);
for(int i = 0; i < size; i++) {
emails.add(Email.valueOf(in.readUTF()));
}
contact_emails = AoCollections.optimalUnmodifiableSet(emails);
}
contact_phone_numbers = in.readUTF();
} catch(ValidationException e) {
throw new IOException(e);
}
}
@Override
public void write(StreamableOutput out, AoservProtocol.Version protocolVersion) throws IOException {
out.writeCompressedInt(pkey);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_46)>=0) out.writeUTF(brand.toString());
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_44)>=0) out.writeUTF(reseller==null ? AoservProtocol.FILTERED : reseller.toString());
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_0_A_125)<=0) {
out.writeUTF(accounting==null ? "" : accounting.toString());
} else {
out.writeNullUTF(Objects.toString(accounting, null));
}
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_44)>=0) out.writeUTF(language);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_0_A_125)<=0) {
out.writeUTF(created_by==null ? "" : created_by.toString());
} else {
out.writeNullUTF(Objects.toString(created_by, null));
}
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_44)>=0) out.writeCompressedInt(category);
out.writeUTF(ticket_type);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_44)>=0) out.writeNullUTF(Objects.toString(from_address, null));
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_44)>=0) out.writeUTF(summary);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_14)<=0) out.writeUTF("");
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_15)>=0 && protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_43)<=0) out.writeCompressedInt(0); // details
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_83_0) < 0) {
out.writeLong(open_date.getTime());
} else {
out.writeTimestamp(open_date);
}
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_43)<=0) out.writeLong(-1);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_43)<=0) out.writeLong(-1);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_43)<=0) out.writeNullUTF(null);
out.writeUTF(client_priority);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_10)<0) {
out.writeUTF(admin_priority==null ? client_priority : admin_priority);
} else {
out.writeNullUTF(admin_priority);
}
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_43)<=0) out.writeNullUTF(null); // technology
out.writeUTF(status);
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_44) >= 0) {
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_83_0) < 0) {
out.writeLong(status_timeout == null ? -1 : status_timeout.getTime());
} else {
out.writeNullTimestamp(status_timeout);
}
}
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_0_A_125)>=0 && protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_43)<=0) out.writeNullUTF(null); // assigned_to
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_0_A_125)>=0) {
if(protocolVersion.compareTo(AoservProtocol.Version.VERSION_1_81_22) < 0) {
out.writeUTF(Strings.join(contact_emails, ", "));
} else {
int size = contact_emails.size();
out.writeCompressedInt(size);
for(Email email : contact_emails) out.writeUTF(email.toString());
}
out.writeUTF(contact_phone_numbers);
}
}
//
//
public int getTicketID() {
return pkey;
}
/**
* May be filtered.
*/
public Brand getBrand() throws IOException, SQLException {
return table.getConnector().getReseller().getBrand().get(brand);
}
/**
* May be null when filtered.
*/
public Reseller getReseller() throws SQLException, IOException {
if(reseller == null) return null;
return table.getConnector().getReseller().getReseller().get(reseller);
}
public Account.Name getAccount_name() {
return accounting;
}
/**
* May be null if not set or filtered.
*/
public Account getAccount() throws SQLException, IOException {
if(accounting == null) return null;
return table.getConnector().getAccount().getAccount().get(accounting);
}
public Language getLanguage() throws SQLException, IOException {
Language la = table.getConnector().getTicket().getLanguage().get(language);
if(la==null) throw new SQLException("Unable to find Language: "+language);
return la;
}
public Administrator getCreatedBy() throws IOException, SQLException {
if(created_by == null) return null;
// Data may be filtered by APIs
return table.getConnector().getAccount().getAdministrator().get(created_by);
}
public Category getCategory() throws IOException, SQLException {
if(category==-1) return null;
Category tc = table.getConnector().getReseller().getCategory().get(category);
if(tc==null) throw new SQLException("Unable to find TicketCategory: "+category);
return tc;
}
public TicketType getTicketType() throws IOException, SQLException {
TicketType ticketTypeObject = table.getConnector().getTicket().getTicketType().get(ticket_type);
if (ticketTypeObject == null) throw new SQLException("Unable to find TicketType: " + ticket_type);
return ticketTypeObject;
}
public Email getFromAddress() {
return from_address;
}
public String getSummary() {
return summary;
}
synchronized public String getDetails() throws IOException, SQLException {
if(!detailsLoaded) {
details = table.getConnector().requestNullLongStringQuery(true, AoservProtocol.CommandID.GET_TICKET_DETAILS, pkey);
detailsLoaded = true;
}
return details;
}
synchronized public String getRawEmail() throws IOException, SQLException {
if(!rawEmailLoaded) {
raw_email = table.getConnector().requestNullLongStringQuery(true, AoservProtocol.CommandID.GET_TICKET_RAW_EMAIL, pkey);
rawEmailLoaded = true;
}
return raw_email;
}
public UnmodifiableTimestamp getOpenDate() {
return open_date;
}
public Priority getClientPriority() throws IOException, SQLException {
Priority clientPriorityObject = table.getConnector().getTicket().getPriority().get(client_priority);
if (clientPriorityObject == null) throw new SQLException("Unable to find Priority: " + client_priority);
return clientPriorityObject;
}
public Priority getAdminPriority() throws IOException, SQLException {
if(admin_priority==null) return null;
Priority adminPriorityObject = table.getConnector().getTicket().getPriority().get(admin_priority);
if (adminPriorityObject == null) throw new SQLException("Unable to find Priority: " + admin_priority);
return adminPriorityObject;
}
public Status getStatus() throws IOException, SQLException {
Status statusObject = table.getConnector().getTicket().getStatus().get(status);
if (statusObject == null) throw new SQLException("Unable to find status: " + status);
return statusObject;
}
public UnmodifiableTimestamp getStatusTimeout() {
return status_timeout;
}
public Set getContactEmails() {
return contact_emails;
}
public String getContactPhoneNumbers() {
return contact_phone_numbers;
}
synchronized public String getInternalNotes() throws IOException, SQLException {
if(!internalNotesLoaded) {
internal_notes = table.getConnector().requestLongStringQuery(true, AoservProtocol.CommandID.GET_TICKET_INTERNAL_NOTES, pkey);
internalNotesLoaded = true;
}
return internal_notes;
}
//
//
public List getTicketActions() throws IOException, SQLException {
return table.getConnector().getTicket().getAction().getActions(this);
}
public List getTicketAssignments() throws IOException, SQLException {
return table.getConnector().getTicket().getAssignment().getTicketAssignments(this);
}
//
//
/*
public void actBounceTicket(Administrator administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AOServProtocol.CommandID.BOUNCE_TICKET, pkey, administrator.getUsername_id(), comments);
}*/
public void actChangeAdminPriority(Priority priority, Administrator business_administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AoservProtocol.CommandID.CHANGE_TICKET_ADMIN_PRIORITY, pkey, priority==null ? "" : priority.getPriority(), business_administrator.getUsername_userId(), comments);
}
public void setClientPriority(Priority clientPriority) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AoservProtocol.CommandID.CHANGE_TICKET_CLIENT_PRIORITY, pkey, clientPriority.getPriority());
}
public void setSummary(String summary) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AoservProtocol.CommandID.SET_TICKET_SUMMARY, pkey, summary);
}
public void addAnnotation(final String summary, final String details) throws IOException, SQLException {
table.getConnector().requestUpdate(
true,
AoservProtocol.CommandID.ADD_TICKET_ANNOTATION,
new AOServConnector.UpdateRequest() {
IntList invalidateList;
@Override
public void writeRequest(StreamableOutput out) throws IOException {
out.writeCompressedInt(pkey);
out.writeUTF(summary);
out.writeNullLongUTF(details);
}
@Override
public void readResponse(StreamableInput in) throws IOException, SQLException {
int code=in.readByte();
if(code==AoservProtocol.DONE) {
invalidateList=AOServConnector.readInvalidateList(in);
} else {
AoservProtocol.checkResult(code, in);
throw new IOException("Unexpected response code: "+code);
}
}
@Override
public void afterRelease() {
table.getConnector().tablesUpdated(invalidateList);
}
}
);
}
public void actAssignTo(Administrator assignedTo, Administrator business_administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AoservProtocol.CommandID.SET_TICKET_ASSIGNED_TO, pkey, assignedTo==null?"":assignedTo.getUsername().getUsername(), business_administrator.getUsername_userId(), comments);
}
public void setContactEmails(final Set contactEmails) throws IOException, SQLException {
final AOServConnector connector = table.getConnector();
connector.requestUpdate(
true,
AoservProtocol.CommandID.SET_TICKET_CONTACT_EMAILS,
new AOServConnector.UpdateRequest() {
IntList invalidateList;
@Override
public void writeRequest(StreamableOutput out) throws IOException {
out.writeCompressedInt(pkey);
out.writeCompressedInt(contactEmails.size());
for(Email email : contactEmails) out.writeUTF(email.toString());
}
@Override
public void readResponse(StreamableInput in) throws IOException, SQLException {
int code=in.readByte();
if(code==AoservProtocol.DONE) {
invalidateList=AOServConnector.readInvalidateList(in);
} else {
AoservProtocol.checkResult(code, in);
throw new IOException("Unexpected response code: "+code);
}
}
@Override
public void afterRelease() {
connector.tablesUpdated(invalidateList);
}
}
);
}
public void setContactPhoneNumbers(String contactPhoneNumbers) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AoservProtocol.CommandID.SET_TICKET_CONTACT_PHONE_NUMBERS, pkey, contactPhoneNumbers);
}
/*
public void actCompleteTicket(Administrator administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AOServProtocol.CommandID.COMPLETE_TICKET, pkey, administrator.getUsername_userId(), comments);
}*/
/*
public void actHoldTicket(String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AOServProtocol.CommandID.HOLD_TICKET, pkey, comments);
}*/
/*
public void actKillTicket(Administrator administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AOServProtocol.CommandID.KILL_TICKET, pkey, administrator.getUsername_userId(), comments);
}*/
/*
public void actReactivateTicket(Administrator administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AOServProtocol.CommandID.REACTIVATE_TICKET, pkey, administrator.getUsername_userId(), comments);
}*/
public void actWorkEntry(Administrator administrator, String comments) throws IOException, SQLException {
table.getConnector().requestUpdateIL(true, AoservProtocol.CommandID.TICKET_WORK, pkey, administrator.getUsername_userId(), comments);
}
/**
* Updates the ticket business if the old business matches the current value.
*
* @return true
if successfully updated or false
if oldAccount doesn't match the current business.
*/
public boolean setAccount(Account oldAccount, Account newAccount) throws IOException, SQLException {
return table.getConnector().requestBooleanQueryIL(
true,
AoservProtocol.CommandID.SET_TICKET_BUSINESS,
pkey,
oldAccount==null ? "" : oldAccount.getName().toString(),
newAccount==null ? "" : newAccount.getName().toString()
);
}
/**
* Updates the ticket type if the old value matches the current value.
*
* @return true
if successfully updated or false
if oldType doesn't match the current type.
*/
public boolean setTicketType(TicketType oldType, TicketType newType) throws IOException, SQLException {
return table.getConnector().requestBooleanQueryIL(true, AoservProtocol.CommandID.CHANGE_TICKET_TYPE, pkey, oldType.getType(), newType.getType());
// table.getConnector().requestUpdateIL(true, AOServProtocol.CommandID.CHANGE_TICKET_TYPE, pkey, ticket_type.pkey, business_administrator.getUsername_userId(), comments);
}
/**
* Updates the ticket status if the old status matches the current value.
*
* @return true
if successfully updated or false
if oldStatus doesn't match the current status.
*/
public boolean setStatus(Status oldStatus, Status newStatus, long statusTimeout) throws IOException, SQLException {
return table.getConnector().requestBooleanQueryIL(true, AoservProtocol.CommandID.SET_TICKET_STATUS, pkey, oldStatus.getStatus(), newStatus.getStatus(), statusTimeout);
}
/**
* Updates the internal notes if the old value matches the current value.
*
* @return true
if successfully updated or false
if oldInternalNotes doesn't match the current internal notes.
*/
public boolean setInternalNotes(final String oldInternalNotes, final String newInternalNotes) throws IOException, SQLException {
return table.getConnector().requestResult(
true,
AoservProtocol.CommandID.SET_TICKET_INTERNAL_NOTES,
new AOServConnector.ResultRequest() {
boolean result;
IntList invalidateList;
@Override
public void writeRequest(StreamableOutput out) throws IOException {
out.writeCompressedInt(pkey);
out.writeLongUTF(oldInternalNotes);
out.writeLongUTF(newInternalNotes);
}
@Override
public void readResponse(StreamableInput in) throws IOException, SQLException {
int code = in.readByte();
if(code==AoservProtocol.DONE) {
result = in.readBoolean();
invalidateList = AOServConnector.readInvalidateList(in);
} else {
AoservProtocol.checkResult(code, in);
throw new IOException("Unexpected response code: "+code);
}
}
@Override
public Boolean afterRelease() {
table.getConnector().tablesUpdated(invalidateList);
return result;
}
}
);
}
//
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy