def backgroundSaveInstance(self, newFilename=None): cntlr = self.modelXbrl.modelManager.cntlr if newFilename and self.modelXbrl.modelDocument.type != ModelDocument.Type.INSTANCE: self.modelXbrl.modelManager.showStatus(_("creating new instance {0}").format(os.path.basename(newFilename))) self.modelXbrl.modelManager.cntlr.waitForUiThreadQueue() # force status update self.modelXbrl.createInstance(newFilename) # creates an instance as this modelXbrl's entrypoing instance = self.modelXbrl cntlr.showStatus(_("Saving {0}").format(instance.modelDocument.basename)) cntlr.waitForUiThreadQueue() # force status update newCntx = ModelXbrl.AUTO_LOCATE_ELEMENT newUnit = ModelXbrl.AUTO_LOCATE_ELEMENT # check user keyed changes for bodyCell in self.gridBody.winfo_children(): if isinstance(bodyCell, gridCell) and bodyCell.isChanged: value = bodyCell.value objId = bodyCell.objectId if objId: if objId[0] == "f": factPrototypeIndex = int(objId[1:]) factPrototype = self.factPrototypes[factPrototypeIndex] concept = factPrototype.concept entityIdentScheme = self.newFactItemOptions.entityIdentScheme entityIdentValue = self.newFactItemOptions.entityIdentValue periodType = factPrototype.concept.periodType periodStart = self.newFactItemOptions.startDateDate if periodType == "duration" else None periodEndInstant = self.newFactItemOptions.endDateDate qnameDims = factPrototype.context.qnameDims prevCntx = instance.matchContext( entityIdentScheme, entityIdentValue, periodType, periodStart, periodEndInstant, qnameDims, [], []) if prevCntx is not None: cntxId = prevCntx.id else: # need new context newCntx = instance.createContext(entityIdentScheme, entityIdentValue, periodType, periodStart, periodEndInstant, concept.qname, qnameDims, [], [], afterSibling=newCntx) cntxId = newCntx.id # new context if concept.isNumeric: if concept.isMonetary: unitMeasure = qname(XbrlConst.iso4217, self.newFactItemOptions.monetaryUnit) unitMeasure.prefix = "iso4217" # want to save with a recommended prefix decimals = self.newFactItemOptions.monetaryDecimals elif concept.isShares: unitMeasure = XbrlConst.qnXbrliShares decimals = self.newFactItemOptions.nonMonetaryDecimals else: unitMeasure = XbrlConst.qnXbrliPure decimals = self.newFactItemOptions.nonMonetaryDecimals prevUnit = instance.matchUnit([unitMeasure],[]) if prevUnit is not None: unitId = prevUnit.id else: newUnit = instance.createUnit([unitMeasure],[], afterSibling=newUnit) unitId = newUnit.id attrs = [("contextRef", cntxId)] if concept.isNumeric: attrs.append(("unitRef", unitId)) attrs.append(("decimals", decimals)) value = Locale.atof(self.modelXbrl.locale, value, str.strip) newFact = instance.createFact(concept.qname, attributes=attrs, text=value) bodyCell.objectId = newFact.objectId() # switch cell to now use fact ID if self.factPrototypes[factPrototypeIndex] is not None: self.factPrototypes[factPrototypeIndex].clear() self.factPrototypes[factPrototypeIndex] = None #dereference fact prototype else: # instance fact, not prototype fact = self.modelXbrl.modelObject(objId) if fact.concept.isNumeric: value = Locale.atof(self.modelXbrl.locale, value, str.strip) if fact.value != value: if fact.concept.isNumeric and fact.isNil != (not value): fact.isNil = not value if value: # had been nil, now it needs decimals fact.decimals = (self.newFactItemOptions.monetaryDecimals if fact.concept.isMonetary else self.newFactItemOptions.nonMonetaryDecimals) fact.text = value XmlValidate.validate(instance, fact) bodyCell.isChanged = False # clear change flag instance.saveInstance(newFilename) # may override prior filename for instance from main menu cntlr.showStatus(_("Saved {0}").format(instance.modelDocument.basename), clearAfter=3000)
def backgroundSaveInstance(self, newFilename=None): cntlr = self.modelXbrl.modelManager.cntlr if newFilename: self.modelXbrl.modelManager.showStatus( _("creating new instance {0}").format( os.path.basename(newFilename))) self.modelXbrl.modelManager.cntlr.waitForUiThreadQueue( ) # force status update self.modelXbrl.createInstance( newFilename ) # creates an instance as this modelXbrl's entrypoing instance = self.modelXbrl cntlr.showStatus( _("Saving {0}").format(instance.modelDocument.basename)) cntlr.waitForUiThreadQueue() # force status update newCntx = ModelXbrl.AUTO_LOCATE_ELEMENT newUnit = ModelXbrl.AUTO_LOCATE_ELEMENT # check user keyed changes for bodyCell in self.gridBody.winfo_children(): if isinstance(bodyCell, gridCell) and bodyCell.isChanged: value = bodyCell.value objId = bodyCell.objectId if objId: if objId[0] == "f": factPrototypeIndex = int(objId[1:]) factPrototype = self.factPrototypes[factPrototypeIndex] concept = factPrototype.concept entityIdentScheme = self.newFactItemOptions.entityIdentScheme entityIdentValue = self.newFactItemOptions.entityIdentValue periodType = factPrototype.concept.periodType periodStart = self.newFactItemOptions.startDateDate if periodType == "duration" else None periodEndInstant = self.newFactItemOptions.endDateDate qnameDims = factPrototype.context.qnameDims prevCntx = instance.matchContext( entityIdentScheme, entityIdentValue, periodType, periodStart, periodEndInstant, qnameDims, [], []) if prevCntx is not None: cntxId = prevCntx.id else: # need new context newCntx = instance.createContext( entityIdentScheme, entityIdentValue, periodType, periodStart, periodEndInstant, concept.qname, qnameDims, [], [], afterSibling=newCntx) cntxId = newCntx.id # new context if concept.isNumeric: if concept.isMonetary: unitMeasure = qname( XbrlConst.iso4217, self.newFactItemOptions.monetaryUnit) unitMeasure.prefix = "iso4217" # want to save with a recommended prefix decimals = self.newFactItemOptions.monetaryDecimals elif concept.isShares: unitMeasure = XbrlConst.qnXbrliShares decimals = self.newFactItemOptions.nonMonetaryDecimals else: unitMeasure = XbrlConst.qnXbrliPure decimals = self.newFactItemOptions.nonMonetaryDecimals prevUnit = instance.matchUnit([unitMeasure], []) if prevUnit is not None: unitId = prevUnit.id else: newUnit = instance.createUnit( [unitMeasure], [], afterSibling=newUnit) unitId = newUnit.id attrs = [("contextRef", cntxId)] if concept.isNumeric: attrs.append(("unitRef", unitId)) attrs.append(("decimals", decimals)) value = Locale.atof(self.modelXbrl.locale, value, str.strip) newFact = instance.createFact(concept.qname, attributes=attrs, text=value) bodyCell.objectId = newFact.objectId( ) # switch cell to now use fact ID if self.factPrototypes[factPrototypeIndex] is not None: self.factPrototypes[factPrototypeIndex].clear() self.factPrototypes[ factPrototypeIndex] = None #dereference fact prototype else: # instance fact, not prototype fact = self.modelXbrl.modelObject(objId) if fact.concept.isNumeric: value = Locale.atof(self.modelXbrl.locale, value, str.strip) if fact.value != value: fact.text = value XmlValidate.validate(instance, fact) bodyCell.isChanged = False # clear change flag instance.saveInstance() cntlr.showStatus(_("Saved {0}").format( instance.modelDocument.basename), clearAfter=3000)
def genFact(dts, concept, preferredLabel, arcrole, relationshipSet, level, visited, elrInfo): try: if concept is not None: if concept.isHypercubeItem: elrInfo["inCube"] = level elrInfo["dims"] = {} elrInfo["lineItems"] =False elrInfo.pop("instant", None) elrInfo.pop("duration", None) elif concept.isDimensionItem: elrInfo["currentDim"] = concept if concept.isTypedDimension: elrInfo["dims"][concept.qname] = (concept, concept.typedDomainElement) if concept.typedDomainElement.isNumeric: elrInfo["domainIter"] = 1 elif concept.name.endswith("Member") or concept.name.endswith("_member"): # don't generate entries for default dim (Domain) (for now) dimConcept = elrInfo["currentDim"] if dimConcept.qname not in elrInfo["dims"]: elrInfo["dims"][dimConcept.qname] = (dimConcept, concept) else: if concept.name.endswith("LineItems") or concept.name.endswith("_line_items"): elrInfo["lineItems"] = True elif ((not elrInfo["inCube"] or # before any hypercube elrInfo["lineItems"]) # in Cube and within Line Items and not concept.isAbstract): # or within line items # generate a fact sampVals = sampleDataValues[elrInfo.get("domainIter",1)] # use first entry if no domain iter if concept.periodType not in elrInfo: qnameDims = {} for _dimConcept, _domConcept in elrInfo["dims"].values(): if _dimConcept.isExplicitDimension: _memVal = _domConcept.qname else: if _domConcept.type is not None and not _domConcept.isNumeric: _memEltVal = genSampleValue(sampVals, _domConcept) else: _memEltVal = str(elrInfo["domainIter"]) _memVal = XmlUtil.addChild(dts.modelDocument.xmlRootElement, _domConcept.qname, text=_memEltVal, appendChild=False) _dimObj = DimValuePrototype(dts, None, _dimConcept.qname, _memVal, "segment") qnameDims[_dimConcept.qname] = _dimObj elrInfo[concept.periodType] = dts.createContext( dts.conceptSampleScheme or "http://www.treasury.gov", "entityId", concept.periodType, sampVals["periodStart"] if concept.periodType == "duration" else None, sampVals["periodEnd"], concept.qname, qnameDims, [], []) cntx = elrInfo[concept.periodType] cntxId = cntx.id if concept.isNumeric: if concept.isMonetary: unitMeasure = qname(XbrlConst.iso4217, "USD") unitMeasure.prefix = "iso4217" # want to save with a recommended prefix decimals = 2 elif concept.isShares: unitMeasure = XbrlConst.qnXbrliShares decimals = 0 else: unitMeasure = XbrlConst.qnXbrliPure decimals = 0 # check if utr unitId is specified utrUnitId = genSampleUtrUnitId(concept) if utrUnitId is not None: _utrEntries = dts.modelManager.disclosureSystem.utrItemTypeEntries[concept.type.name] if _utrEntries: for _utrEntry in _utrEntries.values(): if _utrEntry.unitId == utrUnitId and _utrEntry.isSimple: unitMeasure = qname(_utrEntry.nsUnit, _utrEntry.unitId) break prevUnit = dts.matchUnit([unitMeasure], []) if prevUnit is not None: unitId = prevUnit.id else: newUnit = dts.createUnit([unitMeasure], []) unitId = newUnit.id value = genSampleValue(sampVals, concept) attrs = [("contextRef", cntxId)] if concept.isNumeric: attrs.append(("unitRef", unitId)) attrs.append(("decimals", decimals)) value = Locale.atof(dts.locale, str(value), str.strip) newFact = dts.createFact(concept.qname, attributes=attrs, text=value) if concept not in visited: visited.add(concept) rels = relationshipSet.fromModelObject(concept) lenRels = len(rels) iRel = 0 iFirstLineItem = None while iRel <= lenRels: if iRel == lenRels: # check if cube needs re-iterating if iFirstLineItem is None or elrInfo.get("domainIter",0) >= 2: break reIterateCube = True # cube can re-iterate else: modelRel = rels[iRel] toConcept = modelRel.toModelObject reIterateCube = (toConcept.isHypercubeItem and # finished prior line items and hitting next table iFirstLineItem is not None and elrInfo["lineItems"] and 1 <= elrInfo.get("domainIter",0) < 2) if reIterateCube: # repeat typed dim container iRel = iFirstLineItem elrInfo["domainIter"] += 1 elrInfo.pop("instant", None) # want new contexts for next iteration elrInfo.pop("duration", None) isFirstLineItem = not elrInfo["lineItems"] genFact(dts, toConcept, modelRel.preferredLabel, arcrole, relationshipSet, level+1, visited, elrInfo) if isFirstLineItem and elrInfo["lineItems"] and elrInfo.get("domainIter",0) > 0: iFirstLineItem = iRel iRel += 1 visited.remove(concept) except AttributeError as ex: # bad relationship print ("[exception] {}".format(ex)) return
def genFact(dts, concept, preferredLabel, arcrole, relationshipSet, level, visited, elrInfo): try: if concept is not None: if concept.isHypercubeItem: elrInfo["inCube"] = level elrInfo["dims"] = {} elrInfo["lineItems"] =False elrInfo.pop("instant", None) elrInfo.pop("duration", None) elif concept.isDimensionItem: elrInfo["currentDim"] = concept if concept.isTypedDimension: elrInfo["dims"][concept.qname] = (concept, concept.typedDomainElement) if concept.typedDomainElement.isNumeric: elrInfo["domainIter"] = 1 elif concept.name.endswith("Member"): # don't generate entries for default dim (Domain) (for now) dimConcept = elrInfo["currentDim"] if dimConcept.qname not in elrInfo["dims"]: elrInfo["dims"][dimConcept.qname] = (dimConcept, concept) else: if concept.name.endswith("LineItems"): elrInfo["lineItems"] = True elif ((not elrInfo["inCube"] or # before any hypercube elrInfo["lineItems"]) # in Cube and within Line Items and not concept.isAbstract): # or within line items # generate a fact sampVals = sampleDataValues[elrInfo.get("domainIter",1)] # use first entry if no domain iter if concept.periodType not in elrInfo: qnameDims = {} for _dimConcept, _domConcept in elrInfo["dims"].values(): if _dimConcept.isExplicitDimension: _memVal = _domConcept.qname else: if _domConcept.type is not None and not _domConcept.isNumeric: _memEltVal = genSampleValue(sampVals, _domConcept) else: _memEltVal = str(elrInfo["domainIter"]) _memVal = XmlUtil.addChild(dts.modelDocument.xmlRootElement, _domConcept.qname, text=_memEltVal, appendChild=False) _dimObj = DimValuePrototype(dts, None, _dimConcept.qname, _memVal, "segment") qnameDims[_dimConcept.qname] = _dimObj elrInfo[concept.periodType] = dts.createContext( "http://treasury.gov", "entityId", concept.periodType, sampVals["periodStart"] if concept.periodType == "duration" else None, sampVals["periodEnd"], concept.qname, qnameDims, [], []) cntx = elrInfo[concept.periodType] cntxId = cntx.id if concept.isNumeric: if concept.isMonetary: unitMeasure = qname(XbrlConst.iso4217, "USD") unitMeasure.prefix = "iso4217" # want to save with a recommended prefix decimals = 2 elif concept.isShares: unitMeasure = XbrlConst.qnXbrliShares decimals = 0 else: unitMeasure = XbrlConst.qnXbrliPure decimals = 0 prevUnit = dts.matchUnit([unitMeasure], []) if prevUnit is not None: unitId = prevUnit.id else: newUnit = dts.createUnit([unitMeasure], []) unitId = newUnit.id value = genSampleValue(sampVals, concept) attrs = [("contextRef", cntxId)] if concept.isNumeric: attrs.append(("unitRef", unitId)) attrs.append(("decimals", decimals)) value = Locale.atof(dts.locale, str(value), str.strip) newFact = dts.createFact(concept.qname, attributes=attrs, text=value) if concept not in visited: visited.add(concept) rels = relationshipSet.fromModelObject(concept) lenRels = len(rels) iRel = 0 iFirstLineItem = None while iRel <= lenRels: if iRel == lenRels: # check if cube needs re-iterating if iFirstLineItem is None or elrInfo.get("domainIter",0) >= 2: break reIterateCube = True # cube can re-iterate else: modelRel = rels[iRel] toConcept = modelRel.toModelObject reIterateCube = (toConcept.isHypercubeItem and # finished prior line items and hitting next table iFirstLineItem is not None and elrInfo["lineItems"] and 1 <= elrInfo.get("domainIter",0) < 2) if reIterateCube: # repeat typed dim container iRel = iFirstLineItem elrInfo["domainIter"] += 1 elrInfo.pop("instant", None) # want new contexts for next iteration elrInfo.pop("duration", None) isFirstLineItem = not elrInfo["lineItems"] genFact(dts, toConcept, modelRel.preferredLabel, arcrole, relationshipSet, level+1, visited, elrInfo) if isFirstLineItem and elrInfo["lineItems"] and elrInfo.get("domainIter",0) > 0: iFirstLineItem = iRel iRel += 1 visited.remove(concept) except AttributeError as ex: # bad relationship print ("[exception] {}".format(ex)) return