Example #1
0
def insert_waitinglist_from_form(dbo, post, username):
    """
    Creates a waiting list record from the screen
    data: The webpy data object containing form parameters
    """
    l = dbo.locale
    if post["description"] == "":
        raise asm3.utils.ASMValidationError(_("Description cannot be blank", l))
    if post.integer("owner") == 0:
        raise asm3.utils.ASMValidationError(_("Waiting list entries must have a contact", l))
    if post["dateputon"] == "":
        raise asm3.utils.ASMValidationError(_("Date put on cannot be blank", l))

    nwlid = dbo.insert("animalwaitinglist", {
        "SpeciesID":                post.integer("species"),
        "Size":                     post.integer("size"),
        "DatePutOnList":            post.date("dateputon"),
        "OwnerID":                  post.integer("owner"),
        "AnimalDescription":        post["description"],
        "ReasonForWantingToPart":   post["reasonforwantingtopart"],
        "CanAffordDonation":        post.boolean("canafforddonation"),
        "Urgency":                  post.integer("urgency"),
        "DateRemovedFromList":      post.date("dateremoved"),
        "AutoRemovePolicy":         post.integer("autoremovepolicy"),
        "DateOfLastOwnerContact":   post.date("dateoflastownercontact"),
        "ReasonForRemoval":         post["reasonforremoval"],
        "Comments":                 post["comments"],
        "UrgencyLastUpdatedDate":   dbo.today(),
        "UrgencyUpdateDate":        dbo.today(offset=asm3.configuration.waiting_list_urgency_update_period(dbo))
    }, username)

    # Save any additional field values given
    asm3.additional.save_values_for_link(dbo, post, nwlid, "waitinglist", True)

    return nwlid
Example #2
0
def insert_foundanimal_from_form(dbo, post, username):
    """
    Inserts a new found animal record from the screen
    data: The webpy data object containing form parameters
    """
    l = dbo.locale
    if post.date("datefound") is None:
        raise asm3.utils.ASMValidationError(_("Date found cannot be blank", l))
    if post.date("datereported") is None:
        raise asm3.utils.ASMValidationError(_("Date reported cannot be blank", l))
    if post.integer("owner") == 0:
        raise asm3.utils.ASMValidationError(_("Found animals must have a contact", l))

    nid = dbo.insert("animalfound", {
        "AnimalTypeID":     post.integer("species"),
        "DateReported":     post.date("datereported"),
        "ReturnToOwnerDate": post.date("returntoownerdate"),
        "DateFound":        post.date("datefound"),
        "Sex":              post.integer("sex"),
        "BreedID":          post.integer("breed"),
        "AgeGroup":         post["agegroup"],
        "BaseColourID":     post.integer("colour"),
        "DistFeat":         post["markings"],
        "AreaFound":        post["areafound"],
        "AreaPostcode":     post["areapostcode"],
        "MicrochipNumber":  post["microchip"],
        "OwnerID":          post.integer("owner"),
        "Comments":         post["comments"]
    }, username)

    # Save any additional field values given
    asm3.additional.save_values_for_link(dbo, post, nid, "foundanimal", True)

    return nid
Example #3
0
def update_waitinglist_from_form(dbo, post, username):
    """
    Updates a waiting list record from the screen
    data: The webpy data object containing form parameters
    """
    l = dbo.locale
    wlid = post.integer("id")

    if not dbo.optimistic_check("animalwaitinglist", post.integer("id"), post.integer("recordversion")):
        raise asm3.utils.ASMValidationError(_("This record has been changed by another user, please reload.", l))

    if post["description"] == "":
        raise asm3.utils.ASMValidationError(_("Description cannot be blank", l))
    if post.integer("owner") == 0:
        raise asm3.utils.ASMValidationError(_("Waiting list entries must have a contact", l))
    if post["dateputon"] == "":
        raise asm3.utils.ASMValidationError(_("Date put on cannot be blank", l))

    dbo.update("animalwaitinglist", wlid, {
        "SpeciesID":                post.integer("species"),
        "Size":                     post.integer("size"),
        "DatePutOnList":            post.date("dateputon"),
        "OwnerID":                  post.integer("owner"),
        "AnimalDescription":        post["description"],
        "ReasonForWantingToPart":   post["reasonforwantingtopart"],
        "CanAffordDonation":        post.boolean("canafforddonation"),
        "Urgency":                  post.integer("urgency"),
        "DateRemovedFromList":      post.date("dateremoved"),
        "AutoRemovePolicy":         post.integer("autoremovepolicy"),
        "DateOfLastOwnerContact":   post.date("dateoflastownercontact"),
        "ReasonForRemoval":         post["reasonforremoval"],
        "Comments":                 post["comments"]
    }, username)

    asm3.additional.save_values_for_link(dbo, post, wlid, "waitinglist")
Example #4
0
def insert_stocklevel_from_form(dbo, post, username):
    """
    Inserts a stocklevel item from a dialog.
    A usage record will be written, so usage data should be sent too.
    """
    l = dbo.locale
    if post["name"] == "":
        raise asm3.utils.ASMValidationError(
            _("Stock level must have a name", l))
    if post["unitname"] == "":
        raise asm3.utils.ASMValidationError(
            _("Stock level must have a unit", l))

    nid = dbo.insert("stocklevel", {
        "Name": post["name"],
        "Description": post["description"],
        "StockLocationID": post.integer("location"),
        "UnitName": post["unitname"],
        "Total": post.floating("total"),
        "Balance": post.floating("balance"),
        "Expiry": post.date("expiry"),
        "BatchNumber": post["batchnumber"],
        "Cost": post.integer("cost"),
        "UnitPrice": post.integer("unitprice"),
        "CreatedDate": dbo.now()
    },
                     username,
                     setCreated=False,
                     setRecordVersion=False)

    insert_stockusage(dbo, username, nid, post.floating("balance"),
                      post.date("usagedate"), post.integer("usagetype"),
                      post["comments"])
    return nid
Example #5
0
def update_foundanimal_from_form(dbo, post, username):
    """
    Updates a found animal record from the screen
    post: The webpy data object containing form parameters
    """
    l = dbo.locale
    lfid = post.integer("id")

    if not dbo.optimistic_check("animalfound", post.integer("id"), post.integer("recordversion")):
        raise asm3.utils.ASMValidationError(_("This record has been changed by another user, please reload.", l))

    if post.date("datefound") is None:
        raise asm3.utils.ASMValidationError(_("Date found cannot be blank", l))
    if post.date("datereported") is None:
        raise asm3.utils.ASMValidationError(_("Date reported cannot be blank", l))
    if post.integer("owner") == 0:
        raise asm3.utils.ASMValidationError(_("Found animals must have a contact", l))

    dbo.update("animalfound", lfid, {
        "AnimalTypeID":     post.integer("species"),
        "DateReported":     post.date("datereported"),
        "ReturnToOwnerDate": post.date("returntoownerdate"),
        "DateFound":        post.date("datefound"),
        "Sex":              post.integer("sex"),
        "BreedID":          post.integer("breed"),
        "AgeGroup":         post["agegroup"],
        "BaseColourID":     post.integer("colour"),
        "DistFeat":         post["markings"],
        "AreaFound":        post["areafound"],
        "AreaPostcode":     post["areapostcode"],
        "MicrochipNumber":  post["microchip"],
        "OwnerID":          post.integer("owner"),
        "Comments":         post["comments"]
    }, username)
    asm3.additional.save_values_for_link(dbo, post, lfid, "foundanimal")
Example #6
0
def update_animalcontrol_from_form(dbo, post, username, geocode=True):
    """
    Updates an animal control incident record from the screen
    data: The webpy data object containing form parameters
    """
    l = dbo.locale
    acid = post.integer("id")

    if not dbo.optimistic_check("animalcontrol", post.integer("id"), post.integer("recordversion")):
        raise asm3.utils.ASMValidationError(_("This record has been changed by another user, please reload.", l))

    if post.date("incidentdate") is None:
        raise asm3.utils.ASMValidationError(_("Incident date cannot be blank", l))

    dbo.update("animalcontrol", acid, {
        "IncidentDateTime":     post.datetime("incidentdate", "incidenttime"),
        "IncidentTypeID":       post.integer("incidenttype"),
        "CallDateTime":         post.datetime("calldate", "calltime"),
        "CallNotes":            post["callnotes"],
        "CallTaker":            post["calltaker"],
        "CallerID":             post.integer("caller"),
        "VictimID":             post.integer("victim"),
        "DispatchAddress":      post["dispatchaddress"],
        "DispatchTown":         post["dispatchtown"],
        "DispatchCounty":       post["dispatchcounty"],
        "DispatchPostcode":     post["dispatchpostcode"],
        "JurisdictionID":       post.integer("jurisdiction"),
        "PickupLocationID":     post.integer("pickuplocation"),
        "DispatchLatLong":      post["dispatchlatlong"],
        "DispatchedACO":        post["dispatchedaco"],
        "DispatchDateTime":     post.datetime("dispatchdate", "dispatchtime"),
        "RespondedDateTime":    post.datetime("respondeddate", "respondedtime"),
        "FollowupDateTime":     post.datetime("followupdate", "followuptime"),
        "FollowupComplete":     post.boolean("followupcomplete"),
        "FollowupDateTime2":    post.datetime("followupdate2", "followuptime2"),
        "FollowupComplete2":    post.boolean("followupcomplete2"),
        "FollowupDateTime3":    post.datetime("followupdate3", "followuptime3"),
        "FollowupComplete3":    post.boolean("followupcomplete3"),
        "CompletedDate":        post.datetime("completeddate", "completedtime"),
        "IncidentCompletedID":  post.integer("completedtype"),
        "SiteID":               post.integer("site"),
        "OwnerID":              post.integer("owner"),
        "Owner2ID":             post.integer("owner2"),
        "Owner3ID":             post.integer("owner3"),
        "AnimalDescription":    post["animaldescription"],
        "SpeciesID":            post.integer("species"),
        "Sex":                  post.integer("sex"),
        "AgeGroup":             post["agegroup"]
    }, username)

    asm3.additional.save_values_for_link(dbo, post, username, acid, "incident")
    asm3.diary.update_link_info(dbo, username, asm3.diary.ANIMALCONTROL, acid)
    update_animalcontrol_roles(dbo, acid, post.integer_list("viewroles"), post.integer_list("editroles"))

    # Check/update the geocode for the dispatch address
    if geocode: update_dispatch_geocode(dbo, acid, post["dispatchlatlong"], post["dispatchaddress"], post["dispatchtown"], post["dispatchcounty"], post["dispatchpostcode"])
Example #7
0
def sign_document_page(dbo, mid, email):
    """ Outputs a page that allows signing of document with media id mid. 
        email is the address to send a copy of the signed document to. """
    l = dbo.locale
    scripts = [
        asm3.html.script_tag(JQUERY_JS),
        asm3.html.script_tag(JQUERY_UI_JS),
        asm3.html.script_tag(BOOTSTRAP_JS),
        asm3.html.script_tag(TOUCHPUNCH_JS),
        asm3.html.script_tag(SIGNATURE_JS),
        asm3.html.css_tag(BOOTSTRAP_CSS),
        asm3.html.css_tag(BOOTSTRAP_ICONS_CSS),
        asm3.html.script_i18n(dbo.locale),
        asm3.html.asm_script_tag("service_sign_document.js")
    ]
    dummy, dummy, dummy, contents = asm3.media.get_media_file_data(
        dbo, int(mid))
    content = asm3.utils.fix_relative_document_uris(
        dbo, asm3.utils.bytes2str(contents))
    controller = {
        "id": mid,
        "account": dbo.database,
        "email": email,
        "notes": asm3.media.get_notes_for_id(dbo, int(mid)),
        "signed": asm3.media.has_signature(dbo, mid),
        "content": content
    }
    return asm3.html.js_page(scripts, _("Signing Pad", l), controller)
Example #8
0
def add_message(dbo,
                createdby,
                email,
                message,
                forname="*",
                priority=0,
                expires=None,
                added=None):
    if added is None: added = dbo.today()
    if expires is None: expires = dbo.today(offset=7)
    l = dbo.locale
    mid = dbo.insert(
        "messages", {
            "Added": added,
            "Expires": expires,
            "CreatedBy": createdby,
            "Priority": priority,
            "ForName": forname,
            "Message": message
        })
    # If email is set, we email the message to everyone that it would match
    if email == 1:
        asm3.utils.send_user_email(dbo, createdby, forname,
                                   _("Message from {0}", l).format(createdby),
                                   message)
    return mid
Example #9
0
def create_animal_from_found(dbo, username, aid):
    """
    Creates an animal record from a found animal with the id given
    """
    a = dbo.first_row( dbo.query("SELECT * FROM animalfound WHERE ID = %d" % int(aid)) )
    l = dbo.locale
    data = {
        "animalname":           _("Found Animal {0}", l).format(aid),
        "markings":             str(a["DISTFEAT"]),
        "species":              str(a["ANIMALTYPEID"]),
        "comments":             str(a["COMMENTS"]),
        "broughtinby":          str(a["OWNERID"]),
        "originalowner":        str(a["OWNERID"]),
        "animaltype":           asm3.configuration.default_type(dbo),
        "breed1":               a["BREEDID"],
        "breed2":               a["BREEDID"],
        "basecolour":           str(a["BASECOLOURID"]),
        "microchipped":         asm3.utils.iif(a["MICROCHIPNUMBER"] is not None and a["MICROCHIPNUMBER"] != "", "1", "0"),
        "microchipnumber":      a["MICROCHIPNUMBER"],
        "size":                 asm3.configuration.default_size(dbo),
        "internallocation":     asm3.configuration.default_location(dbo),
        "dateofbirth":          python2display(l, subtract_years(now(dbo.timezone))),
        "estimateddob":         "1",
    }
    # If we're creating shelter codes manually, we need to put something unique
    # in there for now. Use the id
    if asm3.configuration.manual_codes(dbo):
        data["sheltercode"] = "FA" + str(aid)
        data["shortcode"] = "FA" + str(aid)
    nextid, dummy = asm3.animal.insert_animal_from_form(dbo, asm3.utils.PostedData(data, l), username)
    return nextid
Example #10
0
    def tokenCharge(self, payref, item_description=""):
        payments = self.getPayments(payref)
        total_charge_sum = sum(
            round(r.DONATION, 2) + (r.VATAMOUNT if r.VATAMOUNT > 0 else 0) for r in payments # add VAT for consistency with other payment providers
        ) / 100.0
        client_reference_id = "%s-%s" % (self.dbo.database, payref) # prefix database to payref 
        OwnerID = payments[0].OWNERID
        p = asm3.person.get_person(self.dbo, OwnerID)

        if not asm3.utils.is_valid_email_address(p.EMAILADDRESS):
            raise Exception(_("Invalid email address")) 

        url = "https://secure.cardcom.solutions/interface/ChargeToken.aspx"
        params = {
            "Operation": "2", # charge + create token,
            "TerminalNumber": asm3.configuration.cardcom_terminalnumber(self.dbo),
            "UserName": asm3.configuration.cardcom_username(self.dbo),
            "codepage": "65001", # unicode
            "TokenToCharge.DocTypeToCreate": asm3.configuration.cardcom_documenttype(self.dbo), # 3 = nonprofit receipt
            "TokenToCharge.SumToBill": str(total_charge_sum),
            "TokenToCharge.CoinID": "1", # TODO: not critical - use ASM currency
            "TokenToCharge.UniqAsmachta": client_reference_id,
            "InvoiceHead.CustName": asm3.utils.decode_html(p.OWNERNAME)[:50] , 
            "InvoiceHead.CustAddresLine1": asm3.utils.decode_html(p.OWNERADDRESS)[:50], 
            "InvoiceHead.CustCity": asm3.utils.decode_html(p.OWNERTOWN)[:50],            
            "InvoiceHead.CustMobilePH": asm3.utils.decode_html(p.MOBILETELEPHONE)[:50],  
            "InvoiceHead.ExtIsVatFree": "true",# no VAT for nonprofit receipts. TODO: config?
            "InvoiceHead.SendByEmail": "false", # TODO: not critical - config?
            "InvoiceHead.Language": "he", # TODO: not critical - config / use locale?
            "InvoiceHead.Email": p.EMAILADDRESS,
            "TokenToCharge.Token": asm3.person.get_extra_id(self.dbo, p, "Cardcom_Token"),
            "TokenToCharge.CardValidityMonth": asm3.person.get_extra_id(self.dbo, p, "Cardcom_CardValidity").split("/")[0],
            "TokenToCharge.CardValidityYear": asm3.person.get_extra_id(self.dbo, p, "Cardcom_CardValidity").split("/")[1][-2:],
            "TokenToCharge.IdentityNumber": asm3.person.get_extra_id(self.dbo, p, "Cardcom_CardOwnerID")
        }

        for p in self.getInvoiceItems(payments):
            params.update(p)

        asm_debug("params: %s" % params, "cardcom.tokenCharge", self.dbo)
        r = asm3.utils.post_form(url, params)
        if not r["status"] < 400:
            raise Exception("Response not ok: %s %s" % (r["status"], r["response"]))

        results = asm3.utils.parse_qs(r["response"])
        asm_debug("parsed response: %s" % results)

        if results["ResponseCode"] != "0":
            asm3.al.error("Bad Cardcom operation response %s: %s" % (results['ResponseCode'], results['Description']), "cardcom.tokenCharge", self.dbo)
            raise ProcessorError("Bad Cardcom operation response %s: %s" % (results['ResponseCode'], results['Description']))

        trxid = "%s/%s" % (results.get('InvoiceResponse.InvoiceNumber',''), results.get('InternalDealNumber',''))
        rcvd = asm3.utils.cint(results.get("ExtShvaParams.Sum36", total_charge_sum / 100.0))

        self.markPaymentReceived(payref, trxid, rcvd, 0, 0, r["response"])

        InvoiceResponseCode = results.get("InvoiceResponse.ResponseCode")
        if InvoiceResponseCode != "0":
            asm3.al.error("Invoice not created for %s. Response code: %s" % (payref, InvoiceResponseCode), "cardcom.tokenCharge", self.dbo)
Example #11
0
def delete_lookup(dbo, username, lookup, iid):
    l = dbo.locale
    t = LOOKUP_TABLES[lookup]
    for fv in t[LOOKUP_FOREIGNKEYS]:
        table, field = fv.split(".")
        if 0 < dbo.query_int("SELECT COUNT(*) FROM %s WHERE %s = %s" % (table, field, iid)):
            raise asm3.utils.ASMValidationError(_("This item is referred to in the database ({0}) and cannot be deleted until it is no longer in use.", l).format(fv))
    dbo.delete(lookup, iid, username)
Example #12
0
def update_animalcontrol_addlink(dbo, username, acid, animalid):
    """
    Adds a link between an animal and an incident.
    """
    l = dbo.locale
    if 0 != dbo.query_int("SELECT COUNT(*) FROM animalcontrolanimal WHERE AnimalControlID = ? AND AnimalID = ?", (acid, animalid)):
        raise asm3.utils.ASMValidationError(_("That animal is already linked to the incident", l))
    dbo.execute("INSERT INTO animalcontrolanimal (AnimalControlID, AnimalID) VALUES (?, ?)", (acid, animalid))
    asm3.audit.create(dbo, username, "animalcontrolanimal", acid, "", "incident %d linked to animal %d" % (acid, animalid))
Example #13
0
def get_microchip_manufacturer(l, chipno):
    """
    Figures out the microchip manufacturer of chipno. 
    Returns a blank for a blank chip number and does validation for a chip number
        with no matching manufacturer.
    """
    mf = None
    if chipno is None or chipno == "": return ""
    for m in MICROCHIP_MANUFACTURERS:
        if len(chipno) == m["length"] and re.compile(m["regex"]).match(chipno):
            if m["locales"] == "" or l in m["locales"].split(" "):
                mf = m["name"]
                break
    if mf is None and (len(chipno) != 9 and len(chipno) != 10 and len(chipno) != 15):
        return _("Invalid microchip number length", l)
    if mf is None:
        return _("Unknown microchip brand", l)
    return mf
Example #14
0
def update_stocklevel_from_form(dbo, post, username):
    """
    Updates a stocklevel item from a dialog. The post should include
    the ID of the stocklevel to adjust and a usage record will be
    written so usage data should be sent too.
    """
    l = dbo.locale
    slid = post.integer("stocklevelid")
    if slid == 0:
        raise asm3.utils.ASMValidationError("Invalid stock level")
    if post["name"] == "":
        raise asm3.utils.ASMValidationError(
            _("Stock level must have a name", l))
    if post["unitname"] == "":
        raise asm3.utils.ASMValidationError(
            _("Stock level must have a unit", l))
    if post.date("usagedate") is None:
        raise asm3.utils.ASMValidationError(
            _("Stock usage must have a date", l))

    diff = post.floating("balance") - dbo.query_float(
        "SELECT Balance FROM stocklevel WHERE ID = ?", [slid])

    dbo.update("stocklevel",
               slid, {
                   "Name": post["name"],
                   "Description": post["description"],
                   "StockLocationID": post.integer("location"),
                   "UnitName": post["unitname"],
                   "Total": post.floating("total"),
                   "Balance": post.floating("balance"),
                   "Expiry": post.date("expiry"),
                   "BatchNumber": post["batchnumber"],
                   "Cost": post.integer("cost"),
                   "UnitPrice": post.integer("unitprice")
               },
               username,
               setLastChanged=False,
               setRecordVersion=False)

    if diff != 0:
        insert_stockusage(dbo, username, slid, diff, post.date("usagedate"),
                          post.integer("usagetype"), post["comments"])
Example #15
0
def insert_animalcontrol_from_form(dbo, post, username, geocode=True):
    """
    Inserts a new animal control incident record from the screen
    data: The webpy data object containing form parameters
    """
    l = dbo.locale
    if post.date("incidentdate") is None:
        raise asm3.utils.ASMValidationError(_("Incident date cannot be blank", l))

    nid = dbo.insert("animalcontrol", {
        "IncidentDateTime":     post.datetime("incidentdate", "incidenttime"),
        "IncidentTypeID":       post.integer("incidenttype"),
        "CallDateTime":         post.datetime("calldate", "calltime"),
        "CallNotes":            post["callnotes"],
        "CallTaker":            post["calltaker"],
        "CallerID":             post.integer("caller"),
        "VictimID":             post.integer("victim"),
        "DispatchAddress":      post["dispatchaddress"],
        "DispatchTown":         post["dispatchtown"],
        "DispatchCounty":       post["dispatchcounty"],
        "DispatchPostcode":     post["dispatchpostcode"],
        "JurisdictionID":       post.integer("jurisdiction"),
        "PickupLocationID":     post.integer("pickuplocation"),
        "DispatchLatLong":      post["dispatchlatlong"],
        "DispatchedACO":        post["dispatchedaco"],
        "DispatchDateTime":     post.datetime("dispatchdate", "dispatchtime"),
        "RespondedDateTime":    post.datetime("respondeddate", "respondedtime"),
        "FollowupDateTime":     post.datetime("followupdate", "followuptime"),
        "FollowupComplete":     post.boolean("followupcomplete"),
        "FollowupDateTime2":    post.datetime("followupdate2", "followuptime2"),
        "FollowupComplete2":    post.boolean("followupcomplete2"),
        "FollowupDateTime3":    post.datetime("followupdate3", "followuptime3"),
        "FollowupComplete3":    post.boolean("followupcomplete3"),
        "CompletedDate":        post.datetime("completeddate", "completedtime"),
        "IncidentCompletedID":  post.integer("completedtype"),
        "SiteID":               post.integer("site"),
        "OwnerID":              post.integer("owner"),
        "Owner2ID":             post.integer("owner2"),
        "Owner3ID":             post.integer("owner3"),
        "AnimalDescription":    post["animaldescription"],
        "SpeciesID":            post.integer("species"),
        "Sex":                  post.integer("sex"),
        "AgeGroup":             post["agegroup"]
    }, username)

    asm3.additional.save_values_for_link(dbo, post, nid, "incident", True)
    update_animalcontrol_roles(dbo, nid, post.integer_list("viewroles"), post.integer_list("editroles"))

    # Look up a geocode for the dispatch address
    if geocode: update_dispatch_geocode(dbo, nid, "", post["dispatchaddress"], post["dispatchtown"], post["dispatchcounty"], post["dispatchpostcode"])

    return nid
Example #16
0
def save_values_for_link(dbo,
                         post,
                         linkid,
                         linktype="animal",
                         setdefaults=False):
    """
    Saves incoming additional field values from a record.
    Clears existing additional field values before saving (this is because forms
        don't send blank values)
    linkid: The link to the parent record
    linktype: The class of parent record
    setdefaults: If True, will set default values for any keys not supplied
        (Should be True for calls from insert_X_from_form methods)
    Keys of either a.MANDATORY.ID can be used (ASM internal forms)
        or keys of the form additionalFIELDNAME (ASM online forms)
    """
    l = dbo.locale

    dbo.delete(
        "additional", "LinkType IN (%s) AND LinkID=%s" %
        (clause_for_linktype(linktype), linkid))

    for f in get_field_definitions(dbo, linktype):

        key = "a.%s.%s" % (f.mandatory, f.id)
        key2 = "additional%s" % f.fieldname

        if key not in post and key2 not in post:
            if setdefaults and f.DEFAULTVALUE and f.DEFAULTVALUE != "":
                insert_additional(dbo, f.LINKTYPE, linkid, f.ID,
                                  f.DEFAULTVALUE)
            continue

        elif key not in post:
            key = key2

        val = post[key]
        if f.fieldtype == YESNO:
            val = str(post.boolean(key))
        elif f.fieldtype == MONEY:
            val = str(post.integer(key))
        elif f.fieldtype == DATE:
            if len(val.strip()) > 0 and post.date(key) is None:
                raise asm3.utils.ASMValidationError(
                    _("Additional date field '{0}' contains an invalid date.",
                      l).format(f.fieldname))
            val = python2display(dbo.locale, post.date(key))
        insert_additional(dbo, f.LINKTYPE, linkid, f.ID, val)
Example #17
0
def checkout_adoption_page(dbo, token):
    """ Outputs a page that generates paperwork, allows an adopter to sign it
        and then pay their adoption fee and an optional donation """
    l = dbo.locale
    scripts = [
        asm3.html.script_tag(JQUERY_JS),
        asm3.html.script_tag(JQUERY_UI_JS),
        asm3.html.script_tag(BOOTSTRAP_JS),
        asm3.html.script_tag(TOUCHPUNCH_JS),
        asm3.html.script_tag(SIGNATURE_JS),
        asm3.html.css_tag(BOOTSTRAP_CSS),
        asm3.html.css_tag(BOOTSTRAP_ICONS_CSS),
        asm3.html.script_i18n(dbo.locale),
        asm3.html.asm_script_tag("service_checkout_adoption.js")
    ]
    co = asm3.cachedisk.get(token, dbo.database)
    if co is None:
        raise asm3.utils.ASMError("invalid token")
    # Generate the adoption paperwork if it has not been generated already
    if co["mediaid"] == 0:
        dtid = asm3.configuration.adoption_checkout_templateid(dbo)
        content = asm3.wordprocessor.generate_movement_doc(
            dbo, dtid, co["movementid"], "checkout")
        # Save the doc with the person and animal, record the person copy for signing
        tempname = asm3.template.get_document_template_name(dbo, dtid)
        tempname = "%s - %s::%s" % (
            tempname, asm3.animal.get_animal_namecode(dbo, co["animalid"]),
            asm3.person.get_person_name(dbo, co["personid"]))
        asm3.media.create_document_media(dbo, "checkout", asm3.media.ANIMAL,
                                         co["animalid"], tempname, content)
        co["mediaid"] = asm3.media.create_document_media(
            dbo, "checkout", asm3.media.PERSON, co["personid"], tempname,
            content)
        content = asm3.utils.fix_relative_document_uris(
            dbo, asm3.utils.bytes2str(content))
        co["mediacontent"] = content
        asm3.cachedisk.put(token, dbo.database, co, 86400 * 2)
    # Include extra values
    co["donationmsg"] = asm3.configuration.adoption_checkout_donation_msg(dbo)
    co["donationtiers"] = asm3.configuration.adoption_checkout_donation_tiers(
        dbo)
    co["token"] = token
    return asm3.html.js_page(scripts, _("Adoption Checkout", l), co)
Example #18
0
def auto_remove_waitinglist(dbo):
    """
    Finds and automatically marks entries removed that have gone past
    the last contact date + weeks.
    """
    l = dbo.locale
    rows = dbo.query("SELECT a.ID, a.DateOfLastOwnerContact, " \
        "a.AutoRemovePolicy " \
        "FROM animalwaitinglist a WHERE a.DateRemovedFromList Is Null " \
        "AND AutoRemovePolicy > 0 AND DateOfLastOwnerContact Is Not Null")
    updates = []
    for r in rows:
        xdate = add_days(r.DATEOFLASTOWNERCONTACT, 7 * r.AUTOREMOVEPOLICY)
        if after(now(dbo.timezone), xdate):
            asm3.al.debug("auto removing waitinglist entry %d due to policy" % r.ID, "waitinglist.auto_remove_waitinglist", dbo)
            updates.append((now(dbo.timezone), _("Auto removed due to lack of owner contact.", l), r.ID))
    if len(updates) > 0:
        dbo.execute_many("UPDATE animalwaitinglist SET DateRemovedFromList = ?, " \
            "ReasonForRemoval=? WHERE ID=?", updates)
Example #19
0
def sign_document_page(dbo, mid):
    """ Outputs a page that allows signing of document with media id mid"""
    l = dbo.locale
    if asm3.media.has_signature(dbo, mid):
        return "<!DOCTYPE html><head><title>%s</title></head>" \
            "<body><p>%s</p></body></html>" % \
            ( _("Already Signed", l), _("Sorry, this document has already been signed", l))
    h = []
    h.append("""<!DOCTYPE html>
    <html>
    <head>
    <title>
    %(title)s
    </title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    %(css)s
    %(scripts)s
    <script type="text/javascript">
        $(document).ready(function() {
            $("#signature").signature({ guideline: true });
            $("#sig-clear").click(function() {
                $("#signature").signature("clear");
            });
            $("#sig-sign").click(function() {
                var img = $("#signature canvas").get(0).toDataURL("image/png");
                var formdata = "account=%(account)s&method=sign_document&formid=%(id)s&sig=" + encodeURIComponent(img);
                formdata += "&signdate=" + encodeURIComponent(moment().format("YYYY-MM-DD HH:mm:ss"));
                if ($("#signature").signature("isEmpty")) {
                    alert("Signature is required");
                    return;
                }
                $.ajax({
                    type: "POST",
                    url: "service",
                    data: formdata,
                    dataType: "text",
                    mimeType: "textPlain",
                    success: function(response) {
                        $("body").empty().append("<p>%(thankyou)s</p>");
                    },
                    error: function(jqxhr, textstatus, response) {
                        $("body").append("<p>" + response + "</p>");
                    }
                });
            });
            $("#reviewlink").click(function() {
                $("#reviewlink").fadeOut();
                $("#review").slideDown();
            });
        });
    </script>
    <style>
    button {
        padding: 10px;
        font-size: 100%%;
    }
    #signature {
        border: 1px solid #aaa;
        height: 200px;
        width: 100%%;
        max-width: 500px;
    }
    </style>
    </head>
    <body>
    """ % {
        "title":    _("Signing Pad", l),
        "id":       mid,
        "account":  dbo.database,
        "css":      asm3.html.asm_css_tag("asm-icon.css"),
        "thankyou": _("Thank you, the document is now signed.", l),
        "scripts":  asm3.html.script_tag(JQUERY_JS) + asm3.html.script_tag(JQUERY_UI_JS) +
                    asm3.html.script_tag(TOUCHPUNCH_JS) + asm3.html.script_tag(SIGNATURE_JS) + asm3.html.script_tag(MOMENT_JS)
    })
    d = []
    docnotes = []
    docnotes.append(asm3.media.get_notes_for_id(dbo, int(mid)))
    mdate, medianame, mimetype, contents = asm3.media.get_media_file_data(dbo, int(mid))
    d.append(contents)
    d.append("<hr />")
    h.append("<p><b>%s: %s</b></p>" % (_("Signing", l), ", ".join(docnotes)))
    h.append('<p><a id="reviewlink" href="#">%s</a></p>' % _("View Document", l))
    h.append('<div id="review" style="display: none">')
    h.append("\n".join(d))
    h.append('</div>')
    h.append('<div id="signature"></div>')
    h.append('<p>')
    h.append('<button id="sig-clear" type="button">' + _("Clear", l) + '</button>')
    h.append('<button id="sig-sign" type="button">' + _("Sign", l) + '</button>')
    h.append('</p>')
    h.append('<p>')
    h.append(_("Please click the Sign button when you are finished.", l))
    h.append('</p>')
    h.append('<p>')
    h.append(_("Once signed, this document cannot be edited or tampered with.", l))
    h.append('</p>')
    h.append("</body></html>")
    return "\n".join(h)
Example #20
0
def handler(post, path, remoteip, referer, querystring):
    """ Handles the various service method types.
    post:        The GET/POST parameters
    path:        The current system path/code.PATH
    remoteip:    The IP of the caller
    referer:     The referer HTTP header
    querystring: The complete querystring
    return value is a tuple containing MIME type, max-age, content
    """
    # Get service parameters
    account = post["account"]
    username = post["username"]
    password = post["password"]
    method = post["method"]
    animalid = post.integer("animalid")
    formid = post.integer("formid")
    seq = post.integer("seq")
    title = post["title"]
    strip_personal = post.integer("sensitive") == 0

    cache_key = querystring.replace(" ", "")

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key)
    if cached_response is not None:
        asm3.al.debug("cache hit for %s" % (cache_key), "service.handler")
        return cached_response

    # Are we dealing with multiple databases, but no account was specified?
    if account == "" and MULTIPLE_DATABASES:
        return ("text/plain", 0, 0, "ERROR: No database/alias specified")

    dbo = asm3.db.get_database(account)

    if dbo.database in ( "FAIL", "DISABLED", "WRONGSERVER" ):
        asm3.al.error("auth failed - invalid smaccount %s from %s (%s)" % (account, remoteip, dbo.database), "service.handler", dbo)
        return ("text/plain", 0, 0, "ERROR: Invalid database (%s)" % dbo.database)

    # If the database has disabled the service API, stop now
    if not asm3.configuration.service_enabled(dbo):
        asm3.al.error("Service API is disabled (%s)" % method, "service.handler", dbo)
        return ("text/plain", 0, 0, "ERROR: Service API is disabled")

    # Do any database updates need doing in this db?
    dbo.installpath = path
    if asm3.dbupdate.check_for_updates(dbo):
        asm3.dbupdate.perform_updates(dbo)

    # Does the method require us to authenticate? If so, do it.
    user = None
    securitymap = ""
    if method in AUTH_METHODS:
        # If the database has authenticated service methods disabled, stop now
        if not asm3.configuration.service_auth_enabled(dbo):
            asm3.al.error("Service API for auth methods is disabled (%s)" % method, "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Service API for authenticated methods is disabled")
        user = asm3.users.authenticate(dbo, username, password)
        if user is None:
            asm3.al.error("auth failed - %s/%s is not a valid username/password from %s" % (username, password, remoteip), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid username and password")
        securitymap = asm3.users.get_security_map(dbo, user["USERNAME"])

    # Get the preferred locale and timezone for the site
    l = asm3.configuration.locale(dbo)
    dbo.locale = l
    dbo.timezone = asm3.configuration.timezone(dbo)
    asm3.al.info("call %s->%s [%s %s]" % (username, method, str(animalid), title), "service.handler", dbo)

    if method =="animal_image":
        hotlink_protect("animal_image", referer)
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error("animal_image failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            mediadate, data = asm3.media.get_image_file_data(dbo, "animal", asm3.utils.cint(animalid), seq)
            if data == "NOPIC": mediadate, data = asm3.media.get_image_file_data(dbo, "nopic", 0)
            return set_cached_response(cache_key, "image/jpeg", 86400, 3600, data)

    elif method =="animal_thumbnail":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error("animal_thumbnail failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            mediadate, data = asm3.media.get_image_file_data(dbo, "animalthumb", asm3.utils.cint(animalid), seq)
            if data == "NOPIC": mediadate, data = asm3.media.get_image_file_data(dbo, "nopic", 0)
            return set_cached_response(cache_key, "image/jpeg", 86400, 86400, data)

    elif method == "animal_view":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error("animal_view failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            return set_cached_response(cache_key, "text/html", 86400, 120, asm3.publishers.html.get_animal_view(dbo, asm3.utils.cint(animalid)))

    elif method == "animal_view_adoptable_js":
        return set_cached_response(cache_key, "application/javascript", 10800, 600, asm3.publishers.html.get_animal_view_adoptable_js(dbo))

    elif method == "animal_view_adoptable_html":
        return set_cached_response(cache_key, "text/html", 86400, 120, asm3.publishers.html.get_animal_view_adoptable_html(dbo))

    elif method =="dbfs_image":
        hotlink_protect("dbfs_image", referer)
        return set_cached_response(cache_key, "image/jpeg", 86400, 86400, asm3.utils.iif(title.startswith("/"),
            asm3.dbfs.get_string_filepath(dbo, title), asm3.dbfs.get_string(dbo, title)))

    elif method =="extra_image":
        hotlink_protect("extra_image", referer)
        return set_cached_response(cache_key, "image/jpeg", 86400, 86400, asm3.dbfs.get_string(dbo, title, "/reports"))

    elif method == "json_adoptable_animal":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error("json_adoptable_animal failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
            rs = asm3.publishers.base.get_animal_data(dbo, None, asm3.utils.cint(animalid), include_additional_fields = True)
            return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(rs))

    elif method == "html_adoptable_animals":
        return set_cached_response(cache_key, "text/html", 10800, 1800, \
            asm3.publishers.html.get_adoptable_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), locationid=post.integer("locationid")))

    elif method == "html_adopted_animals":
        return set_cached_response(cache_key, "text/html", 10800, 1800, \
            asm3.publishers.html.get_adopted_animals(dbo, daysadopted=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "html_deceased_animals":
        return set_cached_response(cache_key, "text/html", 10800, 1800, \
            asm3.publishers.html.get_deceased_animals(dbo, daysdeceased=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "html_flagged_animals":
        if post["flag"] == "":
            asm3.al.error("html_flagged_animals requested with no flag.", "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid flag")
        return set_cached_response(cache_key, "text/html", 10800, 1800, \
            asm3.publishers.html.get_flagged_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), flag=post["flag"], allanimals=post.integer("all")))

    elif method == "html_held_animals":
        return set_cached_response(cache_key, "text/html", 10800, 1800, \
            asm3.publishers.html.get_held_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "json_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(dbo, None, include_additional_fields = True)
        if strip_personal: rs = strip_personal_data(rs)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(dbo, None, include_additional_fields = True)
        if strip_personal: rs = strip_personal_data(rs)
        return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_adoptable_animal":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error("xml_adoptable_animal failed, %s is not an animalid" % str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
            rs = asm3.publishers.base.get_animal_data(dbo, None, asm3.utils.cint(animalid), include_additional_fields = True)
            return set_cached_response(cache_key, "application/xml", 3600, 3600, asm3.html.xml(rs))

    elif method == "xml_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(dbo, None, include_additional_fields = True)
        if strip_personal: rs = strip_personal_data(rs)
        return set_cached_response(cache_key, "application/xml", 3600, 3600, asm3.html.xml(rs))

    elif method == "json_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.html.xml(rs))

    elif method == "json_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.html.xml(rs))

    elif method == "json_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, "application/xml", 3600, 3600, asm3.html.xml(rs))

    elif method == "html_report":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rhtml = asm3.reports.execute(dbo, crid, username, p)
        return set_cached_response(cache_key, "text/html", 600, 600, rhtml)

    elif method == "csv_mail" or method == "csv_report":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        mcsv = asm3.utils.csv(l, rows, cols, True)
        return set_cached_response(cache_key, "text/csv", 600, 600, mcsv)

    elif method == "jsonp_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], asm3.utils.json(sa)))

    elif method == "json_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(sa))

    elif method == "xml_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return set_cached_response(cache_key, "application/xml", 3600, 3600, asm3.html.xml(sa))

    elif method == "jsonp_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return ("application/javascript", 0, 0, "%s(%s);" % (post["callback"], asm3.utils.json(sa)))

    elif method == "json_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return set_cached_response(cache_key, "application/json", 3600, 3600, asm3.utils.json(sa))

    elif method == "xml_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return set_cached_response(cache_key, "application/xml", 3600, 3600, asm3.html.xml(sa))

    elif method == "rss_timeline":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.VIEW_ANIMAL)
        return set_cached_response(cache_key, "application/rss+xml", 3600, 3600, asm3.html.timeline_rss(dbo))

    elif method == "upload_animal_image":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap, asm3.users.ADD_MEDIA)
        asm3.media.attach_file_from_form(dbo, username, asm3.media.ANIMAL, int(animalid), post)
        return ("text/plain", 0, 0, "OK")

    elif method == "online_form_html":
        if formid == 0:
            raise asm3.utils.ASMError("method online_form_html requires a valid formid")
        return set_cached_response(cache_key, "text/html; charset=utf-8", 120, 120, asm3.onlineform.get_onlineform_html(dbo, formid))

    elif method == "online_form_json":
        if formid == 0:
            raise asm3.utils.ASMError("method online_form_json requires a valid formid")
        return set_cached_response(cache_key, "application/json; charset=utf-8", 30, 30, asm3.onlineform.get_onlineform_json(dbo, formid))

    elif method == "online_form_post":
        flood_protect("online_form_post", remoteip, 15)
        asm3.onlineform.insert_onlineformincoming_from_form(dbo, post, remoteip)
        redirect = post["redirect"]
        if redirect == "":
            redirect = BASE_URL + "/static/pages/form_submitted.html"
        return ("redirect", 0, 0, redirect)

    elif method == "sign_document":
        if formid == 0:
            raise asm3.utils.ASMError("method sign_document requires a valid formid")
        if post["sig"] == "":
            return set_cached_response(cache_key, "text/html", 2, 2, sign_document_page(dbo, formid))
        else:
            asm3.media.sign_document(dbo, "service", formid, post["sig"], post["signdate"])
            asm3.media.create_log(dbo, "service", formid, "ES02", _("Document signed", l))
            return ("text/plain", 0, 0, "OK")

    else:
        asm3.al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise asm3.utils.ASMError("Invalid method '%s'" % method)
Example #21
0
def match_report(dbo,
                 username="******",
                 lostanimalid=0,
                 foundanimalid=0,
                 animalid=0,
                 limit=0):
    """
    Generates the match report and returns it as a string
    """
    l = dbo.locale
    title = _("Match lost and found animals", l)
    h = []
    h.append(asm3.reports.get_report_header(dbo, title, username))
    if limit > 0:
        h.append("<p>(" + _("Limited to {0} matches", l).format(limit) +
                 ")</p>")

    def p(s):
        return "<p>%s</p>" % s

    def td(s):
        return "<td>%s</td>" % s

    def hr():
        return "<hr />"

    lastid = 0
    matches = match(dbo, lostanimalid, foundanimalid, animalid, limit)
    if len(matches) > 0:
        for m in matches:
            if lastid != m.lid:
                if lastid != 0:
                    h.append("</tr></table>")
                    h.append(hr())
                h.append(p(_("{0} - {1} {2} ({3}), contact {4} ({5}) - lost in {6}, postcode {7}, on {8}", l).format( \
                    m.lid, "%s %s %s" % (m.lagegroup, m.lbasecolourname, m.lsexname), \
                    "%s/%s %s" % (m.lspeciesname, m.lbreedname, m.lmicrochip), \
                    m.ldistinguishingfeatures, m.lcontactname, m.lcontactnumber, m.larealost, m.lareapostcode,
                    python2display(l, m.ldatelost))))
                h.append("<table border=\"1\" width=\"100%\"><tr>")
                h.append("<th>%s</th>" % _("Reference", l))
                h.append("<th>%s</th>" % _("Description", l))
                h.append("<th>%s</th>" % _("Area Found", l))
                h.append("<th>%s</th>" % _("Area Postcode", l))
                h.append("<th>%s</th>" % _("Date Found", l))
                h.append("<th>%s</th>" % _("Contact", l))
                h.append("<th>%s</th>" % _("Number", l))
                h.append("<th>%s</th>" % _("Microchip", l))
                h.append("<th>%s</th>" % _("Match", l))
                h.append("</tr>")
                lastid = m.lid
            h.append("<tr>")
            h.append(td(str(m.fid)))
            h.append(
                td("%s %s %s %s %s" %
                   (m.fagegroup, m.fbasecolourname, m.fsexname, m.fspeciesname,
                    m.fbreedname)))
            h.append(td(m.fareafound))
            h.append(td(m.fareapostcode))
            h.append(td(python2display(l, m.fdatefound)))
            h.append(td(m.fcontactname))
            h.append(td(m.fcontactnumber))
            h.append(td(m.fmicrochip))
            h.append(td(str(m.matchpoints) + "%"))
            h.append("</tr>")
        h.append("</tr></table>")
    else:
        h.append(p(_("No matches found.", l)))
    h.append(asm3.reports.get_report_footer(dbo, title, username))
    return "\n".join(h)
Example #22
0
def match(dbo, lostanimalid=0, foundanimalid=0, animalid=0, limit=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
    limit:          Stop when we hit this many matches (or 0 for all)
    returns a list of LostFoundMatch objects
    """
    l = dbo.locale
    batch = []
    matches = []
    matchspecies = asm3.configuration.match_species(dbo)
    matchbreed = asm3.configuration.match_breed(dbo)
    matchage = asm3.configuration.match_age(dbo)
    matchsex = asm3.configuration.match_sex(dbo)
    matcharealost = asm3.configuration.match_area_lost(dbo)
    matchfeatures = asm3.configuration.match_features(dbo)
    matchpostcode = asm3.configuration.match_postcode(dbo)
    matchcolour = asm3.configuration.match_colour(dbo)
    matchmicrochip = asm3.configuration.match_microchip(dbo)
    matchdatewithin2weeks = asm3.configuration.match_within2weeks(dbo)
    matchmax = matchspecies + matchbreed + matchage + matchsex + \
        matcharealost + matchfeatures + matchpostcode + matchcolour + \
        matchmicrochip + matchdatewithin2weeks
    matchpointfloor = asm3.configuration.match_point_floor(dbo)
    includeshelter = asm3.configuration.match_include_shelter(dbo)
    fullmatch = animalid == 0 and lostanimalid == 0 and foundanimalid == 0
    # Ignore records older than 6 months to keep things useful
    giveup = dbo.today(offset=-182)

    # Get our set of lost animals
    lostanimals = None
    if lostanimalid == 0:
        lostanimals = dbo.query(get_lostanimal_query(dbo) + \
            " WHERE a.DateFound Is Null AND a.DateLost > ? ORDER BY a.DateLost", [giveup])
    else:
        lostanimals = dbo.query(get_lostanimal_query(dbo) + \
            " WHERE a.ID = ?", [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 = dbo.query(get_foundanimal_query(dbo) + \
            " WHERE a.ReturnToOwnerDate Is Null" \
            " AND a.DateFound >= ? ", [oldestdate])
    else:
        foundanimals = dbo.query(
            get_foundanimal_query(dbo) + " WHERE a.ID = ?", [foundanimalid])

    # Get the set of shelter animals for comparison - anything brought in recently
    # that's 1. still on shelter or 2. was released to wild, transferred or escaped
    shelteranimals = None
    if includeshelter:
        if animalid == 0:
            shelteranimals = dbo.query(asm3.animal.get_animal_query(dbo) + " WHERE " + \
                "(a.Archived = 0 OR a.ActiveMovementType IN (3,4,7)) " \
                "AND a.DateBroughtIn > ?", [oldestdate])
        else:
            shelteranimals = dbo.query(
                asm3.animal.get_animal_query(dbo) + " WHERE a.ID = ?",
                [animalid])

    asm3.asynctask.set_progress_max(dbo, len(lostanimals))
    for la in lostanimals:
        asm3.asynctask.increment_progress_value(dbo)
        # Stop if we've hit our limit
        if limit > 0 and len(matches) >= limit:
            break
        # 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["MICROCHIPNUMBER"] != "" and la["MICROCHIPNUMBER"] == fa[
                        "MICROCHIPNUMBER"]:
                    matchpoints += matchmicrochip
                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(dbo)
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lmicrochip = la["MICROCHIPNUMBER"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexid = la["SEX"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesid = la["ANIMALTYPEID"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedid = la["BREEDID"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourid = la["BASECOLOURID"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = fa["ID"]
                    m.fanimalid = 0
                    m.fcontactname = fa["OWNERNAME"]
                    m.fmicrochip = fa["MICROCHIPNUMBER"]
                    m.fcontactnumber = fa["HOMETELEPHONE"]
                    m.fareafound = fa["AREAFOUND"]
                    m.fareapostcode = fa["AREAPOSTCODE"]
                    m.fagegroup = fa["AGEGROUP"]
                    m.fsexid = fa["SEX"]
                    m.fsexname = fa["SEXNAME"]
                    m.fspeciesid = fa["ANIMALTYPEID"]
                    m.fspeciesname = fa["SPECIESNAME"]
                    m.fbreedid = fa["BREEDID"]
                    m.fbreedname = fa["BREEDNAME"]
                    m.fdistinguishingfeatures = fa["DISTFEAT"]
                    m.fbasecolourid = fa["BASECOLOURID"]
                    m.fbasecolourname = fa["BASECOLOURNAME"]
                    m.fdatefound = fa["DATEFOUND"]
                    m.matchpoints = int(
                        (float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
                    if fullmatch:
                        batch.append(m.toParams())
                    if limit > 0 and len(matches) >= limit:
                        break

        # Shelter animals
        if includeshelter:
            for a in shelteranimals:
                matchpoints = 0
                foundarea = ""
                foundpostcode = ""
                if la["MICROCHIPNUMBER"] != "" and la["MICROCHIPNUMBER"] == a[
                        "IDENTICHIPNUMBER"]:
                    matchpoints += matchmicrochip
                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["DISTFEAT"], a["MARKINGS"],
                                     matchfeatures)
                if a["ISPICKUP"] == 1:
                    matchpoints += words(la["AREALOST"], a["PICKUPADDRESS"],
                                         matcharealost)
                    foundarea = a["PICKUPADDRESS"]
                elif a["BROUGHTINBYOWNERADDRESS"] is not None:
                    matchpoints += words(la["AREALOST"],
                                         a["BROUGHTINBYOWNERADDRESS"],
                                         matcharealost)
                    if asm3.utils.nulltostr(
                            a["BROUGHTINBYOWNERPOSTCODE"]).find(
                                la["AREAPOSTCODE"]) != -1:
                        matchpoints += matchpostcode
                    foundarea = a["BROUGHTINBYOWNERADDRESS"]
                    foundpostcode = a["BROUGHTINBYOWNERPOSTCODE"]
                elif a["ORIGINALOWNERADDRESS"] is not None:
                    matchpoints += words(la["AREALOST"],
                                         a["ORIGINALOWNERADDRESS"],
                                         matcharealost)
                    if asm3.utils.nulltostr(a["ORIGINALOWNERPOSTCODE"]).find(
                            la["AREAPOSTCODE"]) != -1:
                        matchpoints += matchpostcode
                    foundarea = a["ORIGINALOWNERADDRESS"]
                    foundpostcode = a["ORIGINALOWNERPOSTCODE"]
                if date_diff_days(la["DATELOST"], a["DATEBROUGHTIN"]) <= 14:
                    matchpoints += matchdatewithin2weeks
                if matchpoints > matchmax: matchpoints = matchmax
                if matchpoints >= matchpointfloor:
                    m = LostFoundMatch(dbo)
                    m.lid = la["ID"]
                    m.lcontactname = la["OWNERNAME"]
                    m.lmicrochip = la["MICROCHIPNUMBER"]
                    m.lcontactnumber = la["HOMETELEPHONE"]
                    m.larealost = la["AREALOST"]
                    m.lareapostcode = la["AREAPOSTCODE"]
                    m.lagegroup = la["AGEGROUP"]
                    m.lsexid = la["SEX"]
                    m.lsexname = la["SEXNAME"]
                    m.lspeciesid = la["ANIMALTYPEID"]
                    m.lspeciesname = la["SPECIESNAME"]
                    m.lbreedid = la["BREEDID"]
                    m.lbreedname = la["BREEDNAME"]
                    m.ldistinguishingfeatures = la["DISTFEAT"]
                    m.lbasecolourid = la["BASECOLOURID"]
                    m.lbasecolourname = la["BASECOLOURNAME"]
                    m.ldatelost = la["DATELOST"]
                    m.fid = 0
                    m.fanimalid = a["ID"]
                    m.fcontactname = _("Shelter animal {0} '{1}'",
                                       l).format(a["CODE"], a["ANIMALNAME"])
                    m.fmicrochip = a["IDENTICHIPNUMBER"]
                    m.fcontactnumber = a["SPECIESNAME"]
                    m.fareafound = foundarea
                    m.fareapostcode = foundpostcode
                    m.fagegroup = a["AGEGROUP"]
                    m.fsexid = a["SEX"]
                    m.fsexname = a["SEXNAME"]
                    m.fspeciesid = a["SPECIESID"]
                    m.fspeciesname = a["SPECIESNAME"]
                    m.fbreedid = a["BREEDID"]
                    m.fbreedname = a["BREEDNAME"]
                    m.fdistinguishingfeatures = a["MARKINGS"]
                    m.fbasecolourid = a["BASECOLOURID"]
                    m.fbasecolourname = a["BASECOLOURNAME"]
                    m.fdatefound = a["DATEBROUGHTIN"]
                    m.matchpoints = int(
                        (float(matchpoints) / float(matchmax)) * 100.0)
                    matches.append(m)
                    if fullmatch:
                        batch.append(m.toParams())
                    if limit > 0 and len(matches) >= limit:
                        break

    if fullmatch:
        dbo.execute("DELETE FROM animallostfoundmatch")
        sql = "INSERT INTO animallostfoundmatch (AnimalLostID, AnimalFoundID, AnimalID, LostContactName, LostContactNumber, " \
            "LostArea, LostPostcode, LostAgeGroup, LostSex, LostSpeciesID, LostBreedID, LostFeatures, LostBaseColourID, LostDate, " \
            "LostMicrochipNumber, FoundMicrochipNumber, " \
            "FoundContactName, FoundContactNumber, FoundArea, FoundPostcode, FoundAgeGroup, FoundSex, FoundSpeciesID, FoundBreedID, " \
            "FoundFeatures, FoundBaseColourID, FoundDate, MatchPoints) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
        if len(batch) > 0:
            dbo.execute_many(sql, batch)

    return matches
Example #23
0
def search(dbo, session, q):
    """
    Performs a database wide search for the term given.
    special tokens:

    a:term      Only search animals for term
    ac:term     Only search animal control incidents for term
    p:term      Only search people for term
    la:term     Only search lost animals for term
    li:num      Only search licence numbers for term
    fa:term     Only search found animals for term
    wl:term     Only search waiting list entries for term

    sort:az     Sort results alphabetically az
    sort:za     Sort results alphabetically za
    sort:mr     Sort results most recently changed first
    sort:lr     Sort results least recently changed first

    -- update this list in header.js/bind_search/keywords
    activelost, activefound, 
    onshelter/os, notforadoption, hold, holdtoday, quarantine, deceased, 
    forpublish, people, vets, retailers, staff, fosterers, volunteers, 
    shelters, aco, banned, homechecked, homecheckers, members, donors, drivers,
    reservenohomecheck, notmicrochipped, unsigned, signed

    returns a tuple of:
    results, timetaken, explain, sortname
    """

    # ar (add results) inner method
    def ar(rlist, rtype, sortfield):
        # Return brief records to save bandwidth
        if rtype == "ANIMAL":
            rlist = asm3.animal.get_animals_brief(rlist)
        if rtype == "PERSON":
            pass  # TODO:
        for r in rlist:
            r["RESULTTYPE"] = rtype
            if sortfield == "RELEVANCE":
                # How "relevant" is this record to what was searched for?
                # animal name and code weight higher than other elements.
                # Note that the code below modifies inbound var q, so by the
                # time we read it here, it should only contain the search term
                # itself. Weight everything else by last changed date so there
                # is some semblance of useful order for less relevant items
                qlow = q.lower()
                if rtype == "ANIMAL":
                    r["SORTON"] = r["LASTCHANGEDDATE"]
                    if r["SORTON"] is None: r["SORTON"] = THE_PAST
                    if r["ANIMALNAME"].lower(
                    ) == qlow or r["SHELTERCODE"].lower(
                    ) == qlow or r["SHORTCODE"].lower() == qlow:
                        r["SORTON"] = now()
                    # Put matches where term present just behind direct matches
                    elif r["ANIMALNAME"].lower().find(
                            qlow) != -1 or r["SHELTERCODE"].lower().find(
                                qlow) != -1 or r["SHORTCODE"].lower().find(
                                    qlow) != -1:
                        r["SORTON"] = now() - datetime.timedelta(seconds=1)
                elif rtype == "PERSON":
                    r["SORTON"] = r["LASTCHANGEDDATE"]
                    if r["SORTON"] is None: r["SORTON"] = THE_PAST
                    # Count how many of the keywords in the search were present
                    # in the owner name field - if it's all of them then raise
                    # the relevance.
                    qw = qlow.split(" ")
                    qm = 0
                    for w in qw:
                        if r["OWNERNAME"].lower().find(w) != -1:
                            qm += 1
                    if qm == len(qw):
                        r["SORTON"] = now()
                    # Put matches where term present just behind direct matches
                    if r["OWNERSURNAME"].lower().find(
                            qlow) or r["OWNERNAME"].lower().find(qlow):
                        r["SORTON"] = now() - datetime.timedelta(seconds=1)
                elif rtype == "LICENCE":
                    r["SORTON"] = r["ISSUEDATE"]
                    if r["SORTON"] is None: r["SORTON"] = THE_PAST
                    if r["LICENCENUMBER"].lower() == qlow: r["SORTON"] = now()
                else:
                    r["SORTON"] = r["LASTCHANGEDDATE"]
            else:
                r["SORTON"] = r[sortfield]
                if r["SORTON"] is None and sortfield.endswith("DATE"):
                    r["SORTON"] = THE_PAST
            results.append(r)

    l = dbo.locale

    # start the clock
    starttime = time.time()

    # The returned results
    results = []

    # An i18n explanation of what was searched for
    explain = ""

    # Max records to be returned by search
    limit = asm3.configuration.record_search_limit(dbo)

    # Default sort for the search
    searchsort = asm3.configuration.search_sort(dbo)

    q = q.replace("'", "`")

    # Allow the sort to be overridden
    if q.find("sort:") != -1:
        if "sort:az" in q:
            searchsort = 0
            q = q.replace("sort:az", "")
        elif "sort:za" in q:
            searchsort = 1
            q = q.replace("sort:za", "")
        elif "sort:lr" in q:
            searchsort = 2
            q = q.replace("sort:lr", "")
        elif "sort:mr" in q:
            searchsort = 3
            q = q.replace("sort:mr", "")
        elif "sort:as" in q:
            searchsort = 4
            q = q.replace("sort:as", "")
        elif "sort:sa" in q:
            searchsort = 5
            q = q.replace("sort:sa", "")
        elif "sort:rel" in q:
            searchsort = 6
            q = q.replace("sort:rel", "")

    q = q.strip()

    # Handle sorting ===========================
    animalsort = ""
    personsort = ""
    wlsort = ""
    acsort = ""
    lasort = ""
    lisort = ""
    fasort = ""
    sortdir = "a"
    sortname = ""
    # alphanumeric ascending
    if searchsort == 0:
        animalsort = "ANIMALNAME"
        personsort = "OWNERNAME"
        wlsort = "OWNERNAME"
        acsort = "OWNERNAME"
        lasort = "OWNERNAME"
        lisort = "OWNERNAME"
        fasort = "OWNERNAME"
        sortdir = "a"
        sortname = _("Alphabetically A-Z", l)
    # alphanumeric descending
    elif searchsort == 1:
        animalsort = "ANIMALNAME"
        personsort = "OWNERNAME"
        wlsort = "OWNERNAME"
        acsort = "OWNERNAME"
        lasort = "OWNERNAME"
        lisort = "OWNERNAME"
        fasort = "OWNERNAME"
        sortdir = "d"
        sortname = _("Alphabetically Z-A", l)
    # last changed ascending
    elif searchsort == 2:
        animalsort = "LASTCHANGEDDATE"
        personsort = "LASTCHANGEDDATE"
        wlsort = "LASTCHANGEDDATE"
        acsort = "LASTCHANGEDDATE"
        lasort = "LASTCHANGEDDATE"
        lisort = "ISSUEDATE"
        fasort = "LASTCHANGEDDATE"
        sortdir = "a"
        sortname = _("Least recently changed", l)
    # last changed descending
    elif searchsort == 3:
        animalsort = "LASTCHANGEDDATE"
        personsort = "LASTCHANGEDDATE"
        acsort = "LASTCHANGEDDATE"
        wlsort = "LASTCHANGEDDATE"
        lasort = "LASTCHANGEDDATE"
        lisort = "ISSUEDATE"
        fasort = "LASTCHANGEDDATE"
        sortdir = "d"
        sortname = _("Most recently changed", l)
    # species ascending
    elif searchsort == 4:
        animalsort = "SPECIESNAME"
        personsort = "OWNERNAME"
        acsort = "SPECIESNAME"
        wlsort = "SPECIESNAME"
        lasort = "SPECIESNAME"
        lisort = "COMMENTS"
        fasort = "SPECIESNAME"
        sortdir = "a"
        sortname = _("Species A-Z", l)
    elif searchsort == 5:
        animalsort = "SPECIESNAME"
        personsort = "OWNERNAME"
        acsort = "SPECIESNAME"
        wlsort = "SPECIESNAME"
        lasort = "SPECIESNAME"
        lisort = "COMMENTS"
        fasort = "SPECIESNAME"
        sortdir = "d"
        sortname = _("Species Z-A", l)
    elif searchsort == 6:
        animalsort = "RELEVANCE"
        personsort = "RELEVANCE"
        wlsort = "RELEVANCE"
        acsort = "RELEVANCE"
        lasort = "RELEVANCE"
        lisort = "RELEVANCE"
        fasort = "RELEVANCE"
        sortdir = "d"
        sortname = _("Most relevant", l)

    viewperson = asm3.users.check_permission_bool(session,
                                                  asm3.users.VIEW_PERSON)
    viewanimal = asm3.users.check_permission_bool(session,
                                                  asm3.users.VIEW_ANIMAL)
    viewstaff = asm3.users.check_permission_bool(session,
                                                 asm3.users.VIEW_STAFF)
    viewvolunteer = asm3.users.check_permission_bool(session,
                                                     asm3.users.VIEW_VOLUNTEER)
    user = session.user
    locationfilter = session.locationfilter
    siteid = session.siteid
    visibleanimalids = session.visibleanimalids

    # Special token searches
    if q == "onshelter" or q == "os":
        explain = _("All animals on the shelter.", l)
        if viewanimal:
            ar(
                asm3.animal.get_animal_find_simple(
                    dbo,
                    "",
                    limit=limit,
                    locationfilter=locationfilter,
                    siteid=siteid,
                    visibleanimalids=visibleanimalids), "ANIMAL", animalsort)

    elif q == "notforadoption":
        explain = _("All animals who are flagged as not for adoption.", l)
        if viewanimal:
            ar(asm3.animal.get_animals_not_for_adoption(dbo), "ANIMAL",
               animalsort)

    elif q == "longterm":
        explain = _(
            "All animals who have been on the shelter longer than {0} months.",
            l).format(asm3.configuration.long_term_months(dbo))
        if viewanimal:
            ar(asm3.animal.get_animals_long_term(dbo), "ANIMAL", animalsort)

    elif q == "notmicrochipped":
        explain = _("All animals who have not been microchipped", l)
        if viewanimal:
            ar(asm3.animal.get_animals_not_microchipped(dbo), "ANIMAL",
               animalsort)

    elif q == "hold":
        explain = _("All animals who are currently held in case of reclaim.",
                    l)
        if viewanimal:
            ar(asm3.animal.get_animals_hold(dbo), "ANIMAL", animalsort)

    elif q == "holdtoday":
        explain = _("All animals where the hold ends today.", l)
        if viewanimal:
            ar(asm3.animal.get_animals_hold_today(dbo), "ANIMAL", animalsort)

    elif q == "quarantine":
        explain = _("All animals who are currently quarantined.", l)
        if viewanimal:
            ar(asm3.animal.get_animals_quarantine(dbo), "ANIMAL", animalsort)

    elif q == "deceased":
        explain = _("Recently deceased shelter animals (last 30 days).", l)
        if viewanimal:
            ar(asm3.animal.get_animals_recently_deceased(dbo), "ANIMAL",
               animalsort)

    elif q == "forpublish":
        explain = _("All animals matching current publishing options.", l)
        if viewanimal:
            ar(asm3.publishers.base.get_animal_data(dbo), "ANIMAL", animalsort)

    elif q == "people":
        ar(
            asm3.person.get_person_find_simple(dbo,
                                               "",
                                               user,
                                               classfilter="all",
                                               includeStaff=viewstaff,
                                               includeVolunteers=viewvolunteer,
                                               limit=limit,
                                               siteid=siteid), "PERSON",
            personsort)
        explain = _("All people on file.", l)

    elif q == "vets":
        explain = _("All vets on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="vet",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "retailers":
        explain = _("All retailers on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="retailer",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "staff":
        explain = _("All staff on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="staff",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "fosterers":
        explain = _("All fosterers on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="fosterer",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "volunteers":
        explain = _("All volunteers on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="volunteer",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "shelters":
        explain = _("All animal shelters on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="shelter",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "aco":
        explain = _("All animal care officers on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="aco",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "banned":
        explain = _("All banned owners on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="banned",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "homechecked":
        explain = _("All homechecked owners on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="homechecked",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "homecheckers":
        explain = _("All homecheckers on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="homechecker",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "members":
        explain = _("All members on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="member",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "donors":
        explain = _("All donors on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="donor",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "drivers":
        explain = _("All drivers on file.", l)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    "",
                    user,
                    classfilter="driver",
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q == "reservenohomecheck":
        explain = _(
            "People with active reservations, but no homecheck has been done.",
            l)
        if viewperson:
            ar(asm3.person.get_reserves_without_homechecks(dbo), "PERSON",
               personsort)

    elif q == "overduedonations":
        explain = _("People with overdue donations.", l)
        if viewperson:
            ar(asm3.person.get_overdue_donations(dbo), "PERSON", personsort)

    elif q == "signed":
        explain = _("Document signing requests received in the last week", l)
        if viewperson:
            ar(asm3.person.get_signed_requests(dbo, 7), "PERSON", personsort)

    elif q == "unsigned":
        explain = _(
            "Document signing requests issued in the last month that are unsigned",
            l)
        if viewperson:
            ar(asm3.person.get_unsigned_requests(dbo, 31), "PERSON",
               personsort)

    elif q == "activelost":
        explain = _("Lost animals reported in the last 30 days.", l)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_LOST_ANIMAL):
            ar(
                asm3.lostfound.get_lostanimal_find_simple(dbo,
                                                          "",
                                                          limit=limit,
                                                          siteid=siteid),
                "LOSTANIMAL", lasort)

    elif q == "activefound":
        explain = _("Found animals reported in the last 30 days.", l)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_FOUND_ANIMAL):
            ar(
                asm3.lostfound.get_foundanimal_find_simple(dbo,
                                                           "",
                                                           limit=limit,
                                                           siteid=siteid),
                "FOUNDANIMAL", fasort)

    elif q.startswith("a:") or q.startswith("animal:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("Animals matching '{0}'.", l).format(q)
        if viewanimal:
            ar(
                asm3.animal.get_animal_find_simple(
                    dbo,
                    q,
                    limit=limit,
                    locationfilter=locationfilter,
                    siteid=siteid,
                    visibleanimalids=visibleanimalids), "ANIMAL", animalsort)

    elif q.startswith("ac:") or q.startswith("animalcontrol:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("Animal control incidents matching '{0}'.", l).format(q)
        if asm3.users.check_permission_bool(session, asm3.users.VIEW_INCIDENT):
            ar(
                asm3.animalcontrol.get_animalcontrol_find_simple(
                    dbo, q, user, limit=limit, siteid=siteid), "ANIMALCONTROL",
                acsort)

    elif q.startswith("p:") or q.startswith("person:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("People matching '{0}'.", l).format(q)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    q,
                    user,
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)

    elif q.startswith("wl:") or q.startswith("waitinglist:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("Waiting list entries matching '{0}'.", l).format(q)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_WAITING_LIST):
            ar(
                asm3.waitinglist.get_waitinglist_find_simple(dbo,
                                                             q,
                                                             limit=limit,
                                                             siteid=siteid),
                "WAITINGLIST", wlsort)

    elif q.startswith("la:") or q.startswith("lostanimal:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("Lost animal entries matching '{0}'.", l).format(q)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_LOST_ANIMAL):
            ar(
                asm3.lostfound.get_lostanimal_find_simple(dbo,
                                                          q,
                                                          limit=limit,
                                                          siteid=siteid),
                "LOSTANIMAL", lasort)

    elif q.startswith("fa:") or q.startswith("foundanimal:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("Found animal entries matching '{0}'.", l).format(q)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_FOUND_ANIMAL):
            ar(
                asm3.lostfound.get_foundanimal_find_simple(dbo,
                                                           q,
                                                           limit=limit,
                                                           siteid=siteid),
                "FOUNDANIMAL", fasort)

    elif q.startswith("li:") or q.startswith("license:"):
        q = q[q.find(":") + 1:].strip()
        explain = _("License numbers matching '{0}'.", l).format(q)
        if asm3.users.check_permission_bool(session, asm3.users.VIEW_LICENCE):
            ar(asm3.financial.get_licence_find_simple(dbo, q, limit),
               "LICENCE", lisort)

    # No special tokens, search everything and collate
    else:
        if viewanimal:
            ar(
                asm3.animal.get_animal_find_simple(
                    dbo,
                    q,
                    limit=limit,
                    locationfilter=locationfilter,
                    siteid=siteid,
                    visibleanimalids=visibleanimalids), "ANIMAL", animalsort)
        if asm3.users.check_permission_bool(session, asm3.users.VIEW_INCIDENT):
            ar(
                asm3.animalcontrol.get_animalcontrol_find_simple(
                    dbo, q, user, limit=limit, siteid=siteid), "ANIMALCONTROL",
                acsort)
        if viewperson:
            ar(
                asm3.person.get_person_find_simple(
                    dbo,
                    q,
                    user,
                    includeStaff=viewstaff,
                    includeVolunteers=viewvolunteer,
                    limit=limit,
                    siteid=siteid), "PERSON", personsort)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_WAITING_LIST):
            ar(
                asm3.waitinglist.get_waitinglist_find_simple(dbo,
                                                             q,
                                                             limit=limit,
                                                             siteid=siteid),
                "WAITINGLIST", wlsort)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_LOST_ANIMAL):
            ar(
                asm3.lostfound.get_lostanimal_find_simple(dbo,
                                                          q,
                                                          limit=limit,
                                                          siteid=siteid),
                "LOSTANIMAL", lasort)
        if asm3.users.check_permission_bool(session,
                                            asm3.users.VIEW_FOUND_ANIMAL):
            ar(
                asm3.lostfound.get_foundanimal_find_simple(dbo,
                                                           q,
                                                           limit=limit,
                                                           siteid=siteid),
                "FOUNDANIMAL", fasort)
        if asm3.users.check_permission_bool(session, asm3.users.VIEW_LICENCE):
            ar(asm3.financial.get_licence_find_simple(dbo, q, limit),
               "LICENCE", lisort)
        explain = _("Results for '{0}'.", l).format(q)

    # Apply the sort to the results
    # We return a tuple to the sorted function which forces rows with None in the
    # SORTON key to the end (True, None) for None values, (False, value) for items
    if sortdir == "a":
        sortresults = sorted(results,
                             key=lambda k: (k["SORTON"] is None, k["SORTON"]))
    else:
        sortresults = sorted(results,
                             reverse=True,
                             key=lambda k:
                             (k["SORTON"] is not None, k["SORTON"]))

    # stop the clock
    timetaken = (time.time() - starttime)

    # Return our final set of values
    return sortresults, timetaken, explain, sortname
Example #24
0
    def checkoutUrl(self, payref, return_url="", item_description=""):
        asm_debug("%s %s %s" % (payref, return_url, item_description), "cardcom.checkoutUrl", self.dbo)
        payments = self.getPayments(payref)
        total_charge_sum = sum(
            round(r.DONATION, 2) for r in payments
        )
        client_reference_id = "%s-%s" % (self.dbo.database, payref) # prefix database to payref 
        OwnerID = payments[0].OWNERID
        p = asm3.person.get_person(self.dbo, OwnerID)

        if not asm3.utils.is_valid_email_address(p.EMAILADDRESS):
            raise Exception(_("Invalid email address"))


        url = "https://secure.cardcom.solutions/Interface/LowProfile.aspx"

        params = {
            "TerminalNumber": asm3.configuration.cardcom_terminalnumber(self.dbo),
            "UserName": asm3.configuration.cardcom_username(self.dbo),
            "SumToBill": str(total_charge_sum / 100.0),
            "CoinID": "1", # TODO: not critical - use ASM currency
            "Language": "he", # TODO: not critical - config / use locale?
            "SuccessRedirectUrl": asm3.configuration.cardcom_successurl(self.dbo), # "https://secure.cardcom.solutions/DealWasSuccessful.aspx",
            "ErrorRedirectUrl": asm3.configuration.cardcom_errorurl(self.dbo), # "https://secure.cardcom.solutions/DealWasUnSuccessful.aspx?customVar=1234",
            "APILevel": "10",
            "IsVirtualTerminalMode": "true",
            "codepage": "65001", # unicode
            "ReturnValue": client_reference_id,
            "IndicatorUrl": "%s/pp_cardcom" % BASE_URL, 
        }

        # determine operation by total charge amount. If charge amount>0, charge and create token (this will also create a tax document). If charge amount==0, only create token
        more_params = {}
        if total_charge_sum > 0: 
            more_params = {
                "Operation": "2",  # charge + create token
                "DocTypeToCreate": asm3.configuration.cardcom_documenttype(self.dbo), # 3 = nonprofit receipt
                "InvoiceHead.CustName": asm3.utils.decode_html(p.OWNERNAME)[:50] , 
                "InvoiceHead.CustAddresLine1": asm3.utils.decode_html(p.OWNERADDRESS)[:50], 
                "InvoiceHead.CustCity": asm3.utils.decode_html(p.OWNERTOWN)[:50],            
                "InvoiceHead.CustMobilePH": asm3.utils.decode_html(p.MOBILETELEPHONE)[:50],  
                "InvoiceHead.ExtIsVatFree": "true",# no VAT for nonprofit receipts. TODO: config?
                "InvoiceHead.SendByEmail": "true", # TODO: not critical - config?
                "InvoiceHead.Language": "he", # TODO: not critical - config / use locale?
                "InvoiceHead.Email": p.EMAILADDRESS,
                }
            for p in self.getInvoiceItems(payments):
                more_params.update(p)   
        else: # if total_charge_sum == 0:
            more_params = {
                "Operation": "3" # only create token
                }

        params.update(more_params)

     

        asm_debug("params: %s" % params, "cardcom.checkoutUrl", self.dbo)
        r = asm3.utils.post_form(url, params)
        asm_debug("response %s, text: %s" % (r["status"], r["response"]), "cardcom.checkoutUrl", self.dbo)
        if not r["status"] < 400:
            raise Exception("Response not ok: %s %s" % (r["status"], r["response"]))
        cardcom_reply = asm3.utils.parse_qs(r["response"])
        if "url" not in cardcom_reply:
            raise Exception("No url in response text: %s" % r["response"])
        asm_debug("return cardcom url: %s" % cardcom_reply['url'], "cardcom.checkoutUrl", self.dbo)
        return cardcom_reply['url']
Example #25
0
def handler(post, path, remoteip, referer, querystring):
    """ Handles the various service method types.
    post:        The GET/POST parameters
    path:        The current system path/code.PATH
    remoteip:    The IP of the caller
    referer:     The referer HTTP header
    querystring: The complete querystring
    return value is a tuple containing MIME type, max-age, content
    """
    # Get service parameters
    account = post["account"]
    username = post["username"]
    password = post["password"]
    method = post["method"]
    animalid = post.integer("animalid")
    formid = post.integer("formid")
    mediaid = post.integer("mediaid")
    seq = post.integer("seq")
    title = post["title"]
    strip_personal = post.integer("sensitive") == 0

    # If this method is in the cache protected list, only use
    # whitelisted parameters for the key to prevent callers
    # cache-busting by adding junk parameters
    cache_key = querystring.replace(" ", "")
    if method in CACHE_PROTECT_METHODS:
        cache_key = safe_cache_key(method, cache_key)

    # Do we have a cached response for these parameters?
    cached_response = get_cached_response(cache_key, account)
    if cached_response is not None:
        asm3.al.debug(
            "cache hit: %s (%d bytes)" % (cache_key, len(cached_response[3])),
            "service.handler", account)
        return cached_response

    # Are we dealing with multiple databases, but no account was specified?
    if account == "" and MULTIPLE_DATABASES:
        return ("text/plain", 0, 0, "ERROR: No database/alias specified")

    # Is flood protection activated for this method?
    if method in FLOOD_PROTECT_METHODS:
        flood_protect(method, remoteip)

    dbo = asm3.db.get_database(account)

    if dbo.database in asm3.db.ERROR_VALUES:
        asm3.al.error(
            "auth failed - invalid smaccount %s from %s (%s)" %
            (account, remoteip, dbo.database), "service.handler", dbo)
        return ("text/plain", 0, 0,
                "ERROR: Invalid database (%s)" % dbo.database)

    # If the database has disabled the service API, stop now
    if not asm3.configuration.service_enabled(dbo):
        asm3.al.error("Service API is disabled (%s)" % method,
                      "service.handler", dbo)
        return ("text/plain", 0, 0, "ERROR: Service API is disabled")

    # Do any database updates need doing in this db?
    dbo.installpath = path
    if asm3.dbupdate.check_for_updates(dbo):
        asm3.dbupdate.perform_updates(dbo)

    # Does the method require us to authenticate? If so, do it.
    user = None
    securitymap = ""
    if method in AUTH_METHODS:
        # If the database has authenticated service methods disabled, stop now
        if not asm3.configuration.service_auth_enabled(dbo):
            asm3.al.error(
                "Service API for auth methods is disabled (%s)" % method,
                "service.handler", dbo)
            return ("text/plain", 0, 0,
                    "ERROR: Service API for authenticated methods is disabled")
        user = asm3.users.authenticate(dbo, username, password)
        if user is None:
            asm3.al.error(
                "auth failed - %s/%s is not a valid username/password from %s"
                % (username, password, remoteip), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid username and password")
        securitymap = asm3.users.get_security_map(dbo, user["USERNAME"])

    # Get the preferred locale and timezone for the site
    l = asm3.configuration.locale(dbo)
    dbo.locale = l
    dbo.timezone = asm3.configuration.timezone(dbo)
    dbo.timezone_dst = asm3.configuration.timezone_dst(dbo)
    asm3.al.info("call @%s --> %s [%s]" % (username, method, querystring),
                 "service.handler", dbo)

    if method == "animal_image":
        hotlink_protect("animal_image", referer)
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "animal_image failed, %s is not an animalid" % str(animalid),
                "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            dummy, data = asm3.media.get_image_file_data(
                dbo, "animal", asm3.utils.cint(animalid), seq)
            if data == "NOPIC":
                dummy, data = asm3.media.get_image_file_data(dbo, "nopic", 0)
            return set_cached_response(cache_key, account, "image/jpeg", 86400,
                                       3600, data)

    elif method == "animal_thumbnail":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "animal_thumbnail failed, %s is not an animalid" %
                str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            dummy, data = asm3.media.get_image_file_data(
                dbo, "animalthumb", asm3.utils.cint(animalid), seq)
            if data == "NOPIC":
                dummy, data = asm3.media.get_image_file_data(dbo, "nopic", 0)
            return set_cached_response(cache_key, account, "image/jpeg", 86400,
                                       3600, data)

    elif method == "animal_view":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "animal_view failed, %s is not an animalid" % str(animalid),
                "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            return set_cached_response(
                cache_key, account, "text/html", 86400, 120,
                asm3.publishers.html.get_animal_view(
                    dbo, asm3.utils.cint(animalid)))

    elif method == "animal_view_adoptable_js":
        return set_cached_response(
            cache_key, account, "application/javascript", 10800, 600,
            asm3.publishers.html.get_animal_view_adoptable_js(dbo))

    elif method == "animal_view_adoptable_html":
        return set_cached_response(
            cache_key, account, "text/html", 86400, 120,
            asm3.publishers.html.get_animal_view_adoptable_html(dbo))

    elif method == "checkout":
        processor = asm3.financial.get_payment_processor(
            dbo, post["processor"])
        if not processor.validatePaymentReference(post["payref"]):
            return ("text/plain", 0, 0, "ERROR: Invalid payref")
        if processor.isPaymentReceived(post["payref"]):
            return ("text/plain", 0, 0, "ERROR: Expired payref")
        return_url = post["return"] or asm3.configuration.payment_return_url(
            dbo)
        return set_cached_response(
            cache_key, account, "text/html", 120, 120,
            processor.checkoutPage(post["payref"], return_url, title))

    elif method == "dbfs_image":
        hotlink_protect("dbfs_image", referer)
        return set_cached_response(
            cache_key, account, "image/jpeg", 86400, 86400,
            asm3.utils.iif(title.startswith("/"),
                           asm3.dbfs.get_string_filepath(dbo, title),
                           asm3.dbfs.get_string(dbo, title)))

    elif method == "document_repository":
        return set_cached_response(
            cache_key, account,
            asm3.media.mime_type(asm3.dbfs.get_name_for_id(dbo, mediaid)),
            86400, 86400, asm3.dbfs.get_string_id(dbo, mediaid))

    elif method == "extra_image":
        hotlink_protect("extra_image", referer)
        return set_cached_response(
            cache_key, account, "image/jpeg", 86400, 86400,
            asm3.dbfs.get_string(dbo, title, "/reports"))

    elif method == "media_image":
        hotlink_protect("media_image", referer)
        return set_cached_response(
            cache_key, account, "image/jpeg", 86400, 86400,
            asm3.dbfs.get_string_id(
                dbo,
                dbo.query_int("select dbfsid from media where id = ?",
                              [mediaid])))

    elif method == "json_adoptable_animal":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "json_adoptable_animal failed, %s is not an animalid" %
                str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                            asm3.users.VIEW_ANIMAL)
            rs = asm3.publishers.base.get_animal_data(
                dbo,
                None,
                asm3.utils.cint(animalid),
                include_additional_fields=True)
            return set_cached_response(cache_key, account, "application/json",
                                       3600, 3600, asm3.utils.json(rs))

    elif method == "html_adoptable_animals":
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_adoptable_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), locationid=post.integer("locationid")))

    elif method == "html_adopted_animals":
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_adopted_animals(dbo, daysadopted=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "html_deceased_animals":
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_deceased_animals(dbo, daysdeceased=post.integer("days"), style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "html_flagged_animals":
        if post["flag"] == "":
            asm3.al.error("html_flagged_animals requested with no flag.",
                          "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid flag")
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_flagged_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid"), flag=post["flag"], allanimals=post.integer("all")))

    elif method == "html_held_animals":
        return set_cached_response(cache_key, account, "text/html", 10800, 1800, \
            asm3.publishers.html.get_held_animals(dbo, style=post["template"], \
                speciesid=post.integer("speciesid"), animaltypeid=post.integer("animaltypeid")))

    elif method == "json_adoptable_animals_xp":
        rs = strip_personal_data(
            asm3.publishers.base.get_animal_data(
                dbo, None, include_additional_fields=True))
        return set_cached_response(cache_key, account, "application/json", 600,
                                   600, asm3.utils.json(rs))

    elif method == "json_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(
            dbo, None, include_additional_fields=True)
        if strip_personal: rs = strip_personal_data(rs)
        return set_cached_response(cache_key, account, "application/json", 600,
                                   600, asm3.utils.json(rs))

    elif method == "jsonp_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(
            dbo, None, include_additional_fields=True)
        if strip_personal: rs = strip_personal_data(rs)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_adoptable_animal":
        if asm3.utils.cint(animalid) == 0:
            asm3.al.error(
                "xml_adoptable_animal failed, %s is not an animalid" %
                str(animalid), "service.handler", dbo)
            return ("text/plain", 0, 0, "ERROR: Invalid animalid")
        else:
            asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                            asm3.users.VIEW_ANIMAL)
            rs = asm3.publishers.base.get_animal_data(
                dbo,
                None,
                asm3.utils.cint(animalid),
                include_additional_fields=True)
            return set_cached_response(cache_key, account, "application/xml",
                                       600, 600, asm3.html.xml(rs))

    elif method == "xml_adoptable_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.publishers.base.get_animal_data(
            dbo, None, include_additional_fields=True)
        if strip_personal: rs = strip_personal_data(rs)
        return set_cached_response(cache_key, account, "application/xml", 600,
                                   600, asm3.html.xml(rs))

    elif method == "json_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_found_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_FOUND_ANIMAL)
        rs = asm3.lostfound.get_foundanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.html.xml(rs))

    elif method == "json_held_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.animal.get_animals_hold(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "xml_held_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.animal.get_animals_hold(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.html.xml(rs))

    elif method == "jsonp_held_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.animal.get_animals_hold(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "json_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_lost_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_LOST_ANIMAL)
        rs = asm3.lostfound.get_lostanimal_last_days(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.html.xml(rs))

    elif method == "json_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(rs))

    elif method == "jsonp_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rs)))

    elif method == "xml_recent_adoptions":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        rs = asm3.movement.get_recent_adoptions(dbo)
        return set_cached_response(cache_key, account, "application/xml", 3600,
                                   3600, asm3.html.xml(rs))

    elif method == "html_report":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rhtml = asm3.reports.execute(dbo, crid, username, p)
        rhtml = asm3.utils.fix_relative_document_uris(dbo, rhtml)
        return set_cached_response(cache_key, account, "text/html", 600, 600,
                                   rhtml)

    elif method == "csv_mail" or method == "csv_report":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        mcsv = asm3.utils.csv(l, rows, cols, True)
        return set_cached_response(cache_key, account, "text/csv", 600, 600,
                                   mcsv)

    elif method == "json_report" or method == "json_mail":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        return set_cached_response(cache_key, account, "application/json", 600,
                                   600, asm3.utils.json(rows))

    elif method == "jsonp_report" or method == "jsonp_mail":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_REPORT)
        crid = asm3.reports.get_id(dbo, title)
        p = asm3.reports.get_criteria_params(dbo, crid, post)
        rows, cols = asm3.reports.execute_query(dbo, crid, username, p)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(rows)))

    elif method == "jsonp_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(sa)))

    elif method == "json_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(sa))

    elif method == "xml_recent_changes":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_recent_changes(dbo)
        return set_cached_response(cache_key, account, "application/xml", 3600,
                                   3600, asm3.html.xml(sa))

    elif method == "jsonp_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return ("application/javascript", 0, 0,
                "%s(%s);" % (post["callback"], asm3.utils.json(sa)))

    elif method == "json_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return set_cached_response(cache_key, account, "application/json",
                                   3600, 3600, asm3.utils.json(sa))

    elif method == "xml_shelter_animals":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        sa = asm3.animal.get_shelter_animals(dbo)
        if strip_personal: sa = strip_personal_data(sa)
        return set_cached_response(cache_key, account, "application/xml", 3600,
                                   3600, asm3.html.xml(sa))

    elif method == "rss_timeline":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.VIEW_ANIMAL)
        return set_cached_response(cache_key, account, "application/rss+xml",
                                   3600, 3600, asm3.html.timeline_rss(dbo))

    elif method == "upload_animal_image":
        asm3.users.check_permission_map(l, user["SUPERUSER"], securitymap,
                                        asm3.users.ADD_MEDIA)
        asm3.media.attach_file_from_form(dbo, username, asm3.media.ANIMAL,
                                         int(animalid), post)
        return ("text/plain", 0, 0, "OK")

    elif method == "online_form_html":
        if formid == 0:
            raise asm3.utils.ASMError(
                "method online_form_html requires a valid formid")
        return set_cached_response(
            cache_key, account, "text/html; charset=utf-8", 120, 120,
            asm3.onlineform.get_onlineform_html(dbo, formid))

    elif method == "online_form_json":
        if formid == 0:
            raise asm3.utils.ASMError(
                "method online_form_json requires a valid formid")
        return set_cached_response(
            cache_key, account, "application/json; charset=utf-8", 30, 30,
            asm3.onlineform.get_onlineform_json(dbo, formid))

    elif method == "online_form_post":
        asm3.onlineform.insert_onlineformincoming_from_form(
            dbo, post, remoteip)
        redirect = post["redirect"]
        if redirect == "":
            redirect = BASE_URL + "/static/pages/form_submitted.html"
        return ("redirect", 0, 0, redirect)

    elif method == "sign_document":
        if formid == 0:
            raise asm3.utils.ASMError(
                "method sign_document requires a valid formid")
        if post["sig"] == "":
            m = asm3.media.get_media_by_id(dbo, formid)
            if m is None: raise asm3.utils.ASMError("invalid link")
            token = asm3.utils.md5_hash_hex("%s%s" % (m.ID, m.LINKID))
            if token != post["token"]:
                raise asm3.utils.ASMError("invalid token")
            return set_cached_response(
                cache_key, account, "text/html", 2, 2,
                sign_document_page(dbo, formid, post["email"]))
        else:
            asm3.media.sign_document(dbo, "service", formid, post["sig"],
                                     post["signdate"], "signemail")
            asm3.media.create_log(dbo, "service", formid, "ES02",
                                  _("Document signed", l))
            if post.boolean("sendsigned"):
                m = asm3.media.get_media_by_id(dbo, formid)
                if m is None:
                    raise asm3.utils.ASMError("cannot find %s" % formid)
                content = asm3.utils.bytes2str(
                    asm3.dbfs.get_string(dbo, m.MEDIANAME))
                contentpdf = asm3.utils.html_to_pdf(dbo, content)
                attachments = [("%s.pdf" % m.ID, "application/pdf", contentpdf)
                               ]
                fromaddr = asm3.configuration.email(dbo)
                asm3.utils.send_email(dbo, fromaddr, post["email"], "", "",
                                      _("Signed Document", l), m.MEDIANOTES,
                                      "plain", attachments)
            return ("text/plain", 0, 0, "OK")

    else:
        asm3.al.error("invalid method '%s'" % method, "service.handler", dbo)
        raise asm3.utils.ASMError("Invalid method '%s'" % method)
Example #26
0
def checkout_adoption_post(dbo, post):
    """
    Called by the adoption checkout frontend with the document signature and donation amount.
    Handles the document signing, triggers creation of the payment records, etc.
    Returns the URL needed to redirect to the payment processor to complete payment.
    """
    l = dbo.locale
    co = asm3.cachedisk.get(post["token"], dbo.database)
    if co is None:
        raise asm3.utils.ASMError("invalid token")
    mediaid = co["mediaid"]
    donationamt = post.integer("donationamt") * 100
    # Sign the docs if they haven't been done already
    if not asm3.media.has_signature(dbo, mediaid):
        signdate = "%s %s" % (python2display(
            l, dbo.now()), format_time(dbo.now()))
        asm3.media.sign_document(dbo, "service", mediaid, post["sig"],
                                 signdate, "signemail")
        if post.boolean("sendsigned"):
            m = asm3.media.get_media_by_id(dbo, mediaid)
            if m is None: raise asm3.utils.ASMError("cannot find %s" % mediaid)
            content = asm3.utils.bytes2str(
                asm3.dbfs.get_string(dbo, m.MEDIANAME))
            contentpdf = asm3.utils.html_to_pdf(dbo, content)
            attachments = [("%s.pdf" % m.ID, "application/pdf", contentpdf)]
            asm3.utils.send_email(dbo, asm3.configuration.email(dbo),
                                  co["email"], "", "", _("Signed Document", l),
                                  m.MEDIANOTES, "plain", attachments)
    # Create the due payment records if they haven't been done already, along with a receipt/payref
    if co["paymentfeeid"] == 0:
        co["paymentprocessor"] = asm3.configuration.adoption_checkout_processor(
            dbo)
        co["receiptnumber"] = asm3.financial.get_next_receipt_number(
            dbo)  # Both go on the same receipt
        co["payref"] = "%s-%s" % (co["personcode"], co["receiptnumber"])
        # Adoption Fee
        co["paymentfeeid"] = asm3.financial.insert_donation_from_form(
            dbo, "checkout",
            asm3.utils.PostedData(
                {
                    "person":
                    str(co["personid"]),
                    "animal":
                    str(co["animalid"]),
                    "movement":
                    str(co["movementid"]),
                    "type":
                    asm3.configuration.adoption_checkout_feeid(dbo),
                    "payment":
                    asm3.configuration.adoption_checkout_payment_method(dbo),
                    "amount":
                    co["fee"],
                    "due":
                    python2display(l, dbo.now()),
                    "receiptnumber":
                    co["receiptnumber"],
                    "giftaid":
                    str(co["giftaid"])
                }, l))
        # Donation (not linked to movement on purpose to avoid showing on adoption fee reports)
        if donationamt > 0:
            co["paymentdonid"] = asm3.financial.insert_donation_from_form(
                dbo, "checkout",
                asm3.utils.PostedData(
                    {
                        "person":
                        str(co["personid"]),
                        "animal":
                        str(co["animalid"]),
                        "type":
                        str(
                            asm3.configuration.adoption_checkout_donationid(
                                dbo)),
                        "payment":
                        str(
                            asm3.configuration.
                            adoption_checkout_payment_method(dbo)),
                        "amount":
                        str(donationamt),
                        "due":
                        python2display(l, dbo.now()),
                        "receiptnumber":
                        co["receiptnumber"],
                        "giftaid":
                        str(co["giftaid"])
                    }, l))
        # Update the cache entry
        asm3.cachedisk.put(post["token"], dbo.database, co, 86400 * 2)
    elif co["paymentdonid"] > 0 and donationamt > 0:
        # payments have already been created, must be a user revisiting the checkout.
        # update their donation amount in case they made a different choice this time.
        dbo.update("ownerdonation", co["paymentdonid"],
                   {"Donation": donationamt}, "checkout")
    elif co["paymentdonid"] > 0 and donationamt == 0:
        # The user has changed their voluntary donation amount to 0 - delete it
        dbo.delete("ownerdonation", co["paymentdonid"], "checkout")
    # Construct the payment checkout URL
    params = {
        "account":
        dbo.database,
        "method":
        "checkout",
        "processor":
        co["paymentprocessor"],
        "payref":
        co["payref"],
        "title":
        _("{0}: Adoption fee") +
        asm3.utils.iif(co["paymentdonid"] != "0", _(" + donation"), "")
    }
    url = "%s?%s" % (SERVICE_URL, asm3.utils.urlencode(params))
    return url
Example #27
0
# tablename : ( tablelabel, namefield, namelabel, descfield, modifiers,(foreignkeys) )
# modifiers:
#   add - add new records
#   del - can delete
#   ret - can retire a value
#   species - has a SpeciesID column (breed)
#   pubspec - has a PetFinderSpecies column (species)
#   pubbreed - has a PetFinderBreed column (breed)
#   pubcol - has an AdoptAPetColour column (basecolour)
#   sched - has a RescheduleDays column (vaccinationtype)
#   cost - has a DefaultCost column (citationtype, costtype, donationtype, licencetype)
#   units - has Units column (internallocation)
#   site - has SiteID column (internallocation)
#   vat - has an IsVAT column (donationtype)
LOOKUP_TABLES = {
    "lksaccounttype": (_("Account Types"), "AccountType", _("Type"), "", "",
                       ("accounts.AccountType", )),
    "lkanimalflags": (_("Animal Flags"), "Flag", _("Flag"), "", "add del", ""),
    "animaltype":
    (_("Animal Types"), "AnimalType", _("Type"), "AnimalDescription",
     "add del ret", ("animal.AnimalTypeID", )),
    "basecolour":
    (_("Colors"), "BaseColour", _("Color"), "BaseColourDescription",
     "add del ret pubcol", ("animal.BaseColourID", "animallost.BaseColourID",
                            "animalfound.BaseColourID")),
    "breed": (_("Breeds"), "BreedName", _("Breed"), "BreedDescription",
              "add del ret species pubbreed",
              ("animal.BreedID", "animal.Breed2ID", "animallost.BreedID",
               "animalfound.BreedID")),
    "lkcoattype": (_("Coat Types"), "CoatType", _("Coat Type"), "", "add del",
                   ("animal.CoatType", )),
Example #28
0
# tablename : ( tablelabel, namefield, namelabel, descfield, modifiers,(foreignkeys) )
# modifiers: 
#   add - add new records
#   del - can delete
#   ret - can retire a value
#   species - has a SpeciesID column (breed)
#   pubspec - has a PetFinderSpecies column (species)
#   pubbreed - has a PetFinderBreed column (breed)
#   pubcol - has an AdoptAPetColour column (basecolour)
#   sched - has a RescheduleDays column (vaccinationtype)
#   cost - has a DefaultCost column (citationtype, costtype, donationtype, licencetype)
#   units - has Units column (internallocation)
#   site - has SiteID column (internallocation)
#   vat - has an IsVAT column (donationtype)
LOOKUP_TABLES = {
    "lksaccounttype":   (_("Account Types"), "AccountType", _("Type"), "", "", ("accounts.AccountType",)),
    "lkanimalflags":    (_("Animal Flags"), "Flag", _("Flag"), "", "add del", ""),
    "animaltype":       (_("Animal Types"), "AnimalType", _("Type"), "AnimalDescription", "add del ret", ("animal.AnimalTypeID",)),
    "basecolour":       (_("Colors"), "BaseColour", _("Color"), "BaseColourDescription", "add del ret pubcol", ("animal.BaseColourID", "animallost.BaseColourID", "animalfound.BaseColourID")),
    "breed":            (_("Breeds"), "BreedName", _("Breed"), "BreedDescription", "add del ret species pubbreed", ("animal.BreedID", "animal.Breed2ID", "animallost.BreedID", "animalfound.BreedID")),
    "lkcoattype":       (_("Coat Types"), "CoatType", _("Coat Type"), "", "add del", ("animal.CoatType",)),
    "citationtype":     (_("Citation Types"), "CitationName", _("Citation Type"), "CitationDescription", "add del ret cost", ("ownercitation.CitationTypeID",)),
    "lksclinicstatus":  (_("Clinic Statuses"), "Status", _("Status"), "", "", ("clinicappointment.Status",)),
    "costtype":         (_("Cost Types"), "CostTypeName", _("Cost Type"), "CostTypeDescription", "add del ret cost", ("animalcost.CostTypeID",)),
    "deathreason":      (_("Death Reasons"), "ReasonName", _("Reason"), "ReasonDescription", "add del ret", ("animal.PTSReasonID",)),
    "diet":             (_("Diets"), "DietName", _("Diet"), "DietDescription", "add del ret", ("animaldiet.DietID",)),
    "donationpayment":  (_("Payment Methods"), "PaymentName", _("Type"), "PaymentDescription", "add del ret", ("ownerdonation.DonationPaymentID",)),
    "donationtype":     (_("Payment Types"), "DonationName", _("Type"), "DonationDescription", "add del ret cost vat", ("ownerdonation.DonationTypeID", "accounts.DonationTypeID")),
    "entryreason":      (_("Entry Reasons"), "ReasonName", _("Reason"), "ReasonDescription", "add del ret", ("animal.EntryReasonID", "adoption.ReturnedReasonID") ),
    "incidentcompleted":(_("Incident Completed Types"), "CompletedName", _("Completed Type"), "CompletedDescription", "add del ret", ("animalcontrol.IncidentCompletedID",)),
    "incidenttype":     (_("Incident Types"), "IncidentName", _("Type"), "IncidentDescription", "add del ret", ("animalcontrol.IncidentTypeID",)),
Example #29
0
def create_animal(dbo, username, wlid):
    """
    Creates an animal record from a waiting list entry with the id given
    """
    l = dbo.locale
    a = dbo.first_row(
        dbo.query("SELECT * FROM animalwaitinglist WHERE ID = ?", [wlid]))

    data = {
        "animalname": _("Waiting List {0}", l).format(wlid),
        "markings": str(a["ANIMALDESCRIPTION"]),
        "reasonforentry": str(a["REASONFORWANTINGTOPART"]),
        "species": str(a["SPECIESID"]),
        "hiddenanimaldetails": str(a["COMMENTS"]),
        "broughtinby": str(a["OWNERID"]),
        "originalowner": str(a["OWNERID"]),
        "animaltype": asm3.configuration.default_type(dbo),
        "entryreason": asm3.configuration.default_entry_reason(dbo),
        "breed1": asm3.configuration.default_breed(dbo),
        "breed2": asm3.configuration.default_breed(dbo),
        "basecolour": asm3.configuration.default_colour(dbo),
        "size": asm3.configuration.default_size(dbo),
        "internallocation": asm3.configuration.default_location(dbo),
        "dateofbirth": python2display(l, subtract_years(now(dbo.timezone))),
        "estimateddob": "1"
    }
    # If we aren't showing the time brought in, set it to midnight
    if not asm3.configuration.add_animals_show_time_brought_in(dbo):
        data["timebroughtin"] = "00:00:00"

    # If we're creating shelter codes manually, we need to put something unique
    # in there for now. Use the id
    if asm3.configuration.manual_codes(dbo):
        data["sheltercode"] = "WL" + str(wlid)
        data["shortcode"] = "WL" + str(wlid)
    nextid, code = asm3.animal.insert_animal_from_form(
        dbo, asm3.utils.PostedData(data, l), username)

    # Now that we've created our animal, we should remove this entry from the waiting list
    dbo.update(
        "animalwaitinglist", wlid, {
            "DateRemovedFromList": dbo.today(),
            "ReasonForRemoval": _("Moved to animal record {0}", l).format(code)
        }, username)

    # If there were any logs and media entries on the waiting list, create them on the animal

    # Media
    for me in dbo.query(
            "SELECT * FROM media WHERE LinkTypeID = ? AND LinkID = ?",
        (asm3.media.WAITINGLIST, wlid)):
        ext = me.medianame
        ext = ext[ext.rfind("."):].lower()
        mediaid = dbo.get_id("media")
        medianame = "%d%s" % (mediaid, ext)
        dbo.insert(
            "media",
            {
                "ID": mediaid,
                "DBFSID": 0,
                "MediaSize": 0,
                "MediaName": medianame,
                "MediaMimeType": asm3.media.mime_type(medianame),
                "MediaType": me.mediatype,
                "MediaNotes": me.medianotes,
                "WebsitePhoto": me.websitephoto,
                "WebsiteVideo": me.websitevideo,
                "DocPhoto": me.docphoto,
                "ExcludeFromPublish": me.excludefrompublish,
                # ASM2_COMPATIBILITY
                "NewSinceLastPublish": 1,
                "UpdatedSinceLastPublish": 0,
                # ASM2_COMPATIBILITY
                "LinkID": nextid,
                "LinkTypeID": asm3.media.ANIMAL,
                "Date": me.date,
                "CreatedDate": me.createddate,
                "RetainUntil": me.retainuntil
            },
            generateID=False)

        # Now clone the dbfs item pointed to by this media item if it's a file
        if me.mediatype == asm3.media.MEDIATYPE_FILE:
            filedata = asm3.dbfs.get_string(dbo, me.medianame)
            dbfsid = asm3.dbfs.put_string(dbo, medianame,
                                          "/animal/%d" % nextid, filedata)
            dbo.execute(
                "UPDATE media SET DBFSID = ?, MediaSize = ? WHERE ID = ?",
                (dbfsid, len(filedata), mediaid))

    # Logs
    for lo in dbo.query("SELECT * FROM log WHERE LinkType = ? AND LinkID = ?",
                        (asm3.log.WAITINGLIST, wlid)):
        dbo.insert(
            "log", {
                "LinkID": nextid,
                "LinkType": asm3.log.ANIMAL,
                "LogTypeID": lo.LOGTYPEID,
                "Date": lo.DATE,
                "Comments": lo.COMMENTS
            }, username)

    return nextid