Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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)
        )
Esempio n. 9
0
    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
Esempio n. 10
0
    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
Esempio n. 11
0
    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
Esempio n. 12
0
    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