-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMain.lua
More file actions
256 lines (222 loc) · 10.1 KB
/
Main.lua
File metadata and controls
256 lines (222 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
require "Atlas.AtlasHelpers";
local rootLogger = "AtlasSystems.Addons.AlmaBarcodeLookupAddon";
luanet.load_assembly("System.Windows.Forms");
luanet.load_assembly("log4net");
luanet.load_assembly("System.Xml");
local types = {};
types["System.Windows.Forms.Cursor"] = luanet.import_type("System.Windows.Forms.Cursor");
types["System.Windows.Forms.Cursors"] = luanet.import_type("System.Windows.Forms.Cursors");
types["log4net.LogManager"] = luanet.import_type("log4net.LogManager");
local log = types["log4net.LogManager"].GetLogger(rootLogger);
local settings = {};
settings.AlmaApiUrl = GetSetting("Alma API URL");
settings.AlmaApiKey = GetSetting("Alma API Key");
settings.FieldToPerformLookupWith = GetSetting("Field to Perform Lookup With");
settings.ILLUser = GetSetting("ILL Request User ID");
settings.PickupLib = GetSetting("Pickup Library Code");
settings.HoldIdField = GetSetting("Alma_Hold_ID_Field");
settings.AutoRouteQueue = GetSetting("Auto_Route_On_Success");
local interfaceMngr = nil;
function Init()
interfaceMngr = GetInterfaceManager();
if interfaceMngr then
local ribbonPage = interfaceMngr:CreateRibbonPage("Hold Request");
if ribbonPage then
ribbonPage:CreateButton("Request Hold", GetClientImage("Search32"), "RouteItem", "Actions");
ribbonPage:CreateButton("Check Status", GetClientImage("Refresh32"), "CheckRequestStatus", "Actions");
ribbonPage:CreateButton("Cancel Hold", GetClientImage("Delete32"), "CancelHoldRequest", "Actions");
end
end
AlmaApi.ApiUrl = settings.AlmaApiUrl;
AlmaApi.ApiKey = settings.AlmaApiKey;
end
-- HELPER: Gets raw barcode string from the configured field
function GetRawBarcodeString()
local barcode = nil;
if settings.FieldToPerformLookupWith == "{Default}" then
barcode = GetFieldValue("Transaction", "ItemNumber");
else
local tableCol = Utility.StringSplit(".", settings.FieldToPerformLookupWith);
if #tableCol == 2 then barcode = GetFieldValue(tableCol[1], tableCol[2]); end
end
return barcode;
end
-- HELPER: Gets MMS, Holding, and Item PIDs based on a single Barcode
function GetAlmaItemIdsByBarcode(barcode)
if barcode == nil or barcode == "" then return nil, nil, nil; end
local itemXml = AlmaApi.RetrieveItemByBarcode(barcode);
if itemXml == nil then return nil, nil, nil; end
return AlmaApi.ParseItemIds(itemXml);
end
-- HELPER: Extracts all digits (IDs) from the configured field into a table
function GetRequestIdsFromField()
local rawVal = GetFieldValue("Transaction", settings.HoldIdField);
if rawVal == nil or rawVal == "" then return {} end
local ids = {};
for id in string.gmatch(rawVal, "%d+") do
table.insert(ids, id);
end
return ids;
end
-- HELPER: Parses space-separated barcodes into a clean table
function GetCleanBarcodesList()
local rawBarcodes = GetRawBarcodeString();
if not rawBarcodes or rawBarcodes == "" then return {} end
-- Changed from "," to " " to split barcodes by space
local barcodeList = Utility.StringSplit(" ", rawBarcodes);
local cleanBarcodes = {};
for _, b in ipairs(barcodeList) do
local cb = Utility.Trim(b);
if cb ~= "" then table.insert(cleanBarcodes, cb) end
end
return cleanBarcodes;
end
-- 1. REQUEST HOLD
function RouteItem()
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].WaitCursor;
local cleanBarcodes = GetCleanBarcodesList();
if #cleanBarcodes == 0 then
interfaceMngr:ShowMessage("No barcodes found.", "Error");
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].Default;
return;
end
local isMultiple = #cleanBarcodes > 1;
local transactionNumber = GetFieldValue("Transaction", "TransactionNumber");
local requestIds = {};
local errors = {};
-- Loop over all barcodes and place requests
for _, barcode in ipairs(cleanBarcodes) do
local mmsId, holdingId, itemPid = GetAlmaItemIdsByBarcode(barcode);
if not mmsId then
table.insert(errors, barcode .. ": Could not identify item in Alma.");
else
local responseXml = AlmaApi.PlaceRequest(mmsId, holdingId, itemPid, settings.ILLUser, settings.PickupLib, transactionNumber, isMultiple);
if responseXml ~= nil then
local reqIdNode = responseXml:SelectSingleNode("//request_id");
if reqIdNode then
table.insert(requestIds, reqIdNode.InnerText);
else
local errText = "Unknown Error";
local errorNode = responseXml:SelectSingleNode("//errorMessage");
if errorNode then errText = errorNode.InnerText end
table.insert(errors, barcode .. ": " .. errText);
end
else
table.insert(errors, barcode .. ": No response from Alma.");
end
end
end
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].Default;
-- Process Results
if #requestIds > 0 then
-- Save all IDs separated by commas
SetFieldValue("Transaction", settings.HoldIdField, "Created " .. table.concat(requestIds, ", "));
ExecuteCommand("Save", {});
if #errors == 0 then
log:Info("Hold IDs Saved. Checking for Auto-Route...");
if settings.AutoRouteQueue and settings.AutoRouteQueue ~= "" then
local success, err = pcall(function()
ExecuteCommand("Route", {settings.AutoRouteQueue, true});
end);
if not success then
log:Error("Route command FAILED: " .. Utility.Redact(tostring(err)));
interfaceMngr:ShowMessage("Holds placed, but Auto-Route failed.", "Warning");
end
else
interfaceMngr:ShowMessage("Holds placed successfully! IDs: " .. table.concat(requestIds, ", "), "Success");
end
else
interfaceMngr:ShowMessage("Some holds placed successfully, but with errors:\n" .. table.concat(errors, "\n"), "Warning");
end
else
interfaceMngr:ShowMessage("Failed to place holds:\n" .. table.concat(errors, "\n"), "Error");
end
end
-- 2. CHECK STATUS
function CheckRequestStatus()
local reqIds = GetRequestIdsFromField();
if #reqIds == 0 then
interfaceMngr:ShowMessage("No Request IDs found in " .. settings.HoldIdField .. ".", "Error");
return;
end
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].WaitCursor;
local cleanBarcodes = GetCleanBarcodesList();
local statuses = {};
for i, reqId in ipairs(reqIds) do
local barcode = cleanBarcodes[i];
if barcode then
local mmsId, holdingId, itemPid = GetAlmaItemIdsByBarcode(barcode);
if mmsId then
local responseXml = AlmaApi.GetRequest(mmsId, holdingId, itemPid, reqId);
if responseXml then
local statusNode = responseXml:SelectSingleNode("//request_status");
if statusNode then
local status = statusNode.InnerText;
if status == "HISTORY" then
table.insert(statuses, reqId .. ": Inactive/Cancelled");
else
table.insert(statuses, reqId .. ": " .. status);
end
else
table.insert(statuses, reqId .. ": Request not found (Active)");
end
else
table.insert(statuses, reqId .. ": Failed to retrieve status");
end
else
table.insert(statuses, reqId .. ": Failed to identify base item in Alma");
end
else
table.insert(statuses, reqId .. ": No matching barcode found to check status");
end
end
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].Default;
interfaceMngr:ShowMessage(table.concat(statuses, "\n"), "Status");
end
-- 3. CANCEL HOLD
function CancelHoldRequest()
local reqIds = GetRequestIdsFromField();
if #reqIds == 0 then
interfaceMngr:ShowMessage("No Request IDs found in " .. settings.HoldIdField .. ".", "Error");
return;
end
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].WaitCursor;
local cleanBarcodes = GetCleanBarcodesList();
local transactionNumber = GetFieldValue("Transaction", "TransactionNumber");
local reason = "AdditionalReason05";
local note = transactionNumber or "";
local successCount = 0;
local failCount = 0;
local cancelledIds = {};
for i, reqId in ipairs(reqIds) do
local barcode = cleanBarcodes[i];
if barcode then
local mmsId, holdingId, itemPid = GetAlmaItemIdsByBarcode(barcode);
if mmsId then
local success = AlmaApi.CancelRequest(mmsId, holdingId, itemPid, reqId, reason, note);
if success then
successCount = successCount + 1;
table.insert(cancelledIds, reqId);
else
failCount = failCount + 1;
end
else
failCount = failCount + 1;
end
else
failCount = failCount + 1;
end
end
types["System.Windows.Forms.Cursor"].Current = types["System.Windows.Forms.Cursors"].Default;
if successCount > 0 then
pcall(function()
SetFieldValue("Transaction", settings.HoldIdField, "Cancelled " .. table.concat(cancelledIds, ", "));
ExecuteCommand("Save", {});
end);
local msg = "Cancelled " .. successCount .. " request(s).";
if failCount > 0 then msg = msg .. "\nFailed to cancel " .. failCount .. " request(s)." end
interfaceMngr:ShowMessage(msg, "Info");
else
interfaceMngr:ShowMessage("Failed to cancel holds. They may already be inactive.", "Error");
end
end