Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product templates and extra stock management features #1674

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6011d2e
Started to add optional supplier functionality to person records. #1659
adamdspencer77 Feb 7, 2025
4b1a582
Created product and related lookups. #1659
adamdspencer77 Feb 13, 2025
7f884c5
Prototype stock movement panel complete. #1659
adamdspencer77 Feb 19, 2025
bec847e
Added stock_movement.js to git. #1659
adamdspencer77 Feb 19, 2025
2f8e1bc
Made some SQL tweaks. #1659
adamdspencer77 Feb 19, 2025
d33cd01
Debugged. Added options for defining defaults to options and change u…
adamdspencer77 Feb 20, 2025
9cf8c04
Tidied up code. Added direct links from product to individual product…
adamdspencer77 Feb 23, 2025
9bc7703
Added links from movements to products. #1659
adamdspencer77 Feb 23, 2025
57d1b24
Checkboxes are ticked when opening a product directly via URL. #1659
adamdspencer77 Feb 24, 2025
164439e
Testing dbupdate code. #1659
adamdspencer77 Feb 24, 2025
4623f8b
Moved stock menu items into Financial menu under Stock control headin…
adamdspencer77 Feb 24, 2025
99798cb
Added option to handle minimum stock levels globally. When enabled 'L…
adamdspencer77 Feb 25, 2025
e2967c0
Added global minimum functionality. Fixed bugs. #1659
adamdspencer77 Feb 25, 2025
a83dc09
Added low global stock levels to alerts. #1659
adamdspencer77 Feb 25, 2025
08cac38
Added low stock alerts. Fixed bugs. #1659
adamdspencer77 Feb 25, 2025
79f1e33
Tidied up code following feedback. More bug fixes. #1659
adamdspencer77 Feb 26, 2025
cf87194
Added unit tests. #1659
adamdspencer77 Feb 27, 2025
ad7eeb1
Working through issues with unit tests. #1659
adamdspencer77 Feb 27, 2025
fd0f957
Completed unit test. #1659
adamdspencer77 Feb 27, 2025
138a163
Fixed bug preventing global minima defaulting to 0. #1659
adamdspencer77 Feb 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,588 changes: 911 additions & 677 deletions po/asm.pot

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/asm3/animal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,7 @@ def get_alerts(dbo: Database, lf: LocationFilter = None, age: int = 120) -> Resu
"(SELECT COUNT(*) FROM stocklevel WHERE Balance > 0 AND Expiry Is Not Null AND Expiry > %(today)s AND Expiry <= %(futuremonth)s) AS stexpsoon, " \
"(SELECT COUNT(*) FROM stocklevel WHERE Balance > 0 AND Expiry Is Not Null AND Expiry <= %(today)s) AS stexp, " \
"(SELECT COUNT(*) FROM stocklevel WHERE Balance < Low) AS stlowbal, " \
"(SELECT COUNT(*) FROM product WHERE (SELECT SUM(stocklevel.Balance) FROM stocklevel WHERE stocklevel.ProductID = product.ID) <= product.GlobalMinimum) AS globallows, " \
"(SELECT COUNT(*) FROM animaltransport WHERE (DriverOwnerID = 0 OR DriverOwnerID Is Null) AND Status < 10) AS trnodrv, " \
"(SELECT COUNT(*) FROM animal LEFT OUTER JOIN internallocation il ON il.ID = animal.ShelterLocation " \
"WHERE Archived = 0 AND HasPermanentFoster = 0 AND DaysOnShelter > %(longterm)s %(locfilter)s) AS lngterm, " \
Expand Down
3 changes: 3 additions & 0 deletions src/asm3/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,9 @@ def pdf_zoom(dbo: Database) -> int:
def person_search_columns(dbo: Database) -> str:
return cstring(dbo, "OwnerSearchColumns", DEFAULTS["OwnerSearchColumns"])

def product_movement_usage_type(dbo: Database) -> int:
return cint(dbo, "StockMovementUsageTypeID", 1)

def event_search_columns(dbo: Database) -> str:
return cstring(dbo, "EventSearchColumns", DEFAULTS["EventSearchColumns"])

Expand Down
183 changes: 176 additions & 7 deletions src/asm3/dbupdate.py

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions src/asm3/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,6 @@ def menu_structure(l: str, publisherlist: Dict, reports: MenuItems, mailmerges:
)),
("", "financial", _("Financial", l), (
( asm3.users.VIEW_ACCOUNT, "alt+shift+x", "tagaccounts", "accounts", "asm-icon-accounts", _("Accounts", l) ),
( asm3.users.VIEW_STOCKLEVEL, "", "tagstock", "stocklevel", "asm-icon-stock", _("Stock", l) ),
( asm3.users.VIEW_VOUCHER, "", "", "voucher", "asm-icon-blank", _("Voucher book", l) ),
( asm3.users.VIEW_BOARDING, "", "tagboarding", "--cat", "", _("Boarding", l) ),
( asm3.users.VIEW_BOARDING, "", "tagboarding", "boarding", "asm-icon-boarding", _("Boarding book", l) ),
Expand All @@ -625,7 +624,11 @@ def menu_structure(l: str, publisherlist: Dict, reports: MenuItems, mailmerges:
( asm3.users.VIEW_DONATION, "", "", "calendarview?ev=p", "asm-icon-calendar", _("Payment calendar", l) ),
( asm3.users.ADD_DONATION, "", "", "donation_receive", "asm-icon-blank", _("Receive a payment", l) ),
( asm3.users.VIEW_DONATION, "", "taggb", "--cat", "", "HMRC" ),
( asm3.users.VIEW_DONATION, "", "taggb", "giftaid_hmrc_spreadsheet", "asm-icon-report", "Generate HMRC Gift Aid spreadsheet" )
( asm3.users.VIEW_DONATION, "", "taggb", "giftaid_hmrc_spreadsheet", "asm-icon-report", "Generate HMRC Gift Aid spreadsheet" ),
( asm3.users.VIEW_DONATION, "", "", "--cat", "", _("Stock control", l) ),
( asm3.users.VIEW_STOCKLEVEL, "", "", "product", "asm-icon-stock", _("Products", l) ),
( asm3.users.VIEW_STOCKLEVEL, "", "tagstock", "stocklevel", "asm-icon-stock", _("Stock levels", l) ),
( asm3.users.VIEW_STOCKLEVEL, "", "tastock", "stock_movement", "asm-icon-stock", _("Stock movements", l) )
)),
(asm3.users.USE_INTERNET_PUBLISHER, "publishing", _("Publishing", l), [
("", "", "", "--cat", "asm-icon-settings", _("Configuration", l) ),
Expand Down
31 changes: 28 additions & 3 deletions src/asm3/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"lksmovementtype": (_("Movement Types"), "MovementType", _("Type"), "", "", ("adoption.MovementType", "animal.ActiveMovementType",)),
"lksoutcome": (_("Outcomes"), "Outcome", _("Outcome"), "", "", ""),
"lkownerflags": (_("Person Flags"), "Flag", _("Flag"), "", "add del ret", ""),
"lkproducttype": (_("Product Types"), "ProductTypeName", _("Name"), _("Description"), "add del ret", ""),
"lksrotatype": (_("Rota Types"), "RotaType", _("Type"), "", "", ("ownerrota.RotaTypeID",)),
"lksex": (_("Sexes"), "Sex", _("Sex"), "", "", ("animal.Sex", "animallost.Sex", "animalfound.Sex")),
"lksize": (_("Sizes"), "Size", _("Size"), "", "", ("animal.Size",)),
Expand All @@ -68,6 +69,7 @@
"stocklocation": (_("Stock Locations"), "LocationName", _("Location"), "LocationDescription", "add del ret", ("stocklevel.StockLocationID",)),
"stockusagetype": (_("Stock Usage Type"), "UsageTypeName", _("Usage Type"), "UsageTypeDescription", "add del ret", ("stockusage.StockUsageTypeID",)),
"lkurgency": (_("Urgencies"), "Urgency", _("Urgency"), "", "", ("animalwaitinglist.Urgency",)),
"lktaxrate": (_("Tax Rate"), "TaxRateName", _("Name"), _("Description"), "add del ret", ("lktaxrate.TaxRate",)),
"testtype": (_("Test Types"), "TestName", _("Type"), "TestDescription", "add del ret cost sched", ("animaltest.TestTypeID",)),
"testresult": (_("Test Results"), "ResultName", _("Result"), "ResultDescription", "add del ret", ("animaltest.TestResultID",)),
"lkstransportstatus": (_("Transport Statuses"), "Name", _("Status"), "", "", ("animaltransport.Status",)),
Expand Down Expand Up @@ -805,7 +807,7 @@ def _merge_db_flags(dbflags: Results, flags: str = "") -> Results:
"""
BUILTINS = [ "aco", "adopter", "banned", "coordinator", "dangerous", "deceased", "donor", "driver",
"excludefrombulkemail", "fosterer", "giftaid", "homechecked", "homechecker", "member", "padopter",
"retailer", "shelter", "staff", "sponsor", "vet", "volunteer",
"retailer", "shelter", "staff", "sponsor", "vet", "volunteer", "supplier",
"courtesy", "crueltycase", "nonshelter", "notforadoption", "notforregistration", "quarantine" ]
if flags is None or flags == "" or flags == "|": return dbflags
out = dbflags.copy()
Expand Down Expand Up @@ -992,7 +994,7 @@ def get_lookup(dbo: Database, tablename: str, namefield: str) -> Results:
def insert_lookup(dbo: Database, username: str, lookup: str, name: str, desc: str = "",
speciesid: int = 0, pfbreed: str = "", pfspecies: str = "", apcolour: str = "",
units: str = "", site: int = 1, rescheduledays: int = 0, accountid: int = 0,
defaultcost: int = 0, vat: int = 0, retired: int = 0) -> int:
defaultcost: int = 0, vat: int = 0, retired: int = 0, taxrate: float = 0) -> int:
t = LOOKUP_TABLES[lookup]
nid = 0
if lookup == "basecolour":
Expand Down Expand Up @@ -1073,6 +1075,13 @@ def insert_lookup(dbo: Database, username: str, lookup: str, name: str, desc: st
t[LOOKUP_NAMEFIELD]: name,
"IsRetired": retired
}, username, setCreated=False)
elif lookup == "lktaxrate":
return dbo.insert(lookup, {
t[LOOKUP_NAMEFIELD]: name,
t[LOOKUP_DESCFIELD]: desc,
"TaxRate": taxrate,
"IsRetired": retired
}, username, setCreated=False)
elif t[LOOKUP_DESCFIELD] == "":
# No description
if t[LOOKUP_MODIFIERS].find("ret") != -1:
Expand All @@ -1089,7 +1098,7 @@ def insert_lookup(dbo: Database, username: str, lookup: str, name: str, desc: st
def update_lookup(dbo: Database, username: str, iid: int, lookup: str, name: str, desc: str = "",
speciesid: int = 0, pfbreed: str = "", pfspecies: str = "", apcolour: str = "", units: str = "",
site: int = 1, rescheduledays: int = 0, accountid: int = 0,
defaultcost: int = 0, vat: int = 0, retired: int = 0) -> None:
defaultcost: int = 0, vat: int = 0, retired: int = 0, taxrate: float = 0) -> None:
t = LOOKUP_TABLES[lookup]
if lookup == "basecolour":
dbo.update("basecolour", iid, {
Expand Down Expand Up @@ -1163,6 +1172,13 @@ def update_lookup(dbo: Database, username: str, iid: int, lookup: str, name: str
dbo.execute("UPDATE owner SET AdditionalFlags = %s WHERE AdditionalFlags LIKE ?" % dbo.sql_replace("AdditionalFlags"), (f"{oldflag}|", f"{newflag}|", f"%{oldflag}|%"))
elif lookup == "lkanimalflags":
dbo.execute("UPDATE animal SET AdditionalFlags = %s WHERE AdditionalFlags LIKE ?" % dbo.sql_replace("AdditionalFlags"), (f"{oldflag}|", f"{newflag}|", f"%{oldflag}|%"))
elif lookup == "lktaxrate":
dbo.update(lookup, iid, {
t[LOOKUP_NAMEFIELD]: name,
t[LOOKUP_DESCFIELD]: desc,
"TaxRate": taxrate,
"IsRetired": retired
}, username, setLastChanged=False)
elif t[LOOKUP_DESCFIELD] == "":
# No description
if t[LOOKUP_MODIFIERS].find("ret") != -1:
Expand Down Expand Up @@ -1265,6 +1281,9 @@ def get_pickup_locations(dbo: Database) -> Results:
def get_posneg(dbo: Database) -> Results:
return dbo.query("SELECT * FROM lksposneg ORDER BY Name")

def get_product_types(dbo: Database) -> Results:
return dbo.query("SELECT * FROM lkproducttype ORDER BY ProductTypeName")

def get_reservation_statuses(dbo: Database) -> Results:
return dbo.query("SELECT * FROM reservationstatus ORDER BY StatusName")

Expand Down Expand Up @@ -1325,13 +1344,19 @@ def get_stock_usage_types(dbo: Database) -> Results:
def get_trap_types(dbo: Database) -> Results:
return dbo.query("SELECT * FROM traptype ORDER BY TrapTypeName")

def get_unit_types(dbo: Database) -> Results:
return dbo.query("SELECT * FROM lksunittype ORDER BY ID")

def get_urgencies(dbo: Database) -> Results:
return dbo.query("SELECT * FROM lkurgency ORDER BY ID")

def get_urgency_name(dbo: Database, uid: int) -> str:
if id is None: return ""
return dbo.query_string("SELECT Urgency FROM lkurgency WHERE ID = ?", [uid])

def get_tax_rates(dbo: Database) -> Results:
return dbo.query("SELECT * FROM lktaxrate ORDER BY TaxRateName")

def get_test_types(dbo: Database) -> Results:
return dbo.query("SELECT * FROM testtype ORDER BY TestName")

Expand Down
16 changes: 11 additions & 5 deletions src/asm3/person.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,8 @@ def get_person_find_simple(dbo: Database, query: str, username: str = "", classf
"member": " AND o.IsMember = 1",
"donor": " AND o.IsDonor = 1",
"driver": " AND o.IsDriver = 1",
"sponsor": " AND o.IsSponsor = 1"
"sponsor": " AND o.IsSponsor = 1",
"supplier": " AND o.IsSupplier = 1"
}
typefilters = {
"": "",
Expand Down Expand Up @@ -723,6 +724,7 @@ def get_person_find_advanced(dbo: Database, criteria: Dict[str, str], username:
elif flag == "giftaid": ss.ands.append("o.IsGiftAid=1")
elif flag == "vet": ss.ands.append("o.IsVet=1")
elif flag == "volunteer": ss.ands.append("o.IsVolunteer=1")
elif flag == "supplier": ss.ands.append("o.IsSupplier=1")
elif flag == "padopter": ss.ands.append("EXISTS(SELECT OwnerID FROM adoption WHERE OwnerID = o.ID AND MovementType=1)")
else:
ss.ands.append("LOWER(o.AdditionalFlags) LIKE ?")
Expand Down Expand Up @@ -1098,6 +1100,7 @@ def insert_person_from_form(dbo: Database, post: PostedData, username: str, geoc
"IsVet": 0,
"IsGiftAid": 0,
"IsSponsor": 0,
"IsSupplier": 0,
"AdditionalFlags": "|"
}, username, generateID=False)

Expand Down Expand Up @@ -1310,6 +1313,7 @@ def bi(b):
retailer = bi("retailer" in flags)
vet = bi("vet" in flags)
giftaid = bi("giftaid" in flags)
supplier = bi("supplier" in flags)
excludefrombulkemail = bi("excludefrombulkemail" in flags)
sponsor = bi("sponsor" in flags)
flagstr = "|".join(sorted(flags)) + "|"
Expand Down Expand Up @@ -1342,6 +1346,7 @@ def bi(b):
"IsVet": vet,
"IsSponsor": sponsor,
"IsGiftAid": giftaid,
"IsSupplier": supplier,
"AdditionalFlags": flagstr
}, username)

Expand Down Expand Up @@ -2044,11 +2049,12 @@ def update_check_flags(dbo: Database) -> str:
"retailer": "IsRetailer",
"vet": "IsVet",
"giftaid": "IsGiftAid",
"sponsor": "IsSponsor"
"sponsor": "IsSponsor",
"supplier": "IsSupplier"
}
people = dbo.query("SELECT ID, AdditionalFlags, ExcludeFromBulkEmail, IDCheck, IsBanned, IsDangerous, IsVolunteer, " \
"IsHomeChecker, IsMember, IsAdopter, IsAdoptionCoordinator, IsDonor, IsDriver, " \
"IsShelter, IsACO, IsStaff, IsFosterer, IsRetailer, IsVet, IsGiftAid, IsSponsor FROM owner ORDER BY ID")
"IsShelter, IsACO, IsStaff, IsFosterer, IsRetailer, IsVet, IsGiftAid, IsSponsor, IsSupplier FROM owner ORDER BY ID")
lookupflags = [x["FLAG"] for x in dbo.query("SELECT Flag from lkownerflags ORDER BY Flag")]
batch = []
asm3.asynctask.set_progress_max(dbo, len(people))
Expand Down Expand Up @@ -2118,7 +2124,7 @@ def remove_people_only_cancelled_reserve(dbo: Database, years: int = None, usern
return
cutoff = dbo.today(offset=-365 * retainyears)
people = dbo.query("SELECT ID FROM owner WHERE "
"MatchActive=0 AND IsACO=0 AND IsAdoptionCoordinator=0 AND IsRetailer=0 AND IsHomeChecker=0 AND IsMember=0 AND IsDriver=0 " \
"MatchActive=0 AND IsACO=0 AND IsAdoptionCoordinator=0 AND IsRetailer=0 AND IsHomeChecker=0 AND IsMember=0 AND IsDriver=0 AND IsSupplier=0 " \
"AND IsShelter=0 AND IsFosterer=0 AND IsStaff=0 AND IsVet=0 AND IsVolunteer=0 AND IsAdopter=0 AND IsBanned=0 " \
"AND EXISTS(SELECT ID FROM adoption WHERE OwnerID = owner.ID AND MovementType = 0) " \
"AND NOT EXISTS(SELECT ID FROM adoption WHERE OwnerID = owner.ID AND MovementType > 0) " \
Expand Down Expand Up @@ -2162,7 +2168,7 @@ def update_anonymise_personal_data(dbo: Database, years: int = None, username: s
people = dbo.query_named_params("SELECT ID FROM owner " \
"WHERE OwnerSurname <> :anonymised AND CreatedDate <= :cutoff " \
"AND IsACO=0 AND IsAdoptionCoordinator=0 AND IsRetailer=0 AND IsHomeChecker=0 AND IsMember=0 AND IsDriver=0 " \
f"AND IsShelter=0 AND IsFosterer=0 AND IsStaff=0 AND IsVet=0 AND IsVolunteer=0 {adopterclause} " \
f"AND IsShelter=0 AND IsFosterer=0 AND IsStaff=0 AND IsVet=0 AND IsVolunteer=0 AND IsSupplier=0 {adopterclause} " \
"AND NOT EXISTS(SELECT ID FROM animal WHERE (OriginalOwnerID = owner.ID OR BroughtInByOwnerID = owner.ID) AND DateBroughtIn > :cutoff) " \
"AND NOT EXISTS(SELECT ID FROM animalboarding WHERE OwnerID = owner.ID AND OutDateTime > :cutoff) " \
"AND NOT EXISTS(SELECT ID FROM animalcontrol WHERE (CallerID = owner.ID OR VictimID = owner.ID OR OwnerID = owner.ID OR Owner2ID = owner.ID OR Owner3ID = owner.ID) AND IncidentDateTime > :cutoff) " \
Expand Down
Loading