Exemple #1
0
def get_lostanimal_find_simple(dbo, query = "", limit = 0, onlyindexed = False):
    """
    Returns rows for simple lost animal searches.
    query: The search criteria
    """
    ors = []
    query = query.replace("'", "`")
    def add(field):
        return utils.where_text_filter(dbo, field, query)
    # If no query has been given, show unfound lost animal records
    # for the last 30 days
    if query == "":
        ors.append("a.DateLost > %s AND a.DateFound Is Null" % db.dd(subtract_days(now(dbo.timezone), 30)))
    else:
        if utils.is_numeric(query):
            ors.append("a.ID = " + str(utils.cint(query)))
        ors.append(add("OwnerName"))
        ors.append(add("AreaLost"))
        ors.append(add("AreaPostcode"))
        if not onlyindexed:
            ors.append(add("SexName"))
            ors.append(add("BreedName"))
            ors.append(add("BaseColourName"))
            ors.append(add("SpeciesName"))
            ors.append(add("AgeGroup"))
            ors.append(add("DistFeat"))
            ors.append(add("Comments"))
    sql = get_lostanimal_query() + " WHERE " + " OR ".join(ors)
    if limit > 0: sql += " LIMIT " + str(limit)
    return db.query(dbo, sql)
def get_lostanimal_find_simple(dbo, query="", limit=0, onlyindexed=False):
    """
    Returns rows for simple lost animal searches.
    query: The search criteria
    """
    ors = []
    query = query.replace("'", "`")

    def add(field):
        return utils.where_text_filter(dbo, field, query)

    # If no query has been given, show unfound lost animal records
    # for the last 30 days
    if query == "":
        ors.append("a.DateLost > %s AND a.DateFound Is Null" %
                   db.dd(subtract_days(now(dbo.timezone), 30)))
    else:
        if utils.is_numeric(query):
            ors.append("a.ID = " + str(utils.cint(query)))
        ors.append(add("o.OwnerName"))
        ors.append(add("a.AreaLost"))
        ors.append(add("a.AreaPostcode"))
        if not onlyindexed:
            ors.append(add("x.Sex"))
            ors.append(add("b.BreedName"))
            ors.append(add("c.BaseColour"))
            ors.append(add("s.SpeciesName"))
            ors.append(add("a.AgeGroup"))
            ors.append(add("a.DistFeat"))
            ors.append(add("a.Comments"))
    sql = get_lostanimal_query(dbo) + " WHERE " + " OR ".join(ors)
    if limit > 0: sql += " LIMIT " + str(limit)
    return db.query(dbo, sql)
def get_animalcontrol_find_simple(dbo, query="", limit=0, onlyindexed=False):
    """
    Returns rows for simple animal control searches.
    query: The search criteria
    """
    ors = []
    query = query.replace("'", "`")

    def add(field):
        return utils.where_text_filter(dbo, field, query)

    # If no query has been given, show open animal control records
    # from the last 30 days
    if query == "":
        ors.append("ac.IncidentDateTime > %s AND ac.CompletedDate Is Null" %
                   db.dd(subtract_days(now(dbo.timezone), 30)))
    else:
        if utils.is_numeric(query):
            ors.append("ac.ID = " + str(utils.cint(query)))
        ors.append(add("co.OwnerName"))
        ors.append(add("ti.IncidentName"))
        ors.append(add("ac.DispatchAddress"))
        ors.append(add("ac.DispatchPostcode"))
        ors.append(add("o1.OwnerName"))
        ors.append(add("o2.OwnerName"))
        ors.append(add("o3.OwnerName"))
        ors.append(add("vo.OwnerName"))
        if not onlyindexed:
            ors.append(add("ac.CallNotes"))
            ors.append(add("ac.AnimalDescription"))
    sql = get_animalcontrol_query(dbo) + " WHERE " + " OR ".join(ors)
    if limit > 0: sql += " LIMIT " + str(limit)
    return db.query(dbo, sql)
Exemple #4
0
def get_treatments_outstanding(dbo, offset="m31", locationfilter=""):
    """
    Returns a recordset of shelter animals awaiting medical treatments:
    offset is m to go backwards, or p to go forwards with a number of days.
    ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME,
    TREATMENTNAME, COST, COMMENTS, NAMEDFREQUENCY, NAMEDNUMBEROFTREATMENTS,
    NAMEDSTATUS, DOSAGE, STARTDATE, TREATMENTSGIVEN, TREATMENTSREMAINING,
    TIMINGRULE, TIMINGRULEFREQUENCY, TIMINGRULENOFREQUENCIES, TREATMENTRULE
    TOTALNUMBEROFTREATMENTS, DATEREQUIRED, DATEGIVEN, TREATMENTCOMMENTS,
    TREATMENTNUMBER, TOTALTREATMENTS, GIVENBY, REGIMENID, TREATMENTID
    """
    ec = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(
            subtract_days(now(dbo.timezone),
                          offsetdays)), db.dd(now(dbo.timezone)))
    if offset.startswith("p"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(
            now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays)))
    if locationfilter != "":
        locationfilter = " AND ShelterLocation IN (%s)" % locationfilter
    return embellish_regimen(dbo.locale, db.query(dbo, "SELECT * FROM v_animalmedicaltreatment " \
        "WHERE DateRequired Is Not Null AND DateGiven Is Null " \
        "AND Status = 0 " \
        "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \
        "ORDER BY DateRequired, AnimalName" % (ec, locationfilter)))
Exemple #5
0
def get_donations(dbo, offset="m31"):
    """
    Returns a recordset of donations
    offset is m to go backwards, or p to go forwards with a number of days.
    ID, DONATIONTYPEID, DONATIONNAME, DATE, DATEDUE, DONATION,
    ISGIFTAID, FREQUENCY, FREQUENCYNAME, NEXTCREATED, COMMENTS, OWNERNAME, 
    ANIMALNAME, SHELTERCODE, OWNERID, ANIMALID
    """
    ec = ""
    order = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = "Date >= %s AND Date <= %s" % (db.dd(
            i18n.subtract_days(i18n.now(dbo.timezone),
                               offsetdays)), db.dd(i18n.now(dbo.timezone)))
        order = "Date DESC"
    elif offset.startswith("p"):
        ec = "Date Is Null AND DateDue >= %s AND DateDue <= %s" % (
            db.dd(i18n.now(dbo.timezone)),
            db.dd(i18n.add_days(i18n.now(dbo.timezone), offsetdays)))
        order = "DateDue DESC"
    elif offset.startswith("d"):
        ec = "Date Is Null AND DateDue <= %s" % (db.dd(i18n.now(dbo.timezone)))
        order = "DateDue"
    return db.query(dbo, "SELECT * FROM v_ownerdonation " \
        "WHERE %s "
        "ORDER BY %s" % (ec, order))
Exemple #6
0
def get_animalcontrol_find_simple(dbo, query = "", limit = 0):
    """
    Returns rows for simple animal control searches.
    query: The search criteria
    """
    ors = []
    query = query.replace("'", "`")
    def add(field):
        return utils.where_text_filter(dbo, field, query)
    # If no query has been given, show open animal control records
    # from the last 30 days
    if query == "":
        ors.append("ac.IncidentDateTime > %s AND ac.CompletedDate Is Null" % db.dd(subtract_days(now(dbo.timezone), 30)))
    else:
        if utils.is_numeric(query):
            ors.append("ac.ID = " + str(utils.cint(query)))
        ors.append(add("co.OwnerName"))
        ors.append(add("ti.IncidentName"))
        ors.append(add("ac.DispatchAddress"))
        ors.append(add("ac.DispatchPostcode"))
        ors.append(add("o1.OwnerName"))
        ors.append(add("o2.OwnerName"))
        ors.append(add("o3.OwnerName"))
        ors.append(add("vo.OwnerName"))
        ors.append(u"EXISTS(SELECT ad.Value FROM additional ad " \
            "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \
            "WHERE ad.LinkID=ac.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE '%%%s%%')" % (additional.INCIDENT_IN, query.lower()))
        if not dbo.is_large_db:
            ors.append(add("ac.CallNotes"))
            ors.append(add("ac.AnimalDescription"))
    sql = get_animalcontrol_query(dbo) + " WHERE " + " OR ".join(ors)
    if limit > 0: sql += " LIMIT " + str(limit)
    return db.query(dbo, sql)
Exemple #7
0
def get_foundanimal_find_simple(dbo, query = "", limit = 0):
    """
    Returns rows for simple found animal searches.
    query: The search criteria
    """
    ors = []
    query = query.replace("'", "`")
    def add(field):
        return utils.where_text_filter(dbo, field, query)
    # If no query has been given, show unreturned found animal records
    # for the last 30 days
    if query == "":
        ors.append("a.DateFound > %s AND a.ReturnToOwnerDate Is Null" % db.dd(subtract_days(now(dbo.timezone), 30)))
    else:
        if utils.is_numeric(query):
            ors.append("a.ID = " + str(utils.cint(query)))
        ors.append(add("o.OwnerName"))
        ors.append(add("a.AreaFound"))
        ors.append(add("a.AreaPostcode"))
        ors.append(u"EXISTS(SELECT ad.Value FROM additional ad " \
            "INNER JOIN additionalfield af ON af.ID = ad.AdditionalFieldID AND af.Searchable = 1 " \
            "WHERE ad.LinkID=a.ID AND ad.LinkType IN (%s) AND LOWER(ad.Value) LIKE '%%%s%%')" % (additional.FOUNDANIMAL_IN, query.lower()))
        if not dbo.is_large_db:
            ors.append(add("x.Sex"))
            ors.append(add("b.BreedName"))
            ors.append(add("c.BaseColour"))
            ors.append(add("s.SpeciesName"))
            ors.append(add("a.AgeGroup"))
            ors.append(add("a.DistFeat"))
            ors.append(add("a.Comments"))
    sql = get_foundanimal_query(dbo) + " WHERE " + " OR ".join(ors)
    if limit > 0: sql += " LIMIT " + str(limit)
    return db.query(dbo, sql)
def get_recent_adoptions(dbo, months=1):
    """
    Returns a list of adoptions in the last "months" months.
    """
    return db.query(dbo, get_movement_query(dbo) + \
        "WHERE m.MovementType = 1 AND m.MovementDate Is Not Null AND m.ReturnDate Is Null " \
        "AND m.MovementDate > %s " \
        "ORDER BY m.MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #9
0
def get_recent_transfers(dbo, months = 1):
    """
    Returns a list of transfers in the last "months" months.
    """
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE MovementType = 3 AND MovementDate Is Not Null AND ReturnDate Is Null " \
        "AND MovementDate > %s " \
        "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #10
0
def get_recent_transfers(dbo, months=1):
    """
    Returns a list of transfers in the last "months" months.
    """
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE MovementType = 3 AND MovementDate Is Not Null AND ReturnDate Is Null " \
        "AND MovementDate > %s " \
        "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #11
0
def get_recent_transfers(dbo, months = 1):
    """
    Returns a list of transfers in the last "months" months.
    """
    return db.query(dbo, get_movement_query(dbo) + \
        "WHERE m.MovementType = 3 AND m.MovementDate Is Not Null AND m.ReturnDate Is Null " \
        "AND m.MovementDate > %s " \
        "ORDER BY m.MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #12
0
def clean(dbo):
    """
    Deletes audit trail records older than three months
    """
    d = db.today()
    d = i18n.subtract_days(d, 93);
    count = db.query_int(dbo, "SELECT COUNT(*) FROM audittrail WHERE AuditDate< %s" % db.dd(d))
    al.debug("removing %d audit records older than 93 days." % count, "audit.clean", dbo)
    db.execute(dbo, "DELETE FROM audittrail WHERE AuditDate < %s" % db.dd(d))
Exemple #13
0
def get_recent_nonfosteradoption(dbo, months = 1):
    """
    Returns a list of active movements that aren't reserves,
    fosters, adoptions or transfers in the last "months" months.
    """
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE MovementType > 3 AND MovementDate Is Not Null AND ReturnDate Is Null " \
        "AND MovementDate > %s " \
        "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #14
0
def get_recent_unneutered_adoptions(dbo, months=1):
    """
    Returns a list of adoptions in the last "months" months where the
    animal remains unneutered.
    """
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE MovementType = 1 AND MovementDate Is Not Null AND ReturnDate Is Null " \
        "AND MovementDate > %s AND Neutered = 0 " \
        "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #15
0
def get_recent_nonfosteradoption(dbo, months=1):
    """
    Returns a list of active movements that aren't reserves,
    fosters, adoptions or transfers in the last "months" months.
    """
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE MovementType > 3 AND MovementDate Is Not Null AND ReturnDate Is Null " \
        "AND MovementDate > %s " \
        "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #16
0
def get_recent_unneutered_adoptions(dbo, months = 1):
    """
    Returns a list of adoptions in the last "months" months where the
    animal remains unneutered.
    """
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE MovementType = 1 AND MovementDate Is Not Null AND ReturnDate Is Null " \
        "AND MovementDate > %s AND Neutered = 0 " \
        "ORDER BY MovementDate DESC" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), months * 31)))
Exemple #17
0
def clean(dbo):
    """
    Deletes audit trail records older than three months
    """
    d = i18n.subtract_days(i18n.now(), 93)
    count = dbo.query_int(
        "SELECT COUNT(*) FROM audittrail WHERE AuditDate < ?", [d])
    al.debug("removing %d audit records older than 93 days." % count,
             "audit.clean", dbo)
    dbo.execute("DELETE FROM audittrail WHERE AuditDate < ?", [d])
Exemple #18
0
def get_active_reservations(dbo, age = 0):
    """
    Gets the list of uncancelled reservation movements.
    age: The age of the reservation in days, or 0 for all
    """
    where = ""
    if age > 0:
        where = "AND ReservationDate <= %s" % db.dd(i18n.subtract_days(i18n.now(dbo.timezone), age))
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE ReservationDate Is Not Null AND MovementDate Is Null AND MovementType = 0 AND ReturnDate Is Null " \
        "AND ReservationCancelledDate Is Null %s ORDER BY ReservationDate" % where)
def get_all_upto_today(dbo, user=""):
    """f
    Gets a list of all diary notes upto and including
    today for the user supplied (or all users if no user passed)
    LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO
    """
    sixmonths = i18n.subtract_days(i18n.now(dbo.timezone), 182)
    return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \
        "FROM diary WHERE %s " \
        "AND DiaryDateTime <= %s AND DiaryDateTime >= %s" \
        "ORDER BY DiaryDateTime DESC" % (user_role_where_clause(dbo, user), db.ddt(i18n.now(dbo.timezone)), db.ddt(sixmonths)))
Exemple #20
0
def get_completed_upto_today(dbo, user = ""):
    """
    Gets a list of completed diary notes upto and including
    today for the user supplied (or all users if no user passed)
    LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO
    """
    sixmonths = i18n.subtract_days(i18n.now(dbo.timezone), 182)
    return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \
        "FROM diary WHERE %s " \
        "AND DateCompleted Is Not Null AND DiaryDateTime <= %s AND DiaryDateTime >= %s" \
        "ORDER BY DiaryDateTime DESC" % (user_role_where_clause(dbo, user), db.ddt(i18n.now(dbo.timezone)), db.ddt(sixmonths)))
Exemple #21
0
def get_active_reservations(dbo, age=0):
    """
    Gets the list of uncancelled reservation movements.
    age: The age of the reservation in days, or 0 for all
    """
    where = ""
    if age > 0:
        where = "AND ReservationDate <= %s" % db.dd(
            i18n.subtract_days(i18n.now(dbo.timezone), age))
    return db.query(dbo, "SELECT * FROM v_adoption " \
        "WHERE ReservationDate Is Not Null AND MovementDate Is Null AND MovementType = 0 AND ReturnDate Is Null " \
        "AND ReservationCancelledDate Is Null %s ORDER BY ReservationDate" % where)
Exemple #22
0
def auto_remove_old_incoming_forms(dbo):
    """
    Automatically removes incoming forms older than the daily amount set
    """
    removeafter = configuration.auto_remove_incoming_forms_days(dbo)
    if removeafter <= 0:
        al.debug("auto remove incoming forms is off.", "onlineform.auto_remove_old_incoming_forms")
        return
    removecutoff = i18n.subtract_days(i18n.now(dbo.timezone), removeafter)
    al.debug("remove date: incoming forms < %s" % db.dd(removecutoff), "onlineform.auto_remove_old_incoming_forms")
    sql = "DELETE FROM onlineformincoming WHERE PostedDate < %s" % db.dd(removecutoff)
    count = db.execute(dbo, sql)
    al.debug("removed %d incoming forms older than %d days" % (count, int(removeafter)), "onlineform.auto_remove_old_incoming_forms", dbo)
Exemple #23
0
def auto_remove_old_incoming_forms(dbo):
    """
    Automatically removes incoming forms older than the daily amount set
    """
    removeafter = configuration.auto_remove_incoming_forms_days(dbo)
    if removeafter <= 0:
        al.debug("auto remove incoming forms is off.", "onlineform.auto_remove_old_incoming_forms")
        return
    removecutoff = i18n.subtract_days(i18n.now(dbo.timezone), removeafter)
    al.debug("remove date: incoming forms < %s" % db.dd(removecutoff), "onlineform.auto_remove_old_incoming_forms")
    sql = "DELETE FROM onlineformincoming WHERE PostedDate < %s" % db.dd(removecutoff)
    count = db.execute(dbo, sql)
    al.debug("removed %d incoming forms older than %d days" % (count, int(removeafter)), "onlineform.auto_remove_old_incoming_forms", dbo)
Exemple #24
0
def get_uncompleted_upto_today(dbo, user = "", includecreatedby = True):
    """
    Gets a list of uncompleted diary notes upto and including
    today for the user supplied (or all users if no user passed)
    LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO
    """
    sixmonths = i18n.subtract_days(i18n.now(dbo.timezone), 182)
    current = i18n.now(dbo.timezone)
    alltoday = datetime.datetime(current.year, current.month, current.day, 23, 59, 59)
    return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \
        "FROM diary WHERE %s " \
        "AND DateCompleted Is Null AND DiaryDateTime <= %s AND DiaryDateTime >= %s" \
        "ORDER BY DiaryDateTime DESC" % (user_role_where_clause(dbo, user, includecreatedby), db.ddt(alltoday), db.ddt(sixmonths)))
def get_uncompleted_upto_today(dbo, user=""):
    """
    Gets a list of uncompleted diary notes upto and including
    today for the user supplied (or all users if no user passed)
    LINKID, LINKTYPE, DIARYDATETIME, DIARYFORNAME, SUBJECT, NOTE, LINKINFO
    """
    sixmonths = i18n.subtract_days(i18n.now(dbo.timezone), 182)
    current = i18n.now(dbo.timezone)
    alltoday = datetime.datetime(current.year, current.month, current.day, 23,
                                 59, 59)
    return db.query(dbo, "SELECT *, cast(DiaryDateTime AS time) AS DiaryTime " \
        "FROM diary WHERE %s " \
        "AND DateCompleted Is Null AND DiaryDateTime <= %s AND DiaryDateTime >= %s" \
        "ORDER BY DiaryDateTime DESC" % (user_role_where_clause(dbo, user), db.ddt(alltoday), db.ddt(sixmonths)))
Exemple #26
0
def auto_cancel_reservations(dbo):
    """
    Automatically cancels reservations after the daily amount set
    """
    cancelafter = configuration.auto_cancel_reserves_days(dbo)
    if cancelafter <= 0:
        al.debug("auto reserve cancel is off.", "movement.auto_cancel_reservations")
        return
    cancelcutoff = i18n.subtract_days(i18n.now(dbo.timezone), cancelafter)
    al.debug("cutoff date: reservations < %s" % db.dd(cancelcutoff), "movement.auto_cancel_reservations")
    sql = "UPDATE adoption SET ReservationCancelledDate = %s " \
        "WHERE MovementDate Is Null AND ReservationCancelledDate Is Null AND " \
        "MovementType = 0 AND ReservationDate < %s" % ( db.dd(i18n.now(dbo.timezone)), db.dd(cancelcutoff))
    count = db.execute(dbo, sql)
    al.debug("cancelled %d reservations older than %d days" % (count, int(cancelafter)), "movement.auto_cancel_reservations", dbo)
Exemple #27
0
 def now(self, timenow=True, offset=0, settime=""):
     """ Returns now as a Python date, adjusted for the database timezone.
         timenow: if True, includes the current time
         offset:  Add this many days to now (negative values supported)
         settime: A time in HH:MM:SS format to set
     """
     d = i18n.now(self.timezone)
     if not timenow:
         d = d.replace(hour = 0, minute = 0, second = 0, microsecond = 0)
     if offset > 0:
         d = i18n.add_days(d, offset)
     if offset < 0:
         d = i18n.subtract_days(d, abs(offset))
     if settime != "":
         timebits = settime.split(":")
         d = d.replace(hour = utils.cint(timebits[0]), minute = utils.cint(timebits[1]), second = utils.cint(timebits[2]), microsecond = 0)
     return d
Exemple #28
0
def get_tests_outstanding(dbo, offset = "m31", locationfilter = ""):
    """
    Returns a recordset of animals awaiting tests:
    offset is m to go backwards, or p to go forwards with a number of days.
    ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFTEST, COMMENTS, TESTNAME, RESULTNAME, TESTTYPEID
    """
    ec = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone)))
    if offset.startswith("p"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(now(dbo.timezone)), db.dd( add_days(now(dbo.timezone), offsetdays)))
    if locationfilter != "":
        locationfilter = " AND ShelterLocation IN (%s)" % locationfilter
    return db.query(dbo, "SELECT * FROM v_animaltest " \
        "WHERE DateRequired Is Not Null AND DateOfTest Is Null " \
        "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \
        "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
Exemple #29
0
def get_vaccinations_outstanding(dbo, offset = "m31", locationfilter = ""):
    """
    Returns a recordset of animals awaiting vaccinations:
    offset is m to go backwards, or p to go forwards with a number of days.
    locationfilter is a comma separated list of internal locations to include animals in
    ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFVACCINATION, COMMENTS, VACCINATIONTYPE, VACCINATIONID
    """
    ec = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone)))
    if offset.startswith("p"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(now(dbo.timezone)), db.dd( add_days(now(dbo.timezone), offsetdays)))
    if locationfilter != "":
        locationfilter = " AND ShelterLocation IN (%s)" % locationfilter
    return db.query(dbo, "SELECT * FROM v_animalvaccination " \
        "WHERE DateRequired Is Not Null AND DateOfVaccination Is Null " \
        "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \
        "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
Exemple #30
0
def auto_cancel_reservations(dbo):
    """
    Automatically cancels reservations after the daily amount set
    """
    cancelafter = configuration.auto_cancel_reserves_days(dbo)
    if cancelafter <= 0:
        al.debug("auto reserve cancel is off.",
                 "movement.auto_cancel_reservations")
        return
    cancelcutoff = i18n.subtract_days(i18n.now(dbo.timezone), cancelafter)
    al.debug("cutoff date: reservations < %s" % db.dd(cancelcutoff),
             "movement.auto_cancel_reservations")
    sql = "UPDATE adoption SET ReservationCancelledDate = %s " \
        "WHERE MovementDate Is Null AND ReservationCancelledDate Is Null AND " \
        "MovementType = 0 AND ReservationDate < %s" % ( db.dd(i18n.now(dbo.timezone)), db.dd(cancelcutoff))
    count = db.execute(dbo, sql)
    al.debug(
        "cancelled %d reservations older than %d days" %
        (count, int(cancelafter)), "movement.auto_cancel_reservations", dbo)
Exemple #31
0
def get_tests_outstanding(dbo, offset="m31", locationfilter=""):
    """
    Returns a recordset of animals awaiting tests:
    offset is m to go backwards, or p to go forwards with a number of days.
    ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFTEST, COMMENTS, TESTNAME, RESULTNAME, TESTTYPEID
    """
    ec = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(
            subtract_days(now(dbo.timezone),
                          offsetdays)), db.dd(now(dbo.timezone)))
    if offset.startswith("p"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(
            now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays)))
    if locationfilter != "":
        locationfilter = " AND ShelterLocation IN (%s)" % locationfilter
    return db.query(dbo, "SELECT * FROM v_animaltest " \
        "WHERE DateRequired Is Not Null AND DateOfTest Is Null " \
        "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \
        "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
Exemple #32
0
def get_vaccinations_outstanding(dbo, offset="m31", locationfilter=""):
    """
    Returns a recordset of animals awaiting vaccinations:
    offset is m to go backwards, or p to go forwards with a number of days.
    locationfilter is a comma separated list of internal locations to include animals in
    ID, ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME, DATEREQUIRED, DATEOFVACCINATION, COMMENTS, VACCINATIONTYPE, VACCINATIONID
    """
    ec = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(
            subtract_days(now(dbo.timezone),
                          offsetdays)), db.dd(now(dbo.timezone)))
    if offset.startswith("p"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(
            now(dbo.timezone)), db.dd(add_days(now(dbo.timezone), offsetdays)))
    if locationfilter != "":
        locationfilter = " AND ShelterLocation IN (%s)" % locationfilter
    return db.query(dbo, "SELECT * FROM v_animalvaccination " \
        "WHERE DateRequired Is Not Null AND DateOfVaccination Is Null " \
        "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \
        "ORDER BY DateRequired, AnimalName" % (ec, locationfilter))
Exemple #33
0
def get_donations(dbo, offset = "m31"):
    """
    Returns a recordset of donations
    offset is m to go backwards, or p to go forwards with a number of days.
    ID, DONATIONTYPEID, DONATIONNAME, DATE, DATEDUE, DONATION,
    ISGIFTAID, FREQUENCY, FREQUENCYNAME, NEXTCREATED, COMMENTS, OWNERNAME, 
    ANIMALNAME, SHELTERCODE, OWNERID, ANIMALID
    """
    ec = ""
    order = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = "Date >= %s AND Date <= %s" % (db.dd( i18n.subtract_days(i18n.now(dbo.timezone), offsetdays)), db.dd(i18n.now(dbo.timezone)))
        order = "Date DESC"
    elif offset.startswith("p"):
        ec = "Date Is Null AND DateDue >= %s AND DateDue <= %s" % (db.dd(i18n.now(dbo.timezone)), db.dd(i18n.add_days(i18n.now(dbo.timezone), offsetdays)))
        order = "DateDue DESC"
    elif offset.startswith("d"):
        ec = "Date Is Null AND DateDue <= %s" % (db.dd(i18n.now(dbo.timezone)))
        order = "DateDue"
    return db.query(dbo, "SELECT * FROM v_ownerdonation " \
        "WHERE %s "
        "ORDER BY %s" % (ec, order))
Exemple #34
0
def get_treatments_outstanding(dbo, offset = "m31", locationfilter = ""):
    """
    Returns a recordset of shelter animals awaiting medical treatments:
    offset is m to go backwards, or p to go forwards with a number of days.
    ANIMALID, SHELTERCODE, ANIMALNAME, LOCATIONNAME, WEBSITEMEDIANAME,
    TREATMENTNAME, COST, COMMENTS, NAMEDFREQUENCY, NAMEDNUMBEROFTREATMENTS,
    NAMEDSTATUS, DOSAGE, STARTDATE, TREATMENTSGIVEN, TREATMENTSREMAINING,
    TIMINGRULE, TIMINGRULEFREQUENCY, TIMINGRULENOFREQUENCIES, TREATMENTRULE
    TOTALNUMBEROFTREATMENTS, DATEREQUIRED, DATEGIVEN, TREATMENTCOMMENTS,
    TREATMENTNUMBER, TOTALTREATMENTS, GIVENBY, REGIMENID, TREATMENTID
    """
    ec = ""
    offsetdays = utils.cint(offset[1:])
    if offset.startswith("m"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd( subtract_days(now(dbo.timezone), offsetdays)), db.dd(now(dbo.timezone)))
    if offset.startswith("p"):
        ec = " AND DateRequired >= %s AND DateRequired <= %s" % (db.dd(now(dbo.timezone)), db.dd( add_days(now(dbo.timezone), offsetdays)))
    if locationfilter != "":
        locationfilter = " AND ShelterLocation IN (%s)" % locationfilter
    return embellish_regimen(dbo.locale, db.query(dbo, "SELECT * FROM v_animalmedicaltreatment " \
        "WHERE DateRequired Is Not Null AND DateGiven Is Null " \
        "AND Status = 0 " \
        "AND DeceasedDate Is Null AND (Archived = 0 OR ActiveMovementType = 2) %s %s " \
        "ORDER BY DateRequired, AnimalName" % (ec, locationfilter)))
Exemple #35
0
def get_foundanimal_last_days(dbo, days = 90):
    """
    Returns found animals active for the last X days
    """
    return db.query(dbo, get_foundanimal_query(dbo) + " WHERE a.DateFound > %s AND a.ReturnToOwnerDate Is Null" % db.dd(subtract_days(now(dbo.timezone), days)))
Exemple #36
0
    def executeDeceasedPage(self):
        """
        Generates and uploads the page of recently deceased animals
        """
        self.log("Generating deceased animals page...")

        user = self.user
        thisPage = ""
        thisPageName = "deceased.%s" % self.pc.extension
        totalAnimals = 0
        l = self.dbo.locale

        try:
            cutoff = i18n.subtract_days(i18n.now(self.dbo.timezone),
                                        self.pc.outputAdoptedDays)
            orderby = "a.AnimalName"
            if self.pc.order == 0: orderby = "a.DeceasedDate"
            elif self.pc.order == 1: orderby = "a.DeceasedDate DESC"
            elif self.pc.order == 2: orderby = "a.AnimalName"
            animals = self.dbo.query(animal.get_animal_query(self.dbo) + " WHERE a.DeceasedDate Is Not Null AND " \
                "a.DeceasedDate >= %s AND a.NonShelterAnimal = 0 AND a.DiedOffShelter = 0 " \
                "ORDER BY %s" % (self.dbo.sql_date(cutoff), orderby))
            totalAnimals = len(animals)
            header = self.substituteHFTag(self.getHeader(), -1, user,
                                          i18n._("Recently deceased", l))
            footer = self.substituteHFTag(self.getFooter(), -1, user,
                                          i18n._("Recently deceased", l))
            body = self.getBody()
            thisPage = header
        except Exception as err:
            self.setLastError("Error setting up deceased page: %s" % err)
            self.logError("Error setting up deceased page: %s" % err,
                          sys.exc_info())
            return

        anCount = 0
        for an in animals:
            try:
                anCount += 1
                self.log("Processing: %s: %s (%d of %d)" %
                         (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                          totalAnimals))
                self.updatePublisherProgress(
                    self.getProgress(anCount, len(animals)))

                # If the user cancelled, stop now
                if self.shouldStopPublishing():
                    self.log("User cancelled publish. Stopping.")
                    self.resetPublisherProgress()
                    self.cleanup()
                    return

                # upload images for this animal to our current FTP
                self.uploadImages(an, True)

                # Add to the page
                thisPage += self.substituteBodyTags(body, an)
                self.log("Finished processing: %s" % an["SHELTERCODE"])

            except Exception as err:
                self.logError(
                    "Failed processing animal: %s, %s" %
                    (str(an["SHELTERCODE"]), err), sys.exc_info())

        # Append the footer, flush and upload the page
        thisPage += footer
        self.log("Saving page to disk: %s (%d bytes)" %
                 (thisPageName, len(thisPage)))
        self.saveFile(os.path.join(self.publishDir, thisPageName), thisPage)
        self.log("Saved page to disk: %s" % thisPageName)
        if self.pc.uploadDirectly:
            self.log("Uploading page: %s" % thisPageName)
            self.upload(thisPageName)
            self.log("Uploaded page: %s" % thisPageName)
def match(dbo, lostanimalid=0, foundanimalid=0, animalid=0):
    """
    Performs a lost and found match by going through all lost animals
    lostanimalid:   Compare this lost animal against all found animals
    foundanimalid:  Compare all lost animals against this found animal
    animalid:       Compare all lost animals against this shelter animal
    returns a list LostFoundMatch objects
    """
    l = dbo.locale
    matches = []
    matchspecies = configuration.match_species(dbo)
    matchbreed = configuration.match_breed(dbo)
    matchage = configuration.match_age(dbo)
    matchsex = configuration.match_sex(dbo)
    matcharealost = configuration.match_area_lost(dbo)
    matchfeatures = configuration.match_features(dbo)
    matchpostcode = configuration.match_postcode(dbo)
    matchcolour = configuration.match_colour(dbo)
    matchdatewithin2weeks = configuration.match_within2weeks(dbo)
    matchmax = matchspecies + matchbreed + matchage + matchsex + \
        matcharealost + matchfeatures + matchpostcode + matchcolour + \
        matchdatewithin2weeks
    matchpointfloor = configuration.match_point_floor(dbo)
    includeshelter = configuration.match_include_shelter(dbo)
    # Ignore records older than 6 months to keep things useful
    giveup = subtract_days(now(dbo.timezone), 180)

    # Get our set of lost animals
    lostanimals = None
    if lostanimalid == 0:
        lostanimals = db.query(dbo, get_lostanimal_query(dbo) + \
            " WHERE a.DateFound Is Null AND a.DateLost > %s ORDER BY a.DateLost" % db.dd(giveup))
    else:
        lostanimals = db.query(dbo, get_lostanimal_query(dbo) + \
            " WHERE a.ID = %d" % lostanimalid)

    oldestdate = giveup
    if len(lostanimals) > 0:
        oldestdate = lostanimals[0]["DATELOST"]

    # Get the set of found animals for comparison
    foundanimals = None
    if foundanimalid == 0:
        foundanimals = db.query(dbo, get_foundanimal_query(dbo) + \
            " WHERE a.ReturnToOwnerDate Is Null" \
            " AND a.DateFound >= %s " % db.dd(oldestdate))
    else:
        foundanimals = db.query(
            dbo,
            get_foundanimal_query(dbo) + " WHERE a.ID = %d" % foundanimalid)

    # Get the set of shelter animals for comparison
    shelteranimals = None
    if includeshelter:
        if animalid == 0:
            shelteranimals = db.query(dbo, animal.get_animal_query(dbo) + " WHERE " + \
                "a.DateBroughtIn > %s" % db.dd(oldestdate))
        else:
            shelteranimals = db.query(
                dbo,
                animal.get_animal_query(dbo) + " WHERE a.ID = %d" % animalid)

    for la in lostanimals:
        # Found animals (if an animal id has been given don't
        # check found animals)
        if animalid == 0:
            for fa in foundanimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == fa["ANIMALTYPEID"]:
                    matchpoints += matchspecies
                if la["BREEDID"] == fa["BREEDID"]: matchpoints += matchbreed
                if la["AGEGROUP"] == fa["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == fa["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], fa["AREAFOUND"],
                                     matcharealost)
                matchpoints += words(la["DISTFEAT"], fa["DISTFEAT"],
                                     matchfeatures)
                if la["AREAPOSTCODE"] == fa["AREAPOSTCODE"]:
                    matchpoints += matchpostcode
                if la["BASECOLOURID"] == fa["BASECOLOURID"]:
                    matchpoints += matchcolour
                if date_diff_days(la["DATELOST"], fa["DATEFOUND"]) <= 14:
                    matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = str(fa["ID"])
                    m.fcontactname = fa["OWNERNAME"]
                    m.fcontactnumber = fa["HOMETELEPHONE"]
                    m.fareafound = fa["AREAFOUND"]
                    m.fareapostcode = fa["AREAPOSTCODE"]
                    m.fagegroup = fa["AGEGROUP"]
                    m.fsexname = fa["SEXNAME"]
                    m.fspeciesname = fa["SPECIESNAME"]
                    m.fbreedname = fa["BREEDNAME"]
                    m.fdistinguishingfeatures = fa["DISTFEAT"]
                    m.fbasecolourname = fa["BASECOLOURNAME"]
                    m.fdatefound = fa["DATEFOUND"]
                    m.matchpoints = int(
                        (float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)

        # Shelter animals
        if includeshelter:
            for a in shelteranimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == a["SPECIESID"]:
                    matchpoints += matchspecies
                if la["BREEDID"] == a["BREEDID"] or la["BREEDID"] == a[
                        "BREED2ID"]:
                    matchpoints += matchbreed
                if la["BASECOLOURID"] == a["BASECOLOURID"]:
                    matchpoints += matchcolour
                if la["AGEGROUP"] == a["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == a["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], a["ORIGINALOWNERADDRESS"],
                                     matcharealost)
                matchpoints += words(la["DISTFEAT"], a["MARKINGS"],
                                     matchfeatures)
                if str(a["ORIGINALOWNERPOSTCODE"]).find(la["AREAPOSTCODE"]):
                    matchpoints += matchpostcode
                if date_diff_days(la["DATELOST"], a["DATEBROUGHTIN"]) <= 14:
                    matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = a["CODE"]
                    m.fcontactname = _("Shelter animal {0} '{1}'",
                                       l).format(a["CODE"], a["ANIMALNAME"])
                    m.fcontactnumber = a["SPECIESNAME"]
                    m.fareafound = _("On Shelter", l)
                    m.fareapostcode = a["ORIGINALOWNERPOSTCODE"]
                    m.fagegroup = a["AGEGROUP"]
                    m.fsexname = a["SEXNAME"]
                    m.fspeciesname = a["SPECIESNAME"]
                    m.fbreedname = a["BREEDNAME"]
                    m.fdistinguishingfeatures = a["MARKINGS"]
                    m.fbasecolourname = a["BASECOLOURNAME"]
                    m.fdatefound = a["DATEBROUGHTIN"]
                    m.matchpoints = int(
                        (float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
    return matches
Exemple #38
0
    def run(self):

        self.log("Maddies Fund Publisher starting...")

        BATCH_SIZE = 250  # How many animals to send in one POST
        PERIOD = 214  # How many days to go back when checking for fosters and adoptions (7 months * 30.5 = 214 days)

        if self.isPublisherExecuting(): return
        self.updatePublisherProgress(0)
        self.setLastError("")
        self.setStartPublishing()

        username = configuration.maddies_fund_username(self.dbo)
        password = configuration.maddies_fund_password(self.dbo)
        organisation = configuration.organisation(self.dbo)

        if username == "" or password == "":
            self.setLastError(
                "username and password all need to be set for Maddies Fund Publisher"
            )
            self.cleanup()
            return

        # Send all fosters and adoptions for the period that haven't been sent since they last had a change.
        # (we use lastchangeddate instead of sent date because MPA want an update when a number of key
        #  animal fields change, such as neuter status, microchip info, rabies tag, etc)
        cutoff = i18n.subtract_days(i18n.now(self.dbo.timezone), PERIOD)
        sql = "%s WHERE a.ActiveMovementType IN (1,2) " \
            "AND a.ActiveMovementDate >= ? AND a.DeceasedDate Is Null AND a.NonShelterAnimal = 0 " \
            "AND NOT EXISTS(SELECT AnimalID FROM animalpublished WHERE AnimalID = a.ID AND PublishedTo = 'maddiesfund' AND SentDate >= %s) " \
            "ORDER BY a.ID" % (animal.get_animal_query(self.dbo), self.dbo.sql_greatest(["a.ActiveMovementDate", "a.LastChangedDate"]))
        animals = self.dbo.query(sql, [cutoff], distincton="ID")

        # Now find animals who have been sent previously and are now deceased (using sent date against deceased to prevent re-sends)
        sql = "%s WHERE a.DeceasedDate Is Not Null AND a.DeceasedDate >= ? AND " \
            "EXISTS(SELECT AnimalID FROM animalpublished WHERE AnimalID = a.ID AND " \
            "PublishedTo = 'maddiesfund' AND SentDate < a.DeceasedDate)" % animal.get_animal_query(self.dbo)
        animals += self.dbo.query(sql, [cutoff], distincton="ID")

        # Now find shelter animals who have been sent previously and are back (using sent date against return to prevent re-sends)
        sql = "%s WHERE a.Archived = 0 AND " \
            "EXISTS(SELECT AnimalID FROM animalpublished WHERE AnimalID = a.ID AND " \
            "PublishedTo = 'maddiesfund' AND SentDate < " \
            "(SELECT MAX(ReturnDate) FROM adoption WHERE AnimalID = a.ID AND MovementType IN (1,2) AND ReturnDate Is Not Null))" % animal.get_animal_query(self.dbo)
        animals += self.dbo.query(sql, distincton="ID")

        # Now find animals who have been sent previously and have a new/changed vaccination since then
        sql = "%s WHERE a.Archived = 0 AND " \
            "EXISTS(SELECT p.AnimalID FROM animalpublished p INNER JOIN animalvaccination av ON av.AnimalID = a.ID WHERE p.AnimalID = a.ID AND " \
            "p.PublishedTo = 'maddiesfund' AND (p.SentDate < av.CreatedDate OR p.SentDate < av.LastChangedDate))" % animal.get_animal_query(self.dbo)
        animals += self.dbo.query(sql, [cutoff], distincton="ID")

        if len(animals) == 0:
            self.setLastError("No animals found to publish.")
            return

        # Get an authentication token
        token = ""
        try:
            fields = {
                "username": username,
                "password": password,
                "grant_type": "password"
            }
            r = utils.post_form(MADDIES_FUND_TOKEN_URL, fields)
            token = utils.json_parse(r["response"])["access_token"]
            self.log("got access token: %s (%s)" % (token, r["response"]))
        except Exception as err:
            self.setLastError(
                "failed to get access token: %s (request: '%s') (response: '%s')"
                % (err, r["requestbody"], r["response"]))
            self.cleanup()
            return

        anCount = 0
        thisbatch = []
        processed = []
        for an in animals:
            try:
                anCount += 1
                self.log("Processing: %s: %s (%d of %d)" %
                         (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                          len(animals)))
                self.updatePublisherProgress(
                    self.getProgress(anCount, len(animals)))

                # If the user cancelled, stop now
                if self.shouldStopPublishing():
                    self.log("User cancelled publish. Stopping.")
                    self.resetPublisherProgress()
                    return

                # Build an adoption JSON object containing the adopter and animal
                a = {
                    "PetID":
                    an["ID"],
                    "PetCode":
                    an["SHELTERCODE"],
                    "Site":
                    organisation,
                    "PetName":
                    an["ANIMALNAME"],
                    "PetStatus":
                    self.getPetStatus(an),
                    "PetLitterID":
                    an["ACCEPTANCENUMBER"],
                    "GroupType":
                    utils.iif(
                        utils.nulltostr(an["ACCEPTANCENUMBER"]) != "",
                        "Litter", ""),
                    "PetSpecies":
                    an["SPECIESNAME"],
                    "PetSex":
                    an["SEXNAME"],
                    "DateofBirth":
                    self.getDate(an["DATEOFBIRTH"]),
                    "SpayNeuterStatus":
                    utils.iif(an["NEUTERED"] == 1, "Spayed/Neutered", ""),
                    "Breed":
                    an["BREEDNAME"],
                    "Color":
                    an["BASECOLOURNAME"],
                    "SecondaryColor":
                    "",
                    "Pattern":
                    "",
                    "HealthStatus":
                    an["ASILOMARINTAKECATEGORY"] +
                    1,  # We're zero based, they use 1-base
                    "PetBiography":
                    an["ANIMALCOMMENTS"],
                    "Photo":
                    "%s?method=animal_image&account=%s&animalid=%s" %
                    (SERVICE_URL, self.dbo.database, an["ID"]),
                    "Microchip":
                    an["IDENTICHIPNUMBER"],
                    "MicrochipIssuer":
                    lookups.get_microchip_manufacturer(self.dbo.locale,
                                                       an["IDENTICHIPNUMBER"]),
                    "RelationshipType":
                    self.getRelationshipType(an),
                    "FosterCareDate":
                    self.getDate(an["ACTIVEMOVEMENTDATE"]),
                    "FosterEndDate":
                    "",
                    "RabiesTag":
                    an["RABIESTAG"],
                    "ID":
                    an["CURRENTOWNERID"],
                    "Firstname":
                    an["CURRENTOWNERFORENAMES"],
                    "Lastname":
                    an["CURRENTOWNERSURNAME"],
                    "EmailAddress":
                    self.getEmail(an["CURRENTOWNEREMAILADDRESS"]),
                    "Street":
                    an["CURRENTOWNERADDRESS"],
                    "Apartment":
                    "",
                    "City":
                    an["CURRENTOWNERTOWN"],
                    "State":
                    an["CURRENTOWNERCOUNTY"],
                    "Zipcode":
                    an["CURRENTOWNERPOSTCODE"],
                    "ContactNumber":
                    an["CURRENTOWNERHOMETELEPHONE"],
                    "Organization":
                    organisation,
                }

                # Build a list of intake histories - use the initial one first
                ph = [{
                    "IntakeType": an["ENTRYREASONNAME"],
                    "IntakeDate": self.getDate(an["DATEBROUGHTIN"]),
                    "City": utils.nulltostr(an["BROUGHTINBYOWNERTOWN"]),
                    "State": utils.nulltostr(an["BROUGHTINBYOWNERCOUNTY"]),
                    "LengthOwned": ""
                }]
                # Then any exit movements where the animal was returned
                for ra in movement.get_animal_movements(self.dbo, an["ID"]):
                    if ra["MOVEMENTTYPE"] > 0 and ra["MOVEMENTTYPE"] not in (
                            2, 8) and ra["RETURNDATE"] is not None:
                        ph.append({
                            "IntakeType": ra["RETURNEDREASONNAME"],
                            "IntakeDate": self.getDate(ra["RETURNDATE"]),
                            "City": utils.nulltostr(ra["OWNERTOWN"]),
                            "State": utils.nulltostr(ra["OWNERCOUNTY"]),
                            "LengthOwned": ""  # We don't have this info
                        })
                a["PetHistoryDetails"] = ph

                # Next add vaccination histories
                vh = []
                for v in medical.get_vaccinations(self.dbo, an["ID"]):
                    vh.append({
                        "VaccinationRecordNumber":
                        str(v["ID"]),
                        "VaccinationStatus":
                        utils.iif(v["DATEOFVACCINATION"] is not None,
                                  "Completed", "Scheduled"),
                        "VaccinationStatusDateTime":
                        self.getDate(v["DATEREQUIRED"]),
                        "Vaccine":
                        v["VACCINATIONTYPE"],
                        "Type":
                        "",  # Live/Killed - we don't keep this info yet, see issue #281
                        "Manufacturer":
                        utils.nulltostr(v["MANUFACTURER"]),
                        "VaccineLot":
                        utils.nulltostr(v["BATCHNUMBER"]),
                        "VaccinationNotes":
                        v["COMMENTS"],
                        "Length":
                        "",  # Not sure what this value is for - advised to ignore by MPA devs
                        "RevaccinationDate":
                        self.getDate(v["DATEEXPIRES"])
                    })
                a["PetVaccinationDetails"] = vh

                thisbatch.append(a)
                processed.append(an)
                self.logSuccess("Processed: %s: %s (%d of %d)" %
                                (an["SHELTERCODE"], an["ANIMALNAME"], anCount,
                                 len(animals)))

                # If we have hit our batch size, or this is the
                # last animal then send what we have.
                if len(thisbatch) == BATCH_SIZE or anCount == len(animals):
                    j = utils.json({"Animals": thisbatch})
                    headers = {"Authorization": "Bearer %s" % token}
                    self.log(
                        "HTTP POST request %s: headers: '%s', body: '%s'" %
                        (MADDIES_FUND_UPLOAD_URL, headers, j))
                    r = utils.post_json(MADDIES_FUND_UPLOAD_URL, j, headers)
                    if r["status"] != 200:
                        self.logError("HTTP %d response: %s" %
                                      (r["status"], r["response"]))
                    else:
                        self.log("HTTP %d response: %s" %
                                 (r["status"], r["response"]))
                        self.markAnimalsPublished(processed)
                    # start counting again
                    thisbatch = []
                    processed = []

            except Exception as err:
                self.logError(
                    "Failed processing animal: %s, %s" %
                    (an["SHELTERCODE"], err), sys.exc_info())

        self.cleanup()
Exemple #39
0
def match(dbo, lostanimalid = 0, foundanimalid = 0, animalid = 0):
    """
    Performs a lost and found match by going through all lost animals
    lostanimalid:   Compare this lost animal against all found animals
    foundanimalid:  Compare all lost animals against this found animal
    animalid:       Compare all lost animals against this shelter animal
    returns a list LostFoundMatch objects
    """
    l = dbo.locale
    matches = []
    matchspecies = configuration.match_species(dbo)
    matchbreed = configuration.match_breed(dbo)
    matchage = configuration.match_age(dbo)
    matchsex = configuration.match_sex(dbo)
    matcharealost = configuration.match_area_lost(dbo)
    matchfeatures = configuration.match_features(dbo)
    matchpostcode = configuration.match_postcode(dbo)
    matchcolour = configuration.match_colour(dbo)
    matchdatewithin2weeks = configuration.match_within2weeks(dbo)
    matchmax = matchspecies + matchbreed + matchage + matchsex + \
        matcharealost + matchfeatures + matchpostcode + matchcolour + \
        matchdatewithin2weeks
    matchpointfloor = configuration.match_point_floor(dbo)
    includeshelter = configuration.match_include_shelter(dbo)
    # Ignore records older than 6 months to keep things useful
    giveup = subtract_days(now(dbo.timezone), 180)

    # Get our set of lost animals
    lostanimals = None
    if lostanimalid == 0:
        lostanimals = db.query(dbo, get_lostanimal_query() + \
            " WHERE a.DateFound Is Null AND a.DateLost > %s ORDER BY a.DateLost" % db.dd(giveup))
    else:
        lostanimals = db.query(dbo, get_lostanimal_query() + \
            " WHERE a.ID = %d" % lostanimalid)

    oldestdate = giveup
    if len(lostanimals) > 0:
        oldestdate = lostanimals[0]["DATELOST"]

    # Get the set of found animals for comparison
    foundanimals = None
    if foundanimalid == 0:
        foundanimals = db.query(dbo, get_foundanimal_query() + \
            " WHERE a.ReturnToOwnerDate Is Null" \
            " AND a.DateFound >= %s " % db.dd(oldestdate))
    else:
        foundanimals = db.query(dbo, get_foundanimal_query() + " WHERE a.ID = %d" % foundanimalid)

    # Get the set of shelter animals for comparison
    shelteranimals = None
    if includeshelter:
        if animalid == 0:
            shelteranimals = db.query(dbo, animal.get_animal_query() + " WHERE " + \
                "a.DateBroughtIn > %s" % db.dd(oldestdate))
        else:
            shelteranimals = db.query(dbo, animal.get_animal_query() + " WHERE a.ID = %d" % animalid)

    for la in lostanimals:
        # Found animals (if an animal id has been given don't
        # check found animals)
        if animalid == 0:
            for fa in foundanimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == fa["ANIMALTYPEID"]: matchpoints += matchspecies
                if la["BREEDID"] == fa["BREEDID"]: matchpoints += matchbreed
                if la["AGEGROUP"] == fa["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == fa["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], fa["AREAFOUND"], matcharealost)
                matchpoints += words(la["DISTFEAT"], fa["DISTFEAT"], matchfeatures)
                if la["AREAPOSTCODE"] == fa["AREAPOSTCODE"]: matchpoints += matchpostcode
                if la["BASECOLOURID"] == fa["BASECOLOURID"]: matchpoints += matchcolour
                if date_diff_days(la["DATELOST"], fa["DATEFOUND"]) <= 14: matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = str(fa["ID"])
                    m.fcontactname = fa["OWNERNAME"]
                    m.fcontactnumber = fa["HOMETELEPHONE"]
                    m.fareafound = fa["AREAFOUND"]
                    m.fareapostcode = fa["AREAPOSTCODE"]
                    m.fagegroup = fa["AGEGROUP"]
                    m.fsexname = fa["SEXNAME"]
                    m.fspeciesname = fa["SPECIESNAME"]
                    m.fbreedname = fa["BREEDNAME"]
                    m.fdistinguishingfeatures = fa["DISTFEAT"]
                    m.fbasecolourname = fa["BASECOLOURNAME"]
                    m.fdatefound = fa["DATEFOUND"]
                    m.matchpoints = int((float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)

        # Shelter animals
        if includeshelter:
            for a in shelteranimals:
                matchpoints = 0
                if la["ANIMALTYPEID"] == a["SPECIESID"]: matchpoints += matchspecies
                if la["BREEDID"] == a["BREEDID"] or la["BREEDID"] == a["BREED2ID"]: matchpoints += matchbreed
                if la["BASECOLOURID"] == a["BASECOLOURID"]: matchpoints += matchcolour
                if la["AGEGROUP"] == a["AGEGROUP"]: matchpoints += matchage
                if la["SEX"] == a["SEX"]: matchpoints += matchsex
                matchpoints += words(la["AREALOST"], a["ORIGINALOWNERADDRESS"], matcharealost)
                matchpoints += words(la["DISTFEAT"], a["MARKINGS"], matchfeatures)
                if str(a["ORIGINALOWNERPOSTCODE"]).find(la["AREAPOSTCODE"]): matchpoints += matchpostcode
                if date_diff_days(la["DATELOST"], a["DATEBROUGHTIN"]) <= 14: matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch()
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = a["CODE"]
                    m.fcontactname = _("Shelter animal {0} '{1}'", l).format(a["CODE"], a["ANIMALNAME"])
                    m.fcontactnumber = a["SPECIESNAME"]
                    m.fareafound = _("On Shelter", l)
                    m.fareapostcode = a["ORIGINALOWNERPOSTCODE"]
                    m.fagegroup = a["AGEGROUP"]
                    m.fsexname = a["SEXNAME"]
                    m.fspeciesname = a["SPECIESNAME"]
                    m.fbreedname = a["BREEDNAME"]
                    m.fdistinguishingfeatures = a["MARKINGS"]
                    m.fbasecolourname = a["BASECOLOURNAME"]
                    m.fdatefound = a["DATEBROUGHTIN"]
                    m.matchpoints = int((float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
    return matches