Example #1
0
def create_waitinglist(dbo, username, collationid):
    """
    Creates a waitinglist record from the incoming form data with collationid.
    Also, attaches the form to the waiting list as media.
    """
    l = dbo.locale
    fields = get_onlineformincoming_detail(dbo, collationid)
    d = {}
    d["dateputon"] = i18n.python2display(l, i18n.now(dbo.timezone))
    d["urgency"] = "5"
    for f in fields:
        if f["FIELDNAME"] == "species":
            d["species"] = guess_species(dbo, f["VALUE"])
        if f["FIELDNAME"] == "description": d["description"] = f["VALUE"]
        if f["FIELDNAME"] == "reason": d["reasonforwantingtopart"] = f["VALUE"]
    if not d.has_key("species"): d["species"] = guess_species(dbo, "")
    # Have we got enough info to create the waiting list record? We need a description
    if not d.has_key("description"):
        raise utils.ASMValidationError(
            i18n._(
                "There is not enough information in the form to create a waiting list record (need a description).",
                l))
    # We need the person record before we create the waiting list
    collationid, personid, personname = create_person(dbo, username,
                                                      collationid)
    d["owner"] = personid
    # Create the waiting list
    wlid = waitinglist.insert_waitinglist_from_form(dbo, d, username)
    # Attach the form to the waiting list
    formname = get_onlineformincoming_name(dbo, collationid)
    formhtml = get_onlineformincoming_html(dbo, collationid)
    media.create_document_media(dbo, username, media.WAITINGLIST, wlid,
                                formname, formhtml)
    return (collationid, wlid, utils.padleft(wlid, 6) + " - " + personname)
Example #2
0
File: clinic.py Project: tgage/asm3
def insert_payment_from_appointment(dbo, username, appointmentid, post):
    """
    Creates a payment record from an appointment via the create payment dialog.
    """
    l = dbo.locale
    c = get_appointment(dbo, appointmentid)
    d = {
        "person":
        str(c.OwnerID),
        "animal":
        str(c.AnimalID),
        "type":
        post["paymenttype"],
        "payment":
        post["paymentmethod"],
        "amount":
        str(c.Amount),
        "due":
        post["due"],
        "received":
        post["received"],
        "vat":
        utils.iif(c.IsVAT == 1, "on", ""),
        "vatrate":
        str(c.VATRate),
        "vatamount":
        str(c.VATAmount),
        "comments":
        i18n._("Appointment {0}. {1} on {2} for {3}").format(
            utils.padleft(c.ID, 6), c.OWNERNAME,
            i18n.python2display(l, c.DATETIME), c.ANIMALNAME)
    }
    return financial.insert_donation_from_form(dbo, username,
                                               utils.PostedData(d, l))
Example #3
0
def create_waitinglist(dbo, username, collationid):
    """
    Creates a waitinglist record from the incoming form data with collationid.
    Also, attaches the form to the waiting list as media.
    """
    l = dbo.locale
    fields = get_onlineformincoming_detail(dbo, collationid)
    d = {}
    d["dateputon"] = i18n.python2display(l, i18n.now(dbo.timezone))
    d["urgency"] = "5"
    for f in fields:
        if f["FIELDNAME"] == "species": d["species"] = guess_species(dbo, f["VALUE"])
        if f["FIELDNAME"] == "description": d["description"] = f["VALUE"]
        if f["FIELDNAME"] == "reason": d["reasonforwantingtopart"] = f["VALUE"]
    if not d.has_key("species"): d["species"] = guess_species(dbo, "")
    # Have we got enough info to create the waiting list record? We need a description
    if not d.has_key("description"):
        raise utils.ASMValidationError(i18n._("There is not enough information in the form to create a waiting list record (need a description).", l))
    # We need the person record before we create the waiting list
    collationid, personid, personname = create_person(dbo, username, collationid)
    d["owner"] = personid
    # Create the waiting list
    wlid = waitinglist.insert_waitinglist_from_form(dbo, d, username)
    # Attach the form to the waiting list
    formname = get_onlineformincoming_name(dbo, collationid)
    formhtml = get_onlineformincoming_html(dbo, collationid)
    media.create_document_media(dbo, username, media.WAITINGLIST, wlid, formname, formhtml )
    return (collationid, wlid, utils.padleft(wlid, 6) + " - " + personname)
Example #4
0
def create_animalcontrol(dbo, username, collationid):
    """
    Creates a animal control/incident record from the incoming form data with 
    collationid.
    Also, attaches the form to the incident as media.
    """
    l = dbo.locale
    fields = get_onlineformincoming_detail(dbo, collationid)
    d = {}
    d["incidentdate"] = i18n.python2display(l, i18n.now(dbo.timezone))
    d["incidenttime"] = i18n.format_time_now(dbo.timezone)
    d["calldate"] = d["incidentdate"]
    d["calltime"] = d["incidenttime"]
    d["incidenttype"] = 1
    for f in fields:
        if f["FIELDNAME"] == "callnotes": d["callnotes"] = f["VALUE"]
        if f["FIELDNAME"] == "dispatchaddress": d["dispatchaddress"] = f["VALUE"]
        if f["FIELDNAME"] == "dispatchcity": d["dispatchtown"] = f["VALUE"]
        if f["FIELDNAME"] == "dispatchstate": d["dispatchcounty"] = f["VALUE"]
        if f["FIELDNAME"] == "dispatchzipcode": d["dispatchpostcode"] = f["VALUE"]
    # Have we got enough info to create the animal control record? We need notes and dispatchaddress
    if not d.has_key("callnotes") or not d.has_key("dispatchaddress"):
        raise utils.ASMValidationError(i18n._("There is not enough information in the form to create an incident record (need call notes and dispatch address).", l))
    # We need the person/caller record before we create the incident
    collationid, personid, personname = create_person(dbo, username, collationid)
    d["caller"] = personid
    # Create the incident 
    incidentid = animalcontrol.insert_animalcontrol_from_form(dbo, utils.PostedData(d, dbo.locale), username)
    # Attach the form to the incident
    formname = get_onlineformincoming_name(dbo, collationid)
    formhtml = get_onlineformincoming_html(dbo, collationid)
    media.create_document_media(dbo, username, media.ANIMALCONTROL, incidentid, formname, formhtml )
    return (collationid, incidentid, utils.padleft(incidentid, 6) + " - " + personname)
Example #5
0
def insert_movement_from_form(dbo, username, data):
    """
    Creates a movement record from posted form data 
    """
    movementid = db.get_id(dbo, "adoption")
    adoptionno = utils.df_ks(data, "adoptionno")
    animalid = utils.df_ki(data, "animal")
    if adoptionno == "":
        # No adoption number was supplied, generate a
        # unique number from the movementid
        idx = movementid
        while True:
            adoptionno = utils.padleft(idx, 6)
            data["adoptionno"] = adoptionno
            if 0 == db.query_int(
                    dbo,
                    "SELECT COUNT(*) FROM adoption WHERE AdoptionNumber LIKE '%s'"
                    % adoptionno):
                break
            else:
                idx += 1

    validate_movement_form_data(dbo, data)
    l = dbo.locale
    sql = db.make_insert_user_sql(
        dbo, "adoption", username,
        (("ID", db.di(movementid)), ("AdoptionNumber", db.ds(adoptionno)),
         ("OwnerID", db.di(utils.df_ki(data, "person"))),
         ("RetailerID", db.di(utils.df_ki(data, "retailer"))),
         ("AnimalID", db.di(utils.df_ki(data, "animal"))),
         ("OriginalRetailerMovementID",
          db.di(utils.df_ki(data, "originalretailermovement"))),
         ("MovementDate", utils.df_d(data, "movementdate", l)),
         ("MovementType", utils.df_s(data, "type")),
         ("ReturnDate", utils.df_d(data, "returndate", l)),
         ("ReturnedReasonID", utils.df_s(data, "returncategory")),
         ("Donation", utils.df_m(data, "donation", l)),
         ("InsuranceNumber", utils.df_t(data, "insurance")),
         ("ReasonForReturn", utils.df_t(data, "reason")),
         ("ReservationDate", utils.df_d(data, "reservationdate", l)),
         ("ReservationCancelledDate",
          utils.df_d(data, "reservationcancelled",
                     l)), ("IsTrial", utils.df_c(data, "trial")),
         ("IsPermanentFoster", utils.df_c(data, "permanentfoster")),
         ("TrialEndDate", utils.df_d(data, "trialenddate", l)),
         ("Comments", utils.df_t(data, "comments"))))
    db.execute(dbo, sql)
    audit.create(dbo, username, "adoption", str(movementid))
    animal.update_animal_status(dbo, animalid)
    animal.update_variable_animal_data(dbo, animalid)
    update_movement_donation(dbo, movementid)
    return movementid
Example #6
0
def insert_movement_from_form(dbo, username, post):
    """
    Creates a movement record from posted form data 
    """
    movementid = dbo.get_id("adoption")
    adoptionno = post["adoptionno"]
    animalid = post.integer("animal")

    if adoptionno == "": 
        # No adoption number was supplied, generate a
        # unique number from the movementid
        idx = movementid
        while True:
            adoptionno = utils.padleft(idx, 6)
            post.data["adoptionno"] = adoptionno
            if 0 == dbo.query_int("SELECT COUNT(*) FROM adoption WHERE AdoptionNumber LIKE ?", [adoptionno]):
                break
            else:
                idx += 1

    validate_movement_form_data(dbo, post)

    dbo.insert("adoption", {
        "ID":                           movementid,
        "AdoptionNumber":               adoptionno,
        "OwnerID":                      post.integer("person"),
        "RetailerID":                   post.integer("retailer"),
        "AnimalID":                     post.integer("animal"),
        "OriginalRetailerMovementID":   post.integer("originalretailermovement"),
        "MovementDate":                 post.date("movementdate"),
        "MovementType":                 post.integer("type"),
        "ReturnDate":                   post.date("returndate"),
        "ReturnedReasonID":             post.integer("returncategory"),
        "Donation":                     post.integer("donation"),
        "InsuranceNumber":              post["insurance"],
        "ReasonForReturn":              post["reason"],
        "ReturnedByOwnerID":            post.integer("returnedby"),
        "ReservationDate":              post.date("reservationdate"),
        "ReservationCancelledDate":     post.date("reservationcancelled"),
        "ReservationStatusID":          post.integer("reservationstatus"),
        "IsTrial":                      post.boolean("trial"),
        "IsPermanentFoster":            post.boolean("permanentfoster"),
        "TrialEndDate":                 post.date("trialenddate"),
        "Comments":                     post["comments"]
    }, username, generateID=False)

    animal.update_animal_status(dbo, animalid)
    animal.update_variable_animal_data(dbo, animalid)
    update_movement_donation(dbo, movementid)

    return movementid
Example #7
0
def create_foundanimal(dbo, username, collationid):
    """
    Creates a found animal record from the incoming form data with collationid.
    Also, attaches the form to the found animal as media.
    """
    l = dbo.locale
    fields = get_onlineformincoming_detail(dbo, collationid)
    d = {}
    d["datefound"] = i18n.python2display(l, i18n.now(dbo.timezone))
    d["datereported"] = i18n.python2display(l, i18n.now(dbo.timezone))
    for f in fields:
        if f["FIELDNAME"] == "species":
            d["species"] = guess_species(dbo, f["VALUE"])
        if f["FIELDNAME"] == "sex": d["sex"] = guess_sex(dbo, f["VALUE"])
        if f["FIELDNAME"] == "breed": d["breed"] = guess_breed(dbo, f["VALUE"])
        if f["FIELDNAME"] == "agegroup":
            d["agegroup"] = guess_agegroup(dbo, f["VALUE"])
        if f["FIELDNAME"] == "color":
            d["colour"] = guess_colour(dbo, f["VALUE"])
        if f["FIELDNAME"] == "colour":
            d["colour"] = guess_colour(dbo, f["VALUE"])
        if f["FIELDNAME"] == "description": d["markings"] = f["VALUE"]
        if f["FIELDNAME"] == "areafound": d["areafound"] = f["VALUE"]
        if f["FIELDNAME"] == "areapostcode": d["areapostcode"] = f["VALUE"]
        if f["FIELDNAME"] == "areazipcode": d["areazipcode"] = f["VALUE"]
    if not d.has_key("species"): d["species"] = guess_species(dbo, "")
    if not d.has_key("sex"): d["sex"] = guess_sex(dbo, "")
    if not d.has_key("breed"): d["breed"] = guess_breed(dbo, "")
    if not d.has_key("agegroup"): d["agegroup"] = guess_agegroup(dbo, "")
    if not d.has_key("colour"): d["colour"] = guess_colour(dbo, "")
    # Have we got enough info to create the found animal record? We need a description and areafound
    if not d.has_key("markings") or not d.has_key("areafound"):
        raise utils.ASMValidationError(
            i18n._(
                "There is not enough information in the form to create a found animal record (need a description and area found).",
                l))
    # We need the person record before we create the found animal
    collationid, personid, personname = create_person(dbo, username,
                                                      collationid)
    d["owner"] = personid
    # Create the found animal
    foundanimalid = lostfound.insert_foundanimal_from_form(dbo, d, username)
    # Attach the form to the found animal
    formname = get_onlineformincoming_name(dbo, collationid)
    formhtml = get_onlineformincoming_html(dbo, collationid)
    media.create_document_media(dbo, username, media.FOUNDANIMAL,
                                foundanimalid, formname, formhtml)
    return (collationid, foundanimalid,
            utils.padleft(foundanimalid, 6) + " - " + personname)
Example #8
0
def insert_movement_from_form(dbo, username, data):
    """
    Creates a movement record from posted form data 
    """
    movementid = db.get_id(dbo, "adoption")
    adoptionno = utils.df_ks(data, "adoptionno")
    animalid = utils.df_ki(data, "animal")
    if adoptionno == "": 
        # No adoption number was supplied, generate a
        # unique number from the movementid
        idx = movementid
        while True:
            adoptionno = utils.padleft(idx, 6)
            data["adoptionno"] = adoptionno
            if 0 == db.query_int(dbo, "SELECT COUNT(*) FROM adoption WHERE AdoptionNumber LIKE '%s'" % adoptionno):
                break
            else:
                idx += 1

    validate_movement_form_data(dbo, data)
    l = dbo.locale
    sql = db.make_insert_user_sql(dbo, "adoption", username, ( 
        ( "ID", db.di(movementid)),
        ( "AdoptionNumber", db.ds(adoptionno)),
        ( "OwnerID", db.di(utils.df_ki(data, "person"))),
        ( "RetailerID", db.di(utils.df_ki(data, "retailer"))),
        ( "AnimalID", db.di(utils.df_ki(data, "animal"))),
        ( "OriginalRetailerMovementID", db.di(utils.df_ki(data, "originalretailermovement"))),
        ( "MovementDate", utils.df_d(data, "movementdate", l)),
        ( "MovementType", utils.df_s(data, "type")),
        ( "ReturnDate", utils.df_d(data, "returndate", l)),
        ( "ReturnedReasonID", utils.df_s(data, "returncategory")),
        ( "Donation", utils.df_m(data, "donation", l)),
        ( "InsuranceNumber", utils.df_t(data, "insurance")),
        ( "ReasonForReturn", utils.df_t(data, "reason")),
        ( "ReservationDate", utils.df_d(data, "reservationdate", l)),
        ( "ReservationCancelledDate", utils.df_d(data, "reservationcancelled", l)),
        ( "IsTrial", utils.df_c(data, "trial")),
        ( "IsPermanentFoster", utils.df_c(data, "permanentfoster")),
        ( "TrialEndDate", utils.df_d(data, "trialenddate", l)),
        ( "Comments", utils.df_t(data, "comments"))
        ))
    db.execute(dbo, sql)
    audit.create(dbo, username, "adoption", str(movementid))
    animal.update_animal_status(dbo, animalid)
    animal.update_variable_animal_data(dbo, animalid)
    update_movement_donation(dbo, movementid)
    return movementid
Example #9
0
def create_foundanimal(dbo, username, collationid):
    """
    Creates a found animal record from the incoming form data with collationid.
    Also, attaches the form to the found animal as media.
    """
    l = dbo.locale
    fields = get_onlineformincoming_detail(dbo, collationid)
    d = {}
    d["datefound"] = i18n.python2display(l, i18n.now(dbo.timezone))
    d["datereported"] = i18n.python2display(l, i18n.now(dbo.timezone))
    for f in fields:
        if f["FIELDNAME"] == "species": d["species"] = guess_species(dbo, f["VALUE"])
        if f["FIELDNAME"] == "sex": d["sex"] = guess_sex(dbo, f["VALUE"])
        if f["FIELDNAME"] == "breed": d["breed"] = guess_breed(dbo, f["VALUE"])
        if f["FIELDNAME"] == "agegroup": d["agegroup"] = guess_agegroup(dbo, f["VALUE"])
        if f["FIELDNAME"] == "color": d["colour"] = guess_colour(dbo, f["VALUE"])
        if f["FIELDNAME"] == "colour": d["colour"] = guess_colour(dbo, f["VALUE"])
        if f["FIELDNAME"] == "description": d["markings"] = f["VALUE"]
        if f["FIELDNAME"] == "areafound": d["areafound"] = f["VALUE"]
        if f["FIELDNAME"] == "areapostcode": d["areapostcode"] = f["VALUE"]
        if f["FIELDNAME"] == "areazipcode": d["areazipcode"] = f["VALUE"]
    if not d.has_key("species"): d["species"] = guess_species(dbo, "")
    if not d.has_key("sex"): d["sex"] = guess_sex(dbo, "")
    if not d.has_key("breed"): d["breed"] = guess_breed(dbo, "")
    if not d.has_key("agegroup"): d["agegroup"] = guess_agegroup(dbo, "")
    if not d.has_key("colour"): d["colour"] = guess_colour(dbo, "")
    # Have we got enough info to create the found animal record? We need a description and areafound
    if not d.has_key("markings") or not d.has_key("areafound"):
        raise utils.ASMValidationError(i18n._("There is not enough information in the form to create a found animal record (need a description and area found).", l))
    # We need the person record before we create the found animal
    collationid, personid, personname = create_person(dbo, username, collationid)
    d["owner"] = personid
    # Create the found animal
    foundanimalid = lostfound.insert_foundanimal_from_form(dbo, d, username)
    # Attach the form to the found animal
    formname = get_onlineformincoming_name(dbo, collationid)
    formhtml = get_onlineformincoming_html(dbo, collationid)
    media.create_document_media(dbo, username, media.FOUNDANIMAL, foundanimalid, formname, formhtml )
    return (collationid, foundanimalid, utils.padleft(foundanimalid, 6) + " - " + personname)
Example #10
0
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
Example #11
0
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
Example #12
0
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
Example #13
0
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
Example #14
0
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