def donation_tags(dbo, p): """ Generates a list of tags from a donation result. """ l = dbo.locale tags = { "DONATIONID" : str(p["ID"]), "RECEIPTNUM" : utils.padleft(p["ID"], 8), "DONATIONTYPE" : p["DONATIONNAME"], "DONATIONDATE" : python2display(l, p["DATE"]), "DONATIONDATEDUE" : python2display(l, p["DATEDUE"]), "DONATIONAMOUNT" : format_currency_no_symbol(l, p["DONATION"]), "DONATIONCOMMENTS" : p["COMMENTS"], "DONATIONGIFTAID" : p["ISGIFTAIDNAME"], "DONATIONCREATEDBY" : p["CREATEDBY"], "DONATIONCREATEDBYNAME" : p["CREATEDBY"], "DONATIONCREATEDDATE" : python2display(l, p["CREATEDDATE"]), "DONATIONLASTCHANGEDBY" : p["LASTCHANGEDBY"], "DONATIONLASTCHANGEDBYNAME" : p["LASTCHANGEDBY"], "DONATIONLASTCHANGEDDATE" : python2display(l, p["LASTCHANGEDDATE"]) } return tags
def csv(l, rows, cols=None, includeheader=True): """ Creates a CSV file from a set of resultset rows. If cols has been supplied as a list of strings, fields will be output in that order. """ if rows is None or len(rows) == 0: return "" strio = StringIO() out = UnicodeCSVWriter(strio) if cols is None: cols = [] for k, v in rows[0].iteritems(): cols.append(k) cols = sorted(cols) if includeheader: out.writerow(cols) for r in rows: rd = [] for c in cols: if is_currency(c): rd.append(decode_html(format_currency_no_symbol(l, r[c]))) elif is_date(r[c]): timeportion = "00:00:00" dateportion = "" try: dateportion = python2display(l, r[c]) timeportion = format_time(r[c]) except: pass # Don't stop the show for bad dates/times if timeportion != "00:00:00": # include time if non-midnight dateportion = "%s %s" % (dateportion, timeportion) rd.append(decode_html(dateportion)) else: rd.append(decode_html(r[c])) out.writerow(rd) return strio.getvalue()
def run(self): self.log("PetRescuePublisher starting...") if self.isPublisherExecuting(): return self.updatePublisherProgress(0) self.setLastError("") self.setStartPublishing() token = configuration.petrescue_token(self.dbo) all_desexed = configuration.petrescue_all_desexed(self.dbo) interstate = configuration.petrescue_interstate(self.dbo) postcode = configuration.organisation_postcode(self.dbo) suburb = configuration.organisation_town(self.dbo) state = configuration.organisation_county(self.dbo) contact_name = configuration.organisation(self.dbo) contact_email = configuration.petrescue_email(self.dbo) if contact_email == "": contact_email = configuration.email(self.dbo) contact_number = configuration.organisation_telephone(self.dbo) if token == "": self.setLastError("No PetRescue auth token has been set.") return if postcode == "" or contact_email == "": self.setLastError("You need to set your organisation postcode and contact email under Settings->Options->Shelter Details->Email") return animals = self.getMatchingAnimals(includeAdditionalFields=True) processed = [] if len(animals) == 0: self.setLastError("No animals found to publish.") self.cleanup() return headers = { "Authorization": "Token token=%s" % token, "Accept": "*/*" } anCount = 0 for an in animals: try: anCount += 1 self.log("Processing: %s: %s (%d of %d)" % ( an["SHELTERCODE"], an["ANIMALNAME"], anCount, len(animals))) self.updatePublisherProgress(self.getProgress(anCount, len(animals))) # If the user cancelled, stop now if self.shouldStopPublishing(): self.log("User cancelled publish. Stopping.") self.resetPublisherProgress() self.cleanup() return isdog = an.SPECIESID == 1 iscat = an.SPECIESID == 2 ageinyears = i18n.date_diff_days(an.DATEOFBIRTH, i18n.now()) size = "" if an.SIZE == 2: size = "medium" elif an.SIZE < 2: size = "large" else: size = "small" coat = "" if an.COATTYPE == 0: coat = "short" elif an.COATTYPE == 1: coat = "long" else: coat = "medium_coat" origin = "" if an.ISTRANSFER == 1 and str(an.BROUGHTINBYOWNERNAME).lower().find("pound") == -1: origin = "shelter_transfer" elif an.ISTRANSFER == 1 and str(an.BROUGHTINBYOWNERNAME).lower().find("pound") != -1: origin = "pound_transfer" elif an.ORIGINALOWNERID > 0: origin = "owner_surrender" else: origin = "community_cat" best_feature = "Looking for love" if "BESTFEATURE" in an and an.BESTFEATURE != "": best_feature = an.BESTFEATURE breeder_id = "" if "BREEDERID" in an and an.BREEDERID != "": breeder_id = an.BREEDERID needs_constant_care = False if "NEEDSCONSTANTCARE" in an and an.NEEDSCONSTANTCARE != "" and an.NEEDSCONSTANTCARE != "0": needs_constant_care = True # Check whether we've been vaccinated, wormed and hw treated vaccinated = medical.get_vaccinated(self.dbo, an.ID) sixmonths = self.dbo.today(offset=-182) hwtreated = isdog and self.dbo.query_int("SELECT COUNT(*) FROM animalmedical WHERE LOWER(TreatmentName) LIKE ? " \ "AND LOWER(TreatmentName) LIKE ? AND StartDate>? AND AnimalID=?", ("%heart%", "%worm%", sixmonths, an.ID)) > 0 wormed = (isdog or iscat) and self.dbo.query_int("SELECT COUNT(*) FROM animalmedical WHERE LOWER(TreatmentName) LIKE ? " \ "AND LOWER(TreatmentName) NOT LIKE ? AND StartDate>? AND AnimalID=?", ("%worm%", "%heart%", sixmonths, an.ID)) > 0 # PR want a null value to hide never-treated animals, so we # turn False into a null. if not hwtreated: hwtreated = None if not wormed: wormed = None # Use the fosterer's postcode, state and suburb if available location_postcode = postcode location_state_abbr = state location_suburb = suburb if an.ACTIVEMOVEMENTID and an.ACTIVEMOVEMENTTYPE == 2: fr = self.dbo.first_row(self.dbo.query("SELECT OwnerTown, OwnerCounty, OwnerPostcode FROM adoption m " \ "INNER JOIN owner o ON m.OwnerID = o.ID WHERE m.ID=?", [ an.ACTIVEMOVEMENTID ])) if fr is not None and fr.OWNERPOSTCODE: location_postcode = fr.OWNERPOSTCODE if fr is not None and fr.OWNERCOUNTY: location_state_abbr = fr.OWNERCOUNTY if fr is not None and fr.OWNERTOWN: location_suburb = fr.OWNERTOWN # Build a list of immutable photo URLs photo_urls = [] photos = self.dbo.query("SELECT MediaName FROM media " \ "WHERE LinkTypeID = 0 AND LinkID = ? AND MediaMimeType = 'image/jpeg' " \ "AND (ExcludeFromPublish = 0 OR ExcludeFromPublish Is Null) " \ "ORDER BY WebsitePhoto DESC, ID", [an.ID]) for m in photos: photo_urls.append("%s?account=%s&method=dbfs_image&title=%s" % (SERVICE_URL, self.dbo.database, m.MEDIANAME)) # Only send microchip_number for locations with a Victoria postcode 3xxx microchip_number = "" if location_postcode.startswith("3"): microchip_number = utils.iif(an.IDENTICHIPPED == 1, an.IDENTICHIPNUMBER, "") # Construct a dictionary of info for this animal data = { "remote_id": str(an.ID), # animal identifier in ASM "remote_source": "SM%s" % self.dbo.database, # system/database identifier "name": an.ANIMALNAME.title(), # animal name (title case, they validate against caps) "shelter_code": an.SHELTERCODE, "adoption_fee": i18n.format_currency_no_symbol(self.locale, an.FEE), "species_name": an.SPECIESNAME, "breed_names": self.get_breed_names(an), # [breed1,breed2] or [breed1] "breeder_id": breeder_id, # mandatory for QLD dogs born after 2017-05-26 "mix": an.CROSSBREED == 1, # true | false "date_of_birth": i18n.format_date("%Y-%m-%d", an.DATEOFBIRTH), # iso "gender": an.SEXNAME.lower(), # male | female "personality": self.replace_html_entities(self.getDescription(an)), # 20-4000 chars of free type "best_feature": best_feature, # 25 chars free type, defaults to "Looking for love" requires BESTFEATURE additional field "location_postcode": location_postcode, # shelter/fosterer postcode "location_state_abbr": location_state_abbr, # shelter/fosterer state "location_suburb": location_suburb, # shelter/fosterer suburb "microchip_number": microchip_number, "desexed": an.NEUTERED == 1 or all_desexed, # true | false, validates to always true according to docs "contact_method": "email", # email | phone "size": utils.iif(isdog, size, ""), # dogs only - small | medium | high "senior": isdog and ageinyears > (7 * 365), # dogs only, true | false "vaccinated": vaccinated, # cats, dogs, rabbits, true | false "wormed": wormed, # cats & dogs, true | false "heart_worm_treated": hwtreated, # dogs only, true | false "coat": coat, # Only applies to cats and guinea pigs, but we send for everything: short | medium_coat | long "intake_origin": utils.iif(iscat, origin, ""), # cats only, community_cat | owner_surrender | pound_transfer | shelter_transfer "incompatible_with_cats": an.ISGOODWITHCATS == 1, "incompatible_with_dogs": an.ISGOODWITHDOGS == 1, "incompatible_with_kids_under_5": an.ISGOODWITHCHILDREN == 1, "incompatible_with_kids_6_to_12": an.ISGOODWITHCHILDREN == 1, "needs_constant_care": needs_constant_care, "adoption_process": "", # 4,000 chars how to adopt "contact_details_source": "self", # self | user | group "contact_preferred_method": "email", # email | phone "contact_name": contact_name, # name of contact details owner "contact_number": contact_number, # number to enquire about adoption "contact_email": contact_email, # email to enquire about adoption "foster_needed": False, # true | false "interstate": interstate, # true | false - can the animal be flown to another state for adoption "medical_notes": "", # DISABLED an.HEALTHPROBLEMS, # 4,000 characters medical notes "multiple_animals": an.BONDEDANIMALID > 0 or an.BONDEDANIMAL2ID > 0, # More than one animal included in listing true | false "photo_urls": photo_urls, # List of photo URL strings "status": "active" # active | removed | on_hold | rehomed | suspended | group_suspended } # PetRescue will insert/update accordingly based on whether remote_id/remote_source exists url = PETRESCUE_URL + "listings" jsondata = utils.json(data) self.log("Sending POST to %s to create/update listing: %s" % (url, jsondata)) r = utils.post_json(url, jsondata, headers=headers) if r["status"] != 200: self.logError("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], self.utf8_to_ascii(r["response"]))) else: self.log("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], self.utf8_to_ascii(r["response"]))) self.logSuccess("Processed: %s: %s (%d of %d)" % ( an["SHELTERCODE"], an["ANIMALNAME"], anCount, len(animals))) processed.append(an) except Exception as err: self.logError("Failed processing animal: %s, %s" % (str(an["SHELTERCODE"]), err), sys.exc_info()) try: # Get a list of all animals that we sent to PR recently (14 days) prevsent = self.dbo.query("SELECT AnimalID FROM animalpublished WHERE SentDate>=? AND PublishedTo='petrescue'", [self.dbo.today(offset=-14)]) # Build a list of IDs we just sent, along with a list of ids for animals # that we previously sent and are not in the current sent list. # This identifies the listings we need to cancel animalids_just_sent = set([ x.ID for x in animals ]) animalids_to_cancel = set([ str(x.ANIMALID) for x in prevsent if x.ANIMALID not in animalids_just_sent]) # Get the animal records for the ones we need to cancel if len(animalids_to_cancel) == 0: animals = [] else: animals = self.dbo.query("SELECT ID, ShelterCode, AnimalName, ActiveMovementDate, ActiveMovementType, DeceasedDate " \ "FROM animal a WHERE ID IN (%s)" % ",".join(animalids_to_cancel)) except Exception as err: self.logError("Failed finding listings to cancel: %s" % err, sys.exc_info()) # Cancel the inactive listings for an in animals: try: status = "on_hold" if an.ACTIVEMOVEMENTDATE is not None and an.ACTIVEMOVEMENTTYPE == 1: status = "rehomed" if an.DECEASEDDATE is not None: status = "removed" data = { "status": status } jsondata = utils.json(data) url = PETRESCUE_URL + "listings/%s/SM%s" % (an.ID, self.dbo.database) self.log("Sending PATCH to %s to update existing listing: %s" % (url, jsondata)) r = utils.patch_json(url, jsondata, headers=headers) if r["status"] == 200: self.log("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], self.utf8_to_ascii(r["response"]))) self.logSuccess("%s - %s: Marked with new status %s" % (an.SHELTERCODE, an.ANIMALNAME, status)) # It used to be that we updated animalpublished for this animal to get sentdate to today # we don't do this now so that we'll update dead listings every day for however many days we # look back, but that's it else: self.logError("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], self.utf8_to_ascii(r["response"]))) except Exception as err: self.logError("Failed closing listing for %s - %s: %s" % (an.SHELTERCODE, an.ANIMALNAME, err), sys.exc_info()) # Mark sent animals published self.markAnimalsPublished(processed, first=True) self.cleanup()
def run(self): self.log("PetRescuePublisher starting...") if self.isPublisherExecuting(): return self.updatePublisherProgress(0) self.setLastError("") self.setStartPublishing() token = configuration.petrescue_token(self.dbo) postcode = configuration.organisation_postcode(self.dbo) contact_name = configuration.organisation(self.dbo) contact_email = configuration.email(self.dbo) contact_number = configuration.organisation_telephone(self.dbo) if token == "": self.setLastError("No PetRescue auth token has been set.") return if postcode == "" or contact_email == "": self.setLastError( "You need to set your organisation postcode and contact email under Settings->Options->Shelter Details->Email" ) return animals = self.getMatchingAnimals() processed = [] if len(animals) == 0: self.setLastError("No animals found to publish.") self.cleanup() return headers = {"Authorization": "Token token=%s" % token, "Accept": "*/*"} anCount = 0 for an in animals: try: anCount += 1 self.log("Processing: %s: %s (%d of %d)" % (an["SHELTERCODE"], an["ANIMALNAME"], anCount, len(animals))) self.updatePublisherProgress( self.getProgress(anCount, len(animals))) # If the user cancelled, stop now if self.shouldStopPublishing(): self.log("User cancelled publish. Stopping.") self.resetPublisherProgress() self.cleanup() return isdog = an.SPECIESID == 1 iscat = an.SPECIESID == 2 ageinyears = i18n.date_diff_days(an.DATEOFBIRTH, i18n.now()) vaccinated = medical.get_vaccinated(self.dbo, an.ID) size = "" if an.SIZE == 2: size = "medium" elif an.SIZE < 2: size = "large" else: size = "small" coat = "" if an.COATTYPE == 0: coat = "short" elif an.COATTYPE == 1: coat = "long" else: coat = "medium_coat" origin = "" if an.ISTRANSFER == 1 and an.BROUGHTINBYOWNERNAME.lower().find( "pound") == -1: origin = "shelter_transfer" elif an.ISTRANSFER == 1 and an.BROUGHTINBYOWNERNAME.lower( ).find("pound") != -1: origin = "pound_transfer" elif an.ORIGINALOWNERID > 0: origin = "owner_surrender" else: origin = "community_cat" photo_url = "%s?account=%s&method=animal_image&animalid=%d" % ( SERVICE_URL, self.dbo.database, an.ID) # Construct a dictionary of info for this animal data = { "remote_id": str(an.ID), # animal identifier in ASM "remote_source": "SM%s" % self.dbo.database, # system/database identifier "name": an.ANIMALNAME, # animal name "adoption_fee": i18n.format_currency_no_symbol(self.locale, an.FEE), "species_name": an.SPECIESNAME, "breed_names": self.get_breed_names(an), # breed1,breed2 or breed1 "mix": an.CROSSBREED == 1, # true | false "date_of_birth": i18n.format_date("%Y-%m-%d", an.DATEOFBIRTH), # iso "gender": an.SEXNAME.lower(), # male | female "personality": an.WEBSITEMEDIANOTES, # 20-4000 chars of free type "location_postcode": postcode, # shelter postcode "postcode": postcode, # shelter postcode "microchip_number": utils.iif(an.IDENTICHIPPED == 1, an.IDENTICHIPNUMBER, ""), "desexed": an.NEUTERED == 1, # true | false, validates to always true according to docs "contact_method": "email", # email | phone "size": utils.iif(isdog, size, ""), # dogs only - small | medium | high "senior": isdog and ageinyears > 7, # dogs only, true | false "vaccinated": vaccinated, # cats, dogs, rabbits, true | false "wormed": vaccinated, # cats & dogs, true | false "heart_worm_treated": vaccinated, # dogs only, true | false "coat": utils.iif(iscat, coat, ""), # cats only, short | medium_coat | long "intake_origin": utils.iif( iscat, origin, "" ), # cats only, community_cat | owner_surrender | pound_transfer | shelter_transfer "adoption_process": "", # 4,000 chars how to adopt "contact_details_source": "self", # self | user | group "contact_preferred_method": "email", # email | phone "contact_name": contact_name, # name of contact details owner "contact_number": contact_number, # number to enquire about adoption "contact_email": contact_email, # email to enquire about adoption "foster_needed": False, # true | false "interstate": True, # true | false - can the animal be adopted to another state "medical_notes": an.HEALTHPROBLEMS, # 4,000 characters medical notes "multiple_animals": False, # More than one animal included in listing true | false "photo_urls": [photo_url], # List of photo URL strings "status": "active" # active | removed | on_hold | rehomed | suspended | group_suspended } # PetRescue will insert/update accordingly based on whether remote_id/remote_source exists url = PETRESCUE_URL + "listings" jsondata = utils.json(data) self.log("Sending POST to %s to create/update listing: %s" % (url, jsondata)) r = utils.post_json(url, jsondata, headers=headers) if r["status"] != 200: self.logError("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], r["response"])) else: self.log("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], r["response"])) self.logSuccess("Processed: %s: %s (%d of %d)" % (an["SHELTERCODE"], an["ANIMALNAME"], anCount, len(animals))) processed.append(an) except Exception as err: self.logError( "Failed processing animal: %s, %s" % (str(an["SHELTERCODE"]), err), sys.exc_info()) # Next, identify animals we've previously sent who: # 1. Have an active exit movement in the last month or died in the last month # 2. Have an entry in animalpublished/petrescue where the sent date is older than the active movement # 3. Have an entry in animalpublished/petrescue where the sent date is older than the deceased date animals = self.dbo.query("SELECT a.ID, a.ShelterCode, a.AnimalName, p.SentDate, a.ActiveMovementDate, a.DeceasedDate FROM animal a " \ "INNER JOIN animalpublished p ON p.AnimalID = a.ID AND p.PublishedTo='petrescue' " \ "WHERE Archived = 1 AND ((DeceasedDate Is Not Null AND DeceasedDate >= ?) OR " \ "(ActiveMovementDate Is Not Null AND ActiveMovementDate >= ? AND ActiveMovementType NOT IN (2,8))) " \ "ORDER BY a.ID", [self.dbo.today(offset=-30), self.dbo.today(offset=-30)]) for an in animals: if (an.ACTIVEMOVEMENTDATE and an.SENTDATE < an.ACTIVEMOVEMENTDATE ) or (an.DECEASEDDATE and an.SENTDATE < an.DECEASEDDATE): status = utils.iif(an.DECEASEDDATE is not None, "removed", "rehomed") data = {"status": status} jsondata = utils.json(data) url = PETRESCUE_URL + "listings/%s/SM%s" % (an.ID, self.dbo.database) self.log("Sending PATCH to %s to update existing listing: %s" % (url, jsondata)) r = utils.patch_json(url, jsondata, headers=headers) if r["status"] != 200: self.logError("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], r["response"])) else: self.log("HTTP %d, headers: %s, response: %s" % (r["status"], r["headers"], r["response"])) self.logSuccess("%s - %s: Marked with new status %s" % (an.SHELTERCODE, an.ANIMALNAME, status)) # By marking these animals in the processed list again, their SentDate # will become today, which should exclude them from sending these status # updates to close the listing again in future processed.append(an) # Mark sent animals published self.markAnimalsPublished(processed, first=True) self.cleanup()
def animal_tags(dbo, a): """ Generates a list of tags from an animal result (the deep type from calling animal.get_animal) """ l = dbo.locale displaydob = python2display(l, a["DATEOFBIRTH"]) displayage = a["ANIMALAGE"] estimate = "" if a["ESTIMATEDDOB"] == 1: displaydob = a["AGEGROUP"] displayage = a["AGEGROUP"] estimate = _("estimate", l) tags = { "ANIMALNAME" : a["ANIMALNAME"], "ANIMALTYPENAME" : a["ANIMALTYPENAME"], "BASECOLOURNAME" : a["BASECOLOURNAME"], "BASECOLORNAME" : a["BASECOLOURNAME"], "BREEDNAME" : a["BREEDNAME"], "INTERNALLOCATION" : a["SHELTERLOCATIONNAME"], "LOCATIONUNIT" : a["SHELTERLOCATIONUNIT"], "COATTYPE" : a["COATTYPENAME"], "HEALTHPROBLEMS" : a["HEALTHPROBLEMS"], "ANIMALCREATEDBY" : a["CREATEDBY"], "ANIMALCREATEDDATE" : python2display(l, a["CREATEDDATE"]), "DATEBROUGHTIN" : python2display(l, a["DATEBROUGHTIN"]), "DATEOFBIRTH" : python2display(l, a["DATEOFBIRTH"]), "AGEGROUP" : a["AGEGROUP"], "DISPLAYDOB" : displaydob, "DISPLAYAGE" : displayage, "ESTIMATEDDOB" : estimate, "ANIMALID" : str(a["ID"]), "IDENTICHIPNUMBER" : a["IDENTICHIPNUMBER"], "IDENTICHIPPED" : a["IDENTICHIPPEDNAME"], "IDENTICHIPPEDDATE" : python2display(l, a["IDENTICHIPDATE"]), "MICROCHIPNUMBER" : a["IDENTICHIPNUMBER"], "MICROCHIPPED" : a["IDENTICHIPPEDNAME"], "MICROCHIPDATE" : python2display(l, a["IDENTICHIPDATE"]), "TATTOO" : a["TATTOONAME"], "TATTOODATE" : python2display(l, a["TATTOODATE"]), "TATTOONUMBER" : a["TATTOONUMBER"], "COMBITESTED" : a["COMBITESTEDNAME"], "FIVLTESTED" : a["COMBITESTEDNAME"], "COMBITESTDATE" : python2display(l, a["COMBITESTDATE"]), "FIVLTESTDATE" : python2display(l, a["COMBITESTDATE"]), "COMBITESTRESULT" : a["COMBITESTRESULTNAME"], "FIVTESTRESULT" : a["COMBITESTRESULTNAME"], "FIVRESULT" : a["COMBITESTRESULTNAME"], "FLVTESTRESULT" : a["FLVRESULTNAME"], "FLVRESULT" : a["FLVRESULTNAME"], "HEARTWORMTESTED" : a["HEARTWORMTESTEDNAME"], "HEARTWORMTESTDATE" : python2display(l, a["HEARTWORMTESTDATE"]), "HEARTWORMTESTRESULT" : a["HEARTWORMTESTRESULTNAME"], "HIDDENANIMALDETAILS" : a["HIDDENANIMALDETAILS"], "ANIMALLASTCHANGEDBY" : a["LASTCHANGEDBY"], "ANIMALLASTCHANGEDDATE" : python2display(l, a["LASTCHANGEDDATE"]), "MARKINGS" : a["MARKINGS"], "DECLAWED" : a["DECLAWEDNAME"], "RABIESTAG" : a["RABIESTAG"], "GOODWITHCATS" : a["ISGOODWITHCATSNAME"], "GOODWITHDOGS" : a["ISGOODWITHDOGSNAME"], "GOODWITHCHILDREN" : a["ISGOODWITHCHILDRENNAME"], "HOUSETRAINED" : a["ISHOUSETRAINEDNAME"], "NAMEOFPERSONBROUGHTANIMALIN" : a["BROUGHTINBYOWNERNAME"], "ADDRESSOFPERSONBROUGHTANIMALIN" : a["BROUGHTINBYOWNERADDRESS"], "TOWNOFPERSONBROUGHTANIMALIN" : a["BROUGHTINBYOWNERTOWN"], "COUNTYOFPERSONBROUGHTANIMALIN": a["BROUGHTINBYOWNERCOUNTY"], "POSTCODEOFPERSONBROUGHTIN": a["BROUGHTINBYOWNERPOSTCODE"], "CITYOFPERSONBROUGHTANIMALIN" : a["BROUGHTINBYOWNERTOWN"], "STATEOFPERSONBROUGHTANIMALIN": a["BROUGHTINBYOWNERCOUNTY"], "ZIPCODEOFPERSONBROUGHTIN": a["BROUGHTINBYOWNERPOSTCODE"], "BROUGHTINBYNAME" : a["BROUGHTINBYOWNERNAME"], "BROUGHTINBYADDRESS" : a["BROUGHTINBYOWNERADDRESS"], "BROUGHTINBYTOWN" : a["BROUGHTINBYOWNERTOWN"], "BROUGHTINBYCOUNTY" : a["BROUGHTINBYOWNERCOUNTY"], "BROUGHTINBYPOSTCODE" : a["BROUGHTINBYOWNERPOSTCODE"], "BROUGHTINBYCITY" : a["BROUGHTINBYOWNERTOWN"], "BROUGHTINBYSTATE" : a["BROUGHTINBYOWNERCOUNTY"], "BROUGHTINBYZIPCODE" : a["BROUGHTINBYOWNERPOSTCODE"], "BROUGHTINBYHOMEPHONE" : a["BROUGHTINBYHOMETELEPHONE"], "BROUGHTINBYPHONE" : a["BROUGHTINBYHOMETELEPHONE"], "BROUGHTINBYWORKPHONE" : a["BROUGHTINBYWORKTELEPHONE"], "BROUGHTINBYMOBILEPHONE" : a["BROUGHTINBYMOBILETELEPHONE"], "BROUGHTINBYCELLPHONE" : a["BROUGHTINBYMOBILETELEPHONE"], "BROUGHTINBYEMAIL" : a["BROUGHTINBYEMAILADDRESS"], "NAMEOFOWNERSVET" : a["OWNERSVETNAME"], "NAMEOFCURRENTVET" : a["CURRENTVETNAME"], "HASSPECIALNEEDS" : a["HASSPECIALNEEDSNAME"], "NEUTERED" : a["NEUTEREDNAME"], "FIXED" : a["NEUTEREDNAME"], "ALTERED" : a["NEUTEREDNAME"], "NEUTEREDDATE" : python2display(l, a["NEUTEREDDATE"]), "FIXEDDATE" : python2display(l, a["NEUTEREDDATE"]), "ALTEREDDATE" : python2display(l, a["NEUTEREDDATE"]), "ORIGINALOWNERNAME" : a["ORIGINALOWNERNAME"], "ORIGINALOWNERADDRESS" : a["ORIGINALOWNERADDRESS"], "ORIGINALOWNERTOWN" : a["ORIGINALOWNERTOWN"], "ORIGINALOWNERCOUNTY" : a["ORIGINALOWNERCOUNTY"], "ORIGINALOWNERPOSTCODE" : a["ORIGINALOWNERPOSTCODE"], "ORIGINALOWNERCITY" : a["ORIGINALOWNERTOWN"], "ORIGINALOWNERSTATE" : a["ORIGINALOWNERCOUNTY"], "ORIGINALOWNERZIPCODE" : a["ORIGINALOWNERPOSTCODE"], "ORIGINALOWNERHOMEPHONE" : a["ORIGINALOWNERHOMETELEPHONE"], "ORIGINALOWNERPHONE" : a["ORIGINALOWNERHOMETELEPHONE"], "ORIGINALOWNERWORKPHONE" : a["ORIGINALOWNERWORKTELEPHONE"], "ORIGINALOWNERMOBILEPHONE" : a["ORIGINALOWNERMOBILETELEPHONE"], "ORIGINALOWNERCELLPHONE" : a["ORIGINALOWNERMOBILETELEPHONE"], "ORIGINALOWNEREMAIL" : a["ORIGINALOWNEREMAILADDRESS"], "CURRENTOWNERNAME" : a["CURRENTOWNERNAME"], "CURRENTOWNERADDRESS" : a["CURRENTOWNERADDRESS"], "CURRENTOWNERTOWN" : a["CURRENTOWNERTOWN"], "CURRENTOWNERCOUNTY" : a["CURRENTOWNERCOUNTY"], "CURRENTOWNERPOSTCODE" : a["CURRENTOWNERPOSTCODE"], "CURRENTOWNERCITY" : a["CURRENTOWNERTOWN"], "CURRENTOWNERSTATE" : a["CURRENTOWNERCOUNTY"], "CURRENTOWNERZIPCODE" : a["CURRENTOWNERPOSTCODE"], "CURRENTOWNERHOMEPHONE" : a["CURRENTOWNERHOMETELEPHONE"], "CURRENTOWNERPHONE" : a["CURRENTOWNERHOMETELEPHONE"], "CURRENTOWNERWORKPHONE" : a["CURRENTOWNERWORKTELEPHONE"], "CURRENTOWNERMOBILEPHONE" : a["CURRENTOWNERMOBILETELEPHONE"], "CURRENTOWNERCELLPHONE" : a["CURRENTOWNERMOBILETELEPHONE"], "CURRENTOWNEREMAIL" : a["CURRENTOWNEREMAILADDRESS"], "CURRENTVETNAME" : a["CURRENTVETNAME"], "CURRENTVETADDRESS" : a["CURRENTVETADDRESS"], "CURRENTVETTOWN" : a["CURRENTVETTOWN"], "CURRENTVETCOUNTY" : a["CURRENTVETCOUNTY"], "CURRENTVETPOSTCODE" : a["CURRENTVETPOSTCODE"], "CURRENTVETCITY" : a["CURRENTVETTOWN"], "CURRENTVETSTATE" : a["CURRENTVETCOUNTY"], "CURRENTVETZIPCODE" : a["CURRENTVETPOSTCODE"], "CURRENTVETPHONE" : a["CURRENTVETWORKTELEPHONE"], "OWNERSVETNAME" : a["OWNERSVETNAME"], "OWNERSVETADDRESS" : a["OWNERSVETADDRESS"], "OWNERSVETTOWN" : a["OWNERSVETTOWN"], "OWNERSVETCOUNTY" : a["OWNERSVETCOUNTY"], "OWNERSVETPOSTCODE" : a["OWNERSVETPOSTCODE"], "OWNERSVETCITY" : a["OWNERSVETTOWN"], "OWNERSVETSTATE" : a["OWNERSVETCOUNTY"], "OWNERSVETZIPCODE" : a["OWNERSVETPOSTCODE"], "OWNERSVETPHONE" : a["OWNERSVETWORKTELEPHONE"], "RESERVEDOWNERNAME" : a["RESERVEDOWNERNAME"], "RESERVEDOWNERADDRESS" : a["RESERVEDOWNERADDRESS"], "RESERVEDOWNERTOWN" : a["RESERVEDOWNERTOWN"], "RESERVEDOWNERCOUNTY" : a["RESERVEDOWNERCOUNTY"], "RESERVEDOWNERPOSTCODE" : a["RESERVEDOWNERPOSTCODE"], "RESERVEDOWNERCITY" : a["RESERVEDOWNERTOWN"], "RESERVEDOWNERSTATE" : a["RESERVEDOWNERCOUNTY"], "RESERVEDOWNERZIPCODE" : a["RESERVEDOWNERPOSTCODE"], "RESERVEDOWNERHOMEPHONE" : a["RESERVEDOWNERHOMETELEPHONE"], "RESERVEDOWNERPHONE" : a["RESERVEDOWNERHOMETELEPHONE"], "RESERVEDOWNERWORKPHONE" : a["RESERVEDOWNERWORKTELEPHONE"], "RESERVEDOWNERMOBILEPHONE" : a["RESERVEDOWNERMOBILETELEPHONE"], "RESERVEDOWNERCELLPHONE" : a["RESERVEDOWNERMOBILETELEPHONE"], "RESERVEDOWNEREMAIL" : a["RESERVEDOWNEREMAILADDRESS"], "ENTRYCATEGORY" : a["ENTRYREASONNAME"], "REASONFORENTRY" : a["REASONFORENTRY"], "REASONNOTBROUGHTBYOWNER" : a["REASONNO"], "SEX" : a["SEXNAME"], "SIZE" : a["SIZENAME"], "SPECIESNAME" : a["SPECIESNAME"], "ANIMALCOMMENTS" : a["ANIMALCOMMENTS"], "SHELTERCODE" : a["SHELTERCODE"], "AGE" : a["ANIMALAGE"], "ACCEPTANCENUMBER" : a["ACCEPTANCENUMBER"], "LITTERID" : a["ACCEPTANCENUMBER"], "DECEASEDDATE" : python2display(l, a["DECEASEDDATE"]), "DECEASEDNOTES" : a["PTSREASON"], "DECEASEDCATEGORY" : a["PTSREASONNAME"], "SHORTSHELTERCODE" : a["SHORTCODE"], "MOSTRECENTENTRY" : python2display(l, a["MOSTRECENTENTRYDATE"]), "TIMEONSHELTER" : a["TIMEONSHELTER"], "WEBMEDIAFILENAME" : a["WEBSITEMEDIANAME"], "WEBSITEMEDIANAME" : a["WEBSITEMEDIANAME"], "WEBSITEVIDEOURL" : a["WEBSITEVIDEOURL"], "WEBSITEVIDEONOTES" : a["WEBSITEVIDEONOTES"], "WEBMEDIANOTES" : a["WEBSITEMEDIANOTES"], "WEBSITEMEDIANOTES" : a["WEBSITEMEDIANOTES"], "DOCUMENTIMGLINK" : "<img height=\"200\" src=\"" + html.img_src(a, "animal") + "\" >", "DOCUMENTIMGTHUMBLINK" : "<img src=\"" + html.thumbnail_img_src(a, "animalthumb") + "\" />", "DOCUMENTQRLINK" : "<img src=\"http://chart.apis.google.com/chart?cht=qr&chl=%s&chs=150x150\" />" % (BASE_URL + "/animal?id=%s" % a["ID"]), "ANIMALONSHELTER" : yes_no(l, a["ARCHIVED"] == 0), "ANIMALISRESERVED" : yes_no(l, a["HASACTIVERESERVE"] == 1), "ADOPTIONID" : a["ACTIVEMOVEMENTADOPTIONNUMBER"], "ADOPTIONNUMBER" : a["ACTIVEMOVEMENTADOPTIONNUMBER"], "INSURANCENUMBER" : a["ACTIVEMOVEMENTINSURANCENUMBER"], "RESERVATIONDATE" : python2display(l, a["ACTIVEMOVEMENTRESERVATIONDATE"]), "RETURNDATE" : python2display(l, a["ACTIVEMOVEMENTRETURNDATE"]), "ADOPTIONDATE" : python2display(l, a["ACTIVEMOVEMENTDATE"]), "FOSTEREDDATE" : python2display(l, a["ACTIVEMOVEMENTDATE"]), "TRANSFERDATE" : python2display(l, a["ACTIVEMOVEMENTDATE"]), "MOVEMENTDATE" : python2display(l, a["ACTIVEMOVEMENTDATE"]), "MOVEMENTTYPE" : a["ACTIVEMOVEMENTTYPENAME"], "ADOPTIONDONATION" : format_currency_no_symbol(l, a["ACTIVEMOVEMENTDONATION"]), "ADOPTIONCREATEDBY" : a["ACTIVEMOVEMENTCREATEDBY"], "ADOPTIONCREATEDBYNAME" : a["ACTIVEMOVEMENTCREATEDBYNAME"], "ADOPTIONCREATEDDATE" : python2display(l, a["ACTIVEMOVEMENTCREATEDDATE"]), "ADOPTIONLASTCHANGEDBY" : a["ACTIVEMOVEMENTLASTCHANGEDBY"], "ADOPTIONLASTCHANGEDDATE" : python2display(l, a["ACTIVEMOVEMENTLASTCHANGEDDATE"]) } # Set original owner to be current owner on non-shelter animals if a["NONSHELTERANIMAL"] == 1 and a["ORIGINALOWNERNAME"] is not None and a["ORIGINALOWNERNAME"] != "": tags["CURRENTOWNERNAME"] = a["ORIGINALOWNERNAME"] tags["CURRENTOWNERADDRESS"] = a["ORIGINALOWNERADDRESS"] tags["CURRENTOWNERTOWN"] = a["ORIGINALOWNERTOWN"] tags["CURRENTOWNERCOUNTY"] = a["ORIGINALOWNERCOUNTY"] tags["CURRENTOWNERPOSTCODE"] = a["ORIGINALOWNERPOSTCODE"] tags["CURRENTOWNERCITY"] = a["ORIGINALOWNERTOWN"] tags["CURRENTOWNERSTATE"] = a["ORIGINALOWNERCOUNTY"] tags["CURRENTOWNERZIPCODE"] = a["ORIGINALOWNERPOSTCODE"] tags["CURRENTOWNERHOMEPHONE"] = a["ORIGINALOWNERHOMETELEPHONE"] tags["CURRENTOWNERPHONE"] = a["ORIGINALOWNERHOMETELEPHONE"] tags["CURRENTOWNERWORKPHONE"] = a["ORIGINALOWNERWORKTELEPHONE"] tags["CURRENTOWNERMOBILEPHONE"] = a["ORIGINALOWNERMOBILETELEPHONE"] tags["CURRENTOWNERCELLPHONE"] = a["ORIGINALOWNERMOBILETELEPHONE"] tags["CURRENTOWNEREMAIL"] = a["ORIGINALOWNEREMAILADDRESS"] # If the animal doesn't have a current owner, but does have an open # movement with a future date on it, look up the owner and use that # instead so that we can still generate paperwork for future adoptions. if a["CURRENTOWNERID"] is None or a["CURRENTOWNERID"] == 0: latest = animal.get_latest_movement(dbo, a["ID"]) if latest is not None: p = person.get_person(dbo, latest["OWNERID"]) if p is not None: tags["CURRENTOWNERNAME"] = p["OWNERNAME"] tags["CURRENTOWNERADDRESS"] = p["OWNERADDRESS"] tags["CURRENTOWNERTOWN"] = p["OWNERTOWN"] tags["CURRENTOWNERCOUNTY"] = p["OWNERCOUNTY"] tags["CURRENTOWNERPOSTCODE"] = p["OWNERPOSTCODE"] tags["CURRENTOWNERCITY"] = p["OWNERTOWN"] tags["CURRENTOWNERSTATE"] = p["OWNERCOUNTY"] tags["CURRENTOWNERZIPCODE"] = p["OWNERPOSTCODE"] tags["CURRENTOWNERHOMEPHONE"] = p["HOMETELEPHONE"] tags["CURRENTOWNERPHONE"] = p["HOMETELEPHONE"] tags["CURRENTOWNERWORKPHONE"] = p["WORKTELEPHONE"] tags["CURRENTOWNERMOBILEPHONE"] = p["MOBILETELEPHONE"] tags["CURRENTOWNERCELLPHONE"] = p["MOBILETELEPHONE"] tags["CURRENTOWNEREMAIL"] = p["EMAILADDRESS"] # Additional fields add = additional.get_additional_fields(dbo, int(a["ID"]), "animal") for af in add: val = af["VALUE"] if af["FIELDTYPE"] == additional.YESNO: val = additional_yesno(l, af) if af["FIELDTYPE"] == additional.MONEY: val = format_currency_no_symbol(l, af["VALUE"]) tags[af["FIELDNAME"].upper()] = val include_incomplete = configuration.include_incomplete_medical_doc(dbo) # Vaccinations vaccasc = medical.get_vaccinations(dbo, int(a["ID"]), not include_incomplete) vaccdesc = medical.get_vaccinations(dbo, int(a["ID"]), not include_incomplete, medical.DESCENDING_REQUIRED) for idx in range(1, 101): tags["VACCINATIONNAME" + str(idx)] = "" tags["VACCINATIONREQUIRED" + str(idx)] = "" tags["VACCINATIONGIVEN" + str(idx)] = "" tags["VACCINATIONCOMMENTS" + str(idx)] = "" tags["VACCINATIONDESCRIPTION" + str(idx)] = "" tags["VACCINATIONNAMELAST" + str(idx)] = "" tags["VACCINATIONREQUIREDLAST" + str(idx)] = "" tags["VACCINATIONGIVENLAST" + str(idx)] = "" tags["VACCINATIONCOMMENTSLAST" + str(idx)] = "" tags["VACCINATIONDESCRIPTIONLAST" + str(idx)] = "" idx = 1 for v in vaccasc: tags["VACCINATIONNAME" + str(idx)] = v["VACCINATIONTYPE"] tags["VACCINATIONREQUIRED" + str(idx)] = python2display(l, v["DATEREQUIRED"]) tags["VACCINATIONGIVEN" + str(idx)] = python2display(l, v["DATEOFVACCINATION"]) tags["VACCINATIONCOMMENTS" + str(idx)] = v["COMMENTS"] tags["VACCINATIONDESCRIPTION" + str(idx)] = v["VACCINATIONDESCRIPTION"] idx += 1 idx = 1 uniquetypes = {} recentgiven = {} for v in vaccdesc: tags["VACCINATIONNAMELAST" + str(idx)] = v["VACCINATIONTYPE"] tags["VACCINATIONREQUIREDLAST" + str(idx)] = python2display(l, v["DATEREQUIRED"]) tags["VACCINATIONGIVENLAST" + str(idx)] = python2display(l, v["DATEOFVACCINATION"]) tags["VACCINATIONCOMMENTSLAST" + str(idx)] = v["COMMENTS"] tags["VACCINATIONDESCRIPTIONLAST" + str(idx)] = v["VACCINATIONDESCRIPTION"] idx += 1 # If this is the first of this type of vacc we've seen, make # some keys based on its name. if not uniquetypes.has_key(v["VACCINATIONTYPE"]): vname = v["VACCINATIONTYPE"].upper().replace(" ", "").replace("/", "") uniquetypes[v["VACCINATIONTYPE"]] = v tags["VACCINATIONNAME" + vname] = v["VACCINATIONTYPE"] tags["VACCINATIONREQUIRED" + vname] = python2display(l, v["DATEREQUIRED"]) tags["VACCINATIONGIVEN" + vname] = python2display(l, v["DATEOFVACCINATION"]) tags["VACCINATIONCOMMENTS" + vname] = v["COMMENTS"] tags["VACCINATIONDESCRIPTION" + vname] = v["VACCINATIONDESCRIPTION"] # If this is the first of this type of vacc we've seen that's been given # make some keys based on its name if not recentgiven.has_key(v["VACCINATIONTYPE"]) and v["DATEOFVACCINATION"] is not None: vname = v["VACCINATIONTYPE"].upper().replace(" ", "").replace("/", "") recentgiven[v["VACCINATIONTYPE"]] = v tags["VACCINATIONNAMERECENT" + vname] = v["VACCINATIONTYPE"] tags["VACCINATIONREQUIREDRECENT" + vname] = python2display(l, v["DATEREQUIRED"]) tags["VACCINATIONGIVENRECENT" + vname] = python2display(l, v["DATEOFVACCINATION"]) tags["VACCINATIONCOMMENTSRECENT" + vname] = v["COMMENTS"] tags["VACCINATIONDESCRIPTIONRECENT" + vname] = v["VACCINATIONDESCRIPTION"] # Tests testasc = medical.get_tests(dbo, int(a["ID"]), not include_incomplete) testdesc = medical.get_tests(dbo, int(a["ID"]), not include_incomplete, medical.DESCENDING_REQUIRED) for idx in range(1, 101): tags["TESTNAME" + str(idx)] = "" tags["TESTRESULT" + str(idx)] = "" tags["TESTREQUIRED" + str(idx)] = "" tags["TESTGIVEN" + str(idx)] = "" tags["TESTCOMMENTS" + str(idx)] = "" tags["TESTDESCRIPTION" + str(idx)] = "" tags["TESTNAMELAST" + str(idx)] = "" tags["TESTREQUIREDLAST" + str(idx)] = "" tags["TESTGIVENLAST" + str(idx)] = "" tags["TESTCOMMENTSLAST" + str(idx)] = "" tags["TESTDESCRIPTIONLAST" + str(idx)] = "" idx = 1 for t in testasc: tags["TESTNAME" + str(idx)] = t["TESTNAME"] tags["TESTRESULT" + str(idx)] = t["RESULTNAME"] tags["TESTREQUIRED" + str(idx)] = python2display(l, t["DATEREQUIRED"]) tags["TESTGIVEN" + str(idx)] = python2display(l, t["DATEOFTEST"]) tags["TESTCOMMENTS" + str(idx)] = t["COMMENTS"] tags["TESTDESCRIPTION" + str(idx)] = t["TESTDESCRIPTION"] idx += 1 idx = 1 uniquetypes = {} recentgiven = {} for t in testdesc: tags["TESTNAMELAST" + str(idx)] = t["TESTNAME"] tags["TESTRESULTLAST" + str(idx)] = t["RESULTNAME"] tags["TESTREQUIREDLAST" + str(idx)] = python2display(l, t["DATEREQUIRED"]) tags["TESTGIVENLAST" + str(idx)] = python2display(l, t["DATEOFTEST"]) tags["TESTCOMMENTSLAST" + str(idx)] = t["COMMENTS"] tags["TESTDESCRIPTIONLAST" + str(idx)] = t["TESTDESCRIPTION"] idx += 1 # If this is the first of this type of test we've seen, make # some keys based on its name. if not uniquetypes.has_key(t["TESTNAME"]): tname = t["TESTNAME"].upper().replace(" ", "").replace("/", "") uniquetypes[t["TESTNAME"]] = t tags["TESTNAME" + tname] = t["TESTNAME"] tags["TESTRESULT" + tname] = t["RESULTNAME"] tags["TESTREQUIRED" + tname] = python2display(l, t["DATEREQUIRED"]) tags["TESTGIVEN" + tname] = python2display(l, t["DATEOFTEST"]) tags["TESTCOMMENTS" + tname] = t["COMMENTS"] tags["TESTDESCRIPTION" + tname] = t["TESTDESCRIPTION"] # If this is the first of this type of test we've seen that's been given # make some keys based on its name if not recentgiven.has_key(t["TESTNAME"]) and t["DATEOFTEST"] is not None: tname = t["TESTNAME"].upper().replace(" ", "").replace("/", "") recentgiven[t["TESTNAME"]] = t tags["TESTNAMERECENT" + tname] = t["TESTNAME"] tags["TESTRESULTRECENT" + tname] = t["RESULTNAME"] tags["TESTREQUIREDRECENT" + tname] = python2display(l, t["DATEREQUIRED"]) tags["TESTGIVENRECENT" + tname] = python2display(l, t["DATEOFTEST"]) tags["TESTCOMMENTSRECENT" + tname] = t["COMMENTS"] tags["TESTDESCRIPTIONRECENT" + tname] = t["TESTDESCRIPTION"] # Medical medasc = medical.get_regimens(dbo, int(a["ID"]), not include_incomplete) meddesc = medical.get_regimens(dbo, int(a["ID"]), not include_incomplete, medical.DESCENDING_REQUIRED) for idx in range(1, 101): tags["MEDICALNAME" + str(idx)] = "" tags["MEDICALCOMMENTS" + str(idx)] = "" tags["MEDICALFREQUENCY" + str(idx)] = "" tags["MEDICALNUMBEROFTREATMENTS" + str(idx)] = "" tags["MEDICALSTATUS" + str(idx)] = "" tags["MEDICALDOSAGE" + str(idx)] = "" tags["MEDICALSTARTDATE" + str(idx)] = "" tags["MEDICALTREATMENTSGIVEN" + str(idx)] = "" tags["MEDICALTREATMENTSREMAINING" + str(idx)] = "" tags["MEDICALNAMELAST" + str(idx)] = "" tags["MEDICALCOMMENTSLAST" + str(idx)] = "" tags["MEDICALFREQUENCYLAST" + str(idx)] = "" tags["MEDICALNUMBEROFTREATMENTSLAST" + str(idx)] = "" tags["MEDICALSTATUSLAST" + str(idx)] = "" tags["MEDICALDOSAGELAST" + str(idx)] = "" tags["MEDICALSTARTDATELAST" + str(idx)] = "" tags["MEDICALTREATMENTSGIVENLAST" + str(idx)] = "" tags["MEDICALTREATMENTSREMAININGLAST" + str(idx)] = "" idx = 1 for m in medasc: tags["MEDICALNAME" + str(idx)] = m["TREATMENTNAME"] tags["MEDICALCOMMENTS" + str(idx)] = m["COMMENTS"] tags["MEDICALFREQUENCY" + str(idx)] = m["NAMEDFREQUENCY"] tags["MEDICALNUMBEROFTREATMENTS" + str(idx)] = m["NAMEDNUMBEROFTREATMENTS"] tags["MEDICALSTATUS" + str(idx)] = m["NAMEDSTATUS"] tags["MEDICALDOSAGE" + str(idx)] = m["DOSAGE"] tags["MEDICALSTARTDATE" + str(idx)] = python2display(l, m["STARTDATE"]) tags["MEDICALTREATMENTSGIVEN" + str(idx)] = str(m["TREATMENTSGIVEN"]) tags["MEDICALTREATMENTSREMAINING" + str(idx)] = str(m["TREATMENTSREMAINING"]) idx += 1 idx = 1 uniquetypes = {} recentgiven = {} for m in meddesc: tags["MEDICALNAMELAST" + str(idx)] = m["TREATMENTNAME"] tags["MEDICALCOMMENTSLAST" + str(idx)] = m["COMMENTS"] tags["MEDICALFREQUENCYLAST" + str(idx)] = m["NAMEDFREQUENCY"] tags["MEDICALNUMBEROFTREATMENTSLAST" + str(idx)] = m["NAMEDNUMBEROFTREATMENTS"] tags["MEDICALSTATUSLAST" + str(idx)] = m["NAMEDSTATUS"] tags["MEDICALDOSAGELAST" + str(idx)] = m["DOSAGE"] tags["MEDICALSTARTDATELAST" + str(idx)] = python2display(l, m["STARTDATE"]) tags["MEDICALTREATMENTSGIVENLAST" + str(idx)] = str(m["TREATMENTSGIVEN"]) tags["MEDICALTREATMENTSREMAININGLAST" + str(idx)] = str(m["TREATMENTSREMAINING"]) idx += 1 # If this is the first of this type of med we've seen, make # some keys based on its name. if not uniquetypes.has_key(m["TREATMENTNAME"]): tname = m["TREATMENTNAME"].upper().replace(" ", "").replace("/", "") uniquetypes[m["TREATMENTNAME"]] = m tags["MEDICALNAME" + tname] = m["TREATMENTNAME"] tags["MEDICALCOMMENTS" + tname] = m["COMMENTS"] tags["MEDICALFREQUENCY" + tname] = m["NAMEDFREQUENCY"] tags["MEDICALNUMBEROFTREATMENTS" + tname] = m["NAMEDNUMBEROFTREATMENTS"] tags["MEDICALSTATUS" + tname] = m["NAMEDSTATUS"] tags["MEDICALDOSAGE" + tname] = m["DOSAGE"] tags["MEDICALSTARTDATE" + tname] = python2display(l, m["STARTDATE"]) tags["MEDICALTREATMENTSGIVEN" + tname] = str(m["TREATMENTSGIVEN"]) tags["MEDICALTREATMENTSREMAINING" + tname] = str(m["TREATMENTSREMAINING"]) # If this is the first of this type of med we've seen that's complete if not recentgiven.has_key(m["TREATMENTNAME"]) and m["STATUS"] == 2: tname = m["TREATMENTNAME"].upper().replace(" ", "").replace("/", "") recentgiven[m["TREATMENTNAME"]] = m tags["MEDICALNAMERECENT" + tname] = m["TREATMENTNAME"] tags["MEDICALCOMMENTSRECENT" + tname] = m["COMMENTS"] tags["MEDICALFREQUENCYRECENT" + tname] = m["NAMEDFREQUENCY"] tags["MEDICALNUMBEROFTREATMENTSRECENT" + tname] = m["NAMEDNUMBEROFTREATMENTS"] tags["MEDICALSTATUSRECENT" + tname] = m["NAMEDSTATUS"] tags["MEDICALDOSAGERECENT" + tname] = m["DOSAGE"] tags["MEDICALSTARTDATERECENT" + tname] = python2display(l, m["STARTDATE"]) tags["MEDICALTREATMENTSGIVENRECENT" + tname] = str(m["TREATMENTSGIVEN"]) tags["MEDICALTREATMENTSREMAININGRECENT" + tname] = str(m["TREATMENTSREMAINING"]) # Diet dietasc = animal.get_diets(dbo, int(a["ID"])) dietdesc = animal.get_diets(dbo, int(a["ID"]), animal.DESCENDING) for idx in range(1, 101): tags["DIETNAME" + str(idx)] = "" tags["DIETDESCRIPTION" + str(idx)] = "" tags["DIETDATESTARTED" + str(idx)] = "" tags["DIETCOMMENTS" + str(idx)] = "" tags["DIETNAMELAST" + str(idx)] = "" tags["DIETDESCRIPTIONLAST" + str(idx)] = "" tags["DIETDATESTARTEDLAST" + str(idx)] = "" tags["DIETCOMMENTSLAST" + str(idx)] = "" idx = 1 for d in dietasc: tags["DIETNAME" + str(idx)] = d["DIETNAME"] tags["DIETDESCRIPTION" + str(idx)] = d["DIETDESCRIPTION"] tags["DIETDATESTARTED" + str(idx)] = python2display(l, d["DATESTARTED"]) tags["DIETCOMMENTS" + str(idx)] = d["COMMENTS"] idx += 1 idx = 1 for d in dietdesc: tags["DIETNAMELAST" + str(idx)] = d["DIETNAME"] tags["DIETDESCRIPTIONLAST" + str(idx)] = d["DIETDESCRIPTION"] tags["DIETDATESTARTEDLAST" + str(idx)] = python2display(l, d["DATESTARTED"]) tags["DIETCOMMENTSLAST" + str(idx)] = d["COMMENTS"] idx += 1 # Donations donasc = financial.get_animal_donations(dbo, int(a["ID"])) dondesc = financial.get_animal_donations(dbo, int(a["ID"]), financial.DESCENDING) for idx in range(1, 101): tags["RECEIPTNUM" + str(idx)] = "" tags["DONATIONTYPE" + str(idx)] = "" tags["DONATIONDATE" + str(idx)] = "" tags["DONATIONDATEDUE" + str(idx)] = "" tags["DONATIONAMOUNT" + str(idx)] = "" tags["DONATIONCOMMENTS" + str(idx)] = "" tags["DONATIONGIFTAID" + str(idx)] = "" tags["RECEIPTNUMLAST" + str(idx)] = "" tags["DONATIONTYPELAST" + str(idx)] = "" tags["DONATIONDATELAST" + str(idx)] = "" tags["DONATIONDATEDUELAST" + str(idx)] = "" tags["DONATIONAMOUNTLAST" + str(idx)] = "" tags["DONATIONCOMMENTSLAST" + str(idx)] = "" tags["DONATIONGIFTAIDLAST" + str(idx)] = "" idx = 1 for d in donasc: tags["RECEIPTNUM" + str(idx)] = utils.padleft(d["ID"], 8) tags["DONATIONTYPE" + str(idx)] = d["DONATIONNAME"] tags["DONATIONDATE" + str(idx)] = python2display(l, d["DATE"]) tags["DONATIONDATEDUE" + str(idx)] = python2display(l, d["DATEDUE"]) tags["DONATIONAMOUNT" + str(idx)] = format_currency_no_symbol(l, d["DONATION"]) tags["DONATIONCOMMENTS" + str(idx)] = d["COMMENTS"] tags["DONATIONGIFTAID" + str(idx)] = d["ISGIFTAID"] == 1 and _("Yes", l) or _("No", l) idx = 1 uniquetypes = {} recentrec = {} for d in dondesc: tags["RECEIPTNUMLAST" + str(idx)] = utils.padleft(d["ID"], 8) tags["DONATIONTYPELAST" + str(idx)] = d["DONATIONNAME"] tags["DONATIONDATELAST" + str(idx)] = python2display(l, d["DATE"]) tags["DONATIONDATEDUELAST" + str(idx)] = python2display(l, d["DATEDUE"]) tags["DONATIONAMOUNTLAST" + str(idx)] = format_currency_no_symbol(l, d["DONATION"]) tags["DONATIONCOMMENTSLAST" + str(idx)] = d["COMMENTS"] tags["DONATIONGIFTAIDLAST" + str(idx)] = d["ISGIFTAID"] == 1 and _("Yes", l) or _("No", l) idx += 1 # If this is the first of this type of donation we've seen, make # some keys based on its name. if not uniquetypes.has_key(d["DONATIONNAME"]): dname = d["DONATIONNAME"].upper().replace(" ", "").replace("/", "") uniquetypes[d["DONATIONNAME"]] = d tags["RECEIPTNUM" + dname] = utils.padleft(d["ID"], 8) tags["DONATIONTYPE" + dname] = d["DONATIONNAME"] tags["DONATIONDATE" + dname] = python2display(l, d["DATE"]) tags["DONATIONDATEDUE" + dname] = python2display(l, d["DATEDUE"]) tags["DONATIONAMOUNT" + dname] = format_currency_no_symbol(l, d["DONATION"]) tags["DONATIONCOMMENTS" + dname] = d["COMMENTS"] tags["DONATIONGIFTAID" + dname] = d["ISGIFTAID"] == 1 and _("Yes", l) or _("No", l) # If this is the first of this type of donation we've seen that's received if not recentrec.has_key(d["DONATIONNAME"]) and d["DATE"] is not None: dname = d["DONATIONNAME"].upper().replace(" ", "").replace("/", "") recentrec[d["DONATIONNAME"]] = d tags["RECEIPTNUMRECENT" + dname] = utils.padleft(d["ID"], 8) tags["DONATIONTYPERECENT" + dname] = d["DONATIONNAME"] tags["DONATIONDATERECENT" + dname] = python2display(l, d["DATE"]) tags["DONATIONDATEDUERECENT" + dname] = python2display(l, d["DATEDUE"]) tags["DONATIONAMOUNTRECENT" + dname] = format_currency_no_symbol(l, d["DONATION"]) tags["DONATIONCOMMENTSRECENT" + dname] = d["COMMENTS"] tags["DONATIONGIFTAIDRECENT" + dname] = d["ISGIFTAID"] == 1 and _("Yes", l) or _("No", l) # Logs logasc = log.get_logs(dbo, log.ANIMAL, int(a["ID"]), 0, log.ASCENDING) logdesc = log.get_logs(dbo, log.ANIMAL, int(a["ID"]), 0, log.DESCENDING) for idx in range(1, 101): tags["LOGNAME" + str(idx)] = "" tags["LOGDATE" + str(idx)] = "" tags["LOGCOMMENTS" + str(idx)] = "" tags["LOGNAMELAST" + str(idx)] = "" tags["LOGDATELAST" + str(idx)] = "" tags["LOGCOMMENTSLAST" + str(idx)] = "" idx = 1 for o in logasc: tags["LOGNAME" + str(idx)] = o["LOGTYPENAME"] tags["LOGDATE" + str(idx)] = python2display(l, o["DATE"]) tags["LOGCOMMENTS" + str(idx)] = o["COMMENTS"] idx += 1 idx = 1 uniquetypes = {} recentgiven = {} for o in logdesc: tags["LOGNAMELAST" + str(idx)] = o["LOGTYPENAME"] tags["LOGDATELAST" + str(idx)] = python2display(l, o["DATE"]) tags["LOGCOMMENTSLAST" + str(idx)] = o["COMMENTS"] idx += 1 uniquetypes = {} recentrec = {} # If this is the first of this type of log we've seen, make # some keys based on its name. if not uniquetypes.has_key(o["LOGTYPENAME"]): lname = o["LOGTYPENAME"].upper().replace(" ", "").replace("/", "") uniquetypes[o["LOGTYPENAME"]] = o tags["LOGNAME" + lname] = o["LOGTYPENAME"] tags["LOGDATE" + lname] = python2display(l, o["DATE"]) tags["LOGCOMMENTS" + lname] = o["COMMENTS"] tags["LOGNAMERECENT" + lname] = o["LOGTYPENAME"] tags["LOGDATERECENT" + lname] = python2display(l, o["DATE"]) tags["LOGCOMMENTSRECENT" + lname] = o["COMMENTS"] return tags