From ed5ec0893218fade5e397c565db061c7cfd5f447 Mon Sep 17 00:00:00 2001 From: jdalrymple Date: Mon, 11 Jun 2018 11:50:20 -0400 Subject: [PATCH] Locations, InventoryLevels, InventoryItems and Fulfillment Support (#25) * Adding fulfillment support * Removing options references * Adding casting * Revert "Adding casting" This reverts commit d04956c46d26109f0a65fd79eaa2ae4f11f26fb8. * Found serious errors in my previous PR * add product variants service and export * Adding proper variant support * Fixing update * Adding inventory levels * Adding locations * - Updating list options for inventory levels - Fixing exports - Updating descriptions for inventory levels * - Updating location api description - Adding inventory items service - Adding proper inventory levels list options * Remove empty price rules options * Clean up product options * Fixing few bugs with inventory items * Exporting the object property correctly * Fixing root property for inventory levels * Making mandatory arguments live outside of the options param * Fixing fulfillments * Removed wrong filter options on product variant's count function --- models/index.ts | 3 ++ models/inventory_item.ts | 23 ++++++++++++ models/inventory_level.ts | 18 ++++++++++ models/location.ts | 69 ++++++++++++++++++++++++++++++++++++ options/base.ts | 4 ++- options/fulfillments.ts | 18 ---------- options/index.ts | 4 +-- options/inventory_items.ts | 8 +++++ options/inventory_levels.ts | 13 +++++++ options/price_rules.ts | 3 -- options/products.ts | 21 ++--------- services/fulfillments.ts | 35 +++++++++--------- services/index.ts | 3 ++ services/inventory_items.ts | 40 +++++++++++++++++++++ services/inventory_levels.ts | 69 ++++++++++++++++++++++++++++++++++++ services/locations.ts | 45 +++++++++++++++++++++++ services/orders.ts | 2 +- services/price_rules.ts | 2 +- services/product_variants.ts | 5 ++- services/products.ts | 2 +- services/redirects.ts | 4 +-- services/webhooks.ts | 4 +-- 22 files changed, 325 insertions(+), 70 deletions(-) create mode 100644 models/inventory_item.ts create mode 100644 models/inventory_level.ts create mode 100644 models/location.ts delete mode 100644 options/fulfillments.ts create mode 100644 options/inventory_items.ts create mode 100644 options/inventory_levels.ts delete mode 100644 options/price_rules.ts create mode 100644 services/inventory_items.ts create mode 100644 services/inventory_levels.ts create mode 100644 services/locations.ts diff --git a/models/index.ts b/models/index.ts index 53b2a54..0f43b32 100644 --- a/models/index.ts +++ b/models/index.ts @@ -11,8 +11,11 @@ export * from "./discount"; export * from "./discount_code"; export * from "./fulfillment"; export * from "./gift_card"; +export * from "./inventory_item"; +export * from "./inventory_level"; export * from "./line_item"; export * from "./line_item_property"; +export * from "./location"; export * from "./order"; export * from "./payment_details"; export * from "./price_rule"; diff --git a/models/inventory_item.ts b/models/inventory_item.ts new file mode 100644 index 0000000..5b9ddb2 --- /dev/null +++ b/models/inventory_item.ts @@ -0,0 +1,23 @@ +import { ShopifyObject } from "./base"; + +export interface InventoryItem extends ShopifyObject { + /* + * The date and time (ISO 8601 format) when the inventory item was created. + */ + created_at?: string; + + /* + * The unique SKU (stock keeping unit) of the inventory item. + */ + sku?: string; + + /* + * Whether the inventory item is tracked. If true, then inventory quantity changes are tracked by Shopify + */ + tracked?: boolean; + + /* + * The date and time (ISO 8601 format) when the inventory item was last modified. + */ + updated_at?: number; +} \ No newline at end of file diff --git a/models/inventory_level.ts b/models/inventory_level.ts new file mode 100644 index 0000000..6894a8c --- /dev/null +++ b/models/inventory_level.ts @@ -0,0 +1,18 @@ +import { ShopifyObject } from "./base"; + +export interface InventoryLevel extends ShopifyObject { + /* + * The unique identifier of the inventory item that the inventory level belongs to + */ + inventory_item_id?: number; + + /* + * The unique identifier of the location that the inventory level belongs to. In order to find the ID of the location, use the Location API. + */ + location_id?: number; + + /* + * The quantity of inventory items available for sale. Returns null if the inventory item is not tracked. + */ + available?: number; +} \ No newline at end of file diff --git a/models/location.ts b/models/location.ts new file mode 100644 index 0000000..4f96000 --- /dev/null +++ b/models/location.ts @@ -0,0 +1,69 @@ +import { ShopifyObject } from './base'; + +export interface Location extends ShopifyObject { + /** + * The first line of the address. + */ + address1?: string; + + /** + * The second line of the address. + */ + address2?: string; + + /** + * The city the location is in. + */ + city?: string; + + /** + * The country the location is in. + */ + country?: string; + + /** + * The two-letter code (ISO 3166-1 alpha-2 format) corresponding to country the location is in. + */ + country_code?: string; + + /** + * The date and time (ISO 8601 format) when the location was created. + */ + created_at?: string; + + /** + * Whether this is a fulfillment service location. If true, then the location is a fulfillment service location. + * If false, then the location was created by the merchant and isn't tied to a fulfillment service. + */ + legacy?: string; + + /** + * The name of the location. + */ + name?: string; + + /** + * The phone number of the location. This value can contain special characters like - and +. + */ + phone?: string; + + /** + * The province the location is in. + */ + province?: string; + + /** + * The two-letter code corresponding to province or state the location is in. + */ + province_code?: string; + + /** + * The date and time (ISO 8601 format) when the location was last updated. + */ + updated_at?: string + + /** + * The zip or postal code. + */ + zip?: string +} \ No newline at end of file diff --git a/options/base.ts b/options/base.ts index 6406718..ef85c99 100644 --- a/options/base.ts +++ b/options/base.ts @@ -41,7 +41,7 @@ export interface ProcessedOptions { processed_at_max?: string; } -export interface ListOptions { +export interface BasicListOptions { /** * The maximum number of objects that should be returned, up to 250. Setting this parameter above 250 will result in an error. */ @@ -51,7 +51,9 @@ export interface ListOptions { * The page number of the result list to retrieve. Use this in tandem with limit to page through the webhooks in a shop. */ page?: number; +} +export interface ListOptions extends BasicListOptions { /** * Restricts results to those created after the given id. */ diff --git a/options/fulfillments.ts b/options/fulfillments.ts deleted file mode 100644 index 1ba8161..0000000 --- a/options/fulfillments.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { FinancialStatus } from "../enums/financial_status"; -import { FulfillmentStatus } from "../enums/fulfillment_status"; -import { DateOptions, FieldOptions, ListOptions, ProcessedOptions } from "./base"; - -export interface FulfillmentCountOptions extends DateOptions { - status?: FulfillmentStatus; - - financial_status?: FinancialStatus; - - fulfillment_status?: FulfillmentStatus; -} - -export interface FulfillmentListOptions extends FieldOptions, DateOptions, ProcessedOptions, ListOptions, FulfillmentCountOptions { - /** - * A comma-separated list of order ids. - */ - ids?: string; -} diff --git a/options/index.ts b/options/index.ts index 3a95e55..94d3075 100644 --- a/options/index.ts +++ b/options/index.ts @@ -1,10 +1,10 @@ export * from "./articles"; export * from "./base"; export * from "./blogs"; -export * from "./fulfillments"; export * from "./gift_cards"; +export * from "./inventory_items"; +export * from "./inventory_levels"; export * from "./orders"; -export * from "./price_rules"; export * from "./product_collection"; export * from "./products"; export * from "./redirects"; diff --git a/options/inventory_items.ts b/options/inventory_items.ts new file mode 100644 index 0000000..2fc7df3 --- /dev/null +++ b/options/inventory_items.ts @@ -0,0 +1,8 @@ +import { BasicListOptions } from "./base"; + +export interface InventoryItemListOptions extends BasicListOptions { + /** + * Show only certain inventory items, specified by a comma-seperated list of IDs.. + */ + ids: string; +} \ No newline at end of file diff --git a/options/inventory_levels.ts b/options/inventory_levels.ts new file mode 100644 index 0000000..d9c9ce3 --- /dev/null +++ b/options/inventory_levels.ts @@ -0,0 +1,13 @@ +import { BasicListOptions } from "./base"; + +export interface InventoryLevelListOptions extends BasicListOptions { + /** + * A comma-separated list of inventory item IDs. + */ + inventory_item_ids?: string; + + /** + * A comma-separated list of location IDs. + */ + location_ids?: string; +} \ No newline at end of file diff --git a/options/price_rules.ts b/options/price_rules.ts deleted file mode 100644 index 0ea924b..0000000 --- a/options/price_rules.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface PriceRuleOptions { - -} \ No newline at end of file diff --git a/options/products.ts b/options/products.ts index 8753c30..8273c02 100644 --- a/options/products.ts +++ b/options/products.ts @@ -1,4 +1,4 @@ -import { FieldOptions, ListOptions, PublishedOptions } from './base'; +import { FieldOptions, ListOptions, PublishedOptions, DateOptions } from './base'; export interface ProductBaseOptions { @@ -18,24 +18,7 @@ export interface ProductBaseOptions { collection_id?: string; } -export interface ProductCountOptions extends ProductBaseOptions { - - /** - * Show products created after date (format: 2014-04-25T16:15:47-04:00) - */ - created_at_min?: string; - - created_at_max?: string; - - /** - * Show products last updated after date (format: 2014-04-25T16:15:47-04:00) - */ - updated_at_min?: string; - - updated_at_max?: string; -} - -export interface ProductListOptions extends ProductCountOptions { +export interface ProductListOptions extends ProductBaseOptions, DateOptions { /** * A comma-separated list of product ids diff --git a/services/fulfillments.ts b/services/fulfillments.ts index ce01e82..a02e0d4 100644 --- a/services/fulfillments.ts +++ b/services/fulfillments.ts @@ -39,52 +39,53 @@ export class Fulfillments extends BaseService { * @param fulfillmentId Id of the fulfillment being retrieved. * @param options Options for filtering the result. */ - public get(orderId: number, id: number, options?: Options.FieldOptions) { - return this.createRequest("GET", this.getPath(orderId, `${id}.json`), "fulfillment", options); + public get(orderId: number, fulfillmentId: number, options?: Options.FieldOptions) { + return this.createRequest("GET", this.getPath(orderId, `${fulfillmentId}.json`), "fulfillment", options); } /** - * Lists up to 250 fulfillments for the given blog. + * Lists up to 250 fulfillments for the given order. * @param orderId Id of the blog that the fulfillments belong to. * @param options Options for filtering the results. */ - public list(orderId: number, options?: Options.FulfillmentListOptions) { + public list(orderId: number, options?: Options.FieldOptions & Options.DateOptions & Options.ListOptions) { return this.createRequest("GET", this.getPath(orderId, ".json"), "fulfillments", options); } /** - * Counts the fulfillments on the given blog. + * Counts the fulfillments on the given order. * @param orderId Id of the blog that the fulfillments belong to. * @param options Options for filtering the results. */ - public count(orderId: number, options?: Options.FulfillmentCountOptions) { + public count(orderId: number, options?: Options.DateOptions) { return this.createRequest("GET", this.getPath(orderId, "count.json"), "count", options); } /** - * Opens a fulfillment with the given id. - * @param id The fulfillment's id. + * Opens a fulfillment with the given fulfillmentId. + * @param orderId Id of the blog that the fulfillments belong to. + * @param fulfillmentId The fulfillment's id. */ - public open(orderId: number, id: number) { - return this.createRequest("POST", this.getPath(orderId, `${id}/open.json`), 'fulfillment'); + public open(orderId: number, fulfillmentId: number) { + return this.createRequest("POST", this.getPath(orderId, `${fulfillmentId}/open.json`), 'fulfillment'); } /** - * Cancels a fulfillment with the given id. - * @param id The fulfillment's id. + * Cancels a fulfillment with the given fulfillmentId. + * @param fulfillmentId The fulfillment's id. * @param options Options for canceling the fulfillment. */ - public cancel(orderId: number, id: number) { - return this.createRequest("POST", this.getPath(orderId, `${id}/cancel.json`), 'fulfillment'); + public cancel(orderId: number, fulfillmentId: number) { + return this.createRequest("POST", this.getPath(orderId, `${fulfillmentId}/cancel.json`), 'fulfillment'); } /** * Complete a fulfillment with the given id. - * @param id The fulfillment's id. + * @param fulfillmentId The fulfillment's id. * @param options Options for canceling the fulfillment. */ - public complete(orderId: number, id: number) { - return this.createRequest("POST", this.getPath(orderId, `${id}/complete.json`), 'fulfillment'); + public complete(orderId: number, fulfillmentId: number) { + return this.createRequest("POST", this.getPath(orderId, `${fulfillmentId}/complete.json`), 'fulfillment'); } } diff --git a/services/index.ts b/services/index.ts index 25106bf..61cd4f6 100644 --- a/services/index.ts +++ b/services/index.ts @@ -6,6 +6,9 @@ export * from "./custom_collections"; export * from "./discounts"; export * from "./fulfillments"; export * from "./gift_cards"; +export * from "./inventory_items"; +export * from "./inventory_levels"; +export * from "./locations"; export * from "./orders"; export * from "./price_rule_discounts"; export * from "./price_rules"; diff --git a/services/inventory_items.ts b/services/inventory_items.ts new file mode 100644 index 0000000..5cf8e4f --- /dev/null +++ b/services/inventory_items.ts @@ -0,0 +1,40 @@ +import * as Options from '../options'; +import { BaseService } from '../infrastructure'; +import { InventoryItem } from '../models'; + +/** + * A service for manipulating Shopify's InventoryItems API. + */ +export class InventoryItems extends BaseService { + constructor(shopDomain: string, accessToken: string) { + super(shopDomain, accessToken, "inventory_items"); + } + + /** + * Gets a inventory item with the given id. + * @param id Id of the inventory item being retrieved. + * @param options Options for filtering the result. + */ + public get(id: number, options?: Options.FieldOptions) { + return this.createRequest("GET", `${id}.json`, "inventory_item", options); + } + + /** + * Gets a list of up to 250 of the shop's inventory items. + * @param options Options for filtering the result. + */ + public list(options: Options.InventoryItemListOptions) { + return this.createRequest("GET", ".json", "inventory_items", options); + } + + /** + * Updates an inventory item with the given id. + * @param id The inventory items's id. + * @param inventoryItem The updated inventory item. + */ + public update(id: number, inventoryItem: InventoryItem) { + return this.createRequest("PUT", `${id}.json`, "inventory_item", { inventory_item: inventoryItem }); + } +} + +export default InventoryItems; \ No newline at end of file diff --git a/services/inventory_levels.ts b/services/inventory_levels.ts new file mode 100644 index 0000000..32af685 --- /dev/null +++ b/services/inventory_levels.ts @@ -0,0 +1,69 @@ +import * as Options from '../options'; +import { BaseService } from '../infrastructure'; +import { InventoryLevel } from '../models'; + +/** + * A service for manipulating Shopify's InventoryLevels API. + */ +export class InventoryLevels extends BaseService { + constructor(shopDomain: string, accessToken: string) { + super(shopDomain, accessToken, "inventory_levels"); + } + + /** + * Gets a list of up to 250 of the shop's inventory levels. + * @param options Options for filtering the result. + */ + public list(options?: Options.InventoryLevelListOptions) { + return this.createRequest("GET", ".json", "inventory_levels", options); + } + + /** + * Adjusts the inventory level of an inventory item at a single location. + * @param options Options for adjusting an inventory level. + */ + public adjust(inventoryItemId: number, locationId: number, availableAdjustment: number) { + return this.createRequest("POST", `adjust.json`, "inventory_level", { + location_id: locationId, + inventory_item_id: inventoryItemId, + available_adjustment: availableAdjustment + }); + } + + /** + * Deletes an inventory level of an inventory item at a location. + * @param inventoryItemId Id of the inventory item. + * @param locationId Id of the location being retrieved. + */ + public delete(inventoryItemId: number, locationId: number) { + return this.createRequest("DELETE", `.json?inventory_item_id=${inventoryItemId}&location_id=${locationId}`, "inventory_level"); + } + + /** + * Connects an inventory item to a location by creating an inventory level at that location. + * @param inventoryItemId Id of the inventory item. + * @param locationId Id of the location being retrieved. + * @param options Options for connecting an inventory level. + */ + public connect(inventoryItemId: number, locationId: number, options?: { relocate_if_necessary?: boolean } ) { + return this.createRequest("POST", `connect.json`, "inventory_level", { + location_id: locationId, + inventory_item_id: inventoryItemId, + ...options + }); + } + + /** + * Sets the inventory level for an inventory item at a location. + * @param inventoryLevel Inventory level being set. + * @param options Options for adjusting an inventory level. + */ + public set(inventoryLevel: InventoryLevel, options?: { disconnect_if_necessary?: boolean } ) { + return this.createRequest("POST", `set.json`, "inventory_level", { + ...inventoryLevel, + ...options + }); + } +} + +export default InventoryLevels; \ No newline at end of file diff --git a/services/locations.ts b/services/locations.ts new file mode 100644 index 0000000..830b509 --- /dev/null +++ b/services/locations.ts @@ -0,0 +1,45 @@ +import * as Options from '../options'; +import { Location } from '../models'; +import { BaseService } from '../infrastructure'; + +/** + * A service for manipulating a shops Locations API. + */ +export class Locations extends BaseService { + constructor(shopDomain: string, accessToken: string) { + super(shopDomain, accessToken, "locations"); + } + + /** + * Gets a location with the given id. + * @param id Id of the location being retrieved. + * @param options Options for filtering the result. + */ + public get(id: number, options?: Options.FieldOptions) { + return this.createRequest("GET", `${id}.json`, "location", options); + } + + /** + * Lists up to 250 locations. + * @param options Options for filtering the results. + */ + public list(options?: Options.FieldOptions) { + return this.createRequest("GET", `.json`, "locations", options); + } + + /** + * Counts the amount of locations. + */ + public count() { + return this.createRequest("GET", `count.json`, "count"); + } + + /** + * Lists all the inventory levels on a location. + */ + public inventoryLevels(locationId: number) { + return this.createRequest("GET", `${locationId}/inventory_levels.json`, "inventory_levels"); + } +} + +export default Locations; diff --git a/services/orders.ts b/services/orders.ts index e636a3f..9606945 100644 --- a/services/orders.ts +++ b/services/orders.ts @@ -89,7 +89,7 @@ export class Orders extends BaseService { * @param options Options for canceling the order. */ public cancel(id: number, options?: Options.OrderCancelOptions) { - return this.createRequest("POST", `${id}/cancel.json`, 'order'); + return this.createRequest("POST", `${id}/cancel.json`, 'order', options); } } diff --git a/services/price_rules.ts b/services/price_rules.ts index 14852a5..16966d7 100644 --- a/services/price_rules.ts +++ b/services/price_rules.ts @@ -15,7 +15,7 @@ export class PriceRules extends BaseService { * Gets a list of up to 250 of the shop's Price Rules. * @param options Options for filtering the results. */ - public list(options?: Options.PriceRuleOptions & Options.ListOptions & Options.FieldOptions) { + public list(options?: Options.ListOptions & Options.FieldOptions) { return this.createRequest("GET", ".json", "price_rules", options); } diff --git a/services/product_variants.ts b/services/product_variants.ts index ca5646b..4c60fd6 100644 --- a/services/product_variants.ts +++ b/services/product_variants.ts @@ -31,10 +31,9 @@ export class ProductVariants extends BaseService { /** * Counts the variants on the given product. * @param productId Id of the product that the variants belong to. - * @param options Options for filtering the results. */ - public count(productId: number, options?: Options.FulfillmentCountOptions) { - return this.createRequest("GET", `products/${productId}/variants/count.json`, "count", options); + public count(productId: number) { + return this.createRequest("GET", `products/${productId}/variants/count.json`, "count"); } /** diff --git a/services/products.ts b/services/products.ts index bfade8f..e615277 100644 --- a/services/products.ts +++ b/services/products.ts @@ -12,7 +12,7 @@ export class Products extends BaseService { * @param options Options for filtering the results. * @see https://help.shopify.com/api/reference/product#count */ - public count(options?: Options.ProductCountOptions & Options.PublishedOptions) { + public count(options?: Options.ProductBaseOptions & Options.DateOptions & Options.PublishedOptions) { return this.createRequest("GET", "count.json", "count", options); } diff --git a/services/redirects.ts b/services/redirects.ts index 5b07ad8..7779f9c 100644 --- a/services/redirects.ts +++ b/services/redirects.ts @@ -38,7 +38,7 @@ export class Redirects extends BaseService { * Creates a new redirect. */ public create(redirect: Redirect) { - return this.createRequest("POST", ".json", "redirect", { redirect: redirect }); + return this.createRequest("POST", ".json", "redirect", { redirect }); } /** @@ -46,7 +46,7 @@ export class Redirects extends BaseService { * @param tag The updated redirect. */ public update(id: number, redirect: Redirect) { - return this.createRequest("PUT", `${id}.json`, "redirect", { redirect: redirect }); + return this.createRequest("PUT", `${id}.json`, "redirect", { redirect }); } /** diff --git a/services/webhooks.ts b/services/webhooks.ts index c0c17e4..5292dd4 100644 --- a/services/webhooks.ts +++ b/services/webhooks.ts @@ -38,7 +38,7 @@ export class Webhooks extends BaseService { * Creates a new webhook. */ public create(webhook: Webhook) { - return this.createRequest("POST", ".json", "webhook", { webhook: webhook }); + return this.createRequest("POST", ".json", "webhook", { webhook }); } /** @@ -46,7 +46,7 @@ export class Webhooks extends BaseService { * @param webhook The updated webhook. */ public update(id: number, webhook: Webhook) { - return this.createRequest("PUT", `${id}.json`, "webhook", { webhook: webhook }); + return this.createRequest("PUT", `${id}.json`, "webhook", { webhook }); } /**