Ejemplo n.º 1
0
class Transaction(ObjectFieldGroupBase):

    public_interface = (
        IntField('reference_no'),
        StringField('public_code'),
        IntField('year'),
        IntField('month'),
        IntField('day'),
        ObjectReferenceField('counterparty'),
        PaymentMethodField('payment_method'),
        DescriptionField('description'),
        DecimalField('amount'),
        ObjectReferenceField('subject'),
        IncomeExpenditureField('income_expenditure'),
        StringField('FY'),  # TODO clean up old data and make this an int field
        ObjectReferenceField('fund'),
        DescriptionField('comments'))

    def __str__(self):
        return '{0.__class__.__name__}({0._reference_no}, {0._public_code}, {0.book_date}, {0._counterparty})'.format(
            self)

    @property
    def book_date(self):
        if all((self._year, self._month, self._day)):
            return date(self._year, self._month, self._day)
        else:
            None
Ejemplo n.º 2
0
class Envelope(ObjectFieldGroupBase):
    # Data usage
    #
    # Used to administer the Free-will envelope programme.
    # Records the envelope used by a person in a particular year
    #

    public_interface = (
        IntField('year'),
        ObjectReferenceField('counterparty'),
        ObjectReferenceField('person'),
        IntField('envelope_number'),
    )
Ejemplo n.º 3
0
class OrganisationAddress(ObjectFieldGroupBase):
    # Data usage
    #
    # Allows addresses to be associated with an organisation
    #

    public_interface = (
        ObjectReferenceField('organisation', required=True),
        ObjectReferenceField('address', required=True),
        OrganisationAddressStatusField(
            'status', required=True,
            default=OrganisationAddressStatus.Current),
    )
Ejemplo n.º 4
0
class Counterparty(ObjectFieldGroupBase):
    # Data usage
    #
    # Associates an identifiable person with their financial activity
    #

    public_interface = (
        IntField('reference_no'),
        StringField(
            'bank_text',
            description='Used to identify donors from bank statements'),
        ObjectReferenceField('person'),
        ObjectReferenceField('organisation'),
        StringField('name_override'),
        StringField(
            'method',
            description=
            'Method whereby funds are received or dispersed. Used to aid reconciliation.'
        ),  # TODO enum?
        BooleanField(
            'has_SO_card',
            description='Has donor requested a standing order donor card.'),
        BooleanField(
            'by_email',
            'Has the donor agreed to receive communications by email?'),
        DescriptionField('notes',
                         'Free text record of unusual circumstances.'),
    )

    def __str__(self):
        return '{0.__class__.__name__}({0._reference_no}, {0.name}, {0._bank_text})'.format(
            self)

    @property
    def name(self):
        return self._name_override if self._name_override else self._person.name

    @property
    def lookup_name(self):
        return self.name.lower()
class CommunicationPermission(ObjectFieldGroupBase):

    # Flags indicating a persons communication preferences

    public_interface = (
        ObjectReferenceField('person', required=True),
        BooleanField('is_main_contact'),
        DateTimeField('gdpr_response'),
        BooleanField('by_email'),
        BooleanField('by_phone'),
        BooleanField('by_post'),
        BooleanField('news'),
        BooleanField('finance'),
        # TODO connect this to a "tenant" organisation
    )

    def __str__(self):
        return '{0.__class__.__name__}({0._gdpr_response})'.format(self)
Ejemplo n.º 6
0
class PPS(ObjectFieldGroupBase):
    # Data usage
    #
    # Records PPS number for an individual in order that a tax rebate may be claimed
    # on funds donated to the parish.

    public_interface = (
        ObjectReferenceField('person', required=True),
        PPSStatusField(
            'status',
            required=True,
            default=PPSStatus.Requested,
            description='Has the parishioner responded to a request for a PPS?'
        ),
        StringField('pps'),
        StringField('name_override'),
        IntField('chy3_valid_year', description='The first financial year the most recent CHY3 form is valid from'),
        DescriptionField('notes')
    )
Ejemplo n.º 7
0
class TaxRebate(ObjectFieldGroupBase):
    # Data usage
    #
    # Record of the years in which a person's PPS was submitted in a rebate claim

    public_interface = (
        ObjectReferenceField('person'),
        StringField('status'),
        StringField('2015_rebate'),
        StringField('2016_rebate'),
        StringField('2017_rebate'),
        StringField('2018_rebate'),
    )

    def has_rebate_for_year(self, fy: int):
        field_name = f"{fy}_rebate"
        if hasattr(self, field_name):
            fy_info = getattr(self, field_name)
            if "claimed" in fy_info:
                filing_year = int(fy_info.replace(" - claimed", ""))
                return filing_year
        return None
Ejemplo n.º 8
0
class TransactionCheck(ObjectFieldGroupBase):

    public_interface = (
        ObjectReferenceField('transaction'),
        ObjectReferenceField('statement_item'),
    )
class PersonRebateSubmission(ObjectFieldGroupBase):

    public_interface = (
        ObjectReferenceField('person'),
        ObjectReferenceField('tax_rebate_submission'),
    )
Ejemplo n.º 10
0
class StatementItem(ObjectFieldGroupBase):

    public_interface = (
        ObjectReferenceField('account'),
        # TODO: allow properties to be named differently to internal/db fields
        DateField('date'),
        StringField('details'),
        StringField('currency'),
        DecimalField('debit', use_custom_properties=True),
        DecimalField('credit', use_custom_properties=True),
        DecimalField('balance'),
        StringField('detail_override'),
        StatementItemDesignatedBalanceField(
            'designated_balance', default=StatementItemDesignatedBalance.No))

    # metaclass takes care of dealing with the args
    def __init__(self, *args, **kwargs):
        self._designated_balance = None

    def __str__(self):
        return '{0.__class__.__name__}({0._account}, {0._date}, {0.trimmed_details})'.format(
            self)

    @property
    def debit(self):
        return self._debit if self._debit is not None else Decimal('0.00')

    @debit.setter
    def debit(self, value):
        self._debit = value

    @property
    def credit(self):
        return self._credit if self._credit is not None else Decimal('0.00')

    @credit.setter
    def credit(self, value):
        self._credit = value

    @property
    def net(self):
        return self.credit - self.debit

    @property
    def year(self):
        return self._date.year

    @property
    def month(self):
        return self._date.month

    @property
    def day(self):
        return self._date.day

    @property
    def unified_details(self):
        return self._detail_override if self._detail_override else self._details

    @property
    def public_code(self):
        details = self.unified_details
        # lodgments
        if details.startswith('LODGMENT'):
            return details.replace('LODGMENT', '').strip()
        # direct payments out and in
        elif details.startswith('D0') or details.startswith('E0'):
            return details[0:6]
        # cheque numbers
        elif re.search(r'^\d{6}$', details):
            return details
        else:
            return None

    @property
    def trimmed_details(self):
        """ Drop any text after the specified strings

        :return:
        """
        return re.sub(TRUNCATE_ON_PATTERN, '\g<1>', self.unified_details)
Ejemplo n.º 11
0
class Person(ObjectFieldGroupBase):

    # May be a degenerate object which just refers to an Organisation

    public_interface = (
        ObjectReferenceField('organisation', required=True),
        StringField(
            'family_name',
            description=
            'Surname of individual. Used to correctly address communications to them.'
        ),
        StringField(
            'given_name',
            description=
            'First name of individual. Used to correctly address communications to them.'
        ),
        StringField(
            'title',
            description=
            'Honorific used in formal communications and when addressing letters.'
        ),
        PersonStatusField(
            'status',
            required=True,
            default=PersonStatus.Active,
            description=
            'Is the person living, deceased or has contact been lost with them.'
        ),
        StringField(
            'mobile',
            description=
            'In addition to facilitating voice communications may be used to supplement secure access to personal data.'
        ),
        StringField(
            'other_phone',
            description='Supplementary phone number e.g. work direct dial, fax.'
        ),
        StringField(
            'email',
            description=
            'Primary means of electronic communication and identity for maintaining personal information.'
        ),
        IntField(
            'parishioner_reference_no',
            is_mutable=False,
            description=
            'Internal use. Refers to identity in source data. Required for initial data load.'
        ),
    )

    def __str__(self):
        return '{0.__class__.__name__}({0._parishioner_reference_no}, {0.name})'.format(
            self)

    @property
    def name(self):
        if self._title:
            return '{0._title} {0._given_name} {0._family_name}'.format(self)
        else:
            return '{0._given_name} {0._family_name}'.format(self)

    @property
    def name_without_title(self):
        return '{0._given_name} {0._family_name}'.format(self)
Ejemplo n.º 12
0
class AReferringClass(ObjectFieldGroupBase):
    public_interface = (
        StringField('name'),
        ObjectReferenceField('aclass'),
    )