UNPKG

@twofistedjustice/square-pie

Version:

an easy to use class based chainable interface for the Square API.

558 lines (531 loc) 18.7 kB
const { nanoid } = require("nanoid"); const { define, shazam_max_length, shazam_is_time_RFC3339, } = require("./utilities"); const { uid_length } = require("../pie_defaults"); const order_fulfillment_state = require("./enum/order_fulfillment_enum"); const man = "sets up details on how to fulfill the order. \n" + "This class has two specialized make-methods in addition to the normal one.." + "make_shipment() lets you add shipping details.\n" + "make_pickup() lets you add pickup details.\n" + "They are both one and done type methods. You don't need to add their output to anything. It is automatic.\n" + "https://developer.squareup.com/reference/square/objects/OrderFulfillment"; /** * {@link https://developer.squareup.com/reference/square/objects/OrderFulfillment | **-------> Link To Square Docs <-------**} * @class Order_Fulfillment * @classdesc * * Sets up details on how to fulfill the order.<br><br> * This class has two specialized make-methods in addition to the normal one:<br> * 1- make_shipment() lets you add shipping details.<br> * 2- make_pickup() lets you add pickup details.<br><br> * They are both one and done type methods. You don't need to add their output to anything. It is automatic. * */ class Order_Fulfillment { _display_name = "Order_Fulfillment"; _last_verified_square_api_version = "2021-07-21"; _help = this.display_name + ": " + man; constructor() { this._fardel = { uid: "uid_order_fulfillment#" + nanoid(uid_length), state: undefined, type: undefined, pickup_details: undefined, shipment_details: undefined, }; this.configuration = { maximums: { uid: 60, cancel_reason: 100, failure_reason: 100, note: 500, carrier: 50, shipping_type: 50, curbside_details: 250, customer_id: 191, display_name: 255, email_address: 255, tracking_number: 100, tracking_url: 2000, phone_number: 17, }, }; } // GETTERS get display_name() { return this._display_name; } get square_version() { return `The last verified compatible Square API version is ${this._last_verified_square_api_version}`; } get help() { return this._help; } get uid() { return this._fardel.uid; } get state() { return this._fardel.state; } get type() { return this._fardel.type; } get fardel() { return this._fardel; } get pickup_details() { return this._fardel.pickup_details; } get shipment_details() { return this._fardel.shipment_details; } get limits() { return this.configuration.maximums; } // SETTERS set uid(uid) { this._fardel.uid = uid; } set state(str) { this._fardel.state = str; } set type(str) { this._fardel.type = str; } set pickup_details(obj) { // do not call a setter from another setter - bad things happen this._fardel.shipment_details = undefined; this._fardel.pickup_details = obj; } set shipment_details(obj) { // do not call a setter from another setter - bad things happen this._fardel.pickup_details = undefined; this._fardel.shipment_details = obj; } // PRIVATE METHODS /** * {@link https://developer.squareup.com/reference/square/enums/OrderFulfillmentState | Link To Square Docs}<br> * * #enum_state * Enumerated methods set specific values from a limited set of allowable values defined by Square. * For each value, a sub-method will exist that is the lowercase version of that value. There may also * exist abbreviated aliases. * * Enumerated methods are usually called by other functions and set the value on the object on which * the calling function operates. * @typedef {function} Order_Fulfillment.enum_state * @private * @abstract * @memberOf Order_Fulfillment * @property proposed() sets value to "PROPOSED" * @property reserved() sets value to "RESERVED" * @property prepared() sets value to "PREPARED" * @property completed() sets value to "COMPLETED" * @property canceled() sets value to "CANCELED" * @property failed() sets value to "FAILED" * @example * If you were allowed to choose from the set ["GOOD", "BAD", "UGLY"] in order to set the * value of `clint` on the object 'western' * * vyMar.make_western().clint.().good() => const spaghetti = {western : {clint: "GOOD"}} * */ #enum_state(self, calling_this) { return order_fulfillment_state.state(self, calling_this); } /** * time_date * @ignore * @typedef {function} Order_Fulfillment.time_date * @private * @abstract * @memberOf Order_Fulfillment * @param {fulfillment_object} fulfillment * @param {string} key - the name of the property you want to create * @param {string} time - RFC3339 compliant date-time * @throws Throws an error if time is not RFC3339 compliant * @return Creates a key:value pair on the object passed in * */ #time_date(fulfillment, key, time) { if (shazam_is_time_RFC3339(time, this.display_name, "#time_date")) { !Object.prototype.hasOwnProperty.call(fulfillment, key) ? define(fulfillment, key, time) : (fulfillment[key] = time); } } /** * note * @ignore * @typedef {function} Order_Fulfillment.note * @private * @abstract * @memberOf Order_Fulfillment * @param {fulfillment_object} fulfillment * @param {string} key - the name of the property you want to create * @param {string} note - a string you want to persist * @throws Throws an error if note exceeds character limit (varies according to usage) * @return Creates a key:value pair on the object passed in * */ #note(fulfillment, key, note) { let limit = this.configuration.maximums[key]; if (shazam_max_length(note, limit, this.display_name, "#note")) { !Object.prototype.hasOwnProperty.call(fulfillment, key) ? define(fulfillment, key, note) : (fulfillment[key] = note); } } #schedule_type(fulfillment, key, value) { !Object.prototype.hasOwnProperty.call(fulfillment, key) ? define(fulfillment, key, value) : (fulfillment[key] = value); } /** * {@link https://developer.squareup.com/reference/square/objects/OrderFulfillmentRecipient | Square Docs}<br> * * #recipient() method of Order_Object - method names are exactly the same as the property names listed * in the Square docs. There may be additional methods and/or shortened aliases of other methods. * @typedef {function} Order_Object.recipient * @method * @private * @memberOf Order_Fulfillment * @property {string} customer_id(id) * @property {string} display_name(name) * @property {string} email(email) * @property {string} phone(phone) * @property {object} address(address_object) a fully formed and compliant Square Address Object * */ #recipient(fulfillment) { let display_name = this.display_name; let key = "recipient"; let recipient = { customer_id: undefined, display_name: undefined, email_address: undefined, phone_number: undefined, address: undefined, }; !Object.prototype.hasOwnProperty.call(fulfillment, key) ? define(fulfillment, key, recipient) : (fulfillment[key] = recipient); return { self: this, customer_id: function (id) { if ( shazam_max_length( id, this.self.configuration.customer_id, display_name, key ) ) { fulfillment.recipient.customer_id = id; return this; } }, display_name: function (name) { if ( shazam_max_length( name, this.self.configuration.display_name, display_name, key ) ) { fulfillment.recipient.display_name = name; return this; } }, email: function (email) { if ( shazam_max_length( email, this.self.configuration.email_address, display_name, key ) ) { fulfillment.recipient.email_address = email; return this; } }, phone: function (phone) { if ( shazam_max_length( phone, this.self.configuration.phone_number, display_name, key ) ) { fulfillment.recipient.phone_number = phone; return this; } }, address: function (address_object) { fulfillment.recipient.address = address_object; return this; }, }; } // MAKE METHODS /** * {@link https://developer.squareup.com/reference/square/objects/OrderFulfillmentPickupDetails | Link To Square Docs}<br> * * make_pickup() method of Order_Fulfillment - Makes and sets a compliant pickup object. * * Method names are exactly the same as the property names listed * in the Square docs. There may be additional methods and/or shortened aliases of other methods. * * @typedef {function} Order_Fulfillment.make_pickup * @method * @public * @memberOf Order_Fulfillment * @property state() - {Enumerated} - Calls {@link Order_Fulfillment.enum_state|#enum_state().} * @property {string} cancel_reason(str) - sets `cancel_reason` to the value you pass and `state` to "CANCELED" and . * @property cancel - alias of cancel_reason * @property {string} auto_complete_duration(time) RFC3339 time string * @property {string} expires_at(time) RFC3339 time string * @property {string} pickup_at(time) RFC3339 time string * @property {string} pickup_window_duration(time) use one of the Pie duration utilities to easily construct a compliant duration string. * @property {string} prep_time_duration(time) use one of the Pie duration utilities to easily construct a compliant duration string. * @property {string} note(str) * @property asap() - sets `schedule_type` to "ASAP" * @property scheduled() - sets `schedule_type` to "SCHEDULED" * @property {string} recipient() - calls {@link Order_Fulfillment.recipient|#recipient()} * @property {string} curbside_details(str) - sets `curbside_details` to the value you pass and `is_curbside_pickup` to true. * @property {string} buyer_arrived_at(time) RFC3339 time string * @example * You must use parentheses with every call to make and with every sub-method. If you have to make a lot * of calls from different lines, it will reduce your tying and improve readability to set make() to a * variable. * * let make = myVar.make(); * make.gizmo() * make.gremlin() * //is the same as * myVar.make().gizmo().gremlin() * */ make_pickup() { this.type = "PICKUP"; this.pickup_details = {}; let fulfillment = this._fardel.pickup_details; return { self: this, state: function () { return this.self.#enum_state(this.self, this); }, cancel_reason: function (str) { let key = "cancel_reason"; this.self.#enum_state(this.self, this).canceled(); this.self.#note(fulfillment, key, str); return this; }, cancel: function (str) { return this.cancel_reason(str); }, // You can use one of the duration utilities to make a compliant string auto_complete_duration: function (time) { let key = "auto_complete_duration"; fulfillment[key] = time; return this; }, expires_at: function (time) { let key = "expires_at"; this.self.#time_date(fulfillment, key, time); return this; }, pickup_at: function (time) { let key = "pickup_at"; this.self.#time_date(fulfillment, key, time); return this; }, pickup_window_duration: function (time) { let key = "pickup_window_duration"; this.self.#time_date(fulfillment, key, time); return this; }, prep_time_duration: function (time) { let key = "prep_time_duration"; this.self.#time_date(fulfillment, key, time); return this; }, note: function (str) { let key = "note"; this.self.#note(fulfillment, key, str); return this; }, asap: function () { let value = "ASAP"; this.self.#schedule_type(fulfillment, "schedule_type", value); return this; }, scheduled: function () { let value = "SCHEDULED"; this.self.#schedule_type(fulfillment, "schedule_type", value); return this; }, recipient: function () { return this.self.#recipient(fulfillment); }, curbside_details: function (str) { let key = "curbside_details"; this.self.#note(fulfillment, key, str); this.self._fardel.pickup_details.is_curbside_pickup = true; return this; }, buyer_arrived_at: function (time) { let key = "buyer_arrived_at"; this.self.#time_date(fulfillment, key, time); return this; }, }; } /** * {@link https://developer.squareup.com/reference/square/objects/OrderFulfillmentShipmentDetails | Link To Square Docs}<br> * * make_shipment() method of Order_Fulfillment - Makes and sets a compliant shipment object. * * Method names are exactly the same as the property names listed * in the Square docs. There may be additional methods and/or shortened aliases of other methods. * @typedef {function} Order_Fulfillment.make_shipment * @method * @public * @memberOf Order_Fulfillment * @property state() - {Enumerated} - Calls {@link Order_Fulfillment.enum_state|#enum_state().} * @property expected_shipped_at(time) {time} - RFC3339 time string * @property cancel_reason(str) {string} - sets `cancel_reason` to the value you pass and `state` to "CANCELED" and . * @property cancel() - alias of cancel_reason * @property failure_reason(str) {string} - sets failure_reason to value passed and state to "FAILED" * @property tracking_number(str) {string} * @property shipping_note(str) {string} * @property note(str) {string} * @property tracking_url(str) {string} * @property shipping_type(str) {string} * @property carrier(str) {string} * @property recipient() - calls {@link Order_Fulfillment.recipient|#recipient()} * @example * You must use parentheses with every call to make and with every sub-method. If you have to make a lot * of calls from different lines, it will reduce your tying and improve readability to set make() to a * variable. * * let make = myVar.make(); * make.gizmo() * make.gremlin() * //is the same as * myVar.make().gizmo().gremlin() * */ make_shipment() { this.type = "SHIPMENT"; this.shipment_details = {}; let fulfillment = this._fardel.shipment_details; return { self: this, state: function () { return this.self.#enum_state(this.self, this); }, expected_shipped_at: function (time) { let key = "expected_shipped_at"; this.self.#time_date(fulfillment, key, time); return this; }, cancel_reason: function (str) { let key = "cancel_reason"; this.self.#enum_state(this.self, this).canceled(); this.self.#note(fulfillment, key, str); return this; }, cancel: function (str) { return this.cancel_reason(str); }, failure_reason: function (str) { let key = "failure_reason"; this.self.#enum_state(this.self, this).failed(); this.self.#note(fulfillment, key, str); return this; }, tracking_number: function (str) { let key = "tracking_number"; this.self.#note(fulfillment, key, str); return this; }, shipping_note: function (str) { let key = "shipping_note"; this.self.#note(fulfillment, key, str); return this; }, note: function (str) { return this.shipping_note(str); }, tracking_url: function (str) { let key = "tracking_url"; this.self.#note(fulfillment, key, str); return this; }, shipping_type: function (str) { let key = "shipping_type"; this.self.#note(fulfillment, key, str); return this; }, carrier: function (str) { let key = "carrier"; this.self.#note(fulfillment, key, str); return this; }, recipient: function () { return this.self.#recipient(fulfillment); }, }; } /** * make() method of Order_Fulfillment - Do not use this unless you have pre-built pickup or * shipment objects. Rather use make_pickup() or make_shipment(). * * Method names are exactly the same as the property names listed * in the Square docs. There may be additional methods and/or shortened aliases of other methods. * @typedef {function} Order_Fulfillment.make * @method * @public * @memberOf Order_Fulfillment * @property uid(uid) {string} - automatically set. Use this only to replace the generated uid. * @property state(str) {string} * @property type(str) {string} * @property pickup_details(obj) {object} a fully formed compliant pickup object. Use only if you already have a compliant object. Otherwise, use make_pickup(). * @property shipment_details(obj) {object} a fully formed compliant shipment object. Use only if you already have a compliant object. Otherwise, use make_shipment(). * @example * You must use parentheses with every call to make and with every sub-method. If you have to make a lot * of calls from different lines, it will reduce your tying and improve readability to set make() to a * variable. * * let make = myVar.make(); * make.gizmo() * make.gremlin() * //is the same as * myVar.make().gizmo().gremlin() * */ make() { return { self: this, uid: function (uid) { this.self.uid = uid; return this; }, state: function () { return this.self.#enum_state(this.self, this); }, type: function (str) { this.self.type = str; return this; }, pickup_details: function (obj) { this.self.pickup_details = obj; return this; }, shipment_details: function (obj) { this.self.shipment_details = obj; return this; }, }; } } module.exports = Order_Fulfillment;