예제 #1
0
파일: payroll.py 프로젝트: B-Rich/luca
def compute_payroll(wage_schedule, state_withholding, exemptions):
    """Return a 2013 payroll schedule as a Pandas DataFrame."""

    month_integers = range(1, len(wage_schedule) + 1)

    pd = pandas.DataFrame(index=month_integers)
    pd['wages'] = wage_schedule

    compute = federal_monthly_withholding['MJ'].compute_tax_on
    pd['fedwh'] = [compute(amount, exemptions) for amount in wage_schedule]

    ss_excess = (pd['wages'].cumsum() - ss_limit).clip(zero)
    pd['ss_wages'] = (pd['wages'] - ss_excess).clip(zero)
    pd['ss'] = [cents(n) for n in ss_rate * pd['ss_wages']]
    pd['mc'] = [cents(n) for n in mc_rate * pd['wages']]
    pd['ss2'] = [cents(n) for n in ss_rate * 2 * pd['ss_wages']]
    pd['mc2'] = [cents(n) for n in mc_rate * 2 * pd['wages']]

    pd['statewh'] = [state_withholding(wage)
                     for month, wage in pd['wages'].iteritems()]
    pd['localwh'] = [cents((wage - monthly_school_exemption * exemptions)
                           * bluffton_school_rate) for wage in pd['wages']]

    pd['paycheck'] = (pd['wages'] - pd['fedwh'] - pd['ss'] - pd['mc']
                      - pd['statewh'] - pd['localwh'])

    return pd
예제 #2
0
def compute_payroll(wage_schedule, state_withholding, exemptions):
    """Return a 2013 payroll schedule as a Pandas DataFrame."""

    month_integers = range(1, len(wage_schedule) + 1)

    pd = pandas.DataFrame(index=month_integers)
    pd['wages'] = wage_schedule

    compute = federal_monthly_withholding['MJ'].compute_tax_on
    pd['fedwh'] = [compute(amount, exemptions) for amount in wage_schedule]

    ss_excess = (pd['wages'].cumsum() - ss_limit).clip(zero)
    pd['ss_wages'] = (pd['wages'] - ss_excess).clip(zero)
    pd['ss'] = [cents(n) for n in ss_rate * pd['ss_wages']]
    pd['mc'] = [cents(n) for n in mc_rate * pd['wages']]
    pd['ss2'] = [cents(n) for n in ss_rate * 2 * pd['ss_wages']]
    pd['mc2'] = [cents(n) for n in mc_rate * 2 * pd['wages']]

    pd['statewh'] = [
        state_withholding(wage) for month, wage in pd['wages'].iteritems()
    ]
    pd['localwh'] = [
        cents((wage - monthly_school_exemption * exemptions) *
              bluffton_school_rate) for wage in pd['wages']
    ]

    pd['paycheck'] = (pd['wages'] - pd['fedwh'] - pd['ss'] - pd['mc'] -
                      pd['statewh'] - pd['localwh'])

    return pd
예제 #3
0
파일: f940.py 프로젝트: B-Rich/luca
def compute(form):
    f = form
    f.line6 = f.line4 + f.line5
    f.line7 = f.line3 - f.line6
    f.line8 = cents(f.line7 * Decimal("0.006"))

    if f.all_wages_excluded_from_state_unemployment_tax:
        f.line9 = cents(f.line7 * Decimal(".054"))
    else:
        f.line9 = Decimal("0.00")

    f.line12 = f.line8 + f.line9 + f.line10 + f.line11

    if f.line12 > f.line13:
        f.line14 = f.line12 - f.line13
        f.line15 = zero
    else:
        f.line14 = zero
        f.line15 = f.line13 - f.line12

    if f.line12 > cents("500.00"):
        f.line17 = f.line16a + f.line16b + f.line16c + f.line16d
        # Make this a warning?  assert f.line12 == f.line17
    else:
        f.line16a = f.line16b = f.line16c = f.line16d = ""
        f.line17 = zero
예제 #4
0
def compute(form):
    f = form
    f.line3 = cents(f.line2 * 75 / 1000)
    f.line4 = max(f.line1 - f.line3, zero)
    f.line9 = f.line5 + f.line6 + f.line7 + f.line8
    f.line15 = f.line10 + f.line11 + f.line12 + f.line13 + f.line14
    f.line19 = f.line16 + f.line17 + f.line18
    f.line24 = f.line21 + f.line22 + f.line23
    f.line26 = cents(f.line25 * 2 / 100)
    f.line27 = max(f.line24 - f.line26, zero)
    f.line29 = (f.line4 + f.line9 + f.line15 + f.line19 + f.line20 + f.line27 +
                f.line28)
예제 #5
0
파일: f1040sa.py 프로젝트: B-Rich/luca
def compute(form):
    f = form
    f.line3 = cents(f.line2 * 75 / 1000)
    f.line4 = max(f.line1 - f.line3, zero)
    f.line9 = f.line5 + f.line6 + f.line7 + f.line8
    f.line15 = f.line10 + f.line11 +  f.line12 +  f.line13 + f.line14
    f.line19 = f.line16 + f.line17 +  f.line18
    f.line24 = f.line21 + f.line22 + f.line23
    f.line26 = cents(f.line25 * 2 / 100)
    f.line27 = max(f.line24 - f.line26, zero)
    f.line29 = (f.line4 + f.line9 + f.line15 + f.line19 + f.line20
              + f.line27 + f.line28)
예제 #6
0
def compute(form):
    f = form
    validate.year(f.year)
    validate.quarter(f.quarter)
    f.line4 = not (f.line5a1 or f.line5b1 or f.line5c1)

    social_security_rate = Decimal('0.104' if int(f.year) < 2013 else '0.124')
    medicare_rate = Decimal('0.029')
    additional_medicare_rate = Decimal('0.009')

    f.line5a2 = cents(f.line5a1 * social_security_rate)
    f.line5b2 = cents(f.line5b1 * social_security_rate)
    f.line5c2 = cents(f.line5c1 * medicare_rate)
    if form.form_version >= u'2014':
        f.line5d2 = cents(f.line5d1 * additional_medicare_rate)
        f.line5e = f.line5a2 + f.line5b2 + f.line5c2 + f.line5d2
        f.line6 = f.line3 + f.line5e + f.line5f
    else:
        f.line5d = f.line5a2 + f.line5b2 + f.line5c2
        f.line6 = f.line3 + f.line5d + getattr(f, 'line5e', zero)
    f.line10 = f.line6 + f.line7 + f.line8 + f.line9
    if f.form_version == u'2017':
        f.line12 = f.line10 - f.line11
        f.line16_total = f.line16_month1 + f.line16_month2 + f.line16_month3
        if f.line12 > f.line13:
            f.line14 = f.line10 - f.line13
            f.line15 = zero
        else:
            f.line14 = zero
            f.line15 = f.line13 - f.line10
    elif f.form_version >= u'2014':
        f.line14_total = f.line14_month1 + f.line14_month2 + f.line14_month3
        if f.line11 is None:
            f.line11 = f.line14_total
        if f.line10 > f.line11:
            f.line12 = f.line10 - f.line11
            f.line13 = zero
        else:
            f.line12 = zero
            f.line13 = f.line11 - f.line10
    else:
        f.line16_total = f.line16_month1 + f.line16_month2 + f.line16_month3
        if f.line11 is None:
            f.line11 = f.line16_total
        f.line13 = f.line11 + f.line12a
        if f.line10 > f.line13:
            f.line14 = f.line10 - f.line13
            f.line15 = zero
        else:
            f.line14 = zero
            f.line15 = f.line13 - f.line10
예제 #7
0
def process_form(f):
    subs = (f.Part_I.A, f.Part_I.B)
    for sub in subs:
        sub.profit = sub.rents - sub.expenses
        sub.tax = cents(sub.profit / 10)
    f.total_rents = sum(sub.rents for sub in subs)
    f.total_expenses = sum(sub.expenses for sub in subs)
    f.total_profit = sum(sub.profit for sub in subs)
    f.total_tax = sum(sub.tax for sub in subs)
예제 #8
0
파일: f941.py 프로젝트: rmoorman/luca
def compute(form):
    f = form
    validate.year(f.year)
    validate.quarter(f.quarter)
    f.line4 = not (f.line5a1 or f.line5b1 or f.line5c1)

    social_security_rate = Decimal('0.104' if int(f.year) < 2013 else '0.124')
    medicare_rate = Decimal('0.029')
    additional_medicare_rate = Decimal('0.009')

    f.line5a2 = cents(f.line5a1 * social_security_rate)
    f.line5b2 = cents(f.line5b1 * social_security_rate)
    f.line5c2 = cents(f.line5c1 * medicare_rate)
    if form.form_version >= u'2014':
        f.line5d2 = cents(f.line5d1 * additional_medicare_rate)
        f.line5e = f.line5a2 + f.line5b2 + f.line5c2 + f.line5d2
        f.line6 = f.line3 + f.line5e + f.line5f
    else:
        f.line5d = f.line5a2 + f.line5b2 + f.line5c2
        f.line6 = f.line3 + f.line5d + getattr(f, 'line5e', zero)
    f.line10 = f.line6 + f.line7 + f.line8 + f.line9
    if f.form_version >= u'2014':
        f.line14_total = f.line14_month1 + f.line14_month2 + f.line14_month3
        if f.line11 is None:
            f.line11 = f.line14_total
        if f.line10 > f.line11:
            f.line12 = f.line10 - f.line11
            f.line13 = zero
        else:
            f.line12 = zero
            f.line13 = f.line11 - f.line10
    else:
        f.line16_total = f.line16_month1 + f.line16_month2 + f.line16_month3
        if f.line11 is None:
            f.line11 = f.line16_total
        f.line13 = f.line11 + f.line12a
        if f.line10 > f.line13:
            f.line14 = f.line10 - f.line13
            f.line15 = zero
        else:
            f.line14 = zero
            f.line15 = f.line13 - f.line10
예제 #9
0
파일: taxes.py 프로젝트: zrisher/luca
    def __init__(self, brackets, one_allowance=zero):
        """Return a Pandas tax schedule DataFrame.

        Each element of `brackets` should be a two-element tuple
        ``(over, rate)`` like ``(8926, 15)`` giving the base of the tax
        bracket in dollars ("if the amount is *over*...") and its tax
        rate as a percent.  Each value in the tuple should either be a
        Decimal, or an integer or string that will be automatically
        converted to a Decimal.

        The value `one_allowance` should be the amount of any deduction
        that gets subtracted from income before the tax is computed.

        """
        overs, rates = zip(*brackets)
        df = pd.DataFrame({'over': [cents(value) for value in overs]})
        df['rate'] = [Decimal(rate) * percent for rate in rates]
        df['but_not_over'] = df['over'].shift(-1).fillna(infinity)
        self.brackets = df
        self.one_allowance = cents(one_allowance)
예제 #10
0
def compute(form):
    f = form
    f.line6 = f.line4 + f.line5
    f.line7 = f.line3 - f.line6
    f.line8 = cents(f.line7 * Decimal('0.006'))

    if f.all_wages_excluded_from_state_unemployment_tax:
        f.line9 = cents(f.line7 * Decimal('.054'))
    else:
        f.line9 = Decimal('0.00')

    f.line12 = f.line8 + f.line9 + f.line10 + f.line11

    if f.line12 > f.line13:
        f.line14 = f.line12 - f.line13
        f.line15 = zero
    else:
        f.line14 = zero
        f.line15 = f.line13 - f.line12

    f.line17 = f.line16a + f.line16b + f.line16c + f.line16d
예제 #11
0
파일: f940.py 프로젝트: MattHJensen/luca
def compute(form):
    f = form
    f.line6 = f.line4 + f.line5
    f.line7 = f.line3 - f.line6
    f.line8 = cents(f.line7 * Decimal('0.006'))

    if f.all_wages_excluded_from_state_unemployment_tax:
        f.line9 = cents(f.line7 * Decimal('.054'))
    else:
        f.line9 = Decimal('0.00')

    f.line12 = f.line8 + f.line9 + f.line10 + f.line11

    if f.line12 > f.line13:
        f.line14 = f.line12 - f.line13
        f.line15 = zero
    else:
        f.line14 = zero
        f.line15 = f.line13 - f.line12

    f.line17 = f.line16a + f.line16b + f.line16c + f.line16d
예제 #12
0
파일: f8829.py 프로젝트: B-Rich/luca
def compute(form):
    f = form
    f.line3 = (cents(f.line1) / cents(f.line2)
               ).quantize(Decimal('0.0001'), rounding=ROUND_HALF_UP)
    f.line7 = f.line3

    f.line12a = sum(f['line', n, 'a'] for n in range(9, 12))
    f.line12b = sum(f['line', n, 'b'] for n in range(9, 12))
    f.line13 = cents(f.line12b * f.line7 / hundred)
    f.line14 = f.line12a + f.line13

    f.line15 = max(zero, f.line8 - f.line14)

    f.line22a = sum(f['line', n, 'a'] for n in range(16, 22))
    f.line22b = sum(f['line', n, 'b'] for n in range(16, 22))
    f.line23 = cents(f.line22b * f.line7)
    f.line25 = f.line22a + f.line23 + f.line24

    f.line38 = f.line36 - f.line37
    f.line39 = cents(f.line38 * f.line7)
    f.line41 = cents(f.line39 * f.line40)

    f.line26 = min(f.line15, f.line25)
    f.line27 = f.line15 - f.line26
    f.line29 = f.line41
    f.line31 = f.line28 + f.line29 + f.line30
    f.line32 = min(f.line27, f.line31)
    f.line33 = f.line14 + f.line26 + f.line32
    # TODO: f.line34 should really involve casualty loss plus another form!
    f.line34 = zero
    f.line35 = f.line33 - f.line34

    f.line42 = max(zero, f.line25 - f.line26)
    f.line43 = max(zero, f.line31 - f.line32)
예제 #13
0
파일: f8829.py 프로젝트: zrisher/luca
def compute(form):
    f = form
    f.line3 = (cents(f.line1) / cents(f.line2)).quantize(
        Decimal('0.0001'), rounding=ROUND_HALF_UP)
    f.line7 = f.line3

    f.line12a = sum(f['line', n, 'a'] for n in range(9, 12))
    f.line12b = sum(f['line', n, 'b'] for n in range(9, 12))
    f.line13 = cents(f.line12b * f.line7 / hundred)
    f.line14 = f.line12a + f.line13

    f.line15 = max(zero, f.line8 - f.line14)

    f.line22a = sum(f['line', n, 'a'] for n in range(16, 22))
    f.line22b = sum(f['line', n, 'b'] for n in range(16, 22))
    f.line23 = cents(f.line22b * f.line7)
    f.line25 = f.line22a + f.line23 + f.line24

    f.line38 = f.line36 - f.line37
    f.line39 = cents(f.line38 * f.line7)
    f.line41 = cents(f.line39 * f.line40)

    f.line26 = min(f.line15, f.line25)
    f.line27 = f.line15 - f.line26
    f.line29 = f.line41
    f.line31 = f.line28 + f.line29 + f.line30
    f.line32 = min(f.line27, f.line31)
    f.line33 = f.line14 + f.line26 + f.line32
    # TODO: f.line34 should really involve casualty loss plus another form!
    f.line34 = zero
    f.line35 = f.line33 - f.line34

    f.line42 = max(zero, f.line25 - f.line26)
    f.line43 = max(zero, f.line31 - f.line32)
예제 #14
0
def compute(form):
    f = form
    f.line3 = f.line1a + f.line1b + f.line2
    f.line4 = cents(Decimal('.9235') * f.line3)

    if f.line4 < Decimal('400.00'):
        f.line5 = zero
        f.line6 = zero
        return

    if f.form_version == u'2014':
        ss_limit = Decimal('117000.00')
        combined_rate = Decimal('.153')
        maximum_ss = Decimal('14508.00')
        medicare_rate = Decimal('.029')
    else:
        ss_limit = Decimal('110100.00')
        combined_rate = Decimal('.133')
        maximum_ss = Decimal('11450.40')
        medicare_rate = Decimal('.029')

    if f.line4 <= ss_limit:
        f.line5 = combined_rate * f.line4
    else:
        f.line5 = maximum_ss + medicare_rate * f.line4
    f.line5 = cents(f.line5)

    if f.form_version >= u'2014':
        f.line6 = cents(f.line5 / 2)
        return

    # TODO: re-check the following

    if f.line5 <= Decimal('14643.30'):
        f.line6 = Decimal('.5751') * f.line5
    else:
        f.line6 = Decimal('1100.00') + Decimal('.50') * f.line5
    f.line6 = cents(f.line6)
예제 #15
0
def compute(form):
    f = form
    f.line3 = f.line1a + f.line1b + f.line2
    f.line4 = cents(Decimal('.9235') * f.line3)

    if f.line4 < Decimal('400.00'):
        f.line5 = zero
        f.line6 = zero
        return

    if f.form_version == u'2014':
        ss_limit = Decimal('117000.00')
        combined_rate = Decimal('.153')
        maximum_ss = Decimal('14508.00')
        medicare_rate = Decimal('.029')
    else:
        ss_limit = Decimal('110100.00')
        combined_rate = Decimal('.133')
        maximum_ss = Decimal('11450.40')
        medicare_rate = Decimal('.029')

    if f.line4 <= ss_limit:
        f.line5 = combined_rate * f.line4
    else:
        f.line5 = maximum_ss + medicare_rate * f.line4
    f.line5 = cents(f.line5)

    if f.form_version >= u'2014':
        f.line6 = cents(f.line5 / 2)
        return

    # TODO: re-check the following

    if f.line5 <= Decimal('14643.30'):
        f.line6 = Decimal('.5751') * f.line5
    else:
        f.line6 = Decimal('1100.00') + Decimal('.50') * f.line5
    f.line6 = cents(f.line6)
예제 #16
0
def compute(form):
    f = form
    f.line3 = f.line1a + f.line1b + f.line2
    if f.line3 >= zero:
        f.line4a = cents(Decimal('.9235') * f.line3)
    else:
        f.line4a = f.line3
    f.line4c = f.line4a + f.line4b

    if f.line4c < Decimal('400.00'):
        f.line5b = zero
        f.line6 = zero
        f.line8d = zero
        f.line9 = zero
        f.line10 = zero
        f.line11 = zero
        f.line12 = zero
        f.line13 = zero
        return

    f.line5b = cents(Decimal('.9235') * f.line5a)
    if f.line5b < Decimal('100.00'):
        f.line5b = zero

    f.line6 = f.line4c + f.line5b

    line7 = cents('113700.00')

    if f.line8a >= line7:
        f.line8d = zero
        f.line9 = zero
        f.line10 = zero
    else:
        raise NotImplementedError()

    f.line11 = cents(f.line6 * Decimal('.029'))
    f.line12 = f.line10 + f.line11
    f.line13 = cents(f.line12 * Decimal('0.5'))
예제 #17
0
def compute(form):
    f = form
    f.line3 = f.line1a + f.line1b + f.line2
    if f.line3 >= zero:
        f.line4a = cents(Decimal('.9235') * f.line3)
    else:
        f.line4a = f.line3
    f.line4c = f.line4a + f.line4b

    if f.line4c < Decimal('400.00'):
        f.line5b = zero
        f.line6 = zero
        f.line8d = zero
        f.line9 = zero
        f.line10 = zero
        f.line11 = zero
        f.line12 = zero
        f.line13 = zero
        return

    f.line5b = cents(Decimal('.9235') * f.line5a)
    if f.line5b < Decimal('100.00'):
        f.line5b = zero

    f.line6 = f.line4c + f.line5b

    line7 = cents('113700.00')

    if f.line8a >= line7:
        f.line8d = zero
        f.line9 = zero
        f.line10 = zero
    else:
        raise NotImplementedError()

    f.line11 = cents(f.line6 * Decimal('.029'))
    f.line12 = f.line10 + f.line11
    f.line13 = cents(f.line12 * Decimal('0.5'))
예제 #18
0
파일: f1040se.py 프로젝트: zrisher/luca
from luca.forms.formlib import Form
from luca.kit import cents, zzstr

title = u"Form 1040 Schedule E: Supplemental Income and Loss"
versions = u'2012', u'2013', u'2014'
zero = cents(0)

def defaults(form):
    f = form
    f.ssn = ''
    f.name = ''
    f.is_1099_required = False
    f.is_1099_filed = False

    f.Part_I = Form()
    f.Part_II = Form()

    for letter in 'ABC':
        setattr(f.Part_I, letter, Form())
        sub = getattr(f.Part_I, letter)
        sub.address = ''
        sub.type = ''
        sub.fair_rental_days = 0
        sub.personal_use_days = 0
        sub.qjv = ''
        for i in range(3, 20):
            setattr(sub, 'line%d' % i, zero)

    for letter in 'ABCD':
        setattr(f.Part_II, letter, Form())
        sub = getattr(f.Part_II, letter)
예제 #19
0
파일: test_kit.py 프로젝트: zrisher/luca
 def test_cents_round_up(self):
     assert cents('1.235') == Decimal('1.24')
예제 #20
0
def run_yaml_file(terminal, path, statement_paths,
                  show_balances, show_data, show_transactions,
                  sort_by='date'):

    t = terminal
    screen_width = int(os.environ.get('COLUMNS', '0')) or t.width or 80

    with open(path) as yaml_file:
        rule_tree = yaml.load(yaml_file, Loader=Loader)

    try:
        rule_tree_function = rules.compile_tree(rule_tree)
    except rules.ParseError as e:
        sys.stderr.write('ERROR: {}\n'.format(e))
        sys.exit(1)

    balances = []
    transactions = []

    for path in statement_paths:
        if path.lower().endswith('.pdf'):
            text = extract_text_from_pdf_file(path)

        elif path.lower().endswith('.txt'):
            with open(path) as text_file:
                text = text_file.read().decode('utf-8')

            matching_importers = [importer for importer in importers
                                  if importer.does_this_match(text)]

            if len(matching_importers) == 0:
                raise RuntimeError('cannot find an importer for file: {}'
                                   .format(path))
            elif len(matching_importers) > 1:
                raise RuntimeError('found too many importers for file: {}'
                                   .format(path))
            else:
                importer = matching_importers[0]

            new_balances, new_transactions = importer(text)

        elif path.lower().endswith('.csv'):
            with open(path) as csv_file:
                new_balances, new_transactions = autocsv.importer(csv_file)

        else:
            raise ValueError('no idea what to do with file {!r}'.format(path))

        balances.extend(new_balances)
        transactions.extend(new_transactions)

    output_lines = []
    add = output_lines.append

    for line in verify_balances(balances, transactions, show_balances, t):
        add(line)

    new_splits = []

    for tr in transactions:
        tr.set_full_text()
        category = rule_tree_function(tr)
        if category is not None and category.startswith('Split '):
            pieces = [piece.strip() for piece in category[6:].split(';')]
            full_amount = tr.amount
            for piece in pieces[:-1]:
                tr2 = copy(tr)
                #tr2.category, amount_str = piece.split()
                tr2.category, amount_str = piece.rsplit(None, 1)
                if amount_str.endswith('%'):
                    percent = Decimal(amount_str[:-1])
                    tr2.amount = cents(full_amount * percent / 100)
                else:
                    tr2.amount = Decimal(amount_str.replace(',', ''))
                new_splits.append(tr2)
                tr.amount -= tr2.amount
            category = pieces[-1]
        tr.category = category

    transactions.extend(new_splits)
    transactions = [tr for tr in transactions if tr.category is not None]

    if show_data:
        sio = StringIO()
        w = csv.writer(sio)
        w.writerow(['date', 'amount', 'category', 'account', 'description'])
        for t in transactions:
            w.writerow([
                t.date, t.amount, t.category, t.account, t.description,
                ])
        return sio.getvalue().splitlines()

    catdict = group_transactions_by_category(transactions)
    sumdict = sum_categories(transactions)
    categories = set(catdict) | set(sumdict)

    max_amount = max(abs(v) for v in sumdict.values())
    amount_width = len('{:,}'.format(max_amount)) + 1

    date_width = 10
    gutter = 1
    category_indent = ' ' * (amount_width + 1)
    description_indent = ' ' * (gutter + date_width + gutter)

    f = _make_formatter(terminal, amount_width)

    for category in sorted(categories, key=_category_key):
        csum = sumdict[category]
        depth = category.count('.')
        if not show_transactions and depth:
            name = category[category.rfind('.')+1:]
        else:
            name = category
        if show_transactions:
            name = t.bold(name)
        add('{}{} {}'.format(category_indent * depth, f(csum), name))
        if not show_transactions:
            continue
        transaction_list = catdict.get(category, None)
        if not transaction_list:
            continue

        if sort_by == 'amount':
            transaction_list.sort(key=lambda t: -t.amount)
        elif sort_by == 'date':
            transaction_list.sort(key=lambda t: t.date)

        add('')

        max_amount2 = max(abs(tr.amount) for tr in transaction_list)
        amount_width2 = max(10, len('{:,}'.format(max_amount2)) + 1)
        f2 = _make_formatter(terminal, amount_width2)

        description_width = (
            screen_width -  # content from left to right:
            gutter - date_width - gutter - # (description goes here)
            gutter - amount_width2 - gutter)

        for tr in transaction_list:
            lines = wrap(tr.description, description_width)
            add(' {} {:<{}} {:>{}}'.format(
                tr.date, lines[0], description_width,
                f2(tr.amount), amount_width2))
            for line in lines[1:]:
                add(description_indent + line)
        add('')

    return output_lines
예제 #21
0
파일: test_kit.py 프로젝트: zrisher/luca
 def test_cents_round_down(self):
     assert cents('1.234') == Decimal('1.23')
예제 #22
0
파일: test_kit.py 프로젝트: B-Rich/luca
 def test_cents_round_down(self):
     assert cents('1.234') == Decimal('1.23')
예제 #23
0
파일: test_kit.py 프로젝트: B-Rich/luca
 def test_cents_round_up(self):
     assert cents('1.235') == Decimal('1.24')
예제 #24
0
파일: f8949.py 프로젝트: B-Rich/luca
from luca.forms.formlib import Form
from luca.kit import cents, zstr

title = u'Form 8949: Sales and Other Dispositions of Capital Assets'
versions = '2011', '2012'
zero = cents(0)

def defaults(form):
    f = form
    f.name = ''
    f.ssn = ''

    build_example_row = {
        '2011': _build_example_row_2011,
        '2012': _build_example_row_2012
        }[form.form_version]

    f.Part_I = Form()
    f.Part_I.box = 'A'
    f.Part_I.table = [
        build_example_row(),
        build_example_row(),
        ]

    f.Part_II = Form()
    f.Part_II.box = 'A'
    f.Part_II.table = [
        build_example_row(),
        build_example_row(),
        ]
예제 #25
0
파일: tally.py 프로젝트: B-Rich/luca
def run_yaml_file(terminal, path, statement_paths,
                  show_balances, show_data, show_transactions):

    t = terminal
    screen_width = int(os.environ.get('COLUMNS', '0')) or t.width or 80

    with open(path) as yaml_file:
        rule_tree = yaml.load(yaml_file, Loader=Loader)

    try:
        rule_tree_function = rules.compile_tree(rule_tree)
    except rules.ParseError as e:
        sys.stderr.write('ERROR: {}\n'.format(e))
        sys.exit(1)

    balances = []
    transactions = []

    for path in statement_paths:
        if path.lower().endswith('.pdf'):
            text = extract_text_from_pdf_file(path)
        elif path.lower().endswith('.txt'):
            with open(path) as text_file:
                text = text_file.read().decode('utf-8')
        else:
            raise ValueError('no idea what to do with file {!r}'.format(path))

        matching_importers = [importer for importer in importers
                              if importer.does_this_match(text)]

        if len(matching_importers) == 0:
            raise RuntimeError('cannot find an importer for file: {}'
                               .format(path))
        elif len(matching_importers) > 1:
            raise RuntimeError('found too many importers for file: {}'
                               .format(path))

        importer = matching_importers[0]
        new_balances, new_transactions = importer(text)
        balances.extend(new_balances)
        transactions.extend(new_transactions)

    output_lines = []
    add = output_lines.append

    for line in verify_balances(balances, transactions, show_balances, t):
        add(line)

    new_splits = []

    for tr in transactions:
        tr.set_full_text()
        category = rule_tree_function(tr)
        if category is not None and category.startswith('Split '):
            pieces = [piece.strip() for piece in category[6:].split(';')]
            for piece in pieces[:-1]:
                tr2 = copy(tr)
                #tr2.category, amount_str = piece.split()
                tr2.category, amount_str = piece.rsplit(None, 1)
                if amount_str.endswith('%'):
                    percent = Decimal(amount_str[:-1])
                    tr2.amount = cents(tr.amount * percent / 100)
                else:
                    tr2.amount = Decimal(amount_str.replace(',', ''))
                new_splits.append(tr2)
                tr.amount -= tr2.amount
            category = pieces[-1]
        tr.category = category

    transactions.extend(new_splits)
    transactions = [tr for tr in transactions if tr.category is not None]

    if show_data:
        sio = StringIO()
        w = csv.writer(sio)
        w.writerow(['date', 'amount', 'category', 'account', 'description'])
        for t in transactions:
            w.writerow([
                t.date, t.amount, t.category, t.account, t.description,
                ])
        return sio.getvalue().splitlines()

    catdict = group_transactions_by_category(transactions)
    sumdict = sum_categories(transactions)
    categories = set(catdict) | set(sumdict)

    max_amount = max(abs(v) for v in sumdict.values())
    amount_width = len('{:,}'.format(max_amount)) + 1

    date_width = 10
    gutter = 1
    category_indent = ' ' * (amount_width + 1)
    description_indent = ' ' * (gutter + date_width + gutter)

    f = _make_formatter(terminal, amount_width)

    for category in sorted(categories, key=_category_key):
        csum = sumdict[category]
        depth = category.count('.')
        if not show_transactions and depth:
            name = category[category.rfind('.')+1:]
        else:
            name = category
        if show_transactions:
            name = t.bold(name)
        add('{}{} {}'.format(category_indent * depth, f(csum), name))
        if not show_transactions:
            continue
        transaction_list = catdict.get(category, None)
        if not transaction_list:
            continue

        add('')

        max_amount2 = max(abs(tr.amount) for tr in transaction_list)
        amount_width2 = max(10, len('{:,}'.format(max_amount2)) + 1)
        f2 = _make_formatter(terminal, amount_width2)

        description_width = (
            screen_width -  # content from left to right:
            gutter - date_width - gutter - # (description goes here)
            gutter - amount_width2 - gutter)

        for tr in transaction_list:
            lines = wrap(tr.description, description_width)
            add(' {} {:<{}} {:>{}}'.format(
                tr.date, lines[0], description_width,
                f2(tr.amount), amount_width2))
            for line in lines[1:]:
                add(description_indent + line)
        add('')

    return output_lines