From 7d697a16fa706f16fe70b83f9d47f8c9783b5849 Mon Sep 17 00:00:00 2001 From: Simon Dingley <1590398+ProNotion@users.noreply.github.com> Date: Wed, 21 Oct 2026 06:46:01 +0100 Subject: [PATCH] feat(support): Add Selling Partner API for Support v2025-02-01 Implements the three Support API operations via a new SupportService, exposed as AmazonConnection.Support: - ListCases (POST /support/2025-02-01/cases): auto-pages on nextToken, honours MaxNumberOfPages and surfaces NextToken on the parameter, with ListCasesByNextToken for manual paging. - GetCase (GET /cases/{caseId}). - ListContacts (GET /cases/{caseId}/contacts): same paging pattern, with ListContactsByNextToken. Models under AmazonSpApiSDK/Models/Support are generated from Amazon's support_2025-02-01.json in the existing swagger-codegen style. Fields the model marks x-amzn-api-internal (ListCasesRequest.marketplaceId/sortField, Case.lastOutboundDate) are omitted, as they are not in the public reference. Parameterless JSON constructors are public to satisfy ExecuteRequestAsync. Amazon has not published usage plans for this API, so the rate limits are conservative defaults (1 req/s, burst 1); the limiter adopts the x-amzn-RateLimit-Limit header from the first response. Also adds SupportSample.cs and a README section. Tests: added SupportTests (13 cases) covering deserialisation of Amazon's sandbox responses, request body and query serialisation, validation and rate-limit registration. Full suite passes (17/17). Breaking: no --- README.md | 19 + .../FikaAmazonAPI.SampleCode/SupportSample.cs | 80 ++++ Source/FikaAmazonAPI/AmazonConnection.cs | 3 + .../Models/Support/Appointment.cs | 265 ++++++++++++++ .../Models/Support/Attachment.cs | 154 ++++++++ .../Models/Support/CallbackTiming.cs | 162 +++++++++ .../AmazonSpApiSDK/Models/Support/Case.cs | 343 ++++++++++++++++++ .../Models/Support/CaseFilters.cs | 271 ++++++++++++++ .../Models/Support/ChatContent.cs | 162 +++++++++ .../Models/Support/ChatEvent.cs | 247 +++++++++++++ .../AmazonSpApiSDK/Models/Support/Contact.cs | 254 +++++++++++++ .../Models/Support/DateFilter.cs | 141 +++++++ .../Models/Support/EmailContent.cs | 179 +++++++++ .../AmazonSpApiSDK/Models/Support/Error.cs | 179 +++++++++ .../Models/Support/ErrorList.cs | 137 +++++++ .../Models/Support/ListCasesRequest.cs | 207 +++++++++++ .../Models/Support/ListCasesResult.cs | 154 ++++++++ .../Models/Support/ListContactsResult.cs | 154 ++++++++ .../Models/Support/Participant.cs | 172 +++++++++ .../Models/Support/PhoneContent.cs | 124 +++++++ .../Models/Support/PhoneNumber.cs | 179 +++++++++ .../Parameter/Support/ParameterListCases.cs | 41 +++ .../Support/ParameterListContacts.cs | 29 ++ .../Parameter/Support/SupportSortOrder.cs | 15 + Source/FikaAmazonAPI/Services/ApiUrls.cs | 9 + .../FikaAmazonAPI/Services/SupportService.cs | 166 +++++++++ Source/FikaAmazonAPI/Utils/RateLimitType.cs | 4 + .../Utils/RateLimitsDefinitions.cs | 6 + Source/Tests/SupportTests.cs | 151 ++++++++ 29 files changed, 4007 insertions(+) create mode 100644 Source/FikaAmazonAPI.SampleCode/SupportSample.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Appointment.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Attachment.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CallbackTiming.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Case.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/CaseFilters.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatContent.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ChatEvent.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Contact.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/DateFilter.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/EmailContent.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Error.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ErrorList.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesRequest.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListCasesResult.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/ListContactsResult.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/Participant.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneContent.cs create mode 100644 Source/FikaAmazonAPI/AmazonSpApiSDK/Models/Support/PhoneNumber.cs create mode 100644 Source/FikaAmazonAPI/Parameter/Support/ParameterListCases.cs create mode 100644 Source/FikaAmazonAPI/Parameter/Support/ParameterListContacts.cs create mode 100644 Source/FikaAmazonAPI/Parameter/Support/SupportSortOrder.cs create mode 100644 Source/FikaAmazonAPI/Services/SupportService.cs create mode 100644 Source/Tests/SupportTests.cs 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()); + } + } +}