2018-06-20 20:24:50 +00:00
package connectwise
import (
"encoding/json"
"fmt"
2018-07-10 02:48:02 +00:00
"strconv"
2018-06-20 20:24:50 +00:00
)
2018-07-10 01:25:08 +00:00
//ServiceTeam is a struct to hold the unmarshaled JSON data when making a call to the service API
type ServiceTeam struct {
ID int ` json:"id" `
Name string ` json:"name" `
Leader struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
} ` json:"_info" `
} ` json:"leader" `
Location struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
LocationHref string ` json:"location_href" `
} ` json:"_info" `
} ` json:"location" `
Department struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
DepartmentHref string ` json:"department_href" `
} ` json:"_info" `
} ` json:"department" `
DeleteNotifyFlag bool ` json:"deleteNotifyFlag" `
Info struct {
2018-08-24 01:34:39 +00:00
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
DateEntered string ` json:"dateEntered" `
EnteredBy string ` json:"enteredBy" `
2018-07-10 01:25:08 +00:00
} ` json:"_info" `
}
//BoardTeam is a struct to hold the unmarshaled JSON data when making a call to the service API
type BoardTeam struct {
ID int ` json:"id" `
Name string ` json:"name" `
TeamLeader struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
} ` json:"_info" `
} ` json:"teamLeader" `
Members [ ] int ` json:"members" `
DefaultFlag bool ` json:"defaultFlag" `
NotifyOnTicketDelete bool ` json:"notifyOnTicketDelete" `
BoardID int ` json:"boardId" `
LocationID int ` json:"locationId" `
BusinessUnitID int ` json:"businessUnitId" `
Info struct {
2018-08-24 01:34:39 +00:00
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
2018-07-10 01:25:08 +00:00
} ` json:"_info" `
}
2018-07-10 16:46:10 +00:00
type BoardStatus struct {
ID int ` json:"id" `
Name string ` json:"name" `
Board struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
BoardHref string ` json:"board_href" `
} ` json:"_info" `
} ` json:"board" `
ExternalIntegrationXref struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
StatusExternalIntegrationHref string ` json:"statusExternalIntegration_href" `
} ` json:"_info" `
} ` json:"externalIntegrationXref,omitempty" `
SortOrder int ` json:"sortOrder" `
DisplayOnBoard bool ` json:"displayOnBoard" `
Inactive bool ` json:"inactive" `
ClosedStatus bool ` json:"closedStatus" `
TimeEntryNotAllowed bool ` json:"timeEntryNotAllowed" `
DefaultFlag bool ` json:"defaultFlag" `
EscalationStatus string ` json:"escalationStatus" `
CustomerPortalDescription string ` json:"customerPortalDescription,omitempty" `
CustomerPortalFlag bool ` json:"customerPortalFlag" `
EmailTemplate struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Info struct {
EmailTemplateHref string ` json:"emailTemplate_href" `
} ` json:"_info" `
} ` json:"emailTemplate,omitempty" `
Info struct {
2018-08-24 01:34:39 +00:00
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
DateEntered string ` json:"dateEntered" `
EnteredBy string ` json:"enteredBy" `
2018-07-10 16:46:10 +00:00
} ` json:"_info" `
}
2018-07-07 00:26:11 +00:00
//Ticket is a struct to hold the unmarshaled JSON data when making a call to the Service API
2018-06-20 20:24:50 +00:00
type Ticket struct {
ID int ` json:"id" `
Summary string ` json:"summary" `
RecordType string ` json:"recordType" `
Board struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
BoardHref string ` json:"board_href" `
} ` json:"_info" `
} ` json:"board" `
Status struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
StatusHref string ` json:"status_href" `
} ` json:"_info" `
} ` json:"status" `
Company struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
CompanyHref string ` json:"company_href" `
MobileGUID string ` json:"mobileGuid" `
} ` json:"_info" `
} ` json:"company" `
Site struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
SiteHref string ` json:"site_href" `
MobileGUID string ` json:"mobileGuid" `
} ` json:"_info" `
} ` json:"site,omitempty" `
AddressLine1 string ` json:"addressLine1,omitempty" `
City string ` json:"city,omitempty" `
StateIdentifier string ` json:"stateIdentifier,omitempty" `
Zip string ` json:"zip,omitempty" `
ContactName string ` json:"contactName" `
ContactPhoneNumber string ` json:"contactPhoneNumber" `
ContactEmailAddress string ` json:"contactEmailAddress,omitempty" `
Team struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
TeamHref string ` json:"team_href" `
} ` json:"_info" `
} ` json:"team" `
Priority struct {
ID int ` json:"id" `
Name string ` json:"name" `
Sort int ` json:"sort" `
Info struct {
PriorityHref string ` json:"priority_href" `
ImageHref string ` json:"image_href" `
} ` json:"_info" `
} ` json:"priority" `
ServiceLocation struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
LocationHref string ` json:"location_href" `
} ` json:"_info" `
} ` json:"serviceLocation" `
Source struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
SourceHref string ` json:"source_href" `
} ` json:"_info" `
} ` json:"source" `
Agreement struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
AgreementHref string ` json:"agreement_href" `
} ` json:"_info" `
} ` json:"agreement,omitempty" `
2018-08-24 01:34:39 +00:00
Severity string ` json:"severity" `
Impact string ` json:"impact" `
AllowAllClientsPortalView bool ` json:"allowAllClientsPortalView" `
CustomerUpdatedFlag bool ` json:"customerUpdatedFlag" `
AutomaticEmailContactFlag bool ` json:"automaticEmailContactFlag" `
AutomaticEmailResourceFlag bool ` json:"automaticEmailResourceFlag" `
AutomaticEmailCcFlag bool ` json:"automaticEmailCcFlag" `
ClosedDate string ` json:"closedDate" `
ClosedBy string ` json:"closedBy" `
ClosedFlag bool ` json:"closedFlag" `
DateEntered string ` json:"dateEntered" `
EnteredBy string ` json:"enteredBy" `
ActualHours float64 ` json:"actualHours,omitempty" `
Approved bool ` json:"approved" `
EstimatedExpenseCost float64 ` json:"estimatedExpenseCost" `
EstimatedExpenseRevenue float64 ` json:"estimatedExpenseRevenue" `
EstimatedProductCost float64 ` json:"estimatedProductCost" `
EstimatedProductRevenue float64 ` json:"estimatedProductRevenue" `
EstimatedTimeCost float64 ` json:"estimatedTimeCost" `
EstimatedTimeRevenue float64 ` json:"estimatedTimeRevenue" `
BillingMethod string ` json:"billingMethod" `
SubBillingMethod string ` json:"subBillingMethod" `
DateResolved string ` json:"dateResolved" `
DateResplan string ` json:"dateResplan" `
DateResponded string ` json:"dateResponded" `
ResolveMinutes int ` json:"resolveMinutes" `
ResPlanMinutes int ` json:"resPlanMinutes" `
RespondMinutes int ` json:"respondMinutes" `
IsInSLA bool ` json:"isInSla" `
HasChildTicket bool ` json:"hasChildTicket" `
BillTime string ` json:"billTime" `
BillExpenses string ` json:"billExpenses" `
BillProducts string ` json:"billProducts" `
LocationID int ` json:"locationId" `
BusinessUnitID int ` json:"businessUnitId" `
MobileGUID string ` json:"mobileGuid" `
2018-06-20 20:24:50 +00:00
SLA struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
SLAHref string ` json:"sla_href" `
} ` json:"_info" `
} ` json:"sla" `
Currency struct {
ID int ` json:"id" `
Symbol string ` json:"symbol" `
IsoCode string ` json:"isoCode" `
Name string ` json:"name" `
Info struct {
CurrencyHref string ` json:"currency_href" `
} ` json:"_info" `
} ` json:"currency" `
Info struct {
2018-08-24 01:34:39 +00:00
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
ActivitiesHref string ` json:"activities_href" `
ScheduleentriesHref string ` json:"scheduleentries_href" `
DocumentsHref string ` json:"documents_href" `
ConfigurationsHref string ` json:"configurations_href" `
TasksHref string ` json:"tasks_href" `
NotesHref string ` json:"notes_href" `
ProductsHref string ` json:"products_href" `
TimeentriesHref string ` json:"timeentries_href" `
ExpenseEntriesHref string ` json:"expenseEntries_href" `
2018-06-20 20:24:50 +00:00
} ` json:"_info" `
CustomFields [ ] struct {
ID int ` json:"id" `
Caption string ` json:"caption" `
Type string ` json:"type" `
EntryMethod string ` json:"entryMethod" `
NumberOfDecimals int ` json:"numberOfDecimals" `
2018-08-05 23:00:58 +00:00
//It's not always a string. I need to somehow *puts on sunglasses*... reflect on this as this is a dynamic type.
Value string ` json:"value" `
2018-06-20 20:24:50 +00:00
} ` json:"customFields" `
2018-08-24 01:34:39 +00:00
RequiredDate string ` json:"requiredDate,omitempty" `
BudgetHours float64 ` json:"budgetHours,omitempty" `
AddressLine2 string ` json:"addressLine2,omitempty" `
2018-06-20 20:24:50 +00:00
Contact struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
MobileGUID string ` json:"mobileGuid" `
ContactHref string ` json:"contact_href" `
} ` json:"_info" `
} ` json:"contact,omitempty" `
ContactPhoneExtension string ` json:"contactPhoneExtension,omitempty" `
}
2018-08-24 01:34:39 +00:00
type TicketNote struct {
ID int ` json:"id" `
TicketID int ` json:"ticketId" `
Text string ` json:"text" `
DetailDescriptionFlag bool ` json:"detailDescriptionFlag" `
InternalAnalysisFlag bool ` json:"internalAnalysisFlag" `
ResolutionFlag bool ` json:"resolutionFlag" `
Contact struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
ContactHref string ` json:"contact_href" `
} ` json:"_info" `
} ` json:"contact,omitempty" `
DateCreated string ` json:"dateCreated" `
CreatedBy string ` json:"createdBy" `
InternalFlag bool ` json:"internalFlag" `
ExternalFlag bool ` json:"externalFlag" `
Info struct {
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
} ` json:"_info" `
Member struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
ImageHref string ` json:"image_href" `
} ` json:"_info" `
} ` json:"member,omitempty" `
}
2018-10-12 03:49:05 +00:00
type TicketScheduleEntry struct {
ID int ` json:"id" `
Description string ` json:"description" `
Info struct {
ScheduleHref string ` json:"schedule_href" `
} ` json:"_info" `
}
2018-07-10 01:25:08 +00:00
//Board is a struct to hold the unmarshaled JSON data when making a call to the Service API
type Board struct {
ID int ` json:"id" `
Name string ` json:"name" `
Location struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
LocationHref string ` json:"location_href" `
} ` json:"_info" `
} ` json:"location" `
Department struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
DepartmentHref string ` json:"department_href" `
} ` json:"_info" `
} ` json:"department" `
InactiveFlag bool ` json:"inactiveFlag" `
SignOffTemplate struct {
ID int ` json:"id" `
Name string ` json:"name" `
} ` json:"signOffTemplate" `
SendToContactFlag bool ` json:"sendToContactFlag" `
SendToResourceFlag bool ` json:"sendToResourceFlag" `
ProjectFlag bool ` json:"projectFlag" `
BoardIcon struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
Filename string ` json:"filename" `
DocumentHref string ` json:"document_href" `
DocumentDownloadHref string ` json:"documentDownload_href" `
} ` json:"_info" `
} ` json:"boardIcon,omitempty" `
BillTicketsAfterClosedFlag bool ` json:"billTicketsAfterClosedFlag" `
BillTicketSeparatelyFlag bool ` json:"billTicketSeparatelyFlag" `
BillUnapprovedTimeExpenseFlag bool ` json:"billUnapprovedTimeExpenseFlag" `
OverrideBillingSetupFlag bool ` json:"overrideBillingSetupFlag" `
DispatchMember struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
} ` json:"_info" `
} ` json:"dispatchMember,omitempty" `
ServiceManagerMember struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
} ` json:"_info" `
} ` json:"serviceManagerMember,omitempty" `
DutyManagerMember struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
} ` json:"_info" `
} ` json:"dutyManagerMember,omitempty" `
OncallMember struct {
ID int ` json:"id" `
Identifier string ` json:"identifier" `
Name string ` json:"name" `
Info struct {
MemberHref string ` json:"member_href" `
} ` json:"_info" `
} ` json:"oncallMember,omitempty" `
WorkRole struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
WorkRoleHref string ` json:"workRole_href" `
} ` json:"_info" `
} ` json:"workRole,omitempty" `
WorkType struct {
ID int ` json:"id" `
Name string ` json:"name" `
Info struct {
WorkTypeHref string ` json:"workType_href" `
} ` json:"_info" `
} ` json:"workType,omitempty" `
BillTime string ` json:"billTime" `
BillExpense string ` json:"billExpense" `
BillProduct string ` json:"billProduct" `
AutoAssignNewTicketsFlag bool ` json:"autoAssignNewTicketsFlag" `
AutoAssignNewECTicketsFlag bool ` json:"autoAssignNewECTicketsFlag" `
AutoAssignNewPortalTicketsFlag bool ` json:"autoAssignNewPortalTicketsFlag" `
DiscussionsLockedFlag bool ` json:"discussionsLockedFlag" `
TimeEntryLockedFlag bool ` json:"timeEntryLockedFlag" `
NotifyEmailFrom string ` json:"notifyEmailFrom,omitempty" `
NotifyEmailFromName string ` json:"notifyEmailFromName" `
ClosedLoopDiscussionsFlag bool ` json:"closedLoopDiscussionsFlag" `
ClosedLoopResolutionFlag bool ` json:"closedLoopResolutionFlag" `
ClosedLoopInternalAnalysisFlag bool ` json:"closedLoopInternalAnalysisFlag" `
TimeEntryDiscussionFlag bool ` json:"timeEntryDiscussionFlag" `
TimeEntryResolutionFlag bool ` json:"timeEntryResolutionFlag" `
TimeEntryInternalAnalysisFlag bool ` json:"timeEntryInternalAnalysisFlag" `
ProblemSort string ` json:"problemSort" `
ResolutionSort string ` json:"resolutionSort" `
InternalAnalysisSort string ` json:"internalAnalysisSort" `
EmailConnectorAllowReopenClosedFlag bool ` json:"emailConnectorAllowReopenClosedFlag" `
EmailConnectorReopenStatus struct {
ID int ` json:"id" `
Name string ` json:"name" `
} ` json:"emailConnectorReopenStatus,omitempty" `
EmailConnectorReopenResourcesFlag bool ` json:"emailConnectorReopenResourcesFlag" `
EmailConnectorNewTicketNoMatchFlag bool ` json:"emailConnectorNewTicketNoMatchFlag" `
EmailConnectorNeverReopenByDaysFlag bool ` json:"emailConnectorNeverReopenByDaysFlag" `
EmailConnectorReopenDaysLimit int ` json:"emailConnectorReopenDaysLimit" `
UseMemberDisplayNameFlag bool ` json:"useMemberDisplayNameFlag" `
SendToCCFlag bool ` json:"sendToCCFlag" `
AutoAssignTicketOwnerFlag bool ` json:"autoAssignTicketOwnerFlag" `
ClosedLoopAllFlag bool ` json:"closedLoopAllFlag" `
AllSort string ` json:"allSort" `
Info struct {
2018-08-24 01:34:39 +00:00
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
2018-07-10 01:25:08 +00:00
} ` json:"_info" `
ShowDependenciesFlag bool ` json:"showDependenciesFlag,omitempty" `
ShowEstimatesFlag bool ` json:"showEstimatesFlag,omitempty" `
AutoCloseStatus struct {
ID int ` json:"id" `
Name string ` json:"name" `
} ` json:"autoCloseStatus,omitempty" `
}
2018-07-11 22:04:39 +00:00
type Source struct {
ID int ` json:"id" `
Name string ` json:"name" `
DefaultFlag bool ` json:"defaultFlag" `
Info struct {
2018-08-24 01:34:39 +00:00
LastUpdated string ` json:"lastUpdated" `
UpdatedBy string ` json:"updatedBy" `
2018-07-11 22:04:39 +00:00
} ` json:"_info" `
2018-08-24 01:34:39 +00:00
EnteredBy string ` json:"enteredBy" `
DateEntered string ` json:"dateEntered" `
2018-07-11 22:04:39 +00:00
}
2018-06-29 01:35:34 +00:00
//TimeEntryReference is a struct to hold the unmarshaled JSON data when making a call to the Service API
2018-06-22 20:14:21 +00:00
//TBD: For some reason the Info struct contained in TimeEntryReference does get data when the JSON is unmarshaled into this struct. The ID works fine
type TimeEntryReference struct {
ID int
Info struct {
2018-06-26 15:03:36 +00:00
Notes string ` json:"notes" `
TimeHref string ` json:"time_href" `
} ` json:"_info" `
2018-06-22 20:14:21 +00:00
}
2018-07-07 00:26:11 +00:00
//ConfigurationReference is a struct to hold a reference to Configuration data in the Connectwise API
//TBD: Do these "reference" types really need to be exported???
2018-06-26 16:03:11 +00:00
type ConfigurationReference struct {
ID int ` json:"id" `
DeviceIdentifier string ` json:"deviceIdentifier" `
Info struct {
Name string ` json:"name" `
ConfigurationHref string ` json:"configuration_href" `
} ` json:"_info" `
2018-06-22 20:14:21 +00:00
}
2018-10-12 03:49:05 +00:00
type TicketMerge struct {
MergeTicketIDs [ ] int ` json:"mergeTicketIDs" `
Status struct {
ID int ` json:"id" `
} ` json:"status" `
}
2018-06-29 01:35:34 +00:00
//GetTicketByID expects a ticket ID and returns a pointer to a Ticket struct
2018-07-07 00:29:53 +00:00
func ( cw * Site ) GetTicketByID ( ticketID int ) ( * Ticket , error ) {
2018-07-08 21:16:59 +00:00
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d" , ticketID ) , "GET" , nil )
2018-07-07 23:18:59 +00:00
err := req . Do ( )
2018-07-06 03:20:52 +00:00
if err != nil {
2018-07-07 23:18:59 +00:00
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
2018-07-06 03:20:52 +00:00
}
2018-07-07 23:18:59 +00:00
ticket := & Ticket { }
err = json . Unmarshal ( req . Body , ticket )
2018-07-06 03:20:52 +00:00
if err != nil {
2018-07-06 14:37:53 +00:00
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
2018-07-06 03:20:52 +00:00
}
2018-06-20 20:24:50 +00:00
2018-07-07 23:18:59 +00:00
return ticket , nil
2018-06-20 20:24:50 +00:00
}
2018-06-22 20:14:21 +00:00
2018-10-12 03:49:05 +00:00
func ( cw * Site ) GetTicketScheduleEntriesByID ( ticketID int ) ( * [ ] TicketScheduleEntry , error ) {
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/scheduleentries" , ticketID ) , "GET" , nil )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
ticketScheduleEntries := & [ ] TicketScheduleEntry { }
err = json . Unmarshal ( req . Body , ticketScheduleEntries )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return ticketScheduleEntries , nil
}
2018-06-29 01:35:34 +00:00
//GetTicketTimeEntriesByID expects a ticket ID and returns a pointer a to a slice of TimeEntryReference's, all the time entries attached to that ticket
2018-07-07 00:29:53 +00:00
func ( cw * Site ) GetTicketTimeEntriesByID ( ticketID int ) ( * [ ] TimeEntryReference , error ) {
2018-07-06 03:20:52 +00:00
2018-07-08 21:16:59 +00:00
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/timeentries" , ticketID ) , "GET" , nil )
2018-07-07 23:18:59 +00:00
err := req . Do ( )
2018-07-06 03:20:52 +00:00
if err != nil {
2018-07-07 23:18:59 +00:00
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
2018-07-06 03:20:52 +00:00
}
2018-07-07 23:18:59 +00:00
timeEntryReference := & [ ] TimeEntryReference { }
err = json . Unmarshal ( req . Body , timeEntryReference )
2018-07-06 03:20:52 +00:00
if err != nil {
2018-07-06 14:37:53 +00:00
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
2018-07-06 03:20:52 +00:00
}
2018-06-22 20:14:21 +00:00
2018-07-07 23:18:59 +00:00
return timeEntryReference , nil
2018-06-22 20:14:21 +00:00
}
2018-06-26 16:03:11 +00:00
2018-07-11 22:04:39 +00:00
//TicketTimeEntryCount returns the number of time entries on a ticket in ConnectWise
func ( cw * Site ) TicketTimeEntryCount ( ticketID int ) ( int , error ) {
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/timeentries/count" , ticketID ) , "GET" , nil )
err := req . Do ( )
if err != nil {
return 0 , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
count := & Count { }
err = json . Unmarshal ( req . Body , count )
if err != nil {
return 0 , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return count . Count , nil
}
2018-07-07 00:26:11 +00:00
//GetTicketConfigurationsByID expects a ticket ID and returns a pointer to a slice of the configurations attached to the ticket
2018-07-07 00:29:53 +00:00
func ( cw * Site ) GetTicketConfigurationsByID ( ticketID int ) ( * [ ] ConfigurationReference , error ) {
2018-07-08 21:16:59 +00:00
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/configurations" , ticketID ) , "GET" , nil )
2018-07-07 23:18:59 +00:00
err := req . Do ( )
2018-07-06 03:20:52 +00:00
if err != nil {
2018-07-07 23:18:59 +00:00
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
2018-07-06 03:20:52 +00:00
}
2018-07-07 23:18:59 +00:00
configurationReference := & [ ] ConfigurationReference { }
err = json . Unmarshal ( req . Body , configurationReference )
2018-07-06 03:20:52 +00:00
if err != nil {
2018-07-06 14:37:53 +00:00
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
2018-07-06 03:20:52 +00:00
}
2018-06-26 16:03:11 +00:00
2018-07-07 23:18:59 +00:00
return configurationReference , nil
2018-06-26 16:03:11 +00:00
}
2018-07-10 01:25:08 +00:00
//GetServiceTeams returns a pointer to a slice of the service teams in Connectwise
func ( cw * Site ) GetServiceTeams ( ) ( * [ ] ServiceTeam , error ) {
req := cw . NewRequest ( "/service/teams" , "GET" , nil )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
serviceTeam := & [ ] ServiceTeam { }
err = json . Unmarshal ( req . Body , serviceTeam )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return serviceTeam , nil
}
//GetBoardTeams returns a pointer to a slice of the service teams in Connectwise
func ( cw * Site ) GetBoardTeams ( boardID int ) ( * [ ] BoardTeam , error ) {
req := cw . NewRequest ( fmt . Sprintf ( "/service/boards/%d/teams" , boardID ) , "GET" , nil )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
boardTeam := & [ ] BoardTeam { }
err = json . Unmarshal ( req . Body , boardTeam )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return boardTeam , nil
}
2018-07-10 16:46:10 +00:00
func ( cw * Site ) GetBoardStatuses ( boardID int ) ( * [ ] BoardStatus , error ) {
req := cw . NewRequest ( fmt . Sprintf ( "/service/boards/%d/statuses" , boardID ) , "GET" , nil )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
boardStatus := & [ ] BoardStatus { }
err = json . Unmarshal ( req . Body , boardStatus )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return boardStatus , nil
}
2018-07-10 01:25:08 +00:00
//GetBoardTeamByName returns a pointer to a board team in Connectwise
func ( cw * Site ) GetBoardTeamByName ( boardID int , teamName string ) ( * BoardTeam , error ) {
req := cw . NewRequest ( fmt . Sprintf ( "/service/boards/%d/teams" , boardID ) , "GET" , nil )
req . URLValues . Add ( "conditions" , "name=\"" + teamName + "\"" )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
boardTeam := & [ ] BoardTeam { }
err = json . Unmarshal ( req . Body , boardTeam )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
if len ( * boardTeam ) == 0 {
2018-07-10 02:48:02 +00:00
return nil , fmt . Errorf ( "connectwise returned no results for %d/%s" , boardID , teamName )
2018-07-10 01:25:08 +00:00
}
return & ( * boardTeam ) [ 0 ] , nil
}
//GetBoards returns a pointer to a slice of service boards
func ( cw * Site ) GetBoards ( ) ( * [ ] Board , error ) {
req := cw . NewRequest ( "/service/boards" , "GET" , nil )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
board := & [ ] Board { }
err = json . Unmarshal ( req . Body , board )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return board , nil
}
2018-07-10 02:48:02 +00:00
//AssignTicketToTeam will set the team/id of a ticket
func ( cw * Site ) AssignTicketToTeam ( ticketID , teamID int ) ( * Ticket , error ) {
2018-07-29 18:22:08 +00:00
patches := & [ ] PatchString { }
patch := & PatchString {
2018-07-10 02:48:02 +00:00
Op : "replace" ,
Path : "team/id" ,
Value : strconv . Itoa ( teamID ) }
* patches = append ( * patches , * patch )
patchBody , err := json . Marshal ( patches )
if err != nil {
return nil , fmt . Errorf ( "could not marhsal patch json to byte slice: %s" , err )
}
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d" , ticketID ) , "PATCH" , patchBody )
err = req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
ticket := & Ticket { }
err = json . Unmarshal ( req . Body , ticket )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return ticket , nil
}
2018-07-11 22:04:39 +00:00
2018-10-12 03:49:05 +00:00
//AssignTicketToMember will create a new schedule entry for the member and specify the ticket as the object
func ( cw * Site ) AssignTicketToMember ( ticketID , memberID int ) ( * ScheduleEntry , error ) {
2019-03-08 22:37:26 +00:00
req := cw . NewRequest ( "/schedule/entries" , "GET" , nil )
req . URLValues . Add ( "conditions" , fmt . Sprintf ( "member/id=%d and objectId=%d and doneFlag=false" , memberID , ticketID ) )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "failed to get schedule entries on ticketID '%d' and memberID '%d': %v" , ticketID , memberID , err )
}
scheduleEntries := & [ ] ScheduleEntry { }
err = json . Unmarshal ( req . Body , scheduleEntries )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
// The member is already assined to the ticket, so return the first schedule entry
if len ( * scheduleEntries ) > 0 {
return & ( * scheduleEntries ) [ 0 ] , nil
}
2018-10-12 03:49:05 +00:00
scheduleEntry := & ScheduleEntry { }
scheduleEntry . ObjectID = ticketID
scheduleEntry . Member . ID = memberID
2019-03-08 22:37:26 +00:00
scheduleEntry . Type . ID = 4 //TBD: This should not be here lol *UPDATE* Yes it should be here, this is a constant ID across all CW instances aparently (found in CW docs)
2018-10-12 03:49:05 +00:00
jsonScheduleEntry , err := json . Marshal ( scheduleEntry )
if err != nil {
return nil , fmt . Errorf ( "could not marshal json data: %s" , err )
}
2019-03-08 22:37:26 +00:00
req = cw . NewRequest ( "/schedule/entries" , "POST" , jsonScheduleEntry )
2018-10-12 03:49:05 +00:00
err = req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
scheduleEntry = & ScheduleEntry { }
err = json . Unmarshal ( req . Body , scheduleEntry )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return scheduleEntry , nil
}
2019-03-08 22:37:26 +00:00
// RemoveTicketFromMember accepts a ticketID and a memberID and will mark the member as done, will return an error if it fails
func ( cw * Site ) RemoveTicketFromMember ( ticketID , memberID int ) error {
req := cw . NewRequest ( "/schedule/entries" , "GET" , nil )
req . URLValues . Add ( "conditions" , fmt . Sprintf ( "member/id=%d and objectId=%d and doneFlag=false" , memberID , ticketID ) )
err := req . Do ( )
if err != nil {
return fmt . Errorf ( "failed to get schedule entries on ticketID '%d' and memberID '%d': %v" , ticketID , memberID , err )
}
scheduleEntries := & [ ] ScheduleEntry { }
err = json . Unmarshal ( req . Body , scheduleEntries )
if err != nil {
return fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
for _ , scheduleEntry := range * scheduleEntries {
patches := & [ ] PatchString { }
patch := & PatchString {
Op : "replace" ,
Path : "doneFlag" ,
Value : "true" }
* patches = append ( * patches , * patch )
patchBody , err := json . Marshal ( patches )
if err != nil {
return fmt . Errorf ( "could not marshal patch json to byte slice: %v" , err )
}
req = cw . NewRequest ( fmt . Sprintf ( "/schedule/entries/%d" , scheduleEntry . ID ) , "PATCH" , patchBody )
err = req . Do ( )
if err != nil {
return fmt . Errorf ( "failed update done field for scheduleEntry ID '%d': %v" , scheduleEntry . ID , err )
}
}
return nil
}
2018-10-16 00:20:55 +00:00
//AssignTicketToCompany
func ( cw * Site ) AssignTicketToCompany ( ticketID , companyID int ) ( * Ticket , error ) {
patches := & [ ] PatchString { }
patch := & PatchString {
Op : "replace" ,
Path : "company/id" ,
Value : strconv . Itoa ( companyID ) }
* patches = append ( * patches , * patch )
patchBody , err := json . Marshal ( patches )
2018-12-07 16:07:18 +00:00
if err != nil {
return nil , fmt . Errorf ( "could not marhsal patch json to byte slice: %s" , err )
}
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d" , ticketID ) , "PATCH" , patchBody )
err = req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
ticket := & Ticket { }
err = json . Unmarshal ( req . Body , ticket )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return ticket , nil
}
//AssignTicketToSite
func ( cw * Site ) AssignTicketToSite ( ticketID , siteID int ) ( * Ticket , error ) {
patches := & [ ] PatchString { }
patch := & PatchString {
Op : "replace" ,
Path : "site/id" ,
Value : strconv . Itoa ( siteID ) }
* patches = append ( * patches , * patch )
patchBody , err := json . Marshal ( patches )
2018-10-16 00:20:55 +00:00
if err != nil {
return nil , fmt . Errorf ( "could not marhsal patch json to byte slice: %s" , err )
}
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d" , ticketID ) , "PATCH" , patchBody )
err = req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
ticket := & Ticket { }
err = json . Unmarshal ( req . Body , ticket )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return ticket , nil
}
2018-10-12 03:49:05 +00:00
//AssignTicketToMember will create a new schedule entry for the member and specify the ticket as the object
func ( cw * Site ) TicketMerge ( mainTicketID int , mergedTicketIDs [ ] int , mergedTicketStatusID int ) error {
ticketMerge := & TicketMerge { }
ticketMerge . MergeTicketIDs = mergedTicketIDs
ticketMerge . Status . ID = mergedTicketStatusID
ticketMergeJSON , err := json . Marshal ( ticketMerge )
if err != nil {
return fmt . Errorf ( "could not marshal ticketMerge to JSON: %s" , err )
}
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/merge" , mainTicketID ) , "POST" , ticketMergeJSON )
err = req . Do ( )
if err != nil {
return fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
return nil
}
2018-09-22 21:07:34 +00:00
//SetTicketStatus will set the status on a ticket to the one provided
func ( cw * Site ) SetTicketStatus ( ticketID , statusID int ) ( * Ticket , error ) {
patches := & [ ] PatchString { }
patch := & PatchString {
Op : "replace" ,
Path : "status/id" ,
Value : strconv . Itoa ( statusID ) }
* patches = append ( * patches , * patch )
patchBody , err := json . Marshal ( patches )
if err != nil {
return nil , fmt . Errorf ( "could not marhsal patch json to byte slice: %s" , err )
}
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d" , ticketID ) , "PATCH" , patchBody )
err = req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
ticket := & Ticket { }
err = json . Unmarshal ( req . Body , ticket )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return ticket , nil
}
2018-07-11 22:04:39 +00:00
//GetSources will return a pointer to a slice of sources. Sources are referring to Ticket.Source field
func ( cw * Site ) GetSources ( ) ( * [ ] Source , error ) {
req := cw . NewRequest ( "/service/sources" , "GET" , nil )
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
source := & [ ] Source { }
err = json . Unmarshal ( req . Body , source )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return source , nil
}
2018-08-24 01:34:39 +00:00
2018-09-22 21:07:34 +00:00
//GetTicketNotes will accept a ticketID and return a slice of TicketNote.
2018-08-24 01:34:39 +00:00
func ( cw * Site ) GetTicketNotes ( ticketID int ) ( * [ ] TicketNote , error ) {
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/notes" , ticketID ) , "GET" , nil )
2019-01-16 21:00:49 +00:00
req . PageSize = 2000
2019-01-29 23:56:49 +00:00
2018-08-24 01:34:39 +00:00
err := req . Do ( )
if err != nil {
return nil , fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
ticketNotes := & [ ] TicketNote { }
err = json . Unmarshal ( req . Body , ticketNotes )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal body into struct: %s" , err )
}
return ticketNotes , nil
}
2019-01-29 23:56:49 +00:00
//GetTicketNotes will accept a ticketID and return a slice of TicketNote.
func ( cw * Site ) PostTicketNote ( ticketNote * TicketNote ) error {
body , err := json . Marshal ( ticketNote )
if err != nil {
return fmt . Errorf ( "failed to marshal ticket note to json: %v" , err )
}
req := cw . NewRequest ( fmt . Sprintf ( "/service/tickets/%d/notes" , ticketNote . TicketID ) , "POST" , body )
err = req . Do ( )
if err != nil {
return fmt . Errorf ( "request failed for %s: %s" , req . RestAction , err )
}
return nil
}