diff --git a/README.md b/README.md index 4f9608b7..3e9d28fc 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Install-Package CSharpAmazonSpAPI | [Replenishment](https://developer-docs.amazon.com/sp-api/docs/replenishment-api-v2022-11-07-reference) | ✅ | `listOffers`, `listOfferMetrics`, `getSellingPartnerMetrics` | | [External Fulfillment Shipments](https://developer-docs.amazon.com/sp-api/reference/externalfulfillmentshipments-api-v2024-09-11) | ✅ | `getShipments`, `getShipment`, `processShipment`, `createPackages`, `updatePackage`, `retrieveShippingOptions`, `generateShipLabels`, `generateInvoice`, `retrieveInvoice`, `updatePackageStatus` | | [Data Kiosk (v2023-11-15)](https://developer-docs.amazon.com/sp-api/reference/datakiosk-api-v2023-11-15-reference) | ✅ | `getQueries`, `createQuery`, `getQuery`, `cancelQuery`, `getDocument` | +| [Support (v2025-02-01)](https://developer-docs.amazon/sp-api/reference/support-v2025-02-01) | ✅ | `listCases`, `getCase`, `listContacts` | #### Vendor @@ -1416,6 +1417,24 @@ if (query.ProcessingStatus == Query.ProcessingStatusEnum.DONE && !string.IsNullO var list = amazonConnection.DataKiosk.GetQueries(new ParameterGetQueries { PageSize = 10 }); amazonConnection.DataKiosk.CancelQuery(created.QueryId); ``` +### Support (v2025-02-01): Seller support cases and contact history +For more samples, please check [Here](https://github.com/abuzuhri/Amazon-SP-API-CSharp/blob/main/Source/FikaAmazonAPI.SampleCode/SupportSample.cs). Requires the Selling Partner Support (Restricted) role. +```CSharp +// 1. List cases: auto-pages through every result page and returns a flat list. +var cases = amazonConnection.Support.ListCases(new ParameterListCases +{ + CaseFilters = new CaseFilters( + caseStatuses: new List { CaseFilters.CaseStatusesEnum.PENDINGMERCHANTACTION }, + createdDate: new DateFilter(after: DateTime.UtcNow.AddDays(-30))), + MaxResults = 50 +}); + +// 2. Get a single case. +var supportCase = amazonConnection.Support.GetCase("CASE_ID"); + +// 3. List the case's email, chat and phone contacts (attachment download URLs expire after 15 minutes). +var contacts = amazonConnection.Support.ListContacts("CASE_ID", new ParameterListContacts { SortOrder = SupportSortOrder.ASC }); +``` --- ## Q & A diff --git a/Source/FikaAmazonAPI.SampleCode/SupportSample.cs b/Source/FikaAmazonAPI.SampleCode/SupportSample.cs new file mode 100644 index 00000000..25daf5b7 --- /dev/null +++ b/Source/FikaAmazonAPI.SampleCode/SupportSample.cs @@ -0,0 +1,80 @@ +using FikaAmazonAPI.AmazonSpApiSDK.Models.Support; +using FikaAmazonAPI.Parameter.Support; + +namespace FikaAmazonAPI.SampleCode; + +public class SupportSample +{ + AmazonConnection amazonConnection; + + public SupportSample(AmazonConnection amazonConnection) + { + this.amazonConnection = amazonConnection; + } + + public void ListCases() + { + // Pages through every result page internally and returns a flat list. + // Set MaxNumberOfPages to stop after a given number of pages. + var cases = amazonConnection.Support.ListCases(new ParameterListCases + { + CaseFilters = new CaseFilters( + caseStatuses: new List { CaseFilters.CaseStatusesEnum.PENDINGMERCHANTACTION }, + createdDate: new DateFilter(after: DateTime.UtcNow.AddDays(-30))), + SortOrder = ListCasesRequest.SortOrderEnum.DESC, + MaxResults = 50 + }); + } + + public void ListCasesOnePageWithNextToken() + { + // ONLY USE THIS SAMPLE IF YOU NEED TO GET ONE PAGE EACH TIME, otherwise remove parameter + // 'MaxNumberOfPages' and the library will fetch all cases for you + var parameter = new ParameterListCases + { + MaxResults = 10, + MaxNumberOfPages = 1 + }; + + var cases = amazonConnection.Support.ListCases(parameter); + + // ListCases leaves the token for the next unfetched page on the parameter object. + while (!string.IsNullOrEmpty(parameter.NextToken)) + { + var moreCases = amazonConnection.Support.ListCasesByNextToken(parameter); + parameter.NextToken = moreCases.NextToken; + } + } + + public void GetCase() + { + var supportCase = amazonConnection.Support.GetCase("CASE_ID"); + } + + public void ListContacts() + { + var contacts = amazonConnection.Support.ListContacts("CASE_ID", new ParameterListContacts + { + SortOrder = SupportSortOrder.ASC, + MaxResults = 50 + }); + + foreach (var contact in contacts) + { + // Only the content matching the contact's channel is populated. + // Attachment download URLs expire after 15 minutes. + switch (contact.Channel) + { + case Contact.ChannelEnum.EMAIL: + var message = contact.EmailContent?.Message; + break; + case Contact.ChannelEnum.CHAT: + var transcript = contact.ChatContent?.Transcript; + break; + case Contact.ChannelEnum.PHONE: + var callNotes = contact.PhoneContent?.CallNotes; + break; + } + } + } +} diff --git a/Source/FikaAmazonAPI/AmazonConnection.cs b/Source/FikaAmazonAPI/AmazonConnection.cs index 5bbcaa02..21a821bc 100644 --- a/Source/FikaAmazonAPI/AmazonConnection.cs +++ b/Source/FikaAmazonAPI/AmazonConnection.cs @@ -69,6 +69,7 @@ public class AmazonConnection public MerchantShippingTemplateService MerchantShippingTemplate => this._MerchantShippingTemplate ?? throw _NoCredentials; public ReplenishmentService Replenishment => this._Replenishment ?? throw _NoCredentials; public ApplicationManagementService ApplicationManagement => this._ApplicationManagement ?? throw _NoCredentials; + public SupportService Support => this._Support ?? throw _NoCredentials; private AppIntegrationsServiceV20240401 _AppIntegrationsServiceV20240401 { get; set; } @@ -120,6 +121,7 @@ public class AmazonConnection private MerchantShippingTemplateService _MerchantShippingTemplate { get; set; } private ReplenishmentService _Replenishment { get; set; } private ApplicationManagementService _ApplicationManagement { get; set; } + private SupportService _Support { get; set; } private UnauthorizedAccessException _NoCredentials = new UnauthorizedAccessException($"Error, you cannot make calls to Amazon without credentials!"); @@ -196,6 +198,7 @@ private void Init(AmazonCredential Credentials) this._MerchantShippingTemplate = new MerchantShippingTemplateService(this.Credentials, _loggerFactory); this._Replenishment = new ReplenishmentService(this.Credentials, _loggerFactory); this._ApplicationManagement = new ApplicationManagementService(this.Credentials, _loggerFactory); + this._Support = new SupportService(this.Credentials, _loggerFactory); AmazonCredential.DebugMode = this.Credentials.IsDebugMode; } diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Appointment.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Appointment.cs new file mode 100644 index 00000000..e50efce3 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Appointment.cs @@ -0,0 +1,265 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// An appointment for a contact at a future date. + /// + [DataContract] + public partial class Appointment : IEquatable, IValidatableObject + { + /// + /// The person who is expected to answer the call. + /// + /// The person who is expected to answer the call. + [JsonConverter(typeof(StringEnumConverter))] + public enum AnsweringPartyEnum + { + + /// + /// Enum RECEPTIONIST for value: RECEPTIONIST + /// + [EnumMember(Value = "RECEPTIONIST")] + RECEPTIONIST = 1 + } + + /// + /// The person who is expected to answer the call. + /// + /// The person who is expected to answer the call. + [DataMember(Name="answeringParty", EmitDefaultValue=false)] + public AnsweringPartyEnum? AnsweringParty { get; set; } + /// + /// The appointment status. + /// + /// The appointment status. + [JsonConverter(typeof(StringEnumConverter))] + public enum StatusEnum + { + + /// + /// Enum SCHEDULED for value: SCHEDULED + /// + [EnumMember(Value = "SCHEDULED")] + SCHEDULED = 1, + + /// + /// Enum CANCELLED for value: CANCELLED + /// + [EnumMember(Value = "CANCELLED")] + CANCELLED = 2, + + /// + /// Enum MISSED for value: MISSED + /// + [EnumMember(Value = "MISSED")] + MISSED = 3, + + /// + /// Enum COMPLETED for value: COMPLETED + /// + [EnumMember(Value = "COMPLETED")] + COMPLETED = 4 + } + + /// + /// The appointment status. + /// + /// The appointment status. + [DataMember(Name="status", EmitDefaultValue=false)] + public StatusEnum Status { get; set; } + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public Appointment() { } + /// + /// Initializes a new instance of the class. + /// + /// The unique identifier for the scheduled appointment. (required). + /// The selling partner's phone number. (required). + /// The person who is expected to answer the call.. + /// The time window during which the appointment is scheduled. (required). + /// The appointment status. (required). + public Appointment(string appointmentId = default(string), PhoneNumber phoneNumber = default(PhoneNumber), AnsweringPartyEnum? answeringParty = default(AnsweringPartyEnum?), CallbackTiming callbackTiming = default(CallbackTiming), StatusEnum status = default(StatusEnum)) + { + // to ensure "appointmentId" is required (not null) + if (appointmentId == null) + { + throw new InvalidDataException("appointmentId is a required property for Appointment and cannot be null"); + } + else + { + this.AppointmentId = appointmentId; + } + // to ensure "phoneNumber" is required (not null) + if (phoneNumber == null) + { + throw new InvalidDataException("phoneNumber is a required property for Appointment and cannot be null"); + } + else + { + this.PhoneNumber = phoneNumber; + } + // to ensure "callbackTiming" is required (not null) + if (callbackTiming == null) + { + throw new InvalidDataException("callbackTiming is a required property for Appointment and cannot be null"); + } + else + { + this.CallbackTiming = callbackTiming; + } + this.AnsweringParty = answeringParty; + this.Status = status; + } + + /// + /// The unique identifier for the scheduled appointment. + /// + /// The unique identifier for the scheduled appointment. + [DataMember(Name="appointmentId", EmitDefaultValue=false)] + public string AppointmentId { get; set; } + + /// + /// The selling partner's phone number. + /// + /// The selling partner's phone number. + [DataMember(Name="phoneNumber", EmitDefaultValue=false)] + public PhoneNumber PhoneNumber { get; set; } + + /// + /// The time window during which the appointment is scheduled. + /// + /// The time window during which the appointment is scheduled. + [DataMember(Name="callbackTiming", EmitDefaultValue=false)] + public CallbackTiming CallbackTiming { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Appointment {\n"); + sb.Append(" AppointmentId: ").Append(AppointmentId).Append("\n"); + sb.Append(" PhoneNumber: ").Append(PhoneNumber).Append("\n"); + sb.Append(" AnsweringParty: ").Append(AnsweringParty).Append("\n"); + sb.Append(" CallbackTiming: ").Append(CallbackTiming).Append("\n"); + sb.Append(" Status: ").Append(Status).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Appointment); + } + + /// + /// Returns true if Appointment instances are equal + /// + /// Instance of Appointment to be compared + /// Boolean + public bool Equals(Appointment input) + { + if (input == null) + return false; + + return + ( + this.AppointmentId == input.AppointmentId || + (this.AppointmentId != null && + this.AppointmentId.Equals(input.AppointmentId)) + ) && + ( + this.PhoneNumber == input.PhoneNumber || + (this.PhoneNumber != null && + this.PhoneNumber.Equals(input.PhoneNumber)) + ) && + ( + this.AnsweringParty == input.AnsweringParty || + (this.AnsweringParty != null && + this.AnsweringParty.Equals(input.AnsweringParty)) + ) && + ( + this.CallbackTiming == input.CallbackTiming || + (this.CallbackTiming != null && + this.CallbackTiming.Equals(input.CallbackTiming)) + ) && + ( + this.Status == input.Status || + this.Status.Equals(input.Status) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.AppointmentId != null) + hashCode = hashCode * 59 + this.AppointmentId.GetHashCode(); + if (this.PhoneNumber != null) + hashCode = hashCode * 59 + this.PhoneNumber.GetHashCode(); + if (this.AnsweringParty != null) + hashCode = hashCode * 59 + this.AnsweringParty.GetHashCode(); + if (this.CallbackTiming != null) + hashCode = hashCode * 59 + this.CallbackTiming.GetHashCode(); + hashCode = hashCode * 59 + this.Status.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Attachment.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Attachment.cs new file mode 100644 index 00000000..f21df1d0 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Attachment.cs @@ -0,0 +1,154 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A file attachment. + /// + [DataContract] + public partial class Attachment : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public Attachment() { } + /// + /// Initializes a new instance of the class. + /// + /// The name of the attachment. (required). + /// The download link to the attachment file. The `downloadUrl` is included in the response if available. If there is a failure to return the `downloadUrl`, this field is not included in the response. The `downloadUrl` expires after 15 minutes.. + public Attachment(string name = default(string), string downloadUrl = default(string)) + { + // to ensure "name" is required (not null) + if (name == null) + { + throw new InvalidDataException("name is a required property for Attachment and cannot be null"); + } + else + { + this.Name = name; + } + this.DownloadUrl = downloadUrl; + } + + /// + /// The name of the attachment. + /// + /// The name of the attachment. + [DataMember(Name="name", EmitDefaultValue=false)] + public string Name { get; set; } + + /// + /// The download link to the attachment file. The `downloadUrl` is included in the response if available. If there is a failure to return the `downloadUrl`, this field is not included in the response. The `downloadUrl` expires after 15 minutes. + /// + /// The download link to the attachment file. The `downloadUrl` is included in the response if available. If there is a failure to return the `downloadUrl`, this field is not included in the response. The `downloadUrl` expires after 15 minutes. + [DataMember(Name="downloadUrl", EmitDefaultValue=false)] + public string DownloadUrl { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Attachment {\n"); + sb.Append(" Name: ").Append(Name).Append("\n"); + sb.Append(" DownloadUrl: ").Append(DownloadUrl).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Attachment); + } + + /// + /// Returns true if Attachment instances are equal + /// + /// Instance of Attachment to be compared + /// Boolean + public bool Equals(Attachment input) + { + if (input == null) + return false; + + return + ( + this.Name == input.Name || + (this.Name != null && + this.Name.Equals(input.Name)) + ) && + ( + this.DownloadUrl == input.DownloadUrl || + (this.DownloadUrl != null && + this.DownloadUrl.Equals(input.DownloadUrl)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Name != null) + hashCode = hashCode * 59 + this.Name.GetHashCode(); + if (this.DownloadUrl != null) + hashCode = hashCode * 59 + this.DownloadUrl.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CallbackTiming.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CallbackTiming.cs new file mode 100644 index 00000000..87a97045 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CallbackTiming.cs @@ -0,0 +1,162 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The time window for an appointment callback + /// + [DataContract] + public partial class CallbackTiming : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public CallbackTiming() { } + /// + /// Initializes a new instance of the class. + /// + /// The earliest time at which to call the selling partner. (required). + /// The latest time at which to call the selling partner. (required). + public CallbackTiming(DateTime? earliestCallbackTime = default(DateTime?), DateTime? latestCallbackTime = default(DateTime?)) + { + // to ensure "earliestCallbackTime" is required (not null) + if (earliestCallbackTime == null) + { + throw new InvalidDataException("earliestCallbackTime is a required property for CallbackTiming and cannot be null"); + } + else + { + this.EarliestCallbackTime = earliestCallbackTime; + } + // to ensure "latestCallbackTime" is required (not null) + if (latestCallbackTime == null) + { + throw new InvalidDataException("latestCallbackTime is a required property for CallbackTiming and cannot be null"); + } + else + { + this.LatestCallbackTime = latestCallbackTime; + } + } + + /// + /// The earliest time at which to call the selling partner. + /// + /// The earliest time at which to call the selling partner. + [DataMember(Name="earliestCallbackTime", EmitDefaultValue=false)] + public DateTime? EarliestCallbackTime { get; set; } + + /// + /// The latest time at which to call the selling partner. + /// + /// The latest time at which to call the selling partner. + [DataMember(Name="latestCallbackTime", EmitDefaultValue=false)] + public DateTime? LatestCallbackTime { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class CallbackTiming {\n"); + sb.Append(" EarliestCallbackTime: ").Append(EarliestCallbackTime).Append("\n"); + sb.Append(" LatestCallbackTime: ").Append(LatestCallbackTime).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as CallbackTiming); + } + + /// + /// Returns true if CallbackTiming instances are equal + /// + /// Instance of CallbackTiming to be compared + /// Boolean + public bool Equals(CallbackTiming input) + { + if (input == null) + return false; + + return + ( + this.EarliestCallbackTime == input.EarliestCallbackTime || + (this.EarliestCallbackTime != null && + this.EarliestCallbackTime.Equals(input.EarliestCallbackTime)) + ) && + ( + this.LatestCallbackTime == input.LatestCallbackTime || + (this.LatestCallbackTime != null && + this.LatestCallbackTime.Equals(input.LatestCallbackTime)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.EarliestCallbackTime != null) + hashCode = hashCode * 59 + this.EarliestCallbackTime.GetHashCode(); + if (this.LatestCallbackTime != null) + hashCode = hashCode * 59 + this.LatestCallbackTime.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Case.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Case.cs new file mode 100644 index 00000000..64625f6a --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Case.cs @@ -0,0 +1,343 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The support case. + /// + [DataContract] + public partial class Case : IEquatable, IValidatableObject + { + /// + /// The current status of the case. + /// + /// The current status of the case. + [JsonConverter(typeof(StringEnumConverter))] + public enum StatusEnum + { + + /// + /// Enum RESOLVED for value: RESOLVED + /// + [EnumMember(Value = "RESOLVED")] + RESOLVED = 1, + + /// + /// Enum TRANSFERRED for value: TRANSFERRED + /// + [EnumMember(Value = "TRANSFERRED")] + TRANSFERRED = 2, + + /// + /// Enum PENDINGMERCHANTACTION for value: PENDING_MERCHANT_ACTION + /// + [EnumMember(Value = "PENDING_MERCHANT_ACTION")] + PENDINGMERCHANTACTION = 3, + + /// + /// Enum PENDINGAMAZONACTION for value: PENDING_AMAZON_ACTION + /// + [EnumMember(Value = "PENDING_AMAZON_ACTION")] + PENDINGAMAZONACTION = 4 + } + + /// + /// The current status of the case. + /// + /// The current status of the case. + [DataMember(Name="status", EmitDefaultValue=false)] + public StatusEnum Status { get; set; } + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public Case() { } + /// + /// Initializes a new instance of the class. + /// + /// A globally unique identifier for the case (required). + /// The current status of the case. (required). + /// The subject of the case. (required). + /// The primary email associated with the case. (required). + /// Additional emails that are attached to the case. (required). + /// All appointments for the case.. + /// The time when the case was created. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. (required). + /// The time when the case was last updated, which includes updates to the case details and new contacts added to the case. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. (required). + /// The time when the case was resolved. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format.. + public Case(string caseId = default(string), StatusEnum status = default(StatusEnum), string subject = default(string), string primaryEmail = default(string), List ccEmails = default(List), List appointments = default(List), DateTime? createdDate = default(DateTime?), DateTime? lastUpdatedDate = default(DateTime?), DateTime? resolvedDate = default(DateTime?)) + { + // to ensure "caseId" is required (not null) + if (caseId == null) + { + throw new InvalidDataException("caseId is a required property for Case and cannot be null"); + } + else + { + this.CaseId = caseId; + } + // to ensure "subject" is required (not null) + if (subject == null) + { + throw new InvalidDataException("subject is a required property for Case and cannot be null"); + } + else + { + this.Subject = subject; + } + // to ensure "primaryEmail" is required (not null) + if (primaryEmail == null) + { + throw new InvalidDataException("primaryEmail is a required property for Case and cannot be null"); + } + else + { + this.PrimaryEmail = primaryEmail; + } + // to ensure "ccEmails" is required (not null) + if (ccEmails == null) + { + throw new InvalidDataException("ccEmails is a required property for Case and cannot be null"); + } + else + { + this.CcEmails = ccEmails; + } + // to ensure "createdDate" is required (not null) + if (createdDate == null) + { + throw new InvalidDataException("createdDate is a required property for Case and cannot be null"); + } + else + { + this.CreatedDate = createdDate; + } + // to ensure "lastUpdatedDate" is required (not null) + if (lastUpdatedDate == null) + { + throw new InvalidDataException("lastUpdatedDate is a required property for Case and cannot be null"); + } + else + { + this.LastUpdatedDate = lastUpdatedDate; + } + this.Status = status; + this.Appointments = appointments; + this.ResolvedDate = resolvedDate; + } + + /// + /// A globally unique identifier for the case + /// + /// A globally unique identifier for the case + [DataMember(Name="caseId", EmitDefaultValue=false)] + public string CaseId { get; set; } + + /// + /// The subject of the case. + /// + /// The subject of the case. + [DataMember(Name="subject", EmitDefaultValue=false)] + public string Subject { get; set; } + + /// + /// The primary email associated with the case. + /// + /// The primary email associated with the case. + [DataMember(Name="primaryEmail", EmitDefaultValue=false)] + public string PrimaryEmail { get; set; } + + /// + /// Additional emails that are attached to the case. + /// + /// Additional emails that are attached to the case. + [DataMember(Name="ccEmails", EmitDefaultValue=false)] + public List CcEmails { get; set; } + + /// + /// All appointments for the case. + /// + /// All appointments for the case. + [DataMember(Name="appointments", EmitDefaultValue=false)] + public List Appointments { get; set; } + + /// + /// The time when the case was created. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + /// + /// The time when the case was created. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + [DataMember(Name="createdDate", EmitDefaultValue=false)] + public DateTime? CreatedDate { get; set; } + + /// + /// The time when the case was last updated, which includes updates to the case details and new contacts added to the case. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + /// + /// The time when the case was last updated, which includes updates to the case details and new contacts added to the case. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + [DataMember(Name="lastUpdatedDate", EmitDefaultValue=false)] + public DateTime? LastUpdatedDate { get; set; } + + /// + /// The time when the case was resolved. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + /// + /// The time when the case was resolved. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + [DataMember(Name="resolvedDate", EmitDefaultValue=false)] + public DateTime? ResolvedDate { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Case {\n"); + sb.Append(" CaseId: ").Append(CaseId).Append("\n"); + sb.Append(" Status: ").Append(Status).Append("\n"); + sb.Append(" Subject: ").Append(Subject).Append("\n"); + sb.Append(" PrimaryEmail: ").Append(PrimaryEmail).Append("\n"); + sb.Append(" CcEmails: ").Append(CcEmails).Append("\n"); + sb.Append(" Appointments: ").Append(Appointments).Append("\n"); + sb.Append(" CreatedDate: ").Append(CreatedDate).Append("\n"); + sb.Append(" LastUpdatedDate: ").Append(LastUpdatedDate).Append("\n"); + sb.Append(" ResolvedDate: ").Append(ResolvedDate).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Case); + } + + /// + /// Returns true if Case instances are equal + /// + /// Instance of Case to be compared + /// Boolean + public bool Equals(Case input) + { + if (input == null) + return false; + + return + ( + this.CaseId == input.CaseId || + (this.CaseId != null && + this.CaseId.Equals(input.CaseId)) + ) && + ( + this.Status == input.Status || + this.Status.Equals(input.Status) + ) && + ( + this.Subject == input.Subject || + (this.Subject != null && + this.Subject.Equals(input.Subject)) + ) && + ( + this.PrimaryEmail == input.PrimaryEmail || + (this.PrimaryEmail != null && + this.PrimaryEmail.Equals(input.PrimaryEmail)) + ) && + ( + this.CcEmails == input.CcEmails || + this.CcEmails != null && + this.CcEmails.SequenceEqual(input.CcEmails) + ) && + ( + this.Appointments == input.Appointments || + this.Appointments != null && + this.Appointments.SequenceEqual(input.Appointments) + ) && + ( + this.CreatedDate == input.CreatedDate || + (this.CreatedDate != null && + this.CreatedDate.Equals(input.CreatedDate)) + ) && + ( + this.LastUpdatedDate == input.LastUpdatedDate || + (this.LastUpdatedDate != null && + this.LastUpdatedDate.Equals(input.LastUpdatedDate)) + ) && + ( + this.ResolvedDate == input.ResolvedDate || + (this.ResolvedDate != null && + this.ResolvedDate.Equals(input.ResolvedDate)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.CaseId != null) + hashCode = hashCode * 59 + this.CaseId.GetHashCode(); + hashCode = hashCode * 59 + this.Status.GetHashCode(); + if (this.Subject != null) + hashCode = hashCode * 59 + this.Subject.GetHashCode(); + if (this.PrimaryEmail != null) + hashCode = hashCode * 59 + this.PrimaryEmail.GetHashCode(); + if (this.CcEmails != null) + hashCode = hashCode * 59 + this.CcEmails.GetHashCode(); + if (this.Appointments != null) + hashCode = hashCode * 59 + this.Appointments.GetHashCode(); + if (this.CreatedDate != null) + hashCode = hashCode * 59 + this.CreatedDate.GetHashCode(); + if (this.LastUpdatedDate != null) + hashCode = hashCode * 59 + this.LastUpdatedDate.GetHashCode(); + if (this.ResolvedDate != null) + hashCode = hashCode * 59 + this.ResolvedDate.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CaseFilters.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CaseFilters.cs new file mode 100644 index 00000000..9c3f64f8 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CaseFilters.cs @@ -0,0 +1,271 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// Optional filters for case search. All filters are optional — when absent, no filtering is applied for that field. Different filters are combined with AND logic, and multiple values of the same field are combined with OR logic. + /// + [DataContract] + public partial class CaseFilters : IEquatable, IValidatableObject + { + /// + /// Filter the collection by one or more case statuses. + /// + /// Filter the collection by one or more case statuses. + [JsonConverter(typeof(StringEnumConverter))] + public enum CaseStatusesEnum + { + + /// + /// Enum RESOLVED for value: RESOLVED + /// + [EnumMember(Value = "RESOLVED")] + RESOLVED = 1, + + /// + /// Enum TRANSFERRED for value: TRANSFERRED + /// + [EnumMember(Value = "TRANSFERRED")] + TRANSFERRED = 2, + + /// + /// Enum PENDINGMERCHANTACTION for value: PENDING_MERCHANT_ACTION + /// + [EnumMember(Value = "PENDING_MERCHANT_ACTION")] + PENDINGMERCHANTACTION = 3, + + /// + /// Enum PENDINGAMAZONACTION for value: PENDING_AMAZON_ACTION + /// + [EnumMember(Value = "PENDING_AMAZON_ACTION")] + PENDINGAMAZONACTION = 4 + } + + /// + /// Initializes a new instance of the class. + /// + /// Filter the collection by one or more case statuses.. + /// Filter the collection by case creation date.. + /// Filter the collection by last outbound contact date.. + /// Filter the collection by case resolution date.. + /// Filter the collection by primary email address.. + /// Filter the collection by one or more CC email addresses.. + /// Filter the collection by case subject keywords. Maximum 200 characters.. + public CaseFilters(List caseStatuses = default(List), DateFilter createdDate = default(DateFilter), DateFilter lastOutboundDate = default(DateFilter), DateFilter resolvedDate = default(DateFilter), List primaryEmails = default(List), List ccEmails = default(List), string subjectKeywords = default(string)) + { + this.CaseStatuses = caseStatuses; + this.CreatedDate = createdDate; + this.LastOutboundDate = lastOutboundDate; + this.ResolvedDate = resolvedDate; + this.PrimaryEmails = primaryEmails; + this.CcEmails = ccEmails; + this.SubjectKeywords = subjectKeywords; + } + + /// + /// Filter the collection by one or more case statuses. + /// + /// Filter the collection by one or more case statuses. + [DataMember(Name="caseStatuses", EmitDefaultValue=false)] + public List CaseStatuses { get; set; } + + /// + /// Filter the collection by case creation date. + /// + /// Filter the collection by case creation date. + [DataMember(Name="createdDate", EmitDefaultValue=false)] + public DateFilter CreatedDate { get; set; } + + /// + /// Filter the collection by last outbound contact date. + /// + /// Filter the collection by last outbound contact date. + [DataMember(Name="lastOutboundDate", EmitDefaultValue=false)] + public DateFilter LastOutboundDate { get; set; } + + /// + /// Filter the collection by case resolution date. + /// + /// Filter the collection by case resolution date. + [DataMember(Name="resolvedDate", EmitDefaultValue=false)] + public DateFilter ResolvedDate { get; set; } + + /// + /// Filter the collection by primary email address. + /// + /// Filter the collection by primary email address. + [DataMember(Name="primaryEmails", EmitDefaultValue=false)] + public List PrimaryEmails { get; set; } + + /// + /// Filter the collection by one or more CC email addresses. + /// + /// Filter the collection by one or more CC email addresses. + [DataMember(Name="ccEmails", EmitDefaultValue=false)] + public List CcEmails { get; set; } + + /// + /// Filter the collection by case subject keywords. Maximum 200 characters. + /// + /// Filter the collection by case subject keywords. Maximum 200 characters. + [DataMember(Name="subjectKeywords", EmitDefaultValue=false)] + public string SubjectKeywords { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class CaseFilters {\n"); + sb.Append(" CaseStatuses: ").Append(CaseStatuses).Append("\n"); + sb.Append(" CreatedDate: ").Append(CreatedDate).Append("\n"); + sb.Append(" LastOutboundDate: ").Append(LastOutboundDate).Append("\n"); + sb.Append(" ResolvedDate: ").Append(ResolvedDate).Append("\n"); + sb.Append(" PrimaryEmails: ").Append(PrimaryEmails).Append("\n"); + sb.Append(" CcEmails: ").Append(CcEmails).Append("\n"); + sb.Append(" SubjectKeywords: ").Append(SubjectKeywords).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as CaseFilters); + } + + /// + /// Returns true if CaseFilters instances are equal + /// + /// Instance of CaseFilters to be compared + /// Boolean + public bool Equals(CaseFilters input) + { + if (input == null) + return false; + + return + ( + this.CaseStatuses == input.CaseStatuses || + this.CaseStatuses != null && + this.CaseStatuses.SequenceEqual(input.CaseStatuses) + ) && + ( + this.CreatedDate == input.CreatedDate || + (this.CreatedDate != null && + this.CreatedDate.Equals(input.CreatedDate)) + ) && + ( + this.LastOutboundDate == input.LastOutboundDate || + (this.LastOutboundDate != null && + this.LastOutboundDate.Equals(input.LastOutboundDate)) + ) && + ( + this.ResolvedDate == input.ResolvedDate || + (this.ResolvedDate != null && + this.ResolvedDate.Equals(input.ResolvedDate)) + ) && + ( + this.PrimaryEmails == input.PrimaryEmails || + this.PrimaryEmails != null && + this.PrimaryEmails.SequenceEqual(input.PrimaryEmails) + ) && + ( + this.CcEmails == input.CcEmails || + this.CcEmails != null && + this.CcEmails.SequenceEqual(input.CcEmails) + ) && + ( + this.SubjectKeywords == input.SubjectKeywords || + (this.SubjectKeywords != null && + this.SubjectKeywords.Equals(input.SubjectKeywords)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.CaseStatuses != null) + hashCode = hashCode * 59 + this.CaseStatuses.GetHashCode(); + if (this.CreatedDate != null) + hashCode = hashCode * 59 + this.CreatedDate.GetHashCode(); + if (this.LastOutboundDate != null) + hashCode = hashCode * 59 + this.LastOutboundDate.GetHashCode(); + if (this.ResolvedDate != null) + hashCode = hashCode * 59 + this.ResolvedDate.GetHashCode(); + if (this.PrimaryEmails != null) + hashCode = hashCode * 59 + this.PrimaryEmails.GetHashCode(); + if (this.CcEmails != null) + hashCode = hashCode * 59 + this.CcEmails.GetHashCode(); + if (this.SubjectKeywords != null) + hashCode = hashCode * 59 + this.SubjectKeywords.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + // SubjectKeywords (string) maxLength + if(this.SubjectKeywords != null && this.SubjectKeywords.Length > 200) + { + yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for SubjectKeywords, length must be less than 200.", new [] { "SubjectKeywords" }); + } + + // SubjectKeywords (string) minLength + if(this.SubjectKeywords != null && this.SubjectKeywords.Length < 1) + { + yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for SubjectKeywords, length must be greater than 1.", new [] { "SubjectKeywords" }); + } + + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatContent.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatContent.cs new file mode 100644 index 00000000..c51a62ba --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatContent.cs @@ -0,0 +1,162 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The content for a chat contact. + /// + [DataContract] + public partial class ChatContent : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public ChatContent() { } + /// + /// Initializes a new instance of the class. + /// + /// A list of events that make up the chat contact. Not all chat contacts are broken into chat events, and it is recommended to fallback on the `transcript` when `events` is empty. (required). + /// The human-readable transcript of the chat contact. (required). + public ChatContent(List events = default(List), string transcript = default(string)) + { + // to ensure "events" is required (not null) + if (events == null) + { + throw new InvalidDataException("events is a required property for ChatContent and cannot be null"); + } + else + { + this.Events = events; + } + // to ensure "transcript" is required (not null) + if (transcript == null) + { + throw new InvalidDataException("transcript is a required property for ChatContent and cannot be null"); + } + else + { + this.Transcript = transcript; + } + } + + /// + /// A list of events that make up the chat contact. Not all chat contacts are broken into chat events, and it is recommended to fallback on the `transcript` when `events` is empty. + /// + /// A list of events that make up the chat contact. Not all chat contacts are broken into chat events, and it is recommended to fallback on the `transcript` when `events` is empty. + [DataMember(Name="events", EmitDefaultValue=false)] + public List Events { get; set; } + + /// + /// The human-readable transcript of the chat contact. + /// + /// The human-readable transcript of the chat contact. + [DataMember(Name="transcript", EmitDefaultValue=false)] + public string Transcript { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class ChatContent {\n"); + sb.Append(" Events: ").Append(Events).Append("\n"); + sb.Append(" Transcript: ").Append(Transcript).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ChatContent); + } + + /// + /// Returns true if ChatContent instances are equal + /// + /// Instance of ChatContent to be compared + /// Boolean + public bool Equals(ChatContent input) + { + if (input == null) + return false; + + return + ( + this.Events == input.Events || + this.Events != null && + this.Events.SequenceEqual(input.Events) + ) && + ( + this.Transcript == input.Transcript || + (this.Transcript != null && + this.Transcript.Equals(input.Transcript)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Events != null) + hashCode = hashCode * 59 + this.Events.GetHashCode(); + if (this.Transcript != null) + hashCode = hashCode * 59 + this.Transcript.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatEvent.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatEvent.cs new file mode 100644 index 00000000..4e842d9b --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatEvent.cs @@ -0,0 +1,247 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A single event from a chat contact. + /// + [DataContract] + public partial class ChatEvent : IEquatable, IValidatableObject + { + /// + /// The type of chat event. + /// + /// The type of chat event. + [JsonConverter(typeof(StringEnumConverter))] + public enum TypeEnum + { + + /// + /// Enum MESSAGE for value: MESSAGE + /// + [EnumMember(Value = "MESSAGE")] + MESSAGE = 1, + + /// + /// Enum ATTACHMENT for value: ATTACHMENT + /// + [EnumMember(Value = "ATTACHMENT")] + ATTACHMENT = 2, + + /// + /// Enum PARTICIPANTJOINED for value: PARTICIPANT_JOINED + /// + [EnumMember(Value = "PARTICIPANT_JOINED")] + PARTICIPANTJOINED = 3, + + /// + /// Enum PARTICIPANTLEFT for value: PARTICIPANT_LEFT + /// + [EnumMember(Value = "PARTICIPANT_LEFT")] + PARTICIPANTLEFT = 4, + + /// + /// Enum PARTICIPANTIDLE for value: PARTICIPANT_IDLE + /// + [EnumMember(Value = "PARTICIPANT_IDLE")] + PARTICIPANTIDLE = 5, + + /// + /// Enum CHATENDED for value: CHAT_ENDED + /// + [EnumMember(Value = "CHAT_ENDED")] + CHATENDED = 6 + } + + /// + /// The type of chat event. + /// + /// The type of chat event. + [DataMember(Name="type", EmitDefaultValue=false)] + public TypeEnum Type { get; set; } + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public ChatEvent() { } + /// + /// Initializes a new instance of the class. + /// + /// The time at which the event occurred. (required). + /// The type of chat event. (required). + /// The message from the chat event. Only present if the event type is `MESSAGE`.. + /// The entity that is associated with the event.. + /// All attachments included in the event. Only present if the event type is `ATTACHMENT`.. + public ChatEvent(DateTime? timestamp = default(DateTime?), TypeEnum type = default(TypeEnum), string message = default(string), Participant participant = default(Participant), List attachments = default(List)) + { + // to ensure "timestamp" is required (not null) + if (timestamp == null) + { + throw new InvalidDataException("timestamp is a required property for ChatEvent and cannot be null"); + } + else + { + this.Timestamp = timestamp; + } + this.Type = type; + this.Message = message; + this.Participant = participant; + this.Attachments = attachments; + } + + /// + /// The time at which the event occurred. + /// + /// The time at which the event occurred. + [DataMember(Name="timestamp", EmitDefaultValue=false)] + public DateTime? Timestamp { get; set; } + + /// + /// The message from the chat event. Only present if the event type is `MESSAGE`. + /// + /// The message from the chat event. Only present if the event type is `MESSAGE`. + [DataMember(Name="message", EmitDefaultValue=false)] + public string Message { get; set; } + + /// + /// The entity that is associated with the event. + /// + /// The entity that is associated with the event. + [DataMember(Name="participant", EmitDefaultValue=false)] + public Participant Participant { get; set; } + + /// + /// All attachments included in the event. Only present if the event type is `ATTACHMENT`. + /// + /// All attachments included in the event. Only present if the event type is `ATTACHMENT`. + [DataMember(Name="attachments", EmitDefaultValue=false)] + public List Attachments { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class ChatEvent {\n"); + sb.Append(" Timestamp: ").Append(Timestamp).Append("\n"); + sb.Append(" Type: ").Append(Type).Append("\n"); + sb.Append(" Message: ").Append(Message).Append("\n"); + sb.Append(" Participant: ").Append(Participant).Append("\n"); + sb.Append(" Attachments: ").Append(Attachments).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ChatEvent); + } + + /// + /// Returns true if ChatEvent instances are equal + /// + /// Instance of ChatEvent to be compared + /// Boolean + public bool Equals(ChatEvent input) + { + if (input == null) + return false; + + return + ( + this.Timestamp == input.Timestamp || + (this.Timestamp != null && + this.Timestamp.Equals(input.Timestamp)) + ) && + ( + this.Type == input.Type || + this.Type.Equals(input.Type) + ) && + ( + this.Message == input.Message || + (this.Message != null && + this.Message.Equals(input.Message)) + ) && + ( + this.Participant == input.Participant || + (this.Participant != null && + this.Participant.Equals(input.Participant)) + ) && + ( + this.Attachments == input.Attachments || + this.Attachments != null && + this.Attachments.SequenceEqual(input.Attachments) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Timestamp != null) + hashCode = hashCode * 59 + this.Timestamp.GetHashCode(); + hashCode = hashCode * 59 + this.Type.GetHashCode(); + if (this.Message != null) + hashCode = hashCode * 59 + this.Message.GetHashCode(); + if (this.Participant != null) + hashCode = hashCode * 59 + this.Participant.GetHashCode(); + if (this.Attachments != null) + hashCode = hashCode * 59 + this.Attachments.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Contact.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Contact.cs new file mode 100644 index 00000000..7e97aef2 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Contact.cs @@ -0,0 +1,254 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A contact. + /// + [DataContract] + public partial class Contact : IEquatable, IValidatableObject + { + /// + /// The contact channel for communication between the selling partner and Amazon. + /// + /// The contact channel for communication between the selling partner and Amazon. + [JsonConverter(typeof(StringEnumConverter))] + public enum ChannelEnum + { + + /// + /// Enum PHONE for value: PHONE + /// + [EnumMember(Value = "PHONE")] + PHONE = 1, + + /// + /// Enum CHAT for value: CHAT + /// + [EnumMember(Value = "CHAT")] + CHAT = 2, + + /// + /// Enum EMAIL for value: EMAIL + /// + [EnumMember(Value = "EMAIL")] + EMAIL = 3 + } + + /// + /// The contact channel for communication between the selling partner and Amazon. + /// + /// The contact channel for communication between the selling partner and Amazon. + [DataMember(Name="channel", EmitDefaultValue=false)] + public ChannelEnum Channel { get; set; } + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public Contact() { } + /// + /// Initializes a new instance of the class. + /// + /// A unique identifier for the contact (required). + /// The contact channel for communication between the selling partner and Amazon. (required). + /// The content of the contact. Only available if the contact channel is `EMAIL`.. + /// The content of the contact. Only available if the contact channel is `PHONE`.. + /// The content of the contact. Only available if the contact channel is `CHAT`.. + /// The time at which the contact was created. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. (required). + public Contact(string contactId = default(string), ChannelEnum channel = default(ChannelEnum), EmailContent emailContent = default(EmailContent), PhoneContent phoneContent = default(PhoneContent), ChatContent chatContent = default(ChatContent), DateTime? createdDate = default(DateTime?)) + { + // to ensure "contactId" is required (not null) + if (contactId == null) + { + throw new InvalidDataException("contactId is a required property for Contact and cannot be null"); + } + else + { + this.ContactId = contactId; + } + // to ensure "createdDate" is required (not null) + if (createdDate == null) + { + throw new InvalidDataException("createdDate is a required property for Contact and cannot be null"); + } + else + { + this.CreatedDate = createdDate; + } + this.Channel = channel; + this.EmailContent = emailContent; + this.PhoneContent = phoneContent; + this.ChatContent = chatContent; + } + + /// + /// A unique identifier for the contact + /// + /// A unique identifier for the contact + [DataMember(Name="contactId", EmitDefaultValue=false)] + public string ContactId { get; set; } + + /// + /// The content of the contact. Only available if the contact channel is `EMAIL`. + /// + /// The content of the contact. Only available if the contact channel is `EMAIL`. + [DataMember(Name="emailContent", EmitDefaultValue=false)] + public EmailContent EmailContent { get; set; } + + /// + /// The content of the contact. Only available if the contact channel is `PHONE`. + /// + /// The content of the contact. Only available if the contact channel is `PHONE`. + [DataMember(Name="phoneContent", EmitDefaultValue=false)] + public PhoneContent PhoneContent { get; set; } + + /// + /// The content of the contact. Only available if the contact channel is `CHAT`. + /// + /// The content of the contact. Only available if the contact channel is `CHAT`. + [DataMember(Name="chatContent", EmitDefaultValue=false)] + public ChatContent ChatContent { get; set; } + + /// + /// The time at which the contact was created. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + /// + /// The time at which the contact was created. In [ISO 8601](https://developer-docs.amazon/sp-api/docs/iso-8601) format. + [DataMember(Name="createdDate", EmitDefaultValue=false)] + public DateTime? CreatedDate { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Contact {\n"); + sb.Append(" ContactId: ").Append(ContactId).Append("\n"); + sb.Append(" Channel: ").Append(Channel).Append("\n"); + sb.Append(" EmailContent: ").Append(EmailContent).Append("\n"); + sb.Append(" PhoneContent: ").Append(PhoneContent).Append("\n"); + sb.Append(" ChatContent: ").Append(ChatContent).Append("\n"); + sb.Append(" CreatedDate: ").Append(CreatedDate).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Contact); + } + + /// + /// Returns true if Contact instances are equal + /// + /// Instance of Contact to be compared + /// Boolean + public bool Equals(Contact input) + { + if (input == null) + return false; + + return + ( + this.ContactId == input.ContactId || + (this.ContactId != null && + this.ContactId.Equals(input.ContactId)) + ) && + ( + this.Channel == input.Channel || + this.Channel.Equals(input.Channel) + ) && + ( + this.EmailContent == input.EmailContent || + (this.EmailContent != null && + this.EmailContent.Equals(input.EmailContent)) + ) && + ( + this.PhoneContent == input.PhoneContent || + (this.PhoneContent != null && + this.PhoneContent.Equals(input.PhoneContent)) + ) && + ( + this.ChatContent == input.ChatContent || + (this.ChatContent != null && + this.ChatContent.Equals(input.ChatContent)) + ) && + ( + this.CreatedDate == input.CreatedDate || + (this.CreatedDate != null && + this.CreatedDate.Equals(input.CreatedDate)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.ContactId != null) + hashCode = hashCode * 59 + this.ContactId.GetHashCode(); + hashCode = hashCode * 59 + this.Channel.GetHashCode(); + if (this.EmailContent != null) + hashCode = hashCode * 59 + this.EmailContent.GetHashCode(); + if (this.PhoneContent != null) + hashCode = hashCode * 59 + this.PhoneContent.GetHashCode(); + if (this.ChatContent != null) + hashCode = hashCode * 59 + this.ChatContent.GetHashCode(); + if (this.CreatedDate != null) + hashCode = hashCode * 59 + this.CreatedDate.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/DateFilter.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/DateFilter.cs new file mode 100644 index 00000000..0a31c169 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/DateFilter.cs @@ -0,0 +1,141 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A date range filter with optional before and after bounds. Dates must be in <a href='https://developer-docs.amazon.com/sp-api/docs/iso-8601'>ISO 8601</a> format. + /// + [DataContract] + public partial class DateFilter : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// Include results with timestamps strictly after this value (exclusive).. + /// Include results with timestamps strictly before this value (exclusive).. + public DateFilter(DateTime? after = default(DateTime?), DateTime? before = default(DateTime?)) + { + this.After = after; + this.Before = before; + } + + /// + /// Include results with timestamps strictly after this value (exclusive). + /// + /// Include results with timestamps strictly after this value (exclusive). + [DataMember(Name="after", EmitDefaultValue=false)] + public DateTime? After { get; set; } + + /// + /// Include results with timestamps strictly before this value (exclusive). + /// + /// Include results with timestamps strictly before this value (exclusive). + [DataMember(Name="before", EmitDefaultValue=false)] + public DateTime? Before { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class DateFilter {\n"); + sb.Append(" After: ").Append(After).Append("\n"); + sb.Append(" Before: ").Append(Before).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as DateFilter); + } + + /// + /// Returns true if DateFilter instances are equal + /// + /// Instance of DateFilter to be compared + /// Boolean + public bool Equals(DateFilter input) + { + if (input == null) + return false; + + return + ( + this.After == input.After || + (this.After != null && + this.After.Equals(input.After)) + ) && + ( + this.Before == input.Before || + (this.Before != null && + this.Before.Equals(input.Before)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.After != null) + hashCode = hashCode * 59 + this.After.GetHashCode(); + if (this.Before != null) + hashCode = hashCode * 59 + this.Before.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/EmailContent.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/EmailContent.cs new file mode 100644 index 00000000..6d317f71 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/EmailContent.cs @@ -0,0 +1,179 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The content of an email contact. + /// + [DataContract] + public partial class EmailContent : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public EmailContent() { } + /// + /// Initializes a new instance of the class. + /// + /// The entity who sent the contact. (required). + /// The email body of the contact. (required). + /// All attachments included in the contact.. + public EmailContent(Participant sender = default(Participant), string message = default(string), List attachments = default(List)) + { + // to ensure "sender" is required (not null) + if (sender == null) + { + throw new InvalidDataException("sender is a required property for EmailContent and cannot be null"); + } + else + { + this.Sender = sender; + } + // to ensure "message" is required (not null) + if (message == null) + { + throw new InvalidDataException("message is a required property for EmailContent and cannot be null"); + } + else + { + this.Message = message; + } + this.Attachments = attachments; + } + + /// + /// The entity who sent the contact. + /// + /// The entity who sent the contact. + [DataMember(Name="sender", EmitDefaultValue=false)] + public Participant Sender { get; set; } + + /// + /// The email body of the contact. + /// + /// The email body of the contact. + [DataMember(Name="message", EmitDefaultValue=false)] + public string Message { get; set; } + + /// + /// All attachments included in the contact. + /// + /// All attachments included in the contact. + [DataMember(Name="attachments", EmitDefaultValue=false)] + public List Attachments { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class EmailContent {\n"); + sb.Append(" Sender: ").Append(Sender).Append("\n"); + sb.Append(" Message: ").Append(Message).Append("\n"); + sb.Append(" Attachments: ").Append(Attachments).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as EmailContent); + } + + /// + /// Returns true if EmailContent instances are equal + /// + /// Instance of EmailContent to be compared + /// Boolean + public bool Equals(EmailContent input) + { + if (input == null) + return false; + + return + ( + this.Sender == input.Sender || + (this.Sender != null && + this.Sender.Equals(input.Sender)) + ) && + ( + this.Message == input.Message || + (this.Message != null && + this.Message.Equals(input.Message)) + ) && + ( + this.Attachments == input.Attachments || + this.Attachments != null && + this.Attachments.SequenceEqual(input.Attachments) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Sender != null) + hashCode = hashCode * 59 + this.Sender.GetHashCode(); + if (this.Message != null) + hashCode = hashCode * 59 + this.Message.GetHashCode(); + if (this.Attachments != null) + hashCode = hashCode * 59 + this.Attachments.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Error.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Error.cs new file mode 100644 index 00000000..4e82394f --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Error.cs @@ -0,0 +1,179 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// Error response returned when the request is unsuccessful. + /// + [DataContract] + public partial class Error : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public Error() { } + /// + /// Initializes a new instance of the class. + /// + /// An error code that identifies the type of error that occurred. (required). + /// A message that describes the error condition. (required). + /// Additional details that can help the caller understand or fix the issue.. + public Error(string code = default(string), string message = default(string), string details = default(string)) + { + // to ensure "code" is required (not null) + if (code == null) + { + throw new InvalidDataException("code is a required property for Error and cannot be null"); + } + else + { + this.Code = code; + } + // to ensure "message" is required (not null) + if (message == null) + { + throw new InvalidDataException("message is a required property for Error and cannot be null"); + } + else + { + this.Message = message; + } + this.Details = details; + } + + /// + /// An error code that identifies the type of error that occurred. + /// + /// An error code that identifies the type of error that occurred. + [DataMember(Name="code", EmitDefaultValue=false)] + public string Code { get; set; } + + /// + /// A message that describes the error condition. + /// + /// A message that describes the error condition. + [DataMember(Name="message", EmitDefaultValue=false)] + public string Message { get; set; } + + /// + /// Additional details that can help the caller understand or fix the issue. + /// + /// Additional details that can help the caller understand or fix the issue. + [DataMember(Name="details", EmitDefaultValue=false)] + public string Details { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Error {\n"); + sb.Append(" Code: ").Append(Code).Append("\n"); + sb.Append(" Message: ").Append(Message).Append("\n"); + sb.Append(" Details: ").Append(Details).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Error); + } + + /// + /// Returns true if Error instances are equal + /// + /// Instance of Error to be compared + /// Boolean + public bool Equals(Error input) + { + if (input == null) + return false; + + return + ( + this.Code == input.Code || + (this.Code != null && + this.Code.Equals(input.Code)) + ) && + ( + this.Message == input.Message || + (this.Message != null && + this.Message.Equals(input.Message)) + ) && + ( + this.Details == input.Details || + (this.Details != null && + this.Details.Equals(input.Details)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Code != null) + hashCode = hashCode * 59 + this.Code.GetHashCode(); + if (this.Message != null) + hashCode = hashCode * 59 + this.Message.GetHashCode(); + if (this.Details != null) + hashCode = hashCode * 59 + this.Details.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ErrorList.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ErrorList.cs new file mode 100644 index 00000000..2dfdba68 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ErrorList.cs @@ -0,0 +1,137 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A list of error responses returned when a request is unsuccessful. + /// + [DataContract] + public partial class ErrorList : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public ErrorList() { } + /// + /// Initializes a new instance of the class. + /// + /// array of errors (required). + public ErrorList(List errors = default(List)) + { + // to ensure "errors" is required (not null) + if (errors == null) + { + throw new InvalidDataException("errors is a required property for ErrorList and cannot be null"); + } + else + { + this.Errors = errors; + } + } + + /// + /// array of errors + /// + /// array of errors + [DataMember(Name="errors", EmitDefaultValue=false)] + public List Errors { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class ErrorList {\n"); + sb.Append(" Errors: ").Append(Errors).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ErrorList); + } + + /// + /// Returns true if ErrorList instances are equal + /// + /// Instance of ErrorList to be compared + /// Boolean + public bool Equals(ErrorList input) + { + if (input == null) + return false; + + return + ( + this.Errors == input.Errors || + this.Errors != null && + this.Errors.SequenceEqual(input.Errors) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Errors != null) + hashCode = hashCode * 59 + this.Errors.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesRequest.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesRequest.cs new file mode 100644 index 00000000..7e7e435b --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesRequest.cs @@ -0,0 +1,207 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The request body for the listCases operation. + /// + [DataContract] + public partial class ListCasesRequest : IEquatable, IValidatableObject + { + /// + /// The sort direction. Defaults to DESC when absent. + /// + /// The sort direction. Defaults to DESC when absent. + [JsonConverter(typeof(StringEnumConverter))] + public enum SortOrderEnum + { + + /// + /// Enum ASC for value: ASC + /// + [EnumMember(Value = "ASC")] + ASC = 1, + + /// + /// Enum DESC for value: DESC + /// + [EnumMember(Value = "DESC")] + DESC = 2 + } + + /// + /// The sort direction. Defaults to DESC when absent. + /// + /// The sort direction. Defaults to DESC when absent. + [DataMember(Name="sortOrder", EmitDefaultValue=false)] + public SortOrderEnum? SortOrder { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// Optional filters to narrow the returned collection. When absent, the operation returns all cases for the requesting identity.. + /// The sort direction. Defaults to DESC when absent.. + /// Maximum number of results to return.. + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages.. + public ListCasesRequest(CaseFilters caseFilters = default(CaseFilters), SortOrderEnum? sortOrder = default(SortOrderEnum?), int? maxResults = default(int?), string nextToken = default(string)) + { + this.CaseFilters = caseFilters; + this.SortOrder = sortOrder; + this.MaxResults = maxResults; + this.NextToken = nextToken; + } + + /// + /// Optional filters to narrow the returned collection. When absent, the operation returns all cases for the requesting identity. + /// + /// Optional filters to narrow the returned collection. When absent, the operation returns all cases for the requesting identity. + [DataMember(Name="caseFilters", EmitDefaultValue=false)] + public CaseFilters CaseFilters { get; set; } + + /// + /// Maximum number of results to return. + /// + /// Maximum number of results to return. + [DataMember(Name="maxResults", EmitDefaultValue=false)] + public int? MaxResults { get; set; } + + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages. + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages. + [DataMember(Name="nextToken", EmitDefaultValue=false)] + public string NextToken { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class ListCasesRequest {\n"); + sb.Append(" CaseFilters: ").Append(CaseFilters).Append("\n"); + sb.Append(" SortOrder: ").Append(SortOrder).Append("\n"); + sb.Append(" MaxResults: ").Append(MaxResults).Append("\n"); + sb.Append(" NextToken: ").Append(NextToken).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ListCasesRequest); + } + + /// + /// Returns true if ListCasesRequest instances are equal + /// + /// Instance of ListCasesRequest to be compared + /// Boolean + public bool Equals(ListCasesRequest input) + { + if (input == null) + return false; + + return + ( + this.CaseFilters == input.CaseFilters || + (this.CaseFilters != null && + this.CaseFilters.Equals(input.CaseFilters)) + ) && + ( + this.SortOrder == input.SortOrder || + (this.SortOrder != null && + this.SortOrder.Equals(input.SortOrder)) + ) && + ( + this.MaxResults == input.MaxResults || + (this.MaxResults != null && + this.MaxResults.Equals(input.MaxResults)) + ) && + ( + this.NextToken == input.NextToken || + (this.NextToken != null && + this.NextToken.Equals(input.NextToken)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.CaseFilters != null) + hashCode = hashCode * 59 + this.CaseFilters.GetHashCode(); + if (this.SortOrder != null) + hashCode = hashCode * 59 + this.SortOrder.GetHashCode(); + if (this.MaxResults != null) + hashCode = hashCode * 59 + this.MaxResults.GetHashCode(); + if (this.NextToken != null) + hashCode = hashCode * 59 + this.NextToken.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + // MaxResults (int?) maximum + if(this.MaxResults > (int?)50) + { + yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for MaxResults, must be a value less than or equal to 50.", new [] { "MaxResults" }); + } + + // MaxResults (int?) minimum + if(this.MaxResults < (int?)1) + { + yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for MaxResults, must be a value greater than or equal to 1.", new [] { "MaxResults" }); + } + + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesResult.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesResult.cs new file mode 100644 index 00000000..64647a62 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesResult.cs @@ -0,0 +1,154 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A list of support cases. + /// + [DataContract] + public partial class ListCasesResult : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public ListCasesResult() { } + /// + /// Initializes a new instance of the class. + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages.. + /// A paginated list of support cases. (required). + public ListCasesResult(string nextToken = default(string), List cases = default(List)) + { + // to ensure "cases" is required (not null) + if (cases == null) + { + throw new InvalidDataException("cases is a required property for ListCasesResult and cannot be null"); + } + else + { + this.Cases = cases; + } + this.NextToken = nextToken; + } + + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages. + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages. + [DataMember(Name="nextToken", EmitDefaultValue=false)] + public string NextToken { get; set; } + + /// + /// A paginated list of support cases. + /// + /// A paginated list of support cases. + [DataMember(Name="cases", EmitDefaultValue=false)] + public List Cases { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class ListCasesResult {\n"); + sb.Append(" NextToken: ").Append(NextToken).Append("\n"); + sb.Append(" Cases: ").Append(Cases).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ListCasesResult); + } + + /// + /// Returns true if ListCasesResult instances are equal + /// + /// Instance of ListCasesResult to be compared + /// Boolean + public bool Equals(ListCasesResult input) + { + if (input == null) + return false; + + return + ( + this.NextToken == input.NextToken || + (this.NextToken != null && + this.NextToken.Equals(input.NextToken)) + ) && + ( + this.Cases == input.Cases || + this.Cases != null && + this.Cases.SequenceEqual(input.Cases) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.NextToken != null) + hashCode = hashCode * 59 + this.NextToken.GetHashCode(); + if (this.Cases != null) + hashCode = hashCode * 59 + this.Cases.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListContactsResult.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListContactsResult.cs new file mode 100644 index 00000000..7813bcdf --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListContactsResult.cs @@ -0,0 +1,154 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A list of contacts. + /// + [DataContract] + public partial class ListContactsResult : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public ListContactsResult() { } + /// + /// Initializes a new instance of the class. + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `pageSize` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages.. + /// A list of contacts. (required). + public ListContactsResult(string nextToken = default(string), List contacts = default(List)) + { + // to ensure "contacts" is required (not null) + if (contacts == null) + { + throw new InvalidDataException("contacts is a required property for ListContactsResult and cannot be null"); + } + else + { + this.Contacts = contacts; + } + this.NextToken = nextToken; + } + + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `pageSize` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages. + /// + /// A token to retrieve the next page of results. The response includes `nextToken` when the number of results exceeds the specified `pageSize` value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can return empty pages. + [DataMember(Name="nextToken", EmitDefaultValue=false)] + public string NextToken { get; set; } + + /// + /// A list of contacts. + /// + /// A list of contacts. + [DataMember(Name="contacts", EmitDefaultValue=false)] + public List Contacts { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class ListContactsResult {\n"); + sb.Append(" NextToken: ").Append(NextToken).Append("\n"); + sb.Append(" Contacts: ").Append(Contacts).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as ListContactsResult); + } + + /// + /// Returns true if ListContactsResult instances are equal + /// + /// Instance of ListContactsResult to be compared + /// Boolean + public bool Equals(ListContactsResult input) + { + if (input == null) + return false; + + return + ( + this.NextToken == input.NextToken || + (this.NextToken != null && + this.NextToken.Equals(input.NextToken)) + ) && + ( + this.Contacts == input.Contacts || + this.Contacts != null && + this.Contacts.SequenceEqual(input.Contacts) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.NextToken != null) + hashCode = hashCode * 59 + this.NextToken.GetHashCode(); + if (this.Contacts != null) + hashCode = hashCode * 59 + this.Contacts.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Participant.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Participant.cs new file mode 100644 index 00000000..d692263e --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Participant.cs @@ -0,0 +1,172 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// A participant for a single-directional communication between a selling partner and Amazon support. + /// + [DataContract] + public partial class Participant : IEquatable, IValidatableObject + { + /// + /// The role of the participant. + /// + /// The role of the participant. + [JsonConverter(typeof(StringEnumConverter))] + public enum RoleEnum + { + + /// + /// Enum AMAZON for value: AMAZON + /// + [EnumMember(Value = "AMAZON")] + AMAZON = 1, + + /// + /// Enum SELLINGPARTNER for value: SELLING_PARTNER + /// + [EnumMember(Value = "SELLING_PARTNER")] + SELLINGPARTNER = 2 + } + + /// + /// The role of the participant. + /// + /// The role of the participant. + [DataMember(Name="role", EmitDefaultValue=false)] + public RoleEnum Role { get; set; } + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public Participant() { } + /// + /// Initializes a new instance of the class. + /// + /// The human-readable name of the participant. (required). + /// The role of the participant. (required). + public Participant(string displayName = default(string), RoleEnum role = default(RoleEnum)) + { + // to ensure "displayName" is required (not null) + if (displayName == null) + { + throw new InvalidDataException("displayName is a required property for Participant and cannot be null"); + } + else + { + this.DisplayName = displayName; + } + this.Role = role; + } + + /// + /// The human-readable name of the participant. + /// + /// The human-readable name of the participant. + [DataMember(Name="displayName", EmitDefaultValue=false)] + public string DisplayName { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class Participant {\n"); + sb.Append(" DisplayName: ").Append(DisplayName).Append("\n"); + sb.Append(" Role: ").Append(Role).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as Participant); + } + + /// + /// Returns true if Participant instances are equal + /// + /// Instance of Participant to be compared + /// Boolean + public bool Equals(Participant input) + { + if (input == null) + return false; + + return + ( + this.DisplayName == input.DisplayName || + (this.DisplayName != null && + this.DisplayName.Equals(input.DisplayName)) + ) && + ( + this.Role == input.Role || + this.Role.Equals(input.Role) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.DisplayName != null) + hashCode = hashCode * 59 + this.DisplayName.GetHashCode(); + hashCode = hashCode * 59 + this.Role.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneContent.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneContent.cs new file mode 100644 index 00000000..35839fd6 --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneContent.cs @@ -0,0 +1,124 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The content for a phone contact. + /// + [DataContract] + public partial class PhoneContent : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// Notes that summarize the phone call, provided by Amazon support. + public PhoneContent(string callNotes = default(string)) + { + this.CallNotes = callNotes; + } + + /// + /// Notes that summarize the phone call, provided by Amazon support + /// + /// Notes that summarize the phone call, provided by Amazon support + [DataMember(Name="callNotes", EmitDefaultValue=false)] + public string CallNotes { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class PhoneContent {\n"); + sb.Append(" CallNotes: ").Append(CallNotes).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as PhoneContent); + } + + /// + /// Returns true if PhoneContent instances are equal + /// + /// Instance of PhoneContent to be compared + /// Boolean + public bool Equals(PhoneContent input) + { + if (input == null) + return false; + + return + ( + this.CallNotes == input.CallNotes || + (this.CallNotes != null && + this.CallNotes.Equals(input.CallNotes)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.CallNotes != null) + hashCode = hashCode * 59 + this.CallNotes.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneNumber.cs b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneNumber.cs new file mode 100644 index 00000000..bd78019c --- /dev/null +++ b/Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneNumber.cs @@ -0,0 +1,179 @@ +/* + * The Selling Partner API for Support + * + * The Selling Partner API for Support provides programmatic access to information about Selling Partner support. + * + * OpenAPI spec version: 2025-02-01 + * Contact: Selling Partner API Developer Support + * Generated from: https://github.com/amzn/selling-partner-api-models/blob/main/models/support-api-model/support_2025-02-01.json + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; + +namespace FikaAmazonAPI.AmazonSpApiSDK.Models.Support +{ + /// + /// The selling partner's phone number. + /// + [DataContract] + public partial class PhoneNumber : IEquatable, IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + public PhoneNumber() { } + /// + /// Initializes a new instance of the class. + /// + /// The ISO 3166-1 two-digit country code for the calling country. (required). + /// The phone number to call. (required). + /// The extension to use for the call, if applicable.. + public PhoneNumber(string countryCode = default(string), string number = default(string), string extension = default(string)) + { + // to ensure "countryCode" is required (not null) + if (countryCode == null) + { + throw new InvalidDataException("countryCode is a required property for PhoneNumber and cannot be null"); + } + else + { + this.CountryCode = countryCode; + } + // to ensure "number" is required (not null) + if (number == null) + { + throw new InvalidDataException("number is a required property for PhoneNumber and cannot be null"); + } + else + { + this.Number = number; + } + this.Extension = extension; + } + + /// + /// The ISO 3166-1 two-digit country code for the calling country. + /// + /// The ISO 3166-1 two-digit country code for the calling country. + [DataMember(Name="countryCode", EmitDefaultValue=false)] + public string CountryCode { get; set; } + + /// + /// The phone number to call. + /// + /// The phone number to call. + [DataMember(Name="number", EmitDefaultValue=false)] + public string Number { get; set; } + + /// + /// The extension to use for the call, if applicable. + /// + /// The extension to use for the call, if applicable. + [DataMember(Name="extension", EmitDefaultValue=false)] + public string Extension { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class PhoneNumber {\n"); + sb.Append(" CountryCode: ").Append(CountryCode).Append("\n"); + sb.Append(" Number: ").Append(Number).Append("\n"); + sb.Append(" Extension: ").Append(Extension).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public virtual string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as PhoneNumber); + } + + /// + /// Returns true if PhoneNumber instances are equal + /// + /// Instance of PhoneNumber to be compared + /// Boolean + public bool Equals(PhoneNumber input) + { + if (input == null) + return false; + + return + ( + this.CountryCode == input.CountryCode || + (this.CountryCode != null && + this.CountryCode.Equals(input.CountryCode)) + ) && + ( + this.Number == input.Number || + (this.Number != null && + this.Number.Equals(input.Number)) + ) && + ( + this.Extension == input.Extension || + (this.Extension != null && + this.Extension.Equals(input.Extension)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.CountryCode != null) + hashCode = hashCode * 59 + this.CountryCode.GetHashCode(); + if (this.Number != null) + hashCode = hashCode * 59 + this.Number.GetHashCode(); + if (this.Extension != null) + hashCode = hashCode * 59 + this.Extension.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/Source/FikaAmazonAPI/Parameter/Support/ParameterListCases.cs b/Source/FikaAmazonAPI/Parameter/Support/ParameterListCases.cs new file mode 100644 index 00000000..1ebcb842 --- /dev/null +++ b/Source/FikaAmazonAPI/Parameter/Support/ParameterListCases.cs @@ -0,0 +1,41 @@ +using FikaAmazonAPI.AmazonSpApiSDK.Models.Support; +using FikaAmazonAPI.Search; + +namespace FikaAmazonAPI.Parameter.Support +{ + /// + /// Parameters for listCases. The operation is a POST, so these values are sent as the + /// body rather than as query parameters. + /// + public class ParameterListCases : ParameterBased + { + /// + /// Optional filters to narrow the returned collection. When absent, the operation returns all cases for the requesting identity. + /// + public CaseFilters CaseFilters { get; set; } + + /// + /// The sort direction. Defaults to DESC when absent. + /// + public ListCasesRequest.SortOrderEnum? SortOrder { get; set; } + + /// + /// The maximum number of results to include in each page. The value must be between 1 and 50. Defaults to 10. + /// + public int? MaxResults { get; set; } + + /// + /// A token to retrieve the next page of results. The response includes nextToken when there are multiple pages of results. + /// + public string NextToken { get; set; } + + /// + /// Maximum number of pages to return. When null, all pages are fetched. + /// + [IgnoreToAddParameter] + public int? MaxNumberOfPages { get; set; } + + internal ListCasesRequest ToRequest() => + new ListCasesRequest(caseFilters: CaseFilters, sortOrder: SortOrder, maxResults: MaxResults, nextToken: NextToken); + } +} diff --git a/Source/FikaAmazonAPI/Parameter/Support/ParameterListContacts.cs b/Source/FikaAmazonAPI/Parameter/Support/ParameterListContacts.cs new file mode 100644 index 00000000..19cf0c65 --- /dev/null +++ b/Source/FikaAmazonAPI/Parameter/Support/ParameterListContacts.cs @@ -0,0 +1,29 @@ +using FikaAmazonAPI.Search; + +namespace FikaAmazonAPI.Parameter.Support +{ + [CamelCase] + public class ParameterListContacts : ParameterBased + { + /// + /// The maximum number of results to include in each page. The value must be between 1 and 50. Defaults to 10. + /// + public int? MaxResults { get; set; } + + /// + /// A token to retrieve the next page of results. The response includes nextToken when there are multiple pages of results. + /// + public string NextToken { get; set; } + + /// + /// Sort the returned contacts by createdDate in either ascending or descending order. Defaults to DESC. + /// + public SupportSortOrder? SortOrder { get; set; } + + /// + /// Maximum number of pages to return. When null, all pages are fetched. + /// + [IgnoreToAddParameter] + public int? MaxNumberOfPages { get; set; } + } +} diff --git a/Source/FikaAmazonAPI/Parameter/Support/SupportSortOrder.cs b/Source/FikaAmazonAPI/Parameter/Support/SupportSortOrder.cs new file mode 100644 index 00000000..5e820a5f --- /dev/null +++ b/Source/FikaAmazonAPI/Parameter/Support/SupportSortOrder.cs @@ -0,0 +1,15 @@ +namespace FikaAmazonAPI.Parameter.Support +{ + /// + /// The sort direction for listContacts, which sorts contacts by createdDate. + /// The enum member names match the exact values expected by the SP-API. + /// + public enum SupportSortOrder + { + /// Sort the collection in ascending order. + ASC, + + /// Sort the collection in descending order. + DESC + } +} diff --git a/Source/FikaAmazonAPI/Services/ApiUrls.cs b/Source/FikaAmazonAPI/Services/ApiUrls.cs index 4bdc8407..d23ff02e 100644 --- a/Source/FikaAmazonAPI/Services/ApiUrls.cs +++ b/Source/FikaAmazonAPI/Services/ApiUrls.cs @@ -834,6 +834,15 @@ protected class ApplicationManagementApiUrls public static string RotateApplicationClientSecret => $"{_resourceBaseUrl}/clientSecret"; } + protected class SupportApiUrls + { + private static readonly string _resourceBaseUrl = "/support/2025-02-01"; + + public static string Cases => $"{_resourceBaseUrl}/cases"; + public static string Case(string caseId) => $"{_resourceBaseUrl}/cases/{caseId}"; + public static string Contacts(string caseId) => $"{Case(caseId)}/contacts"; + } + } diff --git a/Source/FikaAmazonAPI/Services/SupportService.cs b/Source/FikaAmazonAPI/Services/SupportService.cs new file mode 100644 index 00000000..9a5dca17 --- /dev/null +++ b/Source/FikaAmazonAPI/Services/SupportService.cs @@ -0,0 +1,166 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +using FikaAmazonAPI.AmazonSpApiSDK.Models.Support; +using FikaAmazonAPI.AmazonSpApiSDK.Models.Token; +using FikaAmazonAPI.Parameter.Support; +using FikaAmazonAPI.Utils; + +using Microsoft.Extensions.Logging; + +using Method = FikaAmazonAPI.RestSharp.Method; + +namespace FikaAmazonAPI.Services +{ + /// + /// Selling Partner API for Support v2025-02-01. Retrieves support cases and their contact history. + /// Requires the Selling Partner Support (Restricted) role. + /// + public class SupportService : RequestService + { + public SupportService(AmazonCredential amazonCredential, ILoggerFactory loggerFactory) : base(amazonCredential, loggerFactory) + { + } + + #region ListCases + + public List ListCases(ParameterListCases parameterListCases) => + Task.Run(() => ListCasesAsync(parameterListCases)).ConfigureAwait(false).GetAwaiter().GetResult(); + + public async Task> ListCasesAsync(ParameterListCases parameterListCases, CancellationToken ct = default) + { + ValidateListCases(parameterListCases); + + List list = new List(); + + var response = await ListCasesByNextTokenAsync(parameterListCases, ct); + if (response?.Cases != null) + list.AddRange(response.Cases); + + // Surface the token on the parameter object so callers can continue manually + // via ListCasesByNextToken, even when MaxNumberOfPages stops the loop below. + parameterListCases.NextToken = response?.NextToken; + + var totalPages = 1; + while (!string.IsNullOrEmpty(parameterListCases.NextToken) && + (!parameterListCases.MaxNumberOfPages.HasValue || totalPages < parameterListCases.MaxNumberOfPages.Value)) + { + var listCasesNextPage = await ListCasesByNextTokenAsync(parameterListCases, ct); + if (listCasesNextPage?.Cases != null) + list.AddRange(listCasesNextPage.Cases); + parameterListCases.NextToken = listCasesNextPage?.NextToken; + totalPages++; + } + + return list; + } + + public ListCasesResult ListCasesByNextToken(ParameterListCases parameterListCases) => + Task.Run(() => ListCasesByNextTokenAsync(parameterListCases)).ConfigureAwait(false).GetAwaiter().GetResult(); + + public async Task ListCasesByNextTokenAsync(ParameterListCases parameterListCases, CancellationToken ct = default) + { + ValidateListCases(parameterListCases); + + await CreateAuthorizedRequestAsync(SupportApiUrls.Cases, Method.Post, null, parameterListCases.ToRequest(), CacheTokenData.TokenDataType.Normal, null, ct); + return await ExecuteRequestAsync(RateLimitType.Support_ListCases, ct); + } + + #endregion + + public Case GetCase(string caseId) => + Task.Run(() => GetCaseAsync(caseId)).ConfigureAwait(false).GetAwaiter().GetResult(); + + public async Task GetCaseAsync(string caseId, CancellationToken ct = default) + { + ValidateCaseId(caseId); + + await CreateAuthorizedRequestAsync(SupportApiUrls.Case(caseId), Method.Get, null, null, CacheTokenData.TokenDataType.Normal, null, ct); + return await ExecuteRequestAsync(RateLimitType.Support_GetCase, ct); + } + + #region ListContacts + + public List ListContacts(string caseId, ParameterListContacts parameterListContacts = null) => + Task.Run(() => ListContactsAsync(caseId, parameterListContacts)).ConfigureAwait(false).GetAwaiter().GetResult(); + + public async Task> ListContactsAsync(string caseId, ParameterListContacts parameterListContacts = null, CancellationToken ct = default) + { + parameterListContacts ??= new ParameterListContacts(); + ValidateListContacts(caseId, parameterListContacts); + + List list = new List(); + + var response = await ListContactsByNextTokenAsync(caseId, parameterListContacts, ct); + if (response?.Contacts != null) + list.AddRange(response.Contacts); + + // Surface the token on the parameter object so callers can continue manually + // via ListContactsByNextToken, even when MaxNumberOfPages stops the loop below. + parameterListContacts.NextToken = response?.NextToken; + + var totalPages = 1; + while (!string.IsNullOrEmpty(parameterListContacts.NextToken) && + (!parameterListContacts.MaxNumberOfPages.HasValue || totalPages < parameterListContacts.MaxNumberOfPages.Value)) + { + var listContactsNextPage = await ListContactsByNextTokenAsync(caseId, parameterListContacts, ct); + if (listContactsNextPage?.Contacts != null) + list.AddRange(listContactsNextPage.Contacts); + parameterListContacts.NextToken = listContactsNextPage?.NextToken; + totalPages++; + } + + return list; + } + + public ListContactsResult ListContactsByNextToken(string caseId, ParameterListContacts parameterListContacts) => + Task.Run(() => ListContactsByNextTokenAsync(caseId, parameterListContacts)).ConfigureAwait(false).GetAwaiter().GetResult(); + + public async Task ListContactsByNextTokenAsync(string caseId, ParameterListContacts parameterListContacts, CancellationToken ct = default) + { + ValidateListContacts(caseId, parameterListContacts); + + var parameter = parameterListContacts.getParameters(); + await CreateAuthorizedRequestAsync(SupportApiUrls.Contacts(caseId), Method.Get, parameter, null, CacheTokenData.TokenDataType.Normal, null, ct); + return await ExecuteRequestAsync(RateLimitType.Support_ListContacts, ct); + } + + #endregion + + internal static void ValidateListCases(ParameterListCases parameterListCases) + { + if (parameterListCases == null) + throw new InvalidDataException("parameterListCases is required"); + + ValidateMaxResults(parameterListCases.MaxResults); + + var subjectKeywords = parameterListCases.CaseFilters?.SubjectKeywords; + if (subjectKeywords != null && (subjectKeywords.Length < 1 || subjectKeywords.Length > 200)) + throw new InvalidDataException("CaseFilters.SubjectKeywords must be between 1 and 200 characters"); + } + + internal static void ValidateListContacts(string caseId, ParameterListContacts parameterListContacts) + { + ValidateCaseId(caseId); + + if (parameterListContacts == null) + throw new InvalidDataException("parameterListContacts is required"); + + ValidateMaxResults(parameterListContacts.MaxResults); + } + + private static void ValidateCaseId(string caseId) + { + if (string.IsNullOrWhiteSpace(caseId)) + throw new InvalidDataException("caseId is required"); + } + + private static void ValidateMaxResults(int? maxResults) + { + if (maxResults.HasValue && (maxResults.Value < 1 || maxResults.Value > 50)) + throw new InvalidDataException("MaxResults must be between 1 and 50"); + } + } +} diff --git a/Source/FikaAmazonAPI/Utils/RateLimitType.cs b/Source/FikaAmazonAPI/Utils/RateLimitType.cs index f56c81d1..ef437ad8 100644 --- a/Source/FikaAmazonAPI/Utils/RateLimitType.cs +++ b/Source/FikaAmazonAPI/Utils/RateLimitType.cs @@ -306,5 +306,9 @@ public enum RateLimitType AplusContent_PostContentDocumentApprovalSubmission, AplusContent_PostContentDocumentSuspendSubmission, + Support_ListCases, + Support_GetCase, + Support_ListContacts, + } } diff --git a/Source/FikaAmazonAPI/Utils/RateLimitsDefinitions.cs b/Source/FikaAmazonAPI/Utils/RateLimitsDefinitions.cs index 38cc8364..732fbf7f 100644 --- a/Source/FikaAmazonAPI/Utils/RateLimitsDefinitions.cs +++ b/Source/FikaAmazonAPI/Utils/RateLimitsDefinitions.cs @@ -316,6 +316,12 @@ internal static Dictionary RateLimitsTime() { RateLimitType.AplusContent_SearchContentPublishRecords, new RateLimits(10.0M, 10) }, { RateLimitType.AplusContent_PostContentDocumentApprovalSubmission, new RateLimits(10.0M, 10) }, { RateLimitType.AplusContent_PostContentDocumentSuspendSubmission, new RateLimits(10.0M, 10) }, + + // Amazon has not published usage plans for the Support API. These are conservative + // defaults; the limiter adopts the x-amzn-RateLimit-Limit header once a response arrives. + { RateLimitType.Support_ListCases, new RateLimits(1.0M, 1) }, + { RateLimitType.Support_GetCase, new RateLimits(1.0M, 1) }, + { RateLimitType.Support_ListContacts, new RateLimits(1.0M, 1) }, }; } diff --git a/Source/Tests/SupportTests.cs b/Source/Tests/SupportTests.cs new file mode 100644 index 00000000..e6066383 --- /dev/null +++ b/Source/Tests/SupportTests.cs @@ -0,0 +1,151 @@ +using FikaAmazonAPI.AmazonSpApiSDK.Models.Support; +using FikaAmazonAPI.Parameter.Support; +using FikaAmazonAPI.Services; +using FikaAmazonAPI.Utils; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Tests +{ + [TestFixture] + public class SupportTests + { + // Response bodies taken from the static sandbox examples in Amazon's support_2025-02-01.json model. + private const string GetCaseResponse = @"{""caseId"": ""1234567890"", ""status"": ""RESOLVED"", ""subject"": ""test subject"", ""primaryEmail"": ""test_seller@domain.com"", ""ccEmails"": [""test_seller1@domain.com"", ""test_seller2@domain.com""], ""createdDate"": ""2024-01-12T10:00:00.000Z"", ""lastUpdatedDate"": ""2024-01-12T10:00:00.000Z"", ""resolvedDate"": ""2024-01-12T10:00:00.000Z"", ""appointments"": [{""appointmentId"": ""TestAppointmentId"", ""answeringParty"": ""RECEPTIONIST"", ""phoneNumber"": {""countryCode"": ""US"", ""number"": ""1234567890"", ""extension"": ""1""}, ""callbackTiming"": {""earliestCallbackTime"": ""2024-01-12T10:00:00.000Z"", ""latestCallbackTime"": ""2024-01-12T11:00:00.000Z""}, ""status"": ""SCHEDULED""}]}"; + + private const string ListContactsResponse = @"{""nextToken"": ""SampleToken"", ""contacts"": [{""contactId"": ""TestContactId"", ""channel"": ""EMAIL"", ""emailContent"": {""sender"": {""displayName"": ""Test Selling Partner Name"", ""role"": ""SELLING_PARTNER""}, ""message"": ""sample email message"", ""attachments"": [{""name"": ""testAttachment.txt"", ""downloadUrl"": ""https://filelocation/filename""}]}, ""createdDate"": ""2024-01-12T11:00:00.000Z""}]}"; + + [Test] + public void Case_DeserialisesSandboxGetCaseResponse() + { + var supportCase = JsonConvert.DeserializeObject(GetCaseResponse)!; + + Assert.That(supportCase.CaseId, Is.EqualTo("1234567890")); + Assert.That(supportCase.Status, Is.EqualTo(Case.StatusEnum.RESOLVED)); + Assert.That(supportCase.CcEmails, Is.EqualTo(new[] { "test_seller1@domain.com", "test_seller2@domain.com" })); + Assert.That(supportCase.CreatedDate, Is.EqualTo(new DateTime(2024, 1, 12, 10, 0, 0, DateTimeKind.Utc))); + + var appointment = supportCase.Appointments.Single(); + Assert.That(appointment.Status, Is.EqualTo(Appointment.StatusEnum.SCHEDULED)); + Assert.That(appointment.AnsweringParty, Is.EqualTo(Appointment.AnsweringPartyEnum.RECEPTIONIST)); + Assert.That(appointment.PhoneNumber.Extension, Is.EqualTo("1")); + Assert.That(appointment.CallbackTiming.LatestCallbackTime, Is.EqualTo(new DateTime(2024, 1, 12, 11, 0, 0, DateTimeKind.Utc))); + } + + [Test] + public void ListContactsResult_DeserialisesSandboxEmailContact() + { + var result = JsonConvert.DeserializeObject(ListContactsResponse)!; + + Assert.That(result.NextToken, Is.EqualTo("SampleToken")); + var contact = result.Contacts.Single(); + Assert.That(contact.Channel, Is.EqualTo(Contact.ChannelEnum.EMAIL)); + Assert.That(contact.EmailContent.Sender.Role, Is.EqualTo(Participant.RoleEnum.SELLINGPARTNER)); + Assert.That(contact.EmailContent.Attachments.Single().DownloadUrl, Is.EqualTo("https://filelocation/filename")); + Assert.That(contact.ChatContent, Is.Null); + } + + [Test] + public void ListContactsResult_DeserialisesChatEvents() + { + const string json = @"{""contacts"": [{""contactId"": ""C1"", ""channel"": ""CHAT"", ""createdDate"": ""2024-01-12T11:00:00Z"", ""chatContent"": {""transcript"": ""hello"", ""events"": [{""timestamp"": ""2024-01-12T11:00:00Z"", ""type"": ""PARTICIPANT_JOINED"", ""participant"": {""displayName"": ""Amazon"", ""role"": ""AMAZON""}}, {""timestamp"": ""2024-01-12T11:01:00Z"", ""type"": ""MESSAGE"", ""message"": ""hello""}]}}]}"; + + var contact = JsonConvert.DeserializeObject(json)!.Contacts.Single(); + + Assert.That(contact.Channel, Is.EqualTo(Contact.ChannelEnum.CHAT)); + Assert.That(contact.ChatContent.Events.Select(e => e.Type), + Is.EqualTo(new[] { ChatEvent.TypeEnum.PARTICIPANTJOINED, ChatEvent.TypeEnum.MESSAGE })); + Assert.That(contact.ChatContent.Events[0].Participant.Role, Is.EqualTo(Participant.RoleEnum.AMAZON)); + } + + [Test] + public void ParameterListCases_SerialisesToAmazonRequestBody() + { + var parameter = new ParameterListCases + { + CaseFilters = new CaseFilters( + caseStatuses: new List { CaseFilters.CaseStatusesEnum.PENDINGMERCHANTACTION }, + createdDate: new DateFilter(after: new DateTime(2026, 9, 1, 0, 0, 0, DateTimeKind.Utc)), + subjectKeywords: "refund"), + SortOrder = ListCasesRequest.SortOrderEnum.ASC, + MaxResults = 25, + MaxNumberOfPages = 2 + }; + + var body = JObject.Parse(JsonConvert.SerializeObject(parameter.ToRequest())); + + Assert.That(body["sortOrder"]!.Value(), Is.EqualTo("ASC")); + Assert.That(body["maxResults"]!.Value(), Is.EqualTo(25)); + Assert.That(body["caseFilters"]!["caseStatuses"]![0]!.Value(), Is.EqualTo("PENDING_MERCHANT_ACTION")); + Assert.That(body["caseFilters"]!["subjectKeywords"]!.Value(), Is.EqualTo("refund")); + Assert.That(body["caseFilters"]!["createdDate"]!["after"], Is.Not.Null); + // Unset values are omitted, and paging controls never reach Amazon. + Assert.That(body.ContainsKey("nextToken"), Is.False); + Assert.That(body["caseFilters"]!["createdDate"]!.Value()!.ContainsKey("before"), Is.False); + Assert.That(body.ContainsKey("maxNumberOfPages"), Is.False); + } + + [Test] + public void ParameterListContacts_BuildsQueryParameters() + { + var parameter = new ParameterListContacts + { + MaxResults = 50, + NextToken = "abc", + SortOrder = SupportSortOrder.ASC, + MaxNumberOfPages = 1 + }; + + var query = parameter.getParameters(); + + Assert.That(query, Is.EquivalentTo(new[] + { + new KeyValuePair("maxResults", "50"), + new KeyValuePair("nextToken", "abc"), + new KeyValuePair("sortOrder", "ASC"), + })); + } + + [Test] + [TestCase(0)] + [TestCase(51)] + public void ValidateListCases_RejectsMaxResultsOutOfRange(int maxResults) + { + Assert.Throws(() => + SupportService.ValidateListCases(new ParameterListCases { MaxResults = maxResults })); + } + + [Test] + public void ValidateListCases_RejectsSubjectKeywordsOver200Characters() + { + var parameter = new ParameterListCases { CaseFilters = new CaseFilters(subjectKeywords: new string('a', 201)) }; + + Assert.Throws(() => SupportService.ValidateListCases(parameter)); + } + + [Test] + public void ValidateListCases_AcceptsEmptyParameter() + { + Assert.DoesNotThrow(() => SupportService.ValidateListCases(new ParameterListCases())); + } + + [Test] + [TestCase(null)] + [TestCase("")] + [TestCase(" ")] + public void ValidateListContacts_RequiresCaseId(string? caseId) + { + Assert.Throws(() => + SupportService.ValidateListContacts(caseId!, new ParameterListContacts())); + } + + [Test] + public void RateLimitsDefinitions_RegistersEverySupportOperation() + { + var definitions = RateLimitsDefinitions.RateLimitsTime(); + + foreach (var type in new[] { RateLimitType.Support_ListCases, RateLimitType.Support_GetCase, RateLimitType.Support_ListContacts }) + Assert.That(definitions.ContainsKey(type), Is.True, type.ToString()); + } + } +}