Beispiel #1
0
def insert_payment_from_appointment(dbo, username, appointmentid, post):
    """
    Creates a payment record from an appointment via the create payment dialog.
    """
    l = dbo.locale
    c = get_appointment(dbo, appointmentid)
    d = {
        "person":
        str(c.OwnerID),
        "animal":
        str(c.AnimalID),
        "type":
        post["paymenttype"],
        "payment":
        post["paymentmethod"],
        "amount":
        str(c.Amount),
        "due":
        post["due"],
        "received":
        post["received"],
        "vat":
        utils.iif(c.IsVAT == 1, "on", ""),
        "vatrate":
        str(c.VATRate),
        "vatamount":
        str(c.VATAmount),
        "comments":
        i18n._("Appointment {0}. {1} on {2} for {3}").format(
            utils.padleft(c.ID, 6), c.OWNERNAME,
            i18n.python2display(l, c.DATETIME), c.ANIMALNAME)
    }
    return financial.insert_donation_from_form(dbo, username,
                                               utils.PostedData(d, l))
Beispiel #2
0
 def test_receive_donation(self):
     data = {
         "person": "1",
         "animal": "1",
         "type":   "1",
         "payment": "1",
         "frequency": "0",
         "amount": "1000",
         "due": base.today()
     }
     post = utils.PostedData(data, "en")
     did = financial.insert_donation_from_form(base.get_dbo(), "test", post)
     financial.update_donation_from_form(base.get_dbo(), "test", post)
     financial.receive_donation(base.get_dbo(), "test", did)
     financial.delete_donation(base.get_dbo(), "test", did)
Beispiel #3
0
 def test_receive_donation(self):
     data = {
         "person": "1",
         "animal": "1",
         "type": "1",
         "payment": "1",
         "frequency": "0",
         "amount": "1000",
         "due": base.today_display()
     }
     post = utils.PostedData(data, "en")
     did = financial.insert_donation_from_form(base.get_dbo(), "test", post)
     financial.update_donation_from_form(base.get_dbo(), "test", post)
     financial.receive_donation(base.get_dbo(), "test", did)
     financial.delete_donation(base.get_dbo(), "test", did)
Beispiel #4
0
            m["returncategory"] = str(configuration.default_entry_reason(dbo))
            try:
                movementid = movement.insert_movement_from_form(
                    dbo, "import", m)
            except Exception, e:
                errors.append((rowno, str(row), "movement: " + str(e)))

        # Donation?
        if hasdonation and personid != 0 and gks(row, "DONATIONAMOUNT") != "":
            d = {}
            d["person"] = str(personid)
            d["animal"] = str(animalid)
            d["movement"] = str(movementid)
            d["amount"] = gks(row, "DONATIONAMOUNT")
            d["comments"] = gks(row, "DONATIONCOMMENTS")
            d["received"] = gkd(dbo, row, "DONATIONDATE", True)
            d["type"] = gkl(dbo, row, "DONATIONTYPE", "donationtype",
                            "DonationName", createmissinglookups)
            if d["type"] == "0":
                d["type"] = str(configuration.default_donation_type(dbo))
            try:
                financial.insert_donation_from_form(dbo, "import", d)
            except Exception, e:
                errors.append((rowno, str(row), "donation: " + str(e)))
            if movementid != 0:
                movement.update_movement_donation(dbo, movementid)

        rowno += 1

    return errors
Beispiel #5
0
def insert_reserve_from_form(dbo, username, data):
    """
    Inserts a movement from the workflow reserve an animal screen.
    Returns the new movement id
    """
    # Validate that we have a date before doing anthing
    l = dbo.locale
    if None == utils.df_kd(data, "reservationdate", l):
        raise utils.ASMValidationError(
            i18n._("Reservations must have a valid reservation date.", l))

    # Do the movement itself first
    move_dict = {
        "person": utils.df_ks(data, "person"),
        "animal": utils.df_ks(data, "animal"),
        "reservationdate": utils.df_ks(data, "reservationdate"),
        "adoptionno": utils.df_ks(data, "movementnumber"),
        "movementdate": "",
        "type": str(NO_MOVEMENT),
        "donation": utils.df_ks(data, "amount"),
        "returncategory": configuration.default_return_reason(dbo)
    }
    movementid = insert_movement_from_form(dbo, username, move_dict)
    # Then the donation if we have one
    donation_amount = int(utils.df_m(data, "amount", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "reservationdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "reservationdate")
            received = ""
        don_dict = {
            "person": utils.df_ks(data, "person"),
            "animal": utils.df_ks(data, "animal"),
            "movement": str(movementid),
            "type": utils.df_ks(data, "donationtype"),
            "payment": utils.df_ks(data, "payment"),
            "frequency": "0",
            "amount": utils.df_ks(data, "amount"),
            "due": due,
            "received": received,
            "giftaid": utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    # And a second donation if there is one
    donation_amount = int(utils.df_m(data, "amount2", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "movementdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "movementdate")
            received = ""
        don_dict = {
            "person": utils.df_ks(data, "person"),
            "animal": utils.df_ks(data, "animal"),
            "movement": str(movementid),
            "type": utils.df_ks(data, "donationtype2"),
            "payment": utils.df_ks(data, "payment2"),
            "frequency": "0",
            "amount": utils.df_ks(data, "amount2"),
            "due": due,
            "received": received,
            "giftaid": utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    return movementid
Beispiel #6
0
def insert_adoption_from_form(dbo, username, data, creating=[]):
    """
    Inserts a movement from the workflow adopt an animal screen.
    Returns the new movement id
    creating is an ongoing list of animals we're already going to
    create adoptions for. It prevents a never ending recursive loop
    of animal1 being bonded to animal2 that's bonded to animal1, etc.
    """
    l = dbo.locale
    # Validate that we have a movement date before doing anthing
    if None == utils.df_kd(data, "movementdate", l):
        raise utils.ASMValidationError(
            i18n._("Adoption movements must have a valid adoption date.", l))
    # Get the animal record for this adoption
    a = animal.get_animal(dbo, utils.df_ki(data, "animal"))
    if a is None:
        raise utils.ASMValidationError(
            "Adoption POST has an invalid animal ID: %d" %
            utils.df_ki(data, "animal"))
    al.debug(
        "Creating adoption for %d (%s - %s)" %
        (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]),
        "movement.insert_adoption_from_form", dbo)
    creating.append(a["ID"])
    # If the animal is bonded to other animals, we call this function
    # again with a copy of the data and the bonded animal substituted
    # so we can create their adoption records too.
    if a["BONDEDANIMALID"] is not None and a["BONDEDANIMALID"] != 0 and a[
            "BONDEDANIMALID"] not in creating:
        al.debug(
            "Found bond to animal %d, creating adoption..." %
            a["BONDEDANIMALID"], "movement.insert_adoption_from_form", dbo)
        newdata = dict(data)
        newdata["animal"] = str(a["BONDEDANIMALID"])
        insert_adoption_from_form(dbo, username, newdata, creating)
    if a["BONDEDANIMAL2ID"] is not None and a["BONDEDANIMAL2ID"] != 0 and a[
            "BONDEDANIMAL2ID"] not in creating:
        al.debug(
            "Found bond to animal %d, creating adoption..." %
            a["BONDEDANIMAL2ID"], "movement.insert_adoption_from_form", dbo)
        newdata = dict(data)
        newdata["animal"] = str(a["BONDEDANIMAL2ID"])
        insert_adoption_from_form(dbo, username, newdata, creating)
    cancel_reserves = configuration.cancel_reserves_on_adoption(dbo)
    # Prepare a dictionary of data for the movement table via insert_movement_from_form
    move_dict = {
        "person": utils.df_ks(data, "person"),
        "animal": utils.df_ks(data, "animal"),
        "adoptionno": utils.df_ks(data, "movementnumber"),
        "movementdate": utils.df_ks(data, "movementdate"),
        "type": str(ADOPTION),
        "donation": utils.df_ks(data, "amount"),
        "insurance": utils.df_ks(data, "insurance"),
        "returncategory": configuration.default_return_reason(dbo),
        "trial": utils.df_ks(data, "trial"),
        "trialenddate": utils.df_ks(data, "trialenddate")
    }
    # Is this animal currently on foster? If so, return the foster
    fm = get_animal_movements(dbo, utils.df_ki(data, "animal"))
    for m in fm:
        if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None:
            return_movement(dbo, m["ID"], utils.df_ki(data, "animal"),
                            utils.df_kd(data, "movementdate", l))
    # Is this animal current at a retailer? If so, return it from the
    # retailer and set the originalretailermovement and retailerid fields
    # on our new adoption movement so it can be linked back
    for m in fm:
        if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None:
            return_movement(dbo, m["ID"], utils.df_ki(data, "animal"),
                            utils.df_kd(data, "movementdate", l))
            move_dict["originalretailermovement"] = str(m["ID"])
            move_dict["retailer"] = str(m["OWNERID"])
    # Did we say we'd like to flag the owner as homechecked?
    if utils.df_kc(data, "homechecked") == 1:
        db.execute(dbo, "UPDATE owner SET IDCheck = 1, DateLastHomeChecked = %s WHERE ID = %d" % \
            ( db.dd(i18n.now(dbo.timezone)), utils.df_ki(data, "person")))
    # If the animal was flagged as not available for adoption, then it
    # shouldn't be since we've just adopted it.
    db.execute(
        dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" %
        utils.df_ks(data, "animal"))
    # Is the animal reserved to the person adopting?
    movementid = 0
    for m in fm:
        if m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \
            and m["RESERVATIONCANCELLEDDATE"] is None and m["ANIMALID"] == utils.df_ki(data, "animal") \
            and m["OWNERID"] == utils.df_ki(data, "person"):
            # yes - update the existing movement
            movementid = m["ID"]
            move_dict["movementid"] = str(movementid)
            move_dict["adoptionno"] = utils.padleft(movementid, 6)
            move_dict["reservationdate"] = str(
                i18n.python2display(l, m["RESERVATIONDATE"]))
            move_dict["comments"] = utils.nulltostr(m["COMMENTS"])
            break
        elif cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \
            and m["RESERVATIONCANCELLEDDATE"] is None:
            # no, but it's reserved to someone else and we're cancelling
            # reserves on adoption
            db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \
                ( utils.df_d(data, "movementdate", l), m["ID"] ))
    if movementid != 0:
        update_movement_from_form(dbo, username, move_dict)
    else:
        movementid = insert_movement_from_form(dbo, username, move_dict)
    # Create the donation if there is one
    donation_amount = int(utils.df_m(data, "amount", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "movementdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "movementdate")
            received = ""
        don_dict = {
            "person": utils.df_ks(data, "person"),
            "animal": utils.df_ks(data, "animal"),
            "movement": str(movementid),
            "type": utils.df_ks(data, "donationtype"),
            "payment": utils.df_ks(data, "payment"),
            "frequency": "0",
            "amount": utils.df_ks(data, "amount"),
            "due": due,
            "received": received,
            "giftaid": utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    # And a second donation if there is one
    donation_amount = int(utils.df_m(data, "amount2", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "movementdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "movementdate")
            received = ""
        don_dict = {
            "person": utils.df_ks(data, "person"),
            "animal": utils.df_ks(data, "animal"),
            "movement": str(movementid),
            "type": utils.df_ks(data, "donationtype2"),
            "payment": utils.df_ks(data, "payment2"),
            "frequency": "0",
            "amount": utils.df_ks(data, "amount2"),
            "due": due,
            "received": received,
            "giftaid": utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    # Then any boarding cost record
    cost_amount = int(utils.df_m(data, "costamount", l))
    cost_type = utils.df_ks(data, "costtype")
    cost_create = utils.df_ki(data, "costcreate")
    if cost_amount > 0 and cost_type != "" and cost_create == 1:
        boc_dict = {
            "animalid": utils.df_ks(data, "animal"),
            "type": cost_type,
            "costdate": utils.df_ks(data, "movementdate"),
            "cost": utils.df_ks(data, "costamount")
        }
        animal.insert_cost_from_form(dbo, username, boc_dict)
    return movementid
Beispiel #7
0
def insert_reserve_from_form(dbo, username, data):
    """
    Inserts a movement from the workflow reserve an animal screen.
    Returns the new movement id
    """
    # Validate that we have a date before doing anthing
    l = dbo.locale
    if None == utils.df_kd(data, "reservationdate", l):
        raise utils.ASMValidationError(i18n._("Reservations must have a valid reservation date.", l))

    # Do the movement itself first
    move_dict = {
        "person"                : utils.df_ks(data, "person"),
        "animal"                : utils.df_ks(data, "animal"),
        "reservationdate"       : utils.df_ks(data, "reservationdate"),
        "adoptionno"            : utils.df_ks(data, "movementnumber"),
        "movementdate"          : "",
        "type"                  : str(NO_MOVEMENT),
        "donation"              : utils.df_ks(data, "amount"),
        "returncategory"        : configuration.default_return_reason(dbo)
    }
    movementid = insert_movement_from_form(dbo, username, move_dict)
    # Then the donation if we have one
    donation_amount = int(utils.df_m(data, "amount", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "reservationdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "reservationdate")
            received = ""
        don_dict = {
            "person"                : utils.df_ks(data, "person"),
            "animal"                : utils.df_ks(data, "animal"),
            "movement"              : str(movementid),
            "type"                  : utils.df_ks(data, "donationtype"),
            "payment"               : utils.df_ks(data, "payment"),
            "frequency"             : "0",
            "amount"                : utils.df_ks(data, "amount"),
            "due"                   : due,
            "received"              : received,
            "giftaid"               : utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    # And a second donation if there is one
    donation_amount = int(utils.df_m(data, "amount2", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "movementdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "movementdate")
            received = ""
        don_dict = {
            "person"                : utils.df_ks(data, "person"),
            "animal"                : utils.df_ks(data, "animal"),
            "movement"              : str(movementid),
            "type"                  : utils.df_ks(data, "donationtype2"),
            "payment"               : utils.df_ks(data, "payment2"),
            "frequency"             : "0",
            "amount"                : utils.df_ks(data, "amount2"),
            "due"                   : due,
            "received"              : received,
            "giftaid"               : utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    return movementid
Beispiel #8
0
def insert_adoption_from_form(dbo, username, data, creating = []):
    """
    Inserts a movement from the workflow adopt an animal screen.
    Returns the new movement id
    creating is an ongoing list of animals we're already going to
    create adoptions for. It prevents a never ending recursive loop
    of animal1 being bonded to animal2 that's bonded to animal1, etc.
    """
    l = dbo.locale
    # Validate that we have a movement date before doing anthing
    if None == utils.df_kd(data, "movementdate", l):
        raise utils.ASMValidationError(i18n._("Adoption movements must have a valid adoption date.", l))
    # Get the animal record for this adoption
    a = animal.get_animal(dbo, utils.df_ki(data, "animal"))
    if a is None:
        raise utils.ASMValidationError("Adoption POST has an invalid animal ID: %d" % utils.df_ki(data, "animal"))
    al.debug("Creating adoption for %d (%s - %s)" % (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]), "movement.insert_adoption_from_form", dbo)
    creating.append(a["ID"])
    # If the animal is bonded to other animals, we call this function
    # again with a copy of the data and the bonded animal substituted
    # so we can create their adoption records too.
    if a["BONDEDANIMALID"] is not None and a["BONDEDANIMALID"] != 0 and a["BONDEDANIMALID"] not in creating:
        al.debug("Found bond to animal %d, creating adoption..." % a["BONDEDANIMALID"], "movement.insert_adoption_from_form", dbo)
        newdata = dict(data)
        newdata["animal"] = str(a["BONDEDANIMALID"])
        insert_adoption_from_form(dbo, username, newdata, creating)
    if a["BONDEDANIMAL2ID"] is not None and a["BONDEDANIMAL2ID"] != 0 and a["BONDEDANIMAL2ID"] not in creating:
        al.debug("Found bond to animal %d, creating adoption..." % a["BONDEDANIMAL2ID"], "movement.insert_adoption_from_form", dbo)
        newdata = dict(data)
        newdata["animal"] = str(a["BONDEDANIMAL2ID"])
        insert_adoption_from_form(dbo, username, newdata, creating)
    cancel_reserves = configuration.cancel_reserves_on_adoption(dbo)
    # Prepare a dictionary of data for the movement table via insert_movement_from_form
    move_dict = {
        "person"                : utils.df_ks(data, "person"),
        "animal"                : utils.df_ks(data, "animal"),
        "adoptionno"            : utils.df_ks(data, "movementnumber"),
        "movementdate"          : utils.df_ks(data, "movementdate"),
        "type"                  : str(ADOPTION),
        "donation"              : utils.df_ks(data, "amount"),
        "insurance"             : utils.df_ks(data, "insurance"),
        "returncategory"        : configuration.default_return_reason(dbo),
        "trial"                 : utils.df_ks(data, "trial"),
        "trialenddate"          : utils.df_ks(data, "trialenddate")
    }
    # Is this animal currently on foster? If so, return the foster
    fm = get_animal_movements(dbo, utils.df_ki(data, "animal"))
    for m in fm:
        if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None:
            return_movement(dbo, m["ID"], utils.df_ki(data, "animal"), utils.df_kd(data, "movementdate", l))
    # Is this animal current at a retailer? If so, return it from the
    # retailer and set the originalretailermovement and retailerid fields
    # on our new adoption movement so it can be linked back
    for m in fm:
        if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None:
            return_movement(dbo, m["ID"], utils.df_ki(data, "animal"), utils.df_kd(data, "movementdate", l))
            move_dict["originalretailermovement"] = str(m["ID"])
            move_dict["retailer"] = str(m["OWNERID"])
    # Did we say we'd like to flag the owner as homechecked?
    if utils.df_kc(data, "homechecked") == 1:
        db.execute(dbo, "UPDATE owner SET IDCheck = 1, DateLastHomeChecked = %s WHERE ID = %d" % \
            ( db.dd(i18n.now(dbo.timezone)), utils.df_ki(data, "person")))
    # If the animal was flagged as not available for adoption, then it
    # shouldn't be since we've just adopted it.
    db.execute(dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" % utils.df_ks(data, "animal"))
    # Is the animal reserved to the person adopting? 
    movementid = 0
    for m in fm:
        if m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \
            and m["RESERVATIONCANCELLEDDATE"] is None and m["ANIMALID"] == utils.df_ki(data, "animal") \
            and m["OWNERID"] == utils.df_ki(data, "person"):
            # yes - update the existing movement
            movementid = m["ID"]
            move_dict["movementid"] = str(movementid)
            move_dict["adoptionno"] = utils.padleft(movementid, 6)
            move_dict["reservationdate"] = str(i18n.python2display(l, m["RESERVATIONDATE"]))
            move_dict["comments"] = utils.nulltostr(m["COMMENTS"])
            break
        elif cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \
            and m["RESERVATIONCANCELLEDDATE"] is None:
            # no, but it's reserved to someone else and we're cancelling
            # reserves on adoption
            db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \
                ( utils.df_d(data, "movementdate", l), m["ID"] ))
    if movementid != 0:
        update_movement_from_form(dbo, username, move_dict)
    else:
        movementid = insert_movement_from_form(dbo, username, move_dict)
    # Create the donation if there is one
    donation_amount = int(utils.df_m(data, "amount", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "movementdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "movementdate")
            received = ""
        don_dict = {
            "person"                : utils.df_ks(data, "person"),
            "animal"                : utils.df_ks(data, "animal"),
            "movement"              : str(movementid),
            "type"                  : utils.df_ks(data, "donationtype"),
            "payment"               : utils.df_ks(data, "payment"),
            "frequency"             : "0",
            "amount"                : utils.df_ks(data, "amount"),
            "due"                   : due,
            "received"              : received,
            "giftaid"               : utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    # And a second donation if there is one
    donation_amount = int(utils.df_m(data, "amount2", l))
    if donation_amount > 0:
        due = ""
        received = utils.df_ks(data, "movementdate")
        if configuration.movement_donations_default_due(dbo):
            due = utils.df_ks(data, "movementdate")
            received = ""
        don_dict = {
            "person"                : utils.df_ks(data, "person"),
            "animal"                : utils.df_ks(data, "animal"),
            "movement"              : str(movementid),
            "type"                  : utils.df_ks(data, "donationtype2"),
            "payment"               : utils.df_ks(data, "payment2"),
            "frequency"             : "0",
            "amount"                : utils.df_ks(data, "amount2"),
            "due"                   : due,
            "received"              : received,
            "giftaid"               : utils.df_ks(data, "giftaid")
        }
        financial.insert_donation_from_form(dbo, username, don_dict)
    # Then any boarding cost record
    cost_amount = int(utils.df_m(data, "costamount", l))
    cost_type = utils.df_ks(data, "costtype")
    cost_create = utils.df_ki(data, "costcreate")
    if cost_amount > 0 and cost_type != "" and cost_create == 1:
        boc_dict = {
            "animalid"          : utils.df_ks(data, "animal"),
            "type"              : cost_type,
            "costdate"          : utils.df_ks(data, "movementdate"),
            "cost"              : utils.df_ks(data, "costamount")
        }
        animal.insert_cost_from_form(dbo, username, boc_dict)
    return movementid
Beispiel #9
0
def csvimport_paypal(dbo, csvdata, donationtypeid, donationpaymentid, flags, user = ""):
    """
    Imports a PayPal CSV file of transactions.
    """
    def v(r, n, n2 = "", n3 = "", n4 = "", n5 = ""):
        """ Read values n(x) from a dictionary r depending on which is present, 
            if none are present empty string is returned """
        if n in r: return r[n]
        if n2 != "" and n2 in r: return r[n2]
        if n3 != "" and n3 in r: return r[n3]
        if n4 != "" and n4 in r: return r[n4]
        if n5 != "" and n5 in r: return r[n5]
        return ""

    if user == "":
        user = "******"
    else:
        user = "******" % user

    reader = utils.UnicodeCSVDictReader(StringIO(csvdata))
    data = list(reader)
    errors = []
    rowno = 1
    asynctask.set_progress_max(dbo, len(data))

    for r in data:

        # Skip blank rows
        if len(r) == 0: continue

        # Should we stop?
        if asynctask.get_cancel(dbo): break

        REQUIRED_FIELDS = [ "Date", "Currency", "Gross", "Fee", "Net", "From Email Address", "Status", "Type" ]
        for rf in REQUIRED_FIELDS:
            if rf not in r:
                asynctask.set_last_error(dbo, "This CSV file does not look like a PayPal CSV (missing %s)" % rf)
                return

        al.debug("import paypal csv: row %d of %d" % (rowno, len(data)), "csvimport.csvimport_paypal", dbo)
        asynctask.increment_progress_value(dbo)

        if r["Status"] != "Completed":
            al.debug("skipping: Status='%s' (!= Completed), Type='%s'" % (r["Status"], r["Type"]), "csvimport.csvimport_paypal", dbo)
            continue

        if r["Type"].find("Payment") == -1:
            al.debug("skipping: Status='%s', Type='%s' (!Payment)" % (r["Status"], r["Type"]), "csvimport.csvimport_paypal", dbo)
            continue

        # Parse name (use all up to last space for first names if only Name exists)
        name = v(r, "Name")
        firstname = v(r, "First Name")
        lastname = v(r, "Last Name")
        if name != "" and firstname == "" and lastname == "":
            if name.find(" ") != -1:
                firstname =name[0:name.rfind(" ")]
                lastname =name[name.rfind(" ")+1:]
            else:
                lastname = name

        # Person data
        personid = 0
        p = {}
        p["ownertype"] = "1"
        p["forenames"] = firstname
        p["surname"] = lastname
        p["address"] = v(r, "Address Line 1", "Street Address 1")
        p["town"] = v(r, "Town/City", "Town", "City")
        p["county"] = v(r, "County", "State", "Province", "Region", "State/Province/Region/County/Territory/Prefecture/Republic")
        p["postcode"] = v(r, "Postcode", "Zip Code", "Zip/Postal Code")
        p["hometelephone"] = v(r, "Contact Phone Number", "Phone Number")
        p["emailaddress"] = v(r, "From Email Address")
        p["flags"] = flags
        try:
            dups = person.get_person_similar(dbo, p["emailaddress"], p["surname"], p["forenames"], p["address"])
            if len(dups) > 0:
                personid = dups[0]["ID"]
                # Merge flags and any extra details
                person.merge_flags(dbo, user, personid, flags)
                person.merge_person_details(dbo, user, personid, p)
            if personid == 0:
                personid = person.insert_person_from_form(dbo, utils.PostedData(p, dbo.locale), user, geocode=False)
        except Exception as e:
            row_error(errors, "person", rowno, r, e, dbo, sys.exc_info())

        # Donation info
        net = utils.cint(utils.cfloat(v(r, "Net")) * 100)
        fee = utils.cint(utils.cfloat(v(r, "Fee")) * 100)
        if personid != 0 and net > 0:
            d = {}
            d["person"] = str(personid)
            d["animal"] = "0"
            d["movement"] = "0"
            d["amount"] = str(net)
            d["fee"] = str(fee)
            d["chequenumber"] = str(v(r, "Transaction ID"))
            comments = "PayPal ID: %s \nItem: %s %s \nCurrency: %s \nGross: %s \nFee: %s \nSubject: %s \nNote: %s" % \
                ( v(r, "Transaction ID"), v(r, "Item ID", "Item Number"), v(r, "Item Title"), v(r, "Currency"), 
                v(r, "Gross"), v(r, "Fee"), v(r, "Subject"), v(r, "Note") )
            d["comments"] = comments
            d["received"] = v(r, "Date")
            d["type"] = str(donationtypeid)
            d["payment"] = str(donationpaymentid)
            try:
                financial.insert_donation_from_form(dbo, user, utils.PostedData(d, dbo.locale))
            except Exception as e:
                row_error(errors, "payment", rowno, r, e, dbo, sys.exc_info())

        rowno += 1

    h = [ "<p>%d success, %d errors</p><table>" % (len(data) - len(errors), len(errors)) ]
    for rowno, row, err in errors:
        h.append("<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (rowno, row, err))
    h.append("</table>")
    return "".join(h)
Beispiel #10
0
def csvimport(dbo, csvdata, encoding = "utf8", user = "", createmissinglookups = False, cleartables = False, checkduplicates = False):
    """
    Imports the csvdata.
    createmissinglookups: If a lookup value is given that's not in our data, add it
    cleartables: Clear down the animal, owner and adoption tables before import
    """

    # Convert line endings to standard unix lf to prevent
    # the Python CSV importer barfing.
    csvdata = csvdata.replace("\r\n", "\n")
    csvdata = csvdata.replace("\r", "\n")

    if user == "":
        user = "******"
    else:
        user = "******" % user

    reader = None
    if encoding == "utf8":
        reader = utils.UnicodeCSVReader(StringIO(csvdata))
    else:
        reader = utils.UnicodeCSVReader(StringIO(csvdata), encoding=encoding)

    # Make sure we have a valid header
    cols = None
    for row in reader:
        cols = row
        break
    if cols is None:
        asynctask.set_last_error(dbo, "Your CSV file is empty")
        return

    onevalid = False
    hasanimal = False
    hasanimalname = False
    hasmed = False
    hasvacc = False
    hasperson = False
    haspersonlastname = False
    haspersonname = False
    haslicence = False
    haslicencenumber = False
    hasmovement = False
    hasmovementdate = False
    hasdonation = False
    hasdonationamount = False
    hasoriginalowner = False
    hasoriginalownerlastname = False
    for col in cols:
        if col in VALID_FIELDS: onevalid = True
        if col.startswith("ANIMAL"): hasanimal = True
        if col == "ANIMALNAME": hasanimalname = True
        if col.startswith("ORIGINALOWNER"): hasoriginalowner = True
        if col.startswith("VACCINATION"): hasvacc = True
        if col.startswith("MEDICAL"): hasmed = True
        if col.startswith("LICENSE"): haslicence = True
        if col == "LICENSENUMBER": haslicencenumber = True
        if col == "ORIGINALOWNERLASTNAME": hasoriginalownerlastname = True
        if col.startswith("PERSON"): hasperson = True
        if col == "PERSONLASTNAME": haspersonlastname = True
        if col == "PERSONNAME": haspersonname = True
        if col.startswith("MOVEMENT"): hasmovement = True
        if col == "MOVEMENTDATE": hasmovementdate = True
        if col.startswith("DONATION"): hasdonation = True
        if col == "DONATIONAMOUNT": hasdonationamount = True

    # Any valid fields?
    if not onevalid:
        asynctask.set_last_error(dbo, "Your CSV file did not contain any fields that ASM recognises")
        return

    # If we have any animal fields, make sure at least ANIMALNAME is supplied
    if hasanimal and not hasanimalname:
        asynctask.set_last_error(dbo, "Your CSV file has animal fields, but no ANIMALNAME column")
        return

    # If we have any person fields, make sure at least PERSONLASTNAME or PERSONNAME is supplied
    if hasperson and not haspersonlastname and not haspersonname:
        asynctask.set_last_error(dbo, "Your CSV file has person fields, but no PERSONNAME or PERSONLASTNAME column")
        return

    # If we have any original owner fields, make sure at least ORIGINALOWNERLASTNAME is supplied
    if hasoriginalowner and not hasoriginalownerlastname:
        asynctask.set_last_error(dbo, "Your CSV file has original owner fields, but no ORIGINALOWNERLASTNAME column")
        return

    # If we have any movement fields, make sure MOVEMENTDATE is supplied
    if hasmovement and not hasmovementdate:
        asynctask.set_last_error(dbo, "Your CSV file has movement fields, but no MOVEMENTDATE column")
        return

    # If we have any donation fields, we need an amount
    if hasdonation and not hasdonationamount:
        asynctask.set_last_error(dbo, "Your CSV file has donation fields, but no DONATIONAMOUNT column")
        return

    # We also need a valid person
    if hasdonation and not (haspersonlastname or haspersonname):
        asynctask.set_last_error(dbo, "Your CSV file has donation fields, but no person to apply the donation to")
        return

    # If we have any med fields, we need an animal
    if hasmed and not hasanimal:
        asynctask.set_last_error(dbo, "Your CSV file has medical fields, but no animal to apply them to")
        return

    # If we have any vacc fields, we need an animal
    if hasvacc and not hasanimal:
        asynctask.set_last_error(dbo, "Your CSV file has vaccination fields, but no animal to apply them to")
        return

    # If we have licence fields, we need a number
    if haslicence and not haslicencenumber:
        asynctask.set_last_error(dbo, "Your CSV file has license fields, but no LICENSENUMBER column")
        return

    # We also need a valid person
    if haslicence and not (haspersonlastname or haspersonname):
        asynctask.set_last_error(dbo, "Your CSV file has license fields, but no person to apply the license to")

    # Read the whole CSV file into a list of maps. Note, the
    # reader has a cursor at the second row already because
    # we read the header in the first row above
    data = []
    for row in reader:
        currow = {}
        for i, col in enumerate(row):
            if i >= len(cols): continue # skip if we run out of cols
            currow[cols[i]] = col
        data.append(currow)

    al.debug("reading CSV data, found %d rows" % len(data), "csvimport.csvimport", dbo)

    # If we're clearing down tables first, do it now
    if cleartables:
        al.warn("Resetting the database by removing all non-lookup data", "csvimport.csvimport", dbo)
        dbupdate.reset_db(dbo)

    # Now that we've read them in, go through all the rows
    # and start importing.
    errors = []
    rowno = 1
    asynctask.set_progress_max(dbo, len(data))
    for row in data:

        al.debug("import csv: row %d of %d" % (rowno, len(data)), "csvimport.csvimport", dbo)
        asynctask.increment_progress_value(dbo)

        # Should we stop?
        if asynctask.get_cancel(dbo): break

        # Do we have animal data to read?
        animalid = 0
        if hasanimal and gks(row, "ANIMALNAME") != "":
            a = {}
            a["animalname"] = gks(row, "ANIMALNAME")
            a["sheltercode"] = gks(row, "ANIMALCODE")
            a["shortcode"] = gks(row, "ANIMALCODE")
            if gks(row, "ANIMALSEX") == "": 
                a["sex"] = "2" # Default unknown if not set
            else:
                a["sex"] = gks(row, "ANIMALSEX").lower().startswith("m") and "1" or "0"
            a["basecolour"] = gkl(dbo, row, "ANIMALCOLOR", "basecolour", "BaseColour", createmissinglookups)
            if a["basecolour"] == "0":
                a["basecolour"] = str(configuration.default_colour(dbo))
            a["species"] = gkl(dbo, row, "ANIMALSPECIES", "species", "SpeciesName", createmissinglookups)
            if a["species"] == "0":
                a["species"] = str(configuration.default_species(dbo))
            a["animaltype"] = gkl(dbo, row, "ANIMALTYPE", "animaltype", "AnimalType", createmissinglookups)
            if a["animaltype"] == "0":
                a["animaltype"] = str(configuration.default_type(dbo))
            a["breed1"] = gkbr(dbo, row, "ANIMALBREED1", a["species"], createmissinglookups)
            if a["breed1"] == "0":
                a["breed1"] = str(configuration.default_breed(dbo))
            a["breed2"] = gkbr(dbo, row, "ANIMALBREED2", a["species"], createmissinglookups)
            if a["breed2"] != "0" and a["breed2"] != a["breed1"]:
                a["crossbreed"] = "on"
            a["size"] = gkl(dbo, row, "ANIMALSIZE", "lksize", "Size", False)
            if gks(row, "ANIMALSIZE") == "": 
                a["size"] = str(configuration.default_size(dbo))
            a["internallocation"] = gkl(dbo, row, "ANIMALLOCATION", "internallocation", "LocationName", createmissinglookups)
            if a["internallocation"] == "0":
                a["internallocation"] = str(configuration.default_location(dbo))
            a["unit"] = gks(row, "ANIMALUNIT")
            a["comments"] = gks(row, "ANIMALCOMMENTS")
            a["markings"] = gks(row, "ANIMALMARKINGS")
            a["hiddenanimaldetails"] = gks(row, "ANIMALHIDDENDETAILS")
            a["healthproblems"] = gks(row, "ANIMALHEALTHPROBLEMS")
            a["notforadoption"] = gkbi(row, "ANIMALNOTFORADOPTION")
            a["nonshelter"] = gkbi(row, "ANIMALNONSHELTER")
            a["housetrained"] = gkynu(row, "ANIMALHOUSETRAINED")
            a["goodwithcats"] = gkynu(row, "ANIMALGOODWITHCATS")
            a["goodwithdogs"] = gkynu(row, "ANIMALGOODWITHDOGS")
            a["goodwithkids"] = gkynu(row, "ANIMALGOODWITHKIDS")
            a["reasonforentry"] = gks(row, "ANIMALREASONFORENTRY")
            a["estimatedage"] = gks(row, "ANIMALAGE")
            a["dateofbirth"] = gkd(dbo, row, "ANIMALDOB", True)
            if gks(row, "ANIMALDOB") == "" and a["estimatedage"] != "":
                a["dateofbirth"] = "" # if we had an age and dob was blank, prefer the age
            a["datebroughtin"] = gkd(dbo, row, "ANIMALENTRYDATE", True)
            a["deceaseddate"] = gkd(dbo, row, "ANIMALDECEASEDDATE")
            a["neutered"] = gkbc(row, "ANIMALNEUTERED")
            a["neutereddate"] = gkd(dbo, row, "ANIMALNEUTEREDDATE")
            if a["neutereddate"] != "": a["neutered"] = "on"
            a["microchipnumber"] = gks(row, "ANIMALMICROCHIP")
            if a["microchipnumber"] != "": a["microchipped"] = "on"
            a["microchipdate"] = gkd(dbo, row, "ANIMALMICROCHIPDATE")
            # image data if any was supplied
            imagedata = gks(row, "ANIMALIMAGE")
            if imagedata.startswith("http"):
                # It's a URL, get the image from the remote server
                r = utils.get_image_url(imagedata, timeout=5000)
                if r["status"] == 200:
                    al.debug("retrieved image from %s (%s bytes)" % (imagedata, len(r["response"])), "csvimport.csvimport", dbo)
                    imagedata = "data:image/jpeg;base64,%s" % base64.b64encode(r["response"])
                else:
                    row_error(errors, "animal", rowno, row, "error reading image from '%s': %s" % (imagedata, r), dbo, sys.exc_info())
                    continue
            elif imagedata.startswith("data:image"):
                # It's a base64 encoded data URI - do nothing as attach_file requires it
                pass
            else:
                # We don't know what it is, don't try and do anything with it
                imagedata = ""
            # If an original owner is specified, create a person record
            # for them and attach it to the animal as original owner
            if gks(row, "ORIGINALOWNERLASTNAME") != "":
                p = {}
                p["title"] = gks(row, "ORIGINALOWNERTITLE")
                p["initials"] = gks(row, "ORIGINALOWNERINITIALS")
                p["forenames"] = gks(row, "ORIGINALOWNERFIRSTNAME")
                p["surname"] = gks(row, "ORIGINALOWNERLASTNAME")
                p["address"] = gks(row, "ORIGINALOWNERADDRESS")
                p["town"] = gks(row, "ORIGINALOWNERCITY")
                p["county"] = gks(row, "ORIGINALOWNERSTATE")
                p["postcode"] = gks(row, "ORIGINALOWNERZIPCODE")
                p["jurisdiction"] = gkl(dbo, row, "ORIGINALOWNERJURISDICTION", "jurisdiction", "JurisdictionName", createmissinglookups)
                p["hometelephone"] = gks(row, "ORIGINALOWNERHOMEPHONE")
                p["worktelephone"] = gks(row, "ORIGINALOWNERWORKPHONE")
                p["mobiletelephone"] = gks(row, "ORIGINALOWNERCELLPHONE")
                p["emailaddress"] = gks(row, "ORIGINALOWNEREMAIL")
                try:
                    if checkduplicates:
                        dups = person.get_person_similar(dbo, p["emailaddress"], p["surname"], p["forenames"], p["address"])
                        if len(dups) > 0:
                            a["originalowner"] = str(dups[0]["ID"])
                    if "originalowner" not in a:
                        ooid = person.insert_person_from_form(dbo, utils.PostedData(p, dbo.locale), user, geocode=False)
                        a["originalowner"] = str(ooid)
                        # Identify an ORIGINALOWNERADDITIONAL additional fields and create them
                        create_additional_fields(dbo, row, errors, rowno, "ORIGINALOWNERADDITIONAL", "person", ooid)
                except Exception as e:
                    row_error(errors, "originalowner", rowno, row, e, dbo, sys.exc_info())
            try:
                if checkduplicates:
                    dup = animal.get_animal_sheltercode(dbo, a["sheltercode"])
                    if dup is not None:
                        animalid = dup["ID"]
                if animalid == 0:
                    animalid, newcode = animal.insert_animal_from_form(dbo, utils.PostedData(a, dbo.locale), user)
                    # Identify any ANIMALADDITIONAL additional fields and create them
                    create_additional_fields(dbo, row, errors, rowno, "ANIMALADDITIONAL", "animal", animalid)
                # If we have some image data, add it to the animal
                if len(imagedata) > 0:
                    imagepost = utils.PostedData({ "filename": "image.jpg", "filetype": "image/jpeg", "filedata": imagedata }, dbo.locale)
                    media.attach_file_from_form(dbo, user, media.ANIMAL, animalid, imagepost)
            except Exception as e:
                row_error(errors, "animal", rowno, row, e, dbo, sys.exc_info())

        # Person data?
        personid = 0
        if hasperson and (gks(row, "PERSONLASTNAME") != "" or gks(row, "PERSONNAME") != ""):
            p = {}
            p["ownertype"] = gks(row, "PERSONCLASS")
            if p["ownertype"] != "1" and p["ownertype"] != "2": 
                p["ownertype"] = "1"
            p["title"] = gks(row, "PERSONTITLE")
            p["initials"] = gks(row, "PERSONINITIALS")
            p["forenames"] = gks(row, "PERSONFIRSTNAME")
            p["surname"] = gks(row, "PERSONLASTNAME")
            # If we have a person name, all upto the last space is first names,
            # everything after the last name
            if gks(row, "PERSONNAME") != "":
                pname = gks(row, "PERSONNAME")
                if pname.find(" ") != -1:
                    p["forenames"] = pname[0:pname.rfind(" ")]
                    p["surname"] = pname[pname.rfind(" ")+1:]
                else:
                    p["surname"] = pname
            p["address"] = gks(row, "PERSONADDRESS")
            p["town"] = gks(row, "PERSONCITY")
            p["county"] = gks(row, "PERSONSTATE")
            p["postcode"] = gks(row, "PERSONZIPCODE")
            p["jurisdiction"] = gkl(dbo, row, "PERSONJURISDICTION", "jurisdiction", "JurisdictionName", createmissinglookups)
            p["hometelephone"] = gks(row, "PERSONHOMEPHONE")
            p["worktelephone"] = gks(row, "PERSONWORKPHONE")
            p["mobiletelephone"] = gks(row, "PERSONCELLPHONE")
            p["emailaddress"] = gks(row, "PERSONEMAIL")
            p["gdprcontactoptin"] = gks(row, "PERSONGDPRCONTACTOPTIN")
            flags = gks(row, "PERSONFLAGS")
            if gkb(row, "PERSONFOSTERER"): flags += ",fosterer"
            if gkb(row, "PERSONMEMBER"): flags += ",member"
            if gkb(row, "PERSONDONOR"): flags += ",donor"
            p["flags"] = flags
            p["comments"] = gks(row, "PERSONCOMMENTS")
            p["membershipnumber"] = gks(row, "PERSONMEMBERSHIPNUMBER")
            p["membershipexpires"] = gkd(dbo, row, "PERSONMEMBERSHIPEXPIRY")
            p["matchactive"] = gkbi(row, "PERSONMATCHACTIVE")
            if p["matchactive"] == "1":
                if "PERSONMATCHADDED" in cols: p["matchadded"] = gkd(dbo, row, "PERSONMATCHADDED")
                if "PERSONMATCHEXPIRES" in cols: p["matchexpires"] = gkd(dbo, row, "PERSONMATCHEXPIRES")
                if "PERSONMATCHSEX" in cols: p["matchsex"] = gks(row, "PERSONMATCHSEX").lower().startswith("m") and "1" or "0"
                if "PERSONMATCHSIZE" in cols: p["matchsize"] = gkl(dbo, row, "PERSONMATCHSIZE", "lksize", "Size", False)
                if "PERSONMATCHCOLOR" in cols: p["matchcolour"] = gkl(dbo, row, "PERSONMATCHCOLOR", "basecolour", "BaseColour", createmissinglookups)
                if "PERSONMATCHAGEFROM" in cols: p["matchagefrom"] = gks(row, "PERSONMATCHAGEFROM")
                if "PERSONMATCHAGETO" in cols: p["matchageto"] = gks(row, "PERSONMATCHAGETO")
                if "PERSONMATCHTYPE" in cols: p["matchanimaltype"] = gkl(dbo, row, "PERSONMATCHTYPE", "animaltype", "AnimalType", createmissinglookups)
                if "PERSONMATCHSPECIES" in cols: p["matchspecies"] = gkl(dbo, row, "PERSONMATCHSPECIES", "species", "SpeciesName", createmissinglookups)
                if "PERSONMATCHBREED1" in cols: p["matchbreed"] = gkbr(dbo, row, "PERSONMATCHBREED1", p["matchspecies"], createmissinglookups)
                if "PERSONMATCHBREED2" in cols: p["matchbreed2"] = gkbr(dbo, row, "PERSONMATCHBREED2", p["matchspecies"], createmissinglookups)
                if "PERSONMATCHGOODWITHCATS" in cols: p["matchgoodwithcats"] = gkynu(row, "PERSONMATCHGOODWITHCATS")
                if "PERSONMATCHGOODWITHDOGS" in cols: p["matchgoodwithdogs"] = gkynu(row, "PERSONMATCHGOODWITHDOGS")
                if "PERSONMATCHGOODWITHCHILDREN" in cols: p["matchgoodwithchildren"] = gkynu(row, "PERSONMATCHGOODWITHCHILDREN")
                if "PERSONMATCHHOUSETRAINED" in cols: p["matchhousetrained"] = gkynu(row, "PERSONMATCHHOUSETRAINED")
                if "PERSONMATCHCOMMENTSCONTAIN" in cols: p["matchcommentscontain"] = gks(row, "PERSONMATCHCOMMENTSCONTAIN")
            try:
                if checkduplicates:
                    dups = person.get_person_similar(dbo, p["emailaddress"], p["surname"], p["forenames"], p["address"])
                    if len(dups) > 0:
                        personid = dups[0].ID
                        # Merge flags and any extra details
                        person.merge_flags(dbo, user, personid, flags)
                        person.merge_gdpr_flags(dbo, user, personid, p["gdprcontactoptin"])
                        # If we deduplicated on the email address, and address details are
                        # present, assume that they are newer than the ones we had and update them
                        # (we do this by setting force=True parameter to merge_person_details,
                        # otherwise we do a regular merge which only fills in any blanks)
                        person.merge_person_details(dbo, user, personid, p, force=dups[0].EMAILADDRESS == p["emailaddress"])
                if personid == 0:
                    personid = person.insert_person_from_form(dbo, utils.PostedData(p, dbo.locale), user, geocode=False)
                    # Identify any PERSONADDITIONAL additional fields and create them
                    create_additional_fields(dbo, row, errors, rowno, "PERSONADDITIONAL", "person", personid)
            except Exception as e:
                row_error(errors, "person", rowno, row, e, dbo, sys.exc_info())

        # Movement to tie animal/person together?
        movementid = 0
        if hasmovement and personid != 0 and animalid != 0 and gks(row, "MOVEMENTDATE") != "":
            m = {}
            m["person"] = str(personid)
            m["animal"] = str(animalid)
            movetype = gks(row, "MOVEMENTTYPE")
            if movetype == "": movetype = "1" # Default to adoption if not supplied
            m["type"] = str(movetype)
            m["movementdate"] = gkd(dbo, row, "MOVEMENTDATE", True)
            m["returndate"] = gkd(dbo, row, "MOVEMENTRETURNDATE")
            m["comments"] = gks(row, "MOVEMENTCOMMENTS")
            m["returncategory"] = str(configuration.default_entry_reason(dbo))
            try:
                movementid = movement.insert_movement_from_form(dbo, user, utils.PostedData(m, dbo.locale))
            except Exception as e:
                row_error(errors, "movement", rowno, row, e, dbo, sys.exc_info())

        # Donation?
        if hasdonation and personid != 0 and gkc(row, "DONATIONAMOUNT") != 0:
            d = {}
            d["person"] = str(personid)
            d["animal"] = str(animalid)
            d["movement"] = str(movementid)
            d["amount"] = str(gkc(row, "DONATIONAMOUNT"))
            d["fee"] = str(gkc(row, "DONATIONFEE"))
            d["comments"] = gks(row, "DONATIONCOMMENTS")
            d["received"] = gkd(dbo, row, "DONATIONDATE", True)
            d["chequenumber"] = gks(row, "DONATIONCHECKNUMBER")
            d["type"] = gkl(dbo, row, "DONATIONTYPE", "donationtype", "DonationName", createmissinglookups)
            if d["type"] == "0":
                d["type"] = str(configuration.default_donation_type(dbo))
            d["payment"] = gkl(dbo, row, "DONATIONPAYMENT", "donationpayment", "PaymentName", createmissinglookups)
            if d["payment"] == "0":
                d["payment"] = "1"
            try:
                financial.insert_donation_from_form(dbo, user, utils.PostedData(d, dbo.locale))
            except Exception as e:
                row_error(errors, "payment", rowno, row, e, dbo, sys.exc_info())
            if movementid != 0: movement.update_movement_donation(dbo, movementid)

        # Vaccination?
        if hasvacc and animalid != 0 and gks(row, "VACCINATIONDUEDATE") != "":
            v = {}
            v["animal"] = str(animalid)
            v["type"] = gkl(dbo, row, "VACCINATIONTYPE", "vaccinationtype", "VaccinationType", createmissinglookups)
            if v["type"] == "0":
                v["type"] = str(configuration.default_vaccination_type(dbo))
            v["required"] = gkd(dbo, row, "VACCINATIONDUEDATE", True)
            v["given"] = gkd(dbo, row, "VACCINATIONGIVENDATE")
            v["expires"] = gkd(dbo, row, "VACCINATIONEXPIRESDATE")
            v["batchnumber"] = gks(row, "VACCINATIONBATCHNUMBER")
            v["manufacturer"] = gks(row, "VACCINATIONMANUFACTURER")
            v["comments"] = gks(row, "VACCINATIONCOMMENTS")
            try:
                medical.insert_vaccination_from_form(dbo, user, utils.PostedData(v, dbo.locale))
            except Exception as e:
                row_error(errors, "vaccination", rowno, row, e, dbo, sys.exc_info())

        # Medical?
        if hasmed and animalid != 0 and gks(row, "MEDICALGIVENDATE") != "" and gks(row, "MEDICALNAME") != "":
            m = {}
            m["animal"] = str(animalid)
            m["treatmentname"] = gks(row, "MEDICALNAME")
            m["dosage"] = gks(row, "MEDICALDOSAGE")
            m["startdate"] = gkd(dbo, row, "MEDICALGIVENDATE")
            m["comments"] = gks(row, "MEDICALCOMMENTS")
            m["singlemulti"] = "0" # single treatment
            m["status"] = "2" # completed
            try:
                medical.insert_regimen_from_form(dbo, user, utils.PostedData(m, dbo.locale))
            except Exception as e:
                row_error(errors, "medical", rowno, row, e, dbo, sys.exc_info())

        # License?
        if haslicence and personid != 0 and gks(row, "LICENSENUMBER") != "":
            l = {}
            l["person"] = str(personid)
            l["animal"] = str(animalid)
            l["type"] = gkl(dbo, row, "LICENSETYPE", "licencetype", "LicenceTypeName", createmissinglookups)
            if l["type"] == "0": l["type"] = 1
            l["number"] = gks(row, "LICENSENUMBER")
            l["fee"] = str(gkc(row, "LICENSEFEE"))
            l["issuedate"] = gkd(dbo, row, "LICENSEISSUEDATE")
            l["expirydate"] = gkd(dbo, row, "LICENSEEXPIRESDATE")
            l["comments"] = gks(row, "LICENSECOMMENTS")
            try:
                financial.insert_licence_from_form(dbo, user, utils.PostedData(l, dbo.locale))
            except Exception as e:
                row_error(errors, "license", rowno, row, e, dbo, sys.exc_info())

        rowno += 1

    h = [ "<p>%d success, %d errors</p><table>" % (len(data) - len(errors), len(errors)) ]
    for rowno, row, err in errors:
        h.append("<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (rowno, row, err))
    h.append("</table>")
    return "".join(h)
                    "csvimport.csvimport", dbo, sys.exc_info())
                errors.append((rowno, str(row), "movement: " + str(e)))

        # Donation?
        if hasdonation and personid != 0 and gks(row, "DONATIONAMOUNT") != "":
            d = {}
            d["person"] = str(personid)
            d["animal"] = str(animalid)
            d["movement"] = str(movementid)
            d["amount"] = gks(row, "DONATIONAMOUNT")
            d["comments"] = gks(row, "DONATIONCOMMENTS")
            d["received"] = gkd(dbo, row, "DONATIONDATE", True)
            d["type"] = gkl(dbo, row, "DONATIONTYPE", "donationtype",
                            "DonationName", createmissinglookups)
            if d["type"] == "0":
                d["type"] = str(configuration.default_donation_type(dbo))
            try:
                financial.insert_donation_from_form(
                    dbo, "import", utils.PostedData(d, dbo.locale))
            except Exception, e:
                al.error(
                    "row %d (%s), donation: %s" % (rowno, str(row), str(e)),
                    "csvimport.csvimport", dbo, sys.exc_info())
                errors.append((rowno, str(row), "donation: " + str(e)))
            if movementid != 0:
                movement.update_movement_donation(dbo, movementid)

        rowno += 1

    return errors
def insert_reserve_from_form(dbo, username, post):
    """
    Inserts a movement from the workflow reserve an animal screen.
    Returns the new movement id
    """
    # Validate that we have a date before doing anthing
    l = dbo.locale
    if None == post.date("reservationdate"):
        raise utils.ASMValidationError(
            i18n._("Reservations must have a valid reservation date.", l))

    # Do the movement itself first
    move_dict = {
        "person": post["person"],
        "animal": post["animal"],
        "reservationdate": post["reservationdate"],
        "adoptionno": post["movementnumber"],
        "movementdate": "",
        "type": str(NO_MOVEMENT),
        "donation": post["amount"],
        "returncategory": configuration.default_return_reason(dbo)
    }
    movementid = insert_movement_from_form(dbo, username,
                                           utils.PostedData(move_dict, l))
    # Then the donation if we have one
    donation_amount = post.integer("amount")
    if donation_amount > 0:
        due = ""
        received = post["reservationdate"]
        if configuration.movement_donations_default_due(dbo):
            due = post["reservationdate"]
            received = ""
        don_dict = {
            "person": post["person"],
            "animal": post["animal"],
            "movement": str(movementid),
            "type": post["donationtype"],
            "payment": post["payment"],
            "destaccount": post["destaccount"],
            "frequency": "0",
            "amount": post["amount"],
            "due": due,
            "received": received,
            "giftaid": post["giftaid"]
        }
        financial.insert_donation_from_form(dbo, username,
                                            utils.PostedData(don_dict, l))
    # And a second donation if there is one
    donation_amount = post.integer("amount2")
    if donation_amount > 0:
        due = ""
        received = post["movementdate"]
        if configuration.movement_donations_default_due(dbo):
            due = post["movementdate"]
            received = ""
        don_dict = {
            "person": post["person"],
            "animal": post["animal"],
            "movement": str(movementid),
            "type": post["donationtype2"],
            "payment": post["payment2"],
            "destaccount": post["destaccount2"],
            "frequency": "0",
            "amount": post["amount2"],
            "due": due,
            "received": received,
            "giftaid": post["giftaid"]
        }
        financial.insert_donation_from_form(dbo, username,
                                            utils.PostedData(don_dict, l))
    return movementid
def insert_reclaim_from_form(dbo, username, post):
    """
    Inserts a movement from the workflow adopt an animal screen.
    Returns the new movement id
    """
    l = dbo.locale
    # Validate that we have a movement date before doing anthing
    if None == post.date("movementdate"):
        raise utils.ASMValidationError(
            i18n._("Reclaim movements must have a valid reclaim date.", l))
    # Get the animal record for this reclaim
    a = animal.get_animal(dbo, post.integer("animal"))
    if a is None:
        raise utils.ASMValidationError(
            "Reclaim POST has an invalid animal ID: %d" %
            post.integer("animal"))
    al.debug(
        "Creating reclaim for %d (%s - %s)" %
        (a["ID"], a["SHELTERCODE"], a["ANIMALNAME"]),
        "movement.insert_reclaim_from_form", dbo)
    # Prepare a dictionary of data for the movement table via insert_movement_from_form
    move_dict = {
        "person": post["person"],
        "animal": post["animal"],
        "adoptionno": post["movementnumber"],
        "movementdate": post["movementdate"],
        "type": str(RECLAIMED),
        "donation": post["amount"],
        "returncategory": configuration.default_return_reason(dbo)
    }
    # Is this animal currently on foster? If so, return the foster
    fm = get_animal_movements(dbo, post.integer("animal"))
    for m in fm:
        if m["MOVEMENTTYPE"] == FOSTER and m["RETURNDATE"] is None:
            return_movement(dbo, m["ID"], post.integer("animal"),
                            post.date("movementdate"))
    # Is this animal current at a retailer? If so, return it from the
    # retailer and set the originalretailermovement and retailerid fields
    # on our new adoption movement so it can be linked back
    for m in fm:
        if m["MOVEMENTTYPE"] == RETAILER and m["RETURNDATE"] is None:
            return_movement(dbo, m["ID"], post.integer("animal"),
                            post.date("movementdate"))
            move_dict["originalretailermovement"] = str(m["ID"])
            move_dict["retailer"] = str(m["OWNERID"])
    # If the animal was flagged as not available for adoption, then it
    # shouldn't be since we've just reclaimed it.
    db.execute(
        dbo, "UPDATE animal SET IsNotAvailableForAdoption = 0 WHERE ID = %s" %
        post["animal"])
    # Is the animal reserved? Should clear it if so
    cancel_reserves = configuration.cancel_reserves_on_adoption(dbo)
    for m in fm:
        if cancel_reserves and m["MOVEMENTTYPE"] == NO_MOVEMENT and m["RESERVATIONDATE"] is not None \
            and m["RESERVATIONCANCELLEDDATE"] is None:
            db.execute(dbo, "UPDATE adoption SET ReservationCancelledDate = %s WHERE ID = %d" % \
                ( post.db_date("movementdate"), m["ID"] ))
    movementid = insert_movement_from_form(dbo, username,
                                           utils.PostedData(move_dict, l))
    # Create the donation if there is one
    donation_amount = post.integer("amount")
    if donation_amount > 0:
        due = ""
        received = post["movementdate"]
        if configuration.movement_donations_default_due(dbo):
            due = post["movementdate"]
            received = ""
        don_dict = {
            "person": post["person"],
            "animal": post["animal"],
            "movement": str(movementid),
            "type": post["donationtype"],
            "payment": post["payment"],
            "destaccount": post["destaccount"],
            "frequency": "0",
            "amount": post["amount"],
            "due": due,
            "received": received,
            "giftaid": post["giftaid"]
        }
        financial.insert_donation_from_form(dbo, username,
                                            utils.PostedData(don_dict, l))
    # Then any boarding cost record
    cost_amount = post.integer("costamount")
    cost_type = post["costtype"]
    cost_create = post.integer("costcreate")
    if cost_amount > 0 and cost_type != "" and cost_create == 1:
        boc_dict = {
            "animalid": post["animal"],
            "type": cost_type,
            "costdate": post["movementdate"],
            "costpaid": post["movementdate"],
            "cost": post["costamount"]
        }
        animal.insert_cost_from_form(dbo, username,
                                     utils.PostedData(boc_dict, l))
    return movementid
Beispiel #14
0
            m["movementdate"] = gkd(dbo, row, "MOVEMENTDATE", True)
            m["comments"] = gks(row, "MOVEMENTCOMMENTS")
            m["returncategory"] = str(configuration.default_entry_reason(dbo))
            try:
                movementid = movement.insert_movement_from_form(dbo, "import", m)
            except Exception,e:
                errors.append( (rowno, str(row), "movement: " + str(e)) )

        # Donation?
        if hasdonation and personid != 0 and gks(row, "DONATIONAMOUNT") != "":
            d = {}
            d["person"] = str(personid)
            d["animal"] = str(animalid)
            d["movement"] = str(movementid)
            d["amount"] = gks(row, "DONATIONAMOUNT")
            d["comments"] = gks(row, "DONATIONCOMMENTS")
            d["received"] = gkd(dbo, row, "DONATIONDATE", True)
            d["type"] = gkl(dbo, row, "DONATIONTYPE", "donationtype", "DonationName", createmissinglookups)
            if d["type"] == "0":
                d["type"] = str(configuration.default_donation_type(dbo))
            try:
                financial.insert_donation_from_form(dbo, "import", d)
            except Exception,e:
                errors.append( (rowno, str(row), "donation: " + str(e)) )
            if movementid != 0: movement.update_movement_donation(dbo, movementid)

        rowno += 1

    return errors