import collections
+
class OrderedSet(collections.MutableSet):
def __init__(self, iterable=None):
retval[key] = Payment._from_toml(self, key, value)
return retval
+ @cached_property
+ def submitted_excluding_subtasks(self) -> Money:
+ retval = Money()
+ for payment in self.payments.values():
+ if payment.submitted is not None or payment.paid is not None:
+ retval += payment.amount
+ return retval
+
+ @cached_property
+ def paid_excluding_subtasks(self) -> Money:
+ retval = Money()
+ for payment in self.payments.values():
+ if payment.paid is not None:
+ retval += payment.amount
+ return retval
+
@property
def parent(self) -> Optional["Node"]:
if self.parent_id is not None:
class BudgetGraph:
nodes: Dict[int, Node]
+ milestone_payments: Dict[Milestone, List[Payment]]
def __init__(self, bugs: Iterable[Bug], config: Config):
self.nodes = OrderedDict()
node.parent.immediate_children.add(node)
self.milestone_payments = OrderedDict()
# useful debug prints
- #for bug in bugs:
+ # for bug in bugs:
# node = self.nodes[bug.id]
# print ("bug added", bug.id, node, node.parent.immediate_children)
subtasks_total += child.fixed_budget_including_subtasks
childlist.append(child.bug.id)
# useful debug prints
- #print ("subtask total", node.bug.id, root.bug.id, subtasks_total,
+ # print ("subtask total", node.bug.id, root.bug.id, subtasks_total,
# childlist)
payees_total = Money(0)
previous_payment = payee_payments.get(payment.payee)
if previous_payment is not None:
# NOT AN ERROR
- print ("NOT AN ERROR", BudgetGraphDuplicatePayeesForTask(
- node.bug.id, root.bug.id,
- previous_payment[-1].payee_key, payment.payee_key))
+ print("NOT AN ERROR", BudgetGraphDuplicatePayeesForTask(
+ node.bug.id, root.bug.id,
+ previous_payment[-1].payee_key, payment.payee_key))
payee_payments[payment.payee].append(payment)
else:
payee_payments[payment.payee] = [payment]
retval[node.assignee].append(node)
return retval
+ @cached_property
+ def assigned_nodes_for_milestones(self) -> Dict[Milestone, List[Node]]:
+ retval = {milestone: []
+ for milestone in self.config.milestones.values()}
+ for node in self.nodes.values():
+ if node.milestone is not None:
+ retval[node.milestone].append(node)
+ return retval
+
@cached_property
def payments(self) -> Dict[Person, Dict[Milestone, List[Payment]]]:
retval = OrderedDict()
milestone_payments = OrderedDict()
for milestone in self.config.milestones.values():
milestone_payments[milestone] = [] # per-person payments
- self.milestone_payments[milestone] = [] # global payments
+ self.milestone_payments[milestone] = [] # global payments
retval[person] = milestone_payments
for node in self.nodes.values():
if node.milestone is not None:
self.milestone_payments[node.milestone].append(payment)
return retval
- def get_milestone_people(self):
+ def get_milestone_people(self) -> Dict[Milestone, OrderedSet]:
"""get a list of people associated with each milestone
"""
- payments = list(self.payments) # just activate the payments
+ payments = list(self.payments) # just activate the payments
retval = OrderedDict()
for milestone in self.milestone_payments.keys():
retval[milestone] = OrderedSet()