From 569ff83efdbf904118787849cabb12bf5f9581ff Mon Sep 17 00:00:00 2001 From: James Gordon Date: Wed, 7 Dec 2016 20:52:39 -0600 Subject: [PATCH] Break down form460.py into schedule submodules --- calaccess_processed/__init__.py | 52 +- calaccess_processed/models/__init__.py | 18 + .../models/campaign/filings/form460.py | 2139 ----------------- .../campaign/filings/form460/__init__.py | 236 ++ .../filings/form460/schedules/__init__.py | 5 + .../campaign/filings/form460/schedules/a.py | 112 + .../campaign/filings/form460/schedules/b.py | 552 +++++ .../campaign/filings/form460/schedules/c.py | 115 + .../campaign/filings/form460/schedules/d.py | 112 + .../campaign/filings/form460/schedules/e.py | 209 ++ .../campaign/filings/form460/schedules/f.py | 312 +++ .../campaign/filings/form460/schedules/g.py | 137 ++ .../campaign/filings/form460/schedules/h.py | 314 +++ .../campaign/filings/form460/schedules/i.py | 125 + 14 files changed, 2273 insertions(+), 2165 deletions(-) delete mode 100644 calaccess_processed/models/campaign/filings/form460.py create mode 100644 calaccess_processed/models/campaign/filings/form460/__init__.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/__init__.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/a.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/b.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/c.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/d.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/e.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/f.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/g.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/h.py create mode 100644 calaccess_processed/models/campaign/filings/form460/schedules/i.py diff --git a/calaccess_processed/__init__.py b/calaccess_processed/__init__.py index be516a32..f38590d7 100644 --- a/calaccess_processed/__init__.py +++ b/calaccess_processed/__init__.py @@ -20,32 +20,32 @@ def get_models_to_process(): campaign.entities.CandidateCommittee, campaign.filings.form460.Form460FilingVersion, campaign.filings.form460.Form460Filing, - campaign.filings.form460.Form460ScheduleAItemVersion, - campaign.filings.form460.Form460ScheduleAItem, - campaign.filings.form460.Form460ScheduleB1ItemVersion, - campaign.filings.form460.Form460ScheduleB1Item, - campaign.filings.form460.Form460ScheduleB2ItemVersion, - campaign.filings.form460.Form460ScheduleB2Item, - campaign.filings.form460.Form460ScheduleB2ItemVersionOld, - campaign.filings.form460.Form460ScheduleB2ItemOld, - campaign.filings.form460.Form460ScheduleCItemVersion, - campaign.filings.form460.Form460ScheduleCItem, - campaign.filings.form460.Form460ScheduleDItemVersion, - campaign.filings.form460.Form460ScheduleDItem, - campaign.filings.form460.Form460ScheduleEItemVersion, - campaign.filings.form460.Form460ScheduleEItem, - campaign.filings.form460.Form460ScheduleESubItemVersion, - campaign.filings.form460.Form460ScheduleESubItem, - campaign.filings.form460.Form460ScheduleFItemVersion, - campaign.filings.form460.Form460ScheduleFItem, - campaign.filings.form460.Form460ScheduleGItemVersion, - campaign.filings.form460.Form460ScheduleGItem, - campaign.filings.form460.Form460ScheduleHItemVersion, - campaign.filings.form460.Form460ScheduleHItem, - campaign.filings.form460.Form460ScheduleH2ItemVersionOld, - campaign.filings.form460.Form460ScheduleH2ItemOld, - campaign.filings.form460.Form460ScheduleIItemVersion, - campaign.filings.form460.Form460ScheduleIItem, + campaign.filings.form460.schedules.a.Form460ScheduleAItemVersion, + campaign.filings.form460.schedules.a.Form460ScheduleAItem, + campaign.filings.form460.schedules.b.Form460ScheduleB1ItemVersion, + campaign.filings.form460.schedules.b.Form460ScheduleB1Item, + campaign.filings.form460.schedules.b.Form460ScheduleB2ItemVersion, + campaign.filings.form460.schedules.b.Form460ScheduleB2Item, + campaign.filings.form460.schedules.b.Form460ScheduleB2ItemVersionOld, + campaign.filings.form460.schedules.b.Form460ScheduleB2ItemOld, + campaign.filings.form460.schedules.c.Form460ScheduleCItemVersion, + campaign.filings.form460.schedules.c.Form460ScheduleCItem, + campaign.filings.form460.schedules.d.Form460ScheduleDItemVersion, + campaign.filings.form460.schedules.d.Form460ScheduleDItem, + campaign.filings.form460.schedules.e.Form460ScheduleEItemVersion, + campaign.filings.form460.schedules.e.Form460ScheduleEItem, + campaign.filings.form460.schedules.e.Form460ScheduleESubItemVersion, + campaign.filings.form460.schedules.e.Form460ScheduleESubItem, + campaign.filings.form460.schedules.f.Form460ScheduleFItemVersion, + campaign.filings.form460.schedules.f.Form460ScheduleFItem, + campaign.filings.form460.schedules.g.Form460ScheduleGItemVersion, + campaign.filings.form460.schedules.g.Form460ScheduleGItem, + campaign.filings.form460.schedules.h.Form460ScheduleHItemVersion, + campaign.filings.form460.schedules.h.Form460ScheduleHItem, + campaign.filings.form460.schedules.h.Form460ScheduleH2ItemVersionOld, + campaign.filings.form460.schedules.h.Form460ScheduleH2ItemOld, + campaign.filings.form460.schedules.i.Form460ScheduleIItemVersion, + campaign.filings.form460.schedules.i.Form460ScheduleIItem, campaign.filings.schedule497.Schedule497FilingVersion, campaign.filings.schedule497.Schedule497Filing, campaign.filings.schedule497.Schedule497Part1ItemVersion, diff --git a/calaccess_processed/models/__init__.py b/calaccess_processed/models/__init__.py index bf6ead8f..6eb535af 100644 --- a/calaccess_processed/models/__init__.py +++ b/calaccess_processed/models/__init__.py @@ -17,30 +17,48 @@ from calaccess_processed.models.campaign.filings.form460 import ( Form460Filing, Form460FilingVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.a import ( Form460ScheduleAItem, Form460ScheduleAItemVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.b import ( Form460ScheduleB1Item, Form460ScheduleB1ItemVersion, Form460ScheduleB2Item, Form460ScheduleB2ItemVersion, Form460ScheduleB2ItemOld, Form460ScheduleB2ItemVersionOld, +) +from calaccess_processed.models.campaign.filings.form460.schedules.c import ( Form460ScheduleCItem, Form460ScheduleCItemVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.d import ( Form460ScheduleDItem, Form460ScheduleDItemVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.e import ( Form460ScheduleEItem, Form460ScheduleEItemVersion, Form460ScheduleESubItem, Form460ScheduleESubItemVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.f import ( Form460ScheduleFItem, Form460ScheduleFItemVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.g import ( Form460ScheduleGItem, Form460ScheduleGItemVersion, +) +from calaccess_processed.models.campaign.filings.form460.schedules.h import ( Form460ScheduleHItem, Form460ScheduleHItemVersion, Form460ScheduleH2ItemOld, Form460ScheduleH2ItemVersionOld, +) +from calaccess_processed.models.campaign.filings.form460.schedules.i import ( Form460ScheduleIItem, Form460ScheduleIItemVersion, ) diff --git a/calaccess_processed/models/campaign/filings/form460.py b/calaccess_processed/models/campaign/filings/form460.py deleted file mode 100644 index 00259123..00000000 --- a/calaccess_processed/models/campaign/filings/form460.py +++ /dev/null @@ -1,2139 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" -Models for storing data from Campaign Disclosure Statements (Form 460). -""" -from __future__ import unicode_literals -from django.db import models -from django.utils.encoding import python_2_unicode_compatible -from calaccess_processed.managers import ProcessedDataManager -from calaccess_processed.models.campaign.filings import ( - CampaignFinanceFilingBase, - CampaignContributionBase, - CampaignExpenditureItemBase, - CampaignExpenditureSubItemBase, - CampaignLoanReceivedItemBase, - CampaignLoanMadeItemBase, -) - - -class Form460FilingBase(CampaignFinanceFilingBase): - """ - Base and abstract model for Form 460 filings. - """ - from_date = models.DateField( - verbose_name='from date', - db_index=True, - null=False, - help_text="The first date of the filing period covered by the statement " - "(from CVR_CAMPAIGN_DISCLOSURE.FROM_DATE)", - ) - thru_date = models.DateField( - verbose_name='thru date', - db_index=True, - null=False, - help_text="The last date of the filing period covered by the statement " - "(from CVR_CAMPAIGN_DISCLOSURE.THRU_DATE)", - ) - monetary_contributions = models.IntegerField( - verbose_name='monetary contributions', - null=True, - help_text="Total monetary contributions (from line 1, column A)", - ) - loans_received = models.IntegerField( - verbose_name='loans received', - null=True, - help_text="Total loans received (from line 2, column A)", - ) - subtotal_cash_contributions = models.IntegerField( - verbose_name='subtotal cash contributions', - null=True, - help_text="Monetary contributions and loans received combined (from " - "line 3, column A)", - ) - nonmonetary_contributions = models.IntegerField( - verbose_name='nonmonetary contributions', - null=True, - help_text="Non-monetary contributions (from line 4, column A)", - ) - total_contributions = models.IntegerField( - verbose_name='total contributions', - null=True, - help_text="Total contributions (from line 5, column A)", - ) - payments_made = models.IntegerField( - verbose_name='payments made', - null=True, - help_text="Payments made (from line 6, column A)", - ) - loans_made = models.IntegerField( - verbose_name='loans made', - null=True, - help_text="Loans made (from line 7, column A)", - ) - subtotal_cash_payments = models.IntegerField( - verbose_name='subtotal cash payments', - null=True, - help_text="Sub-total of cash payments (from line 8, column A)", - ) - unpaid_bills = models.IntegerField( - verbose_name='unpaid bills', - null=True, - help_text="Unpaid bills / accrued expenses (from line 9, column A)", - ) - nonmonetary_adjustment = models.IntegerField( - verbose_name='nonmonetary adjustment', - null=True, - help_text="Non-monetary adjustment (from line 10, column A), which is " - "equal to the total of non-monetary contributions", - ) - total_expenditures_made = models.IntegerField( - verbose_name='total expenditures made', - null=True, - help_text="Total expenditures made (from line 11, column A)", - ) - begin_cash_balance = models.IntegerField( - verbose_name='begin cash balance', - null=True, - help_text="Beginning cash balance (from line 12), which is equal to " - "the Ending Cash Balance (line 16) reported on the summary " - "page of the previous Form 460 filing" - ) - cash_receipts = models.IntegerField( - verbose_name='cash receipts', - null=True, - help_text="Cash receipts (from line 13)", - ) - miscellaneous_cash_increases = models.IntegerField( - verbose_name='miscellaneous cash increases', - null=True, - help_text="Miscellaneous cash increases (from line 14)", - ) - cash_payments = models.IntegerField( - verbose_name='cash payments', - null=True, - help_text="Cash payments (from line 15)", - ) - ending_cash_balance = models.IntegerField( - verbose_name='ending cash balance', - null=True, - help_text="Ending cash balance (from line 16)", - ) - loan_guarantees_received = models.IntegerField( - verbose_name='loan guarantees received', - null=True, - help_text="Loan guarantees received (from line 17)", - ) - cash_equivalents = models.IntegerField( - verbose_name='cash equivalents', - null=True, - help_text="Cash equivalents (from line 18), which includes investments " - "that can't be readily converted to cash, such as outstanding " - "loans the committee has made to others" - ) - outstanding_debts = models.IntegerField( - verbose_name='outstanding debts', - null=True, - help_text="Outstanding debts on loans owed by the committee (from line " - "19)", - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460Filing(Form460FilingBase): - """ - The most recent version of each Form 460 filing by recipient committees. - - Form 460 is the Campaign Disclosure Statement filed by all recipient - committees, including: - * Candidates, officeholders and their controlled committees - * Primarily formed ballot measure committees - * Primarily formed candidate/of ceholder committees - * General purpose committees - - Recipient committes can use Form 460 to file: - * Pre-election statements - * Semi-annual statements - * Quarterly statements - * Termination statements - * Special odd-year report - - Includes information from the cover sheet and summary page of the most - recent version of each Form 460 filing. All versions of the filings can be - found in Form460FilingVersion. - """ - filing_id = models.IntegerField( - verbose_name='filing id', - primary_key=True, - null=False, - help_text='Unique identification number for the Form 460 filing (' - 'from CVR_CAMPAIGN_DISCLOSURE_CD.FILING_ID)', - ) - amendment_count = models.IntegerField( - verbose_name='Count amendments', - db_index=True, - null=False, - help_text='Number of amendments to the Form 460 filing (from ' - 'maximum value of CVR_CAMPAIGN_DISCLOSURE_CD.AMEND_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - index_together = (( - 'filing_id', - 'amendment_count', - ),) - - def __str__(self): - return str(self.filing_id) - - -@python_2_unicode_compatible -class Form460FilingVersion(Form460FilingBase): - """ - Every version of each Form 460 (Campaign Disclosure Statement) filing by recipient committees. - - Includes information found on the cover sheet and summary page of each - version of each Form 460 filing. For the most recent version of each filing, - see Form460Filing. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='versions', - db_constraint=False, - null=True, - on_delete=models.SET_NULL, - help_text='Unique identification number for the Form 460 filing (' - 'from CVR_CAMPAIGN_DISCLOSURE_CD.FILING_ID)', - ) - amend_id = models.IntegerField( - verbose_name='amendment id', - null=False, - help_text='Identifies the version of the Form 497 filing, with 0 ' - 'representing the initial filing (from CVR_CAMPAIGN_' - 'DISCLOSURE_CD.AMEND_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'amend_id', - ),) - index_together = (( - 'filing', - 'amend_id', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.amend_id) - - -class Form460ScheduleAItemBase(CampaignContributionBase): - """ - Abstract base model for items reported on Schedule A of Form 460 filings. - - On Schedule A, campaign filers are required to itemize monetary - contributions received during the period covered by the filing. - """ - amount = models.DecimalField( - verbose_name='amount', - decimal_places=2, - max_digits=14, - help_text="Amount received from the contributor in the period covered " - "by the filing (from RCPT_CD.AMOUNT)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleAItem(Form460ScheduleAItemBase): - """ - Monetary contributions received by campaign filers. - - These transactions are itemized on Schedule A of the most recent version - of each Form 460 filing. For monetary contributions itemized on any version - of any Form 460 filing, see Form460ScheduleAItemVersion. - - Also includes contributions transferred to special election commitees, - which were itemized on Schedule A-1 until around 2001. - - Derived from RCPT_CD records where FORM_TYPE is 'A' or 'A-1'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_a_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the monetary' - ' contribution was reported (from RCPT_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleAItemVersion(Form460ScheduleAItemBase): - """ - Every version of each monetary contribution received by a campaign filer. - - For monetary contributions itemized on Schedule A of the most recent - version of each Form 460 filing, see Form460ScheduleAItem. - - Derived from RCPT_CD records where FORM_TYPE is 'A' or 'A-1'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_a_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the received contribution' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleB1ItemBase(CampaignLoanReceivedItemBase): - """ - Abstract base model for items reported on Schedule B, Part 1, of Form 460. - - On Schedule B, Part 1, campaign filers are required to report loans - received or outstanding during the period covered by the filing. - """ - begin_period_balance = models.DecimalField( - verbose_name='beginning period balance', - decimal_places=2, - max_digits=14, - help_text="Outstanding balance of the loan at the beginning of the" - "period covered by the filing (from LOAN_CD.LOAN_AMT4)" - ) - amount_received = models.DecimalField( - verbose_name='amount received', - decimal_places=2, - max_digits=14, - help_text="Amount received during the period covered by the filing " - "(from LOAN_CD.LOAN_AMT1)" - ) - amount_paid = models.DecimalField( - verbose_name='amount paid', - decimal_places=2, - max_digits=14, - help_text="Amount paid back during the period covered by the filing " - "(from LOAN_CD.LOAN_AMT5)" - ) - amount_forgiven = models.DecimalField( - verbose_name='amount forgiven', - decimal_places=2, - max_digits=14, - help_text="Amount forgiven by the lender during the period covered by " - "the filing (from LOAN_CD.LOAN_AMT6)" - ) - end_period_balance = models.DecimalField( - verbose_name='end period balance', - decimal_places=2, - max_digits=14, - help_text="Outstanding balance of the loan at the end of the period " - "covered by the filing (from LOAN_CD.LOAN_AMT2)" - ) - date_due = models.DateField( - verbose_name='date due', - null=True, - help_text="Date that the loan is due (from LOAN_CD.LOAN_DATE2)" - ) - interest_paid = models.DecimalField( - verbose_name='interest paid', - decimal_places=2, - max_digits=14, - help_text="Amount of interest paid on the loan during the period " - "covered by the campaign filing (from LOAN_CD.LOAN_AMT7)" - ) - original_amount = models.DecimalField( - verbose_name='original amount', - decimal_places=2, - max_digits=14, - help_text="Original amount loaned by the lender to the campaign filer " - "(from LOAN_CD.LOAN_AMT8)" - ) - date_incurred = models.DateField( - verbose_name='date incurred', - null=True, - help_text="Date the loan was made or received (from LOAN_CD.LOAN_DATE1)" - ) - cumulative_ytd_contributions = models.DecimalField( - verbose_name='cumulative year-to-date contributions', - decimal_places=2, - max_digits=14, - help_text="Cumulative amount of contributions (loans, monetary and " - "nonmonetary contributions) received from the lender during " - "the calendar year covered by this statement (from LOAN_CD." - "LOAN_AMT3)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleB1Item(Form460ScheduleB1ItemBase): - """ - Loans received and loan payments by campaign filers. - - These transactions are itemized on Schedule B, Part 1, of the most recent - version of each Form 460 filing. For loans itemized on any version of any - Form 460 filing, see Form460ScheduleB1ItemVersion. - - Derived from LOAN_CD records where FORM_TYPE is 'B1'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_b1_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the loan ' - 'was reported (from LOAN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleB1ItemVersion(Form460ScheduleB1ItemBase): - """ - Every version of each loan received or loan payment made by a campaign filer. - - For outstanding loans itemized on Schedule B, Part 1, of the most recent - version of each Form 460 filing, see Form460ScheduleB1Item. - - Derived from LOAN_CD records where FORM_TYPE is 'B1'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_b1_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the outstanding loan' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleB2ItemBase(models.Model): - """ - Abstract base model for items reported on Schedule B, Part 2, of Form 460. - - On Schedule B, Part 2, campaign filers are required to report loan - guarantors, A "guarantor" is a third party that co-signs, endorses, or - provides security for a loan, or establishes or provides security for a - line of credit. A guarantor is also making a contribution. - """ - line_item = models.IntegerField( - verbose_name='line item', - help_text="Line number of the filing form where the loan is " - "itemized (from LOAN_CD.LINE_ITEM)", - ) - GUARANTOR_CODE_CHOICES = ( - ('COM', "Committee"), - ('IND', "Individual"), - ('OTH', "Other"), - ('PTY', "Political Party"), - ('SCC', "Small Contributor Committee"), - ('???', "Unknown value"), - ) - guarantor_code = models.CharField( - verbose_name='lender code', - max_length=3, - blank=True, - choices=GUARANTOR_CODE_CHOICES, - help_text='Code describing the guarantor (from LOAN_CD.ENTITY_CD)', - ) - guarantor_title = models.CharField( - verbose_name='guarantor title', - max_length=10, - blank=True, - help_text="Name title of the guarantor (from LOAN_CD.LNDR_NAMT)", - ) - guarantor_lastname = models.CharField( - verbose_name='guarantor lastname', - max_length=200, - blank=True, - help_text="Last name of the guarantor or business name (from LOAN_CD." - "LNDR_NAML)", - ) - guarantor_firstname = models.CharField( - verbose_name='guarantor firstname', - max_length=45, - blank=True, - help_text="First name of the guarantor (from LOAN_CD.LNDR_NAMF)", - ) - guarantor_name_suffix = models.CharField( - verbose_name='guarantor name suffix', - max_length=10, - blank=True, - help_text="Name suffix of the guarantor (from LOAN_CD.LNDR_NAMS)", - ) - guarantor_city = models.CharField( - verbose_name='guarantor city', - max_length=30, - blank=True, - help_text='City of the guarantor (from LOAN_CD.LOAN_CITY)', - ) - guarantor_state = models.CharField( - verbose_name='guarantor state', - max_length=2, - blank=True, - help_text='State of the guarantor (from LOAN_CD.LOAN_ST)', - ) - guarantor_zip = models.CharField( - verbose_name='guarantor zip', - max_length=10, - blank=True, - help_text='Zip code (usually zip5, sometimes zip9) of the ' - 'guarantor (from LOAN_CD.LOAN_ZIP4)', - ) - guarantor_employer = models.CharField( - verbose_name='guarantor employer', - max_length=200, - blank=True, - help_text='Employer of the guarantor (from LOAN_CD.LOAN_EMP)', - ) - guarantor_occupation = models.CharField( - verbose_name='guarantor occupation', - max_length=60, - blank=True, - help_text='Occupation of the guarantor (from LOAN_CD.LOAN_OCC)', - ) - guarantor_is_self_employed = models.BooleanField( - verbose_name='guarantor is self employed', - default=False, - help_text='Indicates whether or not the guarantor is self-employed' - '(from LOAN_CD.LOAN_SELF)', - ) - lender_name = models.CharField( - verbose_name='lender name', - max_length=200, - blank=True, - help_text="Name of the lender (from LOAN_CD.INTR_NAML)" - ) - amount_guaranteed_this_period = models.DecimalField( - verbose_name='amount guaranteed this period', - decimal_places=2, - max_digits=14, - help_text="Amount guaranteed for the period covered by the filing " - "(from LOAN_CD.LOAN_AMT1)" - ) - balance_outstanding_to_date = models.DecimalField( - verbose_name='balance outstanding to date', - decimal_places=2, - max_digits=14, - help_text="Outstanding balance for which the guarantor is liable at " - "the close of the reporting period (from LOAN_CD.LOAN_AMT2)" - ) - cumulative_ytd_amount = models.DecimalField( - verbose_name='cumulative year-to-date amount', - decimal_places=2, - max_digits=14, - help_text="Cumulative amount guaranteed during the calendar year " - "covered by the statement (from LOAN_CD.LOAN_AMT3)" - ) - loan_date = models.DateField( - verbose_name='loan date', - null=True, - help_text="Date of the loan or date the line of credit was established" - "(from LOAN_CD.LOAN_DATE1)" - ) - interest_rate = models.CharField( - verbose_name='interest rate', - max_length=30, - blank=True, - help_text='Interest rate of the loan. This is sometimes expressed as a ' - 'decimal (e.g., 0.10) and other times as a percent (e.g., ' - '10.0% (from LOAN_CD.LOAN_RATE)' - ) - transaction_id = models.CharField( - verbose_name='transaction id', - max_length=20, - help_text='Identifies a unique transaction across versions of the a ' - 'given Form 460 filing (from LOAN_CD.TRAN_ID)', - ) - memo_reference_number = models.CharField( - verbose_name='memo reference number', - max_length=20, - blank=True, - help_text="A value assigned by the filer which refers to the item's" - "footnote in the TEXT_MEMO_CD table (from LOAN_CD." - "MEMO_REFNO)", - ) - reported_on_b1 = models.BooleanField( - verbose_name='reported on B1', - default=False, - help_text='Indicates if the item was actually reported on Part 1 of ' - 'Schedule B. Until 2001, campaign filers were required to ' - 'report guarantors of loans or lines of credit on Part 1 of ' - 'Schedule B.' - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleB2Item(Form460ScheduleB2ItemBase): - """ - Guarantees of loans and lines of credit received by campaign filers. - - These transactions are itemized on Schedule B, Part 2, of the most recent - version to each Form 460 filing. For guarantees itemized on - any version of any Form 460 filing, see Form460ScheduleB2ItemVersion. - - Derived from LOAN_CD records where FORM_TYPE is 'B2'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_b2_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the loan ' - 'was reported (from LOAN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleB2ItemVersion(Form460ScheduleB2ItemBase): - """ - Every version of each guarantee of a loan/line of credit to a campaign filer. - - For guaratees itemized on Schedule B, Part 1, of the most recent - version of each Form 460 filing, see Form460ScheduleB2Item. - - Derived from LOAN_CD records where FORM_TYPE is 'B2'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_b2_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the outstanding loan' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleB2ItemBaseOld(CampaignLoanReceivedItemBase): - """ - Abstract base model for Schedule B, Part 2, items from Form 460 circa 2001. - - Until Form 460 was modified in 2001, campaign filers were required to report - repayments made on loans received, loans forgiven, and loans repaid by a - third party on Part 2 of Schedule B. - """ - date_repaid_or_forgiven = models.DateField( - verbose_name='date paid or forgiven', - null=True, - help_text="Date when the loan repayment or forgiveness occurred (from " - "LOAN_CD.LOAN_DATE2)" - ) - date_of_original_loan = models.DateField( - verbose_name='date of original loan', - null=True, - help_text="Date the loan was orginally made (from LOAN_CD.LOAN_DATE1)" - ) - REPAYMENT_TYPE_CHOICES = ( - ('B2F', 'Forgiven'), - ('B2R', 'Repay'), - ('B2T', 'Third party payment'), - ) - repayment_type = models.CharField( - verbose_name='repayment type', - max_length=3, - choices=REPAYMENT_TYPE_CHOICES, - help_text='Indicates whether the item is a loan repayment by the ' - 'campaign filer, a repayment by a third-party or a loan ' - 'forgiveness by the lender (from LOAN_CD.LOAN_TYPE)', - ) - amount_repaid_or_forgiven = models.DecimalField( - verbose_name='amount repaid or forgiven', - decimal_places=2, - max_digits=14, - help_text="Amount paid back or forgiven during the period covered by " - "the filing (from LOAN_CD.LOAN_AMT1)" - ) - outstanding_principle = models.DecimalField( - verbose_name='outstanding principle', - decimal_places=2, - max_digits=14, - help_text="Outstanding principle of the loan at the end of the period " - "covered by the filing (from LOAN_CD.LOAN_AMT2)" - ) - interest_paid = models.DecimalField( - verbose_name='interest paid', - decimal_places=2, - max_digits=14, - help_text="Amount of interest paid on the loan during the period " - "covered by the campaign filing (from LOAN_CD.LOAN_AMT3)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleB2ItemOld(Form460ScheduleB2ItemBaseOld): - """ - Repayments on loans/forgiven loans received by campaign filers circa 2001. - - These transactions are itemized on Schedule B, Part 2, of the most recent - version to each Form 460 filing in the pre-2001 format. For loan repayments - and forgiven loans on any version of any Form 460 filing in the pre-2001 - format, see Form460ScheduleB2ItemVersionOld. - - Derived from LOAN_CD records where LOAN_TYPE is not blank or LOAN_DATE1 is - before December 22, 2000. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_b2_items_old', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the loan ' - 'transaction was reported (from LOAN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - verbose_name_plural = "Form460 schedule b2 items old" - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleB2ItemVersionOld(Form460ScheduleB2ItemBaseOld): - """ - Every version of each repayment/forgiveness of a loan to a campaign filer circa 2001. - - For loan repayments and forgiven loans on any version of any Form 460 filing - in the pre-2001 format, see Form460ScheduleB2ItemOld. - - Derived from LOAN_CD records where LOAN_TYPE is not blank or LOAN_DATE1 is - before December 22, 2000. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_b2_items_old', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the loan transaction' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - verbose_name_plural = "Form460 schedule b2 item versions old" - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleCItemBase(CampaignContributionBase): - """ - Abstract base model for items reported on Schedule C of Form 460 filings. - - On Schedule C, campaign filers are required to itemize nonmonetary - contributions received during the period covered by the filing. - """ - fair_market_value = models.DecimalField( - verbose_name='fair market value', - decimal_places=2, - max_digits=14, - help_text="Amount it would cost to purchase the donated goods or " - "services on the open market (from RCPT_CD.AMOUNT)" - ) - contribution_description = models.CharField( - max_length=90, - blank=True, - help_text="Description of the contributed goods or services (from " - "RCPT_CD.CTRIB_DSCR)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleCItem(Form460ScheduleCItemBase): - """ - Nonmonetary contributions received by campaign filers. - - These transactions are itemized on Schedule C of the most recent version - of each Form 460 filing. For nonmonetary contributions itemized on any - version of any Form 460 filing, see Form460ScheduleCItemVersion. - - Derived from RCPT_CD records where FORM_TYPE is 'C'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_c_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the monetary' - ' contribution was reported (from RCPT_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleCItemVersion(Form460ScheduleCItemBase): - """ - Every version of each nonmonetary contribution received by a campaign filer. - - For nonmonetary contributions itemized on Schedule C of the most recent - version of each Form 460 filing, see Form460ScheduleCItem. - - Derived from RCPT_CD records where FORM_TYPE is 'C'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_c_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the received contribution' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleDItemBase(CampaignExpenditureItemBase): - """ - Abstract base model for items reported on Schedule D of Form 460 filings. - - On Schedule D, campaign filers are required to summarize contributions - and independent expenditures in support or opposition to other candidates - and ballot measures. - """ - cumulative_election_amount = models.DecimalField( - decimal_places=2, - max_digits=14, - null=True, - help_text="If the candidate is subject to contribution limits, the " - "cumulative amount given by the filer during the election " - "cycle as of the Form 460's filing date (from EXPN_CD." - "CUM_OTH)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleDItem(Form460ScheduleDItemBase): - """ - Payments in support or opposition of other candidates and ballot measures. - - These transactions are itemized on Schedule D of the most recent version - of each Form 460 filing. For payments itemized on any version of any Form - 460 filing, see Form460ScheduleDItemVersion. - - Derived from EXPN_CD records where FORM_TYPE is 'D'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_d_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the ' - 'payment was reported (from EXPN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleDItemVersion(Form460ScheduleDItemBase): - """ - Every version of each payment supporting/opposing another candidate/ballot measure. - - For payments itemized on Schedule D of the most recent version of each Form - 460 filing, see Form460ScheduleDItem. - - Derived from EXPN_CD records where FORM_TYPE is 'D'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_d_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the payment made' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -@python_2_unicode_compatible -class Form460ScheduleEItem(CampaignExpenditureItemBase): - """ - Payments made by campaign filers. - - These transactions are itemized on Schedule E of the most recent version - of each Form 460 filing. For payments itemized on any version of any - filing, see Form460ScheduleEItemVersion. - - Does not include: - * Interest paid on loans received - * Loans made to others - * Transfers of campaign funds into savings accounts - * Payments made by agents or contractors on behalf of the filer - * Certificates of deposit - * Money market accounts - * Purchases of other assets that can readily be converted to cash - - Derived from EXPN_CD records where FORM_TYPE is 'E'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_e_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the ' - 'payment was reported (from EXPN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleEItemVersion(CampaignExpenditureItemBase): - """ - Every version of each payment made by a campaign filer. - - For payments itemized on Schedule E of the most recent version of each Form - 460 filing, see Form460ScheduleEItem. - - Does not include: - * Interest paid on loans received - * Loans made to others - * Transfers of campaign funds into savings accounts - * Payments made by agents or contractors on behalf of the filer - * Certificates of deposit - * Money market accounts - * Purchases of other assets that can readily be converted to cash - - Derived from EXPN_CD records where FORM_TYPE is 'E'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_e_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the payment made' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -@python_2_unicode_compatible -class Form460ScheduleESubItem(CampaignExpenditureSubItemBase): - """ - Sub-items of payments made by campaign filers. - - These transactions are itemized on Schedule E of the most recent version - of each Form 460 filing. For sub-item payments on any version of any Form - 460 filing, see Form460ScheduleESubItemVersion. - - A sub-item is a transaction where the amount is lumped into another - "parent" payment reported elsewhere on the filing. - - Includes: - * Payments supporting or opposing other candidates, ballot measures - or committees, which are summarized on Schedule D - * Payments made to vendors over $100 included in credit card payments - * Payments made by agents or independent contractors on behalf of the - campaign filer which were reported on Schedule E instead of G - * Payments made on the accrued expenses reported on Schedule F - - Derived from EXPN_CD records where FORM_TYPE is 'E' and MEMO_CODE is not - blank. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_e_subitems', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the ' - 'payment was reported (from EXPN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleESubItemVersion(CampaignExpenditureSubItemBase): - """ - Every version of each sub-item of a payment by a campaign filer. - - For payments sub-itemized on Schedule E of the most recent version of each - Form 460 filing, see Form460ScheduleESubItem. - - A sub-item is a transaction where the amount is lumped into another - "parent" payment reported elsewhere on the filing. - - Includes: - * Payments supporting or opposing other candidates, ballot measures - or committees, which are summarized on Schedule D - * Payments made to vendors over $100 included in credit card payments - * Payments made by agents or independent contractors on behalf of the - campaign filer which were reported on Schedule E instead of G - * Payments made on the accrued expenses reported on Schedule F - - Derived from EXPN_CD records where FORM_TYPE is 'E' and MEMO_CODE is not - blank. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_e_subitems', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the payment made' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleFItemBase(models.Model): - """ - Abstract base model for items reported on Schedule F of Form 460 filings. - - On Schedule F, campaign filers report unpaid bills for goods or services - accrued during the period covered by the filing. - """ - line_item = models.IntegerField( - verbose_name='line item', - help_text="Line number of the filing form where the unpaid bill is " - "itemized (from DEBT_CD.LINE_ITEM)", - ) - PAYEE_CODE_CHOICES = ( - ('BNM', "Ballot measure's name/title"), - ('COM', "Committee"), - ('IND', "Individual"), - ('OTH', "Other"), - ('PTY', "Political Party"), - ('RCP', "Recipient committee"), - ('SCC', "Small Contributor Committee"), - ('???', "Unknown value"), - ) - payee_code = models.CharField( - verbose_name='payee code', - max_length=3, - blank=True, - choices=PAYEE_CODE_CHOICES, - help_text='Code describing the payee (from DEBT_CD.ENTITY_CD)', - ) - payee_committee_id = models.CharField( - verbose_name='committee id', - max_length=9, - blank=True, - help_text="Payee's filer identification number, if it is a " - "committee (from DEBT_CD.CMTE_ID)", - ) - payee_title = models.CharField( - verbose_name='payee title', - max_length=10, - blank=True, - help_text='Name title of the payee (from DEBT_CD.PAYEE_NAMT)', - ) - payee_lastname = models.CharField( - verbose_name='payee lastname', - max_length=200, - blank=True, - help_text='Last name of the payee or business name (from ' - 'DEBT_CD.PAYEE_NAML)', - ) - payee_firstname = models.CharField( - verbose_name='payee firstname', - max_length=45, - help_text='First name of the payee (from DEBT_CD.PAYEE_NAMF)', - ) - payee_name_suffix = models.CharField( - verbose_name='payee name suffix', - max_length=10, - blank=True, - help_text='Name suffix of the payee (from DEBT_CD.PAYEE_NAMS)', - ) - payee_city = models.CharField( - verbose_name='payee city', - max_length=30, - blank=True, - help_text='City of the payee (from DEBT_CD.PAYEE_CITY)', - ) - payee_state = models.CharField( - verbose_name='payee state', - max_length=2, - blank=True, - help_text='State of the payee (from DEBT_CD.PAYEE_ST)', - ) - payee_zip = models.CharField( - verbose_name='payee zip', - max_length=10, - blank=True, - help_text='Zip code (usually zip5, sometimes zip9) of the ' - 'payee (from DEBT_CD.PAYEE_ZIP4)', - ) - treasurer_title = models.CharField( - verbose_name='treasurer title', - max_length=10, - blank=True, - help_text="Name title of the payee committee's treasurer (from " - "DEBT_CD.TRES_NAMT)", - ) - treasurer_lastname = models.CharField( - verbose_name='treasurer lastname', - max_length=200, - blank=True, - help_text="Last name of the payee committee's treasurer (from " - "DEBT_CD.TRES_NAML)", - ) - treasurer_firstname = models.CharField( - verbose_name='treasurer firstname', - max_length=45, - help_text="First name of the payee committee's treasurer (from " - "DEBT_CD.TRES_NAMF)", - ) - treasurer_name_suffix = models.CharField( - verbose_name='treasurer name suffix', - max_length=10, - blank=True, - help_text="Name suffix of the payee committee's treasurer (from " - "DEBT_CD.TRES_NAMS)", - ) - treasurer_city = models.CharField( - verbose_name='treasurer city', - max_length=30, - blank=True, - help_text="City of the payee committee's treasurer (from DEBT_CD." - "TRES_CITY)", - ) - treasurer_state = models.CharField( - verbose_name='treasurer state', - max_length=2, - blank=True, - help_text="State of the payee committee's treasurer (from DEBT_CD." - "TRES_ST)", - ) - PAYMENT_CODE_CHOICES = ( - ('CMP', 'Campaign paraphernalia/miscellaneous'), - ('CNS', 'Campaign consultants'), - ('CTB', 'Contribution (if nonmonetary, explain)*'), - ('CVC', 'Civic donations'), - ('FIL', 'Candidate filing/ballot feeds'), - ('FND', 'Fundraising events'), - ('IKD', 'In-kind contribution (nonmonetary)'), - ('IND', 'Independent expenditure supporting/opposing others (explain)*'), - ('LEG', 'Legal defense'), - ('LIT', 'Campaign literature and mailings'), - ('LON', 'Loan'), - ('MBR', 'Member communications'), - ('MON', 'Monetary contribution'), - ('MTG', 'Meetings and appearances'), - ('OFC', 'Office expenses'), - ('PET', 'Petition circulating'), - ('PHO', 'Phone banks'), - ('POL', 'Polling and survey research'), - ('POS', 'Postage, delivery and messenger services'), - ('PRO', 'Professional services (legal, accounting)'), - ('PRT', 'Print ads'), - ('RAD', 'Radio airtime and production costs'), - ('RFD', 'Returned contributions'), - ('SAL', 'Campaign workers salaries'), - ('TEL', 'T.V. or cable airtime and production costs'), - ('TRC', 'Candidate travel, lodging and meals (explain)'), - ('TRS', 'Staff/spouse travel, lodging and meals (explain)'), - ('TSF', 'Transfer between committees of the same candidate/sponsor'), - ('VOT', 'Voter registration'), - ('WEB', 'Information technology costs (internet, e-mail)'), - ('???', "Unknown value"), - ) - payment_code = models.CharField( - verbose_name='payment code', - max_length=3, - blank=True, - choices=PAYMENT_CODE_CHOICES, - help_text='Code describing the payment (from DEBT_CD.EXPN_CODE)', - ) - payment_description = models.CharField( - verbose_name="payment description", - max_length=400, - blank=True, - help_text="Purpose of payment and/or description/explanation (from " - "DEBT_CD.EXPN_DSCR)", - ) - begin_balance = models.DecimalField( - verbose_name="begin balance", - decimal_places=2, - max_digits=14, - help_text="Outstanding balance at the beginning of period covered by " - "the filing (from DEBT_CD.BEG_BAL)", - ) - amount_paid = models.DecimalField( - decimal_places=2, - max_digits=14, - help_text='Amount paid this period (from DEBT_CD.AMT_PAID)' - ) - amount_incurred = models.DecimalField( - verbose_name="amount incurred", - decimal_places=2, - max_digits=14, - help_text='Amount incurred this period (from DEBT_CD.AMT_INCUR)', - ) - end_balance = models.DecimalField( - verbose_name="end balance", - decimal_places=2, - max_digits=14, - help_text="Outstanding balance at the end of period covered by the " - "filing (from DEBT_CD.END_BAL)", - ) - transaction_id = models.CharField( - verbose_name='transaction id', - max_length=20, - help_text='Identifies a unique transaction across versions of the a ' - 'given Form 460 filing (from DEBT_CD.TRAN_ID)', - ) - parent_transaction_id = models.CharField( - verbose_name='parent transaction id', - max_length=20, - blank=True, - help_text='Refers to a parent transaction itemized on the same Form ' - '460 filing (from DEBT_CD.BAKREF_TID)', - ) - memo_reference_number = models.CharField( - verbose_name='memo reference number', - max_length=20, - blank=True, - help_text="A value assigned by the filer which refers to the item's" - "footnote in the TEXT_MEMO_CD table (from DEBT_CD." - "MEMO_REFNO)", - ) - memo_code = models.BooleanField( - verbose_name='memo_code', - default=False, - help_text="Memo amount flag (from DEBT_CD.MEMO_CODE)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleFItem(Form460ScheduleFItemBase): - """ - Accrued expenses of campaign filers. - - These transactions are itemized on Schedule F of the most recent version - of each Form 460 filing. For accrued expenses itemized on any version of - of any Form 460 filing, see Form460ScheduleFItemVersion. - - Derived from DEBT_CD records. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_f_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the ' - 'payment was reported (from DEBT_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleFItemVersion(Form460ScheduleFItemBase): - """ - Every version of each accrued expense of a campaign filer. - - For accrued expenses itemized on Schedule F of the most recent version of - each Form 460 filing, see Form460ScheduleGItem. - - Derived from DEBT_CD records. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_f_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the Schedule F items' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleGItemBase(CampaignExpenditureSubItemBase): - """ - Abstract base model for items reported on Schedule G of Form 460 filings. - - On Schedule G, campaign filers are required to itemize payments made on - their behalf by agents or contractors during the period covered by the - filing. - """ - agent_title = models.CharField( - verbose_name='agent title', - max_length=10, - blank=True, - help_text='Name title of the agent (from EXPN_CD.AGENT_NAMT)', - ) - agent_lastname = models.CharField( - verbose_name='agent lastname', - max_length=200, - blank=True, - help_text='Last name of the agent or business name (from ' - 'EXPN_CD.AGENT_NAML)', - ) - agent_firstname = models.CharField( - verbose_name='agent firstname', - max_length=45, - help_text='First name of the agent (from EXPN_CD.AGENT_NAMF)', - ) - agent_name_suffix = models.CharField( - verbose_name='agent name suffix', - max_length=10, - blank=True, - help_text='Name suffix of the agent (from EXPN_CD.AGENT_NAMS)', - ) - PARENT_SCHEDULE_CHOICES = ( - ('E', 'Schedule E: Payments Made'), - ('F', 'Schedule F: Accrued Expenses (Unpaid Bills)') - ) - parent_schedule = models.CharField( - max_length=1, - blank=True, - help_text="Indicates which schedule (E or F) includes the parent item " - "(from EXPN_CD.G_FROM_E_F)", - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleGItem(Form460ScheduleGItemBase): - """ - Payments made by on behalf of campaign filers. - - These transactions are itemized on Schedule G of the most recent version - of each Form 460 filing. For payments itemized on any version of any Form - 460 filing, see Form460schedulegitemversion. - - Derived from EXPN_CD records where FORM_TYPE is 'G'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_g_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the ' - 'payment was reported (from RCPT_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleGItemVersion(Form460ScheduleGItemBase): - """ - Every version of each payment made on behalf of a campaign filer. - - For payments itemized on Schedule G of the most recent version of each Form - 460 filing, see Form460ScheduleGitem. - - Derived from EXPN_CD records where FORM_TYPE is 'G'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_g_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the payment made' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleHItemBase(CampaignLoanMadeItemBase): - """ - Abstract base model for items reported on Schedule H of Form 460. - - On Schedule H, campaign filers are required to report loans made or - currently outstanding to other recipients during the period covered by the - filing. - """ - begin_period_balance = models.DecimalField( - verbose_name='beginning period balance', - decimal_places=2, - max_digits=14, - help_text="Outstanding balance of the loan at the beginning of the" - "period covered by the filing (from LOAN_CD.LOAN_AMT4)" - ) - amount_loaned = models.DecimalField( - verbose_name='amount loaned', - decimal_places=2, - max_digits=14, - help_text="Amount loaned during the period covered by the filing " - "(from LOAN_CD.LOAN_AMT1)" - ) - amount_paid = models.DecimalField( - verbose_name='amount paid', - decimal_places=2, - max_digits=14, - help_text="Amount paid back during the period covered by the filing " - "(from LOAN_CD.LOAN_AMT5)" - ) - amount_forgiven = models.DecimalField( - verbose_name='amount forgiven', - decimal_places=2, - max_digits=14, - help_text="Amount forgiven by the campaign filer during the period " - "covered by the filing (from LOAN_CD.LOAN_AMT6)" - ) - end_period_balance = models.DecimalField( - verbose_name='end period balance', - decimal_places=2, - max_digits=14, - help_text="Outstanding balance of the loan at the end of the period " - "covered by the filing (from LOAN_CD.LOAN_AMT2)" - ) - date_due = models.DateField( - verbose_name='date due', - null=True, - help_text="Date that the loan is due (from LOAN_CD.LOAN_DATE2)" - ) - interest_received = models.DecimalField( - verbose_name='interest paid', - decimal_places=2, - max_digits=14, - help_text="Amount of interest paid on the loan during the period " - "covered by the campaign filing (from LOAN_CD.LOAN_AMT7)" - ) - original_amount = models.DecimalField( - verbose_name='original amount', - decimal_places=2, - max_digits=14, - help_text="Original amount loaned by the lender to the campaign filer " - "(from LOAN_CD.LOAN_AMT8)" - ) - date_incurred = models.DateField( - verbose_name='date incurred', - null=True, - help_text="Date the loan was made or received (from LOAN_CD.LOAN_DATE1)" - ) - cumulative_ytd_contributions = models.DecimalField( - verbose_name='cumulative year-to-date contributions', - decimal_places=2, - max_digits=14, - help_text="Cumulative amount of contributions (loans, monetary and " - "nonmonetary contributions) from the campaign filer to the " - "recipient during the calendar year covered by this statement" - " (from LOAN_CD.LOAN_AMT3)" - ) - reported_on_h1 = models.BooleanField( - verbose_name='reported on H1', - default=False, - help_text='Indicates if the item was actually reported on Part 1 of ' - 'Schedule H. Until 2001, campaign filers were required to ' - 'report loans made to others on Part 1 of Schedule H, ' - 'separate from repayments or forgiveness of those loans ' - '(Schedule H, Part 2)' - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleHItem(Form460ScheduleHItemBase): - """ - Loans made by campaign filers to other recipients. - - These transactions are itemized on Schedule H of the most recent version of - each Form 460 filing. For loans itemized on any version of any Form 460 - filing, see Form460ScheduleHItemVersion. - - Derived from LOAN_CD records where FORM_TYPE is 'H' or 'H1'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_h_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the loan ' - 'was reported (from LOAN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleHItemVersion(Form460ScheduleHItemBase): - """ - Every version of each loan made by a campaign filer another recipient. - - For outstanding loans itemized on Schedule H of the most recent version of - each Form 460 filing, see Form460ScheduleHItem. - - Derived from LOAN_CD records where FORM_TYPE is 'H' or 'H1'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_h_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the outstanding loan' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleH2ItemBaseOld(CampaignLoanMadeItemBase): - """ - Abstract base model for Schedule H, Part 2, items from Form 460 circa 2001. - - Until Form 460 was modified in 2001, campaign filers were required to report - repayments on and forgiveness of loans made to others on Part 2 of Schedule - H. - """ - date_repaid_or_forgiven = models.DateField( - verbose_name='date paid or forgiven', - null=True, - help_text="Date when the loan repayment or forgiveness occurred (from " - "LOAN_CD.LOAN_DATE2)" - ) - date_of_original_loan = models.DateField( - verbose_name='date of original loan', - null=True, - help_text="Date the loan was orginally made (from LOAN_CD.LOAN_DATE1)" - ) - REPAYMENT_TYPE_CHOICES = ( - ('H2F', 'Forgiven'), - ('H2R', 'Repay'), - ('H2T', 'Third party payment'), - ) - repayment_type = models.CharField( - verbose_name='repayment type', - max_length=3, - choices=REPAYMENT_TYPE_CHOICES, - help_text='Indicates whether the item is a loan repayment to the ' - 'campaign filer, a repayment by a third-party or a loan ' - 'forgiveness by the campaign filer (from LOAN_CD.LOAN_TYPE)', - ) - amount_repaid_or_forgiven = models.DecimalField( - verbose_name='amount repaid or forgiven', - decimal_places=2, - max_digits=14, - help_text="Amount paid back or forgiven during the period covered by " - "the filing (from LOAN_CD.LOAN_AMT1)" - ) - outstanding_principle = models.DecimalField( - verbose_name='outstanding principle', - decimal_places=2, - max_digits=14, - help_text="Outstanding balance of the loan at the end of the period " - "covered by the filing (from LOAN_CD.LOAN_AMT2)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleH2ItemOld(Form460ScheduleH2ItemBaseOld): - """ - Repayments on loans/forgiven loans made by campaign filers circa 2001. - - These transactions are itemized on Schedule H, Part 2, of the most recent - version to each Form 460 filing in the pre-2001 format. For loan repayments - and forgiven loans on any version of any Form 460 filing in the pre-2001 - format, see Form460ScheduleH2ItemVersionOld. - - Derived from LOAN_CD records where FORM_TYPE is 'H2'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_h2_items_old', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the Form 460 on which the loan ' - 'was reported (from LOAN_CD.FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - verbose_name_plural = "Form460 schedule h2 items old" - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleH2ItemVersionOld(Form460ScheduleH2ItemBaseOld): - """ - Every version of each repayment/forgiveness of a loan by a campaign filer circa 2001. - - For loan repayments and forgiven loans on any version of any Form 460 filing - in the pre-2001 format, see Form460ScheduleH2ItemOld. - - Derived from LOAN_CD records where FORM_TYPE is 'H2'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_h2_items_old', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the outstanding loan' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - verbose_name_plural = "Form460 schedule h2 item versions old" - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) - - -class Form460ScheduleIItemBase(CampaignContributionBase): - """ - Abstract base model for items reported on Schedule I of Form 460 filings. - - On Schedule I, campaign filers are required to report miscellaneous cash - increases during the period covered by the filing. These include any - transaction that increases the cash position of the filer, but is not a - monetary contribution, loan, or loan repayment. - """ - amount = models.DecimalField( - verbose_name='amount', - decimal_places=2, - max_digits=14, - help_text="Amount of cash increase from the contributor in the period " - "covered by the filing (from RCPT_CD.AMOUNT)" - ) - receipt_description = models.CharField( - verbose_name='receipt description', - max_length=90, - blank=True, - help_text="Description of the cash increase (from RCPT_CD.CTRIB_DSCR)" - ) - - class Meta: - """ - Model options. - """ - abstract = True - - -@python_2_unicode_compatible -class Form460ScheduleIItem(Form460ScheduleIItemBase): - """ - Miscellaneous cash increases to the coffers of campaign filers. - - Includes any transaction that increases the cash position of the filer, but - is not a monetary contribution, loan, or loan repayment. - - These transactions are itemized on Schedule I of the most recent version - of each Form 460 filing. For miscellaneous cash increases itemized on any - version of any Form 460 filing, see Form460ScheduleIItemVersion. - - Derived from RCPT_CD records where FORM_TYPE is 'I'. - """ - filing = models.ForeignKey( - 'Form460Filing', - related_name='schedule_i_items', - null=True, - on_delete=models.SET_NULL, - db_constraint=False, - help_text='Foreign key referring to the Form 460 on which the ' - 'miscellaneous cash increase was report (from RCPT_CD.' - 'FILING_ID)', - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing', - 'line_item', - ),) - - def __str__(self): - return '%s-%s' % (self.filing, self.line_item) - - -@python_2_unicode_compatible -class Form460ScheduleIItemVersion(Form460ScheduleIItemBase): - """ - Every version of each miscellaneous cash increase for a campaign filer. - - Includes any transaction that increases the cash position of the filer, but - is not a monetary contribution, loan, or loan repayment. - - For miscellaneous cash increases itemized on Schedule I of the most recent - version of each Form 460 filing, see Form460ScheduleIItem. - - Derived from RCPT_CD records where FORM_TYPE is 'I'. - """ - filing_version = models.ForeignKey( - 'Form460FilingVersion', - related_name='schedule_i_items', - null=True, - on_delete=models.SET_NULL, - help_text='Foreign key referring to the version of the Form 460 that ' - 'includes the miscellaneous cash increase' - ) - - objects = ProcessedDataManager() - - class Meta: - """ - Model options. - """ - unique_together = (( - 'filing_version', - 'line_item', - ),) - index_together = (( - 'filing_version', - 'line_item', - ),) - - def __str__(self): - return '%s-%s-%s' % ( - self.filing_version.filing_id, - self.filing_version.amend_id, - self.line_item - ) diff --git a/calaccess_processed/models/campaign/filings/form460/__init__.py b/calaccess_processed/models/campaign/filings/form460/__init__.py new file mode 100644 index 00000000..7da83efd --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/__init__.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignFinanceFilingBase + + +class Form460FilingBase(CampaignFinanceFilingBase): + """ + Base and abstract model for Form 460 filings. + """ + from_date = models.DateField( + verbose_name='from date', + db_index=True, + null=False, + help_text="The first date of the filing period covered by the statement " + "(from CVR_CAMPAIGN_DISCLOSURE.FROM_DATE)", + ) + thru_date = models.DateField( + verbose_name='thru date', + db_index=True, + null=False, + help_text="The last date of the filing period covered by the statement " + "(from CVR_CAMPAIGN_DISCLOSURE.THRU_DATE)", + ) + monetary_contributions = models.IntegerField( + verbose_name='monetary contributions', + null=True, + help_text="Total monetary contributions (from line 1, column A)", + ) + loans_received = models.IntegerField( + verbose_name='loans received', + null=True, + help_text="Total loans received (from line 2, column A)", + ) + subtotal_cash_contributions = models.IntegerField( + verbose_name='subtotal cash contributions', + null=True, + help_text="Monetary contributions and loans received combined (from " + "line 3, column A)", + ) + nonmonetary_contributions = models.IntegerField( + verbose_name='nonmonetary contributions', + null=True, + help_text="Non-monetary contributions (from line 4, column A)", + ) + total_contributions = models.IntegerField( + verbose_name='total contributions', + null=True, + help_text="Total contributions (from line 5, column A)", + ) + payments_made = models.IntegerField( + verbose_name='payments made', + null=True, + help_text="Payments made (from line 6, column A)", + ) + loans_made = models.IntegerField( + verbose_name='loans made', + null=True, + help_text="Loans made (from line 7, column A)", + ) + subtotal_cash_payments = models.IntegerField( + verbose_name='subtotal cash payments', + null=True, + help_text="Sub-total of cash payments (from line 8, column A)", + ) + unpaid_bills = models.IntegerField( + verbose_name='unpaid bills', + null=True, + help_text="Unpaid bills / accrued expenses (from line 9, column A)", + ) + nonmonetary_adjustment = models.IntegerField( + verbose_name='nonmonetary adjustment', + null=True, + help_text="Non-monetary adjustment (from line 10, column A), which is " + "equal to the total of non-monetary contributions", + ) + total_expenditures_made = models.IntegerField( + verbose_name='total expenditures made', + null=True, + help_text="Total expenditures made (from line 11, column A)", + ) + begin_cash_balance = models.IntegerField( + verbose_name='begin cash balance', + null=True, + help_text="Beginning cash balance (from line 12), which is equal to " + "the Ending Cash Balance (line 16) reported on the summary " + "page of the previous Form 460 filing" + ) + cash_receipts = models.IntegerField( + verbose_name='cash receipts', + null=True, + help_text="Cash receipts (from line 13)", + ) + miscellaneous_cash_increases = models.IntegerField( + verbose_name='miscellaneous cash increases', + null=True, + help_text="Miscellaneous cash increases (from line 14)", + ) + cash_payments = models.IntegerField( + verbose_name='cash payments', + null=True, + help_text="Cash payments (from line 15)", + ) + ending_cash_balance = models.IntegerField( + verbose_name='ending cash balance', + null=True, + help_text="Ending cash balance (from line 16)", + ) + loan_guarantees_received = models.IntegerField( + verbose_name='loan guarantees received', + null=True, + help_text="Loan guarantees received (from line 17)", + ) + cash_equivalents = models.IntegerField( + verbose_name='cash equivalents', + null=True, + help_text="Cash equivalents (from line 18), which includes investments " + "that can't be readily converted to cash, such as outstanding " + "loans the committee has made to others" + ) + outstanding_debts = models.IntegerField( + verbose_name='outstanding debts', + null=True, + help_text="Outstanding debts on loans owed by the committee (from line " + "19)", + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460Filing(Form460FilingBase): + """ + The most recent version of each Form 460 filing by recipient committees. + + Form 460 is the Campaign Disclosure Statement filed by all recipient + committees, including: + * Candidates, officeholders and their controlled committees + * Primarily formed ballot measure committees + * Primarily formed candidate/of ceholder committees + * General purpose committees + + Recipient committes can use Form 460 to file: + * Pre-election statements + * Semi-annual statements + * Quarterly statements + * Termination statements + * Special odd-year report + + Includes information from the cover sheet and summary page of the most + recent version of each Form 460 filing. All versions of the filings can be + found in Form460FilingVersion. + """ + filing_id = models.IntegerField( + verbose_name='filing id', + primary_key=True, + null=False, + help_text='Unique identification number for the Form 460 filing (' + 'from CVR_CAMPAIGN_DISCLOSURE_CD.FILING_ID)', + ) + amendment_count = models.IntegerField( + verbose_name='Count amendments', + db_index=True, + null=False, + help_text='Number of amendments to the Form 460 filing (from ' + 'maximum value of CVR_CAMPAIGN_DISCLOSURE_CD.AMEND_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + index_together = (( + 'filing_id', + 'amendment_count', + ),) + + def __str__(self): + return str(self.filing_id) + + +@python_2_unicode_compatible +class Form460FilingVersion(Form460FilingBase): + """ + Every version of each Form 460 (Campaign Disclosure Statement) filing by recipient committees. + + Includes information found on the cover sheet and summary page of each + version of each Form 460 filing. For the most recent version of each filing, + see Form460Filing. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='versions', + db_constraint=False, + null=True, + on_delete=models.SET_NULL, + help_text='Unique identification number for the Form 460 filing (' + 'from CVR_CAMPAIGN_DISCLOSURE_CD.FILING_ID)', + ) + amend_id = models.IntegerField( + verbose_name='amendment id', + null=False, + help_text='Identifies the version of the Form 497 filing, with 0 ' + 'representing the initial filing (from CVR_CAMPAIGN_' + 'DISCLOSURE_CD.AMEND_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'amend_id', + ),) + index_together = (( + 'filing', + 'amend_id', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.amend_id) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/__init__.py b/calaccess_processed/models/campaign/filings/form460/schedules/__init__.py new file mode 100644 index 00000000..50cf2039 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Import all of the admins from submodules and thread them together. +""" diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/a.py b/calaccess_processed/models/campaign/filings/form460/schedules/a.py new file mode 100644 index 00000000..d8a38e94 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/a.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignContributionBase + + +class Form460ScheduleAItemBase(CampaignContributionBase): + """ + Abstract base model for items reported on Schedule A of Form 460 filings. + + On Schedule A, campaign filers are required to itemize monetary + contributions received during the period covered by the filing. + """ + amount = models.DecimalField( + verbose_name='amount', + decimal_places=2, + max_digits=14, + help_text="Amount received from the contributor in the period covered " + "by the filing (from RCPT_CD.AMOUNT)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleAItem(Form460ScheduleAItemBase): + """ + Monetary contributions received by campaign filers. + + These transactions are itemized on Schedule A of the most recent version + of each Form 460 filing. For monetary contributions itemized on any version + of any Form 460 filing, see Form460ScheduleAItemVersion. + + Also includes contributions transferred to special election commitees, + which were itemized on Schedule A-1 until around 2001. + + Derived from RCPT_CD records where FORM_TYPE is 'A' or 'A-1'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_a_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the monetary' + ' contribution was reported (from RCPT_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleAItemVersion(Form460ScheduleAItemBase): + """ + Every version of each monetary contribution received by a campaign filer. + + For monetary contributions itemized on Schedule A of the most recent + version of each Form 460 filing, see Form460ScheduleAItem. + + Derived from RCPT_CD records where FORM_TYPE is 'A' or 'A-1'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_a_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the received contribution' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/b.py b/calaccess_processed/models/campaign/filings/form460/schedules/b.py new file mode 100644 index 00000000..c4b2d264 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/b.py @@ -0,0 +1,552 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignLoanReceivedItemBase + + +class Form460ScheduleB1ItemBase(CampaignLoanReceivedItemBase): + """ + Abstract base model for items reported on Schedule B, Part 1, of Form 460. + + On Schedule B, Part 1, campaign filers are required to report loans + received or outstanding during the period covered by the filing. + """ + begin_period_balance = models.DecimalField( + verbose_name='beginning period balance', + decimal_places=2, + max_digits=14, + help_text="Outstanding balance of the loan at the beginning of the" + "period covered by the filing (from LOAN_CD.LOAN_AMT4)" + ) + amount_received = models.DecimalField( + verbose_name='amount received', + decimal_places=2, + max_digits=14, + help_text="Amount received during the period covered by the filing " + "(from LOAN_CD.LOAN_AMT1)" + ) + amount_paid = models.DecimalField( + verbose_name='amount paid', + decimal_places=2, + max_digits=14, + help_text="Amount paid back during the period covered by the filing " + "(from LOAN_CD.LOAN_AMT5)" + ) + amount_forgiven = models.DecimalField( + verbose_name='amount forgiven', + decimal_places=2, + max_digits=14, + help_text="Amount forgiven by the lender during the period covered by " + "the filing (from LOAN_CD.LOAN_AMT6)" + ) + end_period_balance = models.DecimalField( + verbose_name='end period balance', + decimal_places=2, + max_digits=14, + help_text="Outstanding balance of the loan at the end of the period " + "covered by the filing (from LOAN_CD.LOAN_AMT2)" + ) + date_due = models.DateField( + verbose_name='date due', + null=True, + help_text="Date that the loan is due (from LOAN_CD.LOAN_DATE2)" + ) + interest_paid = models.DecimalField( + verbose_name='interest paid', + decimal_places=2, + max_digits=14, + help_text="Amount of interest paid on the loan during the period " + "covered by the campaign filing (from LOAN_CD.LOAN_AMT7)" + ) + original_amount = models.DecimalField( + verbose_name='original amount', + decimal_places=2, + max_digits=14, + help_text="Original amount loaned by the lender to the campaign filer " + "(from LOAN_CD.LOAN_AMT8)" + ) + date_incurred = models.DateField( + verbose_name='date incurred', + null=True, + help_text="Date the loan was made or received (from LOAN_CD.LOAN_DATE1)" + ) + cumulative_ytd_contributions = models.DecimalField( + verbose_name='cumulative year-to-date contributions', + decimal_places=2, + max_digits=14, + help_text="Cumulative amount of contributions (loans, monetary and " + "nonmonetary contributions) received from the lender during " + "the calendar year covered by this statement (from LOAN_CD." + "LOAN_AMT3)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleB1Item(Form460ScheduleB1ItemBase): + """ + Loans received and loan payments by campaign filers. + + These transactions are itemized on Schedule B, Part 1, of the most recent + version of each Form 460 filing. For loans itemized on any version of any + Form 460 filing, see Form460ScheduleB1ItemVersion. + + Derived from LOAN_CD records where FORM_TYPE is 'B1'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_b1_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the loan ' + 'was reported (from LOAN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleB1ItemVersion(Form460ScheduleB1ItemBase): + """ + Every version of each loan received or loan payment made by a campaign filer. + + For outstanding loans itemized on Schedule B, Part 1, of the most recent + version of each Form 460 filing, see Form460ScheduleB1Item. + + Derived from LOAN_CD records where FORM_TYPE is 'B1'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_b1_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the outstanding loan' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) + + +class Form460ScheduleB2ItemBase(models.Model): + """ + Abstract base model for items reported on Schedule B, Part 2, of Form 460. + + On Schedule B, Part 2, campaign filers are required to report loan + guarantors, A "guarantor" is a third party that co-signs, endorses, or + provides security for a loan, or establishes or provides security for a + line of credit. A guarantor is also making a contribution. + """ + line_item = models.IntegerField( + verbose_name='line item', + help_text="Line number of the filing form where the loan is " + "itemized (from LOAN_CD.LINE_ITEM)", + ) + GUARANTOR_CODE_CHOICES = ( + ('COM', "Committee"), + ('IND', "Individual"), + ('OTH', "Other"), + ('PTY', "Political Party"), + ('SCC', "Small Contributor Committee"), + ('???', "Unknown value"), + ) + guarantor_code = models.CharField( + verbose_name='lender code', + max_length=3, + blank=True, + choices=GUARANTOR_CODE_CHOICES, + help_text='Code describing the guarantor (from LOAN_CD.ENTITY_CD)', + ) + guarantor_title = models.CharField( + verbose_name='guarantor title', + max_length=10, + blank=True, + help_text="Name title of the guarantor (from LOAN_CD.LNDR_NAMT)", + ) + guarantor_lastname = models.CharField( + verbose_name='guarantor lastname', + max_length=200, + blank=True, + help_text="Last name of the guarantor or business name (from LOAN_CD." + "LNDR_NAML)", + ) + guarantor_firstname = models.CharField( + verbose_name='guarantor firstname', + max_length=45, + blank=True, + help_text="First name of the guarantor (from LOAN_CD.LNDR_NAMF)", + ) + guarantor_name_suffix = models.CharField( + verbose_name='guarantor name suffix', + max_length=10, + blank=True, + help_text="Name suffix of the guarantor (from LOAN_CD.LNDR_NAMS)", + ) + guarantor_city = models.CharField( + verbose_name='guarantor city', + max_length=30, + blank=True, + help_text='City of the guarantor (from LOAN_CD.LOAN_CITY)', + ) + guarantor_state = models.CharField( + verbose_name='guarantor state', + max_length=2, + blank=True, + help_text='State of the guarantor (from LOAN_CD.LOAN_ST)', + ) + guarantor_zip = models.CharField( + verbose_name='guarantor zip', + max_length=10, + blank=True, + help_text='Zip code (usually zip5, sometimes zip9) of the ' + 'guarantor (from LOAN_CD.LOAN_ZIP4)', + ) + guarantor_employer = models.CharField( + verbose_name='guarantor employer', + max_length=200, + blank=True, + help_text='Employer of the guarantor (from LOAN_CD.LOAN_EMP)', + ) + guarantor_occupation = models.CharField( + verbose_name='guarantor occupation', + max_length=60, + blank=True, + help_text='Occupation of the guarantor (from LOAN_CD.LOAN_OCC)', + ) + guarantor_is_self_employed = models.BooleanField( + verbose_name='guarantor is self employed', + default=False, + help_text='Indicates whether or not the guarantor is self-employed' + '(from LOAN_CD.LOAN_SELF)', + ) + lender_name = models.CharField( + verbose_name='lender name', + max_length=200, + blank=True, + help_text="Name of the lender (from LOAN_CD.INTR_NAML)" + ) + amount_guaranteed_this_period = models.DecimalField( + verbose_name='amount guaranteed this period', + decimal_places=2, + max_digits=14, + help_text="Amount guaranteed for the period covered by the filing " + "(from LOAN_CD.LOAN_AMT1)" + ) + balance_outstanding_to_date = models.DecimalField( + verbose_name='balance outstanding to date', + decimal_places=2, + max_digits=14, + help_text="Outstanding balance for which the guarantor is liable at " + "the close of the reporting period (from LOAN_CD.LOAN_AMT2)" + ) + cumulative_ytd_amount = models.DecimalField( + verbose_name='cumulative year-to-date amount', + decimal_places=2, + max_digits=14, + help_text="Cumulative amount guaranteed during the calendar year " + "covered by the statement (from LOAN_CD.LOAN_AMT3)" + ) + loan_date = models.DateField( + verbose_name='loan date', + null=True, + help_text="Date of the loan or date the line of credit was established" + "(from LOAN_CD.LOAN_DATE1)" + ) + interest_rate = models.CharField( + verbose_name='interest rate', + max_length=30, + blank=True, + help_text='Interest rate of the loan. This is sometimes expressed as a ' + 'decimal (e.g., 0.10) and other times as a percent (e.g., ' + '10.0% (from LOAN_CD.LOAN_RATE)' + ) + transaction_id = models.CharField( + verbose_name='transaction id', + max_length=20, + help_text='Identifies a unique transaction across versions of the a ' + 'given Form 460 filing (from LOAN_CD.TRAN_ID)', + ) + memo_reference_number = models.CharField( + verbose_name='memo reference number', + max_length=20, + blank=True, + help_text="A value assigned by the filer which refers to the item's" + "footnote in the TEXT_MEMO_CD table (from LOAN_CD." + "MEMO_REFNO)", + ) + reported_on_b1 = models.BooleanField( + verbose_name='reported on B1', + default=False, + help_text='Indicates if the item was actually reported on Part 1 of ' + 'Schedule B. Until 2001, campaign filers were required to ' + 'report guarantors of loans or lines of credit on Part 1 of ' + 'Schedule B.' + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleB2Item(Form460ScheduleB2ItemBase): + """ + Guarantees of loans and lines of credit received by campaign filers. + + These transactions are itemized on Schedule B, Part 2, of the most recent + version to each Form 460 filing. For guarantees itemized on + any version of any Form 460 filing, see Form460ScheduleB2ItemVersion. + + Derived from LOAN_CD records where FORM_TYPE is 'B2'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_b2_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the loan ' + 'was reported (from LOAN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleB2ItemVersion(Form460ScheduleB2ItemBase): + """ + Every version of each guarantee of a loan/line of credit to a campaign filer. + + For guaratees itemized on Schedule B, Part 1, of the most recent + version of each Form 460 filing, see Form460ScheduleB2Item. + + Derived from LOAN_CD records where FORM_TYPE is 'B2'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_b2_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the outstanding loan' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) + + +class Form460ScheduleB2ItemBaseOld(CampaignLoanReceivedItemBase): + """ + Abstract base model for Schedule B, Part 2, items from Form 460 circa 2001. + + Until Form 460 was modified in 2001, campaign filers were required to report + repayments made on loans received, loans forgiven, and loans repaid by a + third party on Part 2 of Schedule B. + """ + date_repaid_or_forgiven = models.DateField( + verbose_name='date paid or forgiven', + null=True, + help_text="Date when the loan repayment or forgiveness occurred (from " + "LOAN_CD.LOAN_DATE2)" + ) + date_of_original_loan = models.DateField( + verbose_name='date of original loan', + null=True, + help_text="Date the loan was orginally made (from LOAN_CD.LOAN_DATE1)" + ) + REPAYMENT_TYPE_CHOICES = ( + ('B2F', 'Forgiven'), + ('B2R', 'Repay'), + ('B2T', 'Third party payment'), + ) + repayment_type = models.CharField( + verbose_name='repayment type', + max_length=3, + choices=REPAYMENT_TYPE_CHOICES, + help_text='Indicates whether the item is a loan repayment by the ' + 'campaign filer, a repayment by a third-party or a loan ' + 'forgiveness by the lender (from LOAN_CD.LOAN_TYPE)', + ) + amount_repaid_or_forgiven = models.DecimalField( + verbose_name='amount repaid or forgiven', + decimal_places=2, + max_digits=14, + help_text="Amount paid back or forgiven during the period covered by " + "the filing (from LOAN_CD.LOAN_AMT1)" + ) + outstanding_principle = models.DecimalField( + verbose_name='outstanding principle', + decimal_places=2, + max_digits=14, + help_text="Outstanding principle of the loan at the end of the period " + "covered by the filing (from LOAN_CD.LOAN_AMT2)" + ) + interest_paid = models.DecimalField( + verbose_name='interest paid', + decimal_places=2, + max_digits=14, + help_text="Amount of interest paid on the loan during the period " + "covered by the campaign filing (from LOAN_CD.LOAN_AMT3)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleB2ItemOld(Form460ScheduleB2ItemBaseOld): + """ + Repayments on loans/forgiven loans received by campaign filers circa 2001. + + These transactions are itemized on Schedule B, Part 2, of the most recent + version to each Form 460 filing in the pre-2001 format. For loan repayments + and forgiven loans on any version of any Form 460 filing in the pre-2001 + format, see Form460ScheduleB2ItemVersionOld. + + Derived from LOAN_CD records where LOAN_TYPE is not blank or LOAN_DATE1 is + before December 22, 2000. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_b2_items_old', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the loan ' + 'transaction was reported (from LOAN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + verbose_name_plural = "Form460 schedule b2 items old" + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleB2ItemVersionOld(Form460ScheduleB2ItemBaseOld): + """ + Every version of each repayment/forgiveness of a loan to a campaign filer circa 2001. + + For loan repayments and forgiven loans on any version of any Form 460 filing + in the pre-2001 format, see Form460ScheduleB2ItemOld. + + Derived from LOAN_CD records where LOAN_TYPE is not blank or LOAN_DATE1 is + before December 22, 2000. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_b2_items_old', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the loan transaction' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + verbose_name_plural = "Form460 schedule b2 item versions old" + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/c.py b/calaccess_processed/models/campaign/filings/form460/schedules/c.py new file mode 100644 index 00000000..4bfb38ff --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/c.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignContributionBase + + +class Form460ScheduleCItemBase(CampaignContributionBase): + """ + Abstract base model for items reported on Schedule C of Form 460 filings. + + On Schedule C, campaign filers are required to itemize nonmonetary + contributions received during the period covered by the filing. + """ + fair_market_value = models.DecimalField( + verbose_name='fair market value', + decimal_places=2, + max_digits=14, + help_text="Amount it would cost to purchase the donated goods or " + "services on the open market (from RCPT_CD.AMOUNT)" + ) + contribution_description = models.CharField( + max_length=90, + blank=True, + help_text="Description of the contributed goods or services (from " + "RCPT_CD.CTRIB_DSCR)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleCItem(Form460ScheduleCItemBase): + """ + Nonmonetary contributions received by campaign filers. + + These transactions are itemized on Schedule C of the most recent version + of each Form 460 filing. For nonmonetary contributions itemized on any + version of any Form 460 filing, see Form460ScheduleCItemVersion. + + Derived from RCPT_CD records where FORM_TYPE is 'C'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_c_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the monetary' + ' contribution was reported (from RCPT_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleCItemVersion(Form460ScheduleCItemBase): + """ + Every version of each nonmonetary contribution received by a campaign filer. + + For nonmonetary contributions itemized on Schedule C of the most recent + version of each Form 460 filing, see Form460ScheduleCItem. + + Derived from RCPT_CD records where FORM_TYPE is 'C'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_c_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the received contribution' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/d.py b/calaccess_processed/models/campaign/filings/form460/schedules/d.py new file mode 100644 index 00000000..1aeea257 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/d.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignExpenditureItemBase + + +class Form460ScheduleDItemBase(CampaignExpenditureItemBase): + """ + Abstract base model for items reported on Schedule D of Form 460 filings. + + On Schedule D, campaign filers are required to summarize contributions + and independent expenditures in support or opposition to other candidates + and ballot measures. + """ + cumulative_election_amount = models.DecimalField( + decimal_places=2, + max_digits=14, + null=True, + help_text="If the candidate is subject to contribution limits, the " + "cumulative amount given by the filer during the election " + "cycle as of the Form 460's filing date (from EXPN_CD." + "CUM_OTH)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleDItem(Form460ScheduleDItemBase): + """ + Payments in support or opposition of other candidates and ballot measures. + + These transactions are itemized on Schedule D of the most recent version + of each Form 460 filing. For payments itemized on any version of any Form + 460 filing, see Form460ScheduleDItemVersion. + + Derived from EXPN_CD records where FORM_TYPE is 'D'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_d_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the ' + 'payment was reported (from EXPN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleDItemVersion(Form460ScheduleDItemBase): + """ + Every version of each payment supporting/opposing another candidate/ballot measure. + + For payments itemized on Schedule D of the most recent version of each Form + 460 filing, see Form460ScheduleDItem. + + Derived from EXPN_CD records where FORM_TYPE is 'D'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_d_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the payment made' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/e.py b/calaccess_processed/models/campaign/filings/form460/schedules/e.py new file mode 100644 index 00000000..5cf166b0 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/e.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import ( + CampaignExpenditureItemBase, + CampaignExpenditureSubItemBase, +) + + +@python_2_unicode_compatible +class Form460ScheduleEItem(CampaignExpenditureItemBase): + """ + Payments made by campaign filers. + + These transactions are itemized on Schedule E of the most recent version + of each Form 460 filing. For payments itemized on any version of any + filing, see Form460ScheduleEItemVersion. + + Does not include: + * Interest paid on loans received + * Loans made to others + * Transfers of campaign funds into savings accounts + * Payments made by agents or contractors on behalf of the filer + * Certificates of deposit + * Money market accounts + * Purchases of other assets that can readily be converted to cash + + Derived from EXPN_CD records where FORM_TYPE is 'E'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_e_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the ' + 'payment was reported (from EXPN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleEItemVersion(CampaignExpenditureItemBase): + """ + Every version of each payment made by a campaign filer. + + For payments itemized on Schedule E of the most recent version of each Form + 460 filing, see Form460ScheduleEItem. + + Does not include: + * Interest paid on loans received + * Loans made to others + * Transfers of campaign funds into savings accounts + * Payments made by agents or contractors on behalf of the filer + * Certificates of deposit + * Money market accounts + * Purchases of other assets that can readily be converted to cash + + Derived from EXPN_CD records where FORM_TYPE is 'E'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_e_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the payment made' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) + + +@python_2_unicode_compatible +class Form460ScheduleESubItem(CampaignExpenditureSubItemBase): + """ + Sub-items of payments made by campaign filers. + + These transactions are itemized on Schedule E of the most recent version + of each Form 460 filing. For sub-item payments on any version of any Form + 460 filing, see Form460ScheduleESubItemVersion. + + A sub-item is a transaction where the amount is lumped into another + "parent" payment reported elsewhere on the filing. + + Includes: + * Payments supporting or opposing other candidates, ballot measures + or committees, which are summarized on Schedule D + * Payments made to vendors over $100 included in credit card payments + * Payments made by agents or independent contractors on behalf of the + campaign filer which were reported on Schedule E instead of G + * Payments made on the accrued expenses reported on Schedule F + + Derived from EXPN_CD records where FORM_TYPE is 'E' and MEMO_CODE is not + blank. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_e_subitems', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the ' + 'payment was reported (from EXPN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleESubItemVersion(CampaignExpenditureSubItemBase): + """ + Every version of each sub-item of a payment by a campaign filer. + + For payments sub-itemized on Schedule E of the most recent version of each + Form 460 filing, see Form460ScheduleESubItem. + + A sub-item is a transaction where the amount is lumped into another + "parent" payment reported elsewhere on the filing. + + Includes: + * Payments supporting or opposing other candidates, ballot measures + or committees, which are summarized on Schedule D + * Payments made to vendors over $100 included in credit card payments + * Payments made by agents or independent contractors on behalf of the + campaign filer which were reported on Schedule E instead of G + * Payments made on the accrued expenses reported on Schedule F + + Derived from EXPN_CD records where FORM_TYPE is 'E' and MEMO_CODE is not + blank. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_e_subitems', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the payment made' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/f.py b/calaccess_processed/models/campaign/filings/form460/schedules/f.py new file mode 100644 index 00000000..508293cb --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/f.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager + + +class Form460ScheduleFItemBase(models.Model): + """ + Abstract base model for items reported on Schedule F of Form 460 filings. + + On Schedule F, campaign filers report unpaid bills for goods or services + accrued during the period covered by the filing. + """ + line_item = models.IntegerField( + verbose_name='line item', + help_text="Line number of the filing form where the unpaid bill is " + "itemized (from DEBT_CD.LINE_ITEM)", + ) + PAYEE_CODE_CHOICES = ( + ('BNM', "Ballot measure's name/title"), + ('COM', "Committee"), + ('IND', "Individual"), + ('OTH', "Other"), + ('PTY', "Political Party"), + ('RCP', "Recipient committee"), + ('SCC', "Small Contributor Committee"), + ('???', "Unknown value"), + ) + payee_code = models.CharField( + verbose_name='payee code', + max_length=3, + blank=True, + choices=PAYEE_CODE_CHOICES, + help_text='Code describing the payee (from DEBT_CD.ENTITY_CD)', + ) + payee_committee_id = models.CharField( + verbose_name='committee id', + max_length=9, + blank=True, + help_text="Payee's filer identification number, if it is a " + "committee (from DEBT_CD.CMTE_ID)", + ) + payee_title = models.CharField( + verbose_name='payee title', + max_length=10, + blank=True, + help_text='Name title of the payee (from DEBT_CD.PAYEE_NAMT)', + ) + payee_lastname = models.CharField( + verbose_name='payee lastname', + max_length=200, + blank=True, + help_text='Last name of the payee or business name (from ' + 'DEBT_CD.PAYEE_NAML)', + ) + payee_firstname = models.CharField( + verbose_name='payee firstname', + max_length=45, + help_text='First name of the payee (from DEBT_CD.PAYEE_NAMF)', + ) + payee_name_suffix = models.CharField( + verbose_name='payee name suffix', + max_length=10, + blank=True, + help_text='Name suffix of the payee (from DEBT_CD.PAYEE_NAMS)', + ) + payee_city = models.CharField( + verbose_name='payee city', + max_length=30, + blank=True, + help_text='City of the payee (from DEBT_CD.PAYEE_CITY)', + ) + payee_state = models.CharField( + verbose_name='payee state', + max_length=2, + blank=True, + help_text='State of the payee (from DEBT_CD.PAYEE_ST)', + ) + payee_zip = models.CharField( + verbose_name='payee zip', + max_length=10, + blank=True, + help_text='Zip code (usually zip5, sometimes zip9) of the ' + 'payee (from DEBT_CD.PAYEE_ZIP4)', + ) + treasurer_title = models.CharField( + verbose_name='treasurer title', + max_length=10, + blank=True, + help_text="Name title of the payee committee's treasurer (from " + "DEBT_CD.TRES_NAMT)", + ) + treasurer_lastname = models.CharField( + verbose_name='treasurer lastname', + max_length=200, + blank=True, + help_text="Last name of the payee committee's treasurer (from " + "DEBT_CD.TRES_NAML)", + ) + treasurer_firstname = models.CharField( + verbose_name='treasurer firstname', + max_length=45, + help_text="First name of the payee committee's treasurer (from " + "DEBT_CD.TRES_NAMF)", + ) + treasurer_name_suffix = models.CharField( + verbose_name='treasurer name suffix', + max_length=10, + blank=True, + help_text="Name suffix of the payee committee's treasurer (from " + "DEBT_CD.TRES_NAMS)", + ) + treasurer_city = models.CharField( + verbose_name='treasurer city', + max_length=30, + blank=True, + help_text="City of the payee committee's treasurer (from DEBT_CD." + "TRES_CITY)", + ) + treasurer_state = models.CharField( + verbose_name='treasurer state', + max_length=2, + blank=True, + help_text="State of the payee committee's treasurer (from DEBT_CD." + "TRES_ST)", + ) + PAYMENT_CODE_CHOICES = ( + ('CMP', 'Campaign paraphernalia/miscellaneous'), + ('CNS', 'Campaign consultants'), + ('CTB', 'Contribution (if nonmonetary, explain)*'), + ('CVC', 'Civic donations'), + ('FIL', 'Candidate filing/ballot feeds'), + ('FND', 'Fundraising events'), + ('IKD', 'In-kind contribution (nonmonetary)'), + ('IND', 'Independent expenditure supporting/opposing others (explain)*'), + ('LEG', 'Legal defense'), + ('LIT', 'Campaign literature and mailings'), + ('LON', 'Loan'), + ('MBR', 'Member communications'), + ('MON', 'Monetary contribution'), + ('MTG', 'Meetings and appearances'), + ('OFC', 'Office expenses'), + ('PET', 'Petition circulating'), + ('PHO', 'Phone banks'), + ('POL', 'Polling and survey research'), + ('POS', 'Postage, delivery and messenger services'), + ('PRO', 'Professional services (legal, accounting)'), + ('PRT', 'Print ads'), + ('RAD', 'Radio airtime and production costs'), + ('RFD', 'Returned contributions'), + ('SAL', 'Campaign workers salaries'), + ('TEL', 'T.V. or cable airtime and production costs'), + ('TRC', 'Candidate travel, lodging and meals (explain)'), + ('TRS', 'Staff/spouse travel, lodging and meals (explain)'), + ('TSF', 'Transfer between committees of the same candidate/sponsor'), + ('VOT', 'Voter registration'), + ('WEB', 'Information technology costs (internet, e-mail)'), + ('???', "Unknown value"), + ) + payment_code = models.CharField( + verbose_name='payment code', + max_length=3, + blank=True, + choices=PAYMENT_CODE_CHOICES, + help_text='Code describing the payment (from DEBT_CD.EXPN_CODE)', + ) + payment_description = models.CharField( + verbose_name="payment description", + max_length=400, + blank=True, + help_text="Purpose of payment and/or description/explanation (from " + "DEBT_CD.EXPN_DSCR)", + ) + begin_balance = models.DecimalField( + verbose_name="begin balance", + decimal_places=2, + max_digits=14, + help_text="Outstanding balance at the beginning of period covered by " + "the filing (from DEBT_CD.BEG_BAL)", + ) + amount_paid = models.DecimalField( + decimal_places=2, + max_digits=14, + help_text='Amount paid this period (from DEBT_CD.AMT_PAID)' + ) + amount_incurred = models.DecimalField( + verbose_name="amount incurred", + decimal_places=2, + max_digits=14, + help_text='Amount incurred this period (from DEBT_CD.AMT_INCUR)', + ) + end_balance = models.DecimalField( + verbose_name="end balance", + decimal_places=2, + max_digits=14, + help_text="Outstanding balance at the end of period covered by the " + "filing (from DEBT_CD.END_BAL)", + ) + transaction_id = models.CharField( + verbose_name='transaction id', + max_length=20, + help_text='Identifies a unique transaction across versions of the a ' + 'given Form 460 filing (from DEBT_CD.TRAN_ID)', + ) + parent_transaction_id = models.CharField( + verbose_name='parent transaction id', + max_length=20, + blank=True, + help_text='Refers to a parent transaction itemized on the same Form ' + '460 filing (from DEBT_CD.BAKREF_TID)', + ) + memo_reference_number = models.CharField( + verbose_name='memo reference number', + max_length=20, + blank=True, + help_text="A value assigned by the filer which refers to the item's" + "footnote in the TEXT_MEMO_CD table (from DEBT_CD." + "MEMO_REFNO)", + ) + memo_code = models.BooleanField( + verbose_name='memo_code', + default=False, + help_text="Memo amount flag (from DEBT_CD.MEMO_CODE)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleFItem(Form460ScheduleFItemBase): + """ + Accrued expenses of campaign filers. + + These transactions are itemized on Schedule F of the most recent version + of each Form 460 filing. For accrued expenses itemized on any version of + of any Form 460 filing, see Form460ScheduleFItemVersion. + + Derived from DEBT_CD records. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_f_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the ' + 'payment was reported (from DEBT_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleFItemVersion(Form460ScheduleFItemBase): + """ + Every version of each accrued expense of a campaign filer. + + For accrued expenses itemized on Schedule F of the most recent version of + each Form 460 filing, see Form460ScheduleGItem. + + Derived from DEBT_CD records. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_f_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the Schedule F items' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/g.py b/calaccess_processed/models/campaign/filings/form460/schedules/g.py new file mode 100644 index 00000000..23c57999 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/g.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignExpenditureSubItemBase + + +class Form460ScheduleGItemBase(CampaignExpenditureSubItemBase): + """ + Abstract base model for items reported on Schedule G of Form 460 filings. + + On Schedule G, campaign filers are required to itemize payments made on + their behalf by agents or contractors during the period covered by the + filing. + """ + agent_title = models.CharField( + verbose_name='agent title', + max_length=10, + blank=True, + help_text='Name title of the agent (from EXPN_CD.AGENT_NAMT)', + ) + agent_lastname = models.CharField( + verbose_name='agent lastname', + max_length=200, + blank=True, + help_text='Last name of the agent or business name (from ' + 'EXPN_CD.AGENT_NAML)', + ) + agent_firstname = models.CharField( + verbose_name='agent firstname', + max_length=45, + help_text='First name of the agent (from EXPN_CD.AGENT_NAMF)', + ) + agent_name_suffix = models.CharField( + verbose_name='agent name suffix', + max_length=10, + blank=True, + help_text='Name suffix of the agent (from EXPN_CD.AGENT_NAMS)', + ) + PARENT_SCHEDULE_CHOICES = ( + ('E', 'Schedule E: Payments Made'), + ('F', 'Schedule F: Accrued Expenses (Unpaid Bills)') + ) + parent_schedule = models.CharField( + max_length=1, + blank=True, + help_text="Indicates which schedule (E or F) includes the parent item " + "(from EXPN_CD.G_FROM_E_F)", + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleGItem(Form460ScheduleGItemBase): + """ + Payments made by on behalf of campaign filers. + + These transactions are itemized on Schedule G of the most recent version + of each Form 460 filing. For payments itemized on any version of any Form + 460 filing, see Form460schedulegitemversion. + + Derived from EXPN_CD records where FORM_TYPE is 'G'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_g_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the ' + 'payment was reported (from RCPT_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleGItemVersion(Form460ScheduleGItemBase): + """ + Every version of each payment made on behalf of a campaign filer. + + For payments itemized on Schedule G of the most recent version of each Form + 460 filing, see Form460ScheduleGitem. + + Derived from EXPN_CD records where FORM_TYPE is 'G'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_g_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the payment made' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/h.py b/calaccess_processed/models/campaign/filings/form460/schedules/h.py new file mode 100644 index 00000000..e35f4906 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/h.py @@ -0,0 +1,314 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignLoanMadeItemBase + + +class Form460ScheduleHItemBase(CampaignLoanMadeItemBase): + """ + Abstract base model for items reported on Schedule H of Form 460. + + On Schedule H, campaign filers are required to report loans made or + currently outstanding to other recipients during the period covered by the + filing. + """ + begin_period_balance = models.DecimalField( + verbose_name='beginning period balance', + decimal_places=2, + max_digits=14, + help_text="Outstanding balance of the loan at the beginning of the" + "period covered by the filing (from LOAN_CD.LOAN_AMT4)" + ) + amount_loaned = models.DecimalField( + verbose_name='amount loaned', + decimal_places=2, + max_digits=14, + help_text="Amount loaned during the period covered by the filing " + "(from LOAN_CD.LOAN_AMT1)" + ) + amount_paid = models.DecimalField( + verbose_name='amount paid', + decimal_places=2, + max_digits=14, + help_text="Amount paid back during the period covered by the filing " + "(from LOAN_CD.LOAN_AMT5)" + ) + amount_forgiven = models.DecimalField( + verbose_name='amount forgiven', + decimal_places=2, + max_digits=14, + help_text="Amount forgiven by the campaign filer during the period " + "covered by the filing (from LOAN_CD.LOAN_AMT6)" + ) + end_period_balance = models.DecimalField( + verbose_name='end period balance', + decimal_places=2, + max_digits=14, + help_text="Outstanding balance of the loan at the end of the period " + "covered by the filing (from LOAN_CD.LOAN_AMT2)" + ) + date_due = models.DateField( + verbose_name='date due', + null=True, + help_text="Date that the loan is due (from LOAN_CD.LOAN_DATE2)" + ) + interest_received = models.DecimalField( + verbose_name='interest paid', + decimal_places=2, + max_digits=14, + help_text="Amount of interest paid on the loan during the period " + "covered by the campaign filing (from LOAN_CD.LOAN_AMT7)" + ) + original_amount = models.DecimalField( + verbose_name='original amount', + decimal_places=2, + max_digits=14, + help_text="Original amount loaned by the lender to the campaign filer " + "(from LOAN_CD.LOAN_AMT8)" + ) + date_incurred = models.DateField( + verbose_name='date incurred', + null=True, + help_text="Date the loan was made or received (from LOAN_CD.LOAN_DATE1)" + ) + cumulative_ytd_contributions = models.DecimalField( + verbose_name='cumulative year-to-date contributions', + decimal_places=2, + max_digits=14, + help_text="Cumulative amount of contributions (loans, monetary and " + "nonmonetary contributions) from the campaign filer to the " + "recipient during the calendar year covered by this statement" + " (from LOAN_CD.LOAN_AMT3)" + ) + reported_on_h1 = models.BooleanField( + verbose_name='reported on H1', + default=False, + help_text='Indicates if the item was actually reported on Part 1 of ' + 'Schedule H. Until 2001, campaign filers were required to ' + 'report loans made to others on Part 1 of Schedule H, ' + 'separate from repayments or forgiveness of those loans ' + '(Schedule H, Part 2)' + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleHItem(Form460ScheduleHItemBase): + """ + Loans made by campaign filers to other recipients. + + These transactions are itemized on Schedule H of the most recent version of + each Form 460 filing. For loans itemized on any version of any Form 460 + filing, see Form460ScheduleHItemVersion. + + Derived from LOAN_CD records where FORM_TYPE is 'H' or 'H1'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_h_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the loan ' + 'was reported (from LOAN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleHItemVersion(Form460ScheduleHItemBase): + """ + Every version of each loan made by a campaign filer another recipient. + + For outstanding loans itemized on Schedule H of the most recent version of + each Form 460 filing, see Form460ScheduleHItem. + + Derived from LOAN_CD records where FORM_TYPE is 'H' or 'H1'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_h_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the outstanding loan' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) + + +class Form460ScheduleH2ItemBaseOld(CampaignLoanMadeItemBase): + """ + Abstract base model for Schedule H, Part 2, items from Form 460 circa 2001. + + Until Form 460 was modified in 2001, campaign filers were required to report + repayments on and forgiveness of loans made to others on Part 2 of Schedule + H. + """ + date_repaid_or_forgiven = models.DateField( + verbose_name='date paid or forgiven', + null=True, + help_text="Date when the loan repayment or forgiveness occurred (from " + "LOAN_CD.LOAN_DATE2)" + ) + date_of_original_loan = models.DateField( + verbose_name='date of original loan', + null=True, + help_text="Date the loan was orginally made (from LOAN_CD.LOAN_DATE1)" + ) + REPAYMENT_TYPE_CHOICES = ( + ('H2F', 'Forgiven'), + ('H2R', 'Repay'), + ('H2T', 'Third party payment'), + ) + repayment_type = models.CharField( + verbose_name='repayment type', + max_length=3, + choices=REPAYMENT_TYPE_CHOICES, + help_text='Indicates whether the item is a loan repayment to the ' + 'campaign filer, a repayment by a third-party or a loan ' + 'forgiveness by the campaign filer (from LOAN_CD.LOAN_TYPE)', + ) + amount_repaid_or_forgiven = models.DecimalField( + verbose_name='amount repaid or forgiven', + decimal_places=2, + max_digits=14, + help_text="Amount paid back or forgiven during the period covered by " + "the filing (from LOAN_CD.LOAN_AMT1)" + ) + outstanding_principle = models.DecimalField( + verbose_name='outstanding principle', + decimal_places=2, + max_digits=14, + help_text="Outstanding balance of the loan at the end of the period " + "covered by the filing (from LOAN_CD.LOAN_AMT2)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleH2ItemOld(Form460ScheduleH2ItemBaseOld): + """ + Repayments on loans/forgiven loans made by campaign filers circa 2001. + + These transactions are itemized on Schedule H, Part 2, of the most recent + version to each Form 460 filing in the pre-2001 format. For loan repayments + and forgiven loans on any version of any Form 460 filing in the pre-2001 + format, see Form460ScheduleH2ItemVersionOld. + + Derived from LOAN_CD records where FORM_TYPE is 'H2'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_h2_items_old', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the Form 460 on which the loan ' + 'was reported (from LOAN_CD.FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + verbose_name_plural = "Form460 schedule h2 items old" + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleH2ItemVersionOld(Form460ScheduleH2ItemBaseOld): + """ + Every version of each repayment/forgiveness of a loan by a campaign filer circa 2001. + + For loan repayments and forgiven loans on any version of any Form 460 filing + in the pre-2001 format, see Form460ScheduleH2ItemOld. + + Derived from LOAN_CD records where FORM_TYPE is 'H2'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_h2_items_old', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the outstanding loan' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + verbose_name_plural = "Form460 schedule h2 item versions old" + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + ) diff --git a/calaccess_processed/models/campaign/filings/form460/schedules/i.py b/calaccess_processed/models/campaign/filings/form460/schedules/i.py new file mode 100644 index 00000000..3493bf32 --- /dev/null +++ b/calaccess_processed/models/campaign/filings/form460/schedules/i.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Models for storing data from Campaign Disclosure Statements (Form 460). +""" +from __future__ import unicode_literals +from django.db import models +from django.utils.encoding import python_2_unicode_compatible +from calaccess_processed.managers import ProcessedDataManager +from calaccess_processed.models.campaign.filings import CampaignContributionBase + + +class Form460ScheduleIItemBase(CampaignContributionBase): + """ + Abstract base model for items reported on Schedule I of Form 460 filings. + + On Schedule I, campaign filers are required to report miscellaneous cash + increases during the period covered by the filing. These include any + transaction that increases the cash position of the filer, but is not a + monetary contribution, loan, or loan repayment. + """ + amount = models.DecimalField( + verbose_name='amount', + decimal_places=2, + max_digits=14, + help_text="Amount of cash increase from the contributor in the period " + "covered by the filing (from RCPT_CD.AMOUNT)" + ) + receipt_description = models.CharField( + verbose_name='receipt description', + max_length=90, + blank=True, + help_text="Description of the cash increase (from RCPT_CD.CTRIB_DSCR)" + ) + + class Meta: + """ + Model options. + """ + abstract = True + + +@python_2_unicode_compatible +class Form460ScheduleIItem(Form460ScheduleIItemBase): + """ + Miscellaneous cash increases to the coffers of campaign filers. + + Includes any transaction that increases the cash position of the filer, but + is not a monetary contribution, loan, or loan repayment. + + These transactions are itemized on Schedule I of the most recent version + of each Form 460 filing. For miscellaneous cash increases itemized on any + version of any Form 460 filing, see Form460ScheduleIItemVersion. + + Derived from RCPT_CD records where FORM_TYPE is 'I'. + """ + filing = models.ForeignKey( + 'Form460Filing', + related_name='schedule_i_items', + null=True, + on_delete=models.SET_NULL, + db_constraint=False, + help_text='Foreign key referring to the Form 460 on which the ' + 'miscellaneous cash increase was report (from RCPT_CD.' + 'FILING_ID)', + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing', + 'line_item', + ),) + + def __str__(self): + return '%s-%s' % (self.filing, self.line_item) + + +@python_2_unicode_compatible +class Form460ScheduleIItemVersion(Form460ScheduleIItemBase): + """ + Every version of each miscellaneous cash increase for a campaign filer. + + Includes any transaction that increases the cash position of the filer, but + is not a monetary contribution, loan, or loan repayment. + + For miscellaneous cash increases itemized on Schedule I of the most recent + version of each Form 460 filing, see Form460ScheduleIItem. + + Derived from RCPT_CD records where FORM_TYPE is 'I'. + """ + filing_version = models.ForeignKey( + 'Form460FilingVersion', + related_name='schedule_i_items', + null=True, + on_delete=models.SET_NULL, + help_text='Foreign key referring to the version of the Form 460 that ' + 'includes the miscellaneous cash increase' + ) + + objects = ProcessedDataManager() + + class Meta: + """ + Model options. + """ + unique_together = (( + 'filing_version', + 'line_item', + ),) + index_together = (( + 'filing_version', + 'line_item', + ),) + + def __str__(self): + return '%s-%s-%s' % ( + self.filing_version.filing_id, + self.filing_version.amend_id, + self.line_item + )