diff --git a/Code.lua b/Code.lua index ee9c07e..d6b41cd 100644 --- a/Code.lua +++ b/Code.lua @@ -252,7 +252,7 @@ function SierraApi:UpdateAccessToken(clientKey, clientSecret) ]] local accessToken = self:GetAccessToken(clientKey, clientSecret) - SierraApi.Log:DebugFormat("Updated Access Token: {0}", accessToken) + SierraApi.Log:Debug("Updated Access Token: [REDACTED]") self.AccessToken = accessToken return accessToken end @@ -307,7 +307,7 @@ function SierraApi:GetAccessTokenResponse (clientKey, clientSecret) local authUploadSuccess, authUploadResult = pcall(function() - SierraApi.Log:DebugFormat("Encoded Client Key and Secret: {0}", encodedKeyAndSecret) + SierraApi.Log:Debug("Encoded Client Key and Secret: [REDACTED]") SierraApi.Log:DebugFormat("Posting to URL: {0}", authTokenUrl) return credentialWebClient:UploadString(authTokenUrl, uploadMethod, uploadBody) end) @@ -318,7 +318,7 @@ function SierraApi:GetAccessTokenResponse (clientKey, clientSecret) SierraApi.Log:Warn("Failure occurred while obtaining access token.") error(authUploadResult) else - SierraApi.Log:DebugFormat("Access Token Response: {0}", authUploadResult) + SierraApi.Log:Debug("Access Token Response: [REDACTED]") end @@ -403,7 +403,7 @@ function SierraApi:GetItems (bibId, volume, exact) local entryId = v_entry.id or "" local v_volume = SierraApi:GetVarFieldValue(v_entry, "v") - if v_volume and v_volume ~= "" and volume and volume ~= "" then + if not IsNilOrBlank(v_volume) and not IsNilOrBlank(volume) then if exact then if Utility.Trim(volume) == Utility.Trim(v_volume) then SierraApi.Log:DebugFormat("Sierra item record \"{0}\" matches specified bibId and volume (exact).", entryId); @@ -415,7 +415,7 @@ function SierraApi:GetItems (bibId, volume, exact) table.insert(matchingItems, v_entry) end end - elseif (not volume or volume == "") and (not v_volume or v_volume == "") then + elseif IsNilOrBlank(volume) and IsNilOrBlank(v_volume) then SierraApi.Log:DebugFormat("Sierra item record \"{0}\" matches specified bibId.", entryId); table.insert(matchingItems, v_entry); end @@ -459,7 +459,7 @@ function SierraApi:GetVarFieldValue (itemRecord, varField, subField) for i_vf, v_varField in ipairs(itemRecord.varFields or {}) do if v_varField and v_varField.fieldTag == varField then - if subField and subField ~= "" then + if not IsNilOrBlank(subField) then for i_sf, v_subField in ipairs(v_varField.subFields or {}) do @@ -621,7 +621,7 @@ function SierraApi:BuildItemsWebClient () webClient.Headers:Clear() webClient.Headers:Add("Authorization", "Bearer " .. self.AccessToken) - if self.UserAgent and self.UserAgent ~= "" then + if not IsNilOrBlank(self.UserAgent) then webClient.Headers:Add("User-Agent", self.UserAgent) end @@ -737,6 +737,9 @@ Settings.VolumeSourceFieldRegularExpression = GetSetting("VolumeSourceFieldRegul Settings.ExactSearch = GetSetting("ExactSearch") Settings.ReplaceVolumeWhenNotNull = GetSetting("ReplaceVolumeWhenNotNull") +Settings.LocationDestinationField = GetSetting("LocationDestinationField") +Settings.LocationValueType = GetSetting("LocationValueType") + luanet.load_assembly("System") luanet.load_assembly("log4net") @@ -782,7 +785,11 @@ function TimerElapsed (eventArgs) Log:Debug("Addon Settings: ") for settingKey, settingValue in pairs(Settings) do - Log:DebugFormat("{0}: {1}", settingKey, settingValue) + if settingKey == "ClientKey" or settingKey == "ClientSecret" then + Log:DebugFormat("{0}: [REDACTED]", settingKey) + else + Log:DebugFormat("{0}: {1}", settingKey, settingValue) + end end local successfulAddonExecution, error = pcall(function() @@ -792,7 +799,7 @@ function TimerElapsed (eventArgs) end local accessToken = sierraApi:UpdateAccessToken(Settings.ClientKey, Settings.ClientSecret) - Log:DebugFormat("Generated Access Token: {0}", accessToken) + Log:Debug("Generated Access Token: [REDACTED]") ProcessDataContexts("TransactionStatus", Settings.RequestMonitorQueue, "HandleRequests") end) @@ -830,7 +837,7 @@ function HandleRequests () Log:DebugFormat("Found transaction number {0} in \"{1}\"", tn, Settings.RequestMonitorQueue) local regex - if Settings.VolumeSourceFieldRegularExpressionn and Settings.VolumeSourceFieldRegularExpression ~= "" then + if not IsNilOrBlank(Settings.VolumeSourceFieldRegularExpression) then regex = Types["Regex"](Settings.VolumeSourceFieldRegularExpression) Log:DebugFormat("Found Regex \"{0}\" for VolumeSourceField.", Settings.VolumeSourceFieldRegularExpression) else @@ -844,17 +851,16 @@ function HandleRequests () Log:DebugFormat("Getting BibID from transaction.{0}", Settings.BibIdSourceField) local transactionBibId = GetFieldValue("Transaction", Settings.BibIdSourceField) transactionBibId = transactionBibId:gsub("%D", "") - local transactionVolume - if regex ~= nil then - match = regex:Match(GetFieldValue("Transaction", Settings.VolumeSourceField)) - if match.Success then - Log:DebugFormat("Using Regex for volume source field {0} results in match \"{1}\"", - Settings.VolumeSourceField, match.Value) - transactionVolume = match.Value + local transactionVolume = GetFieldValue("Transaction", Settings.VolumeSourceField); + if regex ~= nil and not IsNilOrBlank(transactionVolume) then + local match = regex:Match(transactionVolume); + if match.Success and match.Value ~= "" then + Log:DebugFormat("Using Regex for volume source field {0} results in match \"{1}\"", Settings.VolumeSourceField, match.Value); + transactionVolume = match.Value; end else Log:DebugFormat("Getting volume source field {0}", Settings.VolumeSourceField) - transactionVolume = GetFieldValue("Transaction", Settings.VolumeSourceField) + transactionVolume = transactionVolume; end return transactionBibId, transactionVolume end @@ -898,7 +904,7 @@ function HandleRequests () SaveDataSource("Transaction") end - if Settings.VolumeDestinationField and Settings.VolumeDestinationField ~= "" then + if not IsNilOrBlank(Settings.VolumeDestinationField) then local currentVolumeDestinationField = GetFieldValue("Transaction", Settings.VolumeDestinationField) if (Settings.ReplaceVolumeWhenNotNull or (not currentVolumeDestinationField) or currentVolumeDestinationField == "") then Log:Debug("Populating volume destination field") @@ -907,7 +913,7 @@ function HandleRequests () end end - if Settings.BarcodeDestinationField and Settings.BarcodeDestinationField ~= "" then + if not IsNilOrBlank(Settings.BarcodeDestinationField) then Log:Debug("Populating barcode destination field") if (not type(sierraRecord.barcode) == "string") or sierraRecord.barcode == "" then @@ -918,6 +924,27 @@ function HandleRequests () SaveDataSource("Transaction") end + if not IsNilOrBlank(Settings.LocationDestinationField) then + Log:Debug("Populating location destination field") + + local locationValue + if sierraRecord.location then + if Settings.LocationValueType == "code" then + locationValue = sierraRecord.location.code + else + locationValue = sierraRecord.location.name + end + end + + if not IsNilOrBlank(locationValue) then + SetFieldValue("Transaction", Settings.LocationDestinationField, locationValue) + SaveDataSource("Transaction") + else + Log:WarnFormat("Sierra item record does not contain location.{0}; leaving {1} unchanged.", + Settings.LocationValueType, Settings.LocationDestinationField) + end + end + return nil end ) @@ -935,6 +962,14 @@ function HandleRequests () end end +function IsNilOrBlank(value) + if not value or value == "" then + return true; + else + return false; + end +end + function TraverseError(err) if not err.GetType then -- Not a .NET type diff --git a/Config.xml b/Config.xml index 41f6a66..f2a2000 100644 --- a/Config.xml +++ b/Config.xml @@ -1,7 +1,7 @@ Sierra ILS Data Import Server Addon - Test Build Atlas Systems, Inc. - 1.2.0 + 1.3.0 true Server @@ -67,6 +67,14 @@ A regular expression for parsing the volume from the field specified in the VolumeSourceField setting. The matched result will be used instead of the value from the VolumeSourceField, whenever volume information is compared. If this is set to blank, the actual value from the VolumeSourceField will be used. + + + Specifies the transaction field where the matched Sierra item's location information should be stored. The value of this setting is optional. If specified, the value of this setting must match the name of a column from the Transactions table. If left blank, no location information will be written. + + + + Determines which property of the Sierra item's location is written to the LocationDestinationField. Set to "name" to use the location's display name or "code" to use the location's code. Any value other than "code" is treated as "name". + Code.lua diff --git a/Readme.md b/Readme.md index c1eba59..5fc19d6 100644 --- a/Readme.md +++ b/Readme.md @@ -4,6 +4,12 @@ This addon imports ILS data from Sierra's Items API for transactions that are in ## Changelog +- `v1.3.0` + - Added option to import the matched Sierra item's location into a configurable Transaction field via the new `LocationDestinationField` and `LocationValueType` settings. + - Fixed a typo in the `VolumeSourceFieldRegularExpression` guard that prevented the configured regex from ever being applied. Sites with a non-empty regex (including the shipped default) will now see the regex used during volume matching. + - Hardened regex-based volume parsing: the regex is now skipped when the source field is nil or blank, the original field value is preserved when the regex finds no match, and zero-width regex matches no longer overwrite the volume with an empty string. + - Redacted `ClientKey`, `ClientSecret`, and Sierra API access tokens from the addon's log output. These values were previously written to the log at the DEBUG level on every timer tick. + - `v1.1.0` - Added ability to parse volume information via regular expressions. - Added exact matching options on volume information. @@ -96,6 +102,18 @@ A regular expression for parsing the volume from the field specified in the Volu *EXAMPLE*: `([B,b]ox\s*\d+)` will parse all box numbers only +### LocationDestinationField + +Specifies the transaction field where the matched Sierra item's location information should be stored. The value of this setting is optional. If specified, the value of this setting must match the name of a column from the Transactions table. If left blank, no location information will be written. + +*Default*: `SubLocation` + +### LocationValueType + +Determines which property of the Sierra item's location is written to the `LocationDestinationField`. Set to `name` to use the location's display name or `code` to use the location's code. Any value other than `code` is treated as `name`. If the Sierra response does not contain location data, the destination field is left unchanged and a warning is logged (the transaction is still routed to the success queue). + +*Default*: `name` + ## Workflow Summary The addon watches the transaction queue specified by the RequestMonitorQueue addon setting. When the addon detects that there are transactions present in the queue, it will grab bibId and volume information from the transaction. Using the bibId and volume information, the addon will attempt to download information regarding a single item using Sierra's API. If exactly one item is found, the item's information will be added to the transaction, which will then be routed to the specified success queue. If anything does not occur as expected during this process, a note will be added to the transaction, and it will be placed into the specified error queue.