def registration_ajax(self, r, **attr):
        """
            Ajax response method, expects a JSON input like:

                {l: the PE label (from the input field),
                 c: boolean to indicate whether to just check
                    the PE label or to register payments
                 d: the payment data (raw data, which payments to update)
                 }

            @param r: the S3Request instance
            @param attr: controller parameters

            @return: JSON response, structure:

                    {l: the actual PE label (to update the input field),
                     p: the person details,
                     f: [{n: the flag name
                          i: the flag instructions
                          },
                         ...],

                     u: whether there are any actionable data
                     s: whether the action is permitted or not

                     d: {t: time stamp
                         h: payment details (raw data)
                         d: payment details (HTML)
                         }

                     e: form error (for label field)

                     a: error message
                     w: warning message
                     m: success message
                     }
        """

        T = current.T

        # Load JSON data from request body
        s = r.body
        s.seek(0)
        try:
            data = json.load(s)
        except (__HOLE__, TypeError):
            r.error(400, current.ERROR.BAD_REQUEST)


        # Initialize processing variables
        output = {}
        alert = None
        error = None
        warning = None
        message = None
        permitted = False
        flags = []

        # Identify the person
        pe_label = data.get("l")
        person = self.get_person(pe_label)

        if person is None:
            error = s3_str(T("No person found with this ID number"))

        else:
            # Get flag info
            flag_info = dvr_get_flag_instructions(person.id,
                                                  action = self.ACTION,
                                                  )
            permitted = flag_info["permitted"]

            check = data.get("c")
            if check:
                name = s3_fullname(person)
                dob = person.date_of_birth
                if dob:
                    dob = S3DateTime.date_represent(dob)
                    person_data = "%s (%s %s)" % (name, T("Date of Birth"), dob)
                else:
                    person_data = name

                output["p"] = s3_str(person_data)
                output["l"] = person.pe_label

                info = flag_info["info"]
                for flagname, instructions in info:
                    flags.append({"n": s3_str(T(flagname)),
                                  "i": s3_str(T(instructions)),
                                  })

                if permitted:
                    payments = self.get_payment_data(person.id)
                else:
                    payments = []
                date = S3DateTime.datetime_represent(current.request.utcnow,
                                                     utc = True,
                                                     )
                output["d"] = {"d": s3_str(self.payment_data_represent(payments)),
                               "t": s3_str(date),
                               "h": payments,
                               }
                if payments:
                    output["u"] = True
                else:
                    output["u"] = False
            else:
                if not permitted:
                    alert = T("Payment registration not permitted")
                else:
                    # Get payment data from JSON
                    payments = data.get("d")
                    if payments:

                        # @todo: read date from JSON data (utcnow as fallback)
                        date = r.utcnow
                        comments = data.get("c")

                        updated, failed = self.register_payments(
                                                    person.id,
                                                    payments,
                                                    date = date,
                                                    comments = comments,
                                                    )
                        message = T("%(number)s payment(s) registered") % \
                                  {"number": updated}
                        if failed:
                            warning = T("%(number)s payment(s) not found") % \
                                      {"number": failed}
                    else:
                        alert = T("No payments specified")

        # Add messages to output
        if alert:
            output["a"] = s3_str(alert)
        if error:
            output["e"] = s3_str(error)
        if message:
            output["m"] = s3_str(message)
        if warning:
            output["w"] = s3_str(warning)

        # Add flag info to output
        output["s"] = permitted
        output["f"] = flags

        current.response.headers["Content-Type"] = "application/json"
        return json.dumps(output)

    # -------------------------------------------------------------------------
dataset/ETHPy150Open sahana/eden/modules/s3db/dvr.py/DVRRegisterPayment.registration_ajax