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 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 = dbo.today() dtd = dbo.query( "SELECT * FROM diarytaskdetail WHERE DiaryTaskHeadID = ? ORDER BY OrderIndex", [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 generate_donation_doc(dbo, template, donationid, username): """ Generates a donation document from a template template: The path/name of the template to use donationid: The donation to generate for """ s = dbfs.get_string_id(dbo, template) d = financial.get_donation(dbo, donationid) if d is None: raise utils.ASMValidationError("%d is not a valid donation ID" % donationid) tags = donation_tags(dbo, d) tags = append_tags(tags, person_tags(dbo, person.get_person(dbo, int(d["OWNERID"])))) if d["ANIMALID"] is not None and d["ANIMALID"] != 0: tags = append_tags(tags, animal_tags(dbo, animal.get_animal(dbo, d["ANIMALID"]))) tags = append_tags(tags, org_tags(dbo, username)) s = substitute_tags(s, tags) return s
def generate_animal_doc(dbo, template, animalid, username): """ Generates an animal document from a template using animal keys and (if a currentowner is available) person keys template: The path/name of the template to use animalid: The animal to generate for """ s = dbfs.get_string_id(dbo, template) a = animal.get_animal(dbo, animalid) if a is None: raise utils.ASMValidationError("%d is not a valid animal ID" % animalid) tags = animal_tags(dbo, a) if a["CURRENTOWNERID"] is not None and a["CURRENTOWNERID"] != 0: tags = append_tags(tags, person_tags(dbo, person.get_person(dbo, int(a["CURRENTOWNERID"])))) tags = append_tags(tags, org_tags(dbo, username)) s = substitute_tags(s, tags) return s
def handler(dbo, user, post): """ Handles posts from the frontend. Depending on the type we either return more HTML for the javascript to inject, or GO URL to have the controller redirect to URL """ l = dbo.locale homelink = "<a href='mobile' class='ui-btn-right' data-icon='home' data-theme='b'>%s</a>" % _( "Home", l) mode = post["posttype"] pid = post.integer("id") animalid = post.integer("animalid") if mode == "vacc": # We're vaccinating an animal a = animal.get_animal(dbo, animalid) medical.update_vaccination_today(dbo, user, pid) return jqm_page_header("", _("Vaccination Given", l), homelink) + \ jqm_p(_("Vaccination marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \ jqm_button("mobile#vacc", _("More Vaccinations", l), "", "false") + \ jqm_page_footer() if mode == "test": # We're performing a test on an animal a = animal.get_animal(dbo, animalid) medical.update_test_today(dbo, user, pid, post.integer("resultid")) return jqm_page_header("", _("Test Performed", l), homelink) + \ jqm_p(_("Test marked as performed for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \ jqm_button("mobile#test", _("More Tests", l), "", "false") + \ jqm_page_footer() elif mode == "med": # We're treating an animal a = animal.get_animal(dbo, animalid) medical.update_treatment_today(dbo, user, pid) return jqm_page_header("", _("Treatment Given", l), homelink) + \ jqm_p(_("Treatment marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + \ jqm_button("mobile#med", _("More Medications", l), "", "false") + \ jqm_page_footer() elif mode == "dia": # We're completing a diary task d = diary.get_diary(dbo, pid) if post["on"] == "0": diary.complete_diary_note(dbo, user, pid) return jqm_page_header("", _("Completed", l), homelink) + \ jqm_p(_("Diary note {0} marked completed", l).format(d["SUBJECT"])) + \ jqm_button("mobile#diary", _("More diary notes", l), "", "false") + \ jqm_page_footer() else: diary.rediarise_diary_note(dbo, user, pid, post.date("on")) return jqm_page_header("", _("Rediarised", l), homelink) + \ jqm_p(_("Diary note {0} rediarised for {1}", l).format(d["SUBJECT"], post["on"])) + \ jqm_button("mobile#diary", _("More diary notes", l), "", "false") + \ jqm_page_footer() elif mode == "dianew": # We're adding a diary note diary.insert_diary(dbo, user, 0, 0, post.date("diarydate"), post["diaryfor"], post["subject"], post["note"]) return "GO mobile" elif mode == "message": # We're adding a message lookups.add_message(dbo, user, post.boolean("email"), post["message"], post["forname"], post.integer("priority"), post.date("expires")) return "GO mobile" elif mode == "log": # We're adding a log to an animal a = animal.get_animal(dbo, animalid) log.add_log(dbo, user, log.ANIMAL, animalid, post.integer("logtypeid"), post["logtext"]) return "GO mobile" elif mode == "hc": # We're marking an owner homechecked person.update_pass_homecheck(dbo, user, post.integer("personid"), post["comments"]) return "GO mobile" elif mode == "vsa": # Return a list of the shelter animals h = [] alin = [] h.append(header(l)) h.append(jqm_page_header("", _("Shelter Animals", l), homelink)) an = animal.get_animal_find_simple(dbo, "", "all") for a in an: alin.append( jqm_listitem_link( "mobile_post?posttype=va&id=%d" % a["ID"], "%s - %s (%s %s %s) %s" % (a["CODE"], a["ANIMALNAME"], a["SEXNAME"], a["BREEDNAME"], a["SPECIESNAME"], a["IDENTICHIPNUMBER"]), "animal")) h.append(jqm_list("\n".join(alin), True)) h.append(jqm_page_footer()) h.append("</body></html>") return "\n".join(h) elif mode == "uai": # Upload an animal image media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, post.data) return "GO mobile_post?posttype=va&id=%d&success=true" % animalid elif mode == "va": # Display a page containing the selected animal by id a = animal.get_animal(dbo, pid) af = additional.get_additional_fields(dbo, pid, "animal") return handler_viewanimal(l, a, af, homelink, post)
def insert_adoption_from_form(dbo, username, data, creating=[]): """ Inserts a movement from the workflow adopt an animal screen. Returns the new movement id creating is an ongoing list of animals we're already going to create adoptions for. It prevents a never ending recursive loop of animal1 being bonded to animal2 that's bonded to animal1, etc. """ l = dbo.locale # Validate that we have a movement date before doing anthing if None == utils.df_kd(data, "movementdate", l): raise utils.ASMValidationError( i18n._("Adoption movements must have a valid adoption date.", l)) # Get the animal record for this adoption a = animal.get_animal(dbo, utils.df_ki(data, "animal")) if a is None: raise utils.ASMValidationError( "Adoption POST has an invalid animal ID: %d" % utils.df_ki(data, "animal")) al.debug( "Creating adoption for %d (%s - %s)" % (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]), "movement.insert_adoption_from_form", dbo) creating.append(a["ID"]) # If the animal is bonded to other animals, we call this function # again with a copy of the data and the bonded animal substituted # so we can create their adoption records too. if a["BONDEDANIMALID"] is not None and a["BONDEDANIMALID"] != 0 and a[ "BONDEDANIMALID"] not in creating: al.debug( "Found bond to animal %d, creating adoption..." % a["BONDEDANIMALID"], "movement.insert_adoption_from_form", dbo) newdata = dict(data) newdata["animal"] = str(a["BONDEDANIMALID"]) insert_adoption_from_form(dbo, username, newdata, creating) if a["BONDEDANIMAL2ID"] is not None and a["BONDEDANIMAL2ID"] != 0 and a[ "BONDEDANIMAL2ID"] not in creating: al.debug( "Found bond to animal %d, creating adoption..." % a["BONDEDANIMAL2ID"], "movement.insert_adoption_from_form", dbo) newdata = dict(data) newdata["animal"] = str(a["BONDEDANIMAL2ID"]) insert_adoption_from_form(dbo, username, newdata, creating) cancel_reserves = configuration.cancel_reserves_on_adoption(dbo) # Prepare a dictionary of data for the movement table via insert_movement_from_form move_dict = { "person": utils.df_ks(data, "person"), "animal": utils.df_ks(data, "animal"), "adoptionno": utils.df_ks(data, "movementnumber"), "movementdate": utils.df_ks(data, "movementdate"), "type": str(ADOPTION), "donation": utils.df_ks(data, "amount"), "insurance": utils.df_ks(data, "insurance"), "returncategory": configuration.default_return_reason(dbo), "trial": utils.df_ks(data, "trial"), "trialenddate": utils.df_ks(data, "trialenddate") } # Is this animal currently on foster? If so, return the foster fm = get_animal_movements(dbo, utils.df_ki(data, "animal")) for m in fm: if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], utils.df_ki(data, "animal"), utils.df_kd(data, "movementdate", l)) # Is this animal current at a retailer? If so, return it from the # retailer and set the originalretailermovement and retailerid fields # on our new adoption movement so it can be linked back for m in fm: if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], utils.df_ki(data, "animal"), utils.df_kd(data, "movementdate", l)) move_dict["originalretailermovement"] = str(m["ID"]) move_dict["retailer"] = str(m["OWNERID"]) # Did we say we'd like to flag the owner as homechecked? if utils.df_kc(data, "homechecked") == 1: db.execute(dbo, "UPDATE owner SET IDCheck = 1, DateLastHomeChecked = %s WHERE ID = %d" % \ ( db.dd(i18n.now(dbo.timezone)), utils.df_ki(data, "person"))) # If the animal was flagged as not available for adoption, then it # shouldn't be since we've just adopted it. db.execute( dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" % utils.df_ks(data, "animal")) # Is the animal reserved to the person adopting? movementid = 0 for m in fm: if m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \ and m["RESERVATIONCANCELLEDDATE"] is None and m["ANIMALID"] == utils.df_ki(data, "animal") \ and m["OWNERID"] == utils.df_ki(data, "person"): # yes - update the existing movement movementid = m["ID"] move_dict["movementid"] = str(movementid) move_dict["adoptionno"] = utils.padleft(movementid, 6) move_dict["reservationdate"] = str( i18n.python2display(l, m["RESERVATIONDATE"])) move_dict["comments"] = utils.nulltostr(m["COMMENTS"]) break elif cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \ and m["RESERVATIONCANCELLEDDATE"] is None: # no, but it's reserved to someone else and we're cancelling # reserves on adoption db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \ ( utils.df_d(data, "movementdate", l), m["ID"] )) if movementid != 0: update_movement_from_form(dbo, username, move_dict) else: movementid = insert_movement_from_form(dbo, username, move_dict) # Create the donation if there is one donation_amount = int(utils.df_m(data, "amount", l)) if donation_amount > 0: due = "" received = utils.df_ks(data, "movementdate") if configuration.movement_donations_default_due(dbo): due = utils.df_ks(data, "movementdate") received = "" don_dict = { "person": utils.df_ks(data, "person"), "animal": utils.df_ks(data, "animal"), "movement": str(movementid), "type": utils.df_ks(data, "donationtype"), "payment": utils.df_ks(data, "payment"), "frequency": "0", "amount": utils.df_ks(data, "amount"), "due": due, "received": received, "giftaid": utils.df_ks(data, "giftaid") } financial.insert_donation_from_form(dbo, username, don_dict) # And a second donation if there is one donation_amount = int(utils.df_m(data, "amount2", l)) if donation_amount > 0: due = "" received = utils.df_ks(data, "movementdate") if configuration.movement_donations_default_due(dbo): due = utils.df_ks(data, "movementdate") received = "" don_dict = { "person": utils.df_ks(data, "person"), "animal": utils.df_ks(data, "animal"), "movement": str(movementid), "type": utils.df_ks(data, "donationtype2"), "payment": utils.df_ks(data, "payment2"), "frequency": "0", "amount": utils.df_ks(data, "amount2"), "due": due, "received": received, "giftaid": utils.df_ks(data, "giftaid") } financial.insert_donation_from_form(dbo, username, don_dict) # Then any boarding cost record cost_amount = int(utils.df_m(data, "costamount", l)) cost_type = utils.df_ks(data, "costtype") cost_create = utils.df_ki(data, "costcreate") if cost_amount > 0 and cost_type != "" and cost_create == 1: boc_dict = { "animalid": utils.df_ks(data, "animal"), "type": cost_type, "costdate": utils.df_ks(data, "movementdate"), "cost": utils.df_ks(data, "costamount") } animal.insert_cost_from_form(dbo, username, boc_dict) return movementid
def handler(dbo, user, post): """ Handles posts from the frontend. Depending on the type we either return more HTML for the javascript to inject, or GO URL to have the controller redirect to URL """ l = dbo.locale homelink = "<a href='mobile' class='ui-btn-right' data-icon='home' data-theme='b'>%s</a>" % _("Home", l) mode = post["posttype"] pid = post.integer("id") animalid = post.integer("animalid") if mode == "vacc": # We're vaccinating an animal a = animal.get_animal(dbo, animalid) medical.update_vaccination_today(dbo, user, pid) return ( jqm_page_header("", _("Vaccination Given", l), homelink) + jqm_p(_("Vaccination marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + jqm_button("mobile#vacc", _("More Vaccinations", l), "", "false") + jqm_page_footer() ) if mode == "test": # We're performing a test on an animal a = animal.get_animal(dbo, animalid) medical.update_test_today(dbo, user, pid, post.integer("resultid")) return ( jqm_page_header("", _("Test Performed", l), homelink) + jqm_p(_("Test marked as performed for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + jqm_button("mobile#test", _("More Tests", l), "", "false") + jqm_page_footer() ) elif mode == "med": # We're treating an animal a = animal.get_animal(dbo, animalid) medical.update_treatment_today(dbo, user, pid) return ( jqm_page_header("", _("Treatment Given", l), homelink) + jqm_p(_("Treatment marked as given for {0} - {1}", l).format(a["ANIMALNAME"], a["SHELTERCODE"])) + jqm_button("mobile#med", _("More Medications", l), "", "false") + jqm_page_footer() ) elif mode == "dia": # We're completing a diary task d = diary.get_diary(dbo, pid) if post["on"] == "0": diary.complete_diary_note(dbo, user, pid) return ( jqm_page_header("", _("Completed", l), homelink) + jqm_p(_("Diary note {0} marked completed", l).format(d["SUBJECT"])) + jqm_button("mobile#diary", _("More diary notes", l), "", "false") + jqm_page_footer() ) else: diary.rediarise_diary_note(dbo, user, pid, post.date("on")) return ( jqm_page_header("", _("Rediarised", l), homelink) + jqm_p(_("Diary note {0} rediarised for {1}", l).format(d["SUBJECT"], post["on"])) + jqm_button("mobile#diary", _("More diary notes", l), "", "false") + jqm_page_footer() ) elif mode == "dianew": # We're adding a diary note diary.insert_diary(dbo, user, 0, 0, post.date("diarydate"), post["diaryfor"], post["subject"], post["note"]) return "GO mobile" elif mode == "message": # We're adding a message lookups.add_message( dbo, user, post.boolean("email"), post["message"], post["forname"], post.integer("priority"), post.date("expires"), ) return "GO mobile" elif mode == "log": # We're adding a log to an animal a = animal.get_animal(dbo, animalid) log.add_log(dbo, user, log.ANIMAL, animalid, post.integer("logtypeid"), post["logtext"]) return "GO mobile" elif mode == "hc": # We're marking an owner homechecked person.update_pass_homecheck(dbo, user, post.integer("personid"), post["comments"]) return "GO mobile" elif mode == "vsa": # Return a list of the shelter animals h = [] alin = [] h.append(header(l)) h.append(jqm_page_header("", _("Shelter Animals", l), homelink)) an = animal.get_animal_find_simple(dbo, "", "all") for a in an: alin.append( jqm_listitem_link( "mobile_post?posttype=va&id=%d" % a["ID"], "%s - %s (%s %s %s) %s" % ( a["CODE"], a["ANIMALNAME"], a["SEXNAME"], a["BREEDNAME"], a["SPECIESNAME"], a["IDENTICHIPNUMBER"], ), "animal", ) ) h.append(jqm_list("\n".join(alin), True)) h.append(jqm_page_footer()) h.append("</body></html>") return "\n".join(h) elif mode == "uai": # Upload an animal image media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, post.data) return "GO mobile_post?posttype=va&id=%d&success=true" % animalid elif mode == "va": # Display a page containing the selected animal by id a = animal.get_animal(dbo, pid) af = additional.get_additional_fields(dbo, pid, "animal") return handler_viewanimal(l, a, af, homelink, post)
def insert_adoption_from_form(dbo, username, data, creating = []): """ Inserts a movement from the workflow adopt an animal screen. Returns the new movement id creating is an ongoing list of animals we're already going to create adoptions for. It prevents a never ending recursive loop of animal1 being bonded to animal2 that's bonded to animal1, etc. """ l = dbo.locale # Validate that we have a movement date before doing anthing if None == utils.df_kd(data, "movementdate", l): raise utils.ASMValidationError(i18n._("Adoption movements must have a valid adoption date.", l)) # Get the animal record for this adoption a = animal.get_animal(dbo, utils.df_ki(data, "animal")) if a is None: raise utils.ASMValidationError("Adoption POST has an invalid animal ID: %d" % utils.df_ki(data, "animal")) al.debug("Creating adoption for %d (%s - %s)" % (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]), "movement.insert_adoption_from_form", dbo) creating.append(a["ID"]) # If the animal is bonded to other animals, we call this function # again with a copy of the data and the bonded animal substituted # so we can create their adoption records too. if a["BONDEDANIMALID"] is not None and a["BONDEDANIMALID"] != 0 and a["BONDEDANIMALID"] not in creating: al.debug("Found bond to animal %d, creating adoption..." % a["BONDEDANIMALID"], "movement.insert_adoption_from_form", dbo) newdata = dict(data) newdata["animal"] = str(a["BONDEDANIMALID"]) insert_adoption_from_form(dbo, username, newdata, creating) if a["BONDEDANIMAL2ID"] is not None and a["BONDEDANIMAL2ID"] != 0 and a["BONDEDANIMAL2ID"] not in creating: al.debug("Found bond to animal %d, creating adoption..." % a["BONDEDANIMAL2ID"], "movement.insert_adoption_from_form", dbo) newdata = dict(data) newdata["animal"] = str(a["BONDEDANIMAL2ID"]) insert_adoption_from_form(dbo, username, newdata, creating) cancel_reserves = configuration.cancel_reserves_on_adoption(dbo) # Prepare a dictionary of data for the movement table via insert_movement_from_form move_dict = { "person" : utils.df_ks(data, "person"), "animal" : utils.df_ks(data, "animal"), "adoptionno" : utils.df_ks(data, "movementnumber"), "movementdate" : utils.df_ks(data, "movementdate"), "type" : str(ADOPTION), "donation" : utils.df_ks(data, "amount"), "insurance" : utils.df_ks(data, "insurance"), "returncategory" : configuration.default_return_reason(dbo), "trial" : utils.df_ks(data, "trial"), "trialenddate" : utils.df_ks(data, "trialenddate") } # Is this animal currently on foster? If so, return the foster fm = get_animal_movements(dbo, utils.df_ki(data, "animal")) for m in fm: if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], utils.df_ki(data, "animal"), utils.df_kd(data, "movementdate", l)) # Is this animal current at a retailer? If so, return it from the # retailer and set the originalretailermovement and retailerid fields # on our new adoption movement so it can be linked back for m in fm: if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], utils.df_ki(data, "animal"), utils.df_kd(data, "movementdate", l)) move_dict["originalretailermovement"] = str(m["ID"]) move_dict["retailer"] = str(m["OWNERID"]) # Did we say we'd like to flag the owner as homechecked? if utils.df_kc(data, "homechecked") == 1: db.execute(dbo, "UPDATE owner SET IDCheck = 1, DateLastHomeChecked = %s WHERE ID = %d" % \ ( db.dd(i18n.now(dbo.timezone)), utils.df_ki(data, "person"))) # If the animal was flagged as not available for adoption, then it # shouldn't be since we've just adopted it. db.execute(dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" % utils.df_ks(data, "animal")) # Is the animal reserved to the person adopting? movementid = 0 for m in fm: if m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \ and m["RESERVATIONCANCELLEDDATE"] is None and m["ANIMALID"] == utils.df_ki(data, "animal") \ and m["OWNERID"] == utils.df_ki(data, "person"): # yes - update the existing movement movementid = m["ID"] move_dict["movementid"] = str(movementid) move_dict["adoptionno"] = utils.padleft(movementid, 6) move_dict["reservationdate"] = str(i18n.python2display(l, m["RESERVATIONDATE"])) move_dict["comments"] = utils.nulltostr(m["COMMENTS"]) break elif cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \ and m["RESERVATIONCANCELLEDDATE"] is None: # no, but it's reserved to someone else and we're cancelling # reserves on adoption db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \ ( utils.df_d(data, "movementdate", l), m["ID"] )) if movementid != 0: update_movement_from_form(dbo, username, move_dict) else: movementid = insert_movement_from_form(dbo, username, move_dict) # Create the donation if there is one donation_amount = int(utils.df_m(data, "amount", l)) if donation_amount > 0: due = "" received = utils.df_ks(data, "movementdate") if configuration.movement_donations_default_due(dbo): due = utils.df_ks(data, "movementdate") received = "" don_dict = { "person" : utils.df_ks(data, "person"), "animal" : utils.df_ks(data, "animal"), "movement" : str(movementid), "type" : utils.df_ks(data, "donationtype"), "payment" : utils.df_ks(data, "payment"), "frequency" : "0", "amount" : utils.df_ks(data, "amount"), "due" : due, "received" : received, "giftaid" : utils.df_ks(data, "giftaid") } financial.insert_donation_from_form(dbo, username, don_dict) # And a second donation if there is one donation_amount = int(utils.df_m(data, "amount2", l)) if donation_amount > 0: due = "" received = utils.df_ks(data, "movementdate") if configuration.movement_donations_default_due(dbo): due = utils.df_ks(data, "movementdate") received = "" don_dict = { "person" : utils.df_ks(data, "person"), "animal" : utils.df_ks(data, "animal"), "movement" : str(movementid), "type" : utils.df_ks(data, "donationtype2"), "payment" : utils.df_ks(data, "payment2"), "frequency" : "0", "amount" : utils.df_ks(data, "amount2"), "due" : due, "received" : received, "giftaid" : utils.df_ks(data, "giftaid") } financial.insert_donation_from_form(dbo, username, don_dict) # Then any boarding cost record cost_amount = int(utils.df_m(data, "costamount", l)) cost_type = utils.df_ks(data, "costtype") cost_create = utils.df_ki(data, "costcreate") if cost_amount > 0 and cost_type != "" and cost_create == 1: boc_dict = { "animalid" : utils.df_ks(data, "animal"), "type" : cost_type, "costdate" : utils.df_ks(data, "movementdate"), "cost" : utils.df_ks(data, "costamount") } animal.insert_cost_from_form(dbo, username, boc_dict) return movementid
def insert_reclaim_from_form(dbo, username, post): """ Inserts a movement from the workflow adopt an animal screen. Returns the new movement id """ l = dbo.locale # Validate that we have a movement date before doing anthing if None == post.date("movementdate"): raise utils.ASMValidationError( i18n._("Reclaim movements must have a valid reclaim date.", l)) # Get the animal record for this reclaim a = animal.get_animal(dbo, post.integer("animal")) if a is None: raise utils.ASMValidationError( "Reclaim POST has an invalid animal ID: %d" % post.integer("animal")) al.debug( "Creating reclaim for %d (%s - %s)" % (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]), "movement.insert_reclaim_from_form", dbo) # Prepare a dictionary of data for the movement table via insert_movement_from_form move_dict = { "person": post["person"], "animal": post["animal"], "adoptionno": post["movementnumber"], "movementdate": post["movementdate"], "type": str(RECLAIMED), "donation": post["amount"], "returncategory": configuration.default_return_reason(dbo) } # Is this animal currently on foster? If so, return the foster fm = get_animal_movements(dbo, post.integer("animal")) for m in fm: if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], post.integer("animal"), post.date("movementdate")) # Is this animal current at a retailer? If so, return it from the # retailer and set the originalretailermovement and retailerid fields # on our new adoption movement so it can be linked back for m in fm: if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], post.integer("animal"), post.date("movementdate")) move_dict["originalretailermovement"] = str(m["ID"]) move_dict["retailer"] = str(m["OWNERID"]) # If the animal was flagged as not available for adoption, then it # shouldn't be since we've just reclaimed it. db.execute( dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" % post["animal"]) # Is the animal reserved? Should clear it if so cancel_reserves = configuration.cancel_reserves_on_adoption(dbo) for m in fm: if cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \ and m["RESERVATIONCANCELLEDDATE"] is None: db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \ ( post.db_date("movementdate"), m["ID"] )) movementid = insert_movement_from_form(dbo, username, utils.PostedData(move_dict, l)) # Create the donation if there is one donation_amount = post.integer("amount") if donation_amount > 0: due = "" received = post["movementdate"] if configuration.movement_donations_default_due(dbo): due = post["movementdate"] received = "" don_dict = { "person": post["person"], "animal": post["animal"], "movement": str(movementid), "type": post["donationtype"], "payment": post["payment"], "destaccount": post["destaccount"], "frequency": "0", "amount": post["amount"], "due": due, "received": received, "giftaid": post["giftaid"] } financial.insert_donation_from_form(dbo, username, utils.PostedData(don_dict, l)) # Then any boarding cost record cost_amount = post.integer("costamount") cost_type = post["costtype"] cost_create = post.integer("costcreate") if cost_amount > 0 and cost_type != "" and cost_create == 1: boc_dict = { "animalid": post["animal"], "type": cost_type, "costdate": post["movementdate"], "costpaid": post["movementdate"], "cost": post["costamount"] } animal.insert_cost_from_form(dbo, username, utils.PostedData(boc_dict, l)) return movementid
def test_get_animal(self): assert animal.get_animal(base.get_dbo(), self.nid) is not None
def test_get_adoption_status(self): a = animal.get_animal(base.get_dbo(), self.nid) assert "Adoptable" == publishers.base.get_adoption_status( base.get_dbo(), a)
def test_get_animals_brief(self): assert animal.get_animals_brief([animal.get_animal(base.get_dbo(), self.nid),])
def insert_reclaim_from_form(dbo, username, post): """f Inserts a movement from the workflow adopt an animal screen. Returns the new movement id """ l = dbo.locale # Validate that we have a movement date before doing anthing if None is post.date("movementdate"): raise utils.ASMValidationError(i18n._("Reclaim movements must have a valid reclaim date.", l)) # Get the animal record for this reclaim a = animal.get_animal(dbo, post.integer("animal")) if a is None: raise utils.ASMValidationError("Reclaim POST has an invalid animal ID: %d" % post.integer("animal")) al.debug("Creating reclaim for %d (%s - %s)" % (a.ID, a.SHELTERCODE, a.ANIMALNAME), "movement.insert_reclaim_from_form", dbo) # Prepare a dictionary of data for the movement table via insert_movement_from_form move_dict = { "person" : post["person"], "animal" : post["animal"], "adoptionno" : post["movementnumber"], "movementdate" : post["movementdate"], "type" : str(RECLAIMED), "donation" : post["amount"], "returncategory" : configuration.default_return_reason(dbo) } # Is this animal currently on foster? If so, return the foster fm = get_animal_movements(dbo, post.integer("animal")) for m in fm: if m.MOVEMENTTYPE == FOSTER and m.RETURNDATE is None: return_movement(dbo, m.ID, post.integer("animal"), post.date("movementdate")) # Is this animal current at a retailer? If so, return it from the # retailer and set the originalretailermovement and retailerid fields # on our new adoption movement so it can be linked back for m in fm: if m.MOVEMENTTYPE == RETAILER and m.RETURNDATE is None: return_movement(dbo, m["ID"], post.integer("animal"), post.date("movementdate")) move_dict["originalretailermovement"] = str(m.ID) move_dict["retailer"] = str(m.OWNERID) # If the animal was flagged as not available for adoption, then it # shouldn't be since we've just reclaimed it. dbo.update("animal", post.integer("animal"), { "IsNotAvailableForAdoption": 0 }) # Is the animal reserved? Should clear it if so cancel_reserves = configuration.cancel_reserves_on_adoption(dbo) for m in fm: if cancel_reserves and m.MOVEMENTTYPE == NO_MOVEMENT and m.RESERVATIONDATE is not None \ and m.RESERVATIONCANCELLEDDATE is None: dbo.update("adoption", m.ID, { "ReservationCancelledDate": post.date("movementdate") }, username) movementid = insert_movement_from_form(dbo, username, utils.PostedData(move_dict, l)) # Create any payments financial.insert_donations_from_form(dbo, username, post, post["movementdate"], False, post["person"], post["animal"], movementid) # Then any boarding cost record cost_amount = post.integer("costamount") cost_type = post["costtype"] cost_create = post.integer("costcreate") if cost_amount > 0 and cost_type != "" and cost_create == 1: boc_dict = { "animalid" : post["animal"], "type" : cost_type, "costdate" : post["movementdate"], "costpaid" : post["movementdate"], "cost" : post["costamount"] } animal.insert_cost_from_form(dbo, username, utils.PostedData(boc_dict, l)) return movementid
def insert_adoption_from_form(dbo, username, post, creating = [], create_payments = True): """ Inserts a movement from the workflow adopt an animal screen. Returns the new movement id creating is an ongoing list of animals we're already going to create adoptions for. It prevents a never ending recursive loop of animal1 being bonded to animal2 that's bonded to animal1, etc. create_payments is True if we should create payments - don't do this for bonded animals or we'll double up all the payments. """ l = dbo.locale # Validate that we have a movement date before doing anthing if None is post.date("movementdate"): raise utils.ASMValidationError(i18n._("Adoption movements must have a valid adoption date.", l)) # Get the animal record for this adoption a = animal.get_animal(dbo, post.integer("animal")) if a is None: raise utils.ASMValidationError("Adoption POST has an invalid animal ID: %d" % post.integer("animal")) al.debug("Creating adoption for %d (%s - %s)" % (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]), "movement.insert_adoption_from_form", dbo) creating.append(a.ID) # If the animal is bonded to other animals, we call this function # again with a copy of the data and the bonded animal substituted # so we can create their adoption records too. We only do this if # the other animals are still on shelter (therefore alive). if a.BONDEDANIMALID is not None and a.BONDEDANIMALID != 0 and a.BONDEDANIMAL1ARCHIVED == 0 and a.BONDEDANIMALID not in creating: al.debug("Found bond to animal %d, creating adoption..." % a.BONDEDANIMALID, "movement.insert_adoption_from_form", dbo) newdata = dict(post.data) newdata["animal"] = str(a.BONDEDANIMALID) insert_adoption_from_form(dbo, username, utils.PostedData(newdata, dbo.locale), creating, create_payments = False) if a.BONDEDANIMAL2ID is not None and a.BONDEDANIMAL2ID != 0 and a.BONDEDANIMAL2ARCHIVED == 0 and a.BONDEDANIMAL2ID not in creating: al.debug("Found bond to animal %d, creating adoption..." % a.BONDEDANIMAL2ID, "movement.insert_adoption_from_form", dbo) newdata = dict(post.data) newdata["animal"] = str(a.BONDEDANIMAL2ID) insert_adoption_from_form(dbo, username, utils.PostedData(newdata, dbo.locale), creating, create_payments = False) cancel_reserves = configuration.cancel_reserves_on_adoption(dbo) # Prepare a dictionary of data for the movement table via insert_movement_from_form move_dict = { "person" : post["person"], "animal" : post["animal"], "adoptionno" : post["movementnumber"], "movementdate" : post["movementdate"], "type" : str(ADOPTION), "donation" : post["amount"], "insurance" : post["insurance"], "returncategory" : configuration.default_return_reason(dbo), "trial" : post["trial"], "trialenddate" : post["trialenddate"] } # Is this animal currently on foster? If so, return the foster fm = get_animal_movements(dbo, post.integer("animal")) for m in fm: if m.MOVEMENTTYPE == FOSTER and m.RETURNDATE is None: return_movement(dbo, m["ID"], post.integer("animal"), post.date("movementdate")) # Is this animal current at a retailer? If so, return it from the # retailer and set the originalretailermovement and retailerid fields # on our new adoption movement so it can be linked back for m in fm: if m.MOVEMENTTYPE == RETAILER and m.RETURNDATE is None: return_movement(dbo, m.ID, post.integer("animal"), post.date("movementdate")) move_dict["originalretailermovement"] = str(m.ID) move_dict["retailer"] = str(m["OWNERID"]) # Did we say we'd like to flag the owner as homechecked? if post.boolean("homechecked") == 1: dbo.update("owner", post.integer("person"), { "IDCheck": 1, "DateLastHomeChecked": dbo.today() }, username) # If the animal was flagged as not available for adoption, then it # shouldn't be since we've just adopted it. dbo.update("animal", a.ID, { "IsNotAvailableForAdoption": 0 }) # Is the animal reserved to the person adopting? movementid = 0 for m in fm: if m.MOVEMENTTYPE == NO_MOVEMENT and m.RESERVATIONDATE is not None \ and m.RESERVATIONCANCELLEDDATE is None and m.ANIMALID == post.integer("animal") \ and m.OWNERID == post.integer("person"): # yes - update the existing movement movementid = m.ID move_dict["movementid"] = str(movementid) move_dict["adoptionno"] = utils.padleft(movementid, 6) move_dict["reservationdate"] = str(i18n.python2display(l, m.RESERVATIONDATE)) move_dict["comments"] = utils.nulltostr(m.COMMENTS) break elif cancel_reserves and m.MOVEMENTTYPE == NO_MOVEMENT and m.RESERVATIONDATE is not None \ and m.RESERVATIONCANCELLEDDATE is None: # no, but it's reserved to someone else and we're cancelling # reserves on adoption dbo.update("adoption", m.ID, { "ReservationCancelledDate": post.date("movementdate") }, username) if movementid != 0: update_movement_from_form(dbo, username, utils.PostedData(move_dict, l)) else: movementid = insert_movement_from_form(dbo, username, utils.PostedData(move_dict, l)) # Create any payments if create_payments: financial.insert_donations_from_form(dbo, username, post, post["movementdate"], False, post["person"], post["animal"], movementid) # Then any boarding cost record cost_amount = post.integer("costamount") cost_type = post["costtype"] cost_create = post.integer("costcreate") if cost_amount > 0 and cost_type != "" and cost_create == 1: boc_dict = { "animalid" : post["animal"], "type" : cost_type, "costdate" : post["movementdate"], "costpaid" : post["movementdate"], "cost" : post["costamount"] } animal.insert_cost_from_form(dbo, username, utils.PostedData(boc_dict, l)) return movementid
"Could not find page '%s' in Facebook user accounts list (%s)" % (page_name, accounts_list)) # If we're posting as the page, we can only post to the page. # switch us to post using the page's access token if post_as == "page": post_to = page_id access_token = page_access_token # If we're posting as us, but to a page, post to the page # but stick with the user's access_token if page_name != "": post_to = page_id # Grab the animal details a = animal.get_animal(dbo, utils.cint(oauth_state[1:])) # Bail out if we have a problem if a is None: raise utils.ASMValidationError( "Facebook response did not contain a valid animal ID (got %s)" % oauth_state[1:]) # Generate the body of the post from our facebook template tags = wordprocessor.animal_tags(dbo, a) template = configuration.facebook_template(dbo) posttext = wordprocessor.substitute_tags(template, tags, False, "$$", "$$") # Post on the wall try:
if page_name != "" and page_id == "": raise utils.ASMValidationError("Could not find page '%s' in Facebook user accounts list (%s)" % (page_name, accounts_list)) # If we're posting as the page, we can only post to the page. # switch us to post using the page's access token if post_as == "page": post_to = page_id access_token = page_access_token # If we're posting as us, but to a page, post to the page # but stick with the user's access_token if page_name != "": post_to = page_id # Grab the animal details a = animal.get_animal(dbo, utils.cint(oauth_state[1:])) # Bail out if we have a problem if a is None: raise utils.ASMValidationError("Facebook response did not contain a valid animal ID (got %s)" % oauth_state[1:]) # Generate the body of the post from our facebook template tags = wordprocessor.animal_tags(dbo, a) template = configuration.facebook_template(dbo) posttext = wordprocessor.substitute_tags(template, tags, False, "$$", "$$") # Post on the wall try: l = dbo.locale fb_url = "https://graph.facebook.com/%s/photos?access_token=%s" % (post_to, access_token)
def csvexport_animals(dbo, dataset, animalids = "", includephoto = False): """ Export CSV data for a set of animals. dataset: The named set of data to use animalids: If dataset == selshelter, a comma separated list of animals to export includephoto: Output a base64 encoded version of the animal's photo if True """ l = dbo.locale q = "" if dataset == "all": q = "SELECT ID FROM animal ORDER BY ID" elif dataset == "shelter": q = "SELECT ID FROM animal WHERE Archived=0 ORDER BY ID" elif dataset == "nonshelter": q = "SELECT ID FROM animal WHERE NonShelterAnimal=1 ORDER BY ID" elif dataset == "selshelter": q = "SELECT ID FROM animal WHERE ID IN (%s) ORDER BY ID" % animalids ids = dbo.query(q) rows = [] for aid in ids: row = collections.OrderedDict() a = animal.get_animal(dbo, aid.ID) if a is None: continue row["ANIMALCODE"] = a["SHELTERCODE"] row["ANIMALNAME"] = a["ANIMALNAME"] if includephoto: row["ANIMALIMAGE"] = "" if a["WEBSITEIMAGECOUNT"] > 0 and includephoto: mdate, mdata = media.get_image_file_data(dbo, "animal", a["ID"]) row["ANIMALIMAGE"] = "data:image/jpg;base64,%s" % base64.b64encode(mdata) row["ANIMALSEX"] = a["SEXNAME"] row["ANIMALTYPE"] = a["ANIMALTYPENAME"] row["ANIMALCOLOR"] = a["BASECOLOURNAME"] row["ANIMALBREED1"] = a["BREEDNAME1"] row["ANIMALBREED2"] = a["BREEDNAME2"] row["ANIMALDOB"] = i18n.python2display(l, a["DATEOFBIRTH"]) row["ANIMALLOCATION"] = a["SHELTERLOCATIONNAME"] row["ANIMALUNIT"] = a["SHELTERLOCATIONUNIT"] row["ANIMALSPECIES"] = a["SPECIESNAME"] row["ANIMALCOMMENTS"] = a["ANIMALCOMMENTS"] row["ANIMALHIDDENDETAILS"] = a["HIDDENANIMALDETAILS"] row["ANIMALHEALTHPROBLEMS"] = a["HEALTHPROBLEMS"] row["ANIMALMARKINGS"] = a["MARKINGS"] row["ANIMALREASONFORENTRY"] = a["REASONFORENTRY"] row["ANIMALNEUTERED"] = a["NEUTERED"] row["ANIMALNEUTEREDDATE"] = i18n.python2display(l, a["NEUTEREDDATE"]) row["ANIMALMICROCHIP"] = a["IDENTICHIPNUMBER"] row["ANIMALMICROCHIPDATE"] = i18n.python2display(l, a["IDENTICHIPDATE"]) row["ANIMALENTRYDATE"] = i18n.python2display(l, a["DATEBROUGHTIN"]) row["ANIMALDECEASEDDATE"] = i18n.python2display(l, a["DECEASEDDATE"]) row["ANIMALNOTFORADOPTION"] = a["ISNOTAVAILABLEFORADOPTION"] row["ANIMALNONSHELTER"] = a["NONSHELTERANIMAL"] row["ANIMALGOODWITHCATS"] = a["ISGOODWITHCATSNAME"] row["ANIMALGOODWITHDOGS"] = a["ISGOODWITHDOGSNAME"] row["ANIMALGOODWITHKIDS"] = a["ISGOODWITHCHILDRENNAME"] row["ANIMALHOUSETRAINED"] = a["ISHOUSETRAINEDNAME"] row["ORIGINALOWNERTITLE"] = a["ORIGINALOWNERTITLE"] row["ORIGINALOWNERINITIALS"] = a["ORIGINALOWNERINITIALS"] row["ORIGINALOWNERFIRSTNAME"] = a["ORIGINALOWNERFORENAMES"] row["ORIGINALOWNERLASTNAME"] = a["ORIGINALOWNERSURNAME"] row["ORIGINALOWNERADDRESS"] = a["ORIGINALOWNERADDRESS"] row["ORIGINALOWNERCITY"] = a["ORIGINALOWNERTOWN"] row["ORIGINALOWNERSTATE"] = a["ORIGINALOWNERCOUNTY"] row["ORIGINALOWNERZIPCODE"] = a["ORIGINALOWNERPOSTCODE"] row["ORIGINALOWNERHOMEPHONE"] = a["ORIGINALOWNERHOMETELEPHONE"] row["ORIGINALOWNERWORKPHONE"] = a["ORIGINALOWNERWORKTELEPHONE"] row["ORIGINALOWNERCELLPHONE"] = a["ORIGINALOWNERMOBILETELEPHONE"] row["ORIGINALOWNEREMAIL"] = a["ORIGINALOWNEREMAILADDRESS"] row["MOVEMENTTYPE"] = a["ACTIVEMOVEMENTTYPE"] row["MOVEMENTDATE"] = i18n.python2display(l, a["ACTIVEMOVEMENTDATE"]) row["PERSONTITLE"] = a["CURRENTOWNERTITLE"] row["PERSONINITIALS"] = a["CURRENTOWNERINITIALS"] row["PERSONFIRSTNAME"] = a["CURRENTOWNERFORENAMES"] row["PERSONLASTNAME"] = a["CURRENTOWNERSURNAME"] row["PERSONADDRESS"] = a["CURRENTOWNERADDRESS"] row["PERSONCITY"] = a["CURRENTOWNERTOWN"] row["PERSONSTATE"] = a["CURRENTOWNERCOUNTY"] row["PERSONZIPCODE"] = a["CURRENTOWNERPOSTCODE"] row["PERSONFOSTERER"] = a["ACTIVEMOVEMENTTYPE"] == 2 and 1 or 0 row["PERSONHOMEPHONE"] = a["CURRENTOWNERHOMETELEPHONE"] row["PERSONWORKPHONE"] = a["CURRENTOWNERWORKTELEPHONE"] row["PERSONCELLPHONE"] = a["CURRENTOWNERMOBILETELEPHONE"] row["PERSONEMAIL"] = a["CURRENTOWNEREMAILADDRESS"] row["VACCINATIONTYPE"] = "" row["VACCINATIONDUEDATE"] = "" row["VACCINATIONGIVENDATE"] = "" row["VACCINATIONEXPIRESDATE"] = "" row["VACCINATIONMANUFACTURER"] = "" row["VACCINATIONBATCHNUMBER"] = "" row["VACCINATIONCOMMENTS"] = "" row["MEDICALNAME"] = "" row["MEDICALDOSAGE"] = "" row["MEDICALGIVENDATE"] = "" row["MEDICALCOMMENTS"] = "" rows.append(row) for v in medical.get_vaccinations(dbo, a["ID"]): row = collections.OrderedDict() row["VACCINATIONTYPE"] = v["VACCINATIONTYPE"] row["VACCINATIONDUEDATE"] = i18n.python2display(l, v["DATEREQUIRED"]) row["VACCINATIONGIVENDATE"] = i18n.python2display(l, v["DATEOFVACCINATION"]) row["VACCINATIONEXPIRESDATE"] = i18n.python2display(l, v["DATEEXPIRES"]) row["VACCINATIONMANUFACTURER"] = v["MANUFACTURER"] row["VACCINATIONBATCHNUMBER"] = v["BATCHNUMBER"] row["VACCINATIONCOMMENTS"] = v["COMMENTS"] row["ANIMALCODE"] = a["SHELTERCODE"] row["ANIMALNAME"] = a["ANIMALNAME"] rows.append(row) for m in medical.get_regimens(dbo, a["ID"]): row = collections.OrderedDict() row["MEDICALNAME"] = m["TREATMENTNAME"] row["MEDICALDOSAGE"] = m["DOSAGE"] row["MEDICALGIVENDATE"] = i18n.python2display(l, m["STARTDATE"]) row["MEDICALCOMMENTS"] = m["COMMENTS"] row["ANIMALCODE"] = a["SHELTERCODE"] row["ANIMALNAME"] = a["ANIMALNAME"] rows.append(row) del a if len(rows) == 0: return "" keys = rows[0].keys() out = StringIO() dict_writer = csv.DictWriter(out, keys) dict_writer.writeheader() dict_writer.writerows(rows) return out.getvalue()
def test_get_animals_brief(self): assert animal.get_animals_brief([ animal.get_animal(base.get_dbo(), self.nid), ])
def insert_reclaim_from_form(dbo, username, post): """f Inserts a movement from the workflow adopt an animal screen. Returns the new movement id """ l = dbo.locale # Validate that we have a movement date before doing anthing if None == post.date("movementdate"): raise utils.ASMValidationError(i18n._("Reclaim movements must have a valid reclaim date.", l)) # Get the animal record for this reclaim a = animal.get_animal(dbo, post.integer("animal")) if a is None: raise utils.ASMValidationError("Reclaim POST has an invalid animal ID: %d" % post.integer("animal")) al.debug("Creating reclaim for %d (%s - %s)" % (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]), "movement.insert_reclaim_from_form", dbo) # Prepare a dictionary of data for the movement table via insert_movement_from_form move_dict = { "person" : post["person"], "animal" : post["animal"], "adoptionno" : post["movementnumber"], "movementdate" : post["movementdate"], "type" : str(RECLAIMED), "donation" : post["amount"], "returncategory" : configuration.default_return_reason(dbo) } # Is this animal currently on foster? If so, return the foster fm = get_animal_movements(dbo, post.integer("animal")) for m in fm: if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], post.integer("animal"), post.date("movementdate")) # Is this animal current at a retailer? If so, return it from the # retailer and set the originalretailermovement and retailerid fields # on our new adoption movement so it can be linked back for m in fm: if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None: return_movement(dbo, m["ID"], post.integer("animal"), post.date("movementdate")) move_dict["originalretailermovement"] = str(m["ID"]) move_dict["retailer"] = str(m["OWNERID"]) # If the animal was flagged as not available for adoption, then it # shouldn't be since we've just reclaimed it. db.execute(dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" % post["animal"]) # Is the animal reserved? Should clear it if so cancel_reserves = configuration.cancel_reserves_on_adoption(dbo) for m in fm: if cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \ and m["RESERVATIONCANCELLEDDATE"] is None: db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \ ( post.db_date("movementdate"), m["ID"] )) movementid = insert_movement_from_form(dbo, username, utils.PostedData(move_dict, l)) # Create any payments financial.insert_donations_from_form(dbo, username, post, post["movementdate"], False, post["person"], post["animal"], movementid) # Then any boarding cost record cost_amount = post.integer("costamount") cost_type = post["costtype"] cost_create = post.integer("costcreate") if cost_amount > 0 and cost_type != "" and cost_create == 1: boc_dict = { "animalid" : post["animal"], "type" : cost_type, "costdate" : post["movementdate"], "costpaid" : post["movementdate"], "cost" : post["costamount"] } animal.insert_cost_from_form(dbo, username, utils.PostedData(boc_dict, l)) return movementid