To test:
1 - Attempt to save a report containing "select force_password_reset_when_set_by_staff from categories"
2 - observe koha prevents this save
3 - apply patch, restart services
4 - repeat step 1
5 - observe your report now saves and runs successfully
While adding this new field to the list of allowed fields, I changed "whitelist" to "allowlist" as suggested by the terminology guide: https://wiki.koha-community.org/wiki/Terminology
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
For SIP based payments, no branchcode is recorded for the corresponding
credit. Koha should be recording the institution id (i.e. branchcode)
for SIP payments.
Test plan:
1) Apply this patch
2) prove t/db_dependent/SIP/Transaction.t
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
To test:
Enable pseudonymization, may need to add bcrypt settings (see bug 28911)
Perform some circulations
View the jobs (Admin->Manage jobs)
Filter for Pseudonymize statistic
Note the progress is 0/1 even when job finished
Apply patch, restart all
Do more circulations
Confirm jobs now say 1/1 complete
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch fixes the markup in the modal, introduced by Bug 32581,
asking whether to update the patron's expiration date when changing the
patron category. The markup needs to be updated to conform with
Bootstrap 5.
To test, apply the patch and go to Patrons.
- Search for any patron and edit it.
- Scroll down to the "Library management" section.
- Change the category.
- You should see a confirmation modal: "Confirm expiration date"
- Test each of the controls to confirm that they work correctly: The
"X" close button, the "Yes" and "No" buttons.
Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This fixes an error in SIP2 patron information response (64) when no currency is set, which can be the case on newly created instances.
Test plan for KTD:
a) Delete currency and related tables
- run 'koha-mysql kohadev' to start SQL client. Then run the following queries:
- delete from aqbasket;
delete from aqbooksellers;
delete from currency;
b) exit
c) run 'perl misc/sip_cli_emulator.pl -a 127.0.0.1 -p 6001 -su term1 -sp term1 -l CPL -m patron_information --patron 42'
Attempting socket connection to 127.0.0.1:6001...connected!
SEND: 9300CNterm1|COterm1|CPCPL|
READ: 941
Trying 'patron_information'
SEND: 6300120251202 115652 AOCPL|AA42|ACterm1|
READ: undef
d) recognize the last response: READ: undef
e) apply patch and restart sip2 server via 'sudo koha-sip --restart kohadev'
e) rerun 'perl misc/sip_cli_emulator.pl -a 127.0.0.1 -p 6001 -su term1 -sp term1 -l CPL -m patron_information --patron 42'
Attempting socket connection to 127.0.0.1:6001...connected!
SEND: 9300CNterm1|COterm1|CPCPL|
READ: 941
Trying 'patron_information'
SEND: 6300120251202 122545 AOCPL|AA42|ACterm1|
READ: 64 00120251202 122546000000000000000000000000AOCPL|AA42|AE koha|BLY|BV0|CC5|PCS|PIY|AFGreetings from Koha. |
f) check the last response is now a patron information response (64)
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
There are 2 occurrences of "0E0" in the test suite output.
We should remove them.
Test plan:
root@kohadevbox:koha$ perl /kohadevbox/misc4dev/run_tests.pl --run-all-tests
And confirm that the 0E0 does no longer appear
You can abort when the update DB process is done
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch corrects a few minor errors in recalls.js. There should be no
change to how the pages work.
The following functions have been changed:
- Cancel a recall from the recalls tab on a patron record
- Expire a recall or revert the waiting status of a recall from the
"Recalls awaiting pickup" page.
- Cancel a recall which has been transferred from the "Recalls queue"
page.
- Mark a recall "Overdue" from the "Recalls queue" page.
- Cancel selected recalls on the "Recalls queue" page.
Sponsored-by: Athens County Public Libraries
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Since OverDrive no longer supplies star ratings through their API we can
remove the corresponding JS from the template.
To test, apply the patch and enable OverDrive integration.
- In the OPAC, perform a search which will return results from your
OverDrive collection.
- Follow the link a the top of Koha search results, "Found X results in
the library's OverDrive collection"
- Confirm that OverDrive search results load correctly and that nothing
looks broken.
Sponsored-by: Athens County Public Libraries
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Before this patch we were setting a variable and nebver unsetting it
Now we can add the conditional directly to the row, so don't need a variable
To test:
1. Go to Acquisitions
2. Click 'Search' in the vendor search
3. Click 'Add to basket' next to 'My basket'
4. Click 'From a new (empty) record'
5. Fill out the form
- Title: enter a title
- Koha item type: choose an item type
5.1. Click 'Add item'
- Fund: choose a fund
- Uncertain price: check
6. Click 'Save'
7. Go back to Acquisitions
8. Click 'Search' in the vendor search
9. Click 'New' > 'Basket'
10. Enter a basket name
11. Click 'Save'
12. Go back to Acquistions
13. Click 'Search' in the vendor search
--> Notice the empty basket is also in bold red, even if it doesn't have uncertain prices
14. Click 'Add to basket'
--> Notice everything is in bold and some in red
15. Apply patch, reload
16. Only affected basket is in red
Signed-off-by: Samuel <sam.sowanick@corvallisoregon.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch corrects two strings in js/transport_status.js so that it has
correct capitalization.
I'm not sure how to test every way these strings are seen in the
interface, but checking the patch should show only capitalization
changes.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This adds to the unit tests in t/db_dependent/Koha/Patrons/Import.t. It confirms that repeating the same patron import (with extended patron attributes) will not generate duplicated borrowersLog entries.
Test plan:
1. prove t/db_dependent/Koha/Patrons/Import.t
Sponsored-by: Auckland University of Technology
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Since bug 26744 was upstreamed when you use the Import patron tool or the import_patrons.pl script from the commandline and pass a preserve-extended-attributes parameter the borrowerlogs inaccurately have an entry added where the attribute 'before' value is empty.
Test plan:
1. Create a patron attribute type named 'INSTID': Koha administration > Patrons and circulation > Patron attribute types > New patron attribute type.
2. Download the patron started CSV from: Tools > Import patrons > click the 'Download a Starter CSV file with all the columns.' link
3. Save values in the: cardnumber, surname, firstname, branchcode, categorycode, auth_method, lang, and patron_attributes columns
4. Make sure your value in the patron_attributes column is INSTID:1234
5. Import this csv file:
cd misc
./import_patrons.pl --file <filename>.csv --matchpoint cardnumber --default branchcode=CPL --overwrite --preserve-extended-attributes --verbose --verbose --confirm
6. Navigate to the patron account in your browser
7. Click 'Modification log' and observe how many entries there are
8. Repeat step 5
9. Notice there is a new entry in your Modification log with an info column value of: { "attribute.INSTID" : { "after" : "1234", "before" : "" } }
10. Repeat step 5 and notice another new entry in the Modification log with an empty "before" value
11. Apply patch
12. Repeat step 5 and notice no new entry in the Modification log
13. Edit your csv and change the patron_attributes value to: INSTID:5678
14. Repeat step 5 and notice the new modification log entry with an info column value of: { "attribute.INSTID" : { "after" : "5678", "before" : "1234" } }
15. Add another new patron attribute type to your Koha named 'home'
16. edit your csv and change the patron_attributes value to: INSTID:5678,home:town
17. Repeat step 5
18. Notice a new Modification log entry with the value of: { "attribute.home" : { "after" : "town", "before" : "" } }
Sponsored-by: Auckland University of Technology
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
To test:
1 - place a hold
2 - check an item in to fill your hold, confirm so item goes to Waiting status
3 - check item in again, get Hold Already Waiting modal
4 - clck Ignore, confirm modal reloads immediately
5 - apply patch, restart_all
6 - reload checkin page
7 - check item in again, get Hold Already Waiting modal
8 - click Ignore, confirm modal goes away and doesn't return
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Just adding the fifth parameter here, since that actually should
be the next published date. But note that it is just a placeholder,
since the test does not use the associated date substitutions.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Before this patch, we pass the previous issue date to generate the next seq - this works for the pattern as we are incrementing.
When the patter is translated ot words, we need to do this from the date of the next issue, so we must pass in the next
published date
This patch changes the call to GetNextSeq from serial-collection.pl to ensure the new issue publication date is used to
generate the numbers.
To test:
0 - Follow the plan to recreate from the initial bug description and recreate
1 - Apply patch
2 - On the serial used in previous patch go to 'Serial collection'
3 - Generate next issue
4 - Confirm the numbering is correctly generated after this patch
Signed-off-by: Wesley Owen <wesleyowen@churchofjesuschrist.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This adds the 26.05 release team as proposed.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Update the teams list to reflect the reality of the 25.11 cycle with an
updated release date and updates to the QA team to reflect those who
performed duties during the cycle.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
We introduced some errant periods in the mailmap which cause parsing
issues.
I also fix the removal of the '=' author by replacing it with a mapping
to the original author of the patch from bug 6979, Robert Fox
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This change updates the print format to use the built-in formatter
for operations like trim, strip HTML, strip newlines, and not
decoding entities.
Test plan:
0. Apply the patch
1. Go to http://localhost:8081/cgi-bin/koha/acqui/basket.pl?basketno=1
2. Click "add to basket"
3. Type "test" next to "From an existing record" and click "Submit"
4. On the "Gairm" row, click "Add order"
5. Fill in the required fields
6. In the "Internal note" put the following:
abc123
7. Click "Save"
8. In the Orders table, click "Export" and then "Print"
9. Note that the print page loads correctly, you can see the internal note,
and you cannot see lines for "Add internal note",
"Edit internal note", or "Add vendor note"
Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch makes the 'Processings' breadcrum element not be tied to a component but a plain string with the link disabled. This was causing errors:
- Breadcrumb element empty
- Error in the browser console
To test:
1. Enable the Preservation module
2. Go to Home > Preservation > Settings
3. Use the 'Add a new processing' button
=> FAIL: The breadcrumb has 'Settings > > Add processing' (i.e. is missing 'Processings' between >)
4. Click on 'Edit this processing'
=> FAIL: Same error, different context
5. Check the browser console
=> FAIL: You see something like this:
```
[Vue Router warn]: No match found for location with path "/cgi-bin/koha/preservation/settings/processings" devtools-BLCumUwL.mjs:59:1
```
6. Run the cypress tests for this module:
k$ run_cypress --spec t/cypress/integration/Preservation/Settings.ts
=> FAIL: The breadcrumb navigation is broken
7. Apply this patch
8. Rebuild things:
$ ktd --shell
k$ yarn build
9. Fully refresh the page (Use cmd+shift+r on macOS, ctrl+shift+r on Linux/Windows)
10. Repeat 2-6
=> SUCCESS: The breadcrumb is no longer broken
=> SUCCESS: No errors/warnings about this in the browser console
=> SUCCESS: Tests pass!
11. Sign off :-D
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The test was looking for .current class but the Vue component
uses aria-current="page" attribute instead.
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
On top of "Bug 41354: Fix record sources Vue app" there is still one
failing test for t/cypress/integration/Admin/RecordSources_spec.ts
1) Breadcrumbs tests
Breadcrumbs:
AssertionError: Timed out retrying after 10000ms: Expected to find element: `.current`, but never found it.
at Context.eval (webpack://koha/./t/cypress/integration/Admin/RecordSources_spec.ts:18:11)
This patch is trying to fix it but it does not
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Cypress tests for Vue app are currently failing because of the following
warnings in the console:
"[Vue Router warn] No match found for location with path"
It happens for routes that are disabled. We should not build a
router-link but a "disabled" link instead.
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Test plan:
1) Navigate to record sources and create a record source
2) In the table there will be a hyperlink on the record source name which shouldn't be there
3) Apply patch and rebuild javascript
4) Hard refresh and then observe that the table should no longer have a hyperlink
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
It fixes a JS error in the console
Uncaught (in promise) TypeError: can't convert undefined to object
Also fixes the cypress tests:
t/cypress/integration/Admin/RecordSources_spec.ts
Test plan:
Create a new record source
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
.dt-select-filter does no longer exist
Here we rely on DT's API to retrieve the correct visible column index.
However we cannot for Selenium tests, not ideal but it fixes the
failure.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
- Use devtool: false to prevent emitting source maps for cypress.
- Add package script to clean built assets, artifacts.
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The following C4::Auth subroutines
- checkauth()
- get_template_and_user()
were in some cases outputting html outside of C4::Output's output mechanisms.
It is important to ensure the consistency of our HTTP responses. Having
multiple output mechanisms for what is essentialy the same type of response not
only leads to unneccessary code duplication and complexity but possibly even
bugs at some point in the future.
For these reasons it is better to output only through C4::Output, when possible.
This patch does that for the two aforementioned C4::Auth cases.
To test unit tests:
1. prove t/db_dependent/Auth.t
As for checkauth(), the change only applies to unauthenticated state and failed
logins.
To test checkauth:
1. Enable system preference opacuserlogin
2. Navigate to OPAC
3. Observe OPAC loading successfully
4. Log in to OPAC with invalid credentials
5. Observe "You entered an incorrect username or password"
6. Navigate to staff client without being logged in (logout if you are in)
7. Observe staff client login screen loading successfully
8. Log in to staff client with invalid credentials
9. Observe "Invalid username or password"
As for get_template_and_user(), the change only applies to SCO/SCI user
navigating outside of the self service modules.
To test get_template_and_user:
1. Enable system preference WebBasedSelfCheck
2. Create a new test patron and note down their username & password
3. Grant them a permission self_checkout_module (under Self check modules)
4. Navigate to http://OPAC/cgi-bin/koha/sco/sco-main.pl
5. Log in with the test patron
6. Observe successful login (should display "Self-checkout system" page)
7. Navigate to http://OPAC/cgi-bin/koha/opac-main.pl
(you can get there by editing the address bar of your web browser)
8. Observe "Log in to your account" page, ie. you have been kicked out
9. Modify your test patron's permissions
10. Remove permission "self_checkout_module" and add "self_checkin_module"
11. Enable system preference SelfCheckInModule
12. Navigate to http://OPAC/cgi-bin/koha/sci/sci-main.pl
13. Log in using your test patron's credentials
14. Observe "Self check-in" page
15. Navigate to http://OPAC/cgi-bin/koha/opac-main.pl
(you can get there by editing the address bar of your web browser)
16. Observe "Log in to your account" page, ie. you have been kicked out
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
it was missing the dataFilter. Also needs coded_values to work correctly
(which needs to be defined outside of document.ready).
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch removes a trivially not required DB object instantiation.
This implies saving CPU usage for the instantiation and algo for
fetching from the DB.
To test:
1. Run:
$ ktd --shell
k$ prove t/db_dependent/Koha/Item/Transfer.t
=> SUCCESS: Tests pass! They cover ->receive()
2. Apply this patch
3. Repeat 1
=> SUCCESS: No behavior change, tests pass!
4. Sign off :-D
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Extends the CSS-based separator approach to field 856 (Electronic Location
and Access) which was still using hardcoded pipe separators.
This completes the conversion of all major repeatable fields in the staff
interface to use consistent CSS-based separators, matching the OPAC
implementation from Bug 27613.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Extends the CSS-based separator approach to additional repeatable fields
that were using hardcoded pipe separators:
- Content type (336)
- Media type (337)
- Carrier type (338)
- Awards (586)
- Production credits (508)
This provides consistent behavior and customization options across
all major repeatable fields in the staff interface, matching the
approach used for classification fields.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch changes the classification display from hardcoded pipe
separators to CSS pseudo-elements, following the same approach as
Bug 27613 for the OPAC.
Changes:
- Wrap each field occurrence in <li> elements within <ul>
- Remove hardcoded delimeter parameter from subfieldSelect
- Add CSS rules to display pipe separators via ::after pseudo-elements
- LOC classification (050)
- Publisher number (028)
- DDC classification (082)
- NLM classification (060)
- Other classification (084)
This allows libraries to customize the separator display via CSS.
It also provides consistent behavior and customization options across
all repeatable classification fields in the staff interface.
To test:
1. Create a record with multiple 050 fields:
050 4 $aE337.5 $b.O54 2025
050 4 $aE415.7 $b.A44 2025
2. View the record in staff interface
=> SUCCESS: Classification looks ok:
```
E337.5 .O54 2025 | E415.7 .A44 2025
```
3. Apply this patch
4. Run:
$ ktd --shell
k$ yarn build
5. Refresh the page
=> SUCCESS: It still looks correct!
6. Sign off :-D
Extends the CSS-based separator approach to all classification fields
that were using hardcoded pipe separators:
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Make edi_order lowercase so that matching is case insensitive.
Signed-off-by: Laura_Escamilla <laura.escamilla@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Test plan:
1) Choose an existing patron and note their first and second names as well as their date of birth
2) In the interface, create a new patron and enter all of those details to be the same as your patron from step 1
3) Submit the form, you will get a warning saying that there is a duplicate
4) In the OPAC, self register a new patron using the same details again
5) The form should submit with no error or warning
6) Apply patch, yarn api:bundle and restart_all
7) Repeat steps 2 - 5
8) Step 3 should still have the same behaviour
9) Step 5 should now show a warning at the top to say that there is a duplicate, please contact a member of staff
10) Find the 'PatronDuplicateMatchingAddFields' syspref and select an extra field there, ensuring that your patron from step 1 has data for that field
11) In either the interface or the OPAC, register a new patron but this time change the data of the new field you added in step 10
12) No warning should show for a duplicate patron
13) prove t/db_dependent/api/v1/patrons.t
14) prove t/db_dependent/Koha/Patrons.t
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pamela Bird <pbird@cityofchesapeake.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pamela Bird <pbird@cityofchesapeake.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pamela Bird <pbird@cityofchesapeake.net>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>