Skip to content

Commit

Permalink
Merge pull request #83 from SuffolkLITLab/income-post-revisions
Browse files Browse the repository at this point in the history
Spelling; improve logic of ALItemizedJobList.total() and friends
  • Loading branch information
nonprofittechy authored Jul 13, 2022
2 parents e0dcacb + ceaab94 commit f074c7d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 58 deletions.
121 changes: 64 additions & 57 deletions docassemble/ALToolbox/al_income.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def recent_years(
where the most recent ones are most likely. E.g. automobile years or
birthdate.
Keyword paramaters:
Keyword parameters:
* past {float} The number of past years to list, including the current year.
The default is 15
* order {string} 'descending' or 'ascending'. Default is `descending`.
Expand All @@ -103,7 +103,7 @@ class ALIncome(DAObject):
"""
Represents an income which may have an hourly rate or a salary. Hourly rate
incomes must include hours per period (times per year). Period is some
demoninator of a year. E.g, to express a weekly period, use 52. The default
denominator of a year. E.g, to express a weekly period, use 52. The default
is 1 (a year).
Attributes:
Expand Down Expand Up @@ -267,7 +267,7 @@ def gross_total(self, times_per_year: float = 1) -> Decimal:
Same as ALIncome total. Returns the income over the specified times_per_year,
representing the `.value` attribute of the item.
`times_per_year` is some demoninator of a year. E.g. to express a weekly
`times_per_year` is some denominator of a year. E.g. to express a weekly
period, use 52. The default is 1 (a year).
"""
return self.total(times_per_year=times_per_year)
Expand All @@ -278,7 +278,7 @@ def net_total(self, times_per_year: float = 1) -> Decimal:
If the job is hourly, the "net" value may not be comparable to the
gross value.
`times_per_year` is some demoninator of a year. E.g, to express a weekly
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
This will force the gathering of the ALJob's `.net` attribute.
Expand All @@ -303,7 +303,7 @@ def normalized_hours(self, times_per_year: float = 1) -> float:
For example, if the person works 10 hours a week, it will return
520 when the times_per_year parameter is 1.
`times_per_year` is some demoninator of a year. E.g, to express a weekly
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
This will force the gathering of the attributes `.hours_per_period` and
Expand Down Expand Up @@ -336,7 +336,7 @@ def total(
times_per_year. You can filter the jobs by `source`. `source` can be a
string or a list.
`times_per_year` is some demoninator of a year. E.g, to express a weekly
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
"""
return self.gross_total(times_per_year=times_per_year, source=source)
Expand All @@ -349,7 +349,7 @@ def gross_total(
times_per_year. You can filter the jobs by `source`. `source` can be a
string or a list.
`times_per_year` is some demoninator of a year. E.g, to express a weekly
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
"""
self._trigger_gather()
Expand Down Expand Up @@ -380,7 +380,7 @@ def net_total(
If the job is hourly, the `net_total()` may not be comparable to the
`gross_total()`.
`times_per_year` is some demoninator of a year. E.g, to express a weekly
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
"""
self._trigger_gather()
Expand Down Expand Up @@ -418,8 +418,8 @@ class ALAsset(ALIncome):
for a given `times_per_year`, such as interest earned in a checking
account. If not defined, the income will be set to 0, to simplify
representing the many common assets that do not earn any income.
.times_per_year {float} Number of times per year the asset earns the
income listed in the `value` attribute.
.times_per_year {float} (Optional) Number of times per year the asset
earns the income listed in the `value` attribute.
.owner {str} (Optional) Full name of the asset owner as a single string.
.source {str} (Optional) The "source" of the asset, like "vase".
"""
Expand All @@ -429,7 +429,7 @@ def total(self, times_per_year: float = 1) -> Decimal:
Returns the .value attribute divided by the times per year you want to
calculate. The value defaults to 0.
`times_per_year` is some demoninator of a year. E.g, to express a weekly
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
"""
if not hasattr(self, "value") or self.value == "":
Expand Down Expand Up @@ -676,7 +676,7 @@ def init(self, *pargs, **kwargs):

def hook_after_gather(self):
"""
Update item lists after they've been gathered or edited to remove non-existant
Update item lists after they've been gathered or edited to remove non-existent
items. Will still allow the developer to set `auto_gather=False` if they
want without affecting this functionality.
See https://docassemble.org/docs/objects.html#DAList.hook_after_gather.
Expand Down Expand Up @@ -748,8 +748,8 @@ class ALItemizedJob(DAObject):
this job.
Fulfills these requirements:
- A job can be hourly. Its wages will be calcuated with that in mind.
- Despite an hourly job, some individual items must be calcuated using the
- A job can be hourly. Its wages will be calculated with that in mind.
- Despite an hourly job, some individual items must be calculated using the
job's whole period.
- Some items will have their own periods.
- In a list of jobs, a developer may need to access full time and part time
Expand Down Expand Up @@ -778,9 +778,11 @@ def _item_value_per_times_per_year(
self, item: ALItemizedValue, times_per_year: float = 1
) -> Decimal:
"""
Given an item and a times_per_year, returns the value accumulated by the
item for that `times_per_year`, applying the attributes of the top-level
ALItemizedJob, such as `times_per_year` and `is_hourly`.
Given an ALItemizedValue and a times_per_year, returns the value
accumulated by the item for that `times_per_year`, applying the
attributes of the top-level ALItemizedJob, such as `times_per_year` and
`is_hourly` as a default, and otherwise applying the attributes of the
ALItemizedValue.
`times_per_year` is some denominator of a year. E.g, to express a weekly
period, use 52. The default is 1 (a year).
Expand All @@ -789,7 +791,7 @@ def _item_value_per_times_per_year(
arg item {ALItemizedValue} Object containing the value and other props
for an "in" or "out" ALItemizedJob item.
kwarg: times_per_year {float} (Optional) Number of times per year you
want to calcualte. E.g, to express a weekly period, use 52. Default is 1.
want to calculate. E.g, to express a weekly period, use 52. Default is 1.
"""
if times_per_year == 0:
return Decimal(0)
Expand Down Expand Up @@ -839,30 +841,40 @@ def gross_total(
Args:
kwarg: times_per_year {float} (Optional) Number of times per year you
want to calcualte. E.g, to express a weekly period, use 52. Default is 1.
want to calculate. E.g, to express a weekly period, use 52. Default is 1.
kwarg: source {str | [str]} (Optional) Source or list of sources of desired
item(s).
"""
# self.to_add._trigger_gather()
total = Decimal(0)
if times_per_year == 0:
return total
# Make sure we're always working with a list of sources (names?)
sources = self.source_to_list(source=source)
# Add up all money coming in from a source
for key, value in self.to_add.elements.items():
if key in sources:
total += self._item_value_per_times_per_year(
value, times_per_year=times_per_year
if source:
# Make sure we're always working with a list of sources (names?)
# Add up all money coming in from a source
sources = self.source_to_list(source=source)
for key, value in self.to_add.elements.items():
if key in sources:
total += self._item_value_per_times_per_year(
value, times_per_year=times_per_year
)
return total
else:
return Decimal(
sum(
self._item_value_per_times_per_year(
item, times_per_year=times_per_year
)
for item in self.to_add.elements
)
return total
)

def deduction_total(
self, times_per_year: float = 1, source: Union[List[str], str] = None
):
"""
Returns the sum of money going out (normally, deductions like union
dues) divided by a pay times_per_year as a postive value. You can
dues) divided by a pay times_per_year as a positive value. You can
filter the items by `source`. `source` can be a string or a list.
Args:
Expand All @@ -875,15 +887,25 @@ def deduction_total(
total = Decimal(0)
if times_per_year == 0:
return total
# Make sure we're always working with a list of sources (names?)
sources = self.source_to_list(source=source)
# Add all the money going out
for key, value in self.to_subtract.elements.items():
if key in sources:
total += self._item_value_per_times_per_year(
value, times_per_year=times_per_year
if source:
# Make sure we're always working with a list of sources (names?)
# Add up all money coming in from a source
sources = self.source_to_list(source=source)
for key, value in self.to_subtract.elements.items():
if key in sources:
total += self._item_value_per_times_per_year(
value, times_per_year=times_per_year
)
return total
else:
return Decimal(
sum(
self._item_value_per_times_per_year(
item, times_per_year=times_per_year
)
for item in self.to_subtract.elements
)
return total
)

def net_total(
self, times_per_year: float = 1, source: Union[List[str], str] = None
Expand All @@ -895,30 +917,15 @@ def net_total(
Args:
kwarg: times_per_year {float} (Optional) Number of times per year you
want to calcualte. E.g, to express a weekly period, use 52. Default is 1.
want to calculate. E.g, to express a weekly period, use 52. Default is 1.
kwarg: source {str | List[str]} (Optional) Source or list of sources of desired
item(s).
"""
# self.to_add._trigger_gather()
# self.to_subtract._trigger_gather()
total = Decimal(0)
if times_per_year == 0:
return total
# Make sure we're always working with a list of sources (names?)
sources = self.source_to_list(source=source)
# Add up all money coming in
for key, value in self.to_add.elements.items():
if key in sources:
total += self._item_value_per_times_per_year(
value, times_per_year=times_per_year
)
# Subtract the money going out
for key, value in self.to_subtract.elements.items():
if key in sources:
total -= self._item_value_per_times_per_year(
value, times_per_year=times_per_year
)
return total
return self.gross_total(
times_per_year=times_per_year, source=source
) - self.deduction_total(times_per_year=times_per_year, source=source)

def source_to_list(self, source: Union[List[str], str] = None) -> List[str]:
"""
Expand Down Expand Up @@ -1009,7 +1016,7 @@ def gross_total(self, times_per_year=1, source: Union[List[str], str] = None):
desired job items to sum from every itemized job.
E.g. ['tips', 'commissions']
kwarg: times_per_year {float} (Optional) Number of times per year you
want to calcualte. E.g, to express a weekly period, use 52. Default is 1.
want to calculate. E.g, to express a weekly period, use 52. Default is 1.
"""
self._trigger_gather()
total = Decimal(0)
Expand All @@ -1033,7 +1040,7 @@ def deduction_total(
desired job items to sum from every itemized job.
E.g. ['taxes', 'dues']
kwarg: times_per_year {float} (Optional) Number of times per year you
want to calcualte. E.g, to express a weekly period, use 52. Default is 1.
want to calculate. E.g, to express a weekly period, use 52. Default is 1.
"""
self._trigger_gather()
total = Decimal(0)
Expand Down
2 changes: 1 addition & 1 deletion docassemble/ALToolbox/data/questions/al_income_demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ fields:
---
# UNIQUE FOR ALVehicleList
---
# Has to have its own. Otherwise it's overriden by ALAssetList.
# Has to have its own. Otherwise it's overridden by ALAssetList.
generic object: ALVehicleList
code: |
# .source is automatically 'vehicle'
Expand Down

0 comments on commit f074c7d

Please sign in to comment.