'Send a single message to a Person Entity (or list thereof)
@ToDo: contact_method = ALL
- look up the pr_contact options available for the pe & send via all
@ToDo: This is not transaction safe
- power failure in the middle will cause no message in the outbox'

@staticmethod
def send_by_pe_id(pe_id, subject='', message='', contact_method='EMAIL', document_ids=None, from_address=None, system_generated=False):

    s3db = current.s3db
    if (contact_method == 'EMAIL'):
        if (not from_address):
            from_address = current.deployment_settings.get_mail_sender()
        table = s3db.msg_email
        _id = table.insert(body=message, subject=subject, from_address=from_address, inbound=False)
        record = dict(id=_id)
        s3db.update_super(table, record)
        message_id = record['message_id']
        if document_ids:
            ainsert = s3db.msg_attachment.insert
            if (not isinstance(document_ids, list)):
                document_ids = [document_ids]
            for document_id in document_ids:
                ainsert(message_id=message_id, document_id=document_id)
    elif (contact_method == 'SMS'):
        table = s3db.msg_sms
        _id = table.insert(body=message, from_address=from_address, inbound=False)
        record = dict(id=_id)
        s3db.update_super(table, record)
        message_id = record['message_id']
    elif (contact_method == 'TWITTER'):
        table = s3db.msg_twitter
        _id = table.insert(body=message, from_address=from_address, inbound=False)
        record = dict(id=_id)
        s3db.update_super(table, record)
        message_id = record['message_id']
    else:
        raise
    table = s3db.msg_outbox
    if isinstance(pe_id, list):
        listindex = 0
        insert = table.insert
        for _id in pe_id:
            try:
                insert(message_id=message_id, pe_id=_id, contact_method=contact_method, system_generated=system_generated)
                listindex = (listindex + 1)
            except:
                return listindex
    else:
        try:
            table.insert(message_id=message_id, pe_id=pe_id, contact_method=contact_method, system_generated=system_generated)
        except:
            return False
    current.s3task.async('msg_process_outbox', args=[contact_method])
    return message_id
