Mercurial > pyarq-presupuestos
comparison Generic/base.py @ 1:2ac1551ad2ab version 0.0.0
add code
| author | Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es> |
|---|---|
| date | Sun, 31 Oct 2010 20:07:33 +0100 |
| parents | |
| children | a7b9f7e7dfa4 |
comparison
equal
deleted
inserted
replaced
| 0:a1703c4f2990 | 1:2ac1551ad2ab |
|---|---|
| 1 #!/usr/bin/python | |
| 2 # -*- coding: utf-8 -*- | |
| 3 ## File base.py | |
| 4 ## This file is part of pyArq-Presupuestos. | |
| 5 ## | |
| 6 ## Copyright (C) 2010 Miguel Ángel Bárcena Rodríguez | |
| 7 ## <miguelangel@obraencurso.es> | |
| 8 ## | |
| 9 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify | |
| 10 ## it under the terms of the GNU General Public License as published by | |
| 11 ## the Free Software Foundation, either version 3 of the License, or | |
| 12 ## (at your option) any later version. | |
| 13 ## | |
| 14 ## pyArq-Presupuestos is distributed in the hope that it will be useful, | |
| 15 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 ## GNU General Public License for more details. | |
| 18 ## | |
| 19 ## You should have received a copy of the GNU General Public License | |
| 20 ## along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | |
| 22 """base module | |
| 23 | |
| 24 In this module are defined the data structures in the | |
| 25 classes: | |
| 26 * Record: data of each record | |
| 27 * ParamentricRecord: data of each parametric record | |
| 28 * Decomposition: data of the decomposition of each record | |
| 29 * Measure: data of the measure of each record | |
| 30 * MeasureLine: each measure line data | |
| 31 * Decimals: data of the decimal places of all the numbers in a budget | |
| 32 * Sheet: data of the sheet of conditions of a budget | |
| 33 * Budget: all data of a budget | |
| 34 * Company: company data | |
| 35 * Office: company office data | |
| 36 * File: file data | |
| 37 * RecordType: Record type data | |
| 38 | |
| 39 schema: | |
| 40 * Budget: | |
| 41 +-- __records: dictionary records { code : Record } | |
| 42 * Record: | |
| 43 +-- code: record code | |
| 44 +-- synonyms: list of synonym codes | |
| 45 +-- hierarchy: A integer number: | |
| 46 0 -> root | |
| 47 1 -> Chapter/Subchapter | |
| 48 2 -> Other | |
| 49 +-- unit: unit of measure of the record | |
| 50 +-- summary: Short description of the record | |
| 51 +-- prices: List of Prices/Dates | |
| 52 +-- type | |
| 53 +-- subtype | |
| 54 "type" and "subtype": | |
| 55 0 Without classifying | |
| 56 EA Auxiliary element | |
| 57 EU Unitary element | |
| 58 EC Complex element | |
| 59 EF Functional element | |
| 60 OB Construction site | |
| 61 PA Cost overrun | |
| 62 PU Unitary budget | |
| 63 1 Labourforce | |
| 64 H Labourforce | |
| 65 2 Machinery and auxiliary equipment | |
| 66 Q Machinery | |
| 67 % Auxiliary equipment | |
| 68 3 Building materials | |
| 69 MC Cement | |
| 70 MCr Ceramic | |
| 71 MM Wood | |
| 72 MS Iron and steel | |
| 73 ME Energy | |
| 74 MCu Copper | |
| 75 MAl Aluminium | |
| 76 ML Bonding agents | |
| 77 M Others materials | |
| 78 Hierarchy type subtype | |
| 79 0->root -> 0 -> None,OB | |
| 80 1->[sub]chapter -> 0 -> None,PU | |
| 81 2->Other -> 0 -> None,EA,EU,EC,EF,PA | |
| 82 1 -> None,H | |
| 83 2 -> None,Q,% | |
| 84 3 -> None,MC,MCr,MM,MS,ME,MCu,Mal,ML,M | |
| 85 +-- parents: List of parent codes | |
| 86 +-- children: list of Decomposition | |
| 87 * Decomposition: | |
| 88 +-- position: Position of the child in the parent descomposition | |
| 89 TODO: change this: the position of the record in the budget | |
| 90 +-- code: child record code | |
| 91 +-- budget: list of budget and amended budget measures | |
| 92 * Measure: | |
| 93 +-- measure: Total result of measure | |
| 94 +-- lines: List of measure lines | |
| 95 * MeasureLine: | |
| 96 +-- type: Line type: | |
| 97 empty string -> Normal | |
| 98 1 -> Parcial Subtotal | |
| 99 2 -> Accumulated Subtotal | |
| 100 3 -> Formula, the comment is a formula. | |
| 101 +-- comment: Can be a descriptive text or a formula | |
| 102 Valid Operator: '(', ')', '+', '-', '*', '/' and | |
| 103 '^' | |
| 104 Valid variable: 'a', 'b', 'c','d' y 'p' | |
| 105 (Pi=3.1415926) | |
| 106 +-- units: Number of Units (a) | |
| 107 +-- length: length (b) | |
| 108 +-- width: width (c) | |
| 109 +-- height: height (d) | |
| 110 +-- label: Record Identifiers that are used by some measure | |
| 111 programs | |
| 112 +-- factor: Factor | |
| 113 +-- yield_: Yield | |
| 114 +-- certification: list of certifications for months measures | |
| 115 * Measure | |
| 116 +-- real_cost: list of real cost of construction for months | |
| 117 measures | |
| 118 * Measure | |
| 119 +-- cost_goals: list of cost goals of construction for months | |
| 120 measures | |
| 121 * Measure | |
| 122 +-- cost_planned: list of costs planned and amended cost planned | |
| 123 measures | |
| 124 * Measure | |
| 125 +-- text: Long Description of the record | |
| 126 +-- sheet: Sheet of conditions object | |
| 127 * Sheet: | |
| 128 +-- sheet_dict: | |
| 129 { <Field key> : { <Section key> : <Paragraph key>}} | |
| 130 +-- files: List of file object | |
| 131 +-- file | |
| 132 * Name | |
| 133 * Type | |
| 134 * Description | |
| 135 +-- __synonyms: synonyms dictionary. TODO | |
| 136 +-- __root: root record code | |
| 137 +-- __decimals: decimals dictionay = { int : Decimals } | |
| 138 * Decimals: | |
| 139 +-- DN: Number of decimal places of the field "equal-size parts" in the | |
| 140 measure lines. | |
| 141 Default: 2 decimal places. | |
| 142 +-- DD: Number of decimal places of the three dimensions in the | |
| 143 measure lines. | |
| 144 Default: 2 decimal places. | |
| 145 +-- DS: Number of decimal places of the total sum of a measure. | |
| 146 Default: 2 decimal places. | |
| 147 +-- DFP: Number of decimal places of the yield factor in a | |
| 148 decomposition of a budget record. | |
| 149 Default: 3 decimal places. | |
| 150 +-- DFC: Number of decimal places of the yield factor in a | |
| 151 decomposition of a chapter or subchapter, and in its measure lines. | |
| 152 Dafault: 3 decimal places. | |
| 153 +-- DFUO: Number of decimal places of the yield factor in a | |
| 154 decomposition of a unit of work. | |
| 155 Default: 3 decimal places. | |
| 156 +-- DFA: Number of decimal places of the yield factor in a | |
| 157 decomposition of a Auxiliary element. | |
| 158 Default: 3 decimal places. | |
| 159 +-- DRP: Number of decimal places of the yield in a decomposition | |
| 160 of a budget record. | |
| 161 Number of decumal places of the result of the multiplication of | |
| 162 the factor and the yield in a decompositon of a budget. | |
| 163 Default: 3 decimal places. | |
| 164 +-- DRC: Number of decimal places of the yield (or measure) in a | |
| 165 decomposition of a chapter or subchapter. | |
| 166 Number of decimal places of the result of the multiplictaion of | |
| 167 the yield (or measure) and the factor in a decomposition of a | |
| 168 chapter or subcharter. | |
| 169 Default: 3 decimal places. | |
| 170 +-- DRUO: Number of decimal places of the yield in a decomposition of a | |
| 171 unit of work. | |
| 172 Decimal places of the result of the multiplication of the yield | |
| 173 and the factor in a descomposition of a unit of work. | |
| 174 Default: 3 decimal places. | |
| 175 +-- DRA: Number of decimal places of the yield in a decompositon of a | |
| 176 auxiliar element. | |
| 177 Number of decimal places of the result of the multiplication of | |
| 178 the yield and the factor in a descomposition of a auxilar element. | |
| 179 Default: 3 decimal places. | |
| 180 +-- DP: Number of decimal places of the price of a budget. | |
| 181 Default: 2 decimal places. | |
| 182 +-- DC: Number of decimal places of the price of a chapter or | |
| 183 subchapter. | |
| 184 Default: 2 decimal places. | |
| 185 +-- DUO: Number of decimal places of the price of a unit of work. | |
| 186 Default: 2 decimal places. | |
| 187 +-- DEA: Number of decimal places of the price of a auxiliar element. | |
| 188 Default: 2 decimal places. | |
| 189 +-- DES: Number of decimal places of the price of the simple elements. | |
| 190 Default: 2 decimal places. | |
| 191 +-- DIR: Number of decimal places of the resulting amount to multiply | |
| 192 the total yield and the price of the elements of a unit of work. | |
| 193 (When there are not measures) | |
| 194 +-- DIM: Number of decimal places of the resulting amount to multiply | |
| 195 the total yield and the price of the elements of a unit of work. | |
| 196 (When there are measures) | |
| 197 +-- DIRC: Number of decimal places of the resulting amount to multiply | |
| 198 the total yield and the price of the elements of a budget, chapter | |
| 199 or a subchapter.(When there are not measures) | |
| 200 +-- DIMC: Number of decimal places of the resulting amount to multiply | |
| 201 the total yield and the price of the elements of a budget, chapter | |
| 202 or a subchapter. (When there are measures) | |
| 203 +-- DCD: Number of decimal places ot the resulting amount to sum the | |
| 204 direct costs of a unit of work (and auxiliar element). | |
| 205 Number of decimal places of the indirect costs. | |
| 206 Default: 2 decimal places. | |
| 207 +-- DIVISA: monetary unit. | |
| 208 +-- __percentages: percentages dictionary: | |
| 209 { "CI" : "", | |
| 210 "GG" : "", | |
| 211 "BI" : "", | |
| 212 "BAJA": "", | |
| 213 "IVA" : ""} | |
| 214 +-- __file_owner | |
| 215 +-- __title_list: titles list: [ "Header", ["Title1", "Title2", ... ] ] | |
| 216 +-- __title_index: A integer. The active group of Prices and Decimals. | |
| 217 +-- __sheet_sections: sheet sections dictionary { sheet_code : sheet_title } | |
| 218 +-- __sheet_fields: sheet fields dictionary { field_code : field_title } | |
| 219 +-- __sheet_paragraphs: sheet paragraphs dictionary | |
| 220 { paragraph_code : paragraph_text} | |
| 221 +-- __companys: Dictionary whith companys object | |
| 222 { company_code: company_object } | |
| 223 * Comapany: | |
| 224 +-- code: company code | |
| 225 +-- summary: short name | |
| 226 +-- name: long name | |
| 227 +-- offices: List of offices: | |
| 228 * Office: | |
| 229 +-- type: office type | |
| 230 "C" Central office. | |
| 231 "D" Local Office. | |
| 232 "R" Performer. | |
| 233 +-- subname: Office name | |
| 234 +-- address: Ofiice address | |
| 235 +-- postal_code: postal code | |
| 236 +-- town: town | |
| 237 +-- province: province/state | |
| 238 +-- country: country | |
| 239 +-- phone: list of phone numbers | |
| 240 +-- fax: list of fax numbers | |
| 241 +-- contact_person: Contact person in the office | |
| 242 +-- cif: CIF | |
| 243 +-- web: web page | |
| 244 +-- email: email | |
| 245 """ | |
| 246 | |
| 247 # Modules | |
| 248 import re | |
| 249 import datetime | |
| 250 import os | |
| 251 | |
| 252 # pyArq-Presupuestos modules | |
| 253 from Generic import fiebdc | |
| 254 from Generic import utils | |
| 255 | |
| 256 class Record(object): | |
| 257 """base.Record: | |
| 258 | |
| 259 Description: | |
| 260 Record object | |
| 261 Constructor: | |
| 262 base.Record(code, synonyms, hierarchy, unit, summary, prices, type, | |
| 263 subtype, text="") | |
| 264 Ancestry: | |
| 265 +-- object | |
| 266 +-- Record | |
| 267 Atributes: | |
| 268 "code": Code string | |
| 269 "recordType": RecordType object | |
| 270 "synonyms": List of synonym codes. | |
| 271 "parents":List of parent codes | |
| 272 "children": Decomposition list, | |
| 273 list of "Decomposition" instances | |
| 274 "unit": measure unit of the record | |
| 275 "summary": Short description of the record | |
| 276 "prices": List of prices/dates | |
| 277 "text": Long Description of the record | |
| 278 "sheet": Sheet of conditions object | |
| 279 "files": List of file object | |
| 280 "labels": List of record labels | |
| 281 Methods: | |
| 282 __getstate__(self) | |
| 283 __setstate__(self, tuple) | |
| 284 __init__(self, filename=None, budget=None) | |
| 285 {get/set}Code | |
| 286 {get/set}Synonyms | |
| 287 {get/set}RecordType | |
| 288 {get/set}Unit | |
| 289 {get/set}Summary | |
| 290 {get/set}Prices | |
| 291 addPrice | |
| 292 _validate_price_date | |
| 293 getPrice | |
| 294 getAmount | |
| 295 getDate | |
| 296 {get/set}Parents | |
| 297 appendParent | |
| 298 {get/set}children | |
| 299 appendChild | |
| 300 {get/set}Text | |
| 301 {get/set}Sheet | |
| 302 {get/set}Files | |
| 303 addFile | |
| 304 {get/set}Labels | |
| 305 addLabel | |
| 306 """ | |
| 307 __slots__ = ["_Record__code", "_Record__synonyms", | |
| 308 "_Record__recordType", "_Record__unit", | |
| 309 "_Record__summary", "_Record__prices", | |
| 310 "_Record__parents", "_Record__children", | |
| 311 "_Record__text", "_Record__sheet", | |
| 312 "_Record__files", "_Record__labels"] | |
| 313 | |
| 314 def __getstate__(self): | |
| 315 return (self.__code, self.__synonyms, self.__recordType, | |
| 316 self.__unit, self.__summary, self.__prices, | |
| 317 self.__parents, self.__children, self.__text, | |
| 318 self.__sheet, self.__files, self.__labels) | |
| 319 | |
| 320 def __setstate__(self, tuple): | |
| 321 self.__code = tuple[0] | |
| 322 self.__synonyms = tuple[1] | |
| 323 self.__recordType = tuple[2] | |
| 324 self.__unit = tuple[3] | |
| 325 self.__summary = tuple[4] | |
| 326 self.__prices = tuple[5] | |
| 327 self.__parents = tuple[6] | |
| 328 self.__children = tuple[7] | |
| 329 self.__text = tuple[8] | |
| 330 self.__sheet = tuple[9] | |
| 331 self.__files = tuple[10] | |
| 332 self.__labels = tuple[11] | |
| 333 | |
| 334 def __init__(self, decimals, code, synonyms, hierarchy, unit, summary, | |
| 335 prices, type, subtype, parents=[], text=""): | |
| 336 self.code = code | |
| 337 self.synonyms = synonyms | |
| 338 self.recordType = (hierarchy, type, subtype) | |
| 339 self.unit = unit | |
| 340 self.summary = summary | |
| 341 self.setPrices(prices, decimals) | |
| 342 self.parents = parents | |
| 343 self.children = [] | |
| 344 self.text = text | |
| 345 self.sheet = Sheet() | |
| 346 self.files = [] | |
| 347 self.labels = [] | |
| 348 | |
| 349 def getCode(self): | |
| 350 return self.__code | |
| 351 | |
| 352 def setCode(self, code): | |
| 353 """setCode(self,code) | |
| 354 | |
| 355 Sets the code, must be a valid code | |
| 356 """ | |
| 357 if not utils.is_valid_code(code)[0]: | |
| 358 raise ValueError, utils.mapping(_("Invalid code: $1"),(str(code),)) | |
| 359 self.__code = code | |
| 360 | |
| 361 def getSynonyms(self): | |
| 362 return self.__synonyms | |
| 363 | |
| 364 def setSynonyms(self,synonyms): | |
| 365 """setSynonyms(self,synonyms) | |
| 366 | |
| 367 Sets the synonyms codes of the record. | |
| 368 synonyms must fulfill: | |
| 369 - must be a list | |
| 370 - the items must be valid codes | |
| 371 """ | |
| 372 if not isinstance(synonyms, list): | |
| 373 raise TypeError, utils.mapping(_("Synonyms ($1) must be a list, " \ | |
| 374 "code: $2"), (str(synonyms), self.__code)) | |
| 375 for code in synonyms: | |
| 376 if not utils.is_valid_code(code)[0]: | |
| 377 raise ValueError, utils.mapping(_("Invalid Code in synomyms "\ | |
| 378 "list ($1) code: $2"), (str(code), self.__code)) | |
| 379 self.__synonyms = synonyms | |
| 380 | |
| 381 def getRecordType(self): | |
| 382 return self.__recordType | |
| 383 | |
| 384 def setRecordType(self, recordType): | |
| 385 """setRecordType(self, recordType) | |
| 386 | |
| 387 Set the record type. | |
| 388 recordType (hierarchy, type,subtype) | |
| 389 | |
| 390 hierarchy must be -1, 0, 1 or 2 | |
| 391 type must be 0, 1, 2, 3 or a empty string | |
| 392 subtype must be EA, EU, EC, EF, OB, PA, PU, H, Q, %, MC, MCr, | |
| 393 MM, MS, ME, MCu, MAl, ML, M, or a empty string | |
| 394 """ | |
| 395 _recordType = RecordType(recordType[0],recordType[1],recordType[2]) | |
| 396 self.__recordType = _recordType | |
| 397 | |
| 398 def getUnit(self): | |
| 399 return self.__unit | |
| 400 | |
| 401 def setUnit(self,unit): | |
| 402 """setUnit(self,unit) | |
| 403 | |
| 404 Set the unit of measure | |
| 405 The unit must be a string. | |
| 406 """ | |
| 407 if not isinstance(unit, str): | |
| 408 raise TypeError, utils.mapping(_("Unit ($1) must be a string: $2"), | |
| 409 (str(unit), self.__code)) | |
| 410 self.__unit = unit | |
| 411 | |
| 412 def getSummary(self): | |
| 413 return self.__summary | |
| 414 | |
| 415 def setSummary(self,summary): | |
| 416 """setSummary(self,summary) | |
| 417 | |
| 418 Set the summary of a record | |
| 419 The summary must be a string. | |
| 420 """ | |
| 421 if not isinstance(summary, str): | |
| 422 raise TypeError, utils.mapping(_("Summary ($1) must be a string: "\ | |
| 423 "$1"), (str(summary), self.__code)) | |
| 424 self.__summary = summary | |
| 425 | |
| 426 def getPrices(self): | |
| 427 return self.__prices | |
| 428 | |
| 429 def setPrices(self, prices, decimals): | |
| 430 """setPrice(self, prices, decimals) | |
| 431 | |
| 432 Set the price list of the record. | |
| 433 prices must fulfill: | |
| 434 - it must be a list | |
| 435 - the items must be a list with two items | |
| 436 - the first item: price must be a float | |
| 437 """ | |
| 438 if not isinstance(prices, list): | |
| 439 raise TypeError, utils.mapping(_("Prices ($1) must be a list: $2"), | |
| 440 (str(prices), self.__code)) | |
| 441 for index in range(len(prices)): | |
| 442 _price_date = prices[index] | |
| 443 _price_date = self._validate_price_date(_price_date, decimals) | |
| 444 prices[index] = _price_date | |
| 445 self.__prices = prices | |
| 446 | |
| 447 def addPrice(self, price_date, decimals): | |
| 448 """addPrice(self, price_date, decimals) | |
| 449 | |
| 450 Add a price to the price list of the record. | |
| 451 price must fulfill: | |
| 452 - must be a list with two items | |
| 453 - the first item: price must be a float | |
| 454 """ | |
| 455 price_date = self._validate_price_date(price_date, decimals) | |
| 456 self.__prices.append(price_date) | |
| 457 | |
| 458 def _validate_price_date(self, price_date, decimals): | |
| 459 if not isinstance(price_date, list) and len(price_date) == 2: | |
| 460 raise ValueError, utils.mapping(_("Price ($1) must be a list"\ | |
| 461 " with two items: $2"), (str(price_date), self.__code)) | |
| 462 _price = price_date[0] | |
| 463 _date = price_date[1] | |
| 464 if not isinstance(_price, float): | |
| 465 raise TypeError, utils.mapping(_("Price must be a float "\ | |
| 466 "number: $1"), (str(_price),)) | |
| 467 _D = decimals.getD(self.recordType) | |
| 468 _price = round(_price, _D) | |
| 469 price_date[0] = _price | |
| 470 # TODO: validate date | |
| 471 return price_date | |
| 472 | |
| 473 def getPrice(self, index_price): | |
| 474 if len(self.__prices) <= index_price: | |
| 475 raise IndexError, _("The record do not have this Price. Code: %s" | |
| 476 % self.__code) | |
| 477 return self.__prices[index_price][0] | |
| 478 | |
| 479 def getDate(self, index_price): | |
| 480 if len(self.__prices) <= index_price: | |
| 481 raise IndexError, _("The record do not have this Price") | |
| 482 return self.__prices[index_price][1] | |
| 483 | |
| 484 def getParents(self): | |
| 485 return self.__parents | |
| 486 | |
| 487 def setParents(self,parents): | |
| 488 """setParents(self,parents) | |
| 489 | |
| 490 Sets the list of parents codes of the record. | |
| 491 parents must fulfill | |
| 492 - it must be a list | |
| 493 - the items must be valid codes | |
| 494 """ | |
| 495 if not isinstance(parents, list): | |
| 496 raise TypeError, utils.mapping(_("Parents ($1) must be a list: $2"), | |
| 497 (str(parents), self.__code)) | |
| 498 for parent in parents: | |
| 499 if not utils.is_valid_code(parent)[0]: | |
| 500 raise ValueError, utils.mapping(_("Invalid parent code ($1) " \ | |
| 501 "in the record: $2"), (str(padre), self.__code)) | |
| 502 self.__parents = parents | |
| 503 | |
| 504 def appendParent(self, parent): | |
| 505 """appendParent(self, parent) | |
| 506 | |
| 507 parent must be a valid code | |
| 508 Append a parent to the list of parents codes of the record. | |
| 509 | |
| 510 """ | |
| 511 if not utils.is_valid_code(parent)[0]: | |
| 512 raise ValueError, utils.mapping(_("Invalid parent code ($1) " \ | |
| 513 "in the record: $2"), (str(parent), self.__code)) | |
| 514 self.__parents.append(parent) | |
| 515 | |
| 516 def getchildren(self): | |
| 517 return self.__children | |
| 518 | |
| 519 def setchildren(self,children): | |
| 520 """setchildren(self,children) | |
| 521 | |
| 522 Sets the list of children of a record | |
| 523 children must fulfill | |
| 524 - it must be a list | |
| 525 - the items must be instances of Decomposition class | |
| 526 """ | |
| 527 if not isinstance(children, list): | |
| 528 raise TypeError, utils.mapping(_("children ($1) must be a list, "\ | |
| 529 "record: $2"), (str(children), self.__code)) | |
| 530 for _child in children: | |
| 531 if not isinstance(_child, Decomposition): | |
| 532 raise ValueError, utils.mapping(_("child ($1) must be a "\ | |
| 533 "Decomposition object, record: $2"), | |
| 534 (str(_child), self.__code)) | |
| 535 _record_code = self.code | |
| 536 for _measure_list in [_child.budgetMeasures, _child.certification, | |
| 537 _child.real_cost, _child.cost_goals, | |
| 538 _child.cost_planned]: | |
| 539 if isinstance(_measure_list, list): | |
| 540 for _measure in _measure_list: | |
| 541 _measurerecordCode = _record_code | |
| 542 self.__children = children | |
| 543 | |
| 544 def appendChild(self, child_code, decimals, factor=0.0, yield_=0.0, | |
| 545 measure=0.0, measure_list=[], type ="", label=""): | |
| 546 """appendChildren(self, child_code, factor=0.0, yield_=0.0, | |
| 547 measure=0.0, measure_list=[], type ="", label="")) | |
| 548 | |
| 549 position: | |
| 550 child_code: | |
| 551 factor: | |
| 552 yield_: | |
| 553 measure: | |
| 554 measure_list: | |
| 555 type: | |
| 556 label: | |
| 557 | |
| 558 Append a child to the list of children | |
| 559 """ | |
| 560 _measure = Measure(decimals, self.recordType, | |
| 561 measure, [], label, factor, yield_) | |
| 562 if len(measure_list) > 0: | |
| 563 measure.buildMeasure(_measure, measure_list, type, decimals, | |
| 564 self.recordType) | |
| 565 _position = len(self.__children) | |
| 566 _child = Decomposition(_position, child_code, [_measure]) | |
| 567 self.__children.append(_child) | |
| 568 return _child | |
| 569 | |
| 570 def getText(self): | |
| 571 return self.__text | |
| 572 | |
| 573 def setText(self,text): | |
| 574 """setText(self,text) | |
| 575 | |
| 576 Sets the text of the record | |
| 577 It must be a string | |
| 578 """ | |
| 579 if not isinstance(text, str): | |
| 580 raise TypeError, utils.mapping(_("Text ($1) must be a string, "\ | |
| 581 "record: $2"), (str(text), self.__code)) | |
| 582 self.__text = text | |
| 583 | |
| 584 def getSheet(self): | |
| 585 return self.__sheet | |
| 586 | |
| 587 def setSheet(self, sheet): | |
| 588 """setSheet(self, sheet) | |
| 589 | |
| 590 Sets the sheet of condition object | |
| 591 """ | |
| 592 if not isinstance(sheet, Sheet): | |
| 593 raise ValueError, _("sheet must be a Sheet instance") | |
| 594 self.__sheet = sheet | |
| 595 | |
| 596 def getFiles(self): | |
| 597 return self.__files | |
| 598 | |
| 599 def setFiles(self, files): | |
| 600 """setFiles(self, files) | |
| 601 | |
| 602 Sets the files list | |
| 603 """ | |
| 604 # TODO: only sets files and File object format (durusdatabase) | |
| 605 if not isinstance(files, list): | |
| 606 raise ValueError, utils.mapping(_("files must be a list: $1"), | |
| 607 str(files)) | |
| 608 _files = [] | |
| 609 for file in files: | |
| 610 if isinstance(file, File): | |
| 611 _files.append(file) | |
| 612 elif isinstance(file, list): | |
| 613 _file_path = file[0] | |
| 614 _type = file[1] | |
| 615 _description = file[2] | |
| 616 if not os.path.exists(file[0]): | |
| 617 raise ValueError, _("Incorrect path") | |
| 618 _file = File(file_path, type, description) | |
| 619 _files.append(_file) | |
| 620 else: | |
| 621 raise ValueError, utils.mapping(_( | |
| 622 "file must be a list or a File object: $1"),str(file)) | |
| 623 self.__files = _files | |
| 624 | |
| 625 | |
| 626 def addFile(self, file_path, type, description): | |
| 627 """addFile(self, file_path, type, description) | |
| 628 | |
| 629 Add a file to a record instance | |
| 630 """ | |
| 631 if not os.path.exists(file_path): | |
| 632 raise ValueError, _("Incorrect path") | |
| 633 _name = os.path.basename(file_path) | |
| 634 _isin = False | |
| 635 for _ofile in self.__files: | |
| 636 if _ofile.name == _name: | |
| 637 _isin = True | |
| 638 if not _isin: | |
| 639 _file = File(_name, type, description) | |
| 640 self.__files.append(_file) | |
| 641 | |
| 642 def getLabels(self): | |
| 643 return self.__labels | |
| 644 | |
| 645 def setLabels(self, labels): | |
| 646 """setLabels(self, labels) | |
| 647 | |
| 648 Sets the labels list of a record | |
| 649 """ | |
| 650 if not isinstance(labels, list): | |
| 651 raise ValueError, _("labels must be a list") | |
| 652 _labels = [] | |
| 653 for _label in labels: | |
| 654 if isinstance(_label, str): | |
| 655 _labels.append(_label) | |
| 656 else: | |
| 657 raise ValueError, _("label must be a string") | |
| 658 self.__labels = _labels | |
| 659 | |
| 660 def addLabel(self, label): | |
| 661 """addLabel(self, label) | |
| 662 | |
| 663 Add a label to a record instance | |
| 664 """ | |
| 665 if not isinstance(label, str): | |
| 666 raise ValueError, _("Label must be a string") | |
| 667 if not label in self.__labels: | |
| 668 self.__labels.append(label) | |
| 669 | |
| 670 recordType = property(getRecordType, setRecordType, None, | |
| 671 """Record Type object | |
| 672 """) | |
| 673 code = property(getCode, setCode, None, | |
| 674 """Record code | |
| 675 """) | |
| 676 synonyms = property(getSynonyms, setSynonyms, None, | |
| 677 """List of codes synonyms of the code | |
| 678 """) | |
| 679 unit = property(getUnit,setUnit, None, | |
| 680 """Measure Unit of the record | |
| 681 """) | |
| 682 summary = property(getSummary, setSummary, None, | |
| 683 """Short description of the record | |
| 684 """) | |
| 685 prices = property(getPrices, None, None, | |
| 686 """List of Price/Date | |
| 687 """) | |
| 688 parents = property(getParents, setParents, None, | |
| 689 """List of codes of the records which the record is in | |
| 690 its decomposition | |
| 691 """) | |
| 692 children = property(getchildren, setchildren, None, | |
| 693 """List of Decompositon intances""") | |
| 694 text = property(getText, setText, None, | |
| 695 """Long description of the record""") | |
| 696 sheet = property(getSheet, setSheet, None, | |
| 697 """Sheet of conditions object""") | |
| 698 files = property(getFiles, setFiles, None, | |
| 699 """File list""") | |
| 700 labels = property(getLabels, setLabels, None, | |
| 701 """Label list""") | |
| 702 | |
| 703 class ParametricRecord(Record): | |
| 704 """base.ParametricRecord: | |
| 705 | |
| 706 Description: | |
| 707 Parametric Record object | |
| 708 Constructor: | |
| 709 base.ParametricRecord(code, synonyms, hierarchy, unit, summary, prices, | |
| 710 type, subtype, text="") | |
| 711 Ancestry: | |
| 712 +-- object | |
| 713 +-- Record | |
| 714 +-- ParametricRecord | |
| 715 Atributes: | |
| 716 | |
| 717 Methods: | |
| 718 | |
| 719 """ | |
| 720 | |
| 721 __slots__ = ["_ParametricRecord__budget", | |
| 722 "_ParametricRecord__code", "_ParametricRecord__synonyms", | |
| 723 "_ParametricRecord__hierarchy", "_ParametricRecord__unit", | |
| 724 "_ParametricRecord__summary", "_ParametricRecord__prices", | |
| 725 "_ParametricRecord__type", "_ParametricRecord__subtype", | |
| 726 "_ParametricRecord__parents", "_ParametricRecord__children", | |
| 727 "_ParametricRecord__text", "_ParametricRecord__sheet", | |
| 728 "_ParametricRecord__files", "_ParametricRecord__labels", | |
| 729 "_ParametricRecord__parameters", | |
| 730 "_ParametricRecord__select_comment", | |
| 731 "_ParametricRecord__vars", | |
| 732 "_ParametricRecord__parametric_summary", | |
| 733 "_ParametricRecord__parametric_text",] | |
| 734 | |
| 735 def __getstate__(self): | |
| 736 return (self.__budget, self.__code, self.__synonyms, self.__hierarchy, | |
| 737 self.__unit, self.__summary, self.__prices, self.__type, | |
| 738 self.__subtype, self.__parents, self.__children, self.__text, | |
| 739 self.__sheet, self.__files, self.__labels, self.__parameters, | |
| 740 self.__select_comment, self.__vars, | |
| 741 self.__parametric_summary, self.__parametric_text) | |
| 742 | |
| 743 def __setstate__(self, tuple): | |
| 744 self.__budget = tuple[0] | |
| 745 self.__code = tuple[1] | |
| 746 self.__synonyms = tuple[2] | |
| 747 self.__hierarchy = tuple[3] | |
| 748 self.__unit = tuple[4] | |
| 749 self.__summary = tuple[5] | |
| 750 self.__prices = tuple[6] | |
| 751 self.__type = tuple[7] | |
| 752 self.__subtype = tuple[8] | |
| 753 self.__parents = tuple[9] | |
| 754 self.__children = tuple[10] | |
| 755 self.__text = tuple[11] | |
| 756 self.__sheet = tuple[12] | |
| 757 self.__files = tuple[13] | |
| 758 self.__labels = tuple[14] | |
| 759 self.__parameters = tuple[15] | |
| 760 self.__select_comment = tuple[16] | |
| 761 self.__vars = tuple[17] | |
| 762 self.__parametric_summary = tuple[18] | |
| 763 self.__parametric_text = tuple[19] | |
| 764 | |
| 765 def __init__(self, budget, code, synonyms, hierarchy, unit, summary, | |
| 766 prices, type, subtype, parents=[], text=""): | |
| 767 Record.__init__(self, budget, code, synonyms, hierarchy, unit, summary, | |
| 768 prices, type, subtype, parents=[], text="") | |
| 769 self.__parameters = {} | |
| 770 self.__select_comment = "" | |
| 771 self.__vars = {} | |
| 772 self.parametric_summary = "" | |
| 773 self.parametric_text = "" | |
| 774 | |
| 775 def getParameter(self, parameter): | |
| 776 if parameter in self.__parameters: | |
| 777 return self.__parameters[parameter] | |
| 778 else: | |
| 779 return None | |
| 780 | |
| 781 def setParameter(self, parameter, parameter_list): | |
| 782 self.__parameters[parameter] = parameter_list | |
| 783 | |
| 784 def getSelectComment(self): | |
| 785 return self.__select_comment | |
| 786 | |
| 787 def setSelectComment(self, select_comment): | |
| 788 self.__select_comment = select_comment | |
| 789 def getVar(self, var): | |
| 790 if var in self.__vars: | |
| 791 return self.__vars[var] | |
| 792 else: | |
| 793 return None | |
| 794 | |
| 795 def setVar(self, var, var_list): | |
| 796 self.__vars[var] = var_list | |
| 797 | |
| 798 def getParametricSummary(self): | |
| 799 return self.__parametric_summary | |
| 800 | |
| 801 def setParametricSummary(self, parametric_summary): | |
| 802 self.__parametric_summary = parametric_summary | |
| 803 | |
| 804 def getParametricText(self): | |
| 805 return self.__parametric_text | |
| 806 | |
| 807 def setParametricText(self, parametric_text): | |
| 808 self.__parametric_text = parametric_text | |
| 809 | |
| 810 parameter = property(getParameter, setParameter, None, | |
| 811 """Record parameter | |
| 812 """) | |
| 813 select_comment = property(getSelectComment, setSelectComment, None, | |
| 814 """Seclect comment | |
| 815 """) | |
| 816 var = property(getVar, setVar, None, | |
| 817 """Record var | |
| 818 """) | |
| 819 parametric_summary = property(getParametricSummary, setParametricSummary, | |
| 820 None, | |
| 821 """Parametric summary | |
| 822 """) | |
| 823 parametric_text = property(getParametricText, setParametricText, None, | |
| 824 """Seclect comment | |
| 825 """) | |
| 826 | |
| 827 class Decomposition(object): | |
| 828 """base.Decomposition: | |
| 829 | |
| 830 Description: | |
| 831 Decomposition object | |
| 832 Constructor: | |
| 833 base.Decomposition(position, code, budgetMeasures, certification=None, | |
| 834 real_cost=None, cost_goals=None, cost_planned=None) | |
| 835 Ancestry: | |
| 836 +-- object | |
| 837 +-- Decomposition | |
| 838 Atributes: | |
| 839 "position": the position of the child record in the parent record | |
| 840 "code": Record code. | |
| 841 Measures: | |
| 842 "budgetMeasures": list of budget and Amended budget measures | |
| 843 "certification": list of certifications for months measures | |
| 844 "real_cost": list of real cost of construction for months measures | |
| 845 "cost_goals": list of cost goals of construction for months measures | |
| 846 "cost_planned": list of costs planned and amended cost planned measures | |
| 847 Methods: | |
| 848 __getstate__(self) | |
| 849 __setstate__(self, tuple) | |
| 850 __init__( position, code, budgetMeasures, certification=None, | |
| 851 real_cost=None, cost_goals=None, cost_planned=None) | |
| 852 {get/set}position | |
| 853 {get/set}Code | |
| 854 {get/set}BudgetMeasures | |
| 855 {get/set}Certification | |
| 856 {get/set}RealCost | |
| 857 {get/set}CostGoals | |
| 858 {get/set}CostPlanned | |
| 859 """ | |
| 860 __slots__ = ["_Decomposition__position", | |
| 861 "_Decomposition__code", | |
| 862 "_Decomposition__budgetMeasures", | |
| 863 "_Decomposition__certification", | |
| 864 "_Decomposition__real_cost", | |
| 865 "_Decomposition__cost_goals", | |
| 866 "_Decomposition__cost_planned", | |
| 867 ] | |
| 868 def __getstate__ (self): | |
| 869 return (self.__position, self.__code, self.__budgetMeasures, | |
| 870 self.__certification, self.__real_cost, self.__cost_goals, | |
| 871 self.__cost_planned) | |
| 872 def __setstate__(self,tuple): | |
| 873 self.__position = tuple[0] | |
| 874 self.__code = tuple[1] | |
| 875 self.__budgetMeasures = tuple[2] | |
| 876 self.__certification = tuple[3] | |
| 877 self.__real_cost = tuple[4] | |
| 878 self.__cost_goals = tuple[5] | |
| 879 self.__cost_planned = tuple[6] | |
| 880 | |
| 881 def __init__(self, position, code, budgetMeasures, certification=None, | |
| 882 real_cost=None, cost_goals=None, cost_planned=None): | |
| 883 self.position = position | |
| 884 self.code = code | |
| 885 self.budgetMeasures = budgetMeasures | |
| 886 self.certification = certification | |
| 887 self.real_cost = real_cost | |
| 888 self.cost_goals = cost_goals | |
| 889 self.cost_planned = cost_planned | |
| 890 def getPosition(self): | |
| 891 return self.__position | |
| 892 def setPosition(self, position): | |
| 893 if not isinstance(position, int): | |
| 894 raise ValueError, _("Position must be a integer") | |
| 895 self.__position = position | |
| 896 def getCode(self): | |
| 897 return self.__code | |
| 898 def setCode(self, code): | |
| 899 self.__code = code | |
| 900 def getBudgetMeasures(self): | |
| 901 return self.__budgetMeasures | |
| 902 def setBudgetMeasures(self, budgetMeasures): | |
| 903 if not isinstance(budgetMeasures, list): | |
| 904 raise ValueError, _("BudgetMeasures atribute must be a list") | |
| 905 for _measure in budgetMeasures: | |
| 906 if not isinstance(_measure, Measure): | |
| 907 raise ValueError, _("BudgetMeasures item must be a Measure "/ | |
| 908 "object") | |
| 909 self.__budgetMeasures = budgetMeasures | |
| 910 def getCertification(self): | |
| 911 return self.__certification | |
| 912 def setCertification(self, certification): | |
| 913 if not (certification is None or isinstance(certification, list)): | |
| 914 raise ValueError, _("Certification atribute must be a list or None") | |
| 915 self.__certification = certification | |
| 916 def getRealCost(self): | |
| 917 return self.__real_cost | |
| 918 def setRealCost(self, real_cost): | |
| 919 if not (real_cost is None or isinstance(real_cost, list)): | |
| 920 raise ValueError, _("Real cost atribute must be a list or None") | |
| 921 self.__real_cost = real_cost | |
| 922 def getCostGoals(self): | |
| 923 return self.__cost_goals | |
| 924 def setCostGoals(self, cost_goals): | |
| 925 if not (cost_goals is None or isinstance(cost_goals, list)): | |
| 926 raise ValueError, _("Cost goals atribute must be a list or None") | |
| 927 self.__cost_goals = cost_goals | |
| 928 def getCostPlanned(self): | |
| 929 return self.__cost_planned | |
| 930 def setCostPlanned(self, cost_planned): | |
| 931 if not (cost_planned is None or isinstance(cost_planned, list)): | |
| 932 raise ValueError, _("Cost Planned atribute must be a list or None") | |
| 933 self.__cost_planned = cost_planned | |
| 934 position = property(getPosition, setPosition, None, | |
| 935 """Postion of the record in the budget | |
| 936 """) | |
| 937 code = property(getCode, setCode, None, | |
| 938 """Record code | |
| 939 """) | |
| 940 budgetMeasures = property(getBudgetMeasures, setBudgetMeasures, None, | |
| 941 """list of budget and Amended budget measures | |
| 942 """) | |
| 943 certification = property(getCertification, setCertification,None, | |
| 944 """ list of certifications by months measures | |
| 945 """) | |
| 946 real_cost = property(getRealCost, setRealCost, None, | |
| 947 """ list of real cost of construction for months measures | |
| 948 """) | |
| 949 cost_goals = property(getCostGoals, setCostGoals, None, | |
| 950 """ list of cost goals of construction for months measures | |
| 951 """) | |
| 952 cost_planned = property(getCostPlanned, setCostPlanned, None, | |
| 953 """ list of costs planned and amended cost planned measures | |
| 954 """) | |
| 955 | |
| 956 | |
| 957 class Measure(object): | |
| 958 """base.Measure: | |
| 959 | |
| 960 Description: | |
| 961 Measure object | |
| 962 Constructor: | |
| 963 base.Measure(decimals, recordType, measure, lines, | |
| 964 label, factor, yield_) | |
| 965 Ancestry: | |
| 966 +-- object | |
| 967 +-- Measure | |
| 968 Atributes: | |
| 969 "measure": Total result of measure. | |
| 970 "lines": List of measure lines, List of LineM instances. | |
| 971 "label": Record Identifiers that are used by some measure programs. | |
| 972 "factor": | |
| 973 "yield": | |
| 974 "fixed": If fixed is True the yield is not calculated from measure | |
| 975 Methods: | |
| 976 __getstate__() | |
| 977 __setstate__(tuple) | |
| 978 __init__(decimals, recordType, measure, lines, | |
| 979 label, factor, yield_) | |
| 980 getMeasure() | |
| 981 setMeasure(measure, decimals) | |
| 982 {get/set}Lines | |
| 983 {get/set}Label | |
| 984 getFactor() | |
| 985 setFactor(factor, decimals, recordType) | |
| 986 getYield() | |
| 987 setYield(yield_, decimals, recordType) | |
| 988 getFixed() | |
| 989 setFixed(decimals) | |
| 990 buildMeasure(list_lines, type, decimals) | |
| 991 calculateMeasure(decimals) | |
| 992 updateYield(decimals) | |
| 993 """ | |
| 994 __slots__ = ["_Measure__measure", | |
| 995 "_Measure__lines", | |
| 996 "_Measure__label", | |
| 997 "_Measure__factor", | |
| 998 "_Measure__yield_", | |
| 999 "_Measure__fixed"] | |
| 1000 def __getstate__ (self): | |
| 1001 return (self.__measure, self.__lines, self.__label, | |
| 1002 self.__factor, self.__yield_, self.__fixed) | |
| 1003 def __setstate__(self,tuple): | |
| 1004 self.__measure = tuple[0] | |
| 1005 self.__lines = tuple[1] | |
| 1006 self.__label = tuple[2] | |
| 1007 self.__factor = tuple[3] | |
| 1008 self.__yield_ = tuple[4] | |
| 1009 self.__fixed = tuple[5] | |
| 1010 def __init__(self, decimals, recordType, measure, lines, | |
| 1011 label, factor, yield_): | |
| 1012 self.setMeasure(measure, decimals) | |
| 1013 self.lines = lines | |
| 1014 self.label = label | |
| 1015 self.setFactor(factor, decimals, recordType) | |
| 1016 self.setYield(yield_, decimals, recordType) | |
| 1017 self.__fixed = False | |
| 1018 | |
| 1019 def getMeasure(self): | |
| 1020 return self.__measure | |
| 1021 def setMeasure(self, measure, decimals): | |
| 1022 if not isinstance(measure, float): | |
| 1023 raise ValueError, utils.mapping(_("Measure must be a float "\ | |
| 1024 "number. Type: $1"), (type(measure),)) | |
| 1025 # TODO: test after | |
| 1026 _DS = decimals.DS | |
| 1027 measure = round(measure, _DS) | |
| 1028 self.__measure = measure | |
| 1029 | |
| 1030 def getLines(self): | |
| 1031 return self.__lines | |
| 1032 def setLines(self, lines): | |
| 1033 if not isinstance(lines, list): | |
| 1034 raise ValueError, _("Lines must be a list") | |
| 1035 for _line in lines: | |
| 1036 if not isinstance(_line, MeasureLine): | |
| 1037 raise ValueError, _("Line must be a MeasureLine objetc") | |
| 1038 self.__lines = lines | |
| 1039 def getLabel(self): | |
| 1040 return self.__label | |
| 1041 def setLabel(self, label): | |
| 1042 self.__label = label | |
| 1043 def setFactor(self, factor, decimals, recordType): | |
| 1044 if not isinstance(factor, float): | |
| 1045 raise ValueError, utils.mapping(_("Factor must be a float number "\ | |
| 1046 "|$1|"), (factor,)) | |
| 1047 # TODO: test after | |
| 1048 _DF = decimals.getDF(recordType) | |
| 1049 factor = round(factor, _DF) | |
| 1050 self.__factor = factor | |
| 1051 | |
| 1052 def getFactor(self): | |
| 1053 return self.__factor | |
| 1054 | |
| 1055 def setYield(self, yield_, decimals, recordType): | |
| 1056 if not isinstance(yield_, float): | |
| 1057 raise ValueError, _("Yield must be a float number") | |
| 1058 # TODO: test after | |
| 1059 _DR = decimals.getDR(recordType) | |
| 1060 yield_ = round(yield_, _DR) | |
| 1061 self.__yield_ = yield_ | |
| 1062 | |
| 1063 def getYield(self): | |
| 1064 return self.__yield_ | |
| 1065 | |
| 1066 def setFixed(self, fixed, decimals): | |
| 1067 if not isinstance(fixed, bool): | |
| 1068 raise ValueError, _("Fixed must be boolean object") | |
| 1069 self.__fixed = fixed | |
| 1070 self.updateYield(decimals) | |
| 1071 | |
| 1072 def getFixed(self): | |
| 1073 return self.__fixed | |
| 1074 | |
| 1075 measure = property(getMeasure, None, None, | |
| 1076 """Total result of the measure | |
| 1077 """) | |
| 1078 lines = property(getLines, setLines, None, | |
| 1079 """List of measure lines, List of "MeasureLine" instances | |
| 1080 """) | |
| 1081 label = property(getLabel, setLabel, None, | |
| 1082 """Record identifiers that are used in some measure programs | |
| 1083 """) | |
| 1084 factor = property(getFactor, None, None, | |
| 1085 """Factor | |
| 1086 """) | |
| 1087 yield_ = property(getYield, None, None, | |
| 1088 """Yield of a record | |
| 1089 """) | |
| 1090 fixed = property(getFixed, setFixed,None, | |
| 1091 """If fixed is True the yield is not calculated from measure | |
| 1092 """) | |
| 1093 | |
| 1094 def buildMeasure(self, list_lines, type, decimals, recordType): | |
| 1095 """setMeasure(self, list_lines, type, decimals) | |
| 1096 | |
| 1097 list_lines: list of measure lines | |
| 1098 [ [linetype, comment, units, length, width, height, formula], ... ] | |
| 1099 linetype: | |
| 1100 #-#empty string -> Normal | |
| 1101 0 -> Normal | |
| 1102 1 -> Parcial Subtotal | |
| 1103 2 -> Accumulated Subtotal | |
| 1104 3 -> Formula | |
| 1105 comment: comment string | |
| 1106 units: Number of Units (a) | |
| 1107 length: Length (b) | |
| 1108 width: Width (c) | |
| 1109 height: Height (d) | |
| 1110 formula: Can be a formula or a empty string | |
| 1111 Valid Operator: '(', ')', '+', '-', '*', '/' and '^' | |
| 1112 Valid variable: 'a', 'b', 'c','d' and 'p' (Pi=3.1415926) | |
| 1113 type: type of action | |
| 1114 M: Set measure | |
| 1115 A: Add measure | |
| 1116 decimal: budget decimals object | |
| 1117 | |
| 1118 Sets the measurelines for a record | |
| 1119 """ | |
| 1120 # TODO: calcutate measure from lines | |
| 1121 _parcial = 0 | |
| 1122 _total = 0 | |
| 1123 _lines = [] | |
| 1124 for _line in list_lines: | |
| 1125 _type, _comment = _line[0], _line[1] | |
| 1126 _units, _length = _line[2], _line[3] | |
| 1127 _width, _height = _line[4], _line[5] | |
| 1128 _formula = _line[6] | |
| 1129 _measure_line = MeasureLine(decimals, _type, _comment, _units, | |
| 1130 _length, _width, _height, _formula) | |
| 1131 _lines.append(_measure_line) | |
| 1132 if type == "M": | |
| 1133 self.lines = _lines | |
| 1134 elif type == "A": | |
| 1135 self.lines.extend(_lines) | |
| 1136 else: | |
| 1137 raise ValueError, utils.mapping(_("Type must be M or A. Type: $1"), | |
| 1138 (type,)) | |
| 1139 self.calculateMeasure(decimals, recordType) | |
| 1140 | |
| 1141 def calculateMeasure(self, decimals, recordType): | |
| 1142 #TODO: round acumulated_subtotal and parcial_subtotal | |
| 1143 if len(self.lines) > 0: | |
| 1144 _acumulated_total = 0.0 | |
| 1145 _parcial_total = 0.0 | |
| 1146 for line in self.lines: | |
| 1147 _parcial = line.parcial | |
| 1148 _acumulated_total += _parcial | |
| 1149 if line.lineType == 2: | |
| 1150 line.setAcumulatedSubtotal(_acumulated_total, decimals) | |
| 1151 elif line.lineType == 1: | |
| 1152 _parcialSubtotal = _acumulated_total - _parcial_total | |
| 1153 line.setParcialSubtotal(_parcialSubtotal, decimals) | |
| 1154 _parcial_total = _acumulated_total | |
| 1155 self.setMeasure(_acumulated_total, decimals) | |
| 1156 _DR = decimals.getDR(recordType) | |
| 1157 self.updateYield(decimals, recordType) | |
| 1158 def updateYield(self, decimals, recordType): | |
| 1159 if not self.fixed: | |
| 1160 self.setYield(self.measure, decimals, recordType) | |
| 1161 | |
| 1162 class MeasureLine(object): | |
| 1163 """base.MeasureLine: | |
| 1164 | |
| 1165 Description: | |
| 1166 MeasureLine object | |
| 1167 Constructor: | |
| 1168 base.MeasureLine(budget, type, comment, units, length, width, height, | |
| 1169 formula) | |
| 1170 Ancestry: | |
| 1171 +-- object | |
| 1172 +-- MeasureLine | |
| 1173 Atributes: | |
| 1174 "lineType": Line type: | |
| 1175 #-#empty string -> Normal | |
| 1176 0 -> Normal | |
| 1177 1 -> Parcial Subtotal | |
| 1178 2 -> Accumulated Subtotal | |
| 1179 3 -> Formula, the comment is a formula. | |
| 1180 "comment": Descriptive text string | |
| 1181 "units": Number of Units (a) | |
| 1182 "length": length (b) | |
| 1183 "width": Width (c) | |
| 1184 "height": Height (d) | |
| 1185 "formula": can be a valid formula or a empty string | |
| 1186 Valid Operator: '(', ')', '+', '-', '*', '/' and '^' | |
| 1187 Valid variable: 'a', 'b', 'c','d'y 'p' (Pi=3.1415926) | |
| 1188 "partial" : result of measure line | |
| 1189 "parcial_subtotal" | |
| 1190 "acumulated_subtotal" | |
| 1191 Methods: | |
| 1192 __getstate__(self) | |
| 1193 __setstate__(self, tuple) | |
| 1194 __init__(self, decimals, type, comment, units, length, width, height, | |
| 1195 formula) | |
| 1196 {get/set}LineType | |
| 1197 {get/set}Comment | |
| 1198 {get/set}Units | |
| 1199 {get/set}Length | |
| 1200 {get/set}Width | |
| 1201 {get/set}Height | |
| 1202 {get/set}Formula | |
| 1203 getParcial | |
| 1204 {get/set}ParcialSubtotal | |
| 1205 {get/set}AcumulatedSubtotal | |
| 1206 calculateParcial | |
| 1207 eval_formula | |
| 1208 """ | |
| 1209 __slots__ = ["_MeasureLine__lineType", | |
| 1210 "_MeasureLine__comment", | |
| 1211 "_MeasureLine__units", | |
| 1212 "_MeasureLine__length", | |
| 1213 "_MeasureLine__width", | |
| 1214 "_MeasureLine__height", | |
| 1215 "_MeasureLine__formula", | |
| 1216 "_MeasureLine__parcial", | |
| 1217 "_MeasureLine__parcial_subtotal", | |
| 1218 "_MeasureLine__acumulated_subtotal", | |
| 1219 ] | |
| 1220 def __getstate__ (self): | |
| 1221 return (self.__lineType, self.__comment, self.__units, | |
| 1222 self.__length, self.__width, self.__height, self.__formula, | |
| 1223 self.__parcial) | |
| 1224 def __setstate__(self,tuple): | |
| 1225 self.__lineType = tuple[0] | |
| 1226 self.__comment = tuple[1] | |
| 1227 self.__units = tuple[2] | |
| 1228 self.__length = tuple[3] | |
| 1229 self.__width = tuple[4] | |
| 1230 self.__height = tuple[5] | |
| 1231 self.__formula = tuple[6] | |
| 1232 self.__parcial = tuple[7] | |
| 1233 #self.calculateParcial() | |
| 1234 def __init__(self, decimals, type, comment, units, length, width, height, | |
| 1235 formula): | |
| 1236 self.__parcial = 0.0 | |
| 1237 self.__parcial_subtotal = 0.0 | |
| 1238 self.__acumulated_subtotal = 0.0 | |
| 1239 self.lineType = type | |
| 1240 self.comment = comment | |
| 1241 self.setUnits(units, decimals) | |
| 1242 self.setLength(length, decimals) | |
| 1243 self.setWidth(width, decimals) | |
| 1244 self.setHeight(height, decimals) | |
| 1245 self.setFormula(formula, decimals) | |
| 1246 #self.calculateParcial() | |
| 1247 def getLineType(self): | |
| 1248 return self.__lineType | |
| 1249 def getComment(self): | |
| 1250 return self.__comment | |
| 1251 def getUnits(self): | |
| 1252 return self.__units | |
| 1253 def getLength(self): | |
| 1254 return self.__length | |
| 1255 def getWidth(self): | |
| 1256 return self.__width | |
| 1257 def getHeight(self): | |
| 1258 return self.__height | |
| 1259 def getFormula(self): | |
| 1260 return self.__formula | |
| 1261 def getParcial(self): | |
| 1262 return self.__parcial | |
| 1263 def getParcialSubtotal(self): | |
| 1264 return self.__parcial_subtotal | |
| 1265 def getAcumulatedSubtotal(self): | |
| 1266 return self.__acumulated_subtotal | |
| 1267 def setParcialSubtotal(self, parcial_subtotal, decimals): | |
| 1268 if not isinstance(parcial_subtotal, float): | |
| 1269 raise ValueError, utils.mapping(_(" Parcial Subtotal must be a "\ | |
| 1270 "float number. Parcial: $1"), (str(parcial_subtotal),)) | |
| 1271 _DS = decimals.DS | |
| 1272 parcial_subtotal = round(parcial_subtotal, _DS) | |
| 1273 self.__parcial_subtotal = parcial_subtotal | |
| 1274 def setAcumulatedSubtotal(self, acumulated_subtotal, decimals): | |
| 1275 if not isinstance(acumulated_subtotal, float): | |
| 1276 raise ValueError, utils.mapping(_(" Acumulated Subtotal must be "\ | |
| 1277 "a float number. Parcial: $1"), | |
| 1278 (str(acumulated_subtotal),)) | |
| 1279 _DS = decimals.DS | |
| 1280 acumulated_subtotal = round(acumulated_subtotal, _DS) | |
| 1281 self.__acumulated_subtotal = acumulated_subtotal | |
| 1282 def calculateParcial(self, decimals): | |
| 1283 _DS = decimals.DS | |
| 1284 if self.lineType == 1 or self.lineType == 2: | |
| 1285 _parcial = 0.0 | |
| 1286 elif self.lineType == 0: # self.formula == "": | |
| 1287 if isinstance(self.units, float): | |
| 1288 _a = self.units | |
| 1289 else: | |
| 1290 _a = 0.0 | |
| 1291 if isinstance(self.length, float): | |
| 1292 _b = self.length | |
| 1293 else: | |
| 1294 _b = 1.0 | |
| 1295 if isinstance(self.width, float): | |
| 1296 _c = self.width | |
| 1297 else: | |
| 1298 _c = 1.0 | |
| 1299 if isinstance(self.height, float): | |
| 1300 _d = self.height | |
| 1301 else: | |
| 1302 _d = 1.0 | |
| 1303 _parcial = _a * _b * _c * _d | |
| 1304 else: | |
| 1305 _parcial = self.eval_formula() | |
| 1306 _parcial = round(_parcial, _DS) | |
| 1307 self.__parcial = _parcial | |
| 1308 | |
| 1309 def setLineType(self, type): | |
| 1310 if not type in [0, 1, 2, 3]: | |
| 1311 raise ValueError, utils.mapping(_("Invalid measure line type ($1)"), | |
| 1312 (str(type),)) | |
| 1313 self.__lineType = type | |
| 1314 def setComment(self, comment): | |
| 1315 if not isinstance(comment, str): | |
| 1316 raise ValueError, utils.mapping(_("Measure Comment must be a "\ | |
| 1317 "string ($1)"), (str(comment),)) | |
| 1318 self.__comment = comment | |
| 1319 def setUnits(self, units, decimals): | |
| 1320 if units != "": | |
| 1321 if not isinstance(units, float): | |
| 1322 raise ValueError, utils.mapping(_("Invalid Measure Units ($1)"), | |
| 1323 (str(units),)) | |
| 1324 _DN = decimals.DN | |
| 1325 units = round(units, _DN) | |
| 1326 self.__units = units | |
| 1327 try: | |
| 1328 self.calculateParcial(decimals) | |
| 1329 except AttributeError: | |
| 1330 pass | |
| 1331 def setLength(self, length, decimals): | |
| 1332 if length != "": | |
| 1333 if not isinstance(length, float): | |
| 1334 raise ValueError, utils.mapping(_("Invalid Measure length ($1)"), | |
| 1335 (str(units),)) | |
| 1336 _DD = decimals.DD | |
| 1337 length = round(length, _DD) | |
| 1338 self.__length = length | |
| 1339 try: | |
| 1340 self.calculateParcial(decimals) | |
| 1341 except AttributeError: | |
| 1342 pass | |
| 1343 def setWidth(self, width, decimals): | |
| 1344 if width != "": | |
| 1345 if not isinstance(width, float): | |
| 1346 raise ValueError, utils.mapping(_("Invalid Measure Width ($1)"), | |
| 1347 (str(units),)) | |
| 1348 _DD = decimals.DD | |
| 1349 width = round(width, _DD) | |
| 1350 self.__width = width | |
| 1351 try: | |
| 1352 self.calculateParcial(decimals) | |
| 1353 except AttributeError: | |
| 1354 pass | |
| 1355 def setHeight(self, height, decimals): | |
| 1356 if height != "": | |
| 1357 if not isinstance(height, float): | |
| 1358 raise ValueError, utils.mapping(_("Invalid Measure Height ($1)"), | |
| 1359 (str(height),)) | |
| 1360 _DD = decimals.DD | |
| 1361 height = round(height, _DD) | |
| 1362 self.__height = height | |
| 1363 try: | |
| 1364 self.calculateParcial(decimals) | |
| 1365 except AttributeError: | |
| 1366 pass | |
| 1367 def setFormula(self, formula, decimals): | |
| 1368 if not isinstance(formula, str): | |
| 1369 raise ValueError, utils.mapping(_("Formula must be a "\ | |
| 1370 "string ($1)"), (str(formula),)) | |
| 1371 if re.match(".*[^0123456789\.()\+\-\*/\^abcdp ].*", formula): | |
| 1372 raise ValueError, utils.mapping(_("There is invalid characters"\ | |
| 1373 "in formula ($1)"), (str(formula),)) | |
| 1374 self.__formula = formula | |
| 1375 try: | |
| 1376 self.calculateParcial(decimals) | |
| 1377 except AttributeError: | |
| 1378 pass | |
| 1379 | |
| 1380 lineType = property(getLineType, setLineType, None, | |
| 1381 """Type of measure line | |
| 1382 """) | |
| 1383 comment = property(getComment, setComment, None, | |
| 1384 """Text | |
| 1385 """) | |
| 1386 units = property(getUnits, None, None, | |
| 1387 """Number of units | |
| 1388 """) | |
| 1389 length = property(getLength, None, None, | |
| 1390 """Length measure | |
| 1391 """) | |
| 1392 width = property(getWidth, None, None, | |
| 1393 """Width measure | |
| 1394 """) | |
| 1395 height = property(getHeight, None, None, | |
| 1396 """Height measure | |
| 1397 """) | |
| 1398 formula = property(getFormula, None, None, | |
| 1399 """Formula | |
| 1400 """) | |
| 1401 parcial = property(getParcial, None, None, | |
| 1402 """result of measure line | |
| 1403 """) | |
| 1404 acumulated_subtotal = property(getAcumulatedSubtotal, | |
| 1405 None, None, | |
| 1406 """Acumulated subtotal | |
| 1407 """) | |
| 1408 parcial_subtotal = property(getParcialSubtotal, | |
| 1409 None, None, | |
| 1410 """Parcial subtotal | |
| 1411 """) | |
| 1412 def eval_formula(self): | |
| 1413 """eval_formula() | |
| 1414 | |
| 1415 formula: | |
| 1416 Valid Operator: '(', ')', '+', '-', '*', '/' and '^' | |
| 1417 Valid variable: 'a', 'b', 'c','d'y 'p' (Pi=3.1415926) | |
| 1418 units: Number of Units (a) | |
| 1419 length: Length (b) | |
| 1420 width: Width (c) | |
| 1421 height: Height (d) | |
| 1422 | |
| 1423 Evals the formula and return the result | |
| 1424 """ | |
| 1425 formula = self.formula | |
| 1426 a = self.units | |
| 1427 b = self.length | |
| 1428 c = self.width | |
| 1429 d = self.height | |
| 1430 if a == "": a = 0.0 | |
| 1431 if b == "": b = 0.0 | |
| 1432 if c == "": c = 0.0 | |
| 1433 if d == "": d = 0.0 | |
| 1434 try: | |
| 1435 a = float(a) | |
| 1436 except: | |
| 1437 raise ValueError, _("'a' value must be a float number") | |
| 1438 try: | |
| 1439 b = float(b) | |
| 1440 except: | |
| 1441 raise ValueError, _("'b' value must be a float number") | |
| 1442 try: | |
| 1443 c = float(c) | |
| 1444 except: | |
| 1445 raise ValueError, _("'c' value must be a float number") | |
| 1446 try: | |
| 1447 d = float(d) | |
| 1448 except: | |
| 1449 raise ValueError, _("'d' value must be a float number") | |
| 1450 # spaces are erased | |
| 1451 formula.replace(" ","") | |
| 1452 # operators and varibles are replaced | |
| 1453 formula = formula.replace("+", " + ") | |
| 1454 formula = formula.replace("-", " - ") | |
| 1455 formula = formula.replace("*", " * ") | |
| 1456 formula = formula.replace("/", " / ") | |
| 1457 formula = formula.replace("^", " ** ") | |
| 1458 formula = formula.replace("(", " ( ") | |
| 1459 formula = formula.replace(")", " ) ") | |
| 1460 formula = formula.replace("a", str(a)) | |
| 1461 formula = formula.replace("b", str(b)) | |
| 1462 formula = formula.replace("c", str(c)) | |
| 1463 formula = formula.replace("d", str(d)) | |
| 1464 formula = formula.replace("p", "3.1415926") | |
| 1465 _list_formula = formula.split(" ") | |
| 1466 _formula2 = "" | |
| 1467 for oper in _list_formula: | |
| 1468 try: | |
| 1469 _float_oper= str(float(oper)) | |
| 1470 _formula2 = _formula2 + _float_oper | |
| 1471 except ValueError: | |
| 1472 _formula2 = _formula2 + oper | |
| 1473 _g ={"__builtins__":{}} | |
| 1474 try: | |
| 1475 return eval(_formula2, _g) | |
| 1476 except: | |
| 1477 raise ValueError, _("Invalid formula") | |
| 1478 | |
| 1479 class Decimals(object): | |
| 1480 """base.Decimals: | |
| 1481 | |
| 1482 Description: | |
| 1483 Decimals object | |
| 1484 Constructor: | |
| 1485 base.Decimals(DN=2, DD=2, DSP=2, DS=2, | |
| 1486 DFC=3, DFPU=3, DFUO=3, DFA=3, | |
| 1487 DRP=3, DRC=3, DRUO=3, DRA=3, | |
| 1488 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2, | |
| 1489 DIR=2, DIM=2, DIRC=2, DIMC=2, DCD=2, | |
| 1490 DIVISA="EUR") | |
| 1491 Ancestry: | |
| 1492 +-- object | |
| 1493 +-- Decimals | |
| 1494 Atributes: | |
| 1495 "DN": Number of decimal places of the field "equal-size parts" in the | |
| 1496 measure lines. | |
| 1497 Default: 2 decimal places. | |
| 1498 "DD": Number of decimal places of the three dimensions in the | |
| 1499 measure lines. | |
| 1500 Default: 2 decimal places. | |
| 1501 "DSP": Number of decimal places of the subtotal of a measure. | |
| 1502 Default: 2 decimal places. | |
| 1503 "DS": Number of decimal places of the total sum of a measure. | |
| 1504 Default: 2 decimal places. | |
| 1505 "DFC": Number of decimal places of the yield factor in a decomposition | |
| 1506 of a chapter or subchapter. | |
| 1507 Dafault: 3 decimal places. | |
| 1508 "DFPU": Number of decimal places of the yield factor in a decomposition | |
| 1509 of a unitary budget. | |
| 1510 Default: 3 decimal places. | |
| 1511 "DFUO": Number of decimal places of the yield factor in a decomposition | |
| 1512 of a unit of work. | |
| 1513 Default: 3 decimal places. | |
| 1514 "DFA": Number of decimal places of the yield factor in a decomposition | |
| 1515 of a Auxiliary element. | |
| 1516 Default: 3 decimal places. | |
| 1517 "DRC": Number of decimal places of the yield in a | |
| 1518 decomposition of a chapter or subchapter. | |
| 1519 Number of decimal places of the result of the multiplictaion of | |
| 1520 the yield (or measure) and the factor in a decomposition of a | |
| 1521 chapter or subcharter. | |
| 1522 Default: 3 decimal places. | |
| 1523 "DRPU": Number of decimal places of the yield in a decomposition | |
| 1524 of a unitary budget record. | |
| 1525 Number of decumal places of the result of the multiplication of | |
| 1526 the factor and the yield in a decompositon of a untitary budget. | |
| 1527 Default: 3 decimal places. | |
| 1528 "DRUO": Number of decimal places of the yield in a decomposition of a | |
| 1529 unit of work. | |
| 1530 Decimal places of the result of the multiplication of the yield | |
| 1531 and the factor in a descomposition of a unit of work. | |
| 1532 Default: 3 decimal places. | |
| 1533 "DRA": Number of decimal places of the yield in a decompositon of a | |
| 1534 auxiliar element. | |
| 1535 Number of decimal places of the result of the multiplication of | |
| 1536 the yield and the factor in a descomposition of a auxilar element.Decimales | |
| 1537 Default: 3 decimal places. | |
| 1538 "DP": Number of decimal places of the price of a budget. | |
| 1539 Default: 2 decimal places. | |
| 1540 "DC": Number of decimal places of the price of a chapter or subchapter. | |
| 1541 Default: 2 decimal places. | |
| 1542 "DPU": Number of decimal places of the price of a unitary budget. | |
| 1543 Default: 2 decimal places. | |
| 1544 "DUO": Number of decimal places of the price of a unit of work. | |
| 1545 Default: 2 decimal places. | |
| 1546 "DEA": Number of decimal places of the price of a auxiliar element. | |
| 1547 Default: 2 decimal places. | |
| 1548 "DES": Number of decimal places of the price of the simple elements. | |
| 1549 Default: 2 decimal places. | |
| 1550 "DIR": Number of decimal places of the resulting amount to multiply | |
| 1551 the total yield and the price of the elements of a unit of work or | |
| 1552 a auxiliar element. | |
| 1553 "DIRC": Number of decimal places of the resulting amount to multiply | |
| 1554 the total yield and the price of the elements of a budget, chapter | |
| 1555 or a subchapter. | |
| 1556 "DCD": Number of decimal places ot the resulting amount to sum the | |
| 1557 direct costs of a unit of work (and auxiliar element). | |
| 1558 Number of decimal places of the indirect costs. | |
| 1559 Default: 2 decimal places. | |
| 1560 "DIVISA": monetary unit. | |
| 1561 Methods: | |
| 1562 __init__(DN=2, DD=2, DSP=2, DS=2, | |
| 1563 DFC=3, DFPU=3, DFUO=3, DFA=3, | |
| 1564 DRC=3, DRPU=3, DRUO=3, DRA=3, | |
| 1565 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2, | |
| 1566 DIR=2, DIRC=2, DCD=2, | |
| 1567 DIVISA="EUR") | |
| 1568 __getitem__(key) | |
| 1569 haskey(key) | |
| 1570 getD(recordtype) | |
| 1571 getDF(recordType) | |
| 1572 getDR(recordType) | |
| 1573 getDI(recordType) | |
| 1574 """ | |
| 1575 # TODO: get/set methods | |
| 1576 def __init__(self, | |
| 1577 DN=2, DD=2, DSP=2, DS=2, | |
| 1578 DFC=3, DFPU=3, DFUO=3, DFA=3, | |
| 1579 DRC=3, DRPU=3, DRUO=3, DRA=3, | |
| 1580 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2, | |
| 1581 DIR=2, DIRC=2, DCD=2, | |
| 1582 DIVISA="EUR" ): | |
| 1583 self.DN = DN | |
| 1584 self.DD = DD | |
| 1585 self.DSP = DSP | |
| 1586 self.DS = DS | |
| 1587 self.DFP = 3 | |
| 1588 self.DFC = DFC | |
| 1589 self.DFPU = DFPU | |
| 1590 self.DFUO = DFUO | |
| 1591 self.DFA = DFA | |
| 1592 self.DRP = 3 | |
| 1593 self.DRC = DRC | |
| 1594 self.DRPU = DRPU | |
| 1595 self.DRUO = DRUO | |
| 1596 self.DRA = DRA | |
| 1597 self.DP = DP | |
| 1598 self.DC = DC | |
| 1599 self.DPU = DPU | |
| 1600 self.DUO = DUO | |
| 1601 self.DEA = DEA | |
| 1602 self.DES = DES | |
| 1603 self.DIR = DIR | |
| 1604 self.DIRC = DIRC | |
| 1605 self.DCD = DCD | |
| 1606 self.DIVISA = DIVISA | |
| 1607 def __getitem__(self, key): | |
| 1608 return self.__dict__[key] | |
| 1609 def haskey(self, key): | |
| 1610 return key in self.__dict__ | |
| 1611 def getD(self, recordType): | |
| 1612 # DP: budget. | |
| 1613 # DC: chapter and subcharter. | |
| 1614 # DUO: unit. | |
| 1615 # DEA: auxiliar element. | |
| 1616 # DES: simple element. | |
| 1617 _hierarchy = recordType.hierarchy | |
| 1618 if _hierarchy == 0: #budget, type 0, subtipe "OB" | |
| 1619 _decimal = self.DP | |
| 1620 elif _hierarchy == 1: #chapter/subcharter, type 0, subtipe "" | |
| 1621 _decimal = self.DC | |
| 1622 else: # other | |
| 1623 _type = recordType.type | |
| 1624 _subtype = recordType.subtype | |
| 1625 if _subtype == "EA": # auxiliar element type 0 subitype "EA" | |
| 1626 _decimal = self.DEA | |
| 1627 if _subtype == "PU": # unitary budget type 0 subitype "PU" | |
| 1628 _decimal = self.DPU | |
| 1629 elif (_type in [1, 2, 3] or | |
| 1630 _subtype in ["H", "Q", "%", "MC", "MCr", "MM", "MS", "ME", | |
| 1631 "MCu", "Mal","ML", "M"] | |
| 1632 ): # simple element | |
| 1633 _decimal = self.DES | |
| 1634 else: # unit type 0, subtipe ["EU", "EC", "EF", "PA"] | |
| 1635 _decimal = self.DUO | |
| 1636 return _decimal | |
| 1637 def getDF(self, recordType): | |
| 1638 # Factor: DF | |
| 1639 # ->DFP: Budget | |
| 1640 # ->DFC: Chapter/Subchapter | |
| 1641 # ->DFUO: Unit | |
| 1642 # ->DFA: Auxiliar | |
| 1643 # ->DFPU: Unitary budget | |
| 1644 if recordType.hierarchy == 0: #budget | |
| 1645 _decimal = self.DFP | |
| 1646 elif recordType.hierarchy == 1: #chapter/subcharter | |
| 1647 _decimal = self.DFC | |
| 1648 else: # other | |
| 1649 if recordType.subtype == "EA": # auxiliar element | |
| 1650 _decimal = self.DFA | |
| 1651 if recordType.subtype == "PU": # unitary budget element | |
| 1652 _decimal = self.DFPU | |
| 1653 else: # unit EU EC EF PA | |
| 1654 _decimal = self.DFUO | |
| 1655 return _decimal | |
| 1656 def getDR(self, recordType): | |
| 1657 # Yield: DR | |
| 1658 # ->DRP: Budget | |
| 1659 # ->DRC: Chapter/Subchapter | |
| 1660 # ->DRUO: Unit | |
| 1661 # ->DRA: Auxiliar | |
| 1662 # ->DRPU: Unitary budget | |
| 1663 if recordType.hierarchy == 0: #budget | |
| 1664 _decimal = self.DRP | |
| 1665 elif recordType.hierarchy == 1: #chapter/subcharter | |
| 1666 _decimal = self.DRC | |
| 1667 else: # other | |
| 1668 if recordType.subtype == "EA": # auxiliar element | |
| 1669 _decimal = self.DRA | |
| 1670 if recordType.subtype == "PU": # unitary budget element | |
| 1671 _decimal = self.DRPU | |
| 1672 else: # unit | |
| 1673 _decimal = self.DRUO | |
| 1674 return _decimal | |
| 1675 def getDI(self, recordType): | |
| 1676 # DIRC: budget, chapter and subcharter. | |
| 1677 # DIR: unit, auxiliar element. | |
| 1678 _hierarchy = recordType.hierarchy | |
| 1679 _subtype = recordType.subtype | |
| 1680 if _hierarchy == 0 or _hierarchy == 1 or _subtype == "PU": | |
| 1681 #budget, type 0, subtipe "OB" | |
| 1682 #chapter/subcharter, type 0, subtipe "" | |
| 1683 #unitary budget, type 2, subtype "PU" | |
| 1684 _decimal = self.DIRC | |
| 1685 else: # other | |
| 1686 # auxiliar element type 0 subitype "EA" | |
| 1687 # unit type 0, subtipe ["EU", "EC", "EF", "PA", "PU"] | |
| 1688 _decimal = self.DIR | |
| 1689 return _decimal | |
| 1690 | |
| 1691 class Sheet(object): | |
| 1692 """base.Sheet: | |
| 1693 Description: | |
| 1694 Sheet of conditions object | |
| 1695 Constructor: | |
| 1696 base.Sheet(sheet_dict) | |
| 1697 Ancestry: | |
| 1698 +-- object | |
| 1699 +-- Sheet | |
| 1700 Atributes: | |
| 1701 "sheet_dict": { <Field key> : { <Section key> : <Paragraph key>} | |
| 1702 <Field key>: must be in Budget.SheetFields | |
| 1703 <Section key>: must be in Budget.SheetSections | |
| 1704 <Paragraph key>: must be in Budget.SheetParagraph | |
| 1705 Methods: | |
| 1706 __getstate__(self) | |
| 1707 __setstate__(self, tuple) | |
| 1708 __init__(self, sheet_dict={}) | |
| 1709 {get/set}Sheet_dict | |
| 1710 getFields | |
| 1711 getSections | |
| 1712 getParagraph | |
| 1713 addField | |
| 1714 addSection | |
| 1715 """ | |
| 1716 __slots__ = ["_Sheet__sheet_dict"] | |
| 1717 def __getstate__ (self): | |
| 1718 return (self.__sheet_dict,) | |
| 1719 def __setstate__(self,tuple): | |
| 1720 self.__sheet_dict = tuple[0] | |
| 1721 def __init__(self): | |
| 1722 self.__sheet_dict = {} | |
| 1723 def getSheet_dict(self): | |
| 1724 return self.__sheet_dict | |
| 1725 def setSheet_dict(self, sheet_dict): | |
| 1726 if not isinstance(sheet_dict, dict): | |
| 1727 raise ValueError, _("sheet_dict must be a dictionay") | |
| 1728 self.__sheet_dict = sheet_dict | |
| 1729 def getFields(self): | |
| 1730 return self.sheet_dict.keys() | |
| 1731 def getSections(self, field): | |
| 1732 if field in self.__sheet_dict: | |
| 1733 return self.__sheet_dict[field].keys() | |
| 1734 else: | |
| 1735 return None | |
| 1736 def getParagraph(self, field, section): | |
| 1737 if (field in self.__sheet_dict and | |
| 1738 section in self.__sheet_dict[field]): | |
| 1739 return self.__sheet_dict[field][section] | |
| 1740 else: | |
| 1741 return None | |
| 1742 def addField(self, field, section_dict): | |
| 1743 if not isinstance(field, str): | |
| 1744 raise ValueError, _("sheet field must be a string") | |
| 1745 if not isinstance(section_dict, dict): | |
| 1746 raise ValueError, _("section_dict must be a dictionary") | |
| 1747 self.__sheet_dict[field] = section_dict | |
| 1748 def addSection(self, field, section, paragraph): | |
| 1749 if not isinstance(field, str): | |
| 1750 raise ValueError, _("sheet field must be a string") | |
| 1751 if not isinstance(section, str): | |
| 1752 raise ValueError, _("sheet section must be a string") | |
| 1753 if not isinstance(paragraph, str): | |
| 1754 raise ValueError, _("sheet paragraph must be a string") | |
| 1755 if not field in self.__sheet_dict: | |
| 1756 self.addField(field, { }) | |
| 1757 _field = self.__sheet_dict[field] | |
| 1758 _field[section] = paragraph | |
| 1759 sheet_dict = property(getSheet_dict, setSheet_dict, None, | |
| 1760 """Sheet dictionary { <Field key> : { <Section key> : <Paragraph key>}""") | |
| 1761 | |
| 1762 class Budget(object): | |
| 1763 """base.Budget: | |
| 1764 | |
| 1765 Description: | |
| 1766 Budget objetc | |
| 1767 Constructor: | |
| 1768 base.Budget() | |
| 1769 Ancestry: | |
| 1770 +-- object | |
| 1771 +-- Budget | |
| 1772 Atributes: | |
| 1773 "filename": file name of the budget file (FIEBDC) | |
| 1774 "__records": Dictionary with the budget records. | |
| 1775 { "code" : Record object, } | |
| 1776 "__synonyms": Dictionary with the records synonums. | |
| 1777 { "code" : ["synonym",],} | |
| 1778 Each record code can have synonym codes. | |
| 1779 "__root": The root record code. | |
| 1780 "__title_list": List with the Headers and list of Titles for prices and | |
| 1781 decimal places. | |
| 1782 [ "Header", ["Title1", "Title2", ... ] ] | |
| 1783 The records can have diferent prices for diferent ages, geografical | |
| 1784 places, ... | |
| 1785 The Headers is the type of hierarchy of the prices | |
| 1786 Each Title have a group of Prices and a Decimals definition | |
| 1787 "__decimals": List with the decimal places used to round the | |
| 1788 result of the calculations with prices and measures | |
| 1789 The values are Decimals objects | |
| 1790 The <0> objets is the default Decimals (seted in FIEBDC-3), | |
| 1791 The others keys are for the diferent groups of Prices | |
| 1792 "__percentages": Dictionary with the percentages | |
| 1793 keys: | |
| 1794 "CI" Indirect Cost | |
| 1795 "GG" General expenses | |
| 1796 "BI" Industrial benefit | |
| 1797 "BAJA" Low (what this do here?) | |
| 1798 "IVA" Tax | |
| 1799 "__file_owner" | |
| 1800 "__comment" | |
| 1801 "__date" | |
| 1802 "__budgetType" A integer. Type of data in budget | |
| 1803 0 -> Undefined | |
| 1804 1 -> Base data. | |
| 1805 2 -> Budget. | |
| 1806 3 -> Certificate. | |
| 1807 4 -> Base date update. | |
| 1808 "__budgetCerficateOrder" Only valid if budgetType is 3. | |
| 1809 "__budgetCerficateDate" Only valid if budgetType is 3 | |
| 1810 "__title_index": A integer. The active group of Prices and Decimals. | |
| 1811 "__sheet_sections": Dictionary whith de sheet sections | |
| 1812 "__sheet_fields": Dictionary whith sheet fields | |
| 1813 "__sheet_paragraphs": Dictionary whith sheet paragraphs | |
| 1814 "__companys": Dictionary whith companys object | |
| 1815 { company_code: company_object } | |
| 1816 "__tec_info": Dictionary whith tecnical information | |
| 1817 {ti_code : ["desciption text", "unit"]} | |
| 1818 "__labels": Label dictionary { "label": [ "code", ], } | |
| 1819 Methods: | |
| 1820 iter | |
| 1821 iterPreOrder | |
| 1822 iterPostOrder | |
| 1823 getRoot(self) | |
| 1824 hasPath(self, path) | |
| 1825 getchildren(self, code) | |
| 1826 setOwner(self, owner) | |
| 1827 setDate(self, date) | |
| 1828 setComment(self, comment) | |
| 1829 setBudgetType(self, type) | |
| 1830 setCertificateOrder(self, order) | |
| 1831 setCertificateDate(self, date) | |
| 1832 setTitleList(self, title) | |
| 1833 getTitleList(self) | |
| 1834 getActiveTitle(self) | |
| 1835 setDecimals(self, dictionary) | |
| 1836 getDecimals(self, decimal="All", N=None) | |
| 1837 setPercentages(self, dictionary) | |
| 1838 getPercentages(self, percentage="All") | |
| 1839 getAllParents(self, code) | |
| 1840 getAllchildren(self, code) | |
| 1841 getNDecomposition(self, code, N) | |
| 1842 getDecomposition(self,code) | |
| 1843 getMeasure(self, path) | |
| 1844 getStrYield | |
| 1845 getStrFactor | |
| 1846 setTree(sef, code, child_code, position, factor, yield_, total, | |
| 1847 list_lines, label, type) | |
| 1848 eval_formula(self, formula, a, b, c, d) | |
| 1849 getText(self, code) | |
| 1850 setText(self, code, text) | |
| 1851 setRecord(self, code, synonyms, hierarchy, unit, sumary, ... | |
| 1852 hasRecord(self, code) | |
| 1853 getRecord | |
| 1854 addPriceToRecord | |
| 1855 getStrPriceFromRecord | |
| 1856 getCode(self, path) | |
| 1857 getAmount | |
| 1858 getStrAmount | |
| 1859 setSheetSection(self, sheet_code, sheet_title) | |
| 1860 hasSheetSection(self, section) | |
| 1861 setSheetSections(self,dictionary) | |
| 1862 setSheetField(self, field_code, field_title) | |
| 1863 hasSheetField(self, field) | |
| 1864 getSheetField(self, field) | |
| 1865 setSheetFields(self, field_dict) | |
| 1866 setSheetParagraph(self, paragraph_code, paragraph_text) | |
| 1867 hasSheetParagraph(self, paragraph) | |
| 1868 getSheetParagraph(self, paragraph) | |
| 1869 setSheetParagraphs(self, paragraph_dict) | |
| 1870 setSheetRecord(self, record_code,field, section_dict) | |
| 1871 addFile(self, record_code, filename) | |
| 1872 setCompany(self, code, summary, name, offices, cif, web, email ) | |
| 1873 getCompany | |
| 1874 getCompanyKeys | |
| 1875 addTecInfo(self, ti_code, text, unit) | |
| 1876 hasTecInfo(self, ti_code) | |
| 1877 getTecInfo(self, ti_code) | |
| 1878 setTecnicalInformation(self, _record_code, _ti_dict) | |
| 1879 changeCode(self, record_code, new_rocord_code) | |
| 1880 addLabel | |
| 1881 setParametricSelectComment | |
| 1882 setParametricSummary | |
| 1883 setParametricText | |
| 1884 """ | |
| 1885 | |
| 1886 | |
| 1887 def __init__(self): | |
| 1888 """__init__(self) | |
| 1889 | |
| 1890 Initialize the budget atributes | |
| 1891 """ | |
| 1892 self.__title_index = 0 | |
| 1893 self.__decimals = [Decimals(), Decimals()] | |
| 1894 self.__percentages = { "CI" : "" ,"GG": "", "BI": "", | |
| 1895 "BAJA": "", "IVA" : ""} | |
| 1896 self.__title_list = [ "", [ ] ] | |
| 1897 self.__root = None | |
| 1898 self.__file_owner = "" | |
| 1899 self.__comment = "" | |
| 1900 self.__budgetCerficateOrder = None | |
| 1901 self.__budgetCerficateDate = None | |
| 1902 self.__date = (0,0,0) | |
| 1903 self.__budgetType = 0 | |
| 1904 self.__records = { } | |
| 1905 self.__synonyms = { } | |
| 1906 self.__sheet_sections = { } | |
| 1907 self.__sheet_fields = { } | |
| 1908 self.__sheet_paragraphs = { } | |
| 1909 self.__companys = { } | |
| 1910 self.__tec_info = { } | |
| 1911 self.__labels = { } | |
| 1912 | |
| 1913 def __getstate__(self): | |
| 1914 return (self.__title_index, self.__decimals, self.__percentages, | |
| 1915 self.__title_list, self.__root, self.__file_owner, | |
| 1916 self.__records, self.__synonyms, self.__sheet_sections, | |
| 1917 self.__sheet_fields, self.__sheet_paragraphs,self.__companys, | |
| 1918 self.__tec_info, self.__labels) | |
| 1919 | |
| 1920 def __setstate__(self, tuple): | |
| 1921 self.__title_index = tuple[0] | |
| 1922 self.__decimals = tuple[1] | |
| 1923 self.__percentages = tuple[3] | |
| 1924 self.__title_list = tuple[4] | |
| 1925 self.__root = tuple[4] | |
| 1926 self.__file_owner = tuple[5] | |
| 1927 self.__records = tuple[6] | |
| 1928 self.__synonyms = tuple[7] | |
| 1929 self.__sheet_sections = tuple[8] | |
| 1930 self.__sheet_fields = tuple[9] | |
| 1931 self.__sheet_paragraphs = tuple[10] | |
| 1932 self.__companys = tuple[11] | |
| 1933 self.__tec_info = tuple[12] | |
| 1934 self.__labels = tuple[13] | |
| 1935 | |
| 1936 def iter(self): | |
| 1937 for record in self.__records: | |
| 1938 yield record | |
| 1939 def iterPreOrder(self, recordCode, codes=[]): | |
| 1940 _children = self.getchildren(recordCode) | |
| 1941 for _child in _children: | |
| 1942 if not _child in codes: | |
| 1943 codes.append(_child) | |
| 1944 self.iterPreOrder(_child, codes) | |
| 1945 return codes | |
| 1946 def iterPostOrder(self, recordCode, codes=[]): | |
| 1947 _children = self.getchildren(recordCode) | |
| 1948 for _child in _children: | |
| 1949 if not _child in codes: | |
| 1950 self.iterPreOrder(_child, codes) | |
| 1951 codes.append(_child) | |
| 1952 return codes | |
| 1953 | |
| 1954 def getRoot(self): | |
| 1955 """getRoot(self) | |
| 1956 | |
| 1957 Returns the root record code | |
| 1958 """ | |
| 1959 return self.__root | |
| 1960 | |
| 1961 def hasPath(self, path): | |
| 1962 """hasPath(self, path) | |
| 1963 | |
| 1964 path: The path of the record in the budget, It is a tuple. | |
| 1965 Tests if the path is valid in the budget | |
| 1966 """ | |
| 1967 try: | |
| 1968 self.getCode(path) | |
| 1969 return True | |
| 1970 except ValueError: | |
| 1971 return False | |
| 1972 | |
| 1973 def getchildren(self, code): | |
| 1974 """getchildren(self, code) | |
| 1975 | |
| 1976 code: a record code. | |
| 1977 Return a list whith the child codes of a record | |
| 1978 """ | |
| 1979 _record = self.__records[code] | |
| 1980 _children = _record.children | |
| 1981 _child_code = [ _child.code for _child in _children ] | |
| 1982 return _child_code | |
| 1983 def setOwner(self, owner): | |
| 1984 """setOwner(self, owner) | |
| 1985 | |
| 1986 owner: data owner | |
| 1987 Set the data owner. | |
| 1988 """ | |
| 1989 if isinstance(owner, basestring): | |
| 1990 self.__file_owner = owner | |
| 1991 else: | |
| 1992 raise TypeError, _("Owner must be a string") | |
| 1993 | |
| 1994 def setDate(self, date): | |
| 1995 """setOwner(self, date) | |
| 1996 | |
| 1997 date (_y, _m, _d) | |
| 1998 Set the date when de file was generated | |
| 1999 """ | |
| 2000 if isinstance(date, tuple) and len(date) == 3 and \ | |
| 2001 isinstance(date[0], int) and isinstance(date[1], int) and \ | |
| 2002 isinstance(date[2], int) and date[1] in range(13) and \ | |
| 2003 date[2] in range(32): | |
| 2004 if date[1] != 0 and date[2] != 0: | |
| 2005 datetime.date(*date) | |
| 2006 self.__date = date | |
| 2007 else: | |
| 2008 raise TypeError, _("Invalid Date: %s" % str(date)) | |
| 2009 | |
| 2010 def setComment(self, comment): | |
| 2011 """setOwner(self, comment) | |
| 2012 | |
| 2013 comment: text to comment the budged | |
| 2014 Set the comment. | |
| 2015 """ | |
| 2016 if isinstance(comment, basestring): | |
| 2017 self.__comment = comment | |
| 2018 else: | |
| 2019 raise TypeError, _("Comment must be a string") | |
| 2020 | |
| 2021 def setBudgeType(self, budget_type): | |
| 2022 """setOwner(self, budget_type) | |
| 2023 | |
| 2024 budget_type: type of data in budget | |
| 2025 0 -> Undefined | |
| 2026 1 -> Base data. | |
| 2027 2 -> Budget. | |
| 2028 3 -> Budget certificate. | |
| 2029 4 -> Base date update. | |
| 2030 Set the budget type. | |
| 2031 """ | |
| 2032 if budget_type in [1, 2, 3, 4]: | |
| 2033 self.__budgetType = budget_type | |
| 2034 else: | |
| 2035 raise ValueError, _("Budget type must be 1, 2, 3 or 4.") | |
| 2036 | |
| 2037 def setCertificateOrder(self, certificate_order, certificate_date): | |
| 2038 """setOwner(self, budget_type) | |
| 2039 | |
| 2040 certificate_order: certificate number | |
| 2041 certificate_date: certificate date | |
| 2042 Set the certificate order and date. | |
| 2043 """ | |
| 2044 if isinstance(certificate_order, int): | |
| 2045 self.__budgetCerficateOrder = certificate_order | |
| 2046 else: | |
| 2047 raise ValueError, _("Certificate order must be a integer.") | |
| 2048 | |
| 2049 def setCertificateDater(self, certificate_date): | |
| 2050 """setCertidicateDate(self, certificate_date) | |
| 2051 | |
| 2052 Set the certificate date. | |
| 2053 """ | |
| 2054 if isinstance(certificate_date, tuple) and \ | |
| 2055 len(certificate_date) == 3 and \ | |
| 2056 isinstance(certificate_date[0], int) and \ | |
| 2057 isinstance(certificate_date[1], int) and \ | |
| 2058 isinstance(certificate_date[2], int): | |
| 2059 datetime.date(*certificate_date) | |
| 2060 self.__budgetCerficateDate = certificate_date | |
| 2061 else: | |
| 2062 raise ValueError, _("Budget certificate Date must be a valid Date.") | |
| 2063 | |
| 2064 def setTitleList(self, title_list): | |
| 2065 """setTitleList(self, title_list) | |
| 2066 | |
| 2067 title_list: [ "Header", ["Title1", "Title2", ... ] ] | |
| 2068 Set the header and titles for the price groups and decimals. | |
| 2069 """ | |
| 2070 title_list[0] = str(title_list[0]) | |
| 2071 if isinstance(title_list, list) and isinstance(title_list[1], list): | |
| 2072 for i in range(len(title_list[1])): | |
| 2073 title_list[1][i] = str(title_list[1][i]) | |
| 2074 self.__title_list = title_list | |
| 2075 else: | |
| 2076 raise TypeError, _("Invalid title list format") | |
| 2077 | |
| 2078 def getTitleList(self): | |
| 2079 """ getTitleList(self) | |
| 2080 | |
| 2081 Returns the header and titles for the price groups and decimals. | |
| 2082 """ | |
| 2083 return self.__title_list | |
| 2084 | |
| 2085 def getActiveTitle(self): | |
| 2086 """getActiveTitle(self) | |
| 2087 | |
| 2088 Returns the active Title of price group | |
| 2089 """ | |
| 2090 return self.__title_index | |
| 2091 | |
| 2092 def setDecimals(self, dictionary, N): | |
| 2093 """setDecimals(self, dictionary, N) | |
| 2094 | |
| 2095 dictionay: the decimal dictionary | |
| 2096 N: the price group | |
| 2097 Sets the Decimals for a price group. | |
| 2098 """ | |
| 2099 if N == -1 or N == len(self.__decimals): | |
| 2100 _default_decimals = self.__decimals[0] | |
| 2101 self.__decimals.append(_default_decimals) | |
| 2102 elif N < len(self.__decimals): | |
| 2103 _default_decimals = self.__decimals[N] | |
| 2104 else: | |
| 2105 raise IndexError, _("Invalid Index Title") | |
| 2106 for _decimal in dictionary: | |
| 2107 if dictionary[_decimal] == "": | |
| 2108 dictionary[_decimal] = eval("_default_decimals." + _decimal) | |
| 2109 decimals = Decimals(dictionary["DN"], dictionary["DD"], | |
| 2110 dictionary["DSP"], dictionary["DS"], | |
| 2111 dictionary["DFC"], | |
| 2112 dictionary["DFPU"], dictionary["DFUO"], | |
| 2113 dictionary["DFA"], dictionary["DRC"], | |
| 2114 dictionary["DRPU"], dictionary["DRUO"], | |
| 2115 dictionary["DRA"], dictionary["DP"], | |
| 2116 dictionary["DC"], dictionary["DPU"], | |
| 2117 dictionary["DUO"], dictionary["DEA"], | |
| 2118 dictionary["DES"], dictionary["DIR"], | |
| 2119 dictionary["DIRC"], dictionary["DCD"], | |
| 2120 dictionary["DIVISA"]) | |
| 2121 self.__decimals[N] = decimals | |
| 2122 def getDecimals(self, decimal="All", N=None): | |
| 2123 """getDecimals(self,decimal="All",N=None) | |
| 2124 | |
| 2125 decimal: | |
| 2126 "All": Return a Decimals objet for a price group | |
| 2127 "keys": Return the keys of a Decimal object | |
| 2128 key: Return a Decimal value for a price group | |
| 2129 N: the price group None,1,2,.. | |
| 2130 None: Return the active price group | |
| 2131 """ | |
| 2132 if N is None: N = self.getActiveTitle() | |
| 2133 if decimal == "All": | |
| 2134 return self.__decimals[N+1] | |
| 2135 elif decimal == "keys": | |
| 2136 return self.__decimals[N+1].keys | |
| 2137 elif self.__decimals[N+1].haskey(decimal): | |
| 2138 return self.__decimals[N+1][decimal] | |
| 2139 else: | |
| 2140 raise KeyError, _("Decimal Key error") | |
| 2141 | |
| 2142 def setPercentages(self, dictionary): | |
| 2143 """setPercentages(self, dictionary): | |
| 2144 | |
| 2145 dictionary: the percentage dictionary | |
| 2146 Sets the percentage dictionary. | |
| 2147 """ | |
| 2148 _default_percentages = self.__percentages | |
| 2149 for percentage in dictionary: | |
| 2150 if dictionary[percentage] == 0: | |
| 2151 dictionary[percentage] = "" | |
| 2152 elif dictionary[percentage] == "": | |
| 2153 dictionary[percentage] = _default_percentages[percentage] | |
| 2154 _percentages = { "CI": dictionary["CI"], | |
| 2155 "GG": dictionary["GG"], | |
| 2156 "BI": dictionary["BI"], | |
| 2157 "BAJA": dictionary["BAJA"], | |
| 2158 "IVA" : dictionary["IVA"]} | |
| 2159 self.__percentages = _percentages | |
| 2160 | |
| 2161 def getPercentages(self, key="All"): | |
| 2162 """getPercentages(self, percentage="All") | |
| 2163 | |
| 2164 key: | |
| 2165 "All": Return the Percentages dictionary | |
| 2166 "keys": Return the keys of a Percentages object | |
| 2167 key: Return a Percentages value for the key | |
| 2168 """ | |
| 2169 if key == "All": | |
| 2170 return self.__percentages | |
| 2171 elif key == "keys": | |
| 2172 return self.__percentages.keys | |
| 2173 elif key in self.__percentages: | |
| 2174 return self.__percentages[key] | |
| 2175 else: | |
| 2176 raise KeyError, _("Invalid Percentage key") | |
| 2177 | |
| 2178 def getAllParents(self,code): | |
| 2179 """getAllParents(self,code) | |
| 2180 | |
| 2181 code: a record code. | |
| 2182 Returns a list with all the parents of a record | |
| 2183 All record which the record is in its descomposition list, | |
| 2184 including the parents of the parents | |
| 2185 """ | |
| 2186 if code in self.__records: | |
| 2187 _parents = self.__records[code].parents | |
| 2188 if len(_parents) == 0: return [ ] | |
| 2189 for _antecesor in _parents[:]: | |
| 2190 _parents = _parents + self.getAllParents(_antecesor) | |
| 2191 return _parents | |
| 2192 else: | |
| 2193 return [ ] | |
| 2194 | |
| 2195 def getAllchildren(self,code): | |
| 2196 """getAllchildren(self,code | |
| 2197 | |
| 2198 code: a record code. | |
| 2199 Returns a list with all the children of a record, including | |
| 2200 the children of the children | |
| 2201 """ | |
| 2202 if code in self.__records: | |
| 2203 _children = self.__records[code].children | |
| 2204 _children = [ _child.code for _child in _children ] | |
| 2205 for _child in _children[:]: | |
| 2206 _children = _children + self.getAllchildren(_child) | |
| 2207 return _children | |
| 2208 else: | |
| 2209 return [ ] | |
| 2210 | |
| 2211 def getNDecomposition(self, code, N): | |
| 2212 """getDecomposition(self,path) | |
| 2213 | |
| 2214 path: the path for a record | |
| 2215 Returns the Decomposition object of a record | |
| 2216 """ | |
| 2217 _record = self.getRecord(code) | |
| 2218 _decomposition_list = _record.children | |
| 2219 _decomposition = _decomposition_list[N] | |
| 2220 return _decomposition | |
| 2221 | |
| 2222 def getDecomposition(self, path): | |
| 2223 """getDecomposition(self,path) | |
| 2224 | |
| 2225 path: the path for a record | |
| 2226 Returns the Decomposition object of a record | |
| 2227 """ | |
| 2228 if path == (0,): | |
| 2229 _type = self.getRecord(self.__root).recordType | |
| 2230 return Decomposition( 0, self.__root, | |
| 2231 [Measure(self.getDecimals(), _type, | |
| 2232 0.0, [], "", 1.0, 1.0)]) | |
| 2233 else: | |
| 2234 return self.getNDecomposition(self.getCode(path[:-1]), path[-1]) | |
| 2235 | |
| 2236 def getMeasure(self, path): | |
| 2237 """getMeasure(self, path) | |
| 2238 | |
| 2239 path: the path for a record | |
| 2240 Return the measute object of a record | |
| 2241 """ | |
| 2242 _decomposition = self.getDecomposition(path) | |
| 2243 _measure = _decomposition.budgetMeasures[0] | |
| 2244 return _measure | |
| 2245 | |
| 2246 def getStrYield(self, measure, recordType): | |
| 2247 #_DR = measure.getDR(self.getDecimals()) | |
| 2248 _DR = self.getDecimals().getDR(recordType) | |
| 2249 _yield = ("%." + str(_DR) + "f" ) % measure.yield_ | |
| 2250 return _yield | |
| 2251 | |
| 2252 def getStrFactor(self, measure, recorType): | |
| 2253 _DF = self.getDecimals().getDF(recordType) | |
| 2254 #_DF = measure.getDF(self.getDecimals()) | |
| 2255 _factor = ("%." + str(_DF) + "f" ) % measure.factor | |
| 2256 return _factor | |
| 2257 | |
| 2258 def setTree(self, code, child_code, position, factor, yield_, total, | |
| 2259 list_lines, label, type): | |
| 2260 """setTree(self, code, child_code, position, factor,yield_, total, | |
| 2261 list_lines, label, type) | |
| 2262 | |
| 2263 code: the parent record code | |
| 2264 child_code: child record code | |
| 2265 position: position of child record in record parent record | |
| 2266 decomposition. Position == -1 -> new child | |
| 2267 factor: | |
| 2268 yield_: | |
| 2269 total: total measure (float) | |
| 2270 list_lines: list of measure lines | |
| 2271 [ [linetype, comment, units, length, width, height], ... ] | |
| 2272 linetype: | |
| 2273 empty string -> Normal | |
| 2274 1 -> Parcial Subtotal | |
| 2275 2 -> Accumulated Subtotal | |
| 2276 3 -> Formula, the comment is a formula. | |
| 2277 comment: Can be a descriptive text or a formula | |
| 2278 Valid Operator: '(', ')', '+', '-', '*', '/' and '^' | |
| 2279 Valid variable: 'a', 'b', 'c','d'y 'p' (Pi=3.1415926) | |
| 2280 units: Number of Units (a) | |
| 2281 length: Length (b) | |
| 2282 width: Width (c) | |
| 2283 height: Height (d) | |
| 2284 label: Record Identifiers that are used by some measure programs. | |
| 2285 type: type of action | |
| 2286 M: Set measure | |
| 2287 A: Add measure | |
| 2288 Sets the decomposition of a record in a child record | |
| 2289 """ | |
| 2290 if not utils.is_valid_code(code)[0]: | |
| 2291 raise ValueError, utils.mapping(_("Invalid parent code: $1"), | |
| 2292 (code,)) | |
| 2293 if not utils.is_valid_code(child_code)[0]: | |
| 2294 raise ValueError, utils.mapping(_("Invalid child code: $1"), | |
| 2295 (code,)) | |
| 2296 if not isinstance(position, int): | |
| 2297 raise ValueError, utils.mapping(_("Invalid position in measure "\ | |
| 2298 "$1, in code $2"), (parent_code, position)) | |
| 2299 # Test circular references | |
| 2300 _all_parent_list = self.getAllParents(code) + [ code ] | |
| 2301 _all_child_list = self.getAllchildren(child_code) + [ child_code ] | |
| 2302 for _parent_code in _all_parent_list: | |
| 2303 if _parent_code in _all_child_list: | |
| 2304 # TODO: change return to except | |
| 2305 print utils.mapping(_("Circular Decomposition, parent code: "\ | |
| 2306 "$1, child code: $2, repeated code: $3"), | |
| 2307 (code, child_code, _parent_code)) | |
| 2308 return | |
| 2309 # Creating reference to parent code in child record | |
| 2310 if child_code in self.__records: | |
| 2311 _child_record = self.__records[child_code] | |
| 2312 else: | |
| 2313 _child_record = self.setRecord(child_code, [], -1, "", "", [], [], | |
| 2314 "", "") | |
| 2315 if code in self.__records: | |
| 2316 code = self.__records[code].code | |
| 2317 _child_record.appendParent(code) | |
| 2318 child_code = self.__records[child_code].code | |
| 2319 if code in self.__records: | |
| 2320 # if the code exits retake previous values. | |
| 2321 _record = self.__records[code] | |
| 2322 _child_number = len(_record.children) | |
| 2323 if position == -1: | |
| 2324 position = _child_number | |
| 2325 if position == _child_number: | |
| 2326 # The record do not have the child | |
| 2327 if not isinstance(factor, float): factor = 1.0 | |
| 2328 if not isinstance(yield_, float): yield_ = 1.0 | |
| 2329 if not isinstance(total, float): total = 0.0 | |
| 2330 if not isinstance(list_lines, list): list_lines = [] | |
| 2331 _child = _record.appendChild(child_code, self.getDecimals(), | |
| 2332 factor, yield_, total, list_lines, type, label) | |
| 2333 elif position < _child_number: | |
| 2334 # The record have the child | |
| 2335 _child = _record.children[position] | |
| 2336 if child_code != "" and child_code != _child.code: | |
| 2337 _child.code = child_code | |
| 2338 if factor != "" : | |
| 2339 if not isinstance(factor, float): | |
| 2340 factor == 1.0 | |
| 2341 _child.budgetMeasures[0].setFactor(factor, | |
| 2342 self.getDecimals(), _record.recordType) | |
| 2343 if yield_ != "": | |
| 2344 if not isinstance(yield_, float): | |
| 2345 yield_ = 1.0 | |
| 2346 _child.budgetMeasures[0].setYield(yield_, | |
| 2347 self.getDecimals(), _record.recordType) | |
| 2348 _measure = _child.budgetMeasures[0] | |
| 2349 if total != "": | |
| 2350 if not isinstance(total, float): | |
| 2351 yield_ = 0.0 | |
| 2352 _measure.setMeasure(total, self.getDecimals()) | |
| 2353 if isinstance(list_lines, list) and len(list_lines) > 0: | |
| 2354 _measure.buildMeasure(list_lines, type, self.getDecimals(), | |
| 2355 _record.recordType) | |
| 2356 if isinstance(label, str) and label != "" : | |
| 2357 _measure.label = label | |
| 2358 else: | |
| 2359 # TODO: change return for except | |
| 2360 print utils.mapping(_("Error: Invalid child position in " | |
| 2361 "decomposition. Parent code: $1 Child code: $2 "\ | |
| 2362 "Position: $3"), (code, child_code, position)) | |
| 2363 return | |
| 2364 else: | |
| 2365 if child_code == "" : | |
| 2366 print utils.mapping(_("Error: Empty child code. Parent code: "\ | |
| 2367 "$1 Position: $2"), (code, position)) | |
| 2368 return | |
| 2369 if position == -1: | |
| 2370 position = 0 | |
| 2371 elif position != 0: | |
| 2372 print utils.mapping(_("Error: Invalid child position in "\ | |
| 2373 "decomposition. Parent code: $1 Child code: $2 "\ | |
| 2374 "Position: $3"), (code, child_code, position)) | |
| 2375 return | |
| 2376 if not isinstance(factor, float): | |
| 2377 factor == 1.0 | |
| 2378 if not isinstance(yield_, float): | |
| 2379 yield_ = 1.0 | |
| 2380 _record = self.setRecord(code, [], "", "", "", [], [], | |
| 2381 "", "") | |
| 2382 _child = _record.appendChild(child_code, self.getDecimals(), | |
| 2383 factor, yield_, total, list_lines, type, label) | |
| 2384 _child.budgetMeasures[0] = measure | |
| 2385 | |
| 2386 def eval_formula(self, formula, a, b, c, d): | |
| 2387 """eval_formula(self, formula, a, b, c, d) | |
| 2388 | |
| 2389 formula: | |
| 2390 Valid Operator: '(', ')', '+', '-', '*', '/' and '^' | |
| 2391 Valid variable: 'a', 'b', 'c','d'y 'p' (Pi=3.1415926) | |
| 2392 units: Number of Units (a) | |
| 2393 length: Length (b) | |
| 2394 width: Width (c) | |
| 2395 height: Height (d) | |
| 2396 | |
| 2397 Evals the formula and return the result | |
| 2398 """ | |
| 2399 if a == "": a = 0.0 | |
| 2400 if b == "": b = 0.0 | |
| 2401 if c == "": c = 0.0 | |
| 2402 if d == "": d = 0.0 | |
| 2403 try: | |
| 2404 a = float(a) | |
| 2405 except: | |
| 2406 raise ValueError, _("'a' value must be a float number") | |
| 2407 try: | |
| 2408 b = float(b) | |
| 2409 except: | |
| 2410 raise ValueError, _("'b' value must be a float number") | |
| 2411 try: | |
| 2412 c = float(c) | |
| 2413 except: | |
| 2414 raise ValueError, _("'c' value must be a float number") | |
| 2415 try: | |
| 2416 d = float(d) | |
| 2417 except: | |
| 2418 raise ValueError, _("'d' value must be a float number") | |
| 2419 # spaces are erased | |
| 2420 sre.sub("[ ]","",formula) | |
| 2421 # operators and varibles are replaced | |
| 2422 formula = formula.replace("+", " + ") | |
| 2423 formula = formula.replace("-", " - ") | |
| 2424 formula = formula.replace("*", " * ") | |
| 2425 formula = formula.replace("/", " / ") | |
| 2426 formula = formula.replace("^", " ** ") | |
| 2427 formula = formula.replace("(", " ( ") | |
| 2428 formula = formula.replace(")", " ) ") | |
| 2429 formula = formula.replace("a", str(a)) | |
| 2430 formula = formula.replace("b", str(b)) | |
| 2431 formula = formula.replace("c", str(c)) | |
| 2432 formula = formula.replace("d", str(d)) | |
| 2433 formula = formula.replace("p", "3.1415926") | |
| 2434 _list_formula = formula.split(" ") | |
| 2435 _formula2 = "" | |
| 2436 for oper in _list_formula: | |
| 2437 try: | |
| 2438 _float_oper= str(float(oper)) | |
| 2439 _formula2 = _formula2 + _float_oper | |
| 2440 except ValueError: | |
| 2441 _formula2 = _formula2 + oper | |
| 2442 _g = {"__builtins__":{}} | |
| 2443 try: | |
| 2444 return eval(_formula2, _g) | |
| 2445 except: | |
| 2446 raise ValueError, _("Invalid formula") | |
| 2447 | |
| 2448 def getText(self,code): | |
| 2449 """getText(self,code) | |
| 2450 | |
| 2451 code: the record code | |
| 2452 Returns the description text of a record | |
| 2453 """ | |
| 2454 if code in self.__records: | |
| 2455 return self.__records[code].text | |
| 2456 else: | |
| 2457 raise IndexError, _("Invalid code") | |
| 2458 | |
| 2459 def setText(self,code,text): | |
| 2460 """setText(self,code,text) | |
| 2461 | |
| 2462 code: the parent record code | |
| 2463 text: the descripion text | |
| 2464 Sests the description text of a record | |
| 2465 """ | |
| 2466 if not utils.is_valid_code(code)[0]: | |
| 2467 raise ValueError, utils.mapping(_("Invalid record: $1"), (code,)) | |
| 2468 if not code in self.__records: | |
| 2469 _record = self.setRecord(code, [], "", "", "", [], [], | |
| 2470 "", "") | |
| 2471 _record.text = text | |
| 2472 else: | |
| 2473 _record = self.__records[code] | |
| 2474 _record.text = text | |
| 2475 | |
| 2476 def setRecord(self, code, synonyms, hierarchy, unit, summary, price, date, | |
| 2477 type, subtype): | |
| 2478 """setRecord(self, code, synonyms, hierarchy, unit, summary, price, | |
| 2479 date, type, subtype) | |
| 2480 | |
| 2481 code: Code string | |
| 2482 synonyms: List of synonym codes of the record | |
| 2483 hierarchy: | |
| 2484 0 -> root | |
| 2485 1 -> Chapter/Subchapter | |
| 2486 2 -> Other | |
| 2487 unit: unit of measure record | |
| 2488 summary: Short description of a record | |
| 2489 price: List of prices | |
| 2490 date: List of dates | |
| 2491 "type" and "subtype": | |
| 2492 0 Without classifying | |
| 2493 EA Auxiliary element | |
| 2494 EU Unitary element | |
| 2495 EC Complex element | |
| 2496 EF Functional element | |
| 2497 OB Construction site | |
| 2498 PA Cost overrun | |
| 2499 PU Unitary budget | |
| 2500 1 Labourforce | |
| 2501 H Labourforce | |
| 2502 2 Machinery and auxiliary equipment | |
| 2503 Q Machinery | |
| 2504 % Auxiliary equipment | |
| 2505 3 Building materials | |
| 2506 MC Cement | |
| 2507 MCr Ceramic | |
| 2508 MM Wood | |
| 2509 MS Iron and steel | |
| 2510 ME Energy | |
| 2511 MCu Copper | |
| 2512 MAl Aluminium | |
| 2513 ML Bonding agents | |
| 2514 M Others materials | |
| 2515 Hierarchy type subtype | |
| 2516 0->root -> 0 -> None,OB | |
| 2517 1->[sub]chapter -> 0 -> None,PU | |
| 2518 2->Other -> 0 -> None,EA,EU,EC,EF,PA | |
| 2519 1 -> None,H | |
| 2520 2 -> None,Q,% | |
| 2521 3 -> None,MC,MCr,MM,MS,ME,MCu,Mal,ML,M | |
| 2522 Adds a record in the budget | |
| 2523 """ | |
| 2524 # hierarchy | |
| 2525 if hierarchy == 0 : | |
| 2526 # is the root record | |
| 2527 if self.__root is None: | |
| 2528 self.__root = code | |
| 2529 else: | |
| 2530 print _("Only can be one root record") | |
| 2531 return | |
| 2532 # retake previous values. | |
| 2533 # TODO: test synonyms | |
| 2534 _budget = self | |
| 2535 if not code in self.__records: | |
| 2536 if code[-1] == "$": | |
| 2537 _record = ParametricRecord(_budget.getDecimals(), code, | |
| 2538 synonyms, hierarchy, | |
| 2539 unit, summary, [], type, subtype, | |
| 2540 [], "") | |
| 2541 else: | |
| 2542 _record = Record(_budget.getDecimals(), code, synonyms, | |
| 2543 hierarchy, unit, | |
| 2544 summary, [], type, subtype,[], "") | |
| 2545 self.__records[code] = _record | |
| 2546 _prices = [[price[i], date[i]] for i in range(len(price))] | |
| 2547 _record.setPrices(_prices, self.getDecimals()) | |
| 2548 else: | |
| 2549 _record = self.__records[code] | |
| 2550 code = _record.code | |
| 2551 if len(synonyms) != 0 and synonyms[0] == "": | |
| 2552 synonyms = _record.synonyms | |
| 2553 if unit == "": | |
| 2554 unit = _record.unit | |
| 2555 if summary == "": | |
| 2556 summary = _record.summary | |
| 2557 #TODO: test empty price list | |
| 2558 if len(price) == 0 or price[0] == "": | |
| 2559 _prices = _record.prices | |
| 2560 else: | |
| 2561 _prices = [ [price[i], date[i]] for i in range(len(price))] | |
| 2562 if type == "": | |
| 2563 type = _record.recordType.type | |
| 2564 _record.synonyms = synonyms | |
| 2565 _record.unit = unit | |
| 2566 _record.summary = summary | |
| 2567 _record.setPrices(_prices, self.getDecimals()) | |
| 2568 _record.recordType.hierarchy = hierarchy | |
| 2569 _record.recordType.type = type | |
| 2570 _record.recordType.subtype = subtype | |
| 2571 return _record | |
| 2572 | |
| 2573 def hasRecord(self,code): | |
| 2574 """hasRecord(self,code) | |
| 2575 | |
| 2576 code: Code record | |
| 2577 Return True if the budget have this record code. | |
| 2578 """ | |
| 2579 if code in self.__records: | |
| 2580 return True | |
| 2581 else: | |
| 2582 return False | |
| 2583 | |
| 2584 def getRecord(self, code): | |
| 2585 """getRecord(self, code) | |
| 2586 | |
| 2587 code: Code record | |
| 2588 Return the Record object | |
| 2589 """ | |
| 2590 return self.__records[code] | |
| 2591 | |
| 2592 def addPriceToRecord(self, price_date, record): | |
| 2593 """addPriceToRecord(self, price, record) | |
| 2594 | |
| 2595 Add a price to the price list of the record. | |
| 2596 price must fulfill: | |
| 2597 - must be a list with two items | |
| 2598 - the first item: price must be a float | |
| 2599 """ | |
| 2600 record.addPrice(price_date, self.getDecimals()) | |
| 2601 | |
| 2602 def getStrPriceFromRecord(self, index_price, record): | |
| 2603 _price = record.getPrice(index_price) | |
| 2604 _D = self.getDecimals().getD(record.recordType) | |
| 2605 _price = ("%." + str(_D) + "f" ) % _price | |
| 2606 return _price | |
| 2607 | |
| 2608 def getCode(self, path): | |
| 2609 """getCode(self, path) | |
| 2610 | |
| 2611 path: path record in the budget. | |
| 2612 Return the code record | |
| 2613 """ | |
| 2614 if isinstance(path, tuple) and len(path)>= 1: | |
| 2615 if path[0] == 0: | |
| 2616 _code = self.__root | |
| 2617 for i in path[1:]: | |
| 2618 if isinstance(i, int): | |
| 2619 _record = self.__records[_code] | |
| 2620 _children_list = _record.children | |
| 2621 try: | |
| 2622 _child = _children_list[i] | |
| 2623 except: | |
| 2624 raise ValueError, _("This record does not exits") | |
| 2625 _code = _child.code | |
| 2626 else: | |
| 2627 raise ValueError, _("Path item must be a integer") | |
| 2628 return _code | |
| 2629 else: | |
| 2630 raise ValueError, _("This record does not exits") | |
| 2631 else: | |
| 2632 raise ValueError, utils.mapping(_("Path must be a not empty "\ | |
| 2633 "tuple: $1"), (str(path),)) | |
| 2634 | |
| 2635 def getAmount(self, path): | |
| 2636 """def getAmount(self,path) | |
| 2637 | |
| 2638 path: record path | |
| 2639 Calculate the record amount | |
| 2640 """ | |
| 2641 if len(path) == 1: | |
| 2642 # root: amount is the root price | |
| 2643 _root = self.getRecord(self.getRoot()) | |
| 2644 _amount = _root.getPrice(self.__title_index) | |
| 2645 return _amount | |
| 2646 else: | |
| 2647 _parent_code = self.getCode(path[:-1]) | |
| 2648 _parent_record = self.getRecord(_parent_code) | |
| 2649 _child_number = path[-1] | |
| 2650 | |
| 2651 _decomposition = _parent_record.children[_child_number] | |
| 2652 _factor = _decomposition.budgetMeasures[0].factor | |
| 2653 _yield = _decomposition.budgetMeasures[0].yield_ | |
| 2654 _child_code = _decomposition.code | |
| 2655 _child_record = self.getRecord(_child_code) | |
| 2656 _price = _child_record.getPrice(self.getActiveTitle()) | |
| 2657 _DR = self.getDecimals().getDR(_parent_record.recordType) | |
| 2658 _total_yield = round(_factor * _yield, _DR) | |
| 2659 _DI = self.getDecimals().getDI(_parent_record.recordType) | |
| 2660 _amount = round(_total_yield * _price, _DI) | |
| 2661 return _amount | |
| 2662 | |
| 2663 def getStrAmount(self, path): | |
| 2664 """def getStrAmount(self, path) | |
| 2665 | |
| 2666 path: record path | |
| 2667 Calculate the string record amount | |
| 2668 """ | |
| 2669 if len(path) == 1: #root | |
| 2670 _root = self.getRecord(self.getRoot()) | |
| 2671 _amount = self.getStrPriceFromRecord(self.__title_index, _root) | |
| 2672 return _amount | |
| 2673 else: | |
| 2674 _parent_code = self.getCode(path[:-1]) | |
| 2675 _parent_record = self.getRecord(_parent_code) | |
| 2676 _amount = self.getAmount(path) | |
| 2677 _DI = self.getDecimals().getDI(_parent_record.recordType) | |
| 2678 _amount = ("%." + str(_DI) + "f") % _amount | |
| 2679 return _amount | |
| 2680 | |
| 2681 def setSheetSection(self,sheet_code,sheet_title): | |
| 2682 if not isinstance(sheet_code, str): | |
| 2683 raise ValueError, _("The sheet code must be a string") | |
| 2684 if not isinstance(sheet_title, str): | |
| 2685 raise ValueError, _("The sheet title must be a string") | |
| 2686 self.__sheet_sections[sheet_code] = sheet_title | |
| 2687 def hasSheetSection(self, section): | |
| 2688 return section in self.__sheet_sections | |
| 2689 def getSheetSection(self, section): | |
| 2690 return self.__sheet_sections[section] | |
| 2691 def setSheetSections(self,dictionary): | |
| 2692 if not isinstance(dictionary, dict): | |
| 2693 raise ValueError, _("The sheet sections must be a dictionary") | |
| 2694 for sheet_code in dictionary.keys(): | |
| 2695 self.setSheetSection(sheet_code, dictionary[sheet_code]) | |
| 2696 def setSheetField(self, field_code, field_title): | |
| 2697 if not isinstance(field_code, str): | |
| 2698 raise ValueError, _("The field code must be a string") | |
| 2699 if not isinstance(field_title, str): | |
| 2700 raise ValueError, _("The field title must be a string") | |
| 2701 self.__sheet_fields[field_code] = field_title | |
| 2702 def hasSheetField(self, field): | |
| 2703 return field in self.__sheet_fields | |
| 2704 def getSheetField(self, field): | |
| 2705 return self.__sheet_fields[field] | |
| 2706 def setSheetFields(self, field_dict): | |
| 2707 if not isinstance(field_dict, dict): | |
| 2708 raise ValueError, _("The sheet field must be a dictionary") | |
| 2709 for field_code in field_dict.keys(): | |
| 2710 self.setSheetField( field_code, field_dict[field_code]) | |
| 2711 def setSheetParagraph(self, paragraph_code, paragraph_text): | |
| 2712 if not isinstance(paragraph_code, str): | |
| 2713 raise ValueError, _("The paragraph code must be a string") | |
| 2714 if not isinstance(paragraph_text, str): | |
| 2715 raise ValueError, _("The paragraph text must be a string") | |
| 2716 self.__sheet_paragraphs[paragraph_code] = paragraph_text | |
| 2717 def hasSheetParagraph(self, paragraph): | |
| 2718 return paragraph in self.__sheet_paragraphs | |
| 2719 def getSheetParagraph(self, paragraph): | |
| 2720 return self.__sheet_paragraphs[paragraph] | |
| 2721 def setSheetParagraphs(self, paragraph_dict): | |
| 2722 if not isinstance(paragraph_dict, dict): | |
| 2723 raise ValueError, _("The paragraph dict must be a dictionary") | |
| 2724 for paragraph_code in paragraph_dict.keys(): | |
| 2725 self.setSheetParagraph( paragraph_code, paragraph_dict[paragraph_code]) | |
| 2726 def setSheetRecord(self, record_code, field, section_dict): | |
| 2727 if not isinstance(record_code, str): | |
| 2728 raise ValueError, _("The record_code code must be a string") | |
| 2729 if not isinstance(field, str): | |
| 2730 raise ValueError, _("The field must be a string") | |
| 2731 if not isinstance(section_dict, dict): | |
| 2732 raise ValueError, _("The section dict must be a dictionary") | |
| 2733 #-# | |
| 2734 # TODO: Add a empty record? | |
| 2735 if not self.hasRecord(record_code): | |
| 2736 print utils.mapping(_("Error: The budget do not have this record "\ | |
| 2737 "code and can not be added the sheet text in the field $1. "\ | |
| 2738 "Record Code: $2"), ( field, record_code)) | |
| 2739 return | |
| 2740 #-# | |
| 2741 if not self.hasSheetField(field): | |
| 2742 self.setSheetField(field, "") | |
| 2743 for section, paragraph in section_dict.iteritems(): | |
| 2744 if not self.hasSheetParagraph(paragraph): | |
| 2745 self.setSheetParagraph(paragraph,"") | |
| 2746 if not self.hasSheetSection(section): | |
| 2747 self.setSheetSection(section, "") | |
| 2748 _sheet = self.getRecord(record_code).getSheet() | |
| 2749 _sheet.addSection(field, section, paragraph) | |
| 2750 def addFile(self, record_code, filepath, type, description): | |
| 2751 if not isinstance(record_code, str): | |
| 2752 raise ValueError, _("The record_code code must be a string") | |
| 2753 if not isinstance(filepath, str): | |
| 2754 raise ValueError, _("The filename must be a string") | |
| 2755 #-# | |
| 2756 # TODO: Add a empty record? | |
| 2757 if not self.hasRecord(record_code): | |
| 2758 print utils.mapping(_("Error: The budget do not have the record "\ | |
| 2759 "code $1 and can not be added the file: $2"), | |
| 2760 (record_code, filepath)) | |
| 2761 return | |
| 2762 #-# | |
| 2763 _record = self.getRecord(record_code) | |
| 2764 _record.addFile(filepath, type, description) | |
| 2765 def setCompany(self, company_code, sumamary, name, offices, | |
| 2766 cif, web, email): | |
| 2767 if not isinstance(company_code, str): | |
| 2768 raise ValueError, _("The company code must be a string") | |
| 2769 if not isinstance(sumamary, str): | |
| 2770 raise ValueError, _("The summary must be a string") | |
| 2771 if not isinstance(name, str): | |
| 2772 raise ValueError, _("The name must be a string") | |
| 2773 if not isinstance(offices, list): | |
| 2774 raise ValueError, _("The name must be a list") | |
| 2775 _offices = [] | |
| 2776 for _office in offices: | |
| 2777 if not isinstance(_office, list): | |
| 2778 raise ValueError, _("The office must be a list") | |
| 2779 if not len(_office) == 10: | |
| 2780 raise ValueError, _("The office must be a 10 items list") | |
| 2781 for _item in _office[:7] + _office[9:10]: | |
| 2782 if not isinstance(_item, str): | |
| 2783 raise ValueError, _("This office item must be a "\ | |
| 2784 "string") | |
| 2785 for _item in _office[7:8]: | |
| 2786 if not isinstance(_item, list): | |
| 2787 raise ValueError, _("This office item must be a "\ | |
| 2788 "list") | |
| 2789 _offices.append(Office(_office[0], | |
| 2790 _office[1], | |
| 2791 _office[2], | |
| 2792 _office[3], | |
| 2793 _office[4], | |
| 2794 _office[5], | |
| 2795 _office[6], | |
| 2796 _office[7], | |
| 2797 _office[8], | |
| 2798 _office[9])) | |
| 2799 if not isinstance(cif, str): | |
| 2800 raise ValueError, _("The name must be a string") | |
| 2801 if not isinstance(web, str): | |
| 2802 raise ValueError, _("The web must be a string") | |
| 2803 if not isinstance(email, str): | |
| 2804 raise ValueError, _("The email must be a string") | |
| 2805 | |
| 2806 self.__companys[company_code] = Company(company_code, sumamary, name, | |
| 2807 _offices, cif, web, email) | |
| 2808 def getCompany(self, company_code): | |
| 2809 return self.__companys[company_code] | |
| 2810 def getCompanyKeys(self): | |
| 2811 return self.__companys.keys() | |
| 2812 def addTecInfo(self, ti_code, text, unit): | |
| 2813 if not isinstance(ti_code, str): | |
| 2814 raise ValueError, _("The tecnical info code must be a string") | |
| 2815 if not isinstance(text, str): | |
| 2816 raise ValueError, _("The tecnical info description must be a "\ | |
| 2817 "string") | |
| 2818 if not isinstance(unit, str): | |
| 2819 raise ValueError, _("The tecnical info unit must be a string") | |
| 2820 self.__tec_info[ti_code] = [text, unit] | |
| 2821 def hasTecInfo(self, ti_code): | |
| 2822 return ti_code in self.__tec_info | |
| 2823 def getTecInfo(self, ti_code): | |
| 2824 return self.__tec_info[ti_code] | |
| 2825 def setTecnicalInformation(self, record_code, ti_dict): | |
| 2826 """setTecnicalInformation(record_code, ti_dict) | |
| 2827 | |
| 2828 Sets the tecnical information to a record | |
| 2829 record_code: the record code | |
| 2830 ti_dict: {ti_code : ti_value} | |
| 2831 """ | |
| 2832 # TODO: setTecnicalInformation | |
| 2833 pass | |
| 2834 def changeCode(self, record_code, new_record_code): | |
| 2835 """changeCode(self, record_code, new_record_code): | |
| 2836 | |
| 2837 Change the record code for a new recor code. | |
| 2838 """ | |
| 2839 if self.hasRecord(record_code) and not self.hasRecord(new_record_code): | |
| 2840 _record = self.__records[code] | |
| 2841 _record.code = new_record_code | |
| 2842 _parents = _record.parents | |
| 2843 for _parent in _parents: | |
| 2844 _decomposition_list = self.__records[_parent].children | |
| 2845 for _decomposition in _decomposition_list: | |
| 2846 if _decomposition.code == record_code: | |
| 2847 _decomposition.code = new_record_code | |
| 2848 break | |
| 2849 _children = self.getchildren(record_code) | |
| 2850 for _child in _children: | |
| 2851 _parents_list = self.__records[_child].parents | |
| 2852 for index in range(len(_parents_list)): | |
| 2853 if _parents_list[index] == record_code: | |
| 2854 _parents_list[index] = new_record_code | |
| 2855 break | |
| 2856 self.__records[new_record_code] = _record | |
| 2857 del self.__records[record_code] | |
| 2858 # TODO: attachment files | |
| 2859 | |
| 2860 def addLabel(self, record_code, label): | |
| 2861 """addLabel(self, record_code, label) | |
| 2862 | |
| 2863 Add a label to a record | |
| 2864 """ | |
| 2865 if not isinstance(label,str): | |
| 2866 raise ValueError, _("The label must be a string") | |
| 2867 if self.hasRecord(record_code): | |
| 2868 _record = self.__records[record_code] | |
| 2869 _record.addLabel(label) | |
| 2870 if not label in self.__labels: | |
| 2871 self.__labels[label] = [record_code] | |
| 2872 else: | |
| 2873 _codes = self.__labels[label] | |
| 2874 if not record_code in _codes: | |
| 2875 _codes.append(record_code) | |
| 2876 def setParametricSelectComment(self, record_code, comment): | |
| 2877 """setParametricSelectComment(self, record_code, comment) | |
| 2878 | |
| 2879 Sets Paramtric Record Select Comment | |
| 2880 """ | |
| 2881 if not isinstance(record_code, str): | |
| 2882 raise ValueError, _("The record_code code must be a string") | |
| 2883 if not isinstance(comment, str): | |
| 2884 raise ValueError, _("The parametric select comment must be a "\ | |
| 2885 "string") | |
| 2886 if not self.hasRecord(record_code): | |
| 2887 print utils.mapping(_("Error: The budget do not have the record "\ | |
| 2888 "code $1 and can not be added the Parametric select comment: "\ | |
| 2889 "$2"), | |
| 2890 (record_code, comment)) | |
| 2891 return | |
| 2892 _record = self.getRecord(record_code) | |
| 2893 if not isinstance(_record, ParametricRecord): | |
| 2894 print utils.mapping(_("Error: The Record $1 is not a "\ | |
| 2895 "Parametric Record and can not have Parametric comment"), | |
| 2896 (record_code,)) | |
| 2897 else: | |
| 2898 _record.select_comment = comment | |
| 2899 | |
| 2900 def setParametricSummary(self, record_code, summary): | |
| 2901 """setParametricSummary(self, record_code, summary) | |
| 2902 | |
| 2903 Sets parametric record summary | |
| 2904 """ | |
| 2905 if not isinstance(record_code, str): | |
| 2906 raise ValueError, _("The record_code code must be a string") | |
| 2907 if not isinstance(summary, str): | |
| 2908 raise ValueError, _("The summary record must be a string") | |
| 2909 if not self.hasRecord(record_code): | |
| 2910 print utils.mapping(_("Error: The budget do not have the record "\ | |
| 2911 "code $1 and can not be seted the summary: $2"), | |
| 2912 (record_code, summary)) | |
| 2913 return | |
| 2914 _record = self.getRecord(record_code) | |
| 2915 if not isinstance(_record, ParametricRecord): | |
| 2916 print utils.mapping(_("Error: The Record $1 is not a "\ | |
| 2917 "Parametric Record and can not have Parametric summary"), | |
| 2918 (record_code,)) | |
| 2919 else: | |
| 2920 self.getRecord(record_code).parametric_summary = summary | |
| 2921 | |
| 2922 def setParametricText(self, record_code, text): | |
| 2923 """setParametricText(self, record_code, text) | |
| 2924 | |
| 2925 Sets parametric record text | |
| 2926 """ | |
| 2927 if not isinstance(record_code, str): | |
| 2928 raise ValueError, _("The record_code code must be a string") | |
| 2929 if not isinstance(text, str): | |
| 2930 raise ValueError, _("The text record must be a string") | |
| 2931 if not self.hasRecord(record_code): | |
| 2932 print utils.mapping(_("Error: The budget do not have the record "\ | |
| 2933 "code $1 and can not be seted the text: $2"), | |
| 2934 (record_code, text)) | |
| 2935 return | |
| 2936 _record = self.getRecord(record_code) | |
| 2937 if not isinstance(_record, ParametricRecord): | |
| 2938 print utils.mapping(_("Error: The Record $1 is not a "\ | |
| 2939 "Parametric Record and can not have Parametric text"), | |
| 2940 (record_code,)) | |
| 2941 else: | |
| 2942 self.getRecord(record_code).parametric_text = text | |
| 2943 | |
| 2944 class Office(object): | |
| 2945 """base.Office: | |
| 2946 | |
| 2947 Description: | |
| 2948 Office of a company | |
| 2949 Constructor: | |
| 2950 base.Office(type, subname, address, postal_code, town, province, | |
| 2951 country, phone, fax, contact_person) | |
| 2952 Ancestry: | |
| 2953 +-- object | |
| 2954 +-- Office | |
| 2955 Atributes: | |
| 2956 "officeType" : type of Office | |
| 2957 are defined: | |
| 2958 "C" Central. | |
| 2959 "D" Local Office. | |
| 2960 "R" performer. | |
| 2961 "subname" : name of Office or Performer | |
| 2962 "address" : | |
| 2963 "postal_code" : | |
| 2964 "town" : | |
| 2965 "province" : | |
| 2966 "country" : | |
| 2967 "phone" : list of phone numbers | |
| 2968 "fax" : list of fax numbers | |
| 2969 "contact_person" : name of contact person | |
| 2970 "values": | |
| 2971 Methods: | |
| 2972 __getstate__(self) | |
| 2973 __setstate__(self, tuple) | |
| 2974 __init__(self, measure, lines, label) | |
| 2975 {get/set}OfficeType | |
| 2976 {get/set}Subname | |
| 2977 {get/set}Address | |
| 2978 {get/set}PostalCode | |
| 2979 {get/set}Town | |
| 2980 {get/set}Province | |
| 2981 {get/set}Country | |
| 2982 {get/set}Phone | |
| 2983 {get/set}Fax | |
| 2984 {get/set}ContactPerson | |
| 2985 getValues | |
| 2986 """ | |
| 2987 __slots__ = ["_Office__officeType", | |
| 2988 "_Office__subname", | |
| 2989 "_Office__address", | |
| 2990 "_Office__postal_code", | |
| 2991 "_Office__town", | |
| 2992 "_Office__province", | |
| 2993 "_Office__country", | |
| 2994 "_Office__phone", | |
| 2995 "_Office__fax", | |
| 2996 "_Office__contact_person", | |
| 2997 ] | |
| 2998 def __getstate__ (self): | |
| 2999 return ( self.__officeType, | |
| 3000 self.__subname, | |
| 3001 self.__address, | |
| 3002 self.__postal_code, | |
| 3003 self.__town, | |
| 3004 self.__province, | |
| 3005 self.__country, | |
| 3006 self.__phone, | |
| 3007 self.__fax, | |
| 3008 self.__contact_person) | |
| 3009 def __setstate__(self,tuple): | |
| 3010 self.__officeType = tuple[0] | |
| 3011 self.__subname = tuple[1] | |
| 3012 self.__address = tuple[2] | |
| 3013 self.__postal_code = tuple[3] | |
| 3014 self.__town = tuple[4] | |
| 3015 self.__province = tuple[5] | |
| 3016 self.__country = tuple[6] | |
| 3017 self.__phone = tuple[7] | |
| 3018 self.__fax = tuple[8] | |
| 3019 self.__contact_person = tuple[9] | |
| 3020 | |
| 3021 def __init__(self, type, subname, address, postal_code, town, province, | |
| 3022 country, phone, fax, contact_person): | |
| 3023 self.officeType = type | |
| 3024 self.subname = subname | |
| 3025 self.address = address | |
| 3026 self.postal_code = postal_code | |
| 3027 self.town = town | |
| 3028 self.province = province | |
| 3029 self.country = country | |
| 3030 self.phone = phone | |
| 3031 self.fax = fax | |
| 3032 self.contact_person = contact_person | |
| 3033 def getOfficeType(self): | |
| 3034 return self.__officeType | |
| 3035 def setOfficeType(self, type): | |
| 3036 self.__officeType = type | |
| 3037 def getSubname(self): | |
| 3038 return self.__subname | |
| 3039 def setSubname(self, subname): | |
| 3040 self.__subname = subname | |
| 3041 def getAddress(self): | |
| 3042 return self.__address | |
| 3043 def setAddress(self, address): | |
| 3044 self.__address = address | |
| 3045 def getPostalCode(self): | |
| 3046 return self.__postal_code | |
| 3047 def setPostalCode(self, postal_code): | |
| 3048 self.__postal_code = postal_code | |
| 3049 def getTown(self): | |
| 3050 return self.__town | |
| 3051 def setTown(self, town): | |
| 3052 self.__town = town | |
| 3053 def getProvince(self): | |
| 3054 return self.__province | |
| 3055 def setProvince(self, province): | |
| 3056 self.__province = province | |
| 3057 def getCountry(self): | |
| 3058 return self.__country | |
| 3059 def setCountry(self, country): | |
| 3060 self.__country = country | |
| 3061 def getPhone(self): | |
| 3062 return self.__phone | |
| 3063 def setPhone(self, phone): | |
| 3064 self.__phone = phone | |
| 3065 def getFax(self): | |
| 3066 return self.__fax | |
| 3067 def setFax(self, fax): | |
| 3068 self.__fax = fax | |
| 3069 def getContactPerson(self): | |
| 3070 return self.__contact_person | |
| 3071 def setContactPerson(self, contact_person): | |
| 3072 self.__contact_person = contact_person | |
| 3073 def getValues(self): | |
| 3074 return {"officeType": self.officeType, | |
| 3075 "subname": self.subname, | |
| 3076 "address": self.address, | |
| 3077 "postal code": self.postal_code, | |
| 3078 "town": self.town, | |
| 3079 "province": self.province, | |
| 3080 "country": self.country, | |
| 3081 "phone": self.phone, | |
| 3082 "fax": self.fax, | |
| 3083 "contact person": self.contact_person, | |
| 3084 } | |
| 3085 officeType = property(getOfficeType, setOfficeType, None, | |
| 3086 """Type of office | |
| 3087 """) | |
| 3088 subname = property(getSubname, setSubname, None, | |
| 3089 """Name of office | |
| 3090 """) | |
| 3091 address = property(getAddress, setAddress, None, | |
| 3092 """Adress | |
| 3093 """) | |
| 3094 postal_code = property(getPostalCode, setPostalCode, None, | |
| 3095 """Postal code | |
| 3096 """) | |
| 3097 town = property(getTown, setTown, None, | |
| 3098 """Town | |
| 3099 """) | |
| 3100 province = property(getProvince, setProvince, None, | |
| 3101 """Province | |
| 3102 """) | |
| 3103 country = property(getCountry, setCountry, None, | |
| 3104 """Country | |
| 3105 """) | |
| 3106 phone = property(getPhone, setPhone, None, | |
| 3107 """Phone numbers | |
| 3108 """) | |
| 3109 fax = property(getFax, setFax, None, | |
| 3110 """Fax numbers | |
| 3111 """) | |
| 3112 contact_person = property(getContactPerson, setContactPerson, None, | |
| 3113 """Contact Person | |
| 3114 """) | |
| 3115 values = property(getValues, None, None, | |
| 3116 """Dictionary with comapany values | |
| 3117 """) | |
| 3118 | |
| 3119 class Company(object): | |
| 3120 """base.Company: | |
| 3121 | |
| 3122 Description: | |
| 3123 Company object | |
| 3124 __slots__ attribute, __getstate__ and __setstate__ method are defined | |
| 3125 to use less ram memory. | |
| 3126 Constructor: | |
| 3127 base.Company(code, summary, name, offices, cif, web, email) | |
| 3128 Ancestry: | |
| 3129 +-- object | |
| 3130 +-- Company | |
| 3131 Atributes: | |
| 3132 "code": code to indentifie the company in the buget | |
| 3133 "summary": short name | |
| 3134 "name": long name | |
| 3135 "offices": List of Offices | |
| 3136 "cif": CIF | |
| 3137 "web": web page | |
| 3138 "email": email | |
| 3139 "values": | |
| 3140 Methods: | |
| 3141 __getstate__(self) | |
| 3142 __setstate__(self, tuple) | |
| 3143 __init__(self, measure, lines, label) | |
| 3144 {get/set}Code | |
| 3145 {get/set}Summary | |
| 3146 {get/set}Name | |
| 3147 {get/set}Offices | |
| 3148 {get/set}Cif | |
| 3149 {get/set}Web | |
| 3150 {get/set}Email | |
| 3151 getValues | |
| 3152 """ | |
| 3153 __slots__ = ["_Company__code", | |
| 3154 "_Company__summary", | |
| 3155 "_Company__name", | |
| 3156 "_Company__offices", | |
| 3157 "_Company__cif", | |
| 3158 "_Company__web", | |
| 3159 "_Company__email", | |
| 3160 ] | |
| 3161 def __getstate__ (self): | |
| 3162 return ( self.__code, | |
| 3163 self.__summary, | |
| 3164 self.__name, | |
| 3165 self.__offices, | |
| 3166 self.__cif, | |
| 3167 self.__web, | |
| 3168 self.__email) | |
| 3169 def __setstate__(self,tuple): | |
| 3170 self.__code = tuple[0] | |
| 3171 self.__summary = tuple[1] | |
| 3172 self.__name = tuple[2] | |
| 3173 self.__offices = tuple[3] | |
| 3174 self.__cif = tuple[4] | |
| 3175 self.__web = tuple[5] | |
| 3176 self.__email = tuple[6] | |
| 3177 | |
| 3178 def __init__(self, code, summary, name, offices, cif, web, email): | |
| 3179 self.code = code | |
| 3180 self.summary = summary | |
| 3181 self.name = name | |
| 3182 self.offices = offices | |
| 3183 self.cif = cif | |
| 3184 self.web = web | |
| 3185 self.email = email | |
| 3186 def getCode(self): | |
| 3187 return self.__code | |
| 3188 def setCode(self, code): | |
| 3189 self.__code = code | |
| 3190 def getSummary(self): | |
| 3191 return self.__summary | |
| 3192 def setSummary(self, summary): | |
| 3193 self.__summary = summary | |
| 3194 def getName(self): | |
| 3195 return self.__name | |
| 3196 def setName(self, name): | |
| 3197 self.__name = name | |
| 3198 def getOffices(self): | |
| 3199 return self.__offices | |
| 3200 def setOffices(self, offices): | |
| 3201 self.__offices = offices | |
| 3202 def getCif(self): | |
| 3203 return self.__cif | |
| 3204 def setCif(self, cif): | |
| 3205 self.__cif = cif | |
| 3206 def getWeb(self): | |
| 3207 return self.__web | |
| 3208 def setWeb(self, web): | |
| 3209 self.__web = web | |
| 3210 def getEmail(self): | |
| 3211 return self.__email | |
| 3212 def setEmail(self, email): | |
| 3213 self.__email = email | |
| 3214 def getValues(self): | |
| 3215 return {"code": self.code, | |
| 3216 "summary": self.summary, | |
| 3217 "name": self.name, | |
| 3218 "cif": self.cif, | |
| 3219 "web": self.web, | |
| 3220 "email": self.email} | |
| 3221 code = property(getCode, setCode, None, | |
| 3222 """Company code | |
| 3223 """) | |
| 3224 summary = property(getSummary, setSummary, None, | |
| 3225 """Company summary | |
| 3226 """) | |
| 3227 name = property(getName, setName, None, | |
| 3228 """Company name | |
| 3229 """) | |
| 3230 offices = property(getOffices, setOffices, None, | |
| 3231 """List of Offices | |
| 3232 """) | |
| 3233 cif = property(getCif, setCif, None, | |
| 3234 """CIF | |
| 3235 """) | |
| 3236 web = property(getWeb, setWeb, None, | |
| 3237 """Web page | |
| 3238 """) | |
| 3239 email = property(getEmail, setEmail, None, | |
| 3240 """Email | |
| 3241 """) | |
| 3242 values = property(getValues, None, None, | |
| 3243 """Dictionary with comapany values | |
| 3244 """) | |
| 3245 | |
| 3246 class File(object): | |
| 3247 """base.Company: | |
| 3248 | |
| 3249 Description: | |
| 3250 File object | |
| 3251 Constructor: | |
| 3252 base.File(name, type, description) | |
| 3253 Ancestry: | |
| 3254 +-- object | |
| 3255 +-- File | |
| 3256 Atributes: | |
| 3257 "name": name | |
| 3258 "fileType": type of file | |
| 3259 "description": description file | |
| 3260 Methods: | |
| 3261 __getstate__(self) | |
| 3262 __setstate__(self, tuple) | |
| 3263 __init__(self, path,type, description) | |
| 3264 {get/set}Name | |
| 3265 {get/set}FileType | |
| 3266 {get/set}Description | |
| 3267 getValues | |
| 3268 """ | |
| 3269 __slots__ = ["_File__name", | |
| 3270 "_File__fileType", | |
| 3271 "_File__description", | |
| 3272 | |
| 3273 ] | |
| 3274 def __getstate__ (self): | |
| 3275 return (self.__name, | |
| 3276 self.__description, | |
| 3277 self.__fileType, | |
| 3278 ) | |
| 3279 def __setstate__(self,tuple): | |
| 3280 self.__name = tuple[0] | |
| 3281 self.__fileType = tuple[1] | |
| 3282 self.__description = tuple[2] | |
| 3283 def __init__(self, name, type, description): | |
| 3284 self.name = name | |
| 3285 self.fileType = type | |
| 3286 self.description = description | |
| 3287 def getName(self): | |
| 3288 return self.__name | |
| 3289 def setName(self, name): | |
| 3290 self.__name = name | |
| 3291 def getFileType(self): | |
| 3292 return self.__fileType | |
| 3293 def setFileType(self, type): | |
| 3294 self.__fileType = type | |
| 3295 def getDescription(self): | |
| 3296 return self.__description | |
| 3297 def setDescription(self, description): | |
| 3298 self.__description = description | |
| 3299 def getValues(self): | |
| 3300 return {"name": self.name, | |
| 3301 "fileType": self.fileType, | |
| 3302 "description": self.description, | |
| 3303 } | |
| 3304 name = property(getName, setName, None, | |
| 3305 """File name | |
| 3306 """) | |
| 3307 fileType = property(getFileType, setFileType, None, | |
| 3308 """FileType | |
| 3309 """) | |
| 3310 description = property(getDescription, setDescription, None, | |
| 3311 """File description | |
| 3312 """) | |
| 3313 values = property(getValues, None, None, | |
| 3314 """Dictionary with file values | |
| 3315 """) | |
| 3316 | |
| 3317 class RecordType(object): | |
| 3318 """base.RecordType: | |
| 3319 | |
| 3320 Description: | |
| 3321 Record Type object | |
| 3322 "hierarchy": | |
| 3323 -1 -> temporarily unfixed | |
| 3324 0 -> root | |
| 3325 1 -> Chapter/Subchapter | |
| 3326 2 -> Other | |
| 3327 "type" and "subtype": | |
| 3328 0 Without classifying | |
| 3329 EA Auxiliary element | |
| 3330 EU Unitary element | |
| 3331 EC Complex element | |
| 3332 EF Functional element | |
| 3333 OB Construction site | |
| 3334 PA Cost overrun | |
| 3335 PU Unitary budget | |
| 3336 1 Labourforce | |
| 3337 H Labourforce | |
| 3338 2 Machinery and auxiliary equipment | |
| 3339 Q Machinery | |
| 3340 % Auxiliary equipment | |
| 3341 3 Building materials | |
| 3342 MC Cement | |
| 3343 MCr Ceramic | |
| 3344 MM Wood | |
| 3345 MS Iron and steel | |
| 3346 ME Energy | |
| 3347 MCu Copper | |
| 3348 MAl Aluminium | |
| 3349 ML Bonding agents | |
| 3350 M Others materials | |
| 3351 Hierarchy type subtype | |
| 3352 0->root -> 0 -> None,OB | |
| 3353 1->[sub]chapter -> 0 -> None,PU | |
| 3354 2->Other -> 0 -> None,EA,EU,EC,EF,PA | |
| 3355 1 -> None,H | |
| 3356 2 -> None,Q,% | |
| 3357 3 -> None,MC,MCr,MM,MS,ME,MCu,Mal,ML,M | |
| 3358 Constructor: | |
| 3359 base.File(hierarchy,type,subtype) | |
| 3360 Ancestry: | |
| 3361 +-- object | |
| 3362 +-- RecordType | |
| 3363 Atributes: | |
| 3364 "hierarchy": hierarchy | |
| 3365 "type": type | |
| 3366 "subtype": subtype | |
| 3367 Methods: | |
| 3368 __getstate__(self) | |
| 3369 __setstate__(self, tuple) | |
| 3370 __init__(self, hierarchy, type, subtype) | |
| 3371 {get/set}Hierarchy | |
| 3372 {get/set}Type | |
| 3373 {get/set}Subtype | |
| 3374 """ | |
| 3375 __slots__ = ["_RecordType__hierarchy", | |
| 3376 "_RecordType__type", | |
| 3377 "_RecordType__subtype", | |
| 3378 ] | |
| 3379 def __getstate__ (self): | |
| 3380 return (self.__hierarchy, | |
| 3381 self.__type, | |
| 3382 self.__subtype, | |
| 3383 ) | |
| 3384 def __setstate__(self,tuple): | |
| 3385 self.__hierarchy = tuple[0] | |
| 3386 self.__type = tuple[1] | |
| 3387 self.__subtype = tuple[2] | |
| 3388 def __init__(self, hierarchy, type, subtype): | |
| 3389 self.hierarchy = hierarchy | |
| 3390 self.type = type | |
| 3391 self.subtype = subtype | |
| 3392 def getHierarchy(self): | |
| 3393 return self.__hierarchy | |
| 3394 def setHierarchy(self, hierarchy): | |
| 3395 if not hierarchy in [-1, 0 , 1 ,2]: | |
| 3396 raise ValueError, utils.mapping(_("Invalid Hierarchy ($1) "\ | |
| 3397 "The hierarchy must be -1, 0, 1 or 2"), (str(hierarchy))) | |
| 3398 self.__hierarchy = hierarchy | |
| 3399 def getType(self): | |
| 3400 return self.__type | |
| 3401 def setType(self, type): | |
| 3402 if not type in ["", 0, 1, 2, 3] : | |
| 3403 raise ValueError, utils.mapping(_("Invalid type ($1),"\ | |
| 3404 "the type must be (empty string,0,1,2,3)"),(str(type))) | |
| 3405 self.__type = type | |
| 3406 def getSubtype(self): | |
| 3407 return self.__subtype | |
| 3408 def setSubtype(self, subtype): | |
| 3409 if not subtype in ["", "OB", "PU", "EA", "EU", "EC", "EF", "PA", "H", | |
| 3410 "Q", "%", "MC", "MCr", "MM", "MS", "ME", "MCu", | |
| 3411 "Mal","ML","M"]: | |
| 3412 raise ValueError, utils.mapping(_("Invalid subtype ($1), The "\ | |
| 3413 "subtype must one in (empty string, EA, "\ | |
| 3414 "EU, EC, EF, OB, PA, PU, H, Q, %, MC, MCr, "\ | |
| 3415 "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype))) | |
| 3416 self.__subtype = subtype | |
| 3417 hierarchy = property(getHierarchy, setHierarchy, None, | |
| 3418 """Record Hierarchy | |
| 3419 -1 -> temporarily unfixed | |
| 3420 0 -> root | |
| 3421 1 -> Chapter/Subchapter | |
| 3422 2 -> Other | |
| 3423 """) | |
| 3424 type = property(getType, setType, None, | |
| 3425 """Record Type | |
| 3426 0 Without classifying | |
| 3427 1 Labourforce | |
| 3428 2 Machinery and auxiliary equipment | |
| 3429 3 Building materials | |
| 3430 """) | |
| 3431 subtype = property(getSubtype, setSubtype, None, | |
| 3432 """Record Subtype | |
| 3433 None | |
| 3434 EA Auxiliary element | |
| 3435 EU Unitary element | |
| 3436 EC Complex element | |
| 3437 EF Functional element | |
| 3438 OB Construction site | |
| 3439 PA Cost overrun | |
| 3440 PU Unitary budget | |
| 3441 H Labourforce | |
| 3442 Q Machinery | |
| 3443 % Auxiliary equipment | |
| 3444 MC Cement | |
| 3445 MCr Ceramic | |
| 3446 MM Wood | |
| 3447 MS Iron and steel | |
| 3448 ME Energy | |
| 3449 MCu Copper | |
| 3450 MAl Aluminium | |
| 3451 ML Bonding agents | |
| 3452 M Others materials | |
| 3453 """) |
