def dvr_update_last_seen(person_id):
    """
        Helper function for automatic updates of dvr_case.last_seen_on

        @param person_id: the person ID
    """

    db = current.db
    s3db = current.s3db

    now = current.request.utcnow
    last_seen_on = None

    if not person_id:
        return

    # Get the last case event
    etable = s3db.dvr_case_event
    query = (etable.person_id == person_id) & \
            (etable.date != None) & \
            (etable.date <= now) & \
            (etable.deleted != True)
    event = db(query).select(etable.date,
                             orderby = ~etable.date,
                             limitby = (0, 1),
                             ).first()
    if event:
        last_seen_on = event.date

    # Check shelter registration history for newer entries
    htable = s3db.cr_shelter_registration_history
    query = (htable.person_id == person_id) & \
            (htable.status.belongs(2, 3)) & \
            (htable.date != None) & \
            (htable.deleted != True)
    if last_seen_on is not None:
        query &= htable.date > last_seen_on
    entry = db(query).select(htable.date,
                             orderby = ~htable.date,
                             limitby = (0, 1),
                             ).first()
    if entry:
        last_seen_on = entry.date

    settings = current.deployment_settings

    # Case appointments to update last_seen_on?
    if settings.get_dvr_appointments_update_last_seen_on():

        atable = s3db.dvr_case_appointment
        ttable = s3db.dvr_case_appointment_type
        left = ttable.on(ttable.id == atable.type_id)
        query = (atable.person_id == person_id) & \
                (atable.date != None) & \
                (ttable.presence_required == True) & \
                (atable.date <= now.date()) & \
                (atable.status == 4) & \
                (atable.deleted != True)
        if last_seen_on is not None:
            query &= atable.date > last_seen_on.date()
        appointment = db(query).select(atable.date,
                                       left = left,
                                       orderby = ~atable.date,
                                       limitby = (0, 1),
                                       ).first()
        if appointment:
            date = appointment.date
            try:
                date = datetime.datetime.combine(date, datetime.time(0, 0, 0))
            except __HOLE__:
                pass
            # Local time offset to UTC (NB: can be 0)
            delta = S3DateTime.get_offset_value(current.session.s3.utc_offset)
            # Default to 08:00 local time (...unless that would be future)
            date = min(now, date + datetime.timedelta(seconds = 28800 - delta))
            last_seen_on = date

    # Allowance payments to update last_seen_on?
    if settings.get_dvr_payments_update_last_seen_on():

        atable = s3db.dvr_allowance
        query = (atable.person_id == person_id) & \
                (atable.paid_on != None) & \
                (atable.status == 2) & \
                (atable.deleted != True)
        if last_seen_on is not None:
            query &= atable.paid_on > last_seen_on
        payment = db(query).select(atable.paid_on,
                                   orderby = ~atable.paid_on,
                                   limitby = (0, 1),
                                   ).first()
        if payment:
            last_seen_on = payment.paid_on

    # Update last_seen_on
    ctable = s3db.dvr_case
    query = (ctable.person_id == person_id) & \
            (ctable.archived != True) & \
            (ctable.deleted != True)
    db(query).update(last_seen_on = last_seen_on,
                     # Don't change author stamp for
                     # system-controlled record update:
                     modified_on = ctable.modified_on,
                     modified_by = ctable.modified_by,
                     )

# =============================================================================
dataset/ETHPy150Open sahana/eden/modules/s3db/dvr.py/dvr_update_last_seen