Skip to content

Commit 061e065

Browse files
committed
code documentation
1 parent 64d78a7 commit 061e065

File tree

8 files changed

+68
-92
lines changed

8 files changed

+68
-92
lines changed

services/README.md

-19
This file was deleted.

services/cls_Sample/ICO/Handler.cls

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1+
/// REST services for managing the coffee business
12
Class ICO.Handler Extends %CSP.REST
23
{
3-
4+
/// Honor the CORS header <a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GREST_CORS">as described here</a>
45
Parameter HandleCorsRequest = 1;
5-
6+
/// Default response content type
67
Parameter CONTENTTYPE = "application/json";
7-
8+
/// Number of days since roasting for the coffee to be considered "stale"
89
Parameter MAXAGE = 5;
910

11+
/// Removes bags of coffee from the catalog
12+
/// Input: <ul><li>id: catalog ID in catalog</li><li>quantity: number of bags to remove</li></ul>
13+
/// Output: New product quantity on-hand, or an error
1014
ClassMethod SellProduct(id As %String, quantity As %Numeric) As %Status
1115
{
1216
try {
17+
// does the ID exist?
1318
if (1 '= ##class(ICO.catalog).%ExistsId(id))
1419
{
1520
set err = {}
@@ -18,6 +23,7 @@ ClassMethod SellProduct(id As %String, quantity As %Numeric) As %Status
1823
}
1924
else
2025
{
26+
// do we have enough quantity?
2127
set item = ##class(ICO.catalog).%OpenId(id)
2228
if (quantity > item.quantity)
2329
{
@@ -27,33 +33,43 @@ ClassMethod SellProduct(id As %String, quantity As %Numeric) As %Status
2733
}
2834
else
2935
{
36+
// decrement the database and return the new quantity
3037
set item.quantity = (item.quantity - quantity)
3138
do item.%JSONExportToString(.outstring)
3239
write outstring
3340
set sc = item.%Save()
3441
}
3542
}
3643
} catch (oException) {
44+
// return the error
3745
set expobj = {}
3846
set expobj."exception" = oException.%AsSystemError()
3947
write expobj.%ToJSON()
4048
}
4149
Quit $$$OK
4250
}
4351

52+
/// Gets bagged coffee inventory for sale from the catalog
53+
/// Input: fresh: if <pre>1</pre>, return stale bags (roasted more than <PARAMETER>MAXAGE</PARAMETER> days ago).
54+
/// Output: JSON listing of products
4455
ClassMethod GetProducts(fresh As %Boolean = 1) As %Status
4556
{
4657
try {
58+
// fields to return
4759
set sqlquery = "SELECT catalog_id, product_code, quantity, price, time_roasted, roasting_notes, img FROM ICO.catalog"
60+
// set the WHERE clause based on whether we want fresh or not (the -? will be replaced by MAXAGE)
4861
if fresh = 1 {
4962
set sqlquery = sqlquery_" WHERE time_roasted > DATEADD('day',-?,CURRENT_DATE)"
5063
} else {
5164
set sqlquery = sqlquery_" WHERE time_roasted <= DATEADD('day',-?,CURRENT_DATE)"
5265
}
66+
// if nothing is left, exclude from the response
5367
set sqlquery = sqlquery_" AND quantity > 0"
68+
// run the query
5469
set rs = ##class(%SQL.Statement).%ExecDirect(,sqlquery, ..#MAXAGE)
5570
set itemsarray = []
5671

72+
// iterate over the results and build a dynamic array
5773
while rs.%Next()
5874
{
5975
do itemsarray.%Push(
@@ -68,6 +84,7 @@ ClassMethod GetProducts(fresh As %Boolean = 1) As %Status
6884
}
6985
)
7086
}
87+
// translate the dynamic arry into JSON and return to client
7188
set itemsobj = {}
7289
set itemsobj."rowcount" = rs.%ROWCOUNT
7390
set itemsobj."products" = itemsarray
@@ -80,6 +97,7 @@ ClassMethod GetProducts(fresh As %Boolean = 1) As %Status
8097
Quit $$$OK
8198
}
8299

100+
/// Create JSON from POST content
83101
ClassMethod GetJSONFromRequest(Output obj As %DynamicObject) As %Boolean
84102
{
85103
set ok = 1
@@ -91,15 +109,20 @@ ClassMethod GetJSONFromRequest(Output obj As %DynamicObject) As %Boolean
91109
Quit ok
92110
}
93111

112+
/// Accepts JSON in an HTTP POST and persists it into the bagged coffee catalog
113+
/// Input: None explicit. Will get HTTP POST content when calling <METHOD>GetJSONFromRequest</METHOD>
114+
/// Output: on success, JSON having a key/value of "success": 1, and the object saved, or an error.
94115
ClassMethod CatalogProduct() As %Status
95116
{
117+
// get HTTP POST content
96118
if '..GetJSONFromRequest(.obj) {
97119
set %response.Status = ..#HTTP400BADREQUEST
98120
set error = {"error": "No JSON body in request"}
99121
write error.%ToJSON()
100122
Quit $$$OK
101123
}
102124

125+
/// construct a new ICO.catalog object and populate it from the input
103126
try {
104127
set catobj = ##class(ICO.catalog).%New()
105128
set catobj.productcode = obj."product_code"
@@ -121,9 +144,13 @@ ClassMethod CatalogProduct() As %Status
121144
Quit $$$OK
122145
}
123146

147+
/// Takes raw coffee beans out of inventory so they can be virtually roasted
148+
/// Input: <ul><li>id: vendor id in catalog</li><li>quantity: amount in kilograms</li></ul>
149+
/// Output: on success, JSON of the item and quantity withdrawn, or an error.
124150
ClassMethod GetRawBeans(id As %String, quantity As %Numeric) As %Status
125151
{
126152
try {
153+
// does the vendor ID exist?
127154
if (1 '= ##class(ICO.inventory).%ExistsId(id))
128155
{
129156
set err = {}
@@ -132,6 +159,7 @@ ClassMethod GetRawBeans(id As %String, quantity As %Numeric) As %Status
132159
}
133160
else
134161
{
162+
// do we have enough quantity?
135163
set item = ##class(ICO.inventory).%OpenId(id)
136164
if (quantity > item.quantitykg)
137165
{
@@ -141,6 +169,7 @@ ClassMethod GetRawBeans(id As %String, quantity As %Numeric) As %Status
141169
}
142170
else
143171
{
172+
// decrement the quantity and return the requested inventory
144173
set item.quantitykg = (item.quantitykg - quantity)
145174
set sc = item.%Save()
146175
do item.%JSONExportToString(.outstring)
@@ -155,6 +184,9 @@ ClassMethod GetRawBeans(id As %String, quantity As %Numeric) As %Status
155184
Quit $$$OK
156185
}
157186

187+
/// Return raw coffee bean inventory
188+
/// Input: None
189+
/// Output: on success, JSON listing all products on hand, or an error.
158190
ClassMethod ListRawBeans() As %Status
159191
{
160192
try {

services/cls_Sample/ICO/catalog.cls

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
///
1+
/// Database representation of bagged and roasted coffee
22
Class ICO.catalog Extends (%Persistent, %JSON.Adaptor) [ ClassType = persistent, DdlAllowed, Final, Owner = {_SYSTEM}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = catalog ]
33
{
4-
4+
/// Unique ID
55
Property catalogid As %Library.BigInt(%JSONFIELDNAME = "catalog_id", MINVAL = 1) [ Identity, SqlColumnNumber = 2, SqlFieldName = catalog_id ];
6-
6+
/// Product Code
77
Property productcode As %Library.String(%JSONFIELDNAME = "product_code", MAXLEN = 128) [ SqlColumnNumber = 3, SqlFieldName = product_code ];
8-
8+
/// Quantity in number of bags
99
Property quantity As %Library.Integer(MAXVAL = 2147483647, MINVAL = -2147483648) [ SqlColumnNumber = 4 ];
10-
10+
/// Price per bag in USD
1111
Property price As %Library.Numeric(MAXVAL = 99999999.99, MINVAL = -99999999.99, SCALE = 2) [ SqlColumnNumber = 5 ];
12-
12+
/// Time at which the coffee beans were roasted
1313
Property timeroasted As %Library.DateTime(%JSONFIELDNAME = "time_roasted") [ SqlColumnNumber = 6, SqlFieldName = time_roasted ];
14-
14+
/// Flowery prose describing the taste of the coffee
1515
Property roastingnotes As %Library.String(%JSONFIELDNAME = "roasting_notes", MAXLEN = 2048) [ SqlColumnNumber = 7, SqlFieldName = roasting_notes ];
16-
16+
/// A product picture
1717
Property img As %Library.String(MAXLEN = 2048) [ SqlColumnNumber = 8 ];
1818

1919
Parameter USEEXTENTSET = 1;

services/cls_Sample/ICO/inventory.cls

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
/// in step 2 add json.adaptor and jsonfieldname properties
1+
/// Database representation of raw coffee bean inventory
22
Class ICO.inventory Extends (%Persistent, %JSON.Adaptor) [ ClassType = persistent, DdlAllowed, Final, Owner = {_SYSTEM}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = inventory ]
33
{
4-
4+
/// Vendor's unique ID
55
Property vendorid As %Library.String(%JSONFIELDNAME = "vendor_id", MAXLEN = 128) [ SqlColumnNumber = 2, SqlFieldName = vendor_id ];
6-
6+
/// Vendor's product code
77
Property vendorproductcode As %Library.String(%JSONFIELDNAME = "vendor_product_code", MAXLEN = 128) [ SqlColumnNumber = 3, SqlFieldName = vendor_product_code ];
8-
8+
/// Quantity of beans in kilograms
99
Property quantitykg As %Library.Numeric(%JSONFIELDNAME = "quantity_kg", MAXVAL = 99999999.99, MINVAL = -99999999.99, SCALE = 2) [ SqlColumnNumber = 4, SqlFieldName = quantity_kg ];
10-
10+
/// Date the product arrived at the warehouse
1111
Property datearrival As %Library.Date(%JSONFIELDNAME = "date_arrival") [ SqlColumnNumber = 5, SqlFieldName = date_arrival ];
12-
12+
/// Date the product left the producer
1313
Property datedeparture As %Library.Date(%JSONFIELDNAME = "date_departure") [ SqlColumnNumber = 6, SqlFieldName = date_departure ];
1414

1515
Parameter USEEXTENTSET = 1;

services/samples/createproducts.sh

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/sh
22

3+
# Creates JSON files representing bags of roasted coffee coming out of the roastery and ready for import into the sales database, ICO.catalog, using loadproducts.sh
4+
35
freshdate=$(date +"%Y-%m-%d")
46
staledate=$(date -d "-6 days" +"%Y-%m-%d")
57

services/samples/loadproducts.sh

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#!/bin/sh
22

3+
# Reads JSON files representing bags of roasted coffee coming out of the roastery and uses a REST API to load the data into the sales catalog
4+
5+
36
IRISDB="http://localhost:52773"
47

58
for jsonfile in *.json ;

setup/README.md

-54
This file was deleted.

setup/manifest_importer.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
KEYFIELDNAMES = ["vendor_id", "vendor_product_code", "quantity_kg"]
66

77
def load_manifest(json_data: dict, conn: pyodbc.Connection) -> Exception:
8-
""" Use SQL to load records into the data structure
8+
""" Use SQL INSERT statements to load records into existing relational tables
99
Args:
1010
json_data: manifest in a Python dictionary
1111
conn: database connection object
1212
Returns:
13-
true if creation is successful, otherwise returns the exception
13+
None if creation is successful, otherwise returns the exception
1414
"""
1515
cursor = conn.cursor()
1616
fieldnamesql = "INSERT INTO ICO.inventory (vendor_id, vendor_product_code, quantity_kg, date_arrival)"
@@ -35,6 +35,12 @@ def load_manifest(json_data: dict, conn: pyodbc.Connection) -> Exception:
3535

3636

3737
def validate_manifest(json_data: dict) -> tuple:
38+
""" Verify that the manifest file contains valid inventory data
39+
Args:
40+
json_data: manifest in a Python dictionary
41+
Returns:
42+
a tuple (original JSON data, True, None) if valid, (None, false, exception) if not
43+
"""
3844
try:
3945
# check if items exists
4046
if (json_data.get("items")) is None:
@@ -79,6 +85,12 @@ def get_connection_info(file_name):
7985
return connections
8086

8187
def main():
88+
""" Entry point to running the program. Loads a file in the same directory named order_manifest.json, parses the file into SQL INSERT statements, and loads the inventory into the database
89+
Args:
90+
None
91+
Returns:
92+
Nothing
93+
"""
8294
with open('./order_manifest.json') as f:
8395
data = json.load(f)
8496

0 commit comments

Comments
 (0)