diff --git a/ShopifySharp.Tests/Checkout_Tests.cs b/ShopifySharp.Tests/Checkout_Tests.cs index 0546503f..eeb38d6f 100644 --- a/ShopifySharp.Tests/Checkout_Tests.cs +++ b/ShopifySharp.Tests/Checkout_Tests.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; +using System.Threading.Tasks; using Xunit; namespace ShopifySharp.Tests @@ -17,16 +13,27 @@ public Checkout_Tests() Service.SetExecutionPolicy(new SmartRetryExecutionPolicy()); } + [Fact] + public async Task Lists_Checkouts() + { + var list = await Service.ListAsync(); + + Assert.NotNull(list); + Assert.NotNull(list.Items); + } + + [Fact] + public async Task Counts_Checkouts() + { + var count = await Service.CountAsync(); + + Assert.True(count >= 0); + } + [Fact(Skip = "You can't use the Checkout API to create a new checkout user experience for an individual store.")] public async Task Creates_Checkouts() { - var checkout = await Service.CreateAsync(new Checkout - { - Email = "joshua@nozzlegear.com" - }); - - Assert.NotNull(checkout); - Assert.Equal("joshua@nozzlegear.com", checkout.Email); + } [Fact(Skip = "You can't use the Checkout API to create a new checkout user experience for an individual store.")] diff --git a/ShopifySharp/Entities/Checkout.cs b/ShopifySharp/Entities/Checkout.cs index 66e886d1..ceb42eb0 100644 --- a/ShopifySharp/Entities/Checkout.cs +++ b/ShopifySharp/Entities/Checkout.cs @@ -1,9 +1,6 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace ShopifySharp { @@ -13,244 +10,215 @@ namespace ShopifySharp public class Checkout : ShopifyObject { /// - /// Unique identifier for a particular order. - /// - [JsonProperty("token")] - public string Token { get; set; } - - /// - /// Unique identifier for a particular cart that is attached to a particular order. - /// - [JsonProperty("cart_token")] - public string CartToken { get; set; } - - /// - /// The customer's email address. + /// The full recovery URL to be sent to a customer to recover their abandoned checkout. /// - [JsonProperty("email")] - public string Email { get; set; } - + [JsonProperty("abandoned_checkout_url")] + public string AbandonedCheckoutUrl { get; set; } + /// - /// The payment gateway used. + /// The mailing address associated with the payment method. /// - [JsonProperty("gateway")] - public string Gateway { get; set; } - + [JsonProperty("billing_address")] + public Address BillingAddress { get; set; } + /// /// Indicates whether or not the person who placed the order would like to receive email /// updates from the shop. This is set when checking the "I want to receive occasional /// emails about new products, promotions and other news" checkbox during checkout. - /// Valid values are "true" and "false." /// [JsonProperty("buyer_accepts_marketing")] public bool? BuyerAcceptsMarketing { get; set; } - + + /// + /// Unique identifier for a particular cart that is attached to a particular order. + /// + [JsonProperty("cart_token")] + public string CartToken { get; set; } + + /// + /// The date and time when the abandoned cart was completed. The API returns this value in ISO 8601 format. + /// + [JsonProperty("closed_at", DefaultValueHandling = DefaultValueHandling.Ignore)] + public DateTimeOffset? ClosedAt { get; set; } + + /// + /// The date and time when the abandoned cart was last modified. The API returns this value in ISO 8601 format. + /// + [JsonProperty("completed_at", DefaultValueHandling = DefaultValueHandling.Ignore)] + public DateTimeOffset? CompletedAt { get; set; } + /// /// The date and time when the abandoned cart was created. The API returns this value in ISO 8601 format. /// [JsonProperty("created_at", DefaultValueHandling = DefaultValueHandling.Ignore)] public DateTimeOffset? CreatedAt { get; set; } - + /// - /// The date and time when the abandoned cart was last modified. The API returns this value in ISO 8601 format. + /// The three letter code (ISO 4217) for the currency used for the payment. /// - [JsonProperty("updated_at", DefaultValueHandling = DefaultValueHandling.Ignore)] - public DateTimeOffset? UpdatedAt { get; set; } - + [JsonProperty("currency")] + public string Currency { get; set; } + + /// + /// Information about the customer. + /// + [JsonProperty("customer")] + public Customer Customer { get; set; } + + /// + /// The two or three-letter language code, optionally followed by a region modifier. Example values: en, en-CA. + /// + [JsonProperty("customer_locale")] + public string CustomerLocale { get; set; } + + /// + /// The ID of the Shopify POS device that created the checkout. + /// + [JsonProperty("device_id")] + public long? DeviceId { get; set; } + + /// + /// Applicable discount codes that can be applied to the order. If no codes exist the value will default to blank. + /// + [JsonProperty("discount_codes")] + public IEnumerable DiscountCodes { get; set; } + + /// + /// The customer's email address. + /// + [JsonProperty("email")] + public string Email { get; set; } + + /// + /// The payment gateway used. + /// + [JsonProperty("gateway")] + public string Gateway { get; set; } + /// /// The URL for the page where the buyer landed when entering the shop. /// [JsonProperty("landing_site")] public string LandingSite { get; set; } - + + /// + /// A list of line item objects, each one containing information about an item in the order. + /// + [JsonProperty("line_items")] + public IEnumerable LineItems { get; set; } + + /// + /// The ID of the physical location where the checkout was processed. + /// + [JsonProperty("location_id")] + public long? LocationId { get; set; } + /// /// The text of an optional note that a shop owner can attach to the order. /// [JsonProperty("note")] public string Note { get; set; } - + /// - /// Extra information that is added to the order. + /// The customer's phone number for receiving SMS notifications. /// - [JsonProperty("note_attributes")] - public IEnumerable NoteAttributes { get; set; } - + [JsonProperty("phone")] + public string Phone { get; set; } + + /// + /// The three-letter code (ISO 4217 format) of the currency that the customer used at checkout. + /// + [JsonProperty("presentment_currency")] + public string PresentmentCurrency { get; set; } + /// /// The website that the customer clicked on to come to the shop. /// [JsonProperty("referring_site")] public string ReferringSite { get; set; } - + + /// + /// The mailing address to where the order will be shipped. This address is optional and will not be available on orders that do not require one. + /// + [JsonProperty("shipping_address")] + public Address ShippingAddress { get; set; } + /// - /// An array of shipping_line objects, each of which details the shipping methods used. Each shipping_line has the following properties: - /// code: A reference to the shipping method. - /// price: The price of this shipping method. - /// source: - /// title: + /// An array of shipping line objects, each of which details the shipping methods used. /// [JsonProperty("shipping_lines")] public IEnumerable ShippingLines { get; set; } - + + /// + /// Where the checkout originated. Known values are: "web", "pos", "iphone", and "android" + /// + [JsonProperty("source_name")] + public string SourceName { get; set; } + /// /// Price of the order before shipping and taxes /// [JsonProperty("subtotal_price")] public decimal? SubtotalPrice { get; set; } - + /// + /// An array of tax line objects, each of which details the taxes applicable to the order. + /// + [JsonProperty("tax_lines")] + public IEnumerable TaxLines { get; set; } + + /// + /// Whether taxes are included in the price. /// [JsonProperty("taxes_included")] public bool? TaxesIncluded { get; set; } - + + /// + /// Unique identifier for a particular order. + /// + [JsonProperty("token")] + public string Token { get; set; } + /// /// The total amount of the discounts to be applied to the price of the order. /// [JsonProperty("total_discounts")] public decimal? TotalDiscounts { get; set; } - + /// /// The sum of all the prices of all the items in the order. /// [JsonProperty("total_line_items_price")] public decimal? TotalLineItemsPrice { get; set; } - + /// /// The sum of all the prices of all the items in the order, taxes and discounts included. /// [JsonProperty("total_price")] public decimal? TotalPrice { get; set; } - + /// /// The sum of all the taxes applied to the line items in the order. /// [JsonProperty("total_tax")] public decimal? TotalTax { get; set; } - + /// /// The sum of all the weights of the line items in the order, in grams. /// [JsonProperty("total_weight")] public decimal? TotalWeight { get; set; } - - /// - /// The three letter code (ISO 4217) for the currency used for the payment. - /// - [JsonProperty("currency")] - public string Currency { get; set; } - + /// /// The date and time when the abandoned cart was last modified. The API returns this value in ISO 8601 format. /// - [JsonProperty("completed_at", DefaultValueHandling = DefaultValueHandling.Ignore)] - public DateTimeOffset? CompletedAt { get; set; } - - /// - /// The date and time when the abandoned cart was completed. The API returns this value in ISO 8601 format. - /// - [JsonProperty("closed_at", DefaultValueHandling = DefaultValueHandling.Ignore)] - public DateTimeOffset? ClosedAt { get; set; } - - /// - /// - [JsonProperty("source_identifier")] - public string SourceIdentifier { get; set; } - - /// - /// - [JsonProperty("source_url")] - public string SourceUrl { get; set; } - - /// - /// A list of line item objects, each one containing information about an item in the order. Each line_item object has the following properties: - /// fulfillment_service: Service provider who is doing the fulfillment. - /// fulfillment_status: How far along an order is in terms line items fulfilled.Valid values are: fulfilled, null or partial. - /// grams: The weight of the item in grams. - /// price: The price of the item. - /// product_id: The unique numeric identifier for the product in the fulfillment. - /// quantity: The number of products that were purchased. - /// requires_shipping: States whether or not the fulfillment requires shipping. Values are: true or false. - /// sku: A unique identifier of the item in the fulfillment. - /// title: The title of the product. - /// variant_id: The id of the product variant. - /// variant_title: The title of the product variant. - /// vendor: The name of the supplier of the item. - /// name: The name of the product variant. - /// - [JsonProperty("line_items")] - public IEnumerable LineItems { get; set; } - - /// - /// - [JsonProperty("name")] - public string Name { get; set; } - - /// - /// - [JsonProperty("source")] - public string Source { get; set; } - - /// - /// Applicable discount codes that can be applied to the order. If no codes exist the value will default to blank. - /// A Discount code will include the following fields: •amount: The amount of the discount. - /// code: The discount code. - /// type: The type of discount.Can be one of: "percentage", "shipping", "fixed_amount" (default). - /// - [JsonProperty("discount_codes")] - public IEnumerable DiscountCodes { get; set; } - - /// - /// The full recovery URL to be sent to a customer to recover their abandoned checkout. - /// - [JsonProperty("abandoned_checkout_url")] - public string AbandonedCheckoutUrl { get; set; } - - /// - /// An array of tax_line objects, each of which details the taxes applicable to the order. Each tax_line has the following properties: - /// price: The amount of tax to be charged. - /// rate: The rate of tax to be applied. - /// title: The name of the tax. - /// - [JsonProperty("tax_lines")] - public IEnumerable TaxLines { get; set; } - - /// - /// Where the checkout originated. Possible values are: "web", "pos", "iphone", and "android" - /// - [JsonProperty("source_name")] - public string SourceName { get; set; } - - /// - /// The mailing address associated with the payment method. It has the following properties: - /// address1: The street address of the billing address. - /// address2: An optional additional field for the street address of the billing address. - /// city: The city of the billing address. - /// company: The company of the person associated with the billing address. - /// country: The name of the country of the billing address. - /// country_code: The two-letter code (ISO 3166-1 alpha-2 two-letter country code) for the country of the billing address. - /// first_name: The first name of the person associated with the payment method. - /// last_name: The last name of the person associated with the payment method. - /// latitude: The latitude of the billing address. - /// longitude: The longitude of the billing address. - /// name: The full name of the person associated with the payment method. - /// phone: The phone number at the billing address. - /// province: The name of the state or province of the billing address. - /// province_code: The two-letter abbreviation of the state or province of the billing address. - /// zip:The zip or postal code of the billing address. - /// - [JsonProperty("billing_address")] - public Address BillingAddress { get; set; } - - /// - /// The mailing address to where the order will be shipped. This address is optional and will not be available on orders that do not require one. - /// - [JsonProperty("shipping_address")] - public Address ShippingAddress { get; set; } - + [JsonProperty("updated_at", DefaultValueHandling = DefaultValueHandling.Ignore)] + public DateTimeOffset? UpdatedAt { get; set; } + /// - /// A object containing information about the customer. + /// The ID of the user who created the checkout. /// - [JsonProperty("customer")] - public Customer Customer { get; set; } - + [JsonProperty("user_id")] + public long? UserId { get; set; } } } diff --git a/ShopifySharp/Filters/CheckoutCountFilter.cs b/ShopifySharp/Filters/CheckoutCountFilter.cs new file mode 100644 index 00000000..14366f1b --- /dev/null +++ b/ShopifySharp/Filters/CheckoutCountFilter.cs @@ -0,0 +1,44 @@ +using System; +using Newtonsoft.Json; + +namespace ShopifySharp.Filters +{ + public class CheckoutCountFilter : Parameterizable + { + /// + /// Restrict results to after the specified ID. + /// + [JsonProperty("since_id")] + public long? SinceId { get; set; } + + /// + /// Restrict results to those created at or after date. + /// + [JsonProperty("created_at_min")] + public DateTimeOffset? CreatedAtMin { get; set; } + + /// + /// Restrict results to those created at or after date. + /// + [JsonProperty("created_at_max")] + public DateTimeOffset? CreatedAtMax { get; set; } + + /// + /// Restrict results to those created at or before date. + /// + [JsonProperty("updated_at_min")] + public DateTimeOffset? UpdatedAtMin { get; set; } + + /// + /// Restrict results to those last updated at or before date. + /// + [JsonProperty("updated_at_max")] + public DateTimeOffset? UpdatedAtMax { get; set; } + + /// + /// Restrict results to those with the given status. Known values: "open", "closed". Default: "open". + /// + [JsonProperty("status")] + public string Status { get; set; } + } +} \ No newline at end of file diff --git a/ShopifySharp/Filters/CheckoutListFilter.cs b/ShopifySharp/Filters/CheckoutListFilter.cs new file mode 100644 index 00000000..dbe382b6 --- /dev/null +++ b/ShopifySharp/Filters/CheckoutListFilter.cs @@ -0,0 +1,44 @@ +using System; +using Newtonsoft.Json; + +namespace ShopifySharp.Filters +{ + public class CheckoutListFilter : ListFilter + { + /// + /// Restrict results to after the specified ID. + /// + [JsonProperty("since_id")] + public long? SinceId { get; set; } + + /// + /// Restrict results to those created at or after date. + /// + [JsonProperty("created_at_min")] + public DateTimeOffset? CreatedAtMin { get; set; } + + /// + /// Restrict results to those created at or after date. + /// + [JsonProperty("created_at_max")] + public DateTimeOffset? CreatedAtMax { get; set; } + + /// + /// Restrict results to those created at or before date. + /// + [JsonProperty("updated_at_min")] + public DateTimeOffset? UpdatedAtMin { get; set; } + + /// + /// Restrict results to those last updated at or before date. + /// + [JsonProperty("updated_at_max")] + public DateTimeOffset? UpdatedAtMax { get; set; } + + /// + /// Restrict results to those with the given status. Known values: "open", "closed". Default: "open". + /// + [JsonProperty("status")] + public string Status { get; set; } + } +} \ No newline at end of file diff --git a/ShopifySharp/Services/Checkout/CheckoutService.cs b/ShopifySharp/Services/Checkout/CheckoutService.cs index 50ce5ff8..47a357ac 100644 --- a/ShopifySharp/Services/Checkout/CheckoutService.cs +++ b/ShopifySharp/Services/Checkout/CheckoutService.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using ShopifySharp.Infrastructure; using System; +using ShopifySharp.Filters; +using ShopifySharp.Lists; namespace ShopifySharp { @@ -15,6 +17,34 @@ public class CheckoutService : ShopifyService /// An API access token for the shop. public CheckoutService(string myShopifyUrl, string shopAccessToken) : base(myShopifyUrl, shopAccessToken) { } + /// + /// Gets a count of all of the shop's orders. + /// + /// Options for filtering the count. + /// The count of all orders for the shop. + public virtual async Task CountAsync(CheckoutCountFilter filter = null) + { + return await ExecuteGetAsync("checkouts/count.json", "count", filter); + } + + /// + /// Gets a list of up to 250 of the shop's abandoned checkouts. + /// + /// Options for filtering the result. + public virtual async Task> ListAsync(ListFilter filter) + { + return await ExecuteGetListAsync("checkouts.json", "checkouts", filter); + } + + /// + /// Gets a list of up to 250 of the shop's abandoned checkouts. + /// + /// Options for filtering the result. + public virtual async Task> ListAsync(CheckoutListFilter filter = null) + { + return await ListAsync(filter?.AsListFilter()); + } + /// /// Creates a new Checkout. ///