def sync_all_children(self): # First, unclaim any child lines we've claimed in a previous call to this function. They'll get reclaimed in this function if necessary. self.unclaimed_lines = list(set(self.unclaimed_lines + [line for line in self.final_lines if not line.traded and line.parent])) # This is a copy of self.final_lines, filtered down to not include child lines (except trades) # It's used to detect differences at the end from self.final_lines, and will get assigned there at the end. final_lines = [line for line in self.final_lines if line.traded or not line.parent] # This function can be called more than once in a row, which is necessary if more lines get added as a result # of child lines being added. (You add a smoke package, it has a smoke detector, which requires the smoke service, # hypothetically has a smoke permit kit or something.) # A queue of lines that need their children synced. Starts with final_lines which is the top and traded lines. lines_to_sync = list(final_lines) pos = 0 while pos < len(lines_to_sync): # walk through each line and sync its children. As children get added, they'll be queued onto # the end of this loop, so they can get their nested children. line = lines_to_sync[pos] pos += 1 prod = self.products.get(line.code) if not prod: self.errors.append("Could not find product %r to sync child lines on line %r" % (line.code, line.pk)) continue # Index the contents of this line's product. contents = self.by_code(self.product_contents.get(prod.code, [])) # for every product in that product: for code, pc in contents.iteritems(): child = self.reclaim_line(parent_id=line.pk, code=code, line_type='CHILD') if not child: # If I wasn't able to reclaim an existing child, we need to make a new one for this agreement/line: child = InvoiceLine(agreement=self.agreement, parent=line) # sync the child line with the product (gets updated quantity, product type, category, etc.) child.update_child(product=self.products[code], pc=pc, parent_line=line) # Save this child. It's either been updated or is new. child.save() # Queue up this line to be synced for ITS children lines_to_sync.append(child) # and add it to final_lines final_lines.append(child) # Did the final set of lines change from what we had before? changed = set(final_lines) ^ set(self.final_lines) # And then, assign the final set of children. self.final_lines = final_lines return bool(changed)
def sync_all_children(self): # First, unclaim any child lines we've claimed in a previous call to this function. They'll get reclaimed in this function if necessary. self.unclaimed_lines = list( set(self.unclaimed_lines + [ line for line in self.final_lines if not line.traded and line.parent ])) # This is a copy of self.final_lines, filtered down to not include child lines (except trades) # It's used to detect differences at the end from self.final_lines, and will get assigned there at the end. final_lines = [ line for line in self.final_lines if line.traded or not line.parent ] # This function can be called more than once in a row, which is necessary if more lines get added as a result # of child lines being added. (You add a smoke package, it has a smoke detector, which requires the smoke service, # hypothetically has a smoke permit kit or something.) # A queue of lines that need their children synced. Starts with final_lines which is the top and traded lines. lines_to_sync = list(final_lines) pos = 0 while pos < len(lines_to_sync): # walk through each line and sync its children. As children get added, they'll be queued onto # the end of this loop, so they can get their nested children. line = lines_to_sync[pos] pos += 1 prod = self.products.get(line.code) if not prod: self.errors.append( "Could not find product %r to sync child lines on line %r" % (line.code, line.pk)) continue # Index the contents of this line's product. contents = self.by_code(self.product_contents.get(prod.code, [])) # for every product in that product: for code, pc in contents.iteritems(): child = self.reclaim_line(parent_id=line.pk, code=code, line_type='CHILD') if not child: # If I wasn't able to reclaim an existing child, we need to make a new one for this agreement/line: child = InvoiceLine(agreement=self.agreement, parent=line) # sync the child line with the product (gets updated quantity, product type, category, etc.) child.update_child(product=self.products[code], pc=pc, parent_line=line) # Save this child. It's either been updated or is new. child.save() # Queue up this line to be synced for ITS children lines_to_sync.append(child) # and add it to final_lines final_lines.append(child) # Did the final set of lines change from what we had before? changed = set(final_lines) ^ set(self.final_lines) # And then, assign the final set of children. self.final_lines = final_lines return bool(changed)