comparison Generic/base.py @ 23:65e7ae0d0e63

GTK2 to GTK3
author Miguel Ángel Bárcena Rodríguez <miguelangel@obraencurso.es>
date Thu, 02 May 2019 16:31:17 +0200
parents 7bd4ca56607d
children 189f8274aecd
comparison
equal deleted inserted replaced
22:7bd4ca56607d 23:65e7ae0d0e63
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 ## File base.py 3 ## File base.py
4 ## This file is part of pyArq-Presupuestos. 4 ## This file is part of pyArq-Presupuestos.
5 ## 5 ##
6 ## Copyright (C) 2010-2014 Miguel Ángel Bárcena Rodríguez 6 ## Copyright (C) 2010-2019 Miguel Ángel Bárcena Rodríguez
7 ## <miguelangel@obraencurso.es> 7 ## <miguelangel@obraencurso.es>
8 ## 8 ##
9 ## pyArq-Presupuestos is free software: you can redistribute it and/or modify 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 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 11 ## the Free Software Foundation, either version 3 of the License, or
132 * Name 132 * Name
133 * Type 133 * Type
134 * Description 134 * Description
135 +-- __synonyms: synonyms dictionary. TODO 135 +-- __synonyms: synonyms dictionary. TODO
136 +-- __root: root record code 136 +-- __root: root record code
137 +-- __decimals: decimals dictionay = { int : Decimals } 137 +-- __decimals: List with the decimal places used to round the
138 - result of the calculations with prices and measures
139 - The values are Decimals objects
140 - The <0> objets is the default Decimals (seted in FIEBDC-3),
141 - The others keys are for the diferent groups of Prices
138 * Decimals: 142 * Decimals:
139 +-- DN: Number of decimal places of the field "equal-size parts" in the 143 +-- DN: Number of decimal places of the field "equal-size parts" in the
140 measure lines. 144 measure lines.
141 Default: 2 decimal places. 145 Default: 2 decimal places.
142 +-- DD: Number of decimal places of the three dimensions in the 146 +-- DD: Number of decimal places of the three dimensions in the
240 +-- fax: list of fax numbers 244 +-- fax: list of fax numbers
241 +-- contact_person: Contact person in the office 245 +-- contact_person: Contact person in the office
242 +-- cif: CIF 246 +-- cif: CIF
243 +-- web: web page 247 +-- web: web page
244 +-- email: email 248 +-- email: email
249 +-- __comment
250 +-- __date
251 +-- __budgetType" A integer. Type of data in budget
252 0 -> Undefined
253 1 -> Base data.
254 2 -> Budget.
255 3 -> Certificate.
256 4 -> Base date update.
257 +-- __budgetCerficateOrder" Only valid if budgetType is 3.
258 +-- __budgetCerficateDate" Only valid if budgetType is 3
259 +-- __tec_info": Dictionary whith tecnical information
260 {ti_code : ["desciption text", "unit"]}
261 +-- __labels": Label dictionary { "label": [ "code", ], }
245 """ 262 """
246 263
247 # Modules 264 # Modules
265 # python 2/3 compatibility
266 #from __future__ import absolute_import, division, print_function, unicode_literals
267
248 import re 268 import re
249 import datetime 269 import datetime
250 import os 270 import os
251 271
252 # pyArq-Presupuestos modules 272 # pyArq-Presupuestos modules
253 from Generic import fiebdc 273 from Generic import fiebdc
254 from Generic import utils 274 from Generic import utils
275
276
277 # Translatable global Vars
278
279 authors = ["Miguel Ángel Bárcena Rodríguez"]
280 copyright = "Copyright \xc2\xa9 2019 Autoras de Pyarq Presupuestos"
281 website = "http://pyarq.obraencurso.es/pyarq-Presupuestos"
282 website_label = "pyarq Presupuestos Web"
283 comments = _("""
284 A free program of measurements, budgets and control of construction sites.
285 In beta development, still there is not a fully functional version.
286 """)
287 help = _(
288 """
289 Usage:
290 pyarqPresupuestos [file]...
291
292 Help Options:
293 -h, --help Show this help
294 """)
255 295
256 class Record(object): 296 class Record(object):
257 """base.Record: 297 """base.Record:
258 298
259 Description: 299 Description:
263 prices, type_, subtype, parents=None, text=None) 303 prices, type_, subtype, parents=None, text=None)
264 Ancestry: 304 Ancestry:
265 +-- object 305 +-- object
266 +-- Record 306 +-- Record
267 Atributes: 307 Atributes:
268 "code": Code string 308 "code": Write/Read. Code string
269 "recordType": RecordType object 309 "recordType": Write/Read. RecordType object
270 "synonyms": List of synonym codes. 310 "synonyms": Write/Read. List of synonym codes.
271 "parents":List of parent codes 311 "parents": Write/Read. List of parent codes
272 "children": Decomposition list, 312 "children": Write/Read. Decomposition list,
273 list of "Decomposition" instances 313 list of "Decomposition" instances
274 "unit": measure unit of the record 314 "unit": Write/Read. measure unit of the record
275 "summary": Short description of the record 315 "summary": Write/Read. Short description of the record
276 "prices": List of prices/dates 316 "prices": Read. List of prices/dates
277 "text": Long Description of the record 317 "text": Write/Read. Long Description of the record
278 "sheet": Sheet of conditions object 318 "sheet": Write/Read. Sheet of conditions object
279 "files": List of file object 319 "files": Write/Read. List of file object
280 "labels": List of record labels 320 "labels": Write/Read. List of record labels
281 Methods: 321 Methods:
282 __getstate__(self) 322 isPercentage
283 __setstate__(self, tuple) 323 percentageMasq
284 __init__(self, filename=None, budget=None) 324 hasPercentageMasq(masq)
285 {get/set}Code 325 {get/set}Code
286 {get/set}Synonyms 326 {get/set}Synonyms
287 {get/set}RecordType 327 {get/set}RecordType
288 {get/set}Unit 328 {get/set}Unit
289 {get/set}Summary 329 {get/set}Summary
290 {get/set}Prices 330 {get/set}Prices
291 addPrice 331 addPrice
292 _validate_price_date
293 getPrice 332 getPrice
294 getAmount 333 getAmount
295 getDate 334 getDate
296 {get/set}Parents 335 {get/set}Parents
297 appendParent 336 appendParent
349 self.text = text 388 self.text = text
350 self.sheet = Sheet() 389 self.sheet = Sheet()
351 self.files = [] 390 self.files = []
352 self.labels = [] 391 self.labels = []
353 392
393 def isPercentage(self):
394 if "%" in self.__code or "&" in self.__code:
395 return True
396 else:
397 return False
398
399 def percentageMasq(self):
400 if "%" in self.__code:
401 return self.__code.split("%")[0]
402 elif "&" in self.__code:
403 return self.__code.split("&")[0]
404
405 def hasPercentageMasq(self, masq):
406 if len(self.__code) >= len(masq):
407 _part_code = self.__code[:len(masq)]
408 if _part_code == masq:
409 return True
410 return False
411
354 def getCode(self): 412 def getCode(self):
355 return self.__code 413 return self.__code
356 414
357 def setCode(self, code): 415 def setCode(self, code):
358 """setCode(self,code) 416 """setCode(code)
359 417
360 Sets the code, must be a valid code 418 Sets the code, must be a valid code
361 """ 419 """
362 if not utils.is_valid_code(code)[0]: 420 if not utils.is_valid_code(code)[0]:
363 raise ValueError, utils.mapping(_("Invalid code: $1"),(str(code),)) 421 raise ValueError( utils.mapping(_("Invalid code: $1"),(str(code),)) )
364 self.__code = code 422 self.__code = code
365 423
366 def getSynonyms(self): 424 def getSynonyms(self):
367 return self.__synonyms 425 return self.__synonyms
368 426
369 def setSynonyms(self,synonyms): 427 def setSynonyms(self,synonyms):
370 """setSynonyms(self,synonyms) 428 """setSynonyms(synonyms)
371 429
372 Sets the synonyms codes of the record. 430 Sets the synonyms codes of the record.
373 synonyms must fulfill: 431 synonyms must fulfill:
374 - must be a list 432 - must be a list
375 - the items must be valid codes 433 - the items must be valid codes
376 """ 434 """
377 if not isinstance(synonyms, list): 435 if not isinstance(synonyms, list):
378 raise TypeError, utils.mapping(_("Synonyms ($1) must be a list, " \ 436 raise TypeError( utils.mapping(_("Synonyms ($1) must be a list, " \
379 "code: $2"), (str(synonyms), self.__code)) 437 "code: $2"), (str(synonyms), str(self.__code))) )
380 for code in synonyms: 438 for code in synonyms:
381 if not utils.is_valid_code(code)[0]: 439 if not utils.is_valid_code(code)[0]:
382 raise ValueError, utils.mapping(_("Invalid Code in synomyms "\ 440 raise ValueError( utils.mapping(_("Invalid Code in synomyms "\
383 "list ($1) code: $2"), (str(code), self.__code)) 441 "list ($1) code: $2"), (str(code), str(self.__code))) )
384 self.__synonyms = synonyms 442 self.__synonyms = synonyms
385 443
386 def getRecordType(self): 444 def getRecordType(self):
387 return self.__recordType 445 return self.__recordType
388 446
389 def setRecordType(self, recordType): 447 def setRecordType(self, recordType):
390 """setRecordType(self, recordType) 448 """setRecordType(recordType)
391 449
392 Set the record type. 450 Set the record type.
393 recordType (hierarchy, type,subtype) 451 recordType (hierarchy, type,subtype)
394 452
395 hierarchy must be -1, 0, 1 or 2 453 hierarchy must be -1, 0, 1 or 2
402 460
403 def getUnit(self): 461 def getUnit(self):
404 return self.__unit 462 return self.__unit
405 463
406 def setUnit(self,unit): 464 def setUnit(self,unit):
407 """setUnit(self,unit) 465 """setUnit(unit)
408 466
409 Set the unit of measure 467 Set the unit of measure
410 The unit must be a string. 468 The unit must be a string.
411 """ 469 """
412 if not isinstance(unit, str): 470 if not isinstance(unit, str):
413 raise TypeError, utils.mapping(_("Unit ($1) must be a string: $2"), 471 raise TypeError( utils.mapping(_("Unit ($1) must be a string: $2"),
414 (str(unit), self.__code)) 472 (str(unit), str(self.__code))) )
415 self.__unit = unit 473 self.__unit = unit
416 474
417 def getSummary(self): 475 def getSummary(self):
418 return self.__summary 476 return self.__summary
419 477
420 def setSummary(self,summary): 478 def setSummary(self,summary):
421 """setSummary(self,summary) 479 """setSummary(summary)
422 480
423 Set the summary of a record 481 Set the summary of a record
424 The summary must be a string. 482 The summary must be a string.
425 """ 483 """
426 if not isinstance(summary, str): 484 if not isinstance(summary, str):
427 raise TypeError, utils.mapping(_("Summary ($1) must be a string: "\ 485 raise TypeError( utils.mapping(_("Summary ($1) must be a string: "\
428 "$1"), (str(summary), self.__code)) 486 "$1"), (str(summary), str(self.__code))) )
429 self.__summary = summary 487 self.__summary = summary
430 488
431 def getPrices(self): 489 def getPrices(self):
432 return self.__prices 490 return self.__prices
433 491
434 def setPrices(self, prices, decimals): 492 def setPrices(self, prices, decimals):
435 """setPrice(self, prices, decimals) 493 """setPrice(prices, decimals)
436 494
437 Set the price list of the record. 495 Set the price list of the record.
438 prices must fulfill: 496 prices must fulfill:
439 - it must be a list 497 - it must be a list
440 - the items must be a list with two items 498 - the items must be a list with two items
441 - the first item: price must be a float 499 - the first item: price must be a float
442 """ 500 """
443 if not isinstance(prices, list): 501 if not isinstance(prices, list):
444 raise TypeError, utils.mapping(_("Prices ($1) must be a list: $2"), 502 raise TypeError( utils.mapping(_("Prices ($1) must be a list: $2"),
445 (str(prices), self.__code)) 503 (str(prices), str(self.__code))) )
446 for index in range(len(prices)): 504 for index in range(len(prices)):
447 _price_date = prices[index] 505 _price_date = prices[index]
448 _price_date = self._validate_price_date(_price_date, decimals) 506 _price_date = self._validate_price_date(_price_date, decimals)
449 prices[index] = _price_date 507 prices[index] = _price_date
450 self.__prices = prices 508 self.__prices = prices
451 509
452 def addPrice(self, price_date, decimals): 510 def addPrice(self, price_date, decimals):
453 """addPrice(self, price_date, decimals) 511 """addPrice(price_date, decimals)
454 512
455 Add a price to the price list of the record. 513 Add a price to the price list of the record.
456 price must fulfill: 514 price must fulfill:
457 - must be a list with two items 515 - must be a list with two items
458 - the first item: price must be a float 516 - the first item: price must be a float
460 price_date = self._validate_price_date(price_date, decimals) 518 price_date = self._validate_price_date(price_date, decimals)
461 self.__prices.append(price_date) 519 self.__prices.append(price_date)
462 520
463 def _validate_price_date(self, price_date, decimals): 521 def _validate_price_date(self, price_date, decimals):
464 if not isinstance(price_date, list) and len(price_date) == 2: 522 if not isinstance(price_date, list) and len(price_date) == 2:
465 raise ValueError, utils.mapping(_("Price ($1) must be a list"\ 523 raise ValueError( utils.mapping(_("Price ($1) must be a list"\
466 " with two items: $2"), (str(price_date), self.__code)) 524 " with two items: $2"), (str(price_date), str(self.__code))) )
467 _price = price_date[0] 525 _price = price_date[0]
468 _date = price_date[1] 526 _date = price_date[1]
469 if not isinstance(_price, float): 527 if not isinstance(_price, float):
470 raise TypeError, utils.mapping(_("Price must be a float "\ 528 raise TypeError( utils.mapping(_("Price must be a float "\
471 "number: $1"), (str(_price),)) 529 "number: $1"), (str(_price),)) )
472 _D = decimals.getD(self.recordType) 530 _D = abs(decimals.getD(self.recordType))
473 _price = round(_price, _D) 531 _price = round(_price, _D)
474 price_date[0] = _price 532 price_date[0] = _price
475 # TODO: validate date 533 # TODO: validate date
476 return price_date 534 return price_date
477 535
478 def getPrice(self, index_price): 536 def getPrice(self, index_price):
479 if len(self.__prices) <= index_price: 537 if len(self.__prices) <= index_price:
480 raise IndexError, _("The record do not have this Price. Code: %s" 538 raise IndexError( _("The record do not have this Price. Code: %s"
481 % self.__code) 539 % self.__code) )
482 return self.__prices[index_price][0] 540 return self.__prices[index_price][0]
483 541
484 def getDate(self, index_price): 542 def getDate(self, index_price):
485 if len(self.__prices) <= index_price: 543 if len(self.__prices) <= index_price:
486 raise IndexError, _("The record do not have this Price") 544 raise IndexError( _("The record do not have this Price") )
487 return self.__prices[index_price][1] 545 return self.__prices[index_price][1]
488 546
489 def getParents(self): 547 def getParents(self):
490 return self.__parents 548 return self.__parents
491 549
492 def setParents(self,parents): 550 def setParents(self,parents):
493 """setParents(self,parents) 551 """setParents(parents)
494 552
495 Sets the list of parents codes of the record. 553 Sets the list of parents codes of the record.
496 parents must fulfill 554 parents must fulfill
497 - it must be a list 555 - it must be a list
498 - the items must be valid codes 556 - the items must be valid codes
499 """ 557 """
500 if not isinstance(parents, list): 558 if not isinstance(parents, list):
501 raise TypeError, utils.mapping(_("Parents ($1) must be a list: $2"), 559 raise TypeError( utils.mapping(_("Parents ($1) must be a list: $2"),
502 (str(parents), self.__code)) 560 (str(parents), str(self.__code))) )
503 for parent in parents: 561 for parent in parents:
504 if not utils.is_valid_code(parent)[0]: 562 if not utils.is_valid_code(parent)[0]:
505 raise ValueError, utils.mapping(_("Invalid parent code ($1) " \ 563 raise ValueError(utils.mapping(_("Invalid parent code ($1) " \
506 "in the record: $2"), (str(padre), self.__code)) 564 "in the record: $2"), (str(padre), str(self.__code))) )
507 self.__parents = parents 565 self.__parents = parents
508 566
509 def appendParent(self, parent): 567 def appendParent(self, parent):
510 """appendParent(self, parent) 568 """appendParent(parent)
511 569
512 parent must be a valid code 570 parent must be a valid code
513 Append a parent to the list of parents codes of the record. 571 Append a parent to the list of parents codes of the record.
514 572
515 """ 573 """
516 if not utils.is_valid_code(parent)[0]: 574 if not utils.is_valid_code(parent)[0]:
517 raise ValueError, utils.mapping(_("Invalid parent code ($1) " \ 575 raise ValueError( utils.mapping(_("Invalid parent code ($1) " \
518 "in the record: $2"), (str(parent), self.__code)) 576 "in the record: $2"), (str(parent), str(self.__code))) )
519 self.__parents.append(parent) 577 self.__parents.append(parent)
520 578
521 def getchildren(self): 579 def getchildren(self):
522 return self.__children 580 return self.__children
523 581
524 def setchildren(self,children): 582 def setchildren(self,children):
525 """setchildren(self,children) 583 """setchildren(children)
526 584
527 Sets the list of children of a record 585 Sets the list of children of a record
528 children must fulfill 586 children must fulfill
529 - it must be a list 587 - it must be a list
530 - the items must be instances of Decomposition class 588 - the items must be instances of Decomposition class
531 """ 589 """
532 if not isinstance(children, list): 590 if not isinstance(children, list):
533 raise TypeError, utils.mapping(_("children ($1) must be a list, "\ 591 raise TypeError( utils.mapping(_("children ($1) must be a list, "\
534 "record: $2"), (str(children), self.__code)) 592 "record: $2"), (str(children), str(self.__code))) )
535 for _child in children: 593 for _child in children:
536 if not isinstance(_child, Decomposition): 594 if not isinstance(_child, Decomposition):
537 raise ValueError, utils.mapping(_("child ($1) must be a "\ 595 raise ValueError( utils.mapping(_("child ($1) must be a "\
538 "Decomposition object, record: $2"), 596 "Decomposition object, record: $2"),
539 (str(_child), self.__code)) 597 (str(_child), str(self.__code))) )
540 _record_code = self.code 598 _record_code = self.code
541 for _measure_list in [_child.budgetMeasures, _child.certification, 599 for _measure_list in [_child.budgetMeasures, _child.certification,
542 _child.real_cost, _child.cost_goals, 600 _child.real_cost, _child.cost_goals,
543 _child.cost_planned]: 601 _child.cost_planned]:
544 if isinstance(_measure_list, list): 602 if isinstance(_measure_list, list):
546 _measurerecordCode = _record_code 604 _measurerecordCode = _record_code
547 self.__children = children 605 self.__children = children
548 606
549 def appendChild(self, child_code, decimals, factor=0.0, yield_=0.0, 607 def appendChild(self, child_code, decimals, factor=0.0, yield_=0.0,
550 measure=0.0, measure_list=None, type_=None, label=None): 608 measure=0.0, measure_list=None, type_=None, label=None):
551 """appendChildren(self, child_code, factor=0.0, yield_=0.0, 609 """appendChildren(child_code, factor=0.0, yield_=0.0,
552 measure=0.0, measure_list=None, type_=None, label=None)) 610 measure=0.0, measure_list=None, type_=None, label=None))
553 611
554 position: 612 position:
555 child_code: 613 child_code:
556 factor: 614 factor:
580 638
581 def getText(self): 639 def getText(self):
582 return self.__text 640 return self.__text
583 641
584 def setText(self,text): 642 def setText(self,text):
585 """setText(self,text) 643 """setText(text)
586 644
587 Sets the text of the record 645 Sets the text of the record
588 It must be a string 646 It must be a string
589 """ 647 """
590 if not isinstance(text, str): 648 if not isinstance(text, str):
591 raise TypeError, utils.mapping(_("Text ($1) must be a string, "\ 649 raise TypeError( utils.mapping(_("Text ($1) must be a string, "\
592 "record: $2"), (str(text), self.__code)) 650 "record: $2"), (str(text), str(self.__code))) )
593 self.__text = text 651 self.__text = text
594 652
595 def getSheet(self): 653 def getSheet(self):
596 return self.__sheet 654 return self.__sheet
597 655
598 def setSheet(self, sheet): 656 def setSheet(self, sheet):
599 """setSheet(self, sheet) 657 """setSheet(sheet)
600 658
601 Sets the sheet of condition object 659 Sets the sheet of condition object
602 """ 660 """
603 if not isinstance(sheet, Sheet): 661 if not isinstance(sheet, Sheet):
604 raise ValueError, _("sheet must be a Sheet instance") 662 raise ValueError( _("sheet must be a Sheet instance") )
605 self.__sheet = sheet 663 self.__sheet = sheet
606 664
607 def getFiles(self): 665 def getFiles(self):
608 return self.__files 666 return self.__files
609 667
610 def setFiles(self, files): 668 def setFiles(self, files):
611 """setFiles(self, files) 669 """setFiles(files)
612 670
613 Sets the files list 671 Sets the files list
614 """ 672 """
615 # TODO: only sets files and File object format (durusdatabase)
616 if not isinstance(files, list): 673 if not isinstance(files, list):
617 raise ValueError, utils.mapping(_("files must be a list: $1"), 674 raise ValueError( utils.mapping(_("files must be a list: $1"),
618 str(files)) 675 str(files)) )
619 _files = [] 676 _files = []
620 for file in files: 677 for file in files:
621 if isinstance(file, File): 678 if isinstance(file, File):
622 _files.append(file) 679 _files.append(file)
623 elif isinstance(file, list): 680 elif isinstance(file, list):
624 _file_path = file[0] 681 _file_path = file[0]
625 _type = file[1] 682 _type = file[1]
626 _description = file[2] 683 _description = file[2]
627 if not os.path.exists(file[0]): 684 if not os.path.exists(file[0]):
628 raise ValueError, _("Incorrect path") 685 raise ValueError( _("Incorrect path") )
629 _file = File(file_path, type_, description) 686 _file = File(file_path, type_, description)
630 _files.append(_file) 687 _files.append(_file)
631 else: 688 else:
632 raise ValueError, utils.mapping(_( 689 raise ValueError( utils.mapping(_(
633 "file must be a list or a File object: $1"),str(file)) 690 "file must be a list or a File object: $1"),str(file)) )
634 self.__files = _files 691 self.__files = _files
635
636 692
637 def addFile(self, file_path, type_, description): 693 def addFile(self, file_path, type_, description):
638 """addFile(self, file_path, type_, description) 694 """addFile(file_path, type_, description)
639 695
640 Add a file to a record instance 696 Add a file to a record instance
641 """ 697 """
642 if not os.path.exists(file_path): 698 if not os.path.exists(file_path):
643 raise ValueError, _("Incorrect path") 699 raise ValueError( _("Incorrect path") )
644 _name = os.path.basename(file_path) 700 _name = os.path.basename(file_path)
645 _isin = False 701 _isin = False
646 for _ofile in self.__files: 702 for _ofile in self.__files:
647 if _ofile.name == _name: 703 if _ofile.name == _name:
648 _isin = True 704 _isin = True
652 708
653 def getLabels(self): 709 def getLabels(self):
654 return self.__labels 710 return self.__labels
655 711
656 def setLabels(self, labels): 712 def setLabels(self, labels):
657 """setLabels(self, labels) 713 """setLabels(labels)
658 714
659 Sets the labels list of a record 715 Sets the labels list of a record
660 """ 716 """
661 if not isinstance(labels, list): 717 if not isinstance(labels, list):
662 raise ValueError, _("labels must be a list") 718 raise ValueError( _("labels must be a list") )
663 _labels = [] 719 _labels = []
664 for _label in labels: 720 for _label in labels:
665 if isinstance(_label, str): 721 if isinstance(_label, str):
666 _labels.append(_label) 722 _labels.append(_label)
667 else: 723 else:
668 raise ValueError, _("label must be a string") 724 raise ValueError( _("label must be a string") )
669 self.__labels = _labels 725 self.__labels = _labels
670 726
671 def addLabel(self, label): 727 def addLabel(self, label):
672 """addLabel(self, label) 728 """addLabel(label)
673 729
674 Add a label to a record instance 730 Add a label to a record instance
675 """ 731 """
676 if not isinstance(label, str): 732 if not isinstance(label, str):
677 raise ValueError, _("Label must be a string") 733 raise ValueError( _("Label must be a string") )
678 if not label in self.__labels: 734 if not label in self.__labels:
679 self.__labels.append(label) 735 self.__labels.append(label)
680 736
681 def getChildPositions(self, child_code): 737 def getChildPositions(self, child_code):
682 """getChildPath(self, child_code): 738 """getChildPath(child_code):
683 739
684 Try to return positions of a childcode 740 Try to return positions of a childcode
685 """ 741 """
686 children = self.children 742 children = self.children
687 positions = [] 743 positions = []
721 files = property(getFiles, setFiles, None, 777 files = property(getFiles, setFiles, None,
722 """File list""") 778 """File list""")
723 labels = property(getLabels, setLabels, None, 779 labels = property(getLabels, setLabels, None,
724 """Label list""") 780 """Label list""")
725 781
782
726 class ParametricRecord(Record): 783 class ParametricRecord(Record):
727 """base.ParametricRecord: 784 """base.ParametricRecord:
728 785
729 Description: 786 Description:
730 Parametric Record object 787 Parametric Record object
782 self.__parameters = tuple[15] 839 self.__parameters = tuple[15]
783 self.__select_comment = tuple[16] 840 self.__select_comment = tuple[16]
784 self.__vars = tuple[17] 841 self.__vars = tuple[17]
785 self.__parametric_summary = tuple[18] 842 self.__parametric_summary = tuple[18]
786 self.__parametric_text = tuple[19] 843 self.__parametric_text = tuple[19]
787 844
788 def __init__(self, budget, code, synonyms, hierarchy, unit, summary, 845 def __init__(self, budget, code, synonyms, hierarchy, unit, summary,
789 prices, type_, subtype, parents=None, text=None): 846 prices, type_, subtype, parents=None, text=None):
790 if parents is None: 847 if parents is None:
791 parents = [] 848 parents = []
792 if text is None: 849 if text is None:
811 def getSelectComment(self): 868 def getSelectComment(self):
812 return self.__select_comment 869 return self.__select_comment
813 870
814 def setSelectComment(self, select_comment): 871 def setSelectComment(self, select_comment):
815 self.__select_comment = select_comment 872 self.__select_comment = select_comment
873
816 def getVar(self, var): 874 def getVar(self, var):
817 if var in self.__vars: 875 if var in self.__vars:
818 return self.__vars[var] 876 return self.__vars[var]
819 else: 877 else:
820 return None 878 return None
848 """Parametric summary 906 """Parametric summary
849 """) 907 """)
850 parametric_text = property(getParametricText, setParametricText, None, 908 parametric_text = property(getParametricText, setParametricText, None,
851 """Seclect comment 909 """Seclect comment
852 """) 910 """)
911
853 912
854 class Decomposition(object): 913 class Decomposition(object):
855 """base.Decomposition: 914 """base.Decomposition:
856 915
857 Description: 916 Description:
870 "certification": list of certifications for months measures 929 "certification": list of certifications for months measures
871 "real_cost": list of real cost of construction for months measures 930 "real_cost": list of real cost of construction for months measures
872 "cost_goals": list of cost goals of construction for months measures 931 "cost_goals": list of cost goals of construction for months measures
873 "cost_planned": list of costs planned and amended cost planned measures 932 "cost_planned": list of costs planned and amended cost planned measures
874 Methods: 933 Methods:
875 __getstate__(self)
876 __setstate__(self, tuple)
877 __init__( position, code, budgetMeasures, certification=None,
878 real_cost=None, cost_goals=None, cost_planned=None)
879 {get/set}position 934 {get/set}position
880 {get/set}Code 935 {get/set}Code
881 {get/set}BudgetMeasures 936 {get/set}BudgetMeasures
882 {get/set}Certification 937 {get/set}Certification
883 {get/set}RealCost 938 {get/set}RealCost
884 {get/set}CostGoals 939 {get/set}CostGoals
885 {get/set}CostPlanned 940 {get/set}CostPlanned
886 """ 941 """
942
887 __slots__ = ["_Decomposition__position", 943 __slots__ = ["_Decomposition__position",
888 "_Decomposition__code", 944 "_Decomposition__code",
889 "_Decomposition__budgetMeasures", 945 "_Decomposition__budgetMeasures",
890 "_Decomposition__certification", 946 "_Decomposition__certification",
891 "_Decomposition__real_cost", 947 "_Decomposition__real_cost",
892 "_Decomposition__cost_goals", 948 "_Decomposition__cost_goals",
893 "_Decomposition__cost_planned", 949 "_Decomposition__cost_planned",
894 ] 950 ]
951
895 def __getstate__ (self): 952 def __getstate__ (self):
896 return (self.__position, self.__code, self.__budgetMeasures, 953 return (self.__position, self.__code, self.__budgetMeasures,
897 self.__certification, self.__real_cost, self.__cost_goals, 954 self.__certification, self.__real_cost, self.__cost_goals,
898 self.__cost_planned) 955 self.__cost_planned)
956
899 def __setstate__(self,tuple): 957 def __setstate__(self,tuple):
900 self.__position = tuple[0] 958 self.__position = tuple[0]
901 self.__code = tuple[1] 959 self.__code = tuple[1]
902 self.__budgetMeasures = tuple[2] 960 self.__budgetMeasures = tuple[2]
903 self.__certification = tuple[3] 961 self.__certification = tuple[3]
912 self.budgetMeasures = budgetMeasures 970 self.budgetMeasures = budgetMeasures
913 self.certification = certification 971 self.certification = certification
914 self.real_cost = real_cost 972 self.real_cost = real_cost
915 self.cost_goals = cost_goals 973 self.cost_goals = cost_goals
916 self.cost_planned = cost_planned 974 self.cost_planned = cost_planned
975
917 def getPosition(self): 976 def getPosition(self):
918 return self.__position 977 return self.__position
978
919 def setPosition(self, position): 979 def setPosition(self, position):
920 if not isinstance(position, int): 980 if not isinstance(position, int):
921 raise ValueError, _("Position must be a integer") 981 raise ValueError( _("Position must be a integer") )
922 self.__position = position 982 self.__position = position
983
923 def getCode(self): 984 def getCode(self):
924 return self.__code 985 return self.__code
986
925 def setCode(self, code): 987 def setCode(self, code):
926 self.__code = code 988 self.__code = code
989
927 def getBudgetMeasures(self): 990 def getBudgetMeasures(self):
928 return self.__budgetMeasures 991 return self.__budgetMeasures
992
929 def setBudgetMeasures(self, budgetMeasures): 993 def setBudgetMeasures(self, budgetMeasures):
930 if not isinstance(budgetMeasures, list): 994 if not isinstance(budgetMeasures, list):
931 raise ValueError, _("BudgetMeasures atribute must be a list") 995 raise ValueError( _("BudgetMeasures atribute must be a list") )
932 for _measure in budgetMeasures: 996 for _measure in budgetMeasures:
933 if not isinstance(_measure, Measure): 997 if not isinstance(_measure, Measure):
934 raise ValueError, _("BudgetMeasures item must be a Measure "/ 998 raise ValueError( _("BudgetMeasures item must be a Measure "/
935 "object") 999 "object") )
936 self.__budgetMeasures = budgetMeasures 1000 self.__budgetMeasures = budgetMeasures
1001
937 def getCertification(self): 1002 def getCertification(self):
938 return self.__certification 1003 return self.__certification
1004
939 def setCertification(self, certification): 1005 def setCertification(self, certification):
940 if not (certification is None or isinstance(certification, list)): 1006 if not (certification is None or isinstance(certification, list)):
941 raise ValueError, _("Certification atribute must be a list or None") 1007 raise ValueError( _("Certification atribute must be a list or None") )
942 self.__certification = certification 1008 self.__certification = certification
1009
943 def getRealCost(self): 1010 def getRealCost(self):
944 return self.__real_cost 1011 return self.__real_cost
1012
945 def setRealCost(self, real_cost): 1013 def setRealCost(self, real_cost):
946 if not (real_cost is None or isinstance(real_cost, list)): 1014 if not (real_cost is None or isinstance(real_cost, list)):
947 raise ValueError, _("Real cost atribute must be a list or None") 1015 raise ValueError( _("Real cost atribute must be a list or None") )
948 self.__real_cost = real_cost 1016 self.__real_cost = real_cost
1017
949 def getCostGoals(self): 1018 def getCostGoals(self):
950 return self.__cost_goals 1019 return self.__cost_goals
1020
951 def setCostGoals(self, cost_goals): 1021 def setCostGoals(self, cost_goals):
952 if not (cost_goals is None or isinstance(cost_goals, list)): 1022 if not (cost_goals is None or isinstance(cost_goals, list)):
953 raise ValueError, _("Cost goals atribute must be a list or None") 1023 raise ValueError( _("Cost goals atribute must be a list or None") )
954 self.__cost_goals = cost_goals 1024 self.__cost_goals = cost_goals
1025
955 def getCostPlanned(self): 1026 def getCostPlanned(self):
956 return self.__cost_planned 1027 return self.__cost_planned
1028
957 def setCostPlanned(self, cost_planned): 1029 def setCostPlanned(self, cost_planned):
958 if not (cost_planned is None or isinstance(cost_planned, list)): 1030 if not (cost_planned is None or isinstance(cost_planned, list)):
959 raise ValueError, _("Cost Planned atribute must be a list or None") 1031 raise ValueError( _("Cost Planned atribute must be a list or None") )
960 self.__cost_planned = cost_planned 1032 self.__cost_planned = cost_planned
1033
961 position = property(getPosition, setPosition, None, 1034 position = property(getPosition, setPosition, None,
962 """Postion of the record in the budget 1035 """Postion of the record in the budget
963 """) 1036 """)
964 code = property(getCode, setCode, None, 1037 code = property(getCode, setCode, None,
965 """Record code 1038 """Record code
998 "label": Record Identifiers that are used by some measure programs. 1071 "label": Record Identifiers that are used by some measure programs.
999 "factor": 1072 "factor":
1000 "yield": 1073 "yield":
1001 "fixed": If fixed is True the yield is not calculated from measure 1074 "fixed": If fixed is True the yield is not calculated from measure
1002 Methods: 1075 Methods:
1003 __getstate__()
1004 __setstate__(tuple)
1005 __init__(decimals, recordType, measure, lines,
1006 label, factor, yield_)
1007 getMeasure() 1076 getMeasure()
1008 setMeasure(measure, decimals) 1077 setMeasure(measure, decimals)
1009 {get/set}Lines 1078 {get/set}Lines
1010 {get/set}Label 1079 {get/set}Label
1011 getFactor() 1080 getFactor()
1016 setFixed(decimals) 1085 setFixed(decimals)
1017 buildMeasure(list_lines, type, decimals) 1086 buildMeasure(list_lines, type, decimals)
1018 calculateMeasure(decimals) 1087 calculateMeasure(decimals)
1019 updateYield(decimals) 1088 updateYield(decimals)
1020 """ 1089 """
1090
1021 __slots__ = ["_Measure__measure", 1091 __slots__ = ["_Measure__measure",
1022 "_Measure__lines", 1092 "_Measure__lines",
1023 "_Measure__label", 1093 "_Measure__label",
1024 "_Measure__factor", 1094 "_Measure__factor",
1025 "_Measure__yield_", 1095 "_Measure__yield_",
1026 "_Measure__fixed"] 1096 "_Measure__fixed"]
1097
1027 def __getstate__ (self): 1098 def __getstate__ (self):
1028 return (self.__measure, self.__lines, self.__label, 1099 return (self.__measure, self.__lines, self.__label,
1029 self.__factor, self.__yield_, self.__fixed) 1100 self.__factor, self.__yield_, self.__fixed)
1101
1030 def __setstate__(self,tuple): 1102 def __setstate__(self,tuple):
1031 self.__measure = tuple[0] 1103 self.__measure = tuple[0]
1032 self.__lines = tuple[1] 1104 self.__lines = tuple[1]
1033 self.__label = tuple[2] 1105 self.__label = tuple[2]
1034 self.__factor = tuple[3] 1106 self.__factor = tuple[3]
1035 self.__yield_ = tuple[4] 1107 self.__yield_ = tuple[4]
1036 self.__fixed = tuple[5] 1108 self.__fixed = tuple[5]
1109
1037 def __init__(self, decimals, recordType, measure, lines, 1110 def __init__(self, decimals, recordType, measure, lines,
1038 label, factor, yield_): 1111 label, factor, yield_):
1039 self.setMeasure(measure, decimals) 1112 self.setMeasure(measure, decimals)
1040 self.lines = lines 1113 self.lines = lines
1041 self.label = label 1114 self.label = label
1043 self.setYield(yield_, decimals, recordType) 1116 self.setYield(yield_, decimals, recordType)
1044 self.__fixed = False 1117 self.__fixed = False
1045 1118
1046 def getMeasure(self): 1119 def getMeasure(self):
1047 return self.__measure 1120 return self.__measure
1121
1048 def setMeasure(self, measure, decimals): 1122 def setMeasure(self, measure, decimals):
1049 if not isinstance(measure, float): 1123 if not isinstance(measure, float):
1050 raise ValueError, utils.mapping(_("Measure must be a float "\ 1124 raise ValueError( utils.mapping(_("Measure must be a float "\
1051 "number. Type: $1"), (type(measure),)) 1125 "number. Type: $1"), (type(measure),)) )
1052 # TODO: test after 1126 # TODO: test after
1053 _DS = decimals.DS 1127 _DS = abs(decimals.DS)
1054 measure = round(measure, _DS) 1128 measure = round(measure, _DS)
1055 self.__measure = measure 1129 self.__measure = measure
1056 1130
1057 def getLines(self): 1131 def getLines(self):
1058 return self.__lines 1132 return self.__lines
1133
1059 def setLines(self, lines): 1134 def setLines(self, lines):
1060 if not isinstance(lines, list): 1135 if not isinstance(lines, list):
1061 raise ValueError, _("Lines must be a list") 1136 raise ValueError( _("Lines must be a list") )
1062 for _line in lines: 1137 for _line in lines:
1063 if not isinstance(_line, MeasureLine): 1138 if not isinstance(_line, MeasureLine):
1064 raise ValueError, _("Line must be a MeasureLine objetc") 1139 raise ValueError( _("Line must be a MeasureLine objetc") )
1065 self.__lines = lines 1140 self.__lines = lines
1141
1066 def getLabel(self): 1142 def getLabel(self):
1067 return self.__label 1143 return self.__label
1144
1068 def setLabel(self, label): 1145 def setLabel(self, label):
1069 self.__label = label 1146 self.__label = label
1147
1070 def setFactor(self, factor, decimals, recordType): 1148 def setFactor(self, factor, decimals, recordType):
1071 if not isinstance(factor, float): 1149 if not isinstance(factor, float):
1072 raise ValueError, utils.mapping(_("Factor must be a float number "\ 1150 raise ValueError( utils.mapping(_("Factor must be a float number "\
1073 "|$1|"), (factor,)) 1151 "|$1|"), (str(factor),)) )
1074 # TODO: test after 1152 # TODO: test after
1075 _DF = decimals.getDF(recordType) 1153 _DF = abs(decimals.getDF(recordType))
1076 factor = round(factor, _DF) 1154 factor = round(factor, _DF)
1077 self.__factor = factor 1155 self.__factor = factor
1078 1156
1079 def getFactor(self): 1157 def getFactor(self):
1080 return self.__factor 1158 return self.__factor
1081 1159
1082 def setYield(self, yield_, decimals, recordType): 1160 def setYield(self, yield_, decimals, recordType):
1083 if not isinstance(yield_, float): 1161 if not isinstance(yield_, float):
1084 raise ValueError, _("Yield must be a float number") 1162 raise ValueError( _("Yield must be a float number") )
1085 # TODO: test after 1163 # TODO: test after
1086 _DR = decimals.getDR(recordType) 1164 _DR = abs(decimals.getDR(recordType))
1087 yield_ = round(yield_, _DR) 1165 yield_ = round(yield_, _DR)
1088 self.__yield_ = yield_ 1166 self.__yield_ = yield_
1089 1167
1090 def getYield(self): 1168 def getYield(self):
1091 return self.__yield_ 1169 return self.__yield_
1092 1170
1093 def setFixed(self, fixed, decimals): 1171 def setFixed(self, fixed, decimals):
1094 if not isinstance(fixed, bool): 1172 if not isinstance(fixed, bool):
1095 raise ValueError, _("Fixed must be boolean object") 1173 raise ValueError( _("Fixed must be boolean object") )
1096 self.__fixed = fixed 1174 self.__fixed = fixed
1097 self.updateYield(decimals) 1175 self.updateYield(decimals)
1098 1176
1099 def getFixed(self): 1177 def getFixed(self):
1100 return self.__fixed 1178 return self.__fixed
1160 if type_ == "M": 1238 if type_ == "M":
1161 self.lines = _lines 1239 self.lines = _lines
1162 elif type_ == "A": 1240 elif type_ == "A":
1163 self.lines.extend(_lines) 1241 self.lines.extend(_lines)
1164 else: 1242 else:
1165 raise ValueError, utils.mapping(_("Type must be M or A. Type: $1"), 1243 raise ValueError( utils.mapping(_("Type must be M or A. Type: $1"),
1166 (type_,)) 1244 (str(type_),)) )
1167 self.calculateMeasure(decimals, recordType) 1245 self.calculateMeasure(decimals, recordType)
1168 1246
1169 def calculateMeasure(self, decimals, recordType): 1247 def calculateMeasure(self, decimals, recordType):
1170 #TODO: round acumulated_subtotal and parcial_subtotal 1248 #TODO: round acumulated_subtotal and parcial_subtotal
1171 if len(self.lines) > 0: 1249 if len(self.lines) > 0:
1179 elif line.lineType == 1: 1257 elif line.lineType == 1:
1180 _parcialSubtotal = _acumulated_total - _parcial_total 1258 _parcialSubtotal = _acumulated_total - _parcial_total
1181 line.setParcialSubtotal(_parcialSubtotal, decimals) 1259 line.setParcialSubtotal(_parcialSubtotal, decimals)
1182 _parcial_total = _acumulated_total 1260 _parcial_total = _acumulated_total
1183 self.setMeasure(_acumulated_total, decimals) 1261 self.setMeasure(_acumulated_total, decimals)
1184 _DR = decimals.getDR(recordType) 1262 _DR = abs(decimals.getDR(recordType))
1185 self.updateYield(decimals, recordType) 1263 self.updateYield(decimals, recordType)
1264
1186 def updateYield(self, decimals, recordType): 1265 def updateYield(self, decimals, recordType):
1187 if not self.fixed: 1266 if not self.fixed:
1188 self.setYield(self.measure, decimals, recordType) 1267 self.setYield(self.measure, decimals, recordType)
1189 1268
1190 class MeasureLine(object): 1269 class MeasureLine(object):
1215 Valid variable: 'a', 'b', 'c','d'y 'p' (Pi=3.1415926) 1294 Valid variable: 'a', 'b', 'c','d'y 'p' (Pi=3.1415926)
1216 "partial" : result of measure line 1295 "partial" : result of measure line
1217 "parcial_subtotal" 1296 "parcial_subtotal"
1218 "acumulated_subtotal" 1297 "acumulated_subtotal"
1219 Methods: 1298 Methods:
1220 __getstate__(self)
1221 __setstate__(self, tuple)
1222 __init__(self, decimals, type_, comment, units, length, width, height,
1223 formula)
1224 {get/set}LineType 1299 {get/set}LineType
1225 {get/set}Comment 1300 {get/set}Comment
1226 {get/set}Units 1301 {get/set}Units
1227 {get/set}Length 1302 {get/set}Length
1228 {get/set}Width 1303 {get/set}Width
1232 {get/set}ParcialSubtotal 1307 {get/set}ParcialSubtotal
1233 {get/set}AcumulatedSubtotal 1308 {get/set}AcumulatedSubtotal
1234 calculateParcial 1309 calculateParcial
1235 eval_formula 1310 eval_formula
1236 """ 1311 """
1312
1237 __slots__ = ["_MeasureLine__lineType", 1313 __slots__ = ["_MeasureLine__lineType",
1238 "_MeasureLine__comment", 1314 "_MeasureLine__comment",
1239 "_MeasureLine__units", 1315 "_MeasureLine__units",
1240 "_MeasureLine__length", 1316 "_MeasureLine__length",
1241 "_MeasureLine__width", 1317 "_MeasureLine__width",
1243 "_MeasureLine__formula", 1319 "_MeasureLine__formula",
1244 "_MeasureLine__parcial", 1320 "_MeasureLine__parcial",
1245 "_MeasureLine__parcial_subtotal", 1321 "_MeasureLine__parcial_subtotal",
1246 "_MeasureLine__acumulated_subtotal", 1322 "_MeasureLine__acumulated_subtotal",
1247 ] 1323 ]
1324
1248 def __getstate__ (self): 1325 def __getstate__ (self):
1249 return (self.__lineType, self.__comment, self.__units, 1326 return (self.__lineType, self.__comment, self.__units,
1250 self.__length, self.__width, self.__height, self.__formula, 1327 self.__length, self.__width, self.__height, self.__formula,
1251 self.__parcial) 1328 self.__parcial)
1329
1252 def __setstate__(self,tuple): 1330 def __setstate__(self,tuple):
1253 self.__lineType = tuple[0] 1331 self.__lineType = tuple[0]
1254 self.__comment = tuple[1] 1332 self.__comment = tuple[1]
1255 self.__units = tuple[2] 1333 self.__units = tuple[2]
1256 self.__length = tuple[3] 1334 self.__length = tuple[3]
1257 self.__width = tuple[4] 1335 self.__width = tuple[4]
1258 self.__height = tuple[5] 1336 self.__height = tuple[5]
1259 self.__formula = tuple[6] 1337 self.__formula = tuple[6]
1260 self.__parcial = tuple[7] 1338 self.__parcial = tuple[7]
1261 #self.calculateParcial() 1339 #self.calculateParcial()
1340
1262 def __init__(self, decimals, type_, comment, units, length, width, height, 1341 def __init__(self, decimals, type_, comment, units, length, width, height,
1263 formula): 1342 formula):
1264 self.__parcial = 0.0 1343 self.__parcial = 0.0
1265 self.__parcial_subtotal = 0.0 1344 self.__parcial_subtotal = 0.0
1266 self.__acumulated_subtotal = 0.0 1345 self.__acumulated_subtotal = 0.0
1270 self.setLength(length, decimals) 1349 self.setLength(length, decimals)
1271 self.setWidth(width, decimals) 1350 self.setWidth(width, decimals)
1272 self.setHeight(height, decimals) 1351 self.setHeight(height, decimals)
1273 self.setFormula(formula, decimals) 1352 self.setFormula(formula, decimals)
1274 #self.calculateParcial() 1353 #self.calculateParcial()
1354
1275 def getLineType(self): 1355 def getLineType(self):
1276 return self.__lineType 1356 return self.__lineType
1357
1277 def getComment(self): 1358 def getComment(self):
1278 return self.__comment 1359 return self.__comment
1360
1279 def getUnits(self): 1361 def getUnits(self):
1280 return self.__units 1362 return self.__units
1363
1281 def getLength(self): 1364 def getLength(self):
1282 return self.__length 1365 return self.__length
1366
1283 def getWidth(self): 1367 def getWidth(self):
1284 return self.__width 1368 return self.__width
1369
1285 def getHeight(self): 1370 def getHeight(self):
1286 return self.__height 1371 return self.__height
1372
1287 def getFormula(self): 1373 def getFormula(self):
1288 return self.__formula 1374 return self.__formula
1375
1289 def getParcial(self): 1376 def getParcial(self):
1290 return self.__parcial 1377 return self.__parcial
1378
1291 def getParcialSubtotal(self): 1379 def getParcialSubtotal(self):
1292 return self.__parcial_subtotal 1380 return self.__parcial_subtotal
1381
1293 def getAcumulatedSubtotal(self): 1382 def getAcumulatedSubtotal(self):
1294 return self.__acumulated_subtotal 1383 return self.__acumulated_subtotal
1384
1295 def setParcialSubtotal(self, parcial_subtotal, decimals): 1385 def setParcialSubtotal(self, parcial_subtotal, decimals):
1296 if not isinstance(parcial_subtotal, float): 1386 if not isinstance(parcial_subtotal, float):
1297 raise ValueError, utils.mapping(_(" Parcial Subtotal must be a "\ 1387 raise ValueError( utils.mapping(_(" Parcial Subtotal must be a "\
1298 "float number. Parcial: $1"), (str(parcial_subtotal),)) 1388 "float number. Parcial: $1"), (str(parcial_subtotal),)) )
1299 _DS = decimals.DS 1389 _DS = abs(decimals.DS)
1300 parcial_subtotal = round(parcial_subtotal, _DS) 1390 parcial_subtotal = round(parcial_subtotal, _DS)
1301 self.__parcial_subtotal = parcial_subtotal 1391 self.__parcial_subtotal = parcial_subtotal
1392
1302 def setAcumulatedSubtotal(self, acumulated_subtotal, decimals): 1393 def setAcumulatedSubtotal(self, acumulated_subtotal, decimals):
1303 if not isinstance(acumulated_subtotal, float): 1394 if not isinstance(acumulated_subtotal, float):
1304 raise ValueError, utils.mapping(_(" Acumulated Subtotal must be "\ 1395 raise ValueError( utils.mapping(_(" Acumulated Subtotal must be "\
1305 "a float number. Parcial: $1"), 1396 "a float number. Parcial: $1"),
1306 (str(acumulated_subtotal),)) 1397 (str(acumulated_subtotal),)) )
1307 _DS = decimals.DS 1398 _DS = abs(decimals.DS)
1308 acumulated_subtotal = round(acumulated_subtotal, _DS) 1399 acumulated_subtotal = round(acumulated_subtotal, _DS)
1309 self.__acumulated_subtotal = acumulated_subtotal 1400 self.__acumulated_subtotal = acumulated_subtotal
1401
1310 def calculateParcial(self, decimals): 1402 def calculateParcial(self, decimals):
1311 _DS = decimals.DS 1403 _DS = abs(decimals.DS)
1312 if self.lineType == 1 or self.lineType == 2: 1404 if self.lineType == 1 or self.lineType == 2:
1313 _parcial = 0.0 1405 _parcial = 0.0
1314 elif self.lineType == 0: # self.formula == "": 1406 elif self.lineType == 0: # self.formula == "":
1315 if isinstance(self.units, float): 1407 if isinstance(self.units, float):
1316 _a = self.units 1408 _a = self.units
1334 _parcial = round(_parcial, _DS) 1426 _parcial = round(_parcial, _DS)
1335 self.__parcial = _parcial 1427 self.__parcial = _parcial
1336 1428
1337 def setLineType(self, type_): 1429 def setLineType(self, type_):
1338 if not type_ in [0, 1, 2, 3]: 1430 if not type_ in [0, 1, 2, 3]:
1339 raise ValueError, utils.mapping(_("Invalid measure line type ($1)"), 1431 raise ValueError( utils.mapping(_("Invalid measure line type ($1)"),
1340 (str(type_),)) 1432 (str(type_),)) )
1341 self.__lineType = type_ 1433 self.__lineType = type_
1434
1342 def setComment(self, comment): 1435 def setComment(self, comment):
1343 if not isinstance(comment, str): 1436 if not isinstance(comment, str):
1344 raise ValueError, utils.mapping(_("Measure Comment must be a "\ 1437 raise ValueError( utils.mapping(_("Measure Comment must be a "\
1345 "string ($1)"), (str(comment),)) 1438 "string ($1)"), (str(comment),)) )
1346 self.__comment = comment 1439 self.__comment = comment
1440
1347 def setUnits(self, units, decimals): 1441 def setUnits(self, units, decimals):
1348 if units != "": 1442 if units != "":
1349 if not isinstance(units, float): 1443 if not isinstance(units, float):
1350 raise ValueError, utils.mapping(_("Invalid Measure Units ($1)"), 1444 raise ValueError( utils.mapping(_("Invalid Measure Units ($1)"),
1351 (str(units),)) 1445 (str(units),)) )
1352 _DN = decimals.DN 1446 _DN = abs(decimals.DN)
1353 units = round(units, _DN) 1447 units = round(units, _DN)
1354 self.__units = units 1448 self.__units = units
1355 try: 1449 try:
1356 self.calculateParcial(decimals) 1450 self.calculateParcial(decimals)
1357 except AttributeError: 1451 except AttributeError:
1358 pass 1452 pass
1453
1359 def setLength(self, length, decimals): 1454 def setLength(self, length, decimals):
1360 if length != "": 1455 if length != "":
1361 if not isinstance(length, float): 1456 if not isinstance(length, float):
1362 raise ValueError, utils.mapping(_("Invalid Measure length ($1)"), 1457 raise ValueError( utils.mapping(_("Invalid Measure length ($1)"),
1363 (str(units),)) 1458 (str(units),)) )
1364 _DD = decimals.DD 1459 _DD = abs(decimals.DD)
1365 length = round(length, _DD) 1460 length = round(length, _DD)
1366 self.__length = length 1461 self.__length = length
1367 try: 1462 try:
1368 self.calculateParcial(decimals) 1463 self.calculateParcial(decimals)
1369 except AttributeError: 1464 except AttributeError:
1370 pass 1465 pass
1466
1371 def setWidth(self, width, decimals): 1467 def setWidth(self, width, decimals):
1372 if width != "": 1468 if width != "":
1373 if not isinstance(width, float): 1469 if not isinstance(width, float):
1374 raise ValueError, utils.mapping(_("Invalid Measure Width ($1)"), 1470 raise ValueError( utils.mapping(_("Invalid Measure Width ($1)"),
1375 (str(units),)) 1471 (str(units),)) )
1376 _DD = decimals.DD 1472 _DD = abs(decimals.DD)
1377 width = round(width, _DD) 1473 width = round(width, _DD)
1378 self.__width = width 1474 self.__width = width
1379 try: 1475 try:
1380 self.calculateParcial(decimals) 1476 self.calculateParcial(decimals)
1381 except AttributeError: 1477 except AttributeError:
1382 pass 1478 pass
1479
1383 def setHeight(self, height, decimals): 1480 def setHeight(self, height, decimals):
1384 if height != "": 1481 if height != "":
1385 if not isinstance(height, float): 1482 if not isinstance(height, float):
1386 raise ValueError, utils.mapping(_("Invalid Measure Height ($1)"), 1483 raise ValueError( utils.mapping(_("Invalid Measure Height ($1)"),
1387 (str(height),)) 1484 (str(height),)) )
1388 _DD = decimals.DD 1485 _DD = abs(decimals.DD)
1389 height = round(height, _DD) 1486 height = round(height, _DD)
1390 self.__height = height 1487 self.__height = height
1391 try: 1488 try:
1392 self.calculateParcial(decimals) 1489 self.calculateParcial(decimals)
1393 except AttributeError: 1490 except AttributeError:
1394 pass 1491 pass
1492
1395 def setFormula(self, formula, decimals): 1493 def setFormula(self, formula, decimals):
1396 if not isinstance(formula, str): 1494 if not isinstance(formula, str):
1397 raise ValueError, utils.mapping(_("Formula must be a "\ 1495 raise ValueError( utils.mapping(_("Formula must be a "\
1398 "string ($1)"), (str(formula),)) 1496 "string ($1)"), (str(formula),)) )
1399 if re.match(".*[^0123456789\.()\+\-\*/\^abcdp ].*", formula): 1497 if re.match(".*[^0123456789\.()\+\-\*/\^abcdp ].*", formula):
1400 raise ValueError, utils.mapping(_("There is invalid characters"\ 1498 raise ValueError( utils.mapping(_("There is invalid characters"\
1401 "in formula ($1)"), (str(formula),)) 1499 "in formula ($1)"), (str(formula),)) )
1402 self.__formula = formula 1500 self.__formula = formula
1403 try: 1501 try:
1404 self.calculateParcial(decimals) 1502 self.calculateParcial(decimals)
1405 except AttributeError: 1503 except AttributeError:
1406 pass 1504 pass
1435 """) 1533 """)
1436 parcial_subtotal = property(getParcialSubtotal, 1534 parcial_subtotal = property(getParcialSubtotal,
1437 None, None, 1535 None, None,
1438 """Parcial subtotal 1536 """Parcial subtotal
1439 """) 1537 """)
1538
1440 def eval_formula(self): 1539 def eval_formula(self):
1441 """eval_formula() 1540 """eval_formula()
1442 1541
1443 formula: 1542 formula:
1444 Valid Operator: '(', ')', '+', '-', '*', '/' and '^' 1543 Valid Operator: '(', ')', '+', '-', '*', '/' and '^'
1460 if c == "": c = 0.0 1559 if c == "": c = 0.0
1461 if d == "": d = 0.0 1560 if d == "": d = 0.0
1462 try: 1561 try:
1463 a = float(a) 1562 a = float(a)
1464 except: 1563 except:
1465 raise ValueError, _("'a' value must be a float number") 1564 raise ValueError( _("'a' value must be a float number") )
1466 try: 1565 try:
1467 b = float(b) 1566 b = float(b)
1468 except: 1567 except:
1469 raise ValueError, _("'b' value must be a float number") 1568 raise ValueError( _("'b' value must be a float number") )
1470 try: 1569 try:
1471 c = float(c) 1570 c = float(c)
1472 except: 1571 except:
1473 raise ValueError, _("'c' value must be a float number") 1572 raise ValueError( _("'c' value must be a float number") )
1474 try: 1573 try:
1475 d = float(d) 1574 d = float(d)
1476 except: 1575 except:
1477 raise ValueError, _("'d' value must be a float number") 1576 raise ValueError( _("'d' value must be a float number") )
1478 # spaces are erased 1577 # spaces are erased
1479 formula.replace(" ","") 1578 formula.replace(" ","")
1480 # operators and varibles are replaced 1579 # operators and varibles are replaced
1481 formula = formula.replace("+", " + ") 1580 formula = formula.replace("+", " + ")
1482 formula = formula.replace("-", " - ") 1581 formula = formula.replace("-", " - ")
1500 _formula2 = _formula2 + oper 1599 _formula2 = _formula2 + oper
1501 _g ={"__builtins__":{}} 1600 _g ={"__builtins__":{}}
1502 try: 1601 try:
1503 return eval(_formula2, _g) 1602 return eval(_formula2, _g)
1504 except: 1603 except:
1505 raise ValueError, _("Invalid formula") 1604 raise ValueError( _("Invalid formula") )
1605
1506 1606
1507 class Decimals(object): 1607 class Decimals(object):
1508 """base.Decimals: 1608 """base.Decimals:
1509 1609
1510 Description: 1610 Description:
1585 direct costs of a unit of work (and auxiliar element). 1685 direct costs of a unit of work (and auxiliar element).
1586 Number of decimal places of the indirect costs. 1686 Number of decimal places of the indirect costs.
1587 Default: 2 decimal places. 1687 Default: 2 decimal places.
1588 "DIVISA": monetary unit. 1688 "DIVISA": monetary unit.
1589 Methods: 1689 Methods:
1590 __init__(DN=2, DD=2, DSP=2, DS=2,
1591 DFC=3, DFPU=3, DFUO=3, DFA=3,
1592 DRC=3, DRPU=3, DRUO=3, DRA=3,
1593 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2,
1594 DIR=2, DIRC=2, DCD=2,
1595 DIVISA="EUR")
1596 __getitem__(key)
1597 haskey(key) 1690 haskey(key)
1598 getD(recordtype) 1691 getD(recordtype)
1599 getDF(recordType) 1692 getDF(recordType)
1600 getDR(recordType) 1693 getDR(recordType)
1601 getDI(recordType) 1694 getDI(recordType)
1602 """ 1695 """
1603 # TODO: get/set methods 1696 # TODO: get/set methods
1697
1604 def __init__(self, 1698 def __init__(self,
1605 DN=2, DD=2, DSP=2, DS=2, 1699 DN=2, DD=2, DSP=2, DS=2,
1606 DFC=3, DFPU=3, DFUO=3, DFA=3, 1700 DFC=3, DFPU=3, DFUO=3, DFA=3,
1607 DRC=3, DRPU=3, DRUO=3, DRA=3, 1701 DRC=3, DRPU=3, DRUO=3, DRA=3,
1608 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2, 1702 DP=2, DC=2, DPU=2, DUO=2, DEA=2, DES=2,
1630 self.DES = DES 1724 self.DES = DES
1631 self.DIR = DIR 1725 self.DIR = DIR
1632 self.DIRC = DIRC 1726 self.DIRC = DIRC
1633 self.DCD = DCD 1727 self.DCD = DCD
1634 self.DIVISA = DIVISA 1728 self.DIVISA = DIVISA
1729
1635 def __getitem__(self, key): 1730 def __getitem__(self, key):
1636 return self.__dict__[key] 1731 return self.__dict__[key]
1732
1637 def haskey(self, key): 1733 def haskey(self, key):
1638 return key in self.__dict__ 1734 return key in self.__dict__
1735
1639 def getD(self, recordType): 1736 def getD(self, recordType):
1640 # DP: budget. 1737 # DP: budget.
1641 # DC: chapter and subcharter. 1738 # DC: chapter and subcharter.
1642 # DUO: unit. 1739 # DUO: unit.
1643 # DEA: auxiliar element. 1740 # DEA: auxiliar element.
1660 ): # simple element 1757 ): # simple element
1661 _decimal = self.DES 1758 _decimal = self.DES
1662 else: # unit type 0, subtipe ["EU", "EC", "EF", "PA"] 1759 else: # unit type 0, subtipe ["EU", "EC", "EF", "PA"]
1663 _decimal = self.DUO 1760 _decimal = self.DUO
1664 return _decimal 1761 return _decimal
1762
1665 def getDF(self, recordType): 1763 def getDF(self, recordType):
1666 # Factor: DF 1764 # Factor: DF
1667 # ->DFP: Budget 1765 # ->DFP: Budget
1668 # ->DFC: Chapter/Subchapter 1766 # ->DFC: Chapter/Subchapter
1669 # ->DFUO: Unit 1767 # ->DFUO: Unit
1679 if recordType.subtype == "PU": # unitary budget element 1777 if recordType.subtype == "PU": # unitary budget element
1680 _decimal = self.DFPU 1778 _decimal = self.DFPU
1681 else: # unit EU EC EF PA 1779 else: # unit EU EC EF PA
1682 _decimal = self.DFUO 1780 _decimal = self.DFUO
1683 return _decimal 1781 return _decimal
1782
1684 def getDR(self, recordType): 1783 def getDR(self, recordType):
1685 # Yield: DR 1784 # Yield: DR
1686 # ->DRP: Budget 1785 # ->DRP: Budget
1687 # ->DRC: Chapter/Subchapter 1786 # ->DRC: Chapter/Subchapter
1688 # ->DRUO: Unit 1787 # ->DRUO: Unit
1698 if recordType.subtype == "PU": # unitary budget element 1797 if recordType.subtype == "PU": # unitary budget element
1699 _decimal = self.DRPU 1798 _decimal = self.DRPU
1700 else: # unit 1799 else: # unit
1701 _decimal = self.DRUO 1800 _decimal = self.DRUO
1702 return _decimal 1801 return _decimal
1802
1703 def getDI(self, recordType): 1803 def getDI(self, recordType):
1704 # DIRC: budget, chapter and subcharter. 1804 # DIRC: budget, chapter and subcharter.
1705 # DIR: unit, auxiliar element. 1805 # DIR: unit, auxiliar element.
1706 _hierarchy = recordType.hierarchy 1806 _hierarchy = recordType.hierarchy
1707 _subtype = recordType.subtype 1807 _subtype = recordType.subtype
1714 # auxiliar element type 0 subitype "EA" 1814 # auxiliar element type 0 subitype "EA"
1715 # unit type 0, subtipe ["EU", "EC", "EF", "PA", "PU"] 1815 # unit type 0, subtipe ["EU", "EC", "EF", "PA", "PU"]
1716 _decimal = self.DIR 1816 _decimal = self.DIR
1717 return _decimal 1817 return _decimal
1718 1818
1819
1719 class Sheet(object): 1820 class Sheet(object):
1720 """base.Sheet: 1821 """base.Sheet:
1721 Description: 1822 Description:
1722 Sheet of conditions object 1823 Sheet of conditions object
1723 Constructor: 1824 Constructor:
1729 "sheet_dict": { <Field key> : { <Section key> : <Paragraph key>} 1830 "sheet_dict": { <Field key> : { <Section key> : <Paragraph key>}
1730 <Field key>: must be in Budget.SheetFields 1831 <Field key>: must be in Budget.SheetFields
1731 <Section key>: must be in Budget.SheetSections 1832 <Section key>: must be in Budget.SheetSections
1732 <Paragraph key>: must be in Budget.SheetParagraph 1833 <Paragraph key>: must be in Budget.SheetParagraph
1733 Methods: 1834 Methods:
1734 __getstate__(self)
1735 __setstate__(self, tuple)
1736 __init__(self, sheet_dict={})
1737 {get/set}Sheet_dict 1835 {get/set}Sheet_dict
1738 getFields 1836 getFields
1739 getSections 1837 getSections
1740 getParagraph 1838 getParagraph
1741 addField 1839 addField
1742 addSection 1840 addSection
1743 """ 1841 """
1744 __slots__ = ["_Sheet__sheet_dict"] 1842 __slots__ = ["_Sheet__sheet_dict"]
1843
1745 def __getstate__ (self): 1844 def __getstate__ (self):
1746 return (self.__sheet_dict,) 1845 return (self.__sheet_dict,)
1846
1747 def __setstate__(self,tuple): 1847 def __setstate__(self,tuple):
1748 self.__sheet_dict = tuple[0] 1848 self.__sheet_dict = tuple[0]
1849
1749 def __init__(self): 1850 def __init__(self):
1750 self.__sheet_dict = {} 1851 self.__sheet_dict = {}
1852
1751 def getSheet_dict(self): 1853 def getSheet_dict(self):
1752 return self.__sheet_dict 1854 return self.__sheet_dict
1855
1753 def setSheet_dict(self, sheet_dict): 1856 def setSheet_dict(self, sheet_dict):
1754 if not isinstance(sheet_dict, dict): 1857 if not isinstance(sheet_dict, dict):
1755 raise ValueError, _("sheet_dict must be a dictionay") 1858 raise ValueError( _("sheet_dict must be a dictionay") )
1756 self.__sheet_dict = sheet_dict 1859 self.__sheet_dict = sheet_dict
1860
1757 def getFields(self): 1861 def getFields(self):
1758 return self.sheet_dict.keys() 1862 return self.sheet_dict.keys()
1863
1759 def getSections(self, field): 1864 def getSections(self, field):
1760 if field in self.__sheet_dict: 1865 if field in self.__sheet_dict:
1761 return self.__sheet_dict[field].keys() 1866 return self.__sheet_dict[field].keys()
1762 else: 1867 else:
1763 return None 1868 return None
1869
1764 def getParagraph(self, field, section): 1870 def getParagraph(self, field, section):
1765 if (field in self.__sheet_dict and 1871 if (field in self.__sheet_dict and
1766 section in self.__sheet_dict[field]): 1872 section in self.__sheet_dict[field]):
1767 return self.__sheet_dict[field][section] 1873 return self.__sheet_dict[field][section]
1768 else: 1874 else:
1769 return None 1875 return None
1876
1770 def addField(self, field, section_dict): 1877 def addField(self, field, section_dict):
1771 if not isinstance(field, str): 1878 if not isinstance(field, str):
1772 raise ValueError, _("sheet field must be a string") 1879 raise ValueError( _("sheet field must be a string") )
1773 if not isinstance(section_dict, dict): 1880 if not isinstance(section_dict, dict):
1774 raise ValueError, _("section_dict must be a dictionary") 1881 raise ValueError( _("section_dict must be a dictionary") )
1775 self.__sheet_dict[field] = section_dict 1882 self.__sheet_dict[field] = section_dict
1883
1776 def addSection(self, field, section, paragraph): 1884 def addSection(self, field, section, paragraph):
1777 if not isinstance(field, str): 1885 if not isinstance(field, str):
1778 raise ValueError, _("sheet field must be a string") 1886 raise ValueError( _("sheet field must be a string") )
1779 if not isinstance(section, str): 1887 if not isinstance(section, str):
1780 raise ValueError, _("sheet section must be a string") 1888 raise ValueError( _("sheet section must be a string") )
1781 if not isinstance(paragraph, str): 1889 if not isinstance(paragraph, str):
1782 raise ValueError, _("sheet paragraph must be a string") 1890 raise ValueError( _("sheet paragraph must be a string") )
1783 if not field in self.__sheet_dict: 1891 if not field in self.__sheet_dict:
1784 self.addField(field, { }) 1892 self.addField(field, { })
1785 _field = self.__sheet_dict[field] 1893 _field = self.__sheet_dict[field]
1786 _field[section] = paragraph 1894 _field[section] = paragraph
1895
1787 sheet_dict = property(getSheet_dict, setSheet_dict, None, 1896 sheet_dict = property(getSheet_dict, setSheet_dict, None,
1788 """Sheet dictionary { <Field key> : { <Section key> : <Paragraph key>}""") 1897 """Sheet dictionary { <Field key> : { <Section key> : <Paragraph key>}""")
1898
1789 1899
1790 class Budget(object): 1900 class Budget(object):
1791 """base.Budget: 1901 """base.Budget:
1792 1902
1793 Description: 1903 Description:
1794 Budget objetc 1904 Budget object
1905 +-- __records: dictionary records { code : Record }
1906 +-- __synonyms: synonyms dictionary. TODO { "code" : ["synonym",],}
1907 Each record code can have synonym codes.
1908 +-- __root: the root record code
1909 +-- __decimals: List with the decimal places used to round the
1910 - result of the calculations with prices and measures
1911 - The values are Decimals objects
1912 - The <0> objets is the default Decimals (seted in FIEBDC-3),
1913 - The others keys are for the diferent groups of Prices
1914 +-- __percentages: percentages dictionary:
1915 { "CI" : "",
1916 "GG" : "",
1917 "BI" : "",
1918 "BAJA": "",
1919 "IVA" : ""}
1920 +-- __file_owner
1921 +-- __title_list: titles list: [ "Header", ["Title1", "Title2", ... ] ]
1922 List with the Headers and list of Titles for prices and
1923 decimal places.
1924 The Headers is the type of hierarchy of the prices
1925 Each Title have a group of Prices and a Decimals definition
1926 The records can have diferent prices for diferent ages, geografical
1927 places, ...
1928 +-- __title_index: A integer. The active group of Prices and Decimals.
1929 +-- __sheet_sections: sheet sections dictionary { sheet_code : sheet_title }
1930 +-- __sheet_fields: sheet fields dictionary { field_code : field_title }
1931 +-- __sheet_paragraphs: sheet paragraphs dictionary
1932 { paragraph_code : paragraph_text}
1933 +-- __companys: Dictionary whith companys object
1934 { company_code: company_object }
1935
1936 +-- __comment
1937 - +-- __date
1938 - +-- __budgetType" A integer. Type of data in budget
1939 - 0 -> Undefined
1940 - 1 -> Base data.
1941 - 2 -> Budget.
1942 - 3 -> Certificate.
1943 - 4 -> Base date update.
1944 - +-- __budgetCerficateOrder" Only valid if budgetType is 3.
1945 - +-- __budgetCerficateDate" Only valid if budgetType is 3
1946 - +-- __tec_info": Dictionary whith tecnical information
1947 - {ti_code : ["desciption text", "unit"]}
1948 - +-- __labels": Label dictionary { "label": [ "code", ], }
1949
1950
1795 Constructor: 1951 Constructor:
1796 base.Budget() 1952 base.Budget()
1797 Ancestry: 1953 Ancestry:
1798 +-- object 1954 +-- object
1799 +-- Budget 1955 +-- Budget
1800 Atributes: 1956 Atributes:
1801 "filename": file name of the budget file (FIEBDC) 1957 No public Atributes
1802 "__records": Dictionary with the budget records.
1803 { "code" : Record object, }
1804 "__synonyms": Dictionary with the records synonums.
1805 { "code" : ["synonym",],}
1806 Each record code can have synonym codes.
1807 "__root": The root record code.
1808 "__title_list": List with the Headers and list of Titles for prices and
1809 decimal places.
1810 [ "Header", ["Title1", "Title2", ... ] ]
1811 The records can have diferent prices for diferent ages, geografical
1812 places, ...
1813 The Headers is the type of hierarchy of the prices
1814 Each Title have a group of Prices and a Decimals definition
1815 "__decimals": List with the decimal places used to round the
1816 result of the calculations with prices and measures
1817 The values are Decimals objects
1818 The <0> objets is the default Decimals (seted in FIEBDC-3),
1819 The others keys are for the diferent groups of Prices
1820 "__percentages": Dictionary with the percentages
1821 keys:
1822 "CI" Indirect Cost
1823 "GG" General expenses
1824 "BI" Industrial benefit
1825 "BAJA" Low (what this do here?)
1826 "IVA" Tax
1827 "__file_owner"
1828 "__comment"
1829 "__date"
1830 "__budgetType" A integer. Type of data in budget
1831 0 -> Undefined
1832 1 -> Base data.
1833 2 -> Budget.
1834 3 -> Certificate.
1835 4 -> Base date update.
1836 "__budgetCerficateOrder" Only valid if budgetType is 3.
1837 "__budgetCerficateDate" Only valid if budgetType is 3
1838 "__title_index": A integer. The active group of Prices and Decimals.
1839 "__sheet_sections": Dictionary whith de sheet sections
1840 "__sheet_fields": Dictionary whith sheet fields
1841 "__sheet_paragraphs": Dictionary whith sheet paragraphs
1842 "__companys": Dictionary whith companys object
1843 { company_code: company_object }
1844 "__tec_info": Dictionary whith tecnical information
1845 {ti_code : ["desciption text", "unit"]}
1846 "__labels": Label dictionary { "label": [ "code", ], }
1847 Methods: 1958 Methods:
1848 iter 1959 iter
1849 iterPreOrder 1960 iterPreOrder
1850 iterPostOrder 1961 iterPostOrder
1851 getRoot(self) 1962 getRoot(self)
1909 setParametricSelectComment 2020 setParametricSelectComment
1910 setParametricSummary 2021 setParametricSummary
1911 setParametricText 2022 setParametricText
1912 """ 2023 """
1913 2024
1914
1915 def __init__(self): 2025 def __init__(self):
1916 """__init__(self) 2026 """__init__(self)
1917 2027
1918 Initialize the budget atributes 2028 Initialize the budget atributes
1919 """ 2029 """
2030 # title_index: A integer. The active group of Prices and Decimals.
2031 # TODO: change title_index
1920 self.__title_index = 0 2032 self.__title_index = 0
2033 # List with the decimal places used to round the
2034 # result of the calculations with prices and measures
2035 # The values are Decimals objects
2036 # The <0> objets is the default Decimals (seted in FIEBDC-3),
2037 # The others keys are for the diferent groups of Prices
1921 self.__decimals = [Decimals(), Decimals()] 2038 self.__decimals = [Decimals(), Decimals()]
2039 # Dictionary with the percentages
2040 # keys:
2041 # "CI" Indirect Cost
2042 # "GG" General expenses
2043 # "BI" Industrial benefit
2044 # "BAJA" Low (what this do here?)
2045 # "IVA" Tax
1922 self.__percentages = { "CI" : "" ,"GG": "", "BI": "", 2046 self.__percentages = { "CI" : "" ,"GG": "", "BI": "",
1923 "BAJA": "", "IVA" : ""} 2047 "BAJA": "", "IVA" : ""}
2048 # List with the Headers and list of Titles for prices and
2049 # decimal places.
2050 # [ "Header", ["Title1", "Title2", ... ] ]
2051 # The records can have diferent prices for diferent ages, geografical
2052 # places, ...
2053 # The Headers is the type of hierarchy of the prices
2054 # Each Title have a group of Prices and a Decimals definition
1924 self.__title_list = [ "", [ ] ] 2055 self.__title_list = [ "", [ ] ]
2056 # The root record code.
1925 self.__root = None 2057 self.__root = None
1926 self.__file_owner = "" 2058 self.__file_owner = ""
1927 self.__comment = "" 2059 self.__comment = ""
1928 self.__budgetCerficateOrder = None 2060 self.__budgetCerficateOrder = None # Only valid if budgetType is 3.
1929 self.__budgetCerficateDate = None 2061 self.__budgetCerficateDate = None # Only valid if budgetType is 3.
1930 self.__date = (0,0,0) 2062 self.__date = (0,0,0)
2063 # budgetType: A integer. Type of data in budget
2064 # 0 -> Undefined
2065 # 1 -> Base data.
2066 # 2 -> Budget.
2067 # 3 -> Certificate.
2068 # 4 -> Base date update.
1931 self.__budgetType = 0 2069 self.__budgetType = 0
2070 # Dictionary with the budget records: { "code" : Record object, }
1932 self.__records = { } 2071 self.__records = { }
2072 # Dictionary with the records synonyms.
2073 # { "code" : ["synonym",],}
2074 # Each record code can have synonym codes.
1933 self.__synonyms = { } 2075 self.__synonyms = { }
2076 # sheet_sections: Dictionary whith de sheet sections
1934 self.__sheet_sections = { } 2077 self.__sheet_sections = { }
2078 # sheet_fields: Dictionary whith sheet fields
1935 self.__sheet_fields = { } 2079 self.__sheet_fields = { }
2080 # sheet_paragraphs: Dictionary whith sheet paragraphs
1936 self.__sheet_paragraphs = { } 2081 self.__sheet_paragraphs = { }
2082 # companys: Dictionary whith companys object
2083 # { company_code: company_object }
1937 self.__companys = { } 2084 self.__companys = { }
2085 # tec_info: Dictionary whith tecnical information
2086 # {ti_code : ["desciption text", "unit"]}
1938 self.__tec_info = { } 2087 self.__tec_info = { }
2088 # labels: Label dictionary { "label": [ "code", ], }
1939 self.__labels = { } 2089 self.__labels = { }
1940 2090
1941 def __getstate__(self): 2091 def __getstate__(self):
1942 return (self.__title_index, self.__decimals, self.__percentages, 2092 return (self.__title_index, self.__decimals, self.__percentages,
1943 self.__title_list, self.__root, self.__file_owner, 2093 self.__title_list, self.__root, self.__file_owner,
1962 self.__labels = tuple[13] 2112 self.__labels = tuple[13]
1963 2113
1964 def iter(self): 2114 def iter(self):
1965 for record in self.__records: 2115 for record in self.__records:
1966 yield record 2116 yield record
2117
1967 def iterPreOrder(self, recordCode, codes=None): 2118 def iterPreOrder(self, recordCode, codes=None):
1968 if codes is None: 2119 if codes is None:
1969 codes = [] 2120 codes = []
1970 _children = self.getchildren(recordCode) 2121 _children = self.getchildren(recordCode)
1971 for _child in _children: 2122 for _child in _children:
1972 if not _child in codes: 2123 if not _child in codes:
1973 codes.append(_child) 2124 codes.append(_child)
1974 self.iterPreOrder(_child, codes) 2125 self.iterPreOrder(_child, codes)
1975 return codes 2126 return codes
2127
1976 def iterPostOrder(self, recordCode, codes=None): 2128 def iterPostOrder(self, recordCode, codes=None):
1977 if codes is None: 2129 if codes is None:
1978 codes = [] 2130 codes = []
1979 _children = self.getchildren(recordCode) 2131 _children = self.getchildren(recordCode)
1980 for _child in _children: 2132 for _child in _children:
2010 """ 2162 """
2011 _record = self.__records[code] 2163 _record = self.__records[code]
2012 _children = _record.children 2164 _children = _record.children
2013 _child_code = [ _child.code for _child in _children ] 2165 _child_code = [ _child.code for _child in _children ]
2014 return _child_code 2166 return _child_code
2167
2015 def setOwner(self, owner): 2168 def setOwner(self, owner):
2016 """setOwner(self, owner) 2169 """setOwner(self, owner)
2017 2170
2018 owner: data owner 2171 owner: data owner
2019 Set the data owner. 2172 Set the data owner.
2020 """ 2173 """
2021 if isinstance(owner, basestring): 2174 if isinstance(owner, basestring):
2022 self.__file_owner = owner 2175 self.__file_owner = owner
2023 else: 2176 else:
2024 raise TypeError, _("Owner must be a string") 2177 raise TypeError( _("Owner must be a string") )
2025 2178
2026 def setDate(self, date): 2179 def setDate(self, date):
2027 """setOwner(self, date) 2180 """setOwner(self, date)
2028 2181
2029 date (_y, _m, _d) 2182 date (_y, _m, _d)
2035 date[2] in range(32): 2188 date[2] in range(32):
2036 if date[1] != 0 and date[2] != 0: 2189 if date[1] != 0 and date[2] != 0:
2037 datetime.date(*date) 2190 datetime.date(*date)
2038 self.__date = date 2191 self.__date = date
2039 else: 2192 else:
2040 raise TypeError, utils.mapping(_("Invalid Date: $1"),(str(date),)) 2193 raise TypeError( utils.mapping(_("Invalid Date: $1"),(str(date),)) )
2041 2194
2042 def setComment(self, comment): 2195 def setComment(self, comment):
2043 """setOwner(self, comment) 2196 """setOwner(self, comment)
2044 2197
2045 comment: text to comment the budged 2198 comment: text to comment the budged
2046 Set the comment. 2199 Set the comment.
2047 """ 2200 """
2048 if isinstance(comment, basestring): 2201 if isinstance(comment, basestring):
2049 self.__comment = comment 2202 self.__comment = comment
2050 else: 2203 else:
2051 raise TypeError, _("Comment must be a string") 2204 raise TypeError( _("Comment must be a string") )
2052 2205
2053 def setBudgeType(self, budget_type): 2206 def setBudgeType(self, budget_type):
2054 """setOwner(self, budget_type) 2207 """setOwner(self, budget_type)
2055 2208
2056 budget_type: type of data in budget 2209 budget_type: type of data in budget
2062 Set the budget type. 2215 Set the budget type.
2063 """ 2216 """
2064 if budget_type in [1, 2, 3, 4]: 2217 if budget_type in [1, 2, 3, 4]:
2065 self.__budgetType = budget_type 2218 self.__budgetType = budget_type
2066 else: 2219 else:
2067 raise ValueError, _("Budget type must be 1, 2, 3 or 4.") 2220 raise ValueError( _("Budget type must be 1, 2, 3 or 4.") )
2068 2221
2069 def setCertificateOrder(self, certificate_order, certificate_date): 2222 def setCertificateOrder(self, certificate_order, certificate_date):
2070 """setOwner(self, budget_type) 2223 """setOwner(self, budget_type)
2071 2224
2072 certificate_order: certificate number 2225 certificate_order: certificate number
2073 certificate_date: certificate date 2226 certificate_date: certificate date
2074 Set the certificate order and date. 2227 Set the certificate order and date.
2075 """ 2228 """
2076 if isinstance(certificate_order, int): 2229 if isinstance(certificate_order, int):
2077 self.__budgetCerficateOrder = certificate_order 2230 self.__budgetCerficateOrder = certificate_order
2078 else: 2231 else:
2079 raise ValueError, _("Certificate order must be a integer.") 2232 raise ValueError( _("Certificate order must be a integer.") )
2080 2233
2081 def setCertificateDater(self, certificate_date): 2234 def setCertificateDater(self, certificate_date):
2082 """setCertidicateDate(self, certificate_date) 2235 """setCertidicateDate(self, certificate_date)
2083 2236
2084 Set the certificate date. 2237 Set the certificate date.
2089 isinstance(certificate_date[1], int) and \ 2242 isinstance(certificate_date[1], int) and \
2090 isinstance(certificate_date[2], int): 2243 isinstance(certificate_date[2], int):
2091 datetime.date(*certificate_date) 2244 datetime.date(*certificate_date)
2092 self.__budgetCerficateDate = certificate_date 2245 self.__budgetCerficateDate = certificate_date
2093 else: 2246 else:
2094 raise ValueError, _("Budget certificate Date must be a valid Date.") 2247 raise ValueError( _("Budget certificate Date must be a valid Date.") )
2095 2248
2096 def setTitleList(self, title_list): 2249 def setTitleList(self, title_list):
2097 """setTitleList(self, title_list) 2250 """setTitleList(self, title_list)
2098 2251
2099 title_list: [ "Header", ["Title1", "Title2", ... ] ] 2252 title_list: [ "Header", ["Title1", "Title2", ... ] ]
2103 if isinstance(title_list, list) and isinstance(title_list[1], list): 2256 if isinstance(title_list, list) and isinstance(title_list[1], list):
2104 for i in range(len(title_list[1])): 2257 for i in range(len(title_list[1])):
2105 title_list[1][i] = str(title_list[1][i]) 2258 title_list[1][i] = str(title_list[1][i])
2106 self.__title_list = title_list 2259 self.__title_list = title_list
2107 else: 2260 else:
2108 raise TypeError, _("Invalid title list format") 2261 raise TypeError( _("Invalid title list format") )
2109 2262
2110 def getTitleList(self): 2263 def getTitleList(self):
2111 """ getTitleList(self) 2264 """ getTitleList(self)
2112 2265
2113 Returns the header and titles for the price groups and decimals. 2266 Returns the header and titles for the price groups and decimals.
2132 _default_decimals = self.__decimals[0] 2285 _default_decimals = self.__decimals[0]
2133 self.__decimals.append(_default_decimals) 2286 self.__decimals.append(_default_decimals)
2134 elif N < len(self.__decimals): 2287 elif N < len(self.__decimals):
2135 _default_decimals = self.__decimals[N] 2288 _default_decimals = self.__decimals[N]
2136 else: 2289 else:
2137 raise IndexError, _("Invalid Index Title") 2290 raise IndexError( _("Invalid Index Title") )
2138 for _decimal in dictionary: 2291 for _decimal in dictionary:
2139 if dictionary[_decimal] == "": 2292 if dictionary[_decimal] == "":
2140 dictionary[_decimal] = eval("_default_decimals." + _decimal) 2293 dictionary[_decimal] = eval("_default_decimals." + _decimal)
2141 decimals = Decimals(dictionary["DN"], dictionary["DD"], 2294 decimals = Decimals(dictionary["DN"], dictionary["DD"],
2142 dictionary["DSP"], dictionary["DS"], 2295 dictionary["DSP"], dictionary["DS"],
2149 dictionary["DUO"], dictionary["DEA"], 2302 dictionary["DUO"], dictionary["DEA"],
2150 dictionary["DES"], dictionary["DIR"], 2303 dictionary["DES"], dictionary["DIR"],
2151 dictionary["DIRC"], dictionary["DCD"], 2304 dictionary["DIRC"], dictionary["DCD"],
2152 dictionary["DIVISA"]) 2305 dictionary["DIVISA"])
2153 self.__decimals[N] = decimals 2306 self.__decimals[N] = decimals
2307
2154 def getDecimals(self, decimal=None, N=None): 2308 def getDecimals(self, decimal=None, N=None):
2155 """getDecimals(self,decimal="All",N=None) 2309 """getDecimals(self,decimal="All",N=None)
2156 2310
2157 decimal: 2311 decimal:
2158 "All": Return a Decimals objet for a price group 2312 "All": Return a Decimals objet for a price group
2168 elif decimal == "keys": 2322 elif decimal == "keys":
2169 return self.__decimals[N+1].keys 2323 return self.__decimals[N+1].keys
2170 elif self.__decimals[N+1].haskey(decimal): 2324 elif self.__decimals[N+1].haskey(decimal):
2171 return self.__decimals[N+1][decimal] 2325 return self.__decimals[N+1][decimal]
2172 else: 2326 else:
2173 raise KeyError, _("Decimal Key error") 2327 raise KeyError( _("Decimal Key error") )
2174 2328
2175 def setPercentages(self, dictionary): 2329 def setPercentages(self, dictionary):
2176 """setPercentages(self, dictionary): 2330 """setPercentages(self, dictionary):
2177 2331
2178 dictionary: the percentage dictionary 2332 dictionary: the percentage dictionary
2206 elif key == "keys": 2360 elif key == "keys":
2207 return self.__percentages.keys 2361 return self.__percentages.keys
2208 elif key in self.__percentages: 2362 elif key in self.__percentages:
2209 return self.__percentages[key] 2363 return self.__percentages[key]
2210 else: 2364 else:
2211 raise KeyError, _("Invalid Percentage key") 2365 raise KeyError( _("Invalid Percentage key") )
2212 2366
2213 def getAllParents(self,code): 2367 def getAllParents(self,code):
2214 """getAllParents(self,code) 2368 """getAllParents(self,code)
2215 2369
2216 code: a record code. 2370 code: a record code.
2278 _measure = _decomposition.budgetMeasures[0] 2432 _measure = _decomposition.budgetMeasures[0]
2279 return _measure 2433 return _measure
2280 2434
2281 def getStrYield(self, measure, recordType): 2435 def getStrYield(self, measure, recordType):
2282 #_DR = measure.getDR(self.getDecimals()) 2436 #_DR = measure.getDR(self.getDecimals())
2283 _DR = self.getDecimals().getDR(recordType) 2437 _DR = abs(self.getDecimals().getDR(recordType))
2284 _yield = ("%." + str(_DR) + "f" ) % measure.yield_ 2438 _yield = ("%." + str(_DR) + "f" ) % measure.yield_
2285 return _yield 2439 return _yield
2286 2440
2287 def getStrFactor(self, measure, recorType): 2441 def getStrFactor(self, measure, recorType):
2288 _DF = self.getDecimals().getDF(recordType) 2442 _DF = abs(self.getDecimals().getDF(recordType))
2289 #_DF = measure.getDF(self.getDecimals()) 2443 #_DF = measure.getDF(self.getDecimals())
2290 _factor = ("%." + str(_DF) + "f" ) % measure.factor 2444 _factor = ("%." + str(_DF) + "f" ) % measure.factor
2291 return _factor 2445 return _factor
2292 2446
2293 def setTree(self, code, child_code, position, factor, yield_, total, 2447 def setTree(self, code, child_code, position, factor, yield_, total,
2323 Sets the decomposition of a record in a child record 2477 Sets the decomposition of a record in a child record
2324 """ 2478 """
2325 if code is None: # No-estructured measures 2479 if code is None: # No-estructured measures
2326 code = self.getRoot() 2480 code = self.getRoot()
2327 if code == None: # No root 2481 if code == None: # No root
2328 print "No-estructured measures. Adding root record", 2482 print( "No-estructured measures. Adding root record " +
2329 self.setRecord("root", [], 0, "", "", [0.0,], [(1,1,1970)], 2483 str(self.setRecord("root", [], 0, "", "", [0.0,], [(1,1,1970)],
2330 0, "") 2484 0, "") ))
2331 code = self.getRoot() 2485 code = self.getRoot()
2332 2486
2333 if not utils.is_valid_code(code)[0]: 2487 if not utils.is_valid_code(code)[0]:
2334 raise ValueError, utils.mapping(_("Invalid parent code: $1"), 2488 raise ValueError( utils.mapping(_("Invalid parent code: $1"),
2335 (code,)) 2489 (str(code),)) )
2336 if not utils.is_valid_code(child_code)[0]: 2490 if not utils.is_valid_code(child_code)[0]:
2337 raise ValueError, utils.mapping(_("Invalid child code: $1 $2"), 2491 raise ValueError( utils.mapping(_("Invalid child code: $1 $2"),
2338 (code,child_code)) 2492 (str(code),str(child_code))) )
2339 if not isinstance(position, int): 2493 if not isinstance(position, int):
2340 raise ValueError, utils.mapping(_("Invalid position in measure "\ 2494 raise ValueError( utils.mapping(_("Invalid position in measure "\
2341 "$1, in code $2"), (parent_code, position)) 2495 "$1, in code $2"), (str(parent_code), str(position))) )
2342 # Test circular references 2496 # Test circular references
2343 _all_parent_list = self.getAllParents(code) + [ code ] 2497 _all_parent_list = self.getAllParents(code) + [ code ]
2344 _all_child_list = self.getAllchildren(child_code) + [ child_code ] 2498 _all_child_list = self.getAllchildren(child_code) + [ child_code ]
2345 for _parent_code in _all_parent_list: 2499 for _parent_code in _all_parent_list:
2346 if _parent_code in _all_child_list: 2500 if _parent_code in _all_child_list:
2347 # TODO: change return to except 2501 # TODO: change return to except
2348 print utils.mapping(_("Circular Decomposition, parent code: "\ 2502 print(utils.mapping(_("Circular Decomposition, parent code: "\
2349 "$1, child code: $2, repeated code: $3"), 2503 "$1, child code: $2, repeated code: $3"),
2350 (code, child_code, _parent_code)) 2504 (str(code), str(child_code), str(_parent_code))) )
2351 return 2505 return
2352 2506
2353 # Creating reference to parent code in child record 2507 # Creating reference to parent code in child record
2354 if child_code in self.__records: 2508 if child_code in self.__records:
2355 _child_record = self.__records[child_code] 2509 _child_record = self.__records[child_code]
2368 position = _child_number 2522 position = _child_number
2369 if position == -2: # No-estructured measures or empty position (error in FIEBDC file) 2523 if position == -2: # No-estructured measures or empty position (error in FIEBDC file)
2370 positions = _record.getChildPositions(child_code) 2524 positions = _record.getChildPositions(child_code)
2371 if len(positions) == 1: 2525 if len(positions) == 1:
2372 position = positions[0] 2526 position = positions[0]
2373 print utils.mapping(_("No-estructured measure or empty position. Parent Code: "\ 2527 print(utils.mapping(_("No-estructured measure or empty position. Parent Code: "\
2374 "$1, Child code: $2, Position: $3"),(code, child_code, position)) 2528 "$1, Child code: $2, Position: $3"),(str(code), str(child_code), str(position))) )
2375 else: 2529 else:
2376 position = _child_number 2530 position = _child_number
2377 print utils.mapping(_("No-estructured measure or empty position. "\ 2531 print(utils.mapping(_("No-estructured measure or empty position. "\
2378 "Repeated child in unspecified position. "\ 2532 "Repeated child in unspecified position. "\
2379 "It is impossible to determine the position. "\ 2533 "It is impossible to determine the position. "\
2380 "New child is added in the decomposition. "\ 2534 "New child is added in the decomposition. "\
2381 "Parent code: $1, Child code: $2, Position: $3"),(code, child_code, position)) 2535 "Parent code: $1, Child code: $2, Position: $3"),(str(code), str(child_code), str(position))) )
2382 if position == _child_number: 2536 if position == _child_number:
2383 # The record do not have the child 2537 # The record do not have the child
2384 if not isinstance(factor, float): factor = 1.0 2538 if not isinstance(factor, float): factor = 1.0
2385 if not isinstance(yield_, float): yield_ = 1.0 2539 if not isinstance(yield_, float): yield_ = 1.0
2386 if not isinstance(total, float): total = 0.0 2540 if not isinstance(total, float): total = 0.0
2412 _record.recordType) 2566 _record.recordType)
2413 if isinstance(label, str) and label != "" : 2567 if isinstance(label, str) and label != "" :
2414 _measure.label = label 2568 _measure.label = label
2415 else: 2569 else:
2416 # TODO: change return for except 2570 # TODO: change return for except
2417 print utils.mapping(_("Error: Invalid child position in " 2571 print(utils.mapping(_("Error: Invalid child position in "
2418 "decomposition. Parent code: $1 Child code: $2 "\ 2572 "decomposition. Parent code: $1 Child code: $2 "\
2419 "Position: $3"), (code, child_code, position)) 2573 "Position: $3"), (str(code), str(child_code), str(position))) )
2420 return 2574 return
2421 else: 2575 else:
2422 if child_code == "" : 2576 if child_code == "" :
2423 print utils.mapping(_("Error: Empty child code. Parent code: "\ 2577 print(utils.mapping(_("Error: Empty child code. Parent code: "\
2424 "$1 Position: $2"), (code, position)) 2578 "$1 Position: $2"), (str(code), str(position))) )
2425 return 2579 return
2426 if position == -1: 2580 if position == -1:
2427 position = 0 2581 position = 0
2428 elif position != 0: 2582 elif position != 0:
2429 print utils.mapping(_("Error: Invalid child position in "\ 2583 print(utils.mapping(_("Error: Invalid child position in "\
2430 "decomposition. Parent code: $1 Child code: $2 "\ 2584 "decomposition. Parent code: $1 Child code: $2 "\
2431 "Position: $3"), (code, child_code, position)) 2585 "Position: $3"), (str(code), str(child_code), str(position))) )
2432 return 2586 return
2433 if not isinstance(factor, float): 2587 if not isinstance(factor, float):
2434 factor = 1.0 2588 factor = 1.0
2435 if not isinstance(yield_, float): 2589 if not isinstance(yield_, float):
2436 yield_ = 1.0 2590 yield_ = 1.0
2459 if c == "": c = 0.0 2613 if c == "": c = 0.0
2460 if d == "": d = 0.0 2614 if d == "": d = 0.0
2461 try: 2615 try:
2462 a = float(a) 2616 a = float(a)
2463 except: 2617 except:
2464 raise ValueError, _("'a' value must be a float number") 2618 raise ValueError( _("'a' value must be a float number") )
2465 try: 2619 try:
2466 b = float(b) 2620 b = float(b)
2467 except: 2621 except:
2468 raise ValueError, _("'b' value must be a float number") 2622 raise ValueError( _("'b' value must be a float number") )
2469 try: 2623 try:
2470 c = float(c) 2624 c = float(c)
2471 except: 2625 except:
2472 raise ValueError, _("'c' value must be a float number") 2626 raise ValueError( _("'c' value must be a float number") )
2473 try: 2627 try:
2474 d = float(d) 2628 d = float(d)
2475 except: 2629 except:
2476 raise ValueError, _("'d' value must be a float number") 2630 raise ValueError( _("'d' value must be a float number") )
2477 # spaces are erased 2631 # spaces are erased
2478 sre.sub("[ ]","",formula) 2632 sre.sub("[ ]","",formula)
2479 # operators and varibles are replaced 2633 # operators and varibles are replaced
2480 formula = formula.replace("+", " + ") 2634 formula = formula.replace("+", " + ")
2481 formula = formula.replace("-", " - ") 2635 formula = formula.replace("-", " - ")
2499 _formula2 = _formula2 + oper 2653 _formula2 = _formula2 + oper
2500 _g = {"__builtins__":{}} 2654 _g = {"__builtins__":{}}
2501 try: 2655 try:
2502 return eval(_formula2, _g) 2656 return eval(_formula2, _g)
2503 except: 2657 except:
2504 raise ValueError, _("Invalid formula") 2658 raise ValueError( _("Invalid formula") )
2505 2659
2506 def getText(self,code): 2660 def getText(self,code):
2507 """getText(self,code) 2661 """getText(self,code)
2508 2662
2509 code: the record code 2663 code: the record code
2510 Returns the description text of a record 2664 Returns the description text of a record
2511 """ 2665 """
2512 if code in self.__records: 2666 if code in self.__records:
2513 return self.__records[code].text 2667 return self.__records[code].text
2514 else: 2668 else:
2515 raise IndexError, _("Invalid code") 2669 raise IndexError( _("Invalid code") )
2516 2670
2517 def setText(self,code,text): 2671 def setText(self,code,text):
2518 """setText(self,code,text) 2672 """setText(self,code,text)
2519 2673
2520 code: the parent record code 2674 code: the parent record code
2521 text: the descripion text 2675 text: the descripion text
2522 Sests the description text of a record 2676 Sests the description text of a record
2523 """ 2677 """
2524 if not utils.is_valid_code(code)[0]: 2678 if not utils.is_valid_code(code)[0]:
2525 raise ValueError, utils.mapping(_("Invalid record: $1"), (code,)) 2679 raise ValueError( utils.mapping(_("Invalid record: $1"), (str(code),)) )
2526 if not code in self.__records: 2680 if not code in self.__records:
2527 _record = self.setRecord(code, [], "", "", "", [], [], 2681 _record = self.setRecord(code, [], "", "", "", [], [],
2528 "", "") 2682 "", "")
2529 _record.text = text 2683 _record.text = text
2530 else: 2684 else:
2583 if hierarchy == 0 : 2737 if hierarchy == 0 :
2584 # is the root record 2738 # is the root record
2585 if self.__root is None: 2739 if self.__root is None:
2586 self.__root = code 2740 self.__root = code
2587 else: 2741 else:
2588 print _("Only can be one root record") 2742 print(_("Only can be one root record") )
2589 return 2743 return
2590 # TODO: If the root is created in settree. No-estructured measures 2744 # TODO: If the root is created in settree. No-estructured measures
2591 # TODO Rewrite root values 2745 # TODO Rewrite root values
2592 # retake previous values. 2746 # retake previous values.
2593 # TODO: test synonyms 2747 # TODO: test synonyms
2657 - must be a list with two items 2811 - must be a list with two items
2658 - the first item: price must be a float 2812 - the first item: price must be a float
2659 """ 2813 """
2660 record.addPrice(price_date, self.getDecimals()) 2814 record.addPrice(price_date, self.getDecimals())
2661 2815
2662 def getStrPriceFromRecord(self, index_price, record): 2816 def getStrPriceFromRecord(self, index_price, record, path):
2663 _price = record.getPrice(index_price) 2817 if record.isPercentage():
2664 _D = self.getDecimals().getD(record.recordType) 2818 _percentageMasq = record.percentageMasq()
2819 _parent_code = self.getCode(path[:-1])
2820 _N_record = path[-1]
2821 _amount_sum = 0.0
2822 for N,_code in enumerate(self.getchildren(_parent_code)[:_N_record]):
2823 _child_record = self.getRecord(_code)
2824 if _child_record.hasPercentageMasq(_percentageMasq):
2825 _path = path[:-1] + (N,)
2826 _amount = self.getAmount(_path)
2827 _amount_sum = _amount_sum + _amount
2828 _price = _amount_sum
2829 else:
2830 _price = record.getPrice(index_price)
2831 _D = abs(self.getDecimals().getD(record.recordType))
2665 _price = ("%." + str(_D) + "f" ) % _price 2832 _price = ("%." + str(_D) + "f" ) % _price
2666 return _price 2833 return _price
2667 2834
2668 def getCode(self, path): 2835 def getCode(self, path):
2669 """getCode(self, path) 2836 """getCode(self, path)
2679 _record = self.__records[_code] 2846 _record = self.__records[_code]
2680 _children_list = _record.children 2847 _children_list = _record.children
2681 try: 2848 try:
2682 _child = _children_list[i] 2849 _child = _children_list[i]
2683 except: 2850 except:
2684 raise ValueError, _("This record does not exits") 2851 raise ValueError( _("This record does not exits") )
2685 _code = _child.code 2852 _code = _child.code
2686 else: 2853 else:
2687 raise ValueError, _("Path item must be a integer") 2854 raise ValueError( _("Path item must be a integer") )
2688 return _code 2855 return _code
2689 else: 2856 else:
2690 raise ValueError, _("This record does not exits") 2857 raise ValueError( _("This record does not exits") )
2691 else: 2858 else:
2692 raise ValueError, utils.mapping(_("Path must be a not empty "\ 2859 raise ValueError( utils.mapping(_("Path must be a not empty "\
2693 "tuple: $1"), (str(path),)) 2860 "tuple: $1"), (str(path),)) )
2694 2861
2695 def getAmount(self, path): 2862 def getAmount(self, path):
2696 """def getAmount(self,path) 2863 """def getAmount(self,path)
2697 2864
2698 path: record path 2865 path: record path
2699 Calculate the record amount 2866 Calculate the record amount
2700 """ 2867 """
2868
2701 if len(path) == 1: 2869 if len(path) == 1:
2702 # root: amount is the root price 2870 # root: amount is the root price
2703 _root = self.getRecord(self.getRoot()) 2871 _root = self.getRecord(self.getRoot())
2704 _amount = _root.getPrice(self.__title_index) 2872 _amount = _root.getPrice(self.__title_index)
2705 return _amount 2873 return _amount
2711 _decomposition = _parent_record.children[_child_number] 2879 _decomposition = _parent_record.children[_child_number]
2712 _factor = _decomposition.budgetMeasures[0].factor 2880 _factor = _decomposition.budgetMeasures[0].factor
2713 _yield = _decomposition.budgetMeasures[0].yield_ 2881 _yield = _decomposition.budgetMeasures[0].yield_
2714 _child_code = _decomposition.code 2882 _child_code = _decomposition.code
2715 _child_record = self.getRecord(_child_code) 2883 _child_record = self.getRecord(_child_code)
2716 _price = _child_record.getPrice(self.getActiveTitle()) 2884 _code = self.getCode(path)
2717 _DR = self.getDecimals().getDR(_parent_record.recordType) 2885 _record = self.getRecord(_code)
2886 if _record.isPercentage():
2887 _percentageMasq = _record.percentageMasq()
2888 _N_record = path[-1]
2889 _amount_sum = 0.0
2890 for N,_code in enumerate(self.getchildren(_parent_code)[:_N_record]):
2891 _child_record = self.getRecord(_code)
2892 if _child_record.hasPercentageMasq(_percentageMasq):
2893 _path = path[:-1] + (N,)
2894 _amount = self.getAmount(_path)
2895 _amount_sum = _amount_sum + _amount
2896 _price = _amount_sum
2897 else:
2898 _price = _child_record.getPrice(self.getActiveTitle())
2899
2900 _DR = abs(self.getDecimals().getDR(_parent_record.recordType))
2718 _total_yield = round(_factor * _yield, _DR) 2901 _total_yield = round(_factor * _yield, _DR)
2719 _DI = self.getDecimals().getDI(_parent_record.recordType) 2902 _DI = abs(self.getDecimals().getDI(_parent_record.recordType))
2720 _amount = round(_total_yield * _price, _DI) 2903 _amount = round(_total_yield * _price, _DI)
2721 return _amount 2904 return _amount
2722 2905
2723 def getStrAmount(self, path): 2906 def getStrAmount(self, path):
2724 """def getStrAmount(self, path) 2907 """def getStrAmount(self, path)
2726 path: record path 2909 path: record path
2727 Calculate the string record amount 2910 Calculate the string record amount
2728 """ 2911 """
2729 if len(path) == 1: #root 2912 if len(path) == 1: #root
2730 _root = self.getRecord(self.getRoot()) 2913 _root = self.getRecord(self.getRoot())
2731 _amount = self.getStrPriceFromRecord(self.__title_index, _root) 2914 _amount = self.getStrPriceFromRecord(self.__title_index, _root, path)
2732 return _amount 2915 return _amount
2733 else: 2916 else:
2734 _parent_code = self.getCode(path[:-1]) 2917 _parent_code = self.getCode(path[:-1])
2735 _parent_record = self.getRecord(_parent_code) 2918 _parent_record = self.getRecord(_parent_code)
2736 _amount = self.getAmount(path) 2919 _amount = self.getAmount(path)
2737 _DI = self.getDecimals().getDI(_parent_record.recordType) 2920 _DI = abs(self.getDecimals().getDI(_parent_record.recordType))
2738 _amount = ("%." + str(_DI) + "f") % _amount 2921 _amount = ("%." + str(_DI) + "f") % _amount
2739 return _amount 2922 return _amount
2740 2923
2741 def setSheetSection(self,sheet_code,sheet_title): 2924 def setSheetSection(self,sheet_code,sheet_title):
2742 if not isinstance(sheet_code, str): 2925 if not isinstance(sheet_code, str):
2743 raise ValueError, _("The sheet code must be a string") 2926 raise ValueError( _("The sheet code must be a string") )
2744 if not isinstance(sheet_title, str): 2927 if not isinstance(sheet_title, str):
2745 raise ValueError, _("The sheet title must be a string") 2928 raise ValueError( _("The sheet title must be a string") )
2746 self.__sheet_sections[sheet_code] = sheet_title 2929 self.__sheet_sections[sheet_code] = sheet_title
2930
2747 def hasSheetSection(self, section): 2931 def hasSheetSection(self, section):
2748 return section in self.__sheet_sections 2932 return section in self.__sheet_sections
2933
2749 def getSheetSection(self, section): 2934 def getSheetSection(self, section):
2750 return self.__sheet_sections[section] 2935 return self.__sheet_sections[section]
2936
2751 def setSheetSections(self,dictionary): 2937 def setSheetSections(self,dictionary):
2752 if not isinstance(dictionary, dict): 2938 if not isinstance(dictionary, dict):
2753 raise ValueError, _("The sheet sections must be a dictionary") 2939 raise ValueError( _("The sheet sections must be a dictionary") )
2754 for sheet_code in dictionary.keys(): 2940 for sheet_code in dictionary.keys():
2755 self.setSheetSection(sheet_code, dictionary[sheet_code]) 2941 self.setSheetSection(sheet_code, dictionary[sheet_code])
2942
2756 def setSheetField(self, field_code, field_title): 2943 def setSheetField(self, field_code, field_title):
2757 if not isinstance(field_code, str): 2944 if not isinstance(field_code, str):
2758 raise ValueError, _("The field code must be a string") 2945 raise ValueError( _("The field code must be a string") )
2759 if not isinstance(field_title, str): 2946 if not isinstance(field_title, str):
2760 raise ValueError, _("The field title must be a string") 2947 raise ValueError( _("The field title must be a string") )
2761 self.__sheet_fields[field_code] = field_title 2948 self.__sheet_fields[field_code] = field_title
2949
2762 def hasSheetField(self, field): 2950 def hasSheetField(self, field):
2763 return field in self.__sheet_fields 2951 return field in self.__sheet_fields
2952
2764 def getSheetField(self, field): 2953 def getSheetField(self, field):
2765 return self.__sheet_fields[field] 2954 return self.__sheet_fields[field]
2955
2766 def setSheetFields(self, field_dict): 2956 def setSheetFields(self, field_dict):
2767 if not isinstance(field_dict, dict): 2957 if not isinstance(field_dict, dict):
2768 raise ValueError, _("The sheet field must be a dictionary") 2958 raise ValueError( _("The sheet field must be a dictionary") )
2769 for field_code in field_dict.keys(): 2959 for field_code in field_dict.keys():
2770 self.setSheetField( field_code, field_dict[field_code]) 2960 self.setSheetField( field_code, field_dict[field_code])
2961
2771 def setSheetParagraph(self, paragraph_code, paragraph_text): 2962 def setSheetParagraph(self, paragraph_code, paragraph_text):
2772 if not isinstance(paragraph_code, str): 2963 if not isinstance(paragraph_code, str):
2773 raise ValueError, _("The paragraph code must be a string") 2964 raise ValueError( _("The paragraph code must be a string") )
2774 if not isinstance(paragraph_text, str): 2965 if not isinstance(paragraph_text, str):
2775 raise ValueError, _("The paragraph text must be a string") 2966 raise ValueError( _("The paragraph text must be a string") )
2776 self.__sheet_paragraphs[paragraph_code] = paragraph_text 2967 self.__sheet_paragraphs[paragraph_code] = paragraph_text
2968
2777 def hasSheetParagraph(self, paragraph): 2969 def hasSheetParagraph(self, paragraph):
2778 return paragraph in self.__sheet_paragraphs 2970 return paragraph in self.__sheet_paragraphs
2971
2779 def getSheetParagraph(self, paragraph): 2972 def getSheetParagraph(self, paragraph):
2780 return self.__sheet_paragraphs[paragraph] 2973 return self.__sheet_paragraphs[paragraph]
2974
2781 def setSheetParagraphs(self, paragraph_dict): 2975 def setSheetParagraphs(self, paragraph_dict):
2782 if not isinstance(paragraph_dict, dict): 2976 if not isinstance(paragraph_dict, dict):
2783 raise ValueError, _("The paragraph dict must be a dictionary") 2977 raise ValueError( _("The paragraph dict must be a dictionary") )
2784 for paragraph_code in paragraph_dict.keys(): 2978 for paragraph_code in paragraph_dict.keys():
2785 self.setSheetParagraph( paragraph_code, paragraph_dict[paragraph_code]) 2979 self.setSheetParagraph( paragraph_code, paragraph_dict[paragraph_code])
2980
2786 def setSheetRecord(self, record_code, field, section_dict): 2981 def setSheetRecord(self, record_code, field, section_dict):
2787 if not isinstance(record_code, str): 2982 if not isinstance(record_code, str):
2788 raise ValueError, _("The record_code code must be a string") 2983 raise ValueError( _("The record_code code must be a string") )
2789 if not isinstance(field, str): 2984 if not isinstance(field, str):
2790 raise ValueError, _("The field must be a string") 2985 raise ValueError( _("The field must be a string") )
2791 if not isinstance(section_dict, dict): 2986 if not isinstance(section_dict, dict):
2792 raise ValueError, _("The section dict must be a dictionary") 2987 raise ValueError( _("The section dict must be a dictionary") )
2793 #-# 2988 #-#
2794 # TODO: Add a empty record? 2989 # TODO: Add a empty record?
2795 if not self.hasRecord(record_code): 2990 if not self.hasRecord(record_code):
2796 print utils.mapping(_("Error: The budget do not have this record "\ 2991 print(utils.mapping(_("Error: The budget do not have this record "\
2797 "code and can not be added the sheet text in the field $1. "\ 2992 "code and can not be added the sheet text in the field $1. "\
2798 "Record Code: $2"), ( field, record_code)) 2993 "Record Code: $2"), ( str(field), str(record_code))) )
2799 return 2994 return
2800 #-# 2995 #-#
2801 if not self.hasSheetField(field): 2996 if not self.hasSheetField(field):
2802 self.setSheetField(field, "") 2997 self.setSheetField(field, "")
2803 for section, paragraph in section_dict.iteritems(): 2998 for section, paragraph in section_dict.iteritems():
2805 self.setSheetParagraph(paragraph,"") 3000 self.setSheetParagraph(paragraph,"")
2806 if not self.hasSheetSection(section): 3001 if not self.hasSheetSection(section):
2807 self.setSheetSection(section, "") 3002 self.setSheetSection(section, "")
2808 _sheet = self.getRecord(record_code).getSheet() 3003 _sheet = self.getRecord(record_code).getSheet()
2809 _sheet.addSection(field, section, paragraph) 3004 _sheet.addSection(field, section, paragraph)
3005
2810 def addFile(self, record_code, filepath, type_, description): 3006 def addFile(self, record_code, filepath, type_, description):
2811 if not isinstance(record_code, str): 3007 if not isinstance(record_code, str):
2812 raise ValueError, _("The record_code code must be a string") 3008 raise ValueError( _("The record_code code must be a string") )
2813 if not isinstance(filepath, str): 3009 #-# str and unicode
2814 raise ValueError, _("The filename must be a string") 3010 if not isinstance(filepath, str) and not isinstance(filepath, unicode):
3011 raise ValueError( _("The filename must be a string") )
2815 #-# 3012 #-#
2816 # TODO: Add a empty record? 3013 # TODO: Add a empty record?
2817 if not self.hasRecord(record_code): 3014 if not self.hasRecord(record_code):
2818 print utils.mapping(_("Error: The budget do not have the record "\ 3015 print(utils.mapping(_("Error: The budget do not have the record "\
2819 "code $1 and can not be added the file: $2"), 3016 "code $1 and can not be added the file: $2"),
2820 (record_code, filepath)) 3017 (str(record_code), str(filepath))) )
2821 return 3018 return
2822 #-# 3019 #-#
2823 _record = self.getRecord(record_code) 3020 _record = self.getRecord(record_code)
2824 _record.addFile(filepath, type_, description) 3021 _record.addFile(filepath, type_, description)
3022
2825 def setCompany(self, company_code, sumamary, name, offices, 3023 def setCompany(self, company_code, sumamary, name, offices,
2826 cif, web, email): 3024 cif, web, email):
2827 if not isinstance(company_code, str): 3025 if not isinstance(company_code, str):
2828 raise ValueError, _("The company code must be a string") 3026 raise ValueError( _("The company code must be a string") )
2829 if not isinstance(sumamary, str): 3027 if not isinstance(sumamary, str):
2830 raise ValueError, _("The summary must be a string") 3028 raise ValueError( _("The summary must be a string") )
2831 if not isinstance(name, str): 3029 if not isinstance(name, str):
2832 raise ValueError, _("The name must be a string") 3030 raise ValueError( _("The name must be a string") )
2833 if not isinstance(offices, list): 3031 if not isinstance(offices, list):
2834 raise ValueError, _("The name must be a list") 3032 raise ValueError( _("The name must be a list") )
2835 _offices = [] 3033 _offices = []
2836 for _office in offices: 3034 for _office in offices:
2837 if not isinstance(_office, list): 3035 if not isinstance(_office, list):
2838 raise ValueError, _("The office must be a list") 3036 raise ValueError( _("The office must be a list") )
2839 if not len(_office) == 10: 3037 if not len(_office) == 10:
2840 raise ValueError, _("The office must be a 10 items list") 3038 raise ValueError( _("The office must be a 10 items list") )
2841 for _item in _office[:7] + _office[9:10]: 3039 for _item in _office[:7] + _office[9:10]:
2842 if not isinstance(_item, str): 3040 if not isinstance(_item, str):
2843 raise ValueError, _("This office item must be a "\ 3041 raise ValueError( _("This office item must be a "\
2844 "string") 3042 "string") )
2845 for _item in _office[7:8]: 3043 for _item in _office[7:8]:
2846 if not isinstance(_item, list): 3044 if not isinstance(_item, list):
2847 raise ValueError, _("This office item must be a "\ 3045 raise ValueError( _("This office item must be a "\
2848 "list") 3046 "list") )
2849 _offices.append(Office(_office[0], 3047 _offices.append(Office(_office[0],
2850 _office[1], 3048 _office[1],
2851 _office[2], 3049 _office[2],
2852 _office[3], 3050 _office[3],
2853 _office[4], 3051 _office[4],
2855 _office[6], 3053 _office[6],
2856 _office[7], 3054 _office[7],
2857 _office[8], 3055 _office[8],
2858 _office[9])) 3056 _office[9]))
2859 if not isinstance(cif, str): 3057 if not isinstance(cif, str):
2860 raise ValueError, _("The name must be a string") 3058 raise ValueError( _("The name must be a string") )
2861 if not isinstance(web, str): 3059 if not isinstance(web, str):
2862 raise ValueError, _("The web must be a string") 3060 raise ValueError( _("The web must be a string") )
2863 if not isinstance(email, str): 3061 if not isinstance(email, str):
2864 raise ValueError, _("The email must be a string") 3062 raise ValueError( _("The email must be a string") )
2865 3063
2866 self.__companys[company_code] = Company(company_code, sumamary, name, 3064 self.__companys[company_code] = Company(company_code, sumamary, name,
2867 _offices, cif, web, email) 3065 _offices, cif, web, email)
2868 def getCompany(self, company_code): 3066 def getCompany(self, company_code):
2869 return self.__companys[company_code] 3067 return self.__companys[company_code]
3068
2870 def getCompanyKeys(self): 3069 def getCompanyKeys(self):
2871 return self.__companys.keys() 3070 return self.__companys.keys()
3071
2872 def addTecInfo(self, ti_code, text, unit): 3072 def addTecInfo(self, ti_code, text, unit):
2873 if not isinstance(ti_code, str): 3073 if not isinstance(ti_code, str):
2874 raise ValueError, _("The tecnical info code must be a string") 3074 raise ValueError( _("The tecnical info code must be a string") )
2875 if not isinstance(text, str): 3075 if not isinstance(text, str):
2876 raise ValueError, _("The tecnical info description must be a "\ 3076 raise ValueError( _("The tecnical info description must be a "\
2877 "string") 3077 "string") )
2878 if not isinstance(unit, str): 3078 if not isinstance(unit, str):
2879 raise ValueError, _("The tecnical info unit must be a string") 3079 raise ValueError( _("The tecnical info unit must be a string") )
2880 self.__tec_info[ti_code] = [text, unit] 3080 self.__tec_info[ti_code] = [text, unit]
3081
2881 def hasTecInfo(self, ti_code): 3082 def hasTecInfo(self, ti_code):
2882 return ti_code in self.__tec_info 3083 return ti_code in self.__tec_info
3084
2883 def getTecInfo(self, ti_code): 3085 def getTecInfo(self, ti_code):
2884 return self.__tec_info[ti_code] 3086 return self.__tec_info[ti_code]
3087
2885 def setTecnicalInformation(self, record_code, ti_dict): 3088 def setTecnicalInformation(self, record_code, ti_dict):
2886 """setTecnicalInformation(record_code, ti_dict) 3089 """setTecnicalInformation(record_code, ti_dict)
2887 3090
2888 Sets the tecnical information to a record 3091 Sets the tecnical information to a record
2889 record_code: the record code 3092 record_code: the record code
2890 ti_dict: {ti_code : ti_value} 3093 ti_dict: {ti_code : ti_value}
2891 """ 3094 """
2892 # TODO: setTecnicalInformation 3095 # TODO: setTecnicalInformation
2893 pass 3096 pass
3097
2894 def changeCode(self, record_code, new_record_code): 3098 def changeCode(self, record_code, new_record_code):
2895 """changeCode(self, record_code, new_record_code): 3099 """changeCode(self, record_code, new_record_code):
2896 3100
2897 Change the record code for a new recor code. 3101 Change the record code for a new recor code.
2898 """ 3102 """
2921 """addLabel(self, record_code, label) 3125 """addLabel(self, record_code, label)
2922 3126
2923 Add a label to a record 3127 Add a label to a record
2924 """ 3128 """
2925 if not isinstance(label,str): 3129 if not isinstance(label,str):
2926 raise ValueError, _("The label must be a string") 3130 raise ValueError( _("The label must be a string") )
2927 if self.hasRecord(record_code): 3131 if self.hasRecord(record_code):
2928 _record = self.__records[record_code] 3132 _record = self.__records[record_code]
2929 _record.addLabel(label) 3133 _record.addLabel(label)
2930 if not label in self.__labels: 3134 if not label in self.__labels:
2931 self.__labels[label] = [record_code] 3135 self.__labels[label] = [record_code]
2932 else: 3136 else:
2933 _codes = self.__labels[label] 3137 _codes = self.__labels[label]
2934 if not record_code in _codes: 3138 if not record_code in _codes:
2935 _codes.append(record_code) 3139 _codes.append(record_code)
3140
2936 def setParametricSelectComment(self, record_code, comment): 3141 def setParametricSelectComment(self, record_code, comment):
2937 """setParametricSelectComment(self, record_code, comment) 3142 """setParametricSelectComment(self, record_code, comment)
2938 3143
2939 Sets Paramtric Record Select Comment 3144 Sets Paramtric Record Select Comment
2940 """ 3145 """
2941 if not isinstance(record_code, str): 3146 if not isinstance(record_code, str):
2942 raise ValueError, _("The record_code code must be a string") 3147 raise ValueError( _("The record_code code must be a string") )
2943 if not isinstance(comment, str): 3148 if not isinstance(comment, str):
2944 raise ValueError, _("The parametric select comment must be a "\ 3149 raise ValueError( _("The parametric select comment must be a "\
2945 "string") 3150 "string") )
2946 if not self.hasRecord(record_code): 3151 if not self.hasRecord(record_code):
2947 print utils.mapping(_("Error: The budget do not have the record "\ 3152 print(utils.mapping(_("Error: The budget do not have the record "\
2948 "code $1 and can not be added the Parametric select comment: "\ 3153 "code $1 and can not be added the Parametric select comment: "\
2949 "$2"), 3154 "$2"),
2950 (record_code, comment)) 3155 (str(record_code), str(comment))) )
2951 return 3156 return
2952 _record = self.getRecord(record_code) 3157 _record = self.getRecord(record_code)
2953 if not isinstance(_record, ParametricRecord): 3158 if not isinstance(_record, ParametricRecord):
2954 print utils.mapping(_("Error: The Record $1 is not a "\ 3159 print(utils.mapping(_("Error: The Record $1 is not a "\
2955 "Parametric Record and can not have Parametric comment"), 3160 "Parametric Record and can not have Parametric comment"),
2956 (record_code,)) 3161 (str(record_code),)) )
2957 else: 3162 else:
2958 _record.select_comment = comment 3163 _record.select_comment = comment
2959 3164
2960 def setParametricSummary(self, record_code, summary): 3165 def setParametricSummary(self, record_code, summary):
2961 """setParametricSummary(self, record_code, summary) 3166 """setParametricSummary(self, record_code, summary)
2962 3167
2963 Sets parametric record summary 3168 Sets parametric record summary
2964 """ 3169 """
2965 if not isinstance(record_code, str): 3170 if not isinstance(record_code, str):
2966 raise ValueError, _("The record_code code must be a string") 3171 raise ValueError( _("The record_code code must be a string") )
2967 if not isinstance(summary, str): 3172 if not isinstance(summary, str):
2968 raise ValueError, _("The summary record must be a string") 3173 raise ValueError( _("The summary record must be a string") )
2969 if not self.hasRecord(record_code): 3174 if not self.hasRecord(record_code):
2970 print utils.mapping(_("Error: The budget do not have the record "\ 3175 print(utils.mapping(_("Error: The budget do not have the record "\
2971 "code $1 and can not be seted the summary: $2"), 3176 "code $1 and can not be seted the summary: $2"),
2972 (record_code, summary)) 3177 (str(record_code), str(summary))) )
2973 return 3178 return
2974 _record = self.getRecord(record_code) 3179 _record = self.getRecord(record_code)
2975 if not isinstance(_record, ParametricRecord): 3180 if not isinstance(_record, ParametricRecord):
2976 print utils.mapping(_("Error: The Record $1 is not a "\ 3181 print(utils.mapping(_("Error: The Record $1 is not a "\
2977 "Parametric Record and can not have Parametric summary"), 3182 "Parametric Record and can not have Parametric summary"),
2978 (record_code,)) 3183 (str(record_code),)) )
2979 else: 3184 else:
2980 self.getRecord(record_code).parametric_summary = summary 3185 self.getRecord(record_code).parametric_summary = summary
2981 3186
2982 def setParametricText(self, record_code, text): 3187 def setParametricText(self, record_code, text):
2983 """setParametricText(self, record_code, text) 3188 """setParametricText(self, record_code, text)
2984 3189
2985 Sets parametric record text 3190 Sets parametric record text
2986 """ 3191 """
2987 if not isinstance(record_code, str): 3192 if not isinstance(record_code, str):
2988 raise ValueError, _("The record_code code must be a string") 3193 raise ValueError( _("The record_code code must be a string") )
2989 if not isinstance(text, str): 3194 if not isinstance(text, str):
2990 raise ValueError, _("The text record must be a string") 3195 raise ValueError( _("The text record must be a string") )
2991 if not self.hasRecord(record_code): 3196 if not self.hasRecord(record_code):
2992 print utils.mapping(_("Error: The budget do not have the record "\ 3197 print(utils.mapping(_("Error: The budget do not have the record "\
2993 "code $1 and can not be seted the text: $2"), 3198 "code $1 and can not be seted the text: $2"),
2994 (record_code, text)) 3199 (str(record_code), str(text))) )
2995 return 3200 return
2996 _record = self.getRecord(record_code) 3201 _record = self.getRecord(record_code)
2997 if not isinstance(_record, ParametricRecord): 3202 if not isinstance(_record, ParametricRecord):
2998 print utils.mapping(_("Error: The Record $1 is not a "\ 3203 print(utils.mapping(_("Error: The Record $1 is not a "\
2999 "Parametric Record and can not have Parametric text"), 3204 "Parametric Record and can not have Parametric text"),
3000 (record_code,)) 3205 (str(record_code),)) )
3001 else: 3206 else:
3002 self.getRecord(record_code).parametric_text = text 3207 self.getRecord(record_code).parametric_text = text
3208
3003 3209
3004 class Office(object): 3210 class Office(object):
3005 """base.Office: 3211 """base.Office:
3006 3212
3007 Description: 3213 Description:
3042 {get/set}Phone 3248 {get/set}Phone
3043 {get/set}Fax 3249 {get/set}Fax
3044 {get/set}ContactPerson 3250 {get/set}ContactPerson
3045 getValues 3251 getValues
3046 """ 3252 """
3253
3047 __slots__ = ["_Office__officeType", 3254 __slots__ = ["_Office__officeType",
3048 "_Office__subname", 3255 "_Office__subname",
3049 "_Office__address", 3256 "_Office__address",
3050 "_Office__postal_code", 3257 "_Office__postal_code",
3051 "_Office__town", 3258 "_Office__town",
3053 "_Office__country", 3260 "_Office__country",
3054 "_Office__phone", 3261 "_Office__phone",
3055 "_Office__fax", 3262 "_Office__fax",
3056 "_Office__contact_person", 3263 "_Office__contact_person",
3057 ] 3264 ]
3265
3058 def __getstate__ (self): 3266 def __getstate__ (self):
3059 return ( self.__officeType, 3267 return ( self.__officeType,
3060 self.__subname, 3268 self.__subname,
3061 self.__address, 3269 self.__address,
3062 self.__postal_code, 3270 self.__postal_code,
3064 self.__province, 3272 self.__province,
3065 self.__country, 3273 self.__country,
3066 self.__phone, 3274 self.__phone,
3067 self.__fax, 3275 self.__fax,
3068 self.__contact_person) 3276 self.__contact_person)
3277
3069 def __setstate__(self,tuple): 3278 def __setstate__(self,tuple):
3070 self.__officeType = tuple[0] 3279 self.__officeType = tuple[0]
3071 self.__subname = tuple[1] 3280 self.__subname = tuple[1]
3072 self.__address = tuple[2] 3281 self.__address = tuple[2]
3073 self.__postal_code = tuple[3] 3282 self.__postal_code = tuple[3]
3088 self.province = province 3297 self.province = province
3089 self.country = country 3298 self.country = country
3090 self.phone = phone 3299 self.phone = phone
3091 self.fax = fax 3300 self.fax = fax
3092 self.contact_person = contact_person 3301 self.contact_person = contact_person
3302
3093 def getOfficeType(self): 3303 def getOfficeType(self):
3094 return self.__officeType 3304 return self.__officeType
3305
3095 def setOfficeType(self, type_): 3306 def setOfficeType(self, type_):
3096 self.__officeType = type_ 3307 self.__officeType = type_
3308
3097 def getSubname(self): 3309 def getSubname(self):
3098 return self.__subname 3310 return self.__subname
3311
3099 def setSubname(self, subname): 3312 def setSubname(self, subname):
3100 self.__subname = subname 3313 self.__subname = subname
3314
3101 def getAddress(self): 3315 def getAddress(self):
3102 return self.__address 3316 return self.__address
3317
3103 def setAddress(self, address): 3318 def setAddress(self, address):
3104 self.__address = address 3319 self.__address = address
3320
3105 def getPostalCode(self): 3321 def getPostalCode(self):
3106 return self.__postal_code 3322 return self.__postal_code
3323
3107 def setPostalCode(self, postal_code): 3324 def setPostalCode(self, postal_code):
3108 self.__postal_code = postal_code 3325 self.__postal_code = postal_code
3326
3109 def getTown(self): 3327 def getTown(self):
3110 return self.__town 3328 return self.__town
3329
3111 def setTown(self, town): 3330 def setTown(self, town):
3112 self.__town = town 3331 self.__town = town
3332
3113 def getProvince(self): 3333 def getProvince(self):
3114 return self.__province 3334 return self.__province
3335
3115 def setProvince(self, province): 3336 def setProvince(self, province):
3116 self.__province = province 3337 self.__province = province
3338
3117 def getCountry(self): 3339 def getCountry(self):
3118 return self.__country 3340 return self.__country
3341
3119 def setCountry(self, country): 3342 def setCountry(self, country):
3120 self.__country = country 3343 self.__country = country
3344
3121 def getPhone(self): 3345 def getPhone(self):
3122 return self.__phone 3346 return self.__phone
3347
3123 def setPhone(self, phone): 3348 def setPhone(self, phone):
3124 self.__phone = phone 3349 self.__phone = phone
3350
3125 def getFax(self): 3351 def getFax(self):
3126 return self.__fax 3352 return self.__fax
3353
3127 def setFax(self, fax): 3354 def setFax(self, fax):
3128 self.__fax = fax 3355 self.__fax = fax
3356
3129 def getContactPerson(self): 3357 def getContactPerson(self):
3130 return self.__contact_person 3358 return self.__contact_person
3359
3131 def setContactPerson(self, contact_person): 3360 def setContactPerson(self, contact_person):
3132 self.__contact_person = contact_person 3361 self.__contact_person = contact_person
3362
3133 def getValues(self): 3363 def getValues(self):
3134 return {"officeType": self.officeType, 3364 return {"officeType": self.officeType,
3135 "subname": self.subname, 3365 "subname": self.subname,
3136 "address": self.address, 3366 "address": self.address,
3137 "postal code": self.postal_code, 3367 "postal code": self.postal_code,
3140 "country": self.country, 3370 "country": self.country,
3141 "phone": self.phone, 3371 "phone": self.phone,
3142 "fax": self.fax, 3372 "fax": self.fax,
3143 "contact person": self.contact_person, 3373 "contact person": self.contact_person,
3144 } 3374 }
3375
3145 officeType = property(getOfficeType, setOfficeType, None, 3376 officeType = property(getOfficeType, setOfficeType, None,
3146 """Type of office 3377 """Type of office
3147 """) 3378 """)
3148 subname = property(getSubname, setSubname, None, 3379 subname = property(getSubname, setSubname, None,
3149 """Name of office 3380 """Name of office
3173 """Contact Person 3404 """Contact Person
3174 """) 3405 """)
3175 values = property(getValues, None, None, 3406 values = property(getValues, None, None,
3176 """Dictionary with comapany values 3407 """Dictionary with comapany values
3177 """) 3408 """)
3409
3178 3410
3179 class Company(object): 3411 class Company(object):
3180 """base.Company: 3412 """base.Company:
3181 3413
3182 Description: 3414 Description:
3208 {get/set}Cif 3440 {get/set}Cif
3209 {get/set}Web 3441 {get/set}Web
3210 {get/set}Email 3442 {get/set}Email
3211 getValues 3443 getValues
3212 """ 3444 """
3445
3213 __slots__ = ["_Company__code", 3446 __slots__ = ["_Company__code",
3214 "_Company__summary", 3447 "_Company__summary",
3215 "_Company__name", 3448 "_Company__name",
3216 "_Company__offices", 3449 "_Company__offices",
3217 "_Company__cif", 3450 "_Company__cif",
3218 "_Company__web", 3451 "_Company__web",
3219 "_Company__email", 3452 "_Company__email",
3220 ] 3453 ]
3454
3221 def __getstate__ (self): 3455 def __getstate__ (self):
3222 return ( self.__code, 3456 return ( self.__code,
3223 self.__summary, 3457 self.__summary,
3224 self.__name, 3458 self.__name,
3225 self.__offices, 3459 self.__offices,
3226 self.__cif, 3460 self.__cif,
3227 self.__web, 3461 self.__web,
3228 self.__email) 3462 self.__email)
3463
3229 def __setstate__(self,tuple): 3464 def __setstate__(self,tuple):
3230 self.__code = tuple[0] 3465 self.__code = tuple[0]
3231 self.__summary = tuple[1] 3466 self.__summary = tuple[1]
3232 self.__name = tuple[2] 3467 self.__name = tuple[2]
3233 self.__offices = tuple[3] 3468 self.__offices = tuple[3]
3241 self.name = name 3476 self.name = name
3242 self.offices = offices 3477 self.offices = offices
3243 self.cif = cif 3478 self.cif = cif
3244 self.web = web 3479 self.web = web
3245 self.email = email 3480 self.email = email
3481
3246 def getCode(self): 3482 def getCode(self):
3247 return self.__code 3483 return self.__code
3484
3248 def setCode(self, code): 3485 def setCode(self, code):
3249 self.__code = code 3486 self.__code = code
3487
3250 def getSummary(self): 3488 def getSummary(self):
3251 return self.__summary 3489 return self.__summary
3490
3252 def setSummary(self, summary): 3491 def setSummary(self, summary):
3253 self.__summary = summary 3492 self.__summary = summary
3493
3254 def getName(self): 3494 def getName(self):
3255 return self.__name 3495 return self.__name
3496
3256 def setName(self, name): 3497 def setName(self, name):
3257 self.__name = name 3498 self.__name = name
3499
3258 def getOffices(self): 3500 def getOffices(self):
3259 return self.__offices 3501 return self.__offices
3502
3260 def setOffices(self, offices): 3503 def setOffices(self, offices):
3261 self.__offices = offices 3504 self.__offices = offices
3505
3262 def getCif(self): 3506 def getCif(self):
3263 return self.__cif 3507 return self.__cif
3508
3264 def setCif(self, cif): 3509 def setCif(self, cif):
3265 self.__cif = cif 3510 self.__cif = cif
3511
3266 def getWeb(self): 3512 def getWeb(self):
3267 return self.__web 3513 return self.__web
3514
3268 def setWeb(self, web): 3515 def setWeb(self, web):
3269 self.__web = web 3516 self.__web = web
3517
3270 def getEmail(self): 3518 def getEmail(self):
3271 return self.__email 3519 return self.__email
3520
3272 def setEmail(self, email): 3521 def setEmail(self, email):
3273 self.__email = email 3522 self.__email = email
3523
3274 def getValues(self): 3524 def getValues(self):
3275 return {"code": self.code, 3525 return {"code": self.code,
3276 "summary": self.summary, 3526 "summary": self.summary,
3277 "name": self.name, 3527 "name": self.name,
3278 "cif": self.cif, 3528 "cif": self.cif,
3279 "web": self.web, 3529 "web": self.web,
3280 "email": self.email} 3530 "email": self.email}
3531
3281 code = property(getCode, setCode, None, 3532 code = property(getCode, setCode, None,
3282 """Company code 3533 """Company code
3283 """) 3534 """)
3284 summary = property(getSummary, setSummary, None, 3535 summary = property(getSummary, setSummary, None,
3285 """Company summary 3536 """Company summary
3300 """Email 3551 """Email
3301 """) 3552 """)
3302 values = property(getValues, None, None, 3553 values = property(getValues, None, None,
3303 """Dictionary with comapany values 3554 """Dictionary with comapany values
3304 """) 3555 """)
3556
3305 3557
3306 class File(object): 3558 class File(object):
3307 """base.Company: 3559 """base.Company:
3308 3560
3309 Description: 3561 Description:
3324 {get/set}Name 3576 {get/set}Name
3325 {get/set}FileType 3577 {get/set}FileType
3326 {get/set}Description 3578 {get/set}Description
3327 getValues 3579 getValues
3328 """ 3580 """
3581
3329 __slots__ = ["_File__name", 3582 __slots__ = ["_File__name",
3330 "_File__fileType", 3583 "_File__fileType",
3331 "_File__description", 3584 "_File__description",
3332
3333 ] 3585 ]
3586
3334 def __getstate__ (self): 3587 def __getstate__ (self):
3335 return (self.__name, 3588 return (self.__name,
3336 self.__description, 3589 self.__description,
3337 self.__fileType, 3590 self.__fileType,
3338 ) 3591 )
3592
3339 def __setstate__(self,tuple): 3593 def __setstate__(self,tuple):
3340 self.__name = tuple[0] 3594 self.__name = tuple[0]
3341 self.__fileType = tuple[1] 3595 self.__fileType = tuple[1]
3342 self.__description = tuple[2] 3596 self.__description = tuple[2]
3597
3343 def __init__(self, name, type_, description): 3598 def __init__(self, name, type_, description):
3344 self.name = name 3599 self.name = name
3345 self.fileType = type_ 3600 self.fileType = type_
3346 self.description = description 3601 self.description = description
3602
3347 def getName(self): 3603 def getName(self):
3348 return self.__name 3604 return self.__name
3605
3349 def setName(self, name): 3606 def setName(self, name):
3350 self.__name = name 3607 self.__name = name
3608
3351 def getFileType(self): 3609 def getFileType(self):
3352 return self.__fileType 3610 return self.__fileType
3611
3353 def setFileType(self, type_): 3612 def setFileType(self, type_):
3354 self.__fileType = type_ 3613 self.__fileType = type_
3614
3355 def getDescription(self): 3615 def getDescription(self):
3356 return self.__description 3616 return self.__description
3617
3357 def setDescription(self, description): 3618 def setDescription(self, description):
3358 self.__description = description 3619 self.__description = description
3620
3359 def getValues(self): 3621 def getValues(self):
3360 return {"name": self.name, 3622 return {"name": self.name,
3361 "fileType": self.fileType, 3623 "fileType": self.fileType,
3362 "description": self.description, 3624 "description": self.description,
3363 } 3625 }
3626
3364 name = property(getName, setName, None, 3627 name = property(getName, setName, None,
3365 """File name 3628 """File name
3366 """) 3629 """)
3367 fileType = property(getFileType, setFileType, None, 3630 fileType = property(getFileType, setFileType, None,
3368 """FileType 3631 """FileType
3371 """File description 3634 """File description
3372 """) 3635 """)
3373 values = property(getValues, None, None, 3636 values = property(getValues, None, None,
3374 """Dictionary with file values 3637 """Dictionary with file values
3375 """) 3638 """)
3639
3376 3640
3377 class RecordType(object): 3641 class RecordType(object):
3378 """base.RecordType: 3642 """base.RecordType:
3379 3643
3380 Description: 3644 Description:
3430 __init__(self, hierarchy, type, subtype) 3694 __init__(self, hierarchy, type, subtype)
3431 {get/set}Hierarchy 3695 {get/set}Hierarchy
3432 {get/set}Type 3696 {get/set}Type
3433 {get/set}Subtype 3697 {get/set}Subtype
3434 """ 3698 """
3699
3435 __slots__ = ["_RecordType__hierarchy", 3700 __slots__ = ["_RecordType__hierarchy",
3436 "_RecordType__type", 3701 "_RecordType__type",
3437 "_RecordType__subtype", 3702 "_RecordType__subtype",
3438 ] 3703 ]
3704
3439 def __getstate__ (self): 3705 def __getstate__ (self):
3440 return (self.__hierarchy, 3706 return (self.__hierarchy,
3441 self.__type, 3707 self.__type,
3442 self.__subtype, 3708 self.__subtype,
3443 ) 3709 )
3710
3444 def __setstate__(self,tuple): 3711 def __setstate__(self,tuple):
3445 self.__hierarchy = tuple[0] 3712 self.__hierarchy = tuple[0]
3446 self.__type = tuple[1] 3713 self.__type = tuple[1]
3447 self.__subtype = tuple[2] 3714 self.__subtype = tuple[2]
3715
3448 def __init__(self, hierarchy, type_, subtype): 3716 def __init__(self, hierarchy, type_, subtype):
3449 self.hierarchy = hierarchy 3717 self.hierarchy = hierarchy
3450 self.type = type_ 3718 self.type = type_
3451 self.subtype = subtype 3719 self.subtype = subtype
3720
3452 def getHierarchy(self): 3721 def getHierarchy(self):
3453 return self.__hierarchy 3722 return self.__hierarchy
3723
3454 def setHierarchy(self, hierarchy): 3724 def setHierarchy(self, hierarchy):
3455 if not hierarchy in [-1, 0 , 1 ,2, ""]: 3725 if not hierarchy in [-1, 0 , 1 ,2, ""]:
3456 raise ValueError, utils.mapping(_("Invalid Hierarchy ($1) "\ 3726 raise ValueError( utils.mapping(_("Invalid Hierarchy ($1) "\
3457 "The hierarchy must be -1, 0, 1, 2"), (str(hierarchy),)) 3727 "The hierarchy must be -1, 0, 1, 2"), (str(hierarchy),)) )
3458 elif hierarchy == "": 3728 elif hierarchy == "":
3459 print "Hierarchy temporarily set to an empty string" 3729 print("Hierarchy temporarily set to an empty string")
3460 #TODO Check empty Hierarchy in Generic.fiebdc.Read._testBudget 3730 #TODO Check empty Hierarchy in Generic.fiebdc.Read._testBudget
3461 self.__hierarchy = hierarchy 3731 self.__hierarchy = hierarchy
3732
3462 def getType(self): 3733 def getType(self):
3463 return self.__type 3734 return self.__type
3735
3464 def setType(self, type_): 3736 def setType(self, type_):
3465 if not type_ in ["", 0, 1, 2, 3] : 3737 if not type_ in ["", 0, 1, 2, 3] :
3466 raise ValueError, utils.mapping(_("Invalid type ($1),"\ 3738 raise ValueError( utils.mapping(_("Invalid type ($1),"\
3467 "the type must be (empty string,0,1,2,3)"),(str(type_)),) 3739 "the type must be (empty string,0,1,2,3)"),(str(type_)),) )
3468 self.__type = type_ 3740 self.__type = type_
3741
3469 def getSubtype(self): 3742 def getSubtype(self):
3470 return self.__subtype 3743 return self.__subtype
3744
3471 def setSubtype(self, subtype): 3745 def setSubtype(self, subtype):
3472 if not subtype in ["", "OB", "PU", "EA", "EU", "EC", "EF", "PA", "H", 3746 if not subtype in ["", "OB", "PU", "EA", "EU", "EC", "EF", "PA", "H",
3473 "Q", "%", "MC", "MCr", "MM", "MS", "ME", "MCu", 3747 "Q", "%", "MC", "MCr", "MM", "MS", "ME", "MCu",
3474 "Mal","ML","M"]: 3748 "Mal","ML","M"]:
3475 raise ValueError, utils.mapping(_("Invalid subtype ($1), The "\ 3749 raise ValueError( utils.mapping(_("Invalid subtype ($1), The "\
3476 "subtype must one in (empty string, EA, "\ 3750 "subtype must one in (empty string, EA, "\
3477 "EU, EC, EF, OB, PA, PU, H, Q, %, MC, MCr, "\ 3751 "EU, EC, EF, OB, PA, PU, H, Q, %, MC, MCr, "\
3478 "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype),)) 3752 "MM, MS, ME, MCu, MAl, ML, M)"), (str(subtype),)) )
3479 self.__subtype = subtype 3753 self.__subtype = subtype
3754
3480 hierarchy = property(getHierarchy, setHierarchy, None, 3755 hierarchy = property(getHierarchy, setHierarchy, None,
3481 """Record Hierarchy 3756 """Record Hierarchy
3482 -1 -> temporarily unfixed 3757 -1 -> temporarily unfixed
3483 0 -> root 3758 0 -> root
3484 1 -> Chapter/Subchapter 3759 1 -> Chapter/Subchapter