From d42f93e79509c0360d34b1e93ec792c5fa484f0d Mon Sep 17 00:00:00 2001 From: Rahul Mody Date: Tue, 3 May 2022 18:05:32 -0400 Subject: [PATCH 1/4] 1.21.0 - api completeness changes --- package-lock.json | 4 +- package.json | 2 +- src/ApiClient.js | 2 +- src/model/CreateOrderRequest.js | 27 ++++++++++ src/model/Inventory.js | 74 ++++++++++++++++++++++++++ src/model/Order.js | 59 +++++++++++++++++++++ src/model/OrderInventory.js | 83 ++++++++++++++++++++++++++++++ src/model/OrderInventoryProject.js | 40 ++++++++++++++ src/model/Project.js | 19 +++++-- test/integration/orders.test.js | 18 +++++++ test/integration/projects.test.js | 8 +++ 11 files changed, 329 insertions(+), 7 deletions(-) create mode 100644 src/model/Inventory.js create mode 100644 src/model/OrderInventory.js create mode 100644 src/model/OrderInventoryProject.js diff --git a/package-lock.json b/package-lock.json index 636e885..3c124c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@patch-technology/patch", - "version": "1.20.0", + "version": "1.21.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@patch-technology/patch", - "version": "1.20.0", + "version": "1.21.0", "license": "MIT", "dependencies": { "query-string": "^7.0.1", diff --git a/package.json b/package.json index 30f3b4b..0432280 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@patch-technology/patch", - "version": "1.20.0", + "version": "1.21.0", "description": "Node.js wrapper for the Patch API", "license": "MIT", "repository": { diff --git a/src/ApiClient.js b/src/ApiClient.js index ec9759f..e1fae62 100644 --- a/src/ApiClient.js +++ b/src/ApiClient.js @@ -16,7 +16,7 @@ class ApiClient { }; this.defaultHeaders = { - 'User-Agent': 'patch-node/1.20.0' + 'User-Agent': 'patch-node/1.21.0' }; /** diff --git a/src/model/CreateOrderRequest.js b/src/model/CreateOrderRequest.js index 4f57f80..e8d02fc 100644 --- a/src/model/CreateOrderRequest.js +++ b/src/model/CreateOrderRequest.js @@ -50,6 +50,25 @@ class CreateOrderRequest { 'Number' ); } + + if (data.hasOwnProperty('total_price')) { + obj['total_price'] = ApiClient.convertToType( + data['total_price'], + 'Number' + ); + } + + if (data.hasOwnProperty('currency')) { + obj['currency'] = ApiClient.convertToType(data['currency'], 'String'); + } + + if (data.hasOwnProperty('amount')) { + obj['amount'] = ApiClient.convertToType(data['amount'], 'Number'); + } + + if (data.hasOwnProperty('unit')) { + obj['unit'] = ApiClient.convertToType(data['unit'], 'String'); + } } return obj; } @@ -67,4 +86,12 @@ CreateOrderRequest.prototype['state'] = undefined; CreateOrderRequest.prototype['vintage_year'] = undefined; +CreateOrderRequest.prototype['total_price'] = undefined; + +CreateOrderRequest.prototype['currency'] = undefined; + +CreateOrderRequest.prototype['amount'] = undefined; + +CreateOrderRequest.prototype['unit'] = undefined; + export default CreateOrderRequest; diff --git a/src/model/Inventory.js b/src/model/Inventory.js new file mode 100644 index 0000000..4164710 --- /dev/null +++ b/src/model/Inventory.js @@ -0,0 +1,74 @@ +/** + * Patch API V1 + * The core API used to integrate with Patch's service + * + * Contact: engineering@usepatch.com + */ + +import ApiClient from '../ApiClient'; + +class Inventory { + constructor(vintageYear, amountAvailable, price, currency, unit) { + Inventory.initialize( + this, + vintageYear, + amountAvailable, + price, + currency, + unit + ); + } + + static initialize(obj, vintageYear, amountAvailable, price, currency, unit) { + obj['vintage_year'] = vintageYear; + obj['amount_available'] = amountAvailable; + obj['price'] = price; + obj['currency'] = currency; + obj['unit'] = unit; + } + + static constructFromObject(data, obj) { + if (data) { + obj = obj || new Inventory(); + + if (data.hasOwnProperty('vintage_year')) { + obj['vintage_year'] = ApiClient.convertToType( + data['vintage_year'], + 'Number' + ); + } + + if (data.hasOwnProperty('amount_available')) { + obj['amount_available'] = ApiClient.convertToType( + data['amount_available'], + 'Number' + ); + } + + if (data.hasOwnProperty('price')) { + obj['price'] = ApiClient.convertToType(data['price'], 'Number'); + } + + if (data.hasOwnProperty('currency')) { + obj['currency'] = ApiClient.convertToType(data['currency'], 'String'); + } + + if (data.hasOwnProperty('unit')) { + obj['unit'] = ApiClient.convertToType(data['unit'], 'String'); + } + } + return obj; + } +} + +Inventory.prototype['vintage_year'] = undefined; + +Inventory.prototype['amount_available'] = undefined; + +Inventory.prototype['price'] = undefined; + +Inventory.prototype['currency'] = undefined; + +Inventory.prototype['unit'] = undefined; + +export default Inventory; diff --git a/src/model/Order.js b/src/model/Order.js index 7f78965..cd9a2fe 100644 --- a/src/model/Order.js +++ b/src/model/Order.js @@ -7,6 +7,7 @@ import ApiClient from '../ApiClient'; import Allocation from './Allocation'; +import OrderInventory from './OrderInventory'; class Order { constructor( @@ -14,6 +15,11 @@ class Order { massG, production, state, + amount, + unit, + price, + patchFee, + currency, allocationState, priceCentsUsd, patchFeeCentsUsd, @@ -25,6 +31,11 @@ class Order { massG, production, state, + amount, + unit, + price, + patchFee, + currency, allocationState, priceCentsUsd, patchFeeCentsUsd, @@ -38,6 +49,11 @@ class Order { massG, production, state, + amount, + unit, + price, + patchFee, + currency, allocationState, priceCentsUsd, patchFeeCentsUsd, @@ -47,6 +63,11 @@ class Order { obj['mass_g'] = massG; obj['production'] = production; obj['state'] = state; + obj['amount'] = amount; + obj['unit'] = unit; + obj['price'] = price; + obj['patch_fee'] = patchFee; + obj['currency'] = currency; obj['allocation_state'] = allocationState; obj['price_cents_usd'] = priceCentsUsd; obj['patch_fee_cents_usd'] = patchFeeCentsUsd; @@ -80,6 +101,26 @@ class Order { obj['state'] = ApiClient.convertToType(data['state'], 'String'); } + if (data.hasOwnProperty('amount')) { + obj['amount'] = ApiClient.convertToType(data['amount'], 'Number'); + } + + if (data.hasOwnProperty('unit')) { + obj['unit'] = ApiClient.convertToType(data['unit'], 'String'); + } + + if (data.hasOwnProperty('price')) { + obj['price'] = ApiClient.convertToType(data['price'], 'Number'); + } + + if (data.hasOwnProperty('patch_fee')) { + obj['patch_fee'] = ApiClient.convertToType(data['patch_fee'], 'Number'); + } + + if (data.hasOwnProperty('currency')) { + obj['currency'] = ApiClient.convertToType(data['currency'], 'String'); + } + if (data.hasOwnProperty('allocation_state')) { obj['allocation_state'] = ApiClient.convertToType( data['allocation_state'], @@ -117,6 +158,12 @@ class Order { if (data.hasOwnProperty('metadata')) { obj['metadata'] = ApiClient.convertToType(data['metadata'], Object); } + + if (data.hasOwnProperty('inventory')) { + obj['inventory'] = ApiClient.convertToType(data['inventory'], [ + OrderInventory + ]); + } } return obj; } @@ -132,6 +179,16 @@ Order.prototype['production'] = undefined; Order.prototype['state'] = undefined; +Order.prototype['amount'] = undefined; + +Order.prototype['unit'] = undefined; + +Order.prototype['price'] = undefined; + +Order.prototype['patch_fee'] = undefined; + +Order.prototype['currency'] = undefined; + Order.prototype['allocation_state'] = undefined; Order.prototype['price_cents_usd'] = undefined; @@ -144,4 +201,6 @@ Order.prototype['registry_url'] = undefined; Order.prototype['metadata'] = undefined; +Order.prototype['inventory'] = undefined; + export default Order; diff --git a/src/model/OrderInventory.js b/src/model/OrderInventory.js new file mode 100644 index 0000000..665ba24 --- /dev/null +++ b/src/model/OrderInventory.js @@ -0,0 +1,83 @@ +/** + * Patch API V1 + * The core API used to integrate with Patch's service + * + * Contact: engineering@usepatch.com + */ + +import ApiClient from '../ApiClient'; +import OrderInventoryProject from './OrderInventoryProject'; + +class OrderInventory { + constructor(project, vintageYear, amount, unit, price, currency) { + OrderInventory.initialize( + this, + project, + vintageYear, + amount, + unit, + price, + currency + ); + } + + static initialize(obj, project, vintageYear, amount, unit, price, currency) { + obj['project'] = project; + obj['vintage_year'] = vintageYear; + obj['amount'] = amount; + obj['unit'] = unit; + obj['price'] = price; + obj['currency'] = currency; + } + + static constructFromObject(data, obj) { + if (data) { + obj = obj || new OrderInventory(); + + if (data.hasOwnProperty('project')) { + obj['project'] = ApiClient.convertToType( + data['project'], + OrderInventoryProject + ); + } + + if (data.hasOwnProperty('vintage_year')) { + obj['vintage_year'] = ApiClient.convertToType( + data['vintage_year'], + 'Number' + ); + } + + if (data.hasOwnProperty('amount')) { + obj['amount'] = ApiClient.convertToType(data['amount'], 'Number'); + } + + if (data.hasOwnProperty('unit')) { + obj['unit'] = ApiClient.convertToType(data['unit'], 'String'); + } + + if (data.hasOwnProperty('price')) { + obj['price'] = ApiClient.convertToType(data['price'], 'Number'); + } + + if (data.hasOwnProperty('currency')) { + obj['currency'] = ApiClient.convertToType(data['currency'], 'String'); + } + } + return obj; + } +} + +OrderInventory.prototype['project'] = undefined; + +OrderInventory.prototype['vintage_year'] = undefined; + +OrderInventory.prototype['amount'] = undefined; + +OrderInventory.prototype['unit'] = undefined; + +OrderInventory.prototype['price'] = undefined; + +OrderInventory.prototype['currency'] = undefined; + +export default OrderInventory; diff --git a/src/model/OrderInventoryProject.js b/src/model/OrderInventoryProject.js new file mode 100644 index 0000000..60701d7 --- /dev/null +++ b/src/model/OrderInventoryProject.js @@ -0,0 +1,40 @@ +/** + * Patch API V1 + * The core API used to integrate with Patch's service + * + * Contact: engineering@usepatch.com + */ + +import ApiClient from '../ApiClient'; + +class OrderInventoryProject { + constructor(id, name) { + OrderInventoryProject.initialize(this, id, name); + } + + static initialize(obj, id, name) { + obj['id'] = id; + obj['name'] = name; + } + + static constructFromObject(data, obj) { + if (data) { + obj = obj || new OrderInventoryProject(); + + if (data.hasOwnProperty('id')) { + obj['id'] = ApiClient.convertToType(data['id'], 'String'); + } + + if (data.hasOwnProperty('name')) { + obj['name'] = ApiClient.convertToType(data['name'], 'String'); + } + } + return obj; + } +} + +OrderInventoryProject.prototype['id'] = undefined; + +OrderInventoryProject.prototype['name'] = undefined; + +export default OrderInventoryProject; diff --git a/src/model/Project.js b/src/model/Project.js index 5e3c2e4..f8bc371 100644 --- a/src/model/Project.js +++ b/src/model/Project.js @@ -7,6 +7,7 @@ import ApiClient from '../ApiClient'; import Highlight from './Highlight'; +import Inventory from './Inventory'; import Photo from './Photo'; import Sdg from './Sdg'; import Standard from './Standard'; @@ -23,7 +24,8 @@ class Project { averagePricePerTonneCentsUsd, remainingMassG, technologyType, - highlights + highlights, + inventory ) { Project.initialize( this, @@ -36,7 +38,8 @@ class Project { averagePricePerTonneCentsUsd, remainingMassG, technologyType, - highlights + highlights, + inventory ); } @@ -51,7 +54,8 @@ class Project { averagePricePerTonneCentsUsd, remainingMassG, technologyType, - highlights + highlights, + inventory ) { obj['id'] = id; obj['production'] = production; @@ -63,6 +67,7 @@ class Project { obj['remaining_mass_g'] = remainingMassG; obj['technology_type'] = technologyType; obj['highlights'] = highlights; + obj['inventory'] = inventory; } static constructFromObject(data, obj) { @@ -164,6 +169,12 @@ class Project { Highlight ]); } + + if (data.hasOwnProperty('inventory')) { + obj['inventory'] = ApiClient.convertToType(data['inventory'], [ + Inventory + ]); + } } return obj; } @@ -209,4 +220,6 @@ Project.prototype['technology_type'] = undefined; Project.prototype['highlights'] = undefined; +Project.prototype['inventory'] = undefined; + export default Project; diff --git a/test/integration/orders.test.js b/test/integration/orders.test.js index 481211a..b12a915 100644 --- a/test/integration/orders.test.js +++ b/test/integration/orders.test.js @@ -92,4 +92,22 @@ describe('Orders Integration', function () { expect(createOrderResponse.success).to.equal(true); }); + + it('supports create orders with a amount and unit', async function () { + const createOrderResponse = await patch.orders.createOrder({ + amount: 100, + unit: 'g' + }); + + expect(createOrderResponse.success).to.equal(true); + }); + + it('supports create orders with a total price and currency', async function () { + const createOrderResponse = await patch.orders.createOrder({ + total_price: 100, + currency: 'EUR' + }); + + expect(createOrderResponse.success).to.equal(true); + }); }); diff --git a/test/integration/projects.test.js b/test/integration/projects.test.js index 1a0122b..4f308d1 100644 --- a/test/integration/projects.test.js +++ b/test/integration/projects.test.js @@ -29,6 +29,14 @@ describe('Project Integration', function () { const parent_technology_type = technology_type.parent_technology_type; expect(parent_technology_type.slug).to.be.a('string'); expect(parent_technology_type.name).to.be.a('string'); + + const inventory = projectResponse.data.inventory; + expect(inventory).to.be.a('array'); + expect(inventory[0].vintage_year).to.be.a('number'); + expect(inventory[0].amount_available).to.be.a('number'); + expect(inventory[0].price).to.be.a('number'); + expect(inventory[0].currency).to.be.a('string'); + expect(inventory[0].unit).to.be.a('string'); }); it('supports fetching all projects from the United States', async function () { From 7ed17ab06aa6c3eec4976ba3f3f8f3c4de3217dd Mon Sep 17 00:00:00 2001 From: Rahul Mody Date: Tue, 3 May 2022 18:14:20 -0400 Subject: [PATCH 2/4] Additional order tests --- test/integration/orders.test.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/integration/orders.test.js b/test/integration/orders.test.js index b12a915..f814581 100644 --- a/test/integration/orders.test.js +++ b/test/integration/orders.test.js @@ -93,13 +93,16 @@ describe('Orders Integration', function () { expect(createOrderResponse.success).to.equal(true); }); - it('supports create orders with a amount and unit', async function () { + it('supports create orders with an amount and unit', async function () { const createOrderResponse = await patch.orders.createOrder({ amount: 100, unit: 'g' }); expect(createOrderResponse.success).to.equal(true); + expect(createOrderResponse.data.amount).to.equal(100); + expect(createOrderResponse.data.unit).to.equal('g'); + expect(createOrderResponse.data.inventory[0].unit).to.equal('g'); }); it('supports create orders with a total price and currency', async function () { @@ -109,5 +112,9 @@ describe('Orders Integration', function () { }); expect(createOrderResponse.success).to.equal(true); + expect( + createOrderResponse.data.price + createOrderResponse.data.patch_fee + ).to.be.within(99, 101); + expect(createOrderResponse.data.currency).to.equal('EUR'); }); }); From c1db1b30beafcce0f28826a2f565cc1bfbd83980 Mon Sep 17 00:00:00 2001 From: Rahul Mody Date: Tue, 3 May 2022 19:00:38 -0400 Subject: [PATCH 3/4] changelog --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 116cc6a..08a22ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.21.0] - 2022-05-03 + +### Added + +- Adds optional `total_price` and `currency` field to `order` creation +- Adds optional `amount` and `unit` field to `order` creation +- Adds inventory to `project` responses +- Adds inventory to `order` responses + +### Changed + +- Deprecates `mass_g` and `total_price_cents_usd` fields for create `order` requests +- Deprecates `average_price_per_tonne_cents_usd` and `remaining_mass_g` from `project` responses +- Deprecates `price_cents_usd`, `patch_fee_cents_usd`, and `mass_g` from `order` responses + ## [1.20.0] - 2022-04-18 ### Added From c6191ebd1d52e4b2050584b92f0d815b2d41f87c Mon Sep 17 00:00:00 2001 From: Rahul Mody Date: Wed, 4 May 2022 16:11:21 -0400 Subject: [PATCH 4/4] update readme --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b978767..eff0bf2 100644 --- a/README.md +++ b/README.md @@ -65,15 +65,17 @@ fulfill the order for you. ```javascript // Create an order - you can create an order -// providing either mass_g or total_price_cents_usd, but not both +// providing either amount (and unit) or total_price (and currency), but not both -// Create order with mass -const mass = 1000000; // Pass in the mass in grams (i.e. 1 metric tonne) -patch.orders.createOrder({ mass_g: mass }); +// Create order with amount +const amount = 1_000_000; // Pass in the amount in unit specified +const unit = 'g'; +patch.orders.createOrder({ amount: amount, unit: unit }); -// Create an order with a maximum total price -const totalPriceCentsUSD = 500; // Pass in the total price in cents (i.e. 5 dollars) -patch.orders.createOrder({ total_price_cents_usd: totalPriceCentsUSD }); +// Create an order with total price +const totalPrice = 500; // Pass in the total price in smallest currency unit (ie cents for USD). +const currency = 'USD'; +patch.orders.createOrder({ total_price: totalPrice, currency: currency }); // Retrieve an order orderId = 'ord_test_1234'; // Pass in the order's id