Created
July 6, 2012 17:35
-
-
Save robrocker7/3061524 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from datetime import timedelta, datetime | |
from subprocess import call | |
from django.db import models | |
from django_extensions.db.fields.encrypted import EncryptedCharField | |
from django.contrib.localflavor.us.models import PhoneNumberField | |
from django.contrib.localflavor.us.us_states import STATE_CHOICES | |
from django.contrib.auth.models import User | |
from django.core.urlresolvers import reverse | |
from django.conf import settings | |
from django.core.mail import mail_managers | |
from django.template import loader, Context | |
from apps.common.models import Phone, Address | |
from apps.profile.models import Profile as Client | |
# Create your models here. | |
class Beneficiary(models.Model): | |
BENE_TYPES = ( | |
('primary', 'Primary'), | |
('contingent', 'Contingent'), | |
) | |
first_name = models.CharField(max_length=30, null=True, blank=True) | |
last_name = models.CharField(max_length=30, null=True, blank=True) | |
street_address = models.CharField(max_length=256, | |
null=True, blank=True) | |
street_address_2 = models.CharField(max_length=256, | |
null=True, blank=True, default='') | |
city = models.CharField(max_length=32, | |
null=True, blank=True) | |
state = models.CharField(max_length=2, | |
choices=STATE_CHOICES, default='TX') | |
zip_code = models.CharField(max_length=10, blank=True, null=True) | |
county = models.CharField(max_length=36, | |
null=True, blank=True) | |
phone = models.ForeignKey(Phone, null=True, blank=True) | |
social = EncryptedCharField(max_length=256, | |
null=True, blank=True) | |
date_of_birth = models.CharField(max_length=10, help_text='Format: DD/MM/YYYY', | |
null=True, blank=True) | |
relationship = models.CharField(max_length=256) | |
bene_type = models.CharField(max_length=12, choices=BENE_TYPES, | |
null=True, blank=True) | |
percentage = models.CharField(max_length=5, default=100, | |
null=True, blank=True) | |
def get_street_address(self): | |
street = [self.street_address] | |
if self.street_address_2: | |
street.append(self.street_address_2) | |
return ' '.join(street) | |
class NameAddressBase(models.Model): | |
name = models.CharField(max_length=256) | |
address = models.ForeignKey(Address, null=True, blank=True) | |
phone = models.ForeignKey(Phone, null=True, blank=True) | |
date_created = models.DateTimeField(auto_now_add=True, | |
null=True, blank=True) | |
created_by = models.ForeignKey(User, null=True, blank=True) | |
class Meta: | |
abstract = True | |
class RegisteredAgent(NameAddressBase): | |
pass | |
class LLCManager(NameAddressBase): | |
pass | |
class Custodian(models.Model): | |
CUSTODIAN_PLAN_TYPES = ( | |
('previous', 'Previous 401(k), 403(b), 457 or Defined Benefit Plan from a past Employer'), | |
('traditional_ira', 'Traditional IRA'), | |
('roth_ira', 'Roth IRA'), | |
('sep_ira', 'SEP IRA'), | |
('inherited_ira', 'Inherited IRA'), | |
('simple_ira', 'Simple IRA'), | |
('new_ira', 'New IRA'), | |
) | |
LIQUIDATE_CHOICES = ( | |
('all_assets', 'Liquidate all assets and transfer cash balance to IRA'), | |
('partial', 'This will be a Partial Transfer/Rollover'), | |
) | |
plan = models.CharField(max_length=48, choices=CUSTODIAN_PLAN_TYPES) | |
first_name = models.CharField(max_length=64, null=True, blank=True) | |
last_name = models.CharField(max_length=64, null=True, blank=True) | |
account_number = models.CharField(max_length=32, null=True, blank=True) | |
new_amount = models.CharField(max_length=36, null=True, blank=True) | |
new_years = models.CharField(max_length=8, null=True, blank=True) | |
liquidate = models.CharField(max_length=18, choices=LIQUIDATE_CHOICES) | |
liquidate_cash = models.CharField(max_length=36, null=True, blank=True) | |
name = models.CharField(max_length=64, null=True, blank=True) | |
address = models.ForeignKey(Address, null=True, blank=True) | |
phone = models.ForeignKey(Phone, null=True, blank=True) | |
date_created = models.DateTimeField(auto_now_add=True, | |
null=True, blank=True) | |
created_by = models.ForeignKey(User, null=True, blank=True) | |
class ProcessStep(models.Model): | |
STEPS = ( | |
('received_intake', 'Recieved Intake'), | |
('send_llc_application', 'Send LLC Application'), | |
('ss4_filled', 'SS4 Filled Out'), | |
('recieved_ss4', 'Recieved SS4'), | |
('setup_ein', 'Setup EIN'), | |
('custodian_app_setup', 'Custodian Application Setup'), | |
('second_form_sent', 'Second Set of Forms Sent'), | |
('custodian_forms_received', 'Custodian Forms Received'), | |
('money_moved_to_ira_services', 'Money Moved to IRA Services'), | |
('money_moved_to_clients_bank', 'Money Moved to Clients Bank'), | |
('sent_final_package', 'Sent Final Package'), | |
) | |
step = models.CharField(max_length=32, choices=STEPS) | |
date_created = models.DateTimeField(auto_now_add=True) | |
class Intake(models.Model): | |
TRANSFER_MAP = ( | |
('transfer', 'Transfer - I will transfer assets from another IRA'), | |
('rollover', 'Rollover - I will rollover cash from an existing IRA or qualified retirement plan - This will be a Rollover of a distribution from a prior IRA or of a lump sum distribution or plan termination distribution paid to me within one taxable year from a qualified employee benefit plan or annuity, either of which is contributed to this IRA within 60 days of receipt of such funds.'), | |
) | |
STATUS_MAP = ( | |
('0', 'Client'), | |
('1', 'Beneficiaries'), | |
('2', 'Custodian Information'), | |
('3', 'IRA Formation,Reg Agent, LLC Manager'), | |
('4', 'Special Instructions'), | |
('5', 'Waiting for payment'), | |
('6', 'Paid'), | |
) | |
IRA_TYPE = ( | |
('traditional_ira', 'Traditional IRA'), | |
('roth_ira', 'Roth IRA'), | |
('roth_conversion', 'Roth Conversion'), | |
('sep_ira', 'SEP IRA'), | |
('inherited_ira', 'Inherited IRA'), | |
) | |
client = models.ForeignKey(Client) | |
beneficiaries = models.ManyToManyField(Beneficiary, related_name='client_beneficiaries', null=True, blank=True) | |
ira_type = models.CharField(max_length=16, choices=IRA_TYPE, | |
null=True, blank=True) | |
custodians = models.ManyToManyField(Custodian, | |
null=True, blank=True) | |
proposed_name_one = models.CharField(max_length=64, | |
null=True, blank=True) | |
proposed_name_two = models.CharField(max_length=64, | |
null=True, blank=True) | |
proposed_name_three = models.CharField(max_length=64, | |
null=True, blank=True) | |
registered_agent = models.ForeignKey(RegisteredAgent, | |
null=True, blank=True) | |
llc_manager = models.ForeignKey(LLCManager, | |
null=True, blank=True) | |
duration = models.BooleanField(default=True, | |
help_text="Leave checked for Perpetual (Recommended)") | |
duration_other = models.CharField(max_length=64, | |
null=True, blank=True) | |
special_instructions = models.TextField(null=True, blank=True) | |
transfer_method = models.CharField(max_length=24, choices=TRANSFER_MAP, | |
null=True, blank=True) | |
intital = models.CharField(max_length=2, help_text="Initials must match the First and Last name you entered earlier", | |
null=True, blank=True) | |
# AGENT INFO | |
agent = models.ForeignKey(User, related_name='agent', | |
null=True, blank=True) | |
marked_for_processing = models.BooleanField(default=False) | |
marked_for_processing_date = models.DateTimeField(null=True, blank=True) | |
# PROCESSING INFO | |
TOTAL_PROCESSING_STEPS = 5 | |
processor = models.ForeignKey(User, related_name='processor', | |
null=True, blank=True) | |
is_processing = models.BooleanField(default=False) | |
processing_date = models.DateTimeField(null=True, blank=True) | |
processing_steps = models.ManyToManyField(ProcessStep,null=True, blank=True) | |
status = models.CharField(max_length=20, choices=STATUS_MAP, | |
null=True, blank=True) | |
date_updated = models.DateTimeField(auto_now=True) | |
date_created = models.DateTimeField(auto_now_add=True) | |
def generate_forms(self): | |
from apps.pdfs.static_pdf import Static | |
forms = {} | |
doc_set = DocumentSet(intake=self) | |
doc_set.save() | |
# generate application | |
from apps.pdfs.application import Application | |
a = Application(self) | |
application = Document().create_application(doc_set, a.file_path) | |
# attach fees | |
fee = Static(self, '10-FeeSchedule.pdf') | |
fees = Document().add_static(doc_set, fee.file_path, 'fee_schedule') | |
# generate beneficiary | |
from apps.pdfs.beneficiary import Beneficiary | |
b = Beneficiary(self) | |
for bc in range(0, len(b.file_path)): | |
beneficiary = Document().create_beneficiary(doc_set, | |
b.file_path[bc]) | |
# generate transfer if transfer_method == 'transfer' | |
if self.transfer_method == 'transfer': | |
from apps.pdfs.transfer import Transfer | |
t = Transfer(self) | |
for tc in range(0, len(t.file_path)): | |
transfer = Document().create_transfer(doc_set, t.file_path[tc]) | |
else: | |
# otherwise attach deposit form | |
from apps.pdfs.deposit import Deposit | |
d = Deposit(self) | |
deposit = Document().create_deposit(doc_set, d.file_path) | |
# add rep auth | |
from apps.pdfs.representative import Representative | |
ra = Representative(self) | |
repauth = Document().create_representative(doc_set, ra.file_path) | |
# add internet access form | |
from apps.pdfs.internetaccess import InternetAccess | |
ia = InternetAccess(self) | |
internetform = Document().create_internetaccess(doc_set, ia.file_path) | |
# attach privacy notice | |
pn = Static(self, '12-PrivacyNotice.pdf') | |
privacy = Document().add_static(doc_set, pn.file_path, 'privacy') | |
# attach account disclosure | |
ad = Static(self, '13-AccountDisclosure.pdf') | |
disclosure = Document().add_static(doc_set, ad.file_path, 'disclosure') | |
# add internet access form | |
from apps.pdfs.repinternet import RepInternet | |
ri = RepInternet(self) | |
repinternetform = Document().create_repinternetaccess(doc_set, ri.file_path) | |
# add ss4 | |
from apps.pdfs.ss4 import SS4 | |
ss4 = SS4(self) | |
ss4form = Document().create_ss4(doc_set, ss4.file_path) | |
# No need to send docset yet | |
# doc_set.create_docset_pdf() | |
return doc_set | |
def mark_for_processing(self): | |
self.marked_for_processing = True | |
self.marked_for_processing_date = datetime.now() | |
self.save() | |
# send email to processors AKA Managers | |
t = loader.get_template('emails/new_intake_available.html') | |
c = Context({ | |
'client_name': self.client.get_full_name(), | |
'client_email': self.client.user.email, | |
'agent_name': self.agent.username, | |
'agent_email': self.agent.email, | |
}) | |
mail_managers('New Intake Ready For Processing', t.render(c), | |
fail_silently=False) | |
def accept_by_processor(self): | |
self.is_processing = True | |
self.processing_date = datetime.now() | |
self.save() | |
def get_status(self): | |
status = [y[1] for x, y in enumerate(self.STATUS_MAP) if y[0] == self.status][0] | |
return status | |
def get_documentsets(self): | |
return self.documentset_set.filter(sent_to_client=True).order_by('-date_created') | |
def __unicode__(self): | |
return '%s - %s' % (self.ira_type, self.client) | |
def get_absolute_url(self): | |
if self.status == '0': | |
return reverse('intake:intake_form') | |
elif self.status == '1': | |
return reverse('intake:intake_form_two') | |
elif self.status == '2': | |
return reverse('intake:intake_form_three') | |
elif self.status == '3': | |
return reverse('intake:intake_form_four') | |
elif self.status == '4': | |
return reverse('intake:intake_form_five') | |
elif self.status == '5': | |
return reverse('intake:intake_form_six') | |
else: | |
return reverse('intake:intake_form') | |
def agent_absolute_url(self): | |
if self.status == '0': | |
return reverse('agent_intake:intake_form', | |
kwargs={'client_id': self.client.id}) | |
elif self.status == '1': | |
return reverse('agent_intake:intake_form_two', | |
kwargs={'client_id': self.client.id}) | |
elif self.status == '2': | |
return reverse('agent_intake:intake_form_three', | |
kwargs={'client_id': self.client.id}) | |
elif self.status == '3': | |
return reverse('agent_intake:intake_form_four', | |
kwargs={'client_id': self.client.id}) | |
elif self.status == '4': | |
return reverse('agent_intake:intake_form_five', | |
kwargs={'client_id': self.client.id}) | |
elif self.status == '5': | |
return reverse('agent_intake:intake_form_six', | |
kwargs={'client_id': self.client.id}) | |
else: | |
return reverse('agent_intake:intake_form', | |
kwargs={'client_id': self.client.id}) | |
class Document(models.Model): | |
DOCUMENT_TYPES = ( | |
('application', 'Application'), | |
('beneficiary', 'Beneficiary'), | |
('transfer', 'Transfer'), | |
('internet_access', 'Internet Access'), | |
('fee_schedule', 'Fee Schedule'), | |
('deposit', 'Deposit'), | |
('rep_auth', 'Representative Auth'), | |
('privacy', 'Privacy Notice'), | |
('disclosure', 'Account Disclosure'), | |
('rep_internet_access', 'Representative Internet Access'), | |
('ss4', 'SS4'), | |
) | |
document_type = models.CharField(max_length=24) | |
file_path = models.FilePathField( | |
path=os.path.join(settings.MEDIA_ROOT, 'forms')) | |
send_to_client = models.BooleanField(default=False) | |
date_created = models.DateTimeField(auto_now_add=True) | |
def add_static(self, doc_set, path, type): | |
d = self | |
d.document_type = type | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_representative(self, doc_set, path): | |
d = self | |
d.document_type = 'rep_auth' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_deposit(self, doc_set, path): | |
d = self | |
d.document_type = 'deposit' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_application(self, doc_set, path): | |
d = self | |
d.document_type = 'application' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_beneficiary(self, doc_set, path): | |
d = self | |
d.document_type = 'beneficiary' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_transfer(self, doc_set, path): | |
d = self | |
d.document_type = 'transfer' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_internetaccess(self, doc_set, path): | |
d = self | |
d.document_type = 'internet_access' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_repinternetaccess(self, doc_set, path): | |
d = self | |
d.document_type = 'rep_internet_access' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def create_ss4(self, doc_set, path): | |
d = self | |
d.document_type = 'ss4' | |
d.file_path = path | |
d.save() | |
doc_set.documents.add(d) | |
return d | |
def get_document_type(self): | |
dtype = [y[1] for x, y in enumerate(self.DOCUMENT_TYPES) if y[0] == self.document_type][0] | |
return dtype | |
def get_absolute_url(self): | |
return '%sforms/%s' % (settings.MEDIA_URL, self.file_path) | |
def __unicode__(self): | |
return '%s (%s-%s-%s)' % ( | |
self.document_type, | |
self.date_created.month, | |
self.date_created.day, | |
self.date_created.year) | |
class DocumentSet(models.Model): | |
intake = models.ForeignKey(Intake) | |
documents = models.ManyToManyField(Document) | |
sent_to_client = models.BooleanField(default=False) | |
date_sent = models.DateTimeField(blank=True, null=True) | |
date_created = models.DateTimeField(auto_now_add=True) | |
def get_documents(self): | |
return self.documents.filter(send_to_client=True).order_by('pk') | |
def create_docset_pdf(self): | |
# generate a large pdf | |
client = self.intake.client | |
EXPORT_PATH = os.path.join(settings.MEDIA_ROOT, 'forms') | |
client_file = '%s_%s_%s' % (client.user.last_name.upper(), | |
client.user.first_name.upper(), | |
client.pk) | |
today = datetime.today() | |
application_name = 'CLIENT_PACKET_%s-%s-%s-%s-%s.pdf' % ( | |
today.month, | |
today.day, | |
today.year, | |
today.hour, | |
today.minute) | |
process_call = [] | |
process_call.append('pdftk') | |
for document in self.documents.all(): | |
process_call.append(os.path.join(EXPORT_PATH, document.file_path)) | |
process_call.append('cat') | |
process_call.append('output') | |
process_call.append(os.path.join(EXPORT_PATH, client_file, | |
application_name)) | |
call(process_call) | |
def __unicode__(self): | |
return '%s %s/%s/%s %s:%s' % ( | |
self.intake.client.get_full_name(), | |
self.date_created.month, | |
self.date_created.day, | |
self.date_created.year, | |
self.date_created.hour, | |
self.date_created.minute) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment