Mercurial > pyarq-presupuestos
diff Generic/base.py @ 23:65e7ae0d0e63
GTK2 to GTK3
author | Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es> |
---|---|
date | Thu, 02 May 2019 16:31:17 +0200 |
parents | 7bd4ca56607d |
children | 189f8274aecd |
line wrap: on
line diff
--- a/Generic/base.py Tue Sep 30 17:16:50 2014 +0200 +++ b/Generic/base.py Thu May 02 16:31:17 2019 +0200 @@ -3,7 +3,7 @@ ## File base.py ## This file is part of pyArq-Presupuestos. ## -## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez +## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez ## <miguelangel@obraencurso.es> ## ## pyArq-Presupuestos is free software: you can redistribute it and/or modify @@ -134,7 +134,11 @@ * Description +-- __synonyms: synonyms dictionary. TODO +-- __root: root record code - +-- __decimals: decimals dictionay = { int : Decimals } + +-- __decimals: List with the decimal places used to round the +- result of the calculations with prices and measures +- The values are Decimals objects +- The <0> objets is the default Decimals (seted in FIEBDC-3), +- The others keys are for the diferent groups of Prices * Decimals: +-- DN: Number of decimal places of the field "equal-size parts" in the measure lines. @@ -242,9 +246,25 @@ +-- cif: CIF +-- web: web page +-- email: email + +-- __comment + +-- __date + +-- __budgetType" A integer. Type of data in budget + 0 -> Undefined + 1 -> Base data. + 2 -> Budget. + 3 -> Certificate. + 4 -> Base date update. + +-- __budgetCerficateOrder" Only valid if budgetType is 3. + +-- __budgetCerficateDate" Only valid if budgetType is 3 + +-- __tec_info": Dictionary whith tecnical information + {ti_code : ["desciption text", "unit"]} + +-- __labels": Label dictionary { "label": [ "code", ], } """ # Modules +# python 2/3 compatibility +#from __future__ import absolute_import, division, print_function, unicode_literals + import re import datetime import os @@ -253,6 +273,26 @@ from Generic import fiebdc from Generic import utils + +# Translatable global Vars + +authors = ["Miguel Ángel Bárcena Rodríguez"] +copyright = "Copyright \xc2\xa9 2019 Autoras de Pyarq Presupuestos" +website = "http://pyarq.obraencurso.es/pyarq-Presupuestos" +website_label = "pyarq Presupuestos Web" +comments = _(""" +A free program of measurements, budgets and control of construction sites. +In beta development, still there is not a fully functional version. +""") +help = _( +""" +Usage: + pyarqPresupuestos [file]... + +Help Options: + -h, --help Show this help +""") + class Record(object): """base.Record: @@ -265,23 +305,23 @@ +-- object +-- Record Atributes: - "code": Code string - "recordType": RecordType object - "synonyms": List of synonym codes. - "parents":List of parent codes - "children": Decomposition list, + "code": Write/Read. Code string + "recordType": Write/Read. RecordType object + "synonyms": Write/Read. List of synonym codes. + "parents": Write/Read. List of parent codes + "children": Write/Read. Decomposition list, list of "Decomposition" instances - "unit": measure unit of the record - "summary": Short description of the record - "prices": List of prices/dates - "text": Long Description of the record - "sheet": Sheet of conditions object - "files": List of file object - "labels": List of record labels + "unit": Write/Read. measure unit of the record + "summary": Write/Read. Short description of the record + "prices": Read. List of prices/dates + "text": Write/Read. Long Description of the record + "sheet": Write/Read. Sheet of conditions object + "files": Write/Read. List of file object + "labels": Write/Read. List of record labels Methods: - __getstate__(self) - __setstate__(self, tuple) - __init__(self, filename=None, budget=None) + isPercentage + percentageMasq + hasPercentageMasq(masq) {get/set}Code {get/set}Synonyms {get/set}RecordType @@ -289,7 +329,6 @@ {get/set}Summary {get/set}Prices addPrice - _validate_price_date getPrice getAmount getDate @@ -351,23 +390,42 @@ self.files = [] self.labels = [] + def isPercentage(self): + if "%" in self.__code or "&" in self.__code: + return True + else: + return False + + def percentageMasq(self): + if "%" in self.__code: + return self.__code.split("%")[0] + elif "&" in self.__code: + return self.__code.split("&")[0] + + def hasPercentageMasq(self, masq): + if len(self.__code) >= len(masq): + _part_code = self.__code[:len(masq)] + if _part_code == masq: + return True + return False + def getCode(self): return self.__code def setCode(self, code): - """setCode(self,code) + """setCode(code) Sets the code, must be a valid code """ if not utils.is_valid_code(code)[0]: - raise ValueError, utils.mapping(_("Invalid code: $1"),(str(code),)) + raise ValueError( utils.mapping(_("Invalid code: $1"),(str(code),)) ) self.__code = code def getSynonyms(self): return self.__synonyms def setSynonyms(self,synonyms): - """setSynonyms(self,synonyms) + """setSynonyms(synonyms) Sets the synonyms codes of the record. synonyms must fulfill: @@ -375,19 +433,19 @@ - the items must be valid codes """ if not isinstance(synonyms, list): - raise TypeError, utils.mapping(_("Synonyms ($1) must be a list, " \ - "code: $2"), (str(synonyms), self.__code)) + raise TypeError( utils.mapping(_("Synonyms ($1) must be a list, " \ + "code: $2"), (str(synonyms), str(self.__code))) ) for code in synonyms: if not utils.is_valid_code(code)[0]: - raise ValueError, utils.mapping(_("Invalid Code in synomyms "\ - "list ($1) code: $2"), (str(code), self.__code)) + raise ValueError( utils.mapping(_("Invalid Code in synomyms "\ + "list ($1) code: $2"), (str(code), str(self.__code))) ) self.__synonyms = synonyms def getRecordType(self): return self.__recordType def setRecordType(self, recordType): - """setRecordType(self, recordType) + """setRecordType(recordType) Set the record type. recordType (hierarchy, type,subtype) @@ -404,35 +462,35 @@ return self.__unit def setUnit(self,unit): - """setUnit(self,unit) + """setUnit(unit) Set the unit of measure The unit must be a string. """ if not isinstance(unit, str): - raise TypeError, utils.mapping(_("Unit ($1) must be a string: $2"), - (str(unit), self.__code)) + raise TypeError( utils.mapping(_("Unit ($1) must be a string: $2"), + (str(unit), str(self.__code))) ) self.__unit = unit def getSummary(self): return self.__summary def setSummary(self,summary): - """setSummary(self,summary) + """setSummary(summary) Set the summary of a record The summary must be a string. """ if not isinstance(summary, str): - raise TypeError, utils.mapping(_("Summary ($1) must be a string: "\ - "$1"), (str(summary), self.__code)) + raise TypeError( utils.mapping(_("Summary ($1) must be a string: "\ + "$1"), (str(summary), str(self.__code))) ) self.__summary = summary def getPrices(self): return self.__prices def setPrices(self, prices, decimals): - """setPrice(self, prices, decimals) + """setPrice(prices, decimals) Set the price list of the record. prices must fulfill: @@ -441,8 +499,8 @@ - the first item: price must be a float """ if not isinstance(prices, list): - raise TypeError, utils.mapping(_("Prices ($1) must be a list: $2"), - (str(prices), self.__code)) + raise TypeError( utils.mapping(_("Prices ($1) must be a list: $2"), + (str(prices), str(self.__code))) ) for index in range(len(prices)): _price_date = prices[index] _price_date = self._validate_price_date(_price_date, decimals) @@ -450,7 +508,7 @@ self.__prices = prices def addPrice(self, price_date, decimals): - """addPrice(self, price_date, decimals) + """addPrice(price_date, decimals) Add a price to the price list of the record. price must fulfill: @@ -462,14 +520,14 @@ def _validate_price_date(self, price_date, decimals): if not isinstance(price_date, list) and len(price_date) == 2: - raise ValueError, utils.mapping(_("Price ($1) must be a list"\ - " with two items: $2"), (str(price_date), self.__code)) + raise ValueError( utils.mapping(_("Price ($1) must be a list"\ + " with two items: $2"), (str(price_date), str(self.__code))) ) _price = price_date[0] _date = price_date[1] if not isinstance(_price, float): - raise TypeError, utils.mapping(_("Price must be a float "\ - "number: $1"), (str(_price),)) - _D = decimals.getD(self.recordType) + raise TypeError( utils.mapping(_("Price must be a float "\ + "number: $1"), (str(_price),)) ) + _D = abs(decimals.getD(self.recordType)) _price = round(_price, _D) price_date[0] = _price # TODO: validate date @@ -477,20 +535,20 @@ def getPrice(self, index_price): if len(self.__prices) <= index_price: - raise IndexError, _("The record do not have this Price. Code: %s" - % self.__code) + raise IndexError( _("The record do not have this Price. Code: %s" + % self.__code) ) return self.__prices[index_price][0] def getDate(self, index_price): if len(self.__prices) <= index_price: - raise IndexError, _("The record do not have this Price") - return self.__prices[index_price][1] + raise IndexError( _("The record do not have this Price") ) + return self.__prices[index_price][1] def getParents(self): return self.__parents def setParents(self,parents): - """setParents(self,parents) + """setParents(parents) Sets the list of parents codes of the record. parents must fulfill @@ -498,31 +556,31 @@ - the items must be valid codes """ if not isinstance(parents, list): - raise TypeError, utils.mapping(_("Parents ($1) must be a list: $2"), - (str(parents), self.__code)) + raise TypeError( utils.mapping(_("Parents ($1) must be a list: $2"), + (str(parents), str(self.__code))) ) for parent in parents: if not utils.is_valid_code(parent)[0]: - raise ValueError, utils.mapping(_("Invalid parent code ($1) " \ - "in the record: $2"), (str(padre), self.__code)) + raise ValueError(utils.mapping(_("Invalid parent code ($1) " \ + "in the record: $2"), (str(padre), str(self.__code))) ) self.__parents = parents def appendParent(self, parent): - """appendParent(self, parent) + """appendParent(parent) parent must be a valid code Append a parent to the list of parents codes of the record. """ if not utils.is_valid_code(parent)[0]: - raise ValueError, utils.mapping(_("Invalid parent code ($1) " \ - "in the record: $2"), (str(parent), self.__code)) + raise ValueError( utils.mapping(_("Invalid parent code ($1) " \ + "in the record: $2"), (str(parent), str(self.__code))) ) self.__parents.append(parent) def getchildren(self): return self.__children def setchildren(self,children): - """setchildren(self,children) + """setchildren(children) Sets the list of children of a record children must fulfill @@ -530,13 +588,13 @@ - the items must be instances of Decomposition class """ if not isinstance(children, list): - raise TypeError, utils.mapping(_("children ($1) must be a list, "\ - "record: $2"), (str(children), self.__code)) + raise TypeError( utils.mapping(_("children ($1) must be a list, "\ + "record: $2"), (str(children), str(self.__code))) ) for _child in children: if not isinstance(_child, Decomposition): - raise ValueError, utils.mapping(_("child ($1) must be a "\ + raise ValueError( utils.mapping(_("child ($1) must be a "\ "Decomposition object, record: $2"), - (str(_child), self.__code)) + (str(_child), str(self.__code))) ) _record_code = self.code for _measure_list in [_child.budgetMeasures, _child.certification, _child.real_cost, _child.cost_goals, @@ -548,7 +606,7 @@ def appendChild(self, child_code, decimals, factor=0.0, yield_=0.0, measure=0.0, measure_list=None, type_=None, label=None): - """appendChildren(self, child_code, factor=0.0, yield_=0.0, + """appendChildren(child_code, factor=0.0, yield_=0.0, measure=0.0, measure_list=None, type_=None, label=None)) position: @@ -582,40 +640,39 @@ return self.__text def setText(self,text): - """setText(self,text) + """setText(text) Sets the text of the record It must be a string """ if not isinstance(text, str): - raise TypeError, utils.mapping(_("Text ($1) must be a string, "\ - "record: $2"), (str(text), self.__code)) + raise TypeError( utils.mapping(_("Text ($1) must be a string, "\ + "record: $2"), (str(text), str(self.__code))) ) self.__text = text def getSheet(self): return self.__sheet def setSheet(self, sheet): - """setSheet(self, sheet) + """setSheet(sheet) Sets the sheet of condition object """ if not isinstance(sheet, Sheet): - raise ValueError, _("sheet must be a Sheet instance") + raise ValueError( _("sheet must be a Sheet instance") ) self.__sheet = sheet def getFiles(self): return self.__files def setFiles(self, files): - """setFiles(self, files) + """setFiles(files) Sets the files list """ - # TODO: only sets files and File object format (durusdatabase) if not isinstance(files, list): - raise ValueError, utils.mapping(_("files must be a list: $1"), - str(files)) + raise ValueError( utils.mapping(_("files must be a list: $1"), + str(files)) ) _files = [] for file in files: if isinstance(file, File): @@ -625,22 +682,21 @@ _type = file[1] _description = file[2] if not os.path.exists(file[0]): - raise ValueError, _("Incorrect path") + raise ValueError( _("Incorrect path") ) _file = File(file_path, type_, description) _files.append(_file) else: - raise ValueError, utils.mapping(_( - "file must be a list or a File object: $1"),str(file)) + raise ValueError( utils.mapping(_( + "file must be a list or a File object: $1"),str(file)) ) self.__files = _files - def addFile(self, file_path, type_, description): - """addFile(self, file_path, type_, description) + """addFile(file_path, type_, description) Add a file to a record instance """ if not os.path.exists(file_path): - raise ValueError, _("Incorrect path") + raise ValueError( _("Incorrect path") ) _name = os.path.basename(file_path) _isin = False for _ofile in self.__files: @@ -654,32 +710,32 @@ return self.__labels def setLabels(self, labels): - """setLabels(self, labels) + """setLabels(labels) Sets the labels list of a record """ if not isinstance(labels, list): - raise ValueError, _("labels must be a list") + raise ValueError( _("labels must be a list") ) _labels = [] for _label in labels: if isinstance(_label, str): _labels.append(_label) else: - raise ValueError, _("label must be a string") + raise ValueError( _("label must be a string") ) self.__labels = _labels def addLabel(self, label): - """addLabel(self, label) + """addLabel(label) Add a label to a record instance """ if not isinstance(label, str): - raise ValueError, _("Label must be a string") + raise ValueError( _("Label must be a string") ) if not label in self.__labels: self.__labels.append(label) def getChildPositions(self, child_code): - """getChildPath(self, child_code): + """getChildPath(child_code): Try to return positions of a childcode """ @@ -723,6 +779,7 @@ labels = property(getLabels, setLabels, None, """Label list""") + class ParametricRecord(Record): """base.ParametricRecord: @@ -784,7 +841,7 @@ self.__vars = tuple[17] self.__parametric_summary = tuple[18] self.__parametric_text = tuple[19] - + def __init__(self, budget, code, synonyms, hierarchy, unit, summary, prices, type_, subtype, parents=None, text=None): if parents is None: @@ -813,6 +870,7 @@ def setSelectComment(self, select_comment): self.__select_comment = select_comment + def getVar(self, var): if var in self.__vars: return self.__vars[var] @@ -851,6 +909,7 @@ """Seclect comment """) + class Decomposition(object): """base.Decomposition: @@ -872,10 +931,6 @@ "cost_goals": list of cost goals of construction for months measures "cost_planned": list of costs planned and amended cost planned measures Methods: - __getstate__(self) - __setstate__(self, tuple) - __init__( position, code, budgetMeasures, certification=None, - real_cost=None, cost_goals=None, cost_planned=None) {get/set}position {get/set}Code {get/set}BudgetMeasures @@ -884,6 +939,7 @@ {get/set}CostGoals {get/set}CostPlanned """ + __slots__ = ["_Decomposition__position", "_Decomposition__code", "_Decomposition__budgetMeasures", @@ -892,10 +948,12 @@ "_Decomposition__cost_goals", "_Decomposition__cost_planned", ] + def __getstate__ (self): return (self.__position, self.__code, self.__budgetMeasures, self.__certification, self.__real_cost, self.__cost_goals, self.__cost_planned) + def __setstate__(self,tuple): self.__position = tuple[0] self.__code = tuple[1] @@ -914,50 +972,65 @@ self.real_cost = real_cost self.cost_goals = cost_goals self.cost_planned = cost_planned + def getPosition(self): return self.__position + def setPosition(self, position): if not isinstance(position, int): - raise ValueError, _("Position must be a integer") + raise ValueError( _("Position must be a integer") ) self.__position = position + def getCode(self): return self.__code + def setCode(self, code): self.__code = code + def getBudgetMeasures(self): return self.__budgetMeasures + def setBudgetMeasures(self, budgetMeasures): if not isinstance(budgetMeasures, list): - raise ValueError, _("BudgetMeasures atribute must be a list") + raise ValueError( _("BudgetMeasures atribute must be a list") ) for _measure in budgetMeasures: if not isinstance(_measure, Measure): - raise ValueError, _("BudgetMeasures item must be a Measure "/ - "object") + raise ValueError( _("BudgetMeasures item must be a Measure "/ + "object") ) self.__budgetMeasures = budgetMeasures + def getCertification(self): return self.__certification + def setCertification(self, certification): if not (certification is None or isinstance(certification, list)): - raise ValueError, _("Certification atribute must be a list or None") + raise ValueError( _("Certification atribute must be a list or None") ) self.__certification = certification + def getRealCost(self): return self.__real_cost + def setRealCost(self, real_cost): if not (real_cost is None or isinstance(real_cost, list)): - raise ValueError, _("Real cost atribute must be a list or None") + raise ValueError( _("Real cost atribute must be a list or None") ) self.__real_cost = real_cost + def getCostGoals(self): return self.__cost_goals + def setCostGoals(self, cost_goals): if not (cost_goals is None or isinstance(cost_goals, list)): - raise ValueError, _("Cost goals atribute must be a list or None") + raise ValueError( _("Cost goals atribute must be a list or None") ) self.__cost_goals = cost_goals + def getCostPlanned(self): return self.__cost_planned + def setCostPlanned(self, cost_planned): if not (cost_planned is None or isinstance(cost_planned, list)): - raise ValueError, _("Cost Planned atribute must be a list or None") + raise ValueError( _("Cost Planned atribute must be a list or None") ) self.__cost_planned = cost_planned + position = property(getPosition, setPosition, None, """Postion of the record in the budget """) @@ -1000,10 +1073,6 @@ "yield": "fixed": If fixed is True the yield is not calculated from measure Methods: - __getstate__() - __setstate__(tuple) - __init__(decimals, recordType, measure, lines, - label, factor, yield_) getMeasure() setMeasure(measure, decimals) {get/set}Lines @@ -1018,15 +1087,18 @@ calculateMeasure(decimals) updateYield(decimals) """ + __slots__ = ["_Measure__measure", "_Measure__lines", "_Measure__label", "_Measure__factor", "_Measure__yield_", "_Measure__fixed"] + def __getstate__ (self): return (self.__measure, self.__lines, self.__label, self.__factor, self.__yield_, self.__fixed) + def __setstate__(self,tuple): self.__measure = tuple[0] self.__lines = tuple[1] @@ -1034,6 +1106,7 @@ self.__factor = tuple[3] self.__yield_ = tuple[4] self.__fixed = tuple[5] + def __init__(self, decimals, recordType, measure, lines, label, factor, yield_): self.setMeasure(measure, decimals) @@ -1045,45 +1118,50 @@ def getMeasure(self): return self.__measure + def setMeasure(self, measure, decimals): if not isinstance(measure, float): - raise ValueError, utils.mapping(_("Measure must be a float "\ - "number. Type: $1"), (type(measure),)) + raise ValueError( utils.mapping(_("Measure must be a float "\ + "number. Type: $1"), (type(measure),)) ) # TODO: test after - _DS = decimals.DS + _DS = abs(decimals.DS) measure = round(measure, _DS) self.__measure = measure def getLines(self): return self.__lines + def setLines(self, lines): if not isinstance(lines, list): - raise ValueError, _("Lines must be a list") + raise ValueError( _("Lines must be a list") ) for _line in lines: if not isinstance(_line, MeasureLine): - raise ValueError, _("Line must be a MeasureLine objetc") + raise ValueError( _("Line must be a MeasureLine objetc") ) self.__lines = lines + def getLabel(self): return self.__label + def setLabel(self, label): self.__label = label + def setFactor(self, factor, decimals, recordType): if not isinstance(factor, float): - raise ValueError, utils.mapping(_("Factor must be a float number "\ - "|$1|"), (factor,)) + raise ValueError( utils.mapping(_("Factor must be a float number "\ + "|$1|"), (str(factor),)) ) # TODO: test after - _DF = decimals.getDF(recordType) + _DF = abs(decimals.getDF(recordType)) factor = round(factor, _DF) self.__factor = factor def getFactor(self): return self.__factor - + def setYield(self, yield_, decimals, recordType): if not isinstance(yield_, float): - raise ValueError, _("Yield must be a float number") + raise ValueError( _("Yield must be a float number") ) # TODO: test after - _DR = decimals.getDR(recordType) + _DR = abs(decimals.getDR(recordType)) yield_ = round(yield_, _DR) self.__yield_ = yield_ @@ -1092,7 +1170,7 @@ def setFixed(self, fixed, decimals): if not isinstance(fixed, bool): - raise ValueError, _("Fixed must be boolean object") + raise ValueError( _("Fixed must be boolean object") ) self.__fixed = fixed self.updateYield(decimals) @@ -1162,8 +1240,8 @@ elif type_ == "A": self.lines.extend(_lines) else: - raise ValueError, utils.mapping(_("Type must be M or A. Type: $1"), - (type_,)) + raise ValueError( utils.mapping(_("Type must be M or A. Type: $1"), + (str(type_),)) ) self.calculateMeasure(decimals, recordType) def calculateMeasure(self, decimals, recordType): @@ -1181,8 +1259,9 @@ line.setParcialSubtotal(_parcialSubtotal, decimals) _parcial_total = _acumulated_total self.setMeasure(_acumulated_total, decimals) - _DR = decimals.getDR(recordType) + _DR = abs(decimals.getDR(recordType)) self.updateYield(decimals, recordType) + def updateYield(self, decimals, recordType): if not self.fixed: self.setYield(self.measure, decimals, recordType) @@ -1217,10 +1296,6 @@ "parcial_subtotal" "acumulated_subtotal" Methods: - __getstate__(self) - __setstate__(self, tuple) - __init__(self, decimals, type_, comment, units, length, width, height, - formula) {get/set}LineType {get/set}Comment {get/set}Units @@ -1234,6 +1309,7 @@ calculateParcial eval_formula """ + __slots__ = ["_MeasureLine__lineType", "_MeasureLine__comment", "_MeasureLine__units", @@ -1245,10 +1321,12 @@ "_MeasureLine__parcial_subtotal", "_MeasureLine__acumulated_subtotal", ] + def __getstate__ (self): return (self.__lineType, self.__comment, self.__units, self.__length, self.__width, self.__height, self.__formula, self.__parcial) + def __setstate__(self,tuple): self.__lineType = tuple[0] self.__comment = tuple[1] @@ -1259,6 +1337,7 @@ self.__formula = tuple[6] self.__parcial = tuple[7] #self.calculateParcial() + def __init__(self, decimals, type_, comment, units, length, width, height, formula): self.__parcial = 0.0 @@ -1272,43 +1351,56 @@ self.setHeight(height, decimals) self.setFormula(formula, decimals) #self.calculateParcial() + def getLineType(self): return self.__lineType + def getComment(self): return self.__comment + def getUnits(self): return self.__units + def getLength(self): return self.__length + def getWidth(self): return self.__width + def getHeight(self): return self.__height + def getFormula(self): return self.__formula + def getParcial(self): return self.__parcial + def getParcialSubtotal(self): return self.__parcial_subtotal + def getAcumulatedSubtotal(self): return self.__acumulated_subtotal + def setParcialSubtotal(self, parcial_subtotal, decimals): if not isinstance(parcial_subtotal, float): - raise ValueError, utils.mapping(_(" Parcial Subtotal must be a "\ - "float number. Parcial: $1"), (str(parcial_subtotal),)) - _DS = decimals.DS + raise ValueError( utils.mapping(_(" Parcial Subtotal must be a "\ + "float number. Parcial: $1"), (str(parcial_subtotal),)) ) + _DS = abs(decimals.DS) parcial_subtotal = round(parcial_subtotal, _DS) self.__parcial_subtotal = parcial_subtotal + def setAcumulatedSubtotal(self, acumulated_subtotal, decimals): if not isinstance(acumulated_subtotal, float): - raise ValueError, utils.mapping(_(" Acumulated Subtotal must be "\ + raise ValueError( utils.mapping(_(" Acumulated Subtotal must be "\ "a float number. Parcial: $1"), - (str(acumulated_subtotal),)) - _DS = decimals.DS + (str(acumulated_subtotal),)) ) + _DS = abs(decimals.DS) acumulated_subtotal = round(acumulated_subtotal, _DS) self.__acumulated_subtotal = acumulated_subtotal + def calculateParcial(self, decimals): - _DS = decimals.DS + _DS = abs(decimals.DS) if self.lineType == 1 or self.lineType == 2: _parcial = 0.0 elif self.lineType == 0: # self.formula == "": @@ -1336,69 +1428,75 @@ def setLineType(self, type_): if not type_ in [0, 1, 2, 3]: - raise ValueError, utils.mapping(_("Invalid measure line type ($1)"), - (str(type_),)) + raise ValueError( utils.mapping(_("Invalid measure line type ($1)"), + (str(type_),)) ) self.__lineType = type_ + def setComment(self, comment): if not isinstance(comment, str): - raise ValueError, utils.mapping(_("Measure Comment must be a "\ - "string ($1)"), (str(comment),)) + raise ValueError( utils.mapping(_("Measure Comment must be a "\ + "string ($1)"), (str(comment),)) ) self.__comment = comment + def setUnits(self, units, decimals): if units != "": if not isinstance(units, float): - raise ValueError, utils.mapping(_("Invalid Measure Units ($1)"), - (str(units),)) - _DN = decimals.DN + raise ValueError( utils.mapping(_("Invalid Measure Units ($1)"), + (str(units),)) ) + _DN = abs(decimals.DN) units = round(units, _DN) self.__units = units try: self.calculateParcial(decimals) except AttributeError: pass + def setLength(self, length, decimals): if length != "": if not isinstance(length, float): - raise ValueError, utils.mapping(_("Invalid Measure length ($1)"), - (str(units),)) - _DD = decimals.DD + raise ValueError( utils.mapping(_("Invalid Measure length ($1)"), + (str(units),)) ) + _DD = abs(decimals.DD) length = round(length, _DD) self.__length = length try: self.calculateParcial(decimals) except AttributeError: pass + def setWidth(self, width, decimals): if width != "": if not isinstance(width, float): - raise ValueError, utils.mapping(_("Invalid Measure Width ($1)"), - (str(units),)) - _DD = decimals.DD + raise ValueError( utils.mapping(_("Invalid Measure Width ($1)"), + (str(units),)) ) + _DD = abs(decimals.DD) width = round(width, _DD) self.__width = width try: self.calculateParcial(decimals) except AttributeError: pass + def setHeight(self, height, decimals): if height != "": if not isinstance(height, float): - raise ValueError, utils.mapping(_("Invalid Measure Height ($1)"), - (str(height),)) - _DD = decimals.DD + raise ValueError( utils.mapping(_("Invalid Measure Height ($1)"), + (str(height),)) ) + _DD = abs(decimals.DD) height = round(height, _DD) self.__height = height try: self.calculateParcial(decimals) except AttributeError: pass + def setFormula(self, formula, decimals): if not isinstance(formula, str): - raise ValueError, utils.mapping(_("Formula must be a "\ - "string ($1)"), (str(formula),)) + raise ValueError( utils.mapping(_("Formula must be a "\ + "string ($1)"), (str(formula),)) ) if re.match(".*[^0123456789\.()\+\-\*/\^abcdp ].*", formula): - raise ValueError, utils.mapping(_("There is invalid characters"\ - "in formula ($1)"), (str(formula),)) + raise ValueError( utils.mapping(_("There is invalid characters"\ + "in formula ($1)"), (str(formula),)) ) self.__formula = formula try: self.calculateParcial(decimals) @@ -1437,6 +1535,7 @@ None, None, """Parcial subtotal """) + def eval_formula(self): """eval_formula() @@ -1462,19 +1561,19 @@ try: a = float(a) except: - raise ValueError, _("'a' value must be a float number") + raise ValueError( _("'a' value must be a float number") ) try: b = float(b) except: - raise ValueError, _("'b' value must be a float number") + raise ValueError( _("'b' value must be a float number") ) try: c = float(c) except: - raise ValueError, _("'c' value must be a float number") + raise ValueError( _("'c' value must be a float number") ) try: d = float(d) except: - raise ValueError, _("'d' value must be a float number") + raise ValueError( _("'d' value must be a float number") ) # spaces are erased formula.replace(" ","") # operators and varibles are replaced @@ -1502,7 +1601,8 @@ try: return eval(_formula2, _g) except: - raise ValueError, _("Invalid formula") + raise ValueError( _("Invalid formula") ) + class Decimals(object): """base.Decimals: @@ -1587,13 +1687,6 @@ Default: 2 decimal places. "DIVISA": monetary unit. Methods: - __init__(DN=2, DD=2, DSP=2, DS=2, - DFC=3, DFPU=3, DFUO=3, DFA=3, - DRC=3, DRPU=3, DRUO=3, DRA=3, - DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2, - DIR=2, DIRC=2, DCD=2, - DIVISA="EUR") - __getitem__(key) haskey(key) getD(recordtype) getDF(recordType) @@ -1601,6 +1694,7 @@ getDI(recordType) """ # TODO: get/set methods + def __init__(self, DN=2, DD=2, DSP=2, DS=2, DFC=3, DFPU=3, DFUO=3, DFA=3, @@ -1632,10 +1726,13 @@ self.DIRC = DIRC self.DCD = DCD self.DIVISA = DIVISA + def __getitem__(self, key): return self.__dict__[key] + def haskey(self, key): return key in self.__dict__ + def getD(self, recordType): # DP: budget. # DC: chapter and subcharter. @@ -1662,6 +1759,7 @@ else: # unit type 0, subtipe ["EU", "EC", "EF", "PA"] _decimal = self.DUO return _decimal + def getDF(self, recordType): # Factor: DF # ->DFP: Budget @@ -1681,6 +1779,7 @@ else: # unit EU EC EF PA _decimal = self.DFUO return _decimal + def getDR(self, recordType): # Yield: DR # ->DRP: Budget @@ -1700,6 +1799,7 @@ else: # unit _decimal = self.DRUO return _decimal + def getDI(self, recordType): # DIRC: budget, chapter and subcharter. # DIR: unit, auxiliar element. @@ -1716,6 +1816,7 @@ _decimal = self.DIR return _decimal + class Sheet(object): """base.Sheet: Description: @@ -1731,9 +1832,6 @@ <Section key>: must be in Budget.SheetSections <Paragraph key>: must be in Budget.SheetParagraph Methods: - __getstate__(self) - __setstate__(self, tuple) - __init__(self, sheet_dict={}) {get/set}Sheet_dict getFields getSections @@ -1742,108 +1840,121 @@ addSection """ __slots__ = ["_Sheet__sheet_dict"] + def __getstate__ (self): return (self.__sheet_dict,) + def __setstate__(self,tuple): self.__sheet_dict = tuple[0] + def __init__(self): self.__sheet_dict = {} + def getSheet_dict(self): return self.__sheet_dict + def setSheet_dict(self, sheet_dict): if not isinstance(sheet_dict, dict): - raise ValueError, _("sheet_dict must be a dictionay") + raise ValueError( _("sheet_dict must be a dictionay") ) self.__sheet_dict = sheet_dict + def getFields(self): return self.sheet_dict.keys() + def getSections(self, field): if field in self.__sheet_dict: return self.__sheet_dict[field].keys() else: return None + def getParagraph(self, field, section): if (field in self.__sheet_dict and section in self.__sheet_dict[field]): return self.__sheet_dict[field][section] else: return None + def addField(self, field, section_dict): if not isinstance(field, str): - raise ValueError, _("sheet field must be a string") + raise ValueError( _("sheet field must be a string") ) if not isinstance(section_dict, dict): - raise ValueError, _("section_dict must be a dictionary") + raise ValueError( _("section_dict must be a dictionary") ) self.__sheet_dict[field] = section_dict + def addSection(self, field, section, paragraph): if not isinstance(field, str): - raise ValueError, _("sheet field must be a string") + raise ValueError( _("sheet field must be a string") ) if not isinstance(section, str): - raise ValueError, _("sheet section must be a string") + raise ValueError( _("sheet section must be a string") ) if not isinstance(paragraph, str): - raise ValueError, _("sheet paragraph must be a string") + raise ValueError( _("sheet paragraph must be a string") ) if not field in self.__sheet_dict: self.addField(field, { }) _field = self.__sheet_dict[field] _field[section] = paragraph + sheet_dict = property(getSheet_dict, setSheet_dict, None, """Sheet dictionary { <Field key> : { <Section key> : <Paragraph key>}""") + class Budget(object): """base.Budget: Description: - Budget objetc + Budget object + +-- __records: dictionary records { code : Record } + +-- __synonyms: synonyms dictionary. TODO { "code" : ["synonym",],} + Each record code can have synonym codes. + +-- __root: the root record code + +-- __decimals: List with the decimal places used to round the +- result of the calculations with prices and measures +- The values are Decimals objects +- The <0> objets is the default Decimals (seted in FIEBDC-3), +- The others keys are for the diferent groups of Prices + +-- __percentages: percentages dictionary: + { "CI" : "", + "GG" : "", + "BI" : "", + "BAJA": "", + "IVA" : ""} + +-- __file_owner + +-- __title_list: titles list: [ "Header", ["Title1", "Title2", ... ] ] + List with the Headers and list of Titles for prices and + decimal places. + The Headers is the type of hierarchy of the prices + Each Title have a group of Prices and a Decimals definition + The records can have diferent prices for diferent ages, geografical + places, ... + +-- __title_index: A integer. The active group of Prices and Decimals. + +-- __sheet_sections: sheet sections dictionary { sheet_code : sheet_title } + +-- __sheet_fields: sheet fields dictionary { field_code : field_title } + +-- __sheet_paragraphs: sheet paragraphs dictionary + { paragraph_code : paragraph_text} + +-- __companys: Dictionary whith companys object + { company_code: company_object } + + +-- __comment +- +-- __date +- +-- __budgetType" A integer. Type of data in budget +- 0 -> Undefined +- 1 -> Base data. +- 2 -> Budget. +- 3 -> Certificate. +- 4 -> Base date update. +- +-- __budgetCerficateOrder" Only valid if budgetType is 3. +- +-- __budgetCerficateDate" Only valid if budgetType is 3 +- +-- __tec_info": Dictionary whith tecnical information +- {ti_code : ["desciption text", "unit"]} +- +-- __labels": Label dictionary { "label": [ "code", ], } + + Constructor: base.Budget() Ancestry: +-- object +-- Budget Atributes: - "filename": file name of the budget file (FIEBDC) - "__records": Dictionary with the budget records. - { "code" : Record object, } - "__synonyms": Dictionary with the records synonums. - { "code" : ["synonym",],} - Each record code can have synonym codes. - "__root": The root record code. - "__title_list": List with the Headers and list of Titles for prices and - decimal places. - [ "Header", ["Title1", "Title2", ... ] ] - The records can have diferent prices for diferent ages, geografical - places, ... - The Headers is the type of hierarchy of the prices - Each Title have a group of Prices and a Decimals definition - "__decimals": List with the decimal places used to round the - result of the calculations with prices and measures - The values are Decimals objects - The <0> objets is the default Decimals (seted in FIEBDC-3), - The others keys are for the diferent groups of Prices - "__percentages": Dictionary with the percentages - keys: - "CI" Indirect Cost - "GG" General expenses - "BI" Industrial benefit - "BAJA" Low (what this do here?) - "IVA" Tax - "__file_owner" - "__comment" - "__date" - "__budgetType" A integer. Type of data in budget - 0 -> Undefined - 1 -> Base data. - 2 -> Budget. - 3 -> Certificate. - 4 -> Base date update. - "__budgetCerficateOrder" Only valid if budgetType is 3. - "__budgetCerficateDate" Only valid if budgetType is 3 - "__title_index": A integer. The active group of Prices and Decimals. - "__sheet_sections": Dictionary whith de sheet sections - "__sheet_fields": Dictionary whith sheet fields - "__sheet_paragraphs": Dictionary whith sheet paragraphs - "__companys": Dictionary whith companys object - { company_code: company_object } - "__tec_info": Dictionary whith tecnical information - {ti_code : ["desciption text", "unit"]} - "__labels": Label dictionary { "label": [ "code", ], } + No public Atributes Methods: iter iterPreOrder @@ -1911,31 +2022,70 @@ setParametricText """ - def __init__(self): """__init__(self) Initialize the budget atributes """ + # title_index: A integer. The active group of Prices and Decimals. + # TODO: change title_index self.__title_index = 0 + # List with the decimal places used to round the + # result of the calculations with prices and measures + # The values are Decimals objects + # The <0> objets is the default Decimals (seted in FIEBDC-3), + # The others keys are for the diferent groups of Prices self.__decimals = [Decimals(), Decimals()] + # Dictionary with the percentages + # keys: + # "CI" Indirect Cost + # "GG" General expenses + # "BI" Industrial benefit + # "BAJA" Low (what this do here?) + # "IVA" Tax self.__percentages = { "CI" : "" ,"GG": "", "BI": "", "BAJA": "", "IVA" : ""} + # List with the Headers and list of Titles for prices and + # decimal places. + # [ "Header", ["Title1", "Title2", ... ] ] + # The records can have diferent prices for diferent ages, geografical + # places, ... + # The Headers is the type of hierarchy of the prices + # Each Title have a group of Prices and a Decimals definition self.__title_list = [ "", [ ] ] + # The root record code. self.__root = None self.__file_owner = "" self.__comment = "" - self.__budgetCerficateOrder = None - self.__budgetCerficateDate = None + self.__budgetCerficateOrder = None # Only valid if budgetType is 3. + self.__budgetCerficateDate = None # Only valid if budgetType is 3. self.__date = (0,0,0) + # budgetType: A integer. Type of data in budget + # 0 -> Undefined + # 1 -> Base data. + # 2 -> Budget. + # 3 -> Certificate. + # 4 -> Base date update. self.__budgetType = 0 + # Dictionary with the budget records: { "code" : Record object, } self.__records = { } + # Dictionary with the records synonyms. + # { "code" : ["synonym",],} + # Each record code can have synonym codes. self.__synonyms = { } + # sheet_sections: Dictionary whith de sheet sections self.__sheet_sections = { } + # sheet_fields: Dictionary whith sheet fields self.__sheet_fields = { } + # sheet_paragraphs: Dictionary whith sheet paragraphs self.__sheet_paragraphs = { } + # companys: Dictionary whith companys object + # { company_code: company_object } self.__companys = { } + # tec_info: Dictionary whith tecnical information + # {ti_code : ["desciption text", "unit"]} self.__tec_info = { } + # labels: Label dictionary { "label": [ "code", ], } self.__labels = { } def __getstate__(self): @@ -1964,6 +2114,7 @@ def iter(self): for record in self.__records: yield record + def iterPreOrder(self, recordCode, codes=None): if codes is None: codes = [] @@ -1973,6 +2124,7 @@ codes.append(_child) self.iterPreOrder(_child, codes) return codes + def iterPostOrder(self, recordCode, codes=None): if codes is None: codes = [] @@ -2012,6 +2164,7 @@ _children = _record.children _child_code = [ _child.code for _child in _children ] return _child_code + def setOwner(self, owner): """setOwner(self, owner) @@ -2021,7 +2174,7 @@ if isinstance(owner, basestring): self.__file_owner = owner else: - raise TypeError, _("Owner must be a string") + raise TypeError( _("Owner must be a string") ) def setDate(self, date): """setOwner(self, date) @@ -2037,7 +2190,7 @@ datetime.date(*date) self.__date = date else: - raise TypeError, utils.mapping(_("Invalid Date: $1"),(str(date),)) + raise TypeError( utils.mapping(_("Invalid Date: $1"),(str(date),)) ) def setComment(self, comment): """setOwner(self, comment) @@ -2048,7 +2201,7 @@ if isinstance(comment, basestring): self.__comment = comment else: - raise TypeError, _("Comment must be a string") + raise TypeError( _("Comment must be a string") ) def setBudgeType(self, budget_type): """setOwner(self, budget_type) @@ -2064,8 +2217,8 @@ if budget_type in [1, 2, 3, 4]: self.__budgetType = budget_type else: - raise ValueError, _("Budget type must be 1, 2, 3 or 4.") - + raise ValueError( _("Budget type must be 1, 2, 3 or 4.") ) + def setCertificateOrder(self, certificate_order, certificate_date): """setOwner(self, budget_type) @@ -2076,7 +2229,7 @@ if isinstance(certificate_order, int): self.__budgetCerficateOrder = certificate_order else: - raise ValueError, _("Certificate order must be a integer.") + raise ValueError( _("Certificate order must be a integer.") ) def setCertificateDater(self, certificate_date): """setCertidicateDate(self, certificate_date) @@ -2091,7 +2244,7 @@ datetime.date(*certificate_date) self.__budgetCerficateDate = certificate_date else: - raise ValueError, _("Budget certificate Date must be a valid Date.") + raise ValueError( _("Budget certificate Date must be a valid Date.") ) def setTitleList(self, title_list): """setTitleList(self, title_list) @@ -2105,7 +2258,7 @@ title_list[1][i] = str(title_list[1][i]) self.__title_list = title_list else: - raise TypeError, _("Invalid title list format") + raise TypeError( _("Invalid title list format") ) def getTitleList(self): """ getTitleList(self) @@ -2134,7 +2287,7 @@ elif N < len(self.__decimals): _default_decimals = self.__decimals[N] else: - raise IndexError, _("Invalid Index Title") + raise IndexError( _("Invalid Index Title") ) for _decimal in dictionary: if dictionary[_decimal] == "": dictionary[_decimal] = eval("_default_decimals." + _decimal) @@ -2151,6 +2304,7 @@ dictionary["DIRC"], dictionary["DCD"], dictionary["DIVISA"]) self.__decimals[N] = decimals + def getDecimals(self, decimal=None, N=None): """getDecimals(self,decimal="All",N=None) @@ -2170,7 +2324,7 @@ elif self.__decimals[N+1].haskey(decimal): return self.__decimals[N+1][decimal] else: - raise KeyError, _("Decimal Key error") + raise KeyError( _("Decimal Key error") ) def setPercentages(self, dictionary): """setPercentages(self, dictionary): @@ -2208,7 +2362,7 @@ elif key in self.__percentages: return self.__percentages[key] else: - raise KeyError, _("Invalid Percentage key") + raise KeyError( _("Invalid Percentage key") ) def getAllParents(self,code): """getAllParents(self,code) @@ -2280,12 +2434,12 @@ def getStrYield(self, measure, recordType): #_DR = measure.getDR(self.getDecimals()) - _DR = self.getDecimals().getDR(recordType) + _DR = abs(self.getDecimals().getDR(recordType)) _yield = ("%." + str(_DR) + "f" ) % measure.yield_ return _yield def getStrFactor(self, measure, recorType): - _DF = self.getDecimals().getDF(recordType) + _DF = abs(self.getDecimals().getDF(recordType)) #_DF = measure.getDF(self.getDecimals()) _factor = ("%." + str(_DF) + "f" ) % measure.factor return _factor @@ -2325,29 +2479,29 @@ if code is None: # No-estructured measures code = self.getRoot() if code == None: # No root - print "No-estructured measures. Adding root record", - self.setRecord("root", [], 0, "", "", [0.0,], [(1,1,1970)], - 0, "") + print( "No-estructured measures. Adding root record " + + str(self.setRecord("root", [], 0, "", "", [0.0,], [(1,1,1970)], + 0, "") )) code = self.getRoot() if not utils.is_valid_code(code)[0]: - raise ValueError, utils.mapping(_("Invalid parent code: $1"), - (code,)) + raise ValueError( utils.mapping(_("Invalid parent code: $1"), + (str(code),)) ) if not utils.is_valid_code(child_code)[0]: - raise ValueError, utils.mapping(_("Invalid child code: $1 $2"), - (code,child_code)) + raise ValueError( utils.mapping(_("Invalid child code: $1 $2"), + (str(code),str(child_code))) ) if not isinstance(position, int): - raise ValueError, utils.mapping(_("Invalid position in measure "\ - "$1, in code $2"), (parent_code, position)) + raise ValueError( utils.mapping(_("Invalid position in measure "\ + "$1, in code $2"), (str(parent_code), str(position))) ) # Test circular references _all_parent_list = self.getAllParents(code) + [ code ] _all_child_list = self.getAllchildren(child_code) + [ child_code ] for _parent_code in _all_parent_list: if _parent_code in _all_child_list: # TODO: change return to except - print utils.mapping(_("Circular Decomposition, parent code: "\ + print(utils.mapping(_("Circular Decomposition, parent code: "\ "$1, child code: $2, repeated code: $3"), - (code, child_code, _parent_code)) + (str(code), str(child_code), str(_parent_code))) ) return # Creating reference to parent code in child record @@ -2370,15 +2524,15 @@ positions = _record.getChildPositions(child_code) if len(positions) == 1: position = positions[0] - print utils.mapping(_("No-estructured measure or empty position. Parent Code: "\ - "$1, Child code: $2, Position: $3"),(code, child_code, position)) + print(utils.mapping(_("No-estructured measure or empty position. Parent Code: "\ + "$1, Child code: $2, Position: $3"),(str(code), str(child_code), str(position))) ) else: position = _child_number - print utils.mapping(_("No-estructured measure or empty position. "\ + print(utils.mapping(_("No-estructured measure or empty position. "\ "Repeated child in unspecified position. "\ "It is impossible to determine the position. "\ "New child is added in the decomposition. "\ - "Parent code: $1, Child code: $2, Position: $3"),(code, child_code, position)) + "Parent code: $1, Child code: $2, Position: $3"),(str(code), str(child_code), str(position))) ) if position == _child_number: # The record do not have the child if not isinstance(factor, float): factor = 1.0 @@ -2414,21 +2568,21 @@ _measure.label = label else: # TODO: change return for except - print utils.mapping(_("Error: Invalid child position in " + print(utils.mapping(_("Error: Invalid child position in " "decomposition. Parent code: $1 Child code: $2 "\ - "Position: $3"), (code, child_code, position)) + "Position: $3"), (str(code), str(child_code), str(position))) ) return else: if child_code == "" : - print utils.mapping(_("Error: Empty child code. Parent code: "\ - "$1 Position: $2"), (code, position)) + print(utils.mapping(_("Error: Empty child code. Parent code: "\ + "$1 Position: $2"), (str(code), str(position))) ) return if position == -1: position = 0 elif position != 0: - print utils.mapping(_("Error: Invalid child position in "\ + print(utils.mapping(_("Error: Invalid child position in "\ "decomposition. Parent code: $1 Child code: $2 "\ - "Position: $3"), (code, child_code, position)) + "Position: $3"), (str(code), str(child_code), str(position))) ) return if not isinstance(factor, float): factor = 1.0 @@ -2461,19 +2615,19 @@ try: a = float(a) except: - raise ValueError, _("'a' value must be a float number") + raise ValueError( _("'a' value must be a float number") ) try: b = float(b) except: - raise ValueError, _("'b' value must be a float number") + raise ValueError( _("'b' value must be a float number") ) try: c = float(c) except: - raise ValueError, _("'c' value must be a float number") + raise ValueError( _("'c' value must be a float number") ) try: d = float(d) except: - raise ValueError, _("'d' value must be a float number") + raise ValueError( _("'d' value must be a float number") ) # spaces are erased sre.sub("[ ]","",formula) # operators and varibles are replaced @@ -2501,7 +2655,7 @@ try: return eval(_formula2, _g) except: - raise ValueError, _("Invalid formula") + raise ValueError( _("Invalid formula") ) def getText(self,code): """getText(self,code) @@ -2512,7 +2666,7 @@ if code in self.__records: return self.__records[code].text else: - raise IndexError, _("Invalid code") + raise IndexError( _("Invalid code") ) def setText(self,code,text): """setText(self,code,text) @@ -2522,7 +2676,7 @@ Sests the description text of a record """ if not utils.is_valid_code(code)[0]: - raise ValueError, utils.mapping(_("Invalid record: $1"), (code,)) + raise ValueError( utils.mapping(_("Invalid record: $1"), (str(code),)) ) if not code in self.__records: _record = self.setRecord(code, [], "", "", "", [], [], "", "") @@ -2585,7 +2739,7 @@ if self.__root is None: self.__root = code else: - print _("Only can be one root record") + print(_("Only can be one root record") ) return # TODO: If the root is created in settree. No-estructured measures # TODO Rewrite root values @@ -2659,9 +2813,22 @@ """ record.addPrice(price_date, self.getDecimals()) - def getStrPriceFromRecord(self, index_price, record): - _price = record.getPrice(index_price) - _D = self.getDecimals().getD(record.recordType) + def getStrPriceFromRecord(self, index_price, record, path): + if record.isPercentage(): + _percentageMasq = record.percentageMasq() + _parent_code = self.getCode(path[:-1]) + _N_record = path[-1] + _amount_sum = 0.0 + for N,_code in enumerate(self.getchildren(_parent_code)[:_N_record]): + _child_record = self.getRecord(_code) + if _child_record.hasPercentageMasq(_percentageMasq): + _path = path[:-1] + (N,) + _amount = self.getAmount(_path) + _amount_sum = _amount_sum + _amount + _price = _amount_sum + else: + _price = record.getPrice(index_price) + _D = abs(self.getDecimals().getD(record.recordType)) _price = ("%." + str(_D) + "f" ) % _price return _price @@ -2681,16 +2848,16 @@ try: _child = _children_list[i] except: - raise ValueError, _("This record does not exits") + raise ValueError( _("This record does not exits") ) _code = _child.code else: - raise ValueError, _("Path item must be a integer") + raise ValueError( _("Path item must be a integer") ) return _code else: - raise ValueError, _("This record does not exits") + raise ValueError( _("This record does not exits") ) else: - raise ValueError, utils.mapping(_("Path must be a not empty "\ - "tuple: $1"), (str(path),)) + raise ValueError( utils.mapping(_("Path must be a not empty "\ + "tuple: $1"), (str(path),)) ) def getAmount(self, path): """def getAmount(self,path) @@ -2698,6 +2865,7 @@ path: record path Calculate the record amount """ + if len(path) == 1: # root: amount is the root price _root = self.getRecord(self.getRoot()) @@ -2713,10 +2881,25 @@ _yield = _decomposition.budgetMeasures[0].yield_ _child_code = _decomposition.code _child_record = self.getRecord(_child_code) - _price = _child_record.getPrice(self.getActiveTitle()) - _DR = self.getDecimals().getDR(_parent_record.recordType) + _code = self.getCode(path) + _record = self.getRecord(_code) + if _record.isPercentage(): + _percentageMasq = _record.percentageMasq() + _N_record = path[-1] + _amount_sum = 0.0 + for N,_code in enumerate(self.getchildren(_parent_code)[:_N_record]): + _child_record = self.getRecord(_code) + if _child_record.hasPercentageMasq(_percentageMasq): + _path = path[:-1] + (N,) + _amount = self.getAmount(_path) + _amount_sum = _amount_sum + _amount + _price = _amount_sum + else: + _price = _child_record.getPrice(self.getActiveTitle()) + + _DR = abs(self.getDecimals().getDR(_parent_record.recordType)) _total_yield = round(_factor * _yield, _DR) - _DI = self.getDecimals().getDI(_parent_record.recordType) + _DI = abs(self.getDecimals().getDI(_parent_record.recordType)) _amount = round(_total_yield * _price, _DI) return _amount @@ -2728,74 +2911,86 @@ """ if len(path) == 1: #root _root = self.getRecord(self.getRoot()) - _amount = self.getStrPriceFromRecord(self.__title_index, _root) + _amount = self.getStrPriceFromRecord(self.__title_index, _root, path) return _amount else: _parent_code = self.getCode(path[:-1]) _parent_record = self.getRecord(_parent_code) _amount = self.getAmount(path) - _DI = self.getDecimals().getDI(_parent_record.recordType) + _DI = abs(self.getDecimals().getDI(_parent_record.recordType)) _amount = ("%." + str(_DI) + "f") % _amount return _amount def setSheetSection(self,sheet_code,sheet_title): if not isinstance(sheet_code, str): - raise ValueError, _("The sheet code must be a string") + raise ValueError( _("The sheet code must be a string") ) if not isinstance(sheet_title, str): - raise ValueError, _("The sheet title must be a string") + raise ValueError( _("The sheet title must be a string") ) self.__sheet_sections[sheet_code] = sheet_title + def hasSheetSection(self, section): return section in self.__sheet_sections + def getSheetSection(self, section): return self.__sheet_sections[section] + def setSheetSections(self,dictionary): if not isinstance(dictionary, dict): - raise ValueError, _("The sheet sections must be a dictionary") + raise ValueError( _("The sheet sections must be a dictionary") ) for sheet_code in dictionary.keys(): self.setSheetSection(sheet_code, dictionary[sheet_code]) + def setSheetField(self, field_code, field_title): if not isinstance(field_code, str): - raise ValueError, _("The field code must be a string") + raise ValueError( _("The field code must be a string") ) if not isinstance(field_title, str): - raise ValueError, _("The field title must be a string") + raise ValueError( _("The field title must be a string") ) self.__sheet_fields[field_code] = field_title + def hasSheetField(self, field): return field in self.__sheet_fields + def getSheetField(self, field): return self.__sheet_fields[field] + def setSheetFields(self, field_dict): if not isinstance(field_dict, dict): - raise ValueError, _("The sheet field must be a dictionary") + raise ValueError( _("The sheet field must be a dictionary") ) for field_code in field_dict.keys(): self.setSheetField( field_code, field_dict[field_code]) + def setSheetParagraph(self, paragraph_code, paragraph_text): if not isinstance(paragraph_code, str): - raise ValueError, _("The paragraph code must be a string") + raise ValueError( _("The paragraph code must be a string") ) if not isinstance(paragraph_text, str): - raise ValueError, _("The paragraph text must be a string") + raise ValueError( _("The paragraph text must be a string") ) self.__sheet_paragraphs[paragraph_code] = paragraph_text + def hasSheetParagraph(self, paragraph): return paragraph in self.__sheet_paragraphs + def getSheetParagraph(self, paragraph): return self.__sheet_paragraphs[paragraph] + def setSheetParagraphs(self, paragraph_dict): if not isinstance(paragraph_dict, dict): - raise ValueError, _("The paragraph dict must be a dictionary") + raise ValueError( _("The paragraph dict must be a dictionary") ) for paragraph_code in paragraph_dict.keys(): self.setSheetParagraph( paragraph_code, paragraph_dict[paragraph_code]) + def setSheetRecord(self, record_code, field, section_dict): if not isinstance(record_code, str): - raise ValueError, _("The record_code code must be a string") + raise ValueError( _("The record_code code must be a string") ) if not isinstance(field, str): - raise ValueError, _("The field must be a string") + raise ValueError( _("The field must be a string") ) if not isinstance(section_dict, dict): - raise ValueError, _("The section dict must be a dictionary") + raise ValueError( _("The section dict must be a dictionary") ) #-# # TODO: Add a empty record? if not self.hasRecord(record_code): - print utils.mapping(_("Error: The budget do not have this record "\ + print(utils.mapping(_("Error: The budget do not have this record "\ "code and can not be added the sheet text in the field $1. "\ - "Record Code: $2"), ( field, record_code)) + "Record Code: $2"), ( str(field), str(record_code))) ) return #-# if not self.hasSheetField(field): @@ -2807,45 +3002,48 @@ self.setSheetSection(section, "") _sheet = self.getRecord(record_code).getSheet() _sheet.addSection(field, section, paragraph) + def addFile(self, record_code, filepath, type_, description): if not isinstance(record_code, str): - raise ValueError, _("The record_code code must be a string") - if not isinstance(filepath, str): - raise ValueError, _("The filename must be a string") + raise ValueError( _("The record_code code must be a string") ) + #-# str and unicode + if not isinstance(filepath, str) and not isinstance(filepath, unicode): + raise ValueError( _("The filename must be a string") ) #-# # TODO: Add a empty record? if not self.hasRecord(record_code): - print utils.mapping(_("Error: The budget do not have the record "\ + print(utils.mapping(_("Error: The budget do not have the record "\ "code $1 and can not be added the file: $2"), - (record_code, filepath)) + (str(record_code), str(filepath))) ) return #-# _record = self.getRecord(record_code) _record.addFile(filepath, type_, description) + def setCompany(self, company_code, sumamary, name, offices, cif, web, email): if not isinstance(company_code, str): - raise ValueError, _("The company code must be a string") + raise ValueError( _("The company code must be a string") ) if not isinstance(sumamary, str): - raise ValueError, _("The summary must be a string") + raise ValueError( _("The summary must be a string") ) if not isinstance(name, str): - raise ValueError, _("The name must be a string") + raise ValueError( _("The name must be a string") ) if not isinstance(offices, list): - raise ValueError, _("The name must be a list") + raise ValueError( _("The name must be a list") ) _offices = [] for _office in offices: if not isinstance(_office, list): - raise ValueError, _("The office must be a list") + raise ValueError( _("The office must be a list") ) if not len(_office) == 10: - raise ValueError, _("The office must be a 10 items list") + raise ValueError( _("The office must be a 10 items list") ) for _item in _office[:7] + _office[9:10]: if not isinstance(_item, str): - raise ValueError, _("This office item must be a "\ - "string") + raise ValueError( _("This office item must be a "\ + "string") ) for _item in _office[7:8]: if not isinstance(_item, list): - raise ValueError, _("This office item must be a "\ - "list") + raise ValueError( _("This office item must be a "\ + "list") ) _offices.append(Office(_office[0], _office[1], _office[2], @@ -2857,31 +3055,36 @@ _office[8], _office[9])) if not isinstance(cif, str): - raise ValueError, _("The name must be a string") + raise ValueError( _("The name must be a string") ) if not isinstance(web, str): - raise ValueError, _("The web must be a string") + raise ValueError( _("The web must be a string") ) if not isinstance(email, str): - raise ValueError, _("The email must be a string") + raise ValueError( _("The email must be a string") ) self.__companys[company_code] = Company(company_code, sumamary, name, _offices, cif, web, email) def getCompany(self, company_code): return self.__companys[company_code] + def getCompanyKeys(self): return self.__companys.keys() + def addTecInfo(self, ti_code, text, unit): if not isinstance(ti_code, str): - raise ValueError, _("The tecnical info code must be a string") + raise ValueError( _("The tecnical info code must be a string") ) if not isinstance(text, str): - raise ValueError, _("The tecnical info description must be a "\ - "string") + raise ValueError( _("The tecnical info description must be a "\ + "string") ) if not isinstance(unit, str): - raise ValueError, _("The tecnical info unit must be a string") + raise ValueError( _("The tecnical info unit must be a string") ) self.__tec_info[ti_code] = [text, unit] + def hasTecInfo(self, ti_code): return ti_code in self.__tec_info + def getTecInfo(self, ti_code): return self.__tec_info[ti_code] + def setTecnicalInformation(self, record_code, ti_dict): """setTecnicalInformation(record_code, ti_dict) @@ -2891,6 +3094,7 @@ """ # TODO: setTecnicalInformation pass + def changeCode(self, record_code, new_record_code): """changeCode(self, record_code, new_record_code): @@ -2923,7 +3127,7 @@ Add a label to a record """ if not isinstance(label,str): - raise ValueError, _("The label must be a string") + raise ValueError( _("The label must be a string") ) if self.hasRecord(record_code): _record = self.__records[record_code] _record.addLabel(label) @@ -2933,27 +3137,28 @@ _codes = self.__labels[label] if not record_code in _codes: _codes.append(record_code) + def setParametricSelectComment(self, record_code, comment): """setParametricSelectComment(self, record_code, comment) Sets Paramtric Record Select Comment """ if not isinstance(record_code, str): - raise ValueError, _("The record_code code must be a string") + raise ValueError( _("The record_code code must be a string") ) if not isinstance(comment, str): - raise ValueError, _("The parametric select comment must be a "\ - "string") + raise ValueError( _("The parametric select comment must be a "\ + "string") ) if not self.hasRecord(record_code): - print utils.mapping(_("Error: The budget do not have the record "\ + print(utils.mapping(_("Error: The budget do not have the record "\ "code $1 and can not be added the Parametric select comment: "\ "$2"), - (record_code, comment)) + (str(record_code), str(comment))) ) return _record = self.getRecord(record_code) if not isinstance(_record, ParametricRecord): - print utils.mapping(_("Error: The Record $1 is not a "\ + print(utils.mapping(_("Error: The Record $1 is not a "\ "Parametric Record and can not have Parametric comment"), - (record_code,)) + (str(record_code),)) ) else: _record.select_comment = comment @@ -2963,19 +3168,19 @@ Sets parametric record summary """ if not isinstance(record_code, str): - raise ValueError, _("The record_code code must be a string") + raise ValueError( _("The record_code code must be a string") ) if not isinstance(summary, str): - raise ValueError, _("The summary record must be a string") + raise ValueError( _("The summary record must be a string") ) if not self.hasRecord(record_code): - print utils.mapping(_("Error: The budget do not have the record "\ + print(utils.mapping(_("Error: The budget do not have the record "\ "code $1 and can not be seted the summary: $2"), - (record_code, summary)) + (str(record_code), str(summary))) ) return _record = self.getRecord(record_code) if not isinstance(_record, ParametricRecord): - print utils.mapping(_("Error: The Record $1 is not a "\ + print(utils.mapping(_("Error: The Record $1 is not a "\ "Parametric Record and can not have Parametric summary"), - (record_code,)) + (str(record_code),)) ) else: self.getRecord(record_code).parametric_summary = summary @@ -2985,22 +3190,23 @@ Sets parametric record text """ if not isinstance(record_code, str): - raise ValueError, _("The record_code code must be a string") + raise ValueError( _("The record_code code must be a string") ) if not isinstance(text, str): - raise ValueError, _("The text record must be a string") + raise ValueError( _("The text record must be a string") ) if not self.hasRecord(record_code): - print utils.mapping(_("Error: The budget do not have the record "\ + print(utils.mapping(_("Error: The budget do not have the record "\ "code $1 and can not be seted the text: $2"), - (record_code, text)) + (str(record_code), str(text))) ) return _record = self.getRecord(record_code) if not isinstance(_record, ParametricRecord): - print utils.mapping(_("Error: The Record $1 is not a "\ + print(utils.mapping(_("Error: The Record $1 is not a "\ "Parametric Record and can not have Parametric text"), - (record_code,)) + (str(record_code),)) ) else: self.getRecord(record_code).parametric_text = text + class Office(object): """base.Office: @@ -3044,6 +3250,7 @@ {get/set}ContactPerson getValues """ + __slots__ = ["_Office__officeType", "_Office__subname", "_Office__address", @@ -3055,6 +3262,7 @@ "_Office__fax", "_Office__contact_person", ] + def __getstate__ (self): return ( self.__officeType, self.__subname, @@ -3066,6 +3274,7 @@ self.__phone, self.__fax, self.__contact_person) + def __setstate__(self,tuple): self.__officeType = tuple[0] self.__subname = tuple[1] @@ -3090,46 +3299,67 @@ self.phone = phone self.fax = fax self.contact_person = contact_person + def getOfficeType(self): return self.__officeType + def setOfficeType(self, type_): self.__officeType = type_ + def getSubname(self): return self.__subname + def setSubname(self, subname): self.__subname = subname + def getAddress(self): return self.__address + def setAddress(self, address): self.__address = address + def getPostalCode(self): return self.__postal_code + def setPostalCode(self, postal_code): self.__postal_code = postal_code + def getTown(self): return self.__town + def setTown(self, town): self.__town = town + def getProvince(self): return self.__province + def setProvince(self, province): self.__province = province + def getCountry(self): return self.__country + def setCountry(self, country): self.__country = country + def getPhone(self): return self.__phone + def setPhone(self, phone): self.__phone = phone + def getFax(self): return self.__fax + def setFax(self, fax): self.__fax = fax + def getContactPerson(self): return self.__contact_person + def setContactPerson(self, contact_person): self.__contact_person = contact_person + def getValues(self): return {"officeType": self.officeType, "subname": self.subname, @@ -3142,6 +3372,7 @@ "fax": self.fax, "contact person": self.contact_person, } + officeType = property(getOfficeType, setOfficeType, None, """Type of office """) @@ -3176,6 +3407,7 @@ """Dictionary with comapany values """) + class Company(object): """base.Company: @@ -3210,6 +3442,7 @@ {get/set}Email getValues """ + __slots__ = ["_Company__code", "_Company__summary", "_Company__name", @@ -3218,6 +3451,7 @@ "_Company__web", "_Company__email", ] + def __getstate__ (self): return ( self.__code, self.__summary, @@ -3226,6 +3460,7 @@ self.__cif, self.__web, self.__email) + def __setstate__(self,tuple): self.__code = tuple[0] self.__summary = tuple[1] @@ -3243,34 +3478,49 @@ self.cif = cif self.web = web self.email = email + def getCode(self): return self.__code + def setCode(self, code): self.__code = code + def getSummary(self): return self.__summary + def setSummary(self, summary): self.__summary = summary + def getName(self): return self.__name + def setName(self, name): self.__name = name + def getOffices(self): return self.__offices + def setOffices(self, offices): self.__offices = offices + def getCif(self): return self.__cif + def setCif(self, cif): self.__cif = cif + def getWeb(self): return self.__web + def setWeb(self, web): self.__web = web + def getEmail(self): return self.__email + def setEmail(self, email): self.__email = email + def getValues(self): return {"code": self.code, "summary": self.summary, @@ -3278,6 +3528,7 @@ "cif": self.cif, "web": self.web, "email": self.email} + code = property(getCode, setCode, None, """Company code """) @@ -3303,6 +3554,7 @@ """Dictionary with comapany values """) + class File(object): """base.Company: @@ -3326,41 +3578,52 @@ {get/set}Description getValues """ + __slots__ = ["_File__name", "_File__fileType", "_File__description", - ] + def __getstate__ (self): return (self.__name, self.__description, self.__fileType, ) + def __setstate__(self,tuple): self.__name = tuple[0] self.__fileType = tuple[1] self.__description = tuple[2] + def __init__(self, name, type_, description): self.name = name self.fileType = type_ self.description = description + def getName(self): return self.__name + def setName(self, name): self.__name = name + def getFileType(self): return self.__fileType + def setFileType(self, type_): self.__fileType = type_ + def getDescription(self): return self.__description + def setDescription(self, description): self.__description = description + def getValues(self): return {"name": self.name, "fileType": self.fileType, "description": self.description, } + name = property(getName, setName, None, """File name """) @@ -3374,6 +3637,7 @@ """Dictionary with file values """) + class RecordType(object): """base.RecordType: @@ -3432,51 +3696,62 @@ {get/set}Type {get/set}Subtype """ + __slots__ = ["_RecordType__hierarchy", "_RecordType__type", "_RecordType__subtype", ] + def __getstate__ (self): return (self.__hierarchy, self.__type, self.__subtype, ) + def __setstate__(self,tuple): self.__hierarchy = tuple[0] self.__type = tuple[1] self.__subtype = tuple[2] + def __init__(self, hierarchy, type_, subtype): self.hierarchy = hierarchy self.type = type_ self.subtype = subtype + def getHierarchy(self): return self.__hierarchy + def setHierarchy(self, hierarchy): if not hierarchy in [-1, 0 , 1 ,2, ""]: - raise ValueError, utils.mapping(_("Invalid Hierarchy ($1) "\ - "The hierarchy must be -1, 0, 1, 2"), (str(hierarchy),)) + raise ValueError( utils.mapping(_("Invalid Hierarchy ($1) "\ + "The hierarchy must be -1, 0, 1, 2"), (str(hierarchy),)) ) elif hierarchy == "": - print "Hierarchy temporarily set to an empty string" + print("Hierarchy temporarily set to an empty string") #TODO Check empty Hierarchy in Generic.fiebdc.Read._testBudget self.__hierarchy = hierarchy + def getType(self): return self.__type + def setType(self, type_): if not type_ in ["", 0, 1, 2, 3] : - raise ValueError, utils.mapping(_("Invalid type ($1),"\ - "the type must be (empty string,0,1,2,3)"),(str(type_)),) + raise ValueError( utils.mapping(_("Invalid type ($1),"\ + "the type must be (empty string,0,1,2,3)"),(str(type_)),) ) self.__type = type_ + def getSubtype(self): return self.__subtype + def setSubtype(self, subtype): if not subtype in ["", "OB", "PU", "EA", "EU", "EC", "EF", "PA", "H", "Q", "%", "MC", "MCr", "MM", "MS", "ME", "MCu", "Mal","ML","M"]: - raise ValueError, utils.mapping(_("Invalid subtype ($1), The "\ + raise ValueError( utils.mapping(_("Invalid subtype ($1), The "\ "subtype must one in (empty string, EA, "\ "EU, EC, EF, OB, PA, PU, H, Q, %, MC, MCr, "\ - "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype),)) + "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype),)) ) self.__subtype = subtype + hierarchy = property(getHierarchy, setHierarchy, None, """Record Hierarchy -1 -> temporarily unfixed