def from_database(cls, portal_data, link_list=list()): new = cls(None) new.tags = Tags.from_database(portal_data['tags']) new._parameters = Parameters.from_database(portal_data['parameters'], target='parameters') new._type = portal_data['type'] new.life = LifeCycle.from_database(portal_data['life']) new.location = portal_data['location'] new.size = portal_data['size'] ids = portal_data['used'] real_ids = [ID.from_database(id).bbid for id in ids] new.used = set(real_ids) new.guide = Guide.from_database(portal_data['guide']) new.components = [ ID.from_database(id).bbid for id in portal_data['components'] ] new.interview = InterviewTracker.from_database( portal_data['interview'], link_list) new.summary = None # Obsolete new.valuation = None # Obsolete new.stage = None # Obsolete new._path_archive = portal_data['path_archive'] # don't bother reinfl- # ating archived paths, they won't be used new._used_archive = portal_data['used_archive'] fins = portal_data.get('financials_structure') new_fins = Financials.from_database(fins, new, period=None) new.set_financials(new_fins) new.cap_table = CapTable.from_database(portal_data['cap_table']) return new
def get_line(self, **kargs): """ Model.get_line() -> LineItem --``bbid`` is bbid of line --``buid`` is BU id Method finds a LineItem matching the locator. """ period_end = kargs['period'] bbid = ID.from_database(kargs['bbid']).bbid buid = ID.from_database(kargs['buid']).bbid fins_attr = kargs['financials_attr'] if period_end: key = ( kargs.get('resolution', 'monthly'), kargs.get('name', 'default'), ) time_line = self.timelines[key] if isinstance(period_end, str): period_end = date_from_iso(period_end) period = time_line[period_end] else: period = self.time_line.current_period financials = self.get_financials(buid, period) line = financials.find_line(bbid, fins_attr) return line
def from_database(cls, data, statement): """ LineItem.from_database() -> None **CLASS METHOD** Method deserializes all LineItems belonging to ``statement``. """ # first pass: create a dict of lines new = cls(parent=None, ) new.tags = Tags.from_database(data['tags']) id_str = data['driver_id'] if id_str: new._driver_id = ID.from_database(id_str).bbid # defer resolution of .xl new.xl_data = xl_mgmt.LineData(new) new.xl_format = xl_mgmt.LineFormat.from_database(data['xl_format']) new.summary_type = data['summary_type'] new.summary_count = data['summary_count'] new._consolidate = data['consolidate'] new._replica = data['replica'] new._include_details = data['include_details'] new._sum_details = data['sum_details'] new.log = data['log'] new.guide = Guide.from_database(data['guide']) new.id.bbid = ID.from_database(data['bbid']).bbid position = data['position'] position = int(position) if position else None new.position = position workspace = data.get('workspace', None) if workspace and workspace != 'null': new.workspace.update(workspace) usage = data.get('usage', None) if usage and usage != 'null': new.usage = LineItemUsage.from_database(usage) old_magic_keys = { "kpi", "covenants", "financials", "overall", "business summary" } if 'show on report' in new.tags.all or (new.tags.all & old_magic_keys): new.usage.show_on_report = True if "business summary" in new.tags.all: new.usage.show_on_card = True if 'monitor' in new.tags.all: new.usage.monitor = True return new
def from_database(cls, portal_data, taxo_dir): """ Taxonomy.from_database() -> TaxoDir --``portal_data`` is a dictionary containing serialized TaxoDir data --``model`` is the Model instance the new TaxoDir will be attached to Method deserializes TaxoDir into a rich object from flat portal data. """ new = cls(taxo_dir) for taxo_unit in portal_data: key_list = taxo_unit.pop('keys') temp = new for k in key_list: this_dict = temp if k in this_dict: temp = dict.__getitem__(this_dict, k) else: dict.__setitem__(this_dict, k, cls(taxo_dir)) temp = dict.__getitem__(this_dict, k) id_hex = taxo_unit['bbid'] bbid = ID.from_database(id_hex).bbid if id_hex else None bu = new.taxo_dir.get(bbid) dict.__setitem__(this_dict, k, bu) return new
def from_database(cls, portal_data, statement): target = portal_data.pop('target') line_item = LineItem.from_database(portal_data, statement) new = cls(None) new.__dict__.update(line_item.__dict__) new.target = ID.from_database(target).bbid return new
def from_database(cls, portal_data): new = cls() new.tags = Tags.from_database(portal_data.get('tags')) new.conversion_table = portal_data.get('conversion_table') new.formula_bbid = ID.from_database( portal_data.get('formula_bbid')).bbid new.parameters = Parameters.from_database( portal_data.get('parameters'), target='parameters') new.run_on_past = portal_data.get('run_on_past', False) formula = cls._FM.local_catalog.issue(new.formula_bbid) new.id.set_namespace(formula.id.namespace) new.id.assign(new.name or formula.tags.name) return new
def process(self, message, *pargs, **kargs): """ Analyst.process(message) -> message Method works to improve the model until it's either (i) good enough to stop work altogether or (ii) a question for the user comes up and the Engine needs to pause work. """ n = 0 message = self.choose_direction(message, *pargs, **kargs) # use choose_direction() to for substantive work. method also weeds # out messages that are ready for portal delivery right away. yenta.diary.clear() while self.status in [TOPIC_NEEDED, PENDING_RESPONSE]: # model = message[0] # if self.status == PENDING_RESPONSE: topic_bbid_hex = model.transcript[-1][0]["topic_bbid"] topic_bbid = ID.from_database(topic_bbid_hex).bbid topic = yenta.TM.local_catalog.issue(topic_bbid) logger.info('{} {}'.format(self.status, topic.source)) message = topic.process(message) # elif self.status == TOPIC_NEEDED: topic = yenta.select_topic(model) if topic: logger.info('{} {}'.format(self.status, topic.source)) message = topic.process(message) else: pass # Yenta.select_topic() returned None for Topic, which means # it couldn't find any matches in the Topic Catalog. In such # an event, Yenta notes dry run on focal point and IC shifts # to the next focal point message = self.choose_direction(message, *pargs, **kargs) # the engine has done more work on the model. use choose_direction() # to see if it can stop or needs to continue. # n = n + 1 if n > self.max_cycles: break # circuit-breaker logic # return message
def find_line(self, line_id, statement_attr): """ Financials.find_line() -> LineItem --``line_id`` bbid of line Finds a LineItem across all statements by its bbid. """ if isinstance(line_id, str): line_id = ID.from_database(line_id).bbid statement = self.get_statement(statement_attr) if statement: for line in statement.get_full_ordered(): if line.id.bbid == line_id: return line raise bb_exceptions.StructureError( 'Could not find line with id {}'.format(line_id) )
def from_database(cls, portal_data, model, **kargs): """ TimeLine.from_database(portal_data) -> TimeLine **CLASS METHOD** Method extracts a TimeLine from portal_data. """ if isinstance(portal_data['period_start'], str): period_start = date_from_iso(portal_data['period_start']) period_end = date_from_iso(portal_data['period_end']) else: period_start = portal_data['period_start'] period_end = portal_data['period_end'] new = cls(period_start, period_end) new.complete = portal_data.get('complete') or False new.periods_used = portal_data.get('periods_used') or 1 new.parameters.add( Parameters.from_database(portal_data['parameters'], target='parameters')) new._inflate_line_storage(portal_data['financials_values']) # convert unit_parameters keys to UUID for k, v in Parameters.from_database(portal_data['unit_parameters'], target='unit_parameters').items(): new.unit_parameters.add({ID.from_database(k).bbid: v}) time_line = kargs['time_line'] time_line.add_period(new) return new
def from_database(cls, portal_data, financials): """ Statement.from_database(portal_data) -> Statement **CLASS METHOD** Method extracts a Statement from portal_data. """ new = cls(parent=financials) new.tags = Tags.from_database(portal_data['tags']) if portal_data['bbid'] is not None: new.id.bbid = ID.from_database(portal_data['bbid']).bbid # deserialize all LineItems catalog = dict() for row in portal_data['lines']: if row.get('link'): new_line = Link.from_database(row, new) elif 'driver_id' in row: new_line = LineItem.from_database(row, new) else: new_line = Step.from_database(row) parent_id = row.get('parent_bbid', None) if parent_id is None and new.id.bbid is not None: # no parent id, top-level line belongs to statement parent_id = new.id.bbid.hex if parent_id: par_id = ID.from_database(parent_id).bbid else: par_id = None sub_lines = catalog.setdefault(par_id, list()) sub_lines.append(new_line) if catalog: def build_line_structure(seed, catalog): details = catalog.pop(seed.id.bbid, list()) for line in details: old_bbid = line.id.bbid position = getattr(line, 'position', None) seed.add_line(line, position=position, noclear=True) line.id.bbid = old_bbid build_line_structure(line, catalog) build_line_structure(new, catalog) # DISPLAY TYPE stmt_type = portal_data.get("display_type", None) if stmt_type and stmt_type != "null": new.display_type = stmt_type if new.display_type == "regular" and new.name: if "covenant" in new.name.casefold(): new.display_type = new.COVENANT_TYPE if "kpi" in new.name.casefold(): new.display_type = new.KPI_TYPE # Visible attribute visible = portal_data.get("visible", None) if isinstance(visible, bool): new.visible = visible # Behavioral settings compute = portal_data.get("compute", None) if compute != "null" and compute is not None: new.compute = compute balance_sheet = portal_data.get("balance_sheet", None) if balance_sheet != "null" and balance_sheet is not None: new.balance_sheet = balance_sheet return new
def from_database(cls, portal_data): new = cls() new.__dict__.update(portal_data) new.used = [ID.from_database(id).bbid for id in portal_data['used']] return new
def from_database(cls, portal_model): """ Model.from_database(portal_model) -> Model **CLASS METHOD** Method extracts a Model from portal_model. Method expects ``portal_model`` to be nested dictionary containing all necessary information for rebuilding a Model instance. """ name = portal_model.pop('name', None) M = cls(name) M.portal_data.update(portal_model) business_name = portal_model.get("business_name", None) del portal_model tags = M.portal_data.pop('tags') if tags: M.tags = Tags.from_database(tags) # set basic attributes M._processing_status = M.portal_data.pop('processing_status', 'intake') M._ref_date = M.portal_data.pop('ref_date') if isinstance(M._ref_date, str): M._ref_date = date_from_iso(M._ref_date) M._started = M.portal_data.pop('started') M.topic_list = M.portal_data.pop('topic_list', list()) M.transcript = M.portal_data.pop('transcript', list()) M.report_summary = M.portal_data.pop('report_summary', None) M._fiscal_year_end = M.portal_data.pop('fiscal_year_end') scen = M.portal_data.pop('scenarios') if scen is not None: M.scenarios = scen link_list = list() # first deserialize BusinessUnits into directory temp_directory = dict() bu_list = M.portal_data.pop('business_units', list()) reg_bus = [bu for bu in bu_list if not bu.get('taxonomy', False)] taxo_bus = [bu for bu in bu_list if bu.get('taxonomy', False)] for flat_bu in reg_bus: rich_bu = BusinessUnit.from_database(flat_bu, link_list) rich_bu.relationships.set_model(M) bbid = ID.from_database(flat_bu['bbid']).bbid temp_directory[bbid] = rich_bu # now rebuild structure company_id = M.portal_data.pop('company', None) if company_id: company_id = ID.from_database(company_id).bbid def build_bu_structure(seed, directory): component_list = seed.components seed.components = None seed._set_components() for component_id in component_list: sub_bu = directory[component_id] seed.add_component(sub_bu) build_bu_structure(sub_bu, directory) top_bu = temp_directory[company_id] build_bu_structure(top_bu, temp_directory) M.set_company(top_bu) # TaxoDir if taxo_bus: M.taxo_dir = TaxoDir.from_database(taxo_bus, M, link_list) # Fix Links if link_list: for link in link_list: targ_id = link.target if targ_id in M.bu_directory: link.target = M.bu_directory[targ_id] elif targ_id in M.taxo_dir.bu_directory: link.target = M.taxo_dir.bu_directory[targ_id] else: c = "ERROR: Cannot locate link target: " + targ_id.hex raise LookupError(c) # Taxonomy data = M.portal_data.pop('taxonomy', None) if data: M.taxonomy = Taxonomy.from_database(data, M.taxo_dir) # Target target_id = M.portal_data.pop('target', None) if target_id: target_id = ID.from_database(target_id).bbid try: M.target = M.bu_directory[target_id] except KeyError: M.target = M.taxo_dir.bu_directory[target_id] # reinflate timelines timeline_data = M.portal_data.pop('timelines', list()) if timeline_data: timelines = {} for data in timeline_data: key = (data['resolution'], data['name']) timelines[key] = TimeLine.from_database(data, model=M) M.timelines = timelines # reinflate drivers drivers = M.portal_data.pop('drivers', list()) if drivers: M.drivers = DriverContainer.from_database(drivers) if business_name and business_name != M.title: M.set_name(business_name) M.portal_data.pop('title') M.portal_data.pop('bbid') return M