def ar(rlist, rtype, sortfield): # Return brief records if rtype == "ANIMAL": rlist = animal.get_animals_brief(rlist) if rtype == "PERSON": pass # TODO: for r in rlist: r["RESULTTYPE"] = rtype if sortfield == "RELEVANCE": # How "relevant" is this record to what was searched for? # animal name and code weight higher than other elements. # Note that the code below modifies inbound var q, so by the # time we read it here, it should only contain the search term # itself. Weight everything else by last changed date so there # is some semblance of useful order for less relevant items r["SORTON"] = r["LASTCHANGEDDATE"] qlow = q.lower() if rtype == "ANIMAL": if r["ANIMALNAME"].lower() == qlow or r["SHELTERCODE"].lower() == qlow or r["SHORTCODE"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["ANIMALNAME"].lower().find(qlow) != -1 or r["SHELTERCODE"].lower().find(qlow) != -1 or r["SHORTCODE"].lower().find(qlow) != -1: r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "PERSON": if r["OWNERSURNAME"].lower() == qlow or r["OWNERNAME"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["OWNERSURNAME"].lower().find(qlow) or r["OWNERNAME"].lower().find(qlow): r["SORTON"] = now() - datetime.timedelta(seconds=1) else: r["SORTON"] = r[sortfield] results.append(r)
def insert_waitinglist_from_form(dbo, data, username): """ Creates a waiting list record from the screen data: The webpy data object containing form parameters """ l = dbo.locale if utils.df_ks(data, "description") == "": raise utils.ASMValidationError(_("Description cannot be blank", l)) if utils.df_ki(data, "owner") == "0": raise utils.ASMValidationError(_("Waiting list entries must have a contact", l)) if utils.df_ks(data, "dateputon") == "": raise utils.ASMValidationError(_("Date put on cannot be blank", l)) nwlid = db.get_id(dbo, "animalwaitinglist") db.execute(dbo, db.make_insert_user_sql(dbo, "animalwaitinglist", username, ( ( "ID", db.di(nwlid)), ( "SpeciesID", utils.df_s(data, "species")), ( "DatePutOnList", utils.df_d(data, "dateputon", l)), ( "OwnerID", utils.df_s(data, "owner")), ( "AnimalDescription", utils.df_t(data, "description")), ( "ReasonForWantingToPart", utils.df_t(data, "reasonforwantingtopart")), ( "CanAffordDonation", utils.df_c(data, "canafforddonation")), ( "Urgency", utils.df_s(data, "urgency")), ( "DateRemovedFromList", utils.df_d(data, "dateremoved", l)), ( "AutoRemovePolicy", utils.df_s(data, "autoremovepolicy")), ( "DateOfLastOwnerContact", db.dd(now(dbo.timezone))), ( "ReasonForRemoval", utils.df_t(data, "reasonforremoval")), ( "Comments", utils.df_t(data, "comments")), ( "UrgencyLastUpdatedDate", db.dd(now(dbo.timezone))), ( "UrgencyUpdateDate", db.dd(add_days(now(dbo.timezone), configuration.waiting_list_urgency_update_period(dbo)))) ))) audit.create(dbo, username, "animalwaitinglist", str(nwlid)) return nwlid
def update_user_activity(dbo, user, timenow = True): """ If timenow is True, updates this user's last activity time to now. If timenow is False, removes this user from the active list. """ if dbo is None or user is None: return cachekey = "%s_activity" % dbo.database ac = utils.nulltostr(cachemem.get(cachekey)) # Prune old activity and remove the current user nc = [] for a in ac.split(","): # If there are any errors reading or parsing # the entry, skip it try: if a != "": u, d = a.split("=") # if the last seen value was more than an hour ago, # don't bother adding that user p = i18n.parse_date("%Y-%m-%d %H:%M:%S", d) if i18n.subtract_hours(i18n.now(dbo.timezone), 1) > p: continue # Don't add the current user if u == user: continue nc.append(a) except: continue # Add this user with the new time if timenow: nc.append("%s=%s" % (user, i18n.format_date("%Y-%m-%d %H:%M:%S", i18n.now(dbo.timezone)))) cachemem.put(cachekey, ",".join(nc), 3600 * 8)
def get_completed_upto_today(dbo, user = ""): """ Gets a list of completed diary notes upto and including today for the user supplied (or all users if no user passed) LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO """ sixmonths = i18n.subtract_days(i18n.now(dbo.timezone), 182) return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \ "FROM diary WHERE %s " \ "AND DateCompleted Is Not Null AND DiaryDateTime <= %s AND DiaryDateTime >= %s" \ "ORDER BY DiaryDateTime DESC" % (user_role_where_clause(dbo, user), db.ddt(i18n.now(dbo.timezone)), db.ddt(sixmonths)))
def jqm_options_next_month(l): d = now() days = [] for dummy in xrange(0, 31): days.append(jqm_option(python2display(l, d))) d = add_days(d, 1) d = add_months(now(), 3) days.append(jqm_option(python2display(l, d))) d = add_months(now(), 6) days.append(jqm_option(python2display(l, d))) d = add_years(now(), 1) days.append(jqm_option(python2display(l, d))) return "\n".join(days)
def get_uncompleted_upto_today(dbo, user = "", includecreatedby = True): """ Gets a list of uncompleted diary notes upto and including today for the user supplied (or all users if no user passed) LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO """ sixmonths = i18n.subtract_days(i18n.now(dbo.timezone), 182) current = i18n.now(dbo.timezone) alltoday = datetime.datetime(current.year, current.month, current.day, 23, 59, 59) return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \ "FROM diary WHERE %s " \ "AND DateCompleted Is Null AND DiaryDateTime <= %s AND DiaryDateTime >= %s" \ "ORDER BY DiaryDateTime DESC" % (user_role_where_clause(dbo, user, includecreatedby), db.ddt(alltoday), db.ddt(sixmonths)))
def insert_animalcontrol(dbo, username): """ Creates a new animal control incident record and returns the id """ l = dbo.locale d = { "incidentdate": python2display(l, now(dbo.timezone)), "incidenttime": format_time_now(dbo.timezone), "incidenttype": configuration.default_incident(dbo), "calldate": python2display(l, now(dbo.timezone)), "calltime": format_time_now(dbo.timezone), "calltaker": username } return insert_animalcontrol_from_form(dbo, utils.PostedData(d, dbo.locale), username)
def auto_cancel_reservations(dbo): """ Automatically cancels reservations after the daily amount set """ cancelafter = configuration.auto_cancel_reserves_days(dbo) if cancelafter <= 0: al.debug("auto reserve cancel is off.", "movement.auto_cancel_reservations") return cancelcutoff = i18n.subtract_days(i18n.now(dbo.timezone), cancelafter) al.debug("cutoff date: reservations < %s" % db.dd(cancelcutoff), "movement.auto_cancel_reservations") sql = "UPDATE adoption SET ReservationCancelledDate = %s " \ "WHERE MovementDate Is Null AND ReservationCancelledDate Is Null AND " \ "MovementType = 0 AND ReservationDate < %s" % ( db.dd(i18n.now(dbo.timezone)), db.dd(cancelcutoff)) count = db.execute(dbo, sql) al.debug("cancelled %d reservations older than %d days" % (count, int(cancelafter)), "movement.auto_cancel_reservations", dbo)
def create_waitinglist(dbo, username, collationid): """ Creates a waitinglist record from the incoming form data with collationid. Also, attaches the form to the waiting list as media. """ l = dbo.locale fields = get_onlineformincoming_detail(dbo, collationid) d = {} d["dateputon"] = i18n.python2display(l, i18n.now(dbo.timezone)) d["urgency"] = "5" for f in fields: if f["FIELDNAME"] == "species": d["species"] = guess_species(dbo, f["VALUE"]) if f["FIELDNAME"] == "description": d["description"] = f["VALUE"] if f["FIELDNAME"] == "reason": d["reasonforwantingtopart"] = f["VALUE"] if not d.has_key("species"): d["species"] = guess_species(dbo, "") # Have we got enough info to create the waiting list record? We need a description if not d.has_key("description"): raise utils.ASMValidationError(i18n._("There is not enough information in the form to create a waiting list record (need a description).", l)) # We need the person record before we create the waiting list collationid, personid, personname = create_person(dbo, username, collationid) d["owner"] = personid # Create the waiting list wlid = waitinglist.insert_waitinglist_from_form(dbo, d, username) # Attach the form to the waiting list formname = get_onlineformincoming_name(dbo, collationid) formhtml = get_onlineformincoming_html(dbo, collationid) media.create_document_media(dbo, username, media.WAITINGLIST, wlid, formname, formhtml ) return (collationid, wlid, utils.padleft(wlid, 6) + " - " + personname)
def execute_diary_task(dbo, username, tasktype, taskid, linkid, selecteddate): """ Runs a diary task tasktype: ANIMAL or PERSON taskid: The ID of the diarytaskhead record to run linkid: The ID of the animal or person to run against selecteddate: If the task has any detail records with a pivot of 0, the date to supply (as python date) """ def fix(s): return s.replace("<", "<").replace(">", ">") rollingdate = i18n.now(dbo.timezone) dtd = db.query(dbo, "SELECT * FROM diarytaskdetail WHERE DiaryTaskHeadID = %d ORDER BY ID" % int(taskid)) tags = {} linktype = ANIMAL if tasktype == "ANIMAL": linktype = ANIMAL tags = wordprocessor.animal_tags(dbo, animal.get_animal(dbo, int(linkid))) elif tasktype == "PERSON": linktype = PERSON tags = wordprocessor.person_tags(dbo, person.get_person(dbo, int(linkid))) for d in dtd: if d["DAYPIVOT"] == 9999: rollingdate = selecteddate else: rollingdate = i18n.add_days(rollingdate, int(d["DAYPIVOT"])) insert_diary(dbo, username, linktype, int(linkid), rollingdate, \ d["WHOFOR"], \ wordprocessor.substitute_tags(fix(d["SUBJECT"]), tags, True), \ wordprocessor.substitute_tags(fix(d["NOTE"]), tags, True))
def get_lostanimal_find_simple(dbo, query = "", limit = 0): """ Returns rows for simple lost animal searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show unfound lost animal records # for the last 30 days if query == "": ors.append("a.DateLost > %s AND a.DateFound Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("o.OwnerName")) ors.append(add("a.AreaLost")) ors.append(add("a.AreaPostcode")) ors.append(u"EXISTS(SELECT ad.Value FROM additional ad " \ "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \ "WHERE ad.LinkID=a.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE '%%%s%%')" % (additional.LOSTANIMAL_IN, query.lower())) if not dbo.is_large_db: ors.append(add("x.Sex")) ors.append(add("b.BreedName")) ors.append(add("c.BaseColour")) ors.append(add("s.SpeciesName")) ors.append(add("a.AgeGroup")) ors.append(add("a.DistFeat")) ors.append(add("a.Comments")) sql = get_lostanimal_query(dbo) + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def get_lostanimal_find_simple(dbo, query = "", limit = 0, onlyindexed = False): """ Returns rows for simple lost animal searches. query: The search criteria """ ors = [] query = query.replace("'", "`") def add(field): return utils.where_text_filter(dbo, field, query) # If no query has been given, show unfound lost animal records # for the last 30 days if query == "": ors.append("a.DateLost > %s AND a.DateFound Is Null" % db.dd(subtract_days(now(dbo.timezone), 30))) else: if utils.is_numeric(query): ors.append("a.ID = " + str(utils.cint(query))) ors.append(add("OwnerName")) ors.append(add("AreaLost")) ors.append(add("AreaPostcode")) if not onlyindexed: ors.append(add("SexName")) ors.append(add("BreedName")) ors.append(add("BaseColourName")) ors.append(add("SpeciesName")) ors.append(add("AgeGroup")) ors.append(add("DistFeat")) ors.append(add("Comments")) sql = get_lostanimal_query() + " WHERE " + " OR ".join(ors) if limit > 0: sql += " LIMIT " + str(limit) return db.query(dbo, sql)
def auto_logout(dbo): """ Marks all users logged out who have been logged in for longer than 8 hours to account for people not logging out manually. """ cutoff = i18n.now() - datetime.timedelta(hours = -8) db.execute(dbo, "DELETE FROM activeuser WHERE Since <= %s" % db.dd(cutoff))
def make_insert_user_sql(dbo, table, username, s, stampRecordVersion = True): """ Creates insert sql for a user, 'table' is the table name, username is the name of the user to be stamped in the fields 's' is a tuple of tuples containing the field names and values, eg: make_insert_user_sql("animal", "jeff", ( ( "ID", di(52) ), ( "AnimalName", ds("Indy") ) )) """ l = list(s) l.append(("CreatedBy", ds(username))) l.append(("CreatedDate", ddt(i18n.now(dbo.timezone)))) l.append(("LastChangedBy", ds(username))) l.append(("LastChangedDate", ddt(i18n.now(dbo.timezone)))) if stampRecordVersion: l.append(("RecordVersion", di(recordversion()))) return make_insert_sql(table, l)
def gkd(dbo, m, f, usetoday = False): """ reads field f from map m, returning a display date. string is empty if key not present or date is invalid. If usetoday is set to True, then today's date is returned if the date is blank. """ if not m.has_key(f): return "" lv = str(m[f]) # If there's a space, then I guess we have time info - throw it away if lv.find(" ") > 0: lv = lv[0:lv.find(" ")] # Now split it by either / or - b = lv.split("/") if lv.find("-") != -1: b = lv.split("-") # We should have three date bits now if len(b) != 3: # We don't have a valid date, if use today is on return that if usetoday: return i18n.python2display(dbo.locale, i18n.now(dbo.timezone)) else: return "" else: # Which of our 3 bits is the year? if utils.cint(b[0]) > 1900: # it's Y/M/D d = datetime.datetime(utils.cint(b[0]), utils.cint(b[1]), utils.cint(b[2])) elif dbo.locale == "en": # Assume it's M/D/Y for US d = datetime.datetime(utils.cint(b[2]), utils.cint(b[0]), utils.cint(b[1])) else: # Assume it's D/M/Y d = datetime.datetime(utils.cint(b[2]), utils.cint(b[1]), utils.cint(b[0])) return i18n.python2display(dbo.locale, d)
def insert_reserve_for_animal_name(dbo, username, personid, animalname): """ Creates a reservation for the animal with animalname to personid. animalname can either be just the name of a shelter animal, or it can be in the form name::code. If a code is present, that will be used to locate the animal. """ l = dbo.locale if animalname.find("::") != -1: animalcode = animalname.split("::")[1] aid = db.query_int(dbo, "SELECT ID FROM animal WHERE ShelterCode = %s ORDER BY ID DESC" % db.ds(animalcode)) else: aid = db.query_int(dbo, "SELECT ID FROM animal WHERE LOWER(AnimalName) LIKE '%s' ORDER BY ID DESC" % animalname.lower()) # Bail out if we couldn't find a matching animal if aid == 0: return move_dict = { "person" : str(personid), "animal" : str(aid), "reservationdate" : i18n.python2display(l, i18n.now(dbo.timezone)), "reservationstatus" : configuration.default_reservation_status(dbo), "movementdate" : "", "type" : str(NO_MOVEMENT), "returncategory" : configuration.default_return_reason(dbo) } return insert_movement_from_form(dbo, username, utils.PostedData(move_dict, l))
def create_animal_from_found(dbo, username, aid): """ Creates an animal record from a found animal with the id given """ a = db.query(dbo, "SELECT * FROM animalfound WHERE ID = %d" % int(aid))[0] l = dbo.locale data = { "animalname": _("Found Animal {0}", l).format(aid), "markings": str(a["DISTFEAT"]), "species": str(a["ANIMALTYPEID"]), "comments": str(a["COMMENTS"]), "broughtinby": str(a["OWNERID"]), "originalowner": str(a["OWNERID"]), "animaltype": configuration.default_type(dbo), "breed1": a["BREEDID"], "breed2": a["BREEDID"], "basecolour": str(a["BASECOLOURID"]), "size": configuration.default_size(dbo), "internallocation": configuration.default_location(dbo), "dateofbirth": python2display(l, subtract_years(now(dbo.timezone))), "estimateddob": "1", } # If we're creating shelter codes manually, we need to put something unique # in there for now. Use the id if configuration.manual_codes(dbo): data["sheltercode"] = "FA" + str(aid) data["shortcode"] = "FA" + str(aid) nextid, code = animal.insert_animal_from_form(dbo, data, username) return nextid
def update_vaccination_today(dbo, username, vaccid): """ Marks a vaccination record as given today. """ db.execute(dbo, db.make_update_user_sql(dbo, "animalvaccination", username, "ID = %d" % vaccid, ( ( "DateOfVaccination", db.dd(now(dbo.timezone)) ), None ) ))
def update_test_today(dbo, username, testid, resultid): """ Marks a test record as performed today. """ db.execute(dbo, db.make_update_user_sql(dbo, "animaltest", username, "ID = %d" % testid, ( ( "DateOfTest", db.dd(now(dbo.timezone)) ), ( "TestResultID", db.di(resultid) ) )))
def get_recent_transfers(dbo, months = 1): """ Returns a list of transfers in the last "months" months. """ return db.query(dbo, get_movement_query(dbo) + \ "WHERE m.MovementType = 3 AND m.MovementDate Is Not Null AND m.ReturnDate Is Null " \ "AND m.MovementDate > %s " \ "ORDER BY m.MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
def get_recent_transfers(dbo, months = 1): """ Returns a list of transfers in the last "months" months. """ return db.query(dbo, "SELECT * FROM v_adoption " \ "WHERE MovementType = 3 AND MovementDate Is Not Null AND ReturnDate Is Null " \ "AND MovementDate > %s " \ "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
def get_trial_adoptions(dbo, mode = "ALL"): """ Returns a list of trial adoption movements. If mode is EXPIRING, shows trials that end today or before. If mode is ACTIVE, shows trials that end after today. If mode is ALL, returns all trials. """ where = "" if mode == "ALL": where = "" elif mode == "EXPIRING": where = "AND TrialEndDate <= %s " % db.dd(i18n.now(dbo.timezone)) elif mode == "ACTIVE": where = "AND TrialEndDate > %s " % db.dd(i18n.now(dbo.timezone)) return db.query(dbo, "SELECT * FROM v_adoption " \ "WHERE IsTrial = 1 AND MovementType = 1 AND (ReturnDate Is Null OR ReturnDate > %s) %s" \ "ORDER BY TrialEndDate" % (db.dd(i18n.now(dbo.timezone)), where))
def get_recent_nonfosteradoption(dbo, months = 1): """ Returns a list of active movements that aren't reserves, fosters, adoptions or transfers in the last "months" months. """ return db.query(dbo, "SELECT * FROM v_adoption " \ "WHERE MovementType > 3 AND MovementDate Is Not Null AND ReturnDate Is Null " \ "AND MovementDate > %s " \ "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
def get_recent_unneutered_adoptions(dbo, months = 1): """ Returns a list of adoptions in the last "months" months where the animal remains unneutered. """ return db.query(dbo, "SELECT * FROM v_adoption " \ "WHERE MovementType = 1 AND MovementDate Is Not Null AND ReturnDate Is Null " \ "AND MovementDate > %s AND Neutered = 0 " \ "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
def receive_donation(dbo, username, did): """ Marks a donation received """ if id is None or did == "": return db.execute(dbo, "UPDATE ownerdonation SET Date = %s WHERE ID = %d" % ( db.dd(i18n.now(dbo.timezone)), int(did))) audit.edit(dbo, username, "ownerdonation", str(did) + ": received") update_matching_transaction(dbo, username, int(did)) check_create_next_donation(dbo, username, did)
def get_active_traploans(dbo): """ Returns all active traploan records ID, TRAPTYPEID, TRAPTYPENAME, LOANDATE, DEPOSITRETURNDATE, TRAPNUMBER, RETURNDUEDATE, RETURNDATE, OWNERNAME """ return db.query(dbo, get_traploan_query(dbo) + \ "WHERE ot.ReturnDate Is Null OR ot.ReturnDate > %s " \ "ORDER BY ot.LoanDate DESC" % db.dd(now(dbo.timezone)))
def get_movements(dbo, movementtype): """ Gets the list of movements of a particular type (unreturned or returned after today and for animals who aren't deceased) """ return db.query(dbo, get_movement_query(dbo) + \ "WHERE m.MovementType = %d AND " \ "(m.ReturnDate Is Null OR m.ReturnDate > %s) " \ "AND a.DeceasedDate Is Null " \ "ORDER BY m.MovementDate DESC" % (int(movementtype), db.dd(i18n.now(dbo.timezone))))
def auto_remove_waitinglist(dbo): """ Finds and automatically marks entries removed that have gone past the last contact date + weeks. """ l = dbo.locale rows = db.query(dbo, "SELECT a.ID, a.DateOfLastOwnerContact, " \ "a.AutoRemovePolicy " \ "FROM animalwaitinglist a WHERE a.DateRemovedFromList Is Null " \ "AND AutoRemovePolicy > 0 AND DateOfLastOwnerContact Is Not Null") updates = [] for r in rows: xdate = add_days(r["DATEOFLASTOWNERCONTACT"], 7 * r["AUTOREMOVEPOLICY"]) if after(now(dbo.timezone), xdate): al.debug("auto removing waitinglist entry %d due to policy" % int(r["ID"]), "waitinglist.auto_remove_waitinglist", dbo) updates.append((now(dbo.timezone), _("Auto removed due to lack of owner contact.", l), r["ID"])) if len(updates) > 0: db.execute_many(dbo, "UPDATE animalwaitinglist SET DateRemovedFromList = %s, " \ "ReasonForRemoval=%s WHERE ID=%s", updates)
def get_future(dbo, user = ""): """ Gets a list of future diary notes for the user supplied (or all users if no user passed) LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO """ return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \ "FROM diary WHERE %s " \ "AND DiaryDateTime > %s" \ "ORDER BY DiaryDateTime" % (user_role_where_clause(dbo, user), db.ddt(i18n.now(dbo.timezone))))
def get_movements(dbo, movementtype): """ Gets the list of movements of a particular type (unreturned or returned after today and for animals who aren't deceased) """ return db.query(dbo, "SELECT * FROM v_adoption " \ "WHERE MovementType = %d AND " \ "(ReturnDate Is Null OR ReturnDate > %s) " \ "AND DeceasedDate Is Null " \ "ORDER BY MovementDate DESC" % (int(movementtype), db.dd(i18n.now(dbo.timezone))))
def receive_donation(dbo, username, did): """ Marks a donation received """ if id is None or did == "": return db.execute( dbo, "UPDATE ownerdonation SET Date = %s WHERE ID = %d" % (db.dd(i18n.now(dbo.timezone)), int(did))) audit.edit(dbo, username, "ownerdonation", str(did) + ": received") update_matching_transaction(dbo, username, int(did)) check_create_next_donation(dbo, username, did)
def insert_onlineformincoming_from_form(dbo, data, remoteip): """ Create onlineformincoming records from posted data. We create a row for every key/value pair in the posted data with a unique collation ID. """ IGNORE_FIELDS = [ "formname", "flags", "redirect", "account", "filechooser", "method" ] collationid = db.query_int( dbo, "SELECT MAX(CollationID) FROM onlineformincoming") + 1 formname = utils.df_ks(data, "formname") posteddate = i18n.now(dbo.timezone) flags = utils.df_ks(data, "flags") for k, v in data.iteritems(): if k not in IGNORE_FIELDS: label = "" displayindex = 0 fieldname = k # Form fields should have a _ONLINEFORMFIELD.ID suffix we can use to get the # original label and display position if k.find("_") != -1: fid = utils.cint(k[k.rfind("_") + 1:]) fieldname = k[0:k.rfind("_")] if fid != 0: fld = db.query( dbo, "SELECT Label, DisplayIndex FROM onlineformfield WHERE ID = %d" % fid) if len(fld) > 0: label = fld[0]["LABEL"] displayindex = fld[0]["DISPLAYINDEX"] sql = db.make_insert_sql( "onlineformincoming", (("CollationID", db.di(collationid)), ("FormName", db.ds(formname)), ("PostedDate", db.ddt(posteddate)), ("Flags", db.ds(flags)), ("FieldName", db.ds(fieldname)), ("Label", db.ds(label)), ("DisplayIndex", db.di(displayindex)), ("Host", db.ds(remoteip)), ("Value", db.ds(v)))) db.execute(dbo, sql) # Sort out the preview of the first few fields fieldssofar = 0 preview = [] for fld in get_onlineformincoming_detail(dbo, collationid): if fieldssofar < 3: fieldssofar += 1 preview.append(fld["LABEL"] + ": " + fld["VALUE"]) db.execute( dbo, "UPDATE onlineformincoming SET Preview = %s WHERE CollationID = %s" % (db.ds(", ".join(preview)), db.di(collationid))) return collationid
def reports_email(dbo): """ Batch email reports """ try: # Email any daily reports for local time of now extreports.email_daily_reports(dbo, i18n.now(dbo.timezone)) except: em = str(sys.exc_info()[0]) al.error("FAIL: running daily email of reports_email: %s" % em, "cron.reports_email", dbo, sys.exc_info())
def add_log(dbo, username, linktype, linkid, logtypeid, logtext): logid = db.get_id(dbo, "log") sql = db.make_insert_user_sql( dbo, "log", username, (("ID", db.di(logid)), ("LogTypeID", db.di(logtypeid)), ("LinkID", db.di(linkid)), ("LinkType", db.di(linktype)), ("Date", db.dd(i18n.now(dbo.timezone))), ("Comments", db.ds(logtext)))) db.execute(dbo, sql) audit.create(dbo, username, "log", str(logid)) return logid
def gkd(dbo, m, f, usetoday = False): """ reads field f from map m, returning a display date. string is empty if key not present or date is invalid. If usetoday is set to True, then today's date is returned if the date is blank. """ if f not in m: return "" lv = str(m[f]) # If there's a space, then I guess we have time info - throw it away if lv.find(" ") > 0: lv = lv[0:lv.find(" ")] # Now split it by either / or - b = lv.split("/") if lv.find("-") != -1: b = lv.split("-") # We should have three date bits now if len(b) != 3: # We don't have a valid date, if use today is on return that if usetoday: return i18n.python2display(dbo.locale, i18n.now(dbo.timezone)) else: return "" else: try: # Which of our 3 bits is the year? if utils.cint(b[0]) > 1900: # it's Y/M/D d = datetime.datetime(utils.cint(b[0]), utils.cint(b[1]), utils.cint(b[2])) elif dbo.locale == "en": # Assume it's M/D/Y for US d = datetime.datetime(utils.cint(b[2]), utils.cint(b[0]), utils.cint(b[1])) else: # Assume it's D/M/Y d = datetime.datetime(utils.cint(b[2]), utils.cint(b[1]), utils.cint(b[0])) return i18n.python2display(dbo.locale, d) except: # We've got an invalid date - return today if usetoday: return i18n.python2display(dbo.locale, i18n.now(dbo.timezone)) else: return ""
def get_tests_outstanding(dbo, offset="m31", locationfilter=""): """ Returns a recordset of animals awaiting tests: offset is m to go backwards, or p to go forwards with a number of days. ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFTEST, COMMENTS, TESTNAME, RESULTNAME, TESTTYPEID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return db.query(dbo, "SELECT * FROM v_animaltest " \ "WHERE DateRequired Is Not Null AND DateOfTest Is Null " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
def get_active_reservations(dbo, age=0): """ Gets the list of uncancelled reservation movements. age: The age of the reservation in days, or 0 for all """ where = "" if age > 0: where = "AND ReservationDate <= %s" % db.dd( i18n.subtract_days(i18n.now(dbo.timezone), age)) return db.query(dbo, "SELECT * FROM v_adoption " \ "WHERE ReservationDate Is Not Null AND MovementDate Is Null AND MovementType = 0 AND ReturnDate Is Null " \ "AND ReservationCancelledDate Is Null %s ORDER BY ReservationDate" % where)
def insert_waitinglist_from_form(dbo, data, username): """ Creates a waiting list record from the screen data: The webpy data object containing form parameters """ l = dbo.locale if utils.df_ks(data, "description") == "": raise utils.ASMValidationError(_("Description cannot be blank", l)) if utils.df_ki(data, "owner") == "0": raise utils.ASMValidationError( _("Waiting list entries must have a contact", l)) if utils.df_ks(data, "dateputon") == "": raise utils.ASMValidationError(_("Date put on cannot be blank", l)) nwlid = db.get_id(dbo, "animalwaitinglist") db.execute( dbo, db.make_insert_user_sql( dbo, "animalwaitinglist", username, (("ID", db.di(nwlid)), ("SpeciesID", utils.df_s(data, "species")), ("DatePutOnList", utils.df_d(data, "dateputon", l)), ("OwnerID", utils.df_s(data, "owner")), ("AnimalDescription", utils.df_t(data, "description")), ("ReasonForWantingToPart", utils.df_t(data, "reasonforwantingtopart")), ("CanAffordDonation", utils.df_c(data, "canafforddonation")), ("Urgency", utils.df_s(data, "urgency")), ("DateRemovedFromList", utils.df_d(data, "dateremoved", l)), ("AutoRemovePolicy", utils.df_s(data, "autoremovepolicy")), ("DateOfLastOwnerContact", db.dd(now(dbo.timezone))), ("ReasonForRemoval", utils.df_t(data, "reasonforremoval")), ("Comments", utils.df_t(data, "comments")), ("UrgencyLastUpdatedDate", db.dd(now(dbo.timezone))), ("UrgencyUpdateDate", db.dd( add_days( now(dbo.timezone), configuration.waiting_list_urgency_update_period(dbo))) )))) audit.create(dbo, username, "animalwaitinglist", str(nwlid)) return nwlid
def make_update_user_sql(dbo, table, username, cond, s, stampRecordVersion = True): """ Creates update sql for a given user, 'table' is the table name, username is the username of the user making the change, cond is the where condition eg: make_update_user_sql("animal", "jeff", "ID = 52", (( "AnimalName", ds("James") ))) """ l = list(s) l.append(("LastChangedBy", ds(username))) l.append(("LastChangedDate", ddt(i18n.now(dbo.timezone)))) if stampRecordVersion: l.append(("RecordVersion", di(recordversion()))) return make_update_sql(table, cond, l);
def get_vaccinations_outstanding(dbo, offset="m31", locationfilter=""): """ Returns a recordset of animals awaiting vaccinations: offset is m to go backwards, or p to go forwards with a number of days. locationfilter is a comma separated list of internal locations to include animals in ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFVACCINATION, COMMENTS, VACCINATIONTYPE, VACCINATIONID """ ec = "" offsetdays = utils.cint(offset[1:]) if offset.startswith("m"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone))) if offset.startswith("p"): ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays))) if locationfilter != "": locationfilter = " AND ShelterLocation IN (%s)" % locationfilter return db.query(dbo, "SELECT * FROM v_animalvaccination " \ "WHERE DateRequired Is Not Null AND DateOfVaccination Is Null " \ "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \ "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
def auto_remove_old_incoming_forms(dbo): """ Automatically removes incoming forms older than the daily amount set """ removeafter = configuration.auto_remove_incoming_forms_days(dbo) if removeafter <= 0: al.debug("auto remove incoming forms is off.", "onlineform.auto_remove_old_incoming_forms") return removecutoff = i18n.subtract_days(i18n.now(dbo.timezone), removeafter) al.debug("remove date: incoming forms < %s" % db.dd(removecutoff), "onlineform.auto_remove_old_incoming_forms") sql = "DELETE FROM onlineformincoming WHERE PostedDate < %s" % db.dd(removecutoff) count = db.execute(dbo, sql) al.debug("removed %d incoming forms older than %d days" % (count, int(removeafter)), "onlineform.auto_remove_old_incoming_forms", dbo)
def create_foundanimal(dbo, username, collationid): """ Creates a found animal record from the incoming form data with collationid. Also, attaches the form to the found animal as media. """ l = dbo.locale fields = get_onlineformincoming_detail(dbo, collationid) d = {} d["datefound"] = i18n.python2display(l, i18n.now(dbo.timezone)) d["datereported"] = i18n.python2display(l, i18n.now(dbo.timezone)) for f in fields: if f["FIELDNAME"] == "species": d["species"] = guess_species(dbo, f["VALUE"]) if f["FIELDNAME"] == "sex": d["sex"] = guess_sex(dbo, f["VALUE"]) if f["FIELDNAME"] == "breed": d["breed"] = guess_breed(dbo, f["VALUE"]) if f["FIELDNAME"] == "agegroup": d["agegroup"] = guess_agegroup(dbo, f["VALUE"]) if f["FIELDNAME"] == "color": d["colour"] = guess_colour(dbo, f["VALUE"]) if f["FIELDNAME"] == "colour": d["colour"] = guess_colour(dbo, f["VALUE"]) if f["FIELDNAME"] == "description": d["markings"] = f["VALUE"] if f["FIELDNAME"] == "areafound": d["areafound"] = f["VALUE"] if f["FIELDNAME"] == "areapostcode": d["areapostcode"] = f["VALUE"] if f["FIELDNAME"] == "areazipcode": d["areazipcode"] = f["VALUE"] if not d.has_key("species"): d["species"] = guess_species(dbo, "") if not d.has_key("sex"): d["sex"] = guess_sex(dbo, "") if not d.has_key("breed"): d["breed"] = guess_breed(dbo, "") if not d.has_key("agegroup"): d["agegroup"] = guess_agegroup(dbo, "") if not d.has_key("colour"): d["colour"] = guess_colour(dbo, "") # Have we got enough info to create the found animal record? We need a description and areafound if not d.has_key("markings") or not d.has_key("areafound"): raise utils.ASMValidationError(i18n._("There is not enough information in the form to create a found animal record (need a description and area found).", l)) # We need the person record before we create the found animal collationid, personid, personname = create_person(dbo, username, collationid) d["owner"] = personid # Create the found animal foundanimalid = lostfound.insert_foundanimal_from_form(dbo, utils.PostedData(d, dbo.locale), username) # Attach the form to the found animal formname = get_onlineformincoming_name(dbo, collationid) formhtml = get_onlineformincoming_html(dbo, collationid) media.create_document_media(dbo, username, media.FOUNDANIMAL, foundanimalid, formname, formhtml ) return (collationid, foundanimalid, utils.padleft(foundanimalid, 6) + " - " + personname)
def plcAgeYears(self, agegroup="", dob=None): """ Returns an age in years as a float/string from either an agegroup or a date of birth. """ years = 1 if dob is not None: days = i18n.date_diff_days(dob, i18n.now(self.dbo.timezone)) years = days / 365.0 else: years = configuration.age_group_for_name(self.dbo, agegroup) if years == 0: years = 1 return "%0.1f" % years
def add_message(dbo, createdby, email, message, forname="*", priority=0, expires=add_days(now(), 7), added=now()): l = dbo.locale db.execute( dbo, db.make_insert_sql( "messages", (("ID", db.di(db.get_id(dbo, "messages"))), ("Added", db.dd(added)), ("Expires", db.dd(expires)), ("CreatedBy", db.ds(createdby)), ("Priority", db.di(priority)), ("ForName", db.ds(forname)), ("Message", db.ds(message))))) # If email is set, we email the message to everyone that it would match if email == 1: utils.send_user_email(dbo, createdby, forname, _("Message from {0}", l).format(createdby), message)
def ar(rlist, rtype, sortfield): # Return brief records if rtype == "ANIMAL": rlist = animal.get_animals_brief(rlist) if rtype == "PERSON": pass # TODO: for r in rlist: r["RESULTTYPE"] = rtype if sortfield == "RELEVANCE": # How "relevant" is this record to what was searched for? # animal name and code weight higher than other elements. # Note that the code below modifies inbound var q, so by the # time we read it here, it should only contain the search term # itself. Weight everything else by last changed date so there # is some semblance of useful order for less relevant items r["SORTON"] = r["LASTCHANGEDDATE"] qlow = q.lower() if rtype == "ANIMAL": if r["ANIMALNAME"].lower( ) == qlow or r["SHELTERCODE"].lower( ) == qlow or r["SHORTCODE"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["ANIMALNAME"].lower().find( qlow) != -1 or r["SHELTERCODE"].lower().find( qlow) != -1 or r["SHORTCODE"].lower().find( qlow) != -1: r["SORTON"] = now() - datetime.timedelta(seconds=1) elif rtype == "PERSON": if r["OWNERSURNAME"].lower( ) == qlow or r["OWNERNAME"].lower() == qlow: r["SORTON"] = now() # Put matches where term present just behind direct matches if r["OWNERSURNAME"].lower().find( qlow) or r["OWNERNAME"].lower().find(qlow): r["SORTON"] = now() - datetime.timedelta(seconds=1) else: r["SORTON"] = r[sortfield] results.append(r)
def auto_remove_waitinglist(dbo): """ Finds and automatically marks entries removed that have gone past the last contact date + weeks. """ l = dbo.locale rows = dbo.query("SELECT a.ID, a.DateOfLastOwnerContact, " \ "a.AutoRemovePolicy " \ "FROM animalwaitinglist a WHERE a.DateRemovedFromList Is Null " \ "AND AutoRemovePolicy > 0 AND DateOfLastOwnerContact Is Not Null") updates = [] for r in rows: xdate = add_days(r.DATEOFLASTOWNERCONTACT, 7 * r.AUTOREMOVEPOLICY) if after(now(dbo.timezone), xdate): al.debug("auto removing waitinglist entry %d due to policy" % r.ID, "waitinglist.auto_remove_waitinglist", dbo) updates.append((now(dbo.timezone), _("Auto removed due to lack of owner contact.", l), r.ID)) if len(updates) > 0: dbo.execute_many("UPDATE animalwaitinglist SET DateRemovedFromList = ?, " \ "ReasonForRemoval=? WHERE ID=?", updates)
def get_waitinglist(dbo, priorityfloor=5, species=-1, addresscontains="", includeremoved=0, namecontains="", descriptioncontains=""): """ Retrieves the waiting list priorityfloor: The lowest urgency to show (1 = urgent, 5 = lowest) species: A species filter or -1 for all addresscontains: A partial address includeremoved: Whether or not to include removed entries namecontains: A partial name descriptioncontains: A partial description """ l = dbo.locale ranks = get_waitinglist_ranks(dbo) sql = get_waitinglist_query() + " WHERE a.Urgency <= " + str(priorityfloor) if includeremoved == 0: sql += " AND a.DateRemovedFromList Is Null" if species != -1: sql += " AND a.SpeciesID = " + str(species) if addresscontains != "": sql += " AND UPPER(OwnerAddress) Like '%" + str( addresscontains).upper().replace("'", "`") + "%'" if namecontains != "": sql += " AND UPPER(OwnerName) Like '%" + str( namecontains).upper().replace("'", "`") + "%'" if descriptioncontains != "": sql += " AND UPPER(AnimalDescription) Like '%" + str( descriptioncontains).upper().replace("'", "`") + "%'" sql += " ORDER BY a.Urgency, a.DatePutOnList" rows = db.query(dbo, sql) wlh = configuration.waiting_list_highlights(dbo).split(" ") for r in rows: r["HIGHLIGHT"] = "" for hi in wlh: if hi != "": if hi.find("|") == -1: wid = hi h = "1" else: wid, h = hi.split("|") if wid == str(r["WLID"]).strip(): r["HIGHLIGHT"] = h break if ranks.has_key(r["WLID"]): r["RANK"] = ranks[r["WLID"]] else: r["RANK"] = "" r["TIMEONLIST"] = date_diff(l, r["DATEPUTONLIST"], now(dbo.timezone)) return rows
def login(dbo, username): """ Marks the given user as logged in """ logout(dbo, username) db.execute( dbo, "DELETE FROM activeuser WHERE UPPER(UserName) LIKE '%s'" % str(username.upper())) db.execute( dbo, db.make_insert_sql("activeuser", (("UserName", db.ds(username)), ("Since", db.ddt(i18n.now())), ("Messages", db.ds("asm3"))))) al.info("%s logged in" % username, "users.login", dbo)
def create_animal(dbo, username, wlid): """ Creates an animal record from a waiting list entry with the id given """ a = db.query(dbo, "SELECT * FROM animalwaitinglist WHERE ID = %d" % wlid)[0] l = dbo.locale data = { "animalname": _("Waiting List {0}", l).format(wlid), "markings": str(a["ANIMALDESCRIPTION"]), "reasonforentry": str(a["REASONFORWANTINGTOPART"]), "species": str(a["SPECIESID"]), "comments": str(a["COMMENTS"]), "broughtinby": str(a["OWNERID"]), "originalowner": str(a["OWNERID"]), "animaltype": configuration.default_type(dbo), "breed1": configuration.default_breed(dbo), "breed2": configuration.default_breed(dbo), "basecolour": configuration.default_colour(dbo), "size": configuration.default_size(dbo), "internallocation": configuration.default_location(dbo), "dateofbirth": python2display(l, subtract_years(now(dbo.timezone))), "estimateddob": "1" } # If we're creating shelter codes manually, we need to put something unique # in there for now. Use the id if configuration.manual_codes(dbo): data["sheltercode"] = "WL" + str(wlid) data["shortcode"] = "WL" + str(wlid) nextid, code = animal.insert_animal_from_form(dbo, data, username) # Now that we've created our animal, we should remove this entry from the waiting list db.execute(dbo, "UPDATE animalwaitinglist SET DateRemovedFromList = %s, ReasonForRemoval = %s " \ "WHERE ID = %d" % ( db.dd(now(dbo.timezone)), db.ds(_("Moved to animal record {0}", l).format(code)), wlid)) return nextid
def substituteHFTag(self, searchin, page, user, title=""): """ Substitutes special header and footer tokens in searchin. page contains the current page number. """ output = searchin nav = self.navbar.replace( "<a href=\"%d.%s\">%d</a>" % (page, self.pc.extension, page), str(page)) dateportion = i18n.python2display(self.locale, i18n.now(self.dbo.timezone)) timeportion = i18n.format_date("%H:%M:%S", i18n.now(self.dbo.timezone)) if page != -1: output = output.replace("$$NAV$$", nav) else: output = output.replace("$$NAV$$", "") output = output.replace("$$TITLE$$", title) output = output.replace("$$TOTAL$$", str(self.totalAnimals)) output = output.replace("$$DATE$$", dateportion) output = output.replace("$$TIME$$", timeportion) output = output.replace("$$DATETIME$$", "%s %s" % (dateportion, timeportion)) output = output.replace("$$VERSION$$", i18n.get_version()) output = output.replace("$$REGISTEREDTO$$", configuration.organisation(self.dbo)) output = output.replace( "$$USER$$", "%s (%s)" % (user, users.get_real_name(self.dbo, user))) output = output.replace("$$ORGNAME$$", configuration.organisation(self.dbo)) output = output.replace("$$ORGADDRESS$$", configuration.organisation_address(self.dbo)) output = output.replace("$$ORGTEL$$", configuration.organisation_telephone(self.dbo)) output = output.replace("$$ORGEMAIL$$", configuration.email(self.dbo)) return output
def get_waitinglist_by_id(dbo, wid): """ Returns a single waitinglist record for the ID given """ l = dbo.locale r = dbo.first_row( dbo.query(get_waitinglist_query(dbo) + " WHERE a.ID = ?", [wid])) if not r: return None ranks = get_waitinglist_ranks(dbo) if r.WLID in ranks: r.RANK = ranks[r.WLID] else: r.RANK = "" r.TIMEONLIST = date_diff(l, r.DATEPUTONLIST, now(dbo.timezone)) return r
def get_waitinglist_by_id(dbo, wid): """ Returns a single waitinglist record for the ID given """ l = dbo.locale sql = get_waitinglist_query() + " WHERE a.ID = %d" % int(wid) rows = db.query(dbo, sql) if len(rows) == 0: return None r = rows[0] ranks = get_waitinglist_ranks(dbo) if ranks.has_key(r["WLID"]): r["RANK"] = ranks[r["WLID"]] else: r["RANK"] = "" r["TIMEONLIST"] = date_diff(l, r["DATEPUTONLIST"], now(dbo.timezone)) return r
def now(self, timenow=True, offset=0, settime=""): """ Returns now as a Python date, adjusted for the database timezone. timenow: if True, includes the current time offset: Add this many days to now (negative values supported) settime: A time in HH:MM:SS format to set """ d = i18n.now(self.timezone) if not timenow: d = d.replace(hour = 0, minute = 0, second = 0, microsecond = 0) if offset > 0: d = i18n.add_days(d, offset) if offset < 0: d = i18n.subtract_days(d, abs(offset)) if settime != "": timebits = settime.split(":") d = d.replace(hour = utils.cint(timebits[0]), minute = utils.cint(timebits[1]), second = utils.cint(timebits[2]), microsecond = 0) return d
def writeJavaScript(self, animals): # Remove original owner and other sensitive info from javascript database # before saving it for a in animals: for k in a.iterkeys(): if k.startswith("ORIGINALOWNER") or k.startswith("BROUGHTINBY") \ or k.startswith("RESERVEDOWNER") or k.startswith("CURRENTOWNER") \ or k == "DISPLAYLOCATION": a[k] = "" self.saveFile( os.path.join(self.publishDir, "db.js"), "publishDate='%s';animals=%s;" % (i18n.python2display(self.locale, i18n.now( self.dbo.timezone)), utils.json(animals))) if self.pc.uploadDirectly: self.log("Uploading javascript database...") self.upload("db.js") self.log("Uploaded javascript database.")
def reregistrationPDF(self, fields, sig, realname, orgname, orgaddress, orgtown, orgcounty, orgpostcode): """ Generates a reregistration PDF document containing the authorised user's electronic signature. """ gender = fields["petgender"] if gender == "M": gender = "Male" elif gender == "F": gender = "Female" h = "<p align=\"right\"><b>%s</b><br />%s<br />%s, %s<br />%s</p>" % ( orgname, orgaddress, orgtown, orgcounty, orgpostcode) h += "<h2>Change of Registered Owner/Keeper</h2>" h += "<table border=\"1\">" h += "<tr><td>Chip:</td><td><b>%s</b></td></tr>" % fields["microchip"] h += "<tr><td>Implanted:</td><td>%s</td></tr>" % fields["implantdate"] h += "<tr><td>Animal:</td><td>%s</td></tr>" % fields["petname"] h += "<tr><td>DOB:</td><td>%s</td></tr>" % fields["petdob"] h += "<tr><td>Type:</td><td>%s %s %s</td></tr>" % ( gender, fields["petbreed"], fields["petspecies"]) h += "<tr><td>Colour:</td><td>%s</td></tr>" % fields["petcolour"] h += "<tr><td>Neutered:</td><td>%s</td></tr>" % fields["petneutered"] h += "<tr><td>New Owner:</td><td>%s %s %s</td></tr>" % ( fields["prefix"], fields["firstname"], fields["surname"]) h += "<tr><td>Address:</td><td>%s<br/>%s<br/>%s %s</td></tr>" % ( fields["address1"], fields["city"], fields["county"], fields["postcode"]) h += "<tr><td>Telephone:</td><td>H: %s<br/>W: %s<br/>M: %s</td></tr>" % ( fields["telhome"], fields["telwork"], fields["telmobile"]) h += "<tr><td>Email:</td><td>%s</td></tr>" % fields["email"] h += "</table>" h += "<p>I/We confirm that every effort has been made to reunite the animal with its owner/keeper, or that the previous " \ "owner has relinquished ownership/keepership.</p>\n" h += "<p>If the animal was a stray then the animal has been in our care for the minimum required time period before " \ "rehoming took place.</p>\n" h += "<p>Authorised Signature: <br /><img src=\"%s\" /><br />%s</p>\n" % ( sig, realname) h += "<p>Date: %s</p>\n" % i18n.python2display( self.dbo.locale, i18n.now(self.dbo.timezone)) h += "<p>Authorisation: I understand that the information I have given on this form will be retained by PETtrac and " \ "hereby agree that it may be disclosed to any person or persons who may be involved in securing the welfare of the " \ "pet above. PETtrac reserves the right to amend any microchip record in the event that we are subsequently " \ "provided with additional information.</p>\n" return utils.html_to_pdf(h)
def create_waitinglist_from_found(dbo, username, aid): """ Creates a waiting list entry from a found animal with the id given """ a = dbo.first_row( dbo.query("SELECT * FROM animalfound WHERE ID = %d" % int(aid)) ) l = dbo.locale data = { "dateputon": python2display(l, now(dbo.timezone)), "description": str(a["DISTFEAT"]), "species": str(a["ANIMALTYPEID"]), "comments": str(a["COMMENTS"]), "owner": str(a["OWNERID"]), "breed1": a["BREEDID"], "breed2": a["BREEDID"], "basecolour": str(a["BASECOLOURID"]), "urgency": str(configuration.waiting_list_default_urgency(dbo)) } nextid = waitinglist.insert_waitinglist_from_form(dbo, utils.PostedData(data, dbo.locale), username) return nextid
def update_pass_homecheck(dbo, user, personid, comments): """ Marks a person as homechecked and appends any comments supplied to their record. """ by = users.get_personid(dbo, user) if by != 0: db.execute( dbo, "UPDATE owner SET HomeCheckedBy = %d WHERE ID = %d" % (by, personid)) db.execute( dbo, "UPDATE owner SET IDCheck = 1, DateLastHomeChecked = %s WHERE ID = %d" % (db.dd(now(dbo.timezone)), personid)) if comments != "": com = db.query_string( dbo, "SELECT Comments FROM owner WHERE ID = %d" % personid) com += "\n" + comments db.execute( dbo, "UPDATE owner SET Comments = %s WHERE ID = %d" % (db.ds(com), personid))
def stock_take_from_mobile_form(dbo, username, post): """ Post should contain sl{ID} values for new balances. """ if post.integer("usagetype") == 0: raise utils.ASMValidationError("No usage type passed") for k in post.data.iterkeys(): if k.startswith("sl"): slid = utils.cint(k.replace("sl", "")) sl = get_stocklevel(dbo, slid) slb = utils.cfloat(sl.BALANCE) # balance sln = post.floating(k) # new balance # If the balance hasn't changed, do nothing if slb == sln: continue # Update the level dbo.update("stocklevel", slid, {"Balance": sln}) # Write a stock usage record for the difference insert_stockusage(dbo, username, slid, sln - slb, now(dbo.timezone), post.integer("usagetype"), "")
def getAge(self, dob, speciesid): """ Returns an age banding based on date of birth and species """ # Kitten (0-8 weeks) = 1, Kitten/Juvenile (9 weeks- 5 months) = 2, Adult Cat (6 months - 8 years) =3, # Senior Cat (9 years) = 4, Puppy (0-8 weeks) = 5, Puppy/Juvenile (9 weeks 11-months) =6, Adult Dog (1 # year - 7 years) =7, Senior Dog (8 years) = 8 ageinyears = i18n.date_diff_days(dob, i18n.now()) ageinyears /= 365.0 age = 0 # Cats if speciesid == 2: if ageinyears < 0.15: age = 1 elif ageinyears < 0.5: age = 2 elif ageinyears < 8: age = 3 else: age = 4 # Dogs elif speciesid == 1: if ageinyears < 0.15: age = 5 elif ageinyears < 0.9: age = 6 elif ageinyears < 8: age = 7 else: age = 8 return age
def org_tags(dbo, username): """ Generates a list of tags from the organisation and user info """ u = users.get_users(dbo, username) realname = "" email = "" if len(u) > 0: u = u[0] realname = u["REALNAME"] email = u["EMAILADDRESS"] tags = { "ORGANISATION" : configuration.organisation(dbo), "ORGANISATIONADDRESS" : configuration.organisation_address(dbo), "ORGANISATIONTELEPHONE" : configuration.organisation_telephone(dbo), "DATE" : python2display(dbo.locale, now(dbo.timezone)), "USERNAME" : username, "USERREALNAME" : realname, "USEREMAILADDRESS" : email } return tags