Class: TheFox::Timr::Model::Task
- Inherits:
-
BasicModel
- Object
- BasicModel
- TheFox::Timr::Model::Task
- Includes:
- Error
- Defined in:
- lib/timr/model/task.rb
Instance Attribute Summary collapse
-
#current_track ⇒ Object
readonly
Returns the value of attribute current_track.
-
#description ⇒ Object
Returns the value of attribute description.
-
#foreign_id ⇒ Object
Returns the value of attribute foreign_id.
-
#has_flat_rate ⇒ Object
Returns the value of attribute has_flat_rate.
-
#hourly_rate ⇒ Object
Returns the value of attribute hourly_rate.
Attributes inherited from BasicModel
Class Method Summary collapse
-
.create_task_from_hash(options) ⇒ Object
Create a new Task using a Hash.
-
.load_task_from_file(path) ⇒ Object
Load a Task from a file into a Task instance.
-
.load_task_from_file_with_id(base_path, task_id) ⇒ Object
Search a Task in a base path for a Track by ID.
Instance Method Summary collapse
-
#add_track(track, set_as_current_track = false) ⇒ Object
Add a Track.
-
#begin_datetime(options = Hash.new) ⇒ Object
Uses ‘tracks()` with `options` to filter.
-
#begin_datetime_s(options = Hash.new) ⇒ Object
Options:.
-
#billed_duration(options = Hash.new) ⇒ Object
Alias for ‘duration` method.
-
#consumed_budge ⇒ Object
Get the actual consumed budge.
-
#continue(options = Hash.new) ⇒ Object
Continues the current Track.
-
#duration(options = Hash.new) ⇒ Object
Consumed duration.
-
#end_datetime(options = Hash.new) ⇒ Object
Uses ‘tracks()` with `options` to filter.
-
#end_datetime_s(options = Hash.new) ⇒ Object
Options:.
-
#eql?(task) ⇒ Boolean
Are two Tasks equal?.
-
#estimated_budge ⇒ Object
Calculate the budge based on estimation.
-
#estimation ⇒ Object
Get estimation.
-
#estimation=(estimation) ⇒ Object
Set estimation.
-
#estimation_s ⇒ Object
Get estimation as String.
-
#find_track_by_id(track_id) ⇒ Object
Find a Track by ID even if the ID is not 40 characters long.
-
#formatted(options = Hash.new) ⇒ Object
Return formatted String.
-
#id_foreign_or_short ⇒ Object
Get Foreign ID or Short ID.
-
#initialize ⇒ Task
constructor
A new instance of Task.
- #inspect ⇒ Object
-
#is_billed=(is_billed) ⇒ Object
Set is_billed.
-
#loss_budge ⇒ Object
Calculates the budge loss when a Flat Rate is used and the consumed duration is greater than the estimation.
-
#move_track(track, target_task) ⇒ Object
Move a Track to another Task.
-
#name(max_length = nil) ⇒ Object
Get name.
-
#name=(name) ⇒ Object
Set name.
-
#name_s(max_length = nil) ⇒ Object
Get name or ‘—` if name is not set.
-
#pause(options = Hash.new) ⇒ Object
Pauses a current running Track.
-
#remaining_time ⇒ Object
Get the remaining Time of estimation.
-
#remaining_time_percent ⇒ Object
Get the remaining Time as percent.
-
#remaining_time_percent_s ⇒ Object
Get the remaining Time Percent as String.
-
#remaining_time_s ⇒ Object
Get the remaining Time as Human String.
-
#remove_track(track) ⇒ Object
Remove a Track.
- #reset ⇒ Object
-
#start(options = Hash.new) ⇒ Object
Start a new Track by given ‘options`.
-
#status ⇒ Object
Get Task status as Status instance.
-
#stop(options = Hash.new) ⇒ Object
Stops a current running Track.
-
#to_compact_array ⇒ Object
Used to print informations to STDOUT.
-
#to_compact_str ⇒ Object
Used to print informations to STDOUT.
-
#to_detailed_array(options = Hash.new) ⇒ Object
Used to print informations to STDOUT.
-
#to_detailed_str ⇒ Object
Used to print informations to STDOUT.
-
#to_s ⇒ Object
To String.
-
#to_track_array(options = Hash.new) ⇒ Object
Use to print informations for Track.
-
#tracks(options = Hash.new) ⇒ Object
Select Track by Time Range and/or Status.
-
#unbilled_duration(options = Hash.new) ⇒ Object
Alias for ‘duration` method.
Methods inherited from BasicModel
#changed, create_path_by_id, #created=, #delete_file, find_file_by_id, get_id_from_path, #id, #id=, #load_from_file, #modified=, #post_save_to_file, #pre_load_from_file, #save_to_file, #short_id
Constructor Details
#initialize ⇒ Task
Returns a new instance of Task.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/timr/model/task.rb', line 16 def initialize super() # Meta @foreign_id = nil # --id @name = nil @description = nil @current_track = nil @estimation = nil @hourly_rate = nil @has_flat_rate = false # Data @tracks = Hash.new end |
Instance Attribute Details
#current_track ⇒ Object (readonly)
Returns the value of attribute current_track.
12 13 14 |
# File 'lib/timr/model/task.rb', line 12 def current_track @current_track end |
#description ⇒ Object
Returns the value of attribute description.
11 12 13 |
# File 'lib/timr/model/task.rb', line 11 def description @description end |
#foreign_id ⇒ Object
Returns the value of attribute foreign_id.
10 11 12 |
# File 'lib/timr/model/task.rb', line 10 def foreign_id @foreign_id end |
#has_flat_rate ⇒ Object
Returns the value of attribute has_flat_rate.
14 15 16 |
# File 'lib/timr/model/task.rb', line 14 def has_flat_rate @has_flat_rate end |
#hourly_rate ⇒ Object
Returns the value of attribute hourly_rate.
13 14 15 |
# File 'lib/timr/model/task.rb', line 13 def hourly_rate @hourly_rate end |
Class Method Details
.create_task_from_hash(options) ⇒ Object
Create a new Task using a Hash.
Options:
-
‘:name` (String)
-
‘:description` (String)
-
‘:estimation` (String|Integer|Duration)
-
‘:hourly_rate` (Integer)
1017 1018 1019 1020 1021 1022 1023 1024 1025 |
# File 'lib/timr/model/task.rb', line 1017 def create_task_from_hash() task = Task.new task.name = .fetch(:name, nil) task.description = .fetch(:description, nil) task.estimation = .fetch(:estimation, nil) task.hourly_rate = .fetch(:hourly_rate, nil) task.has_flat_rate = .fetch(:has_flat_rate, false) task end |
.load_task_from_file(path) ⇒ Object
Load a Task from a file into a Task instance.
994 995 996 997 998 |
# File 'lib/timr/model/task.rb', line 994 def load_task_from_file(path) task = Task.new task.load_from_file(path) task end |
.load_task_from_file_with_id(base_path, task_id) ⇒ Object
Search a Task in a base path for a Track by ID. If found a file load it into a Task instance.
1002 1003 1004 1005 1006 1007 |
# File 'lib/timr/model/task.rb', line 1002 def load_task_from_file_with_id(base_path, task_id) task_file_path = BasicModel.find_file_by_id(base_path, task_id) if task_file_path load_task_from_file(task_file_path) end end |
Instance Method Details
#add_track(track, set_as_current_track = false) ⇒ Object
Add a Track.
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/timr/model/task.rb', line 80 def add_track(track, set_as_current_track = false) track.task = self @tracks[track.id] = track if set_as_current_track @current_track = track end # Mark Task as changed. changed end |
#begin_datetime(options = Hash.new) ⇒ Object
Uses ‘tracks()` with `options` to filter.
Options:
-
‘:from`
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/timr/model/task.rb', line 317 def begin_datetime( = Hash.new) from_opt = .fetch(:from, nil) # Cache # if @begin_datetime # return @begin_datetime # end # Cannot use this cache because of :from :to range limitation. # It needs always to be direct from child Tracks, because the # cache does not know when the begin and end datetimes of the # child Tracks change. # Do not sort. We only need to sort the tracks # by begin_datetime and take the first. [:sort] = false first_track = tracks() .select{ |track_id, track| track.begin_datetime } # filter nil .sort_by{ |track_id, track| track.begin_datetime } .to_h # sort_by makes [[]] .values # no keys to take the first .first if first_track bdt = first_track.begin_datetime() end if from_opt && bdt && from_opt > bdt bdt = from_opt end bdt end |
#begin_datetime_s(options = Hash.new) ⇒ Object
Options:
-
‘:format`
354 355 356 357 358 359 360 361 362 363 |
# File 'lib/timr/model/task.rb', line 354 def begin_datetime_s( = Hash.new) format_opt = .fetch(:format, HUMAN_DATETIME_FOMRAT) bdt = begin_datetime() if bdt bdt.strftime(format_opt) else '---' end end |
#billed_duration(options = Hash.new) ⇒ Object
Alias for ‘duration` method.
Options:
-
‘:billed` (Boolean)
660 661 662 |
# File 'lib/timr/model/task.rb', line 660 def billed_duration( = Hash.new) duration(.merge({:billed => true})) end |
#consumed_budge ⇒ Object
Get the actual consumed budge.
503 504 505 506 507 508 509 |
# File 'lib/timr/model/task.rb', line 503 def consumed_budge if @hourly_rate duration.to_i.to_f / 3600.0 * @hourly_rate else 0.0 end end |
#continue(options = Hash.new) ⇒ Object
Continues the current Track. Only if it isn’t already running.
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'lib/timr/model/task.rb', line 608 def continue( = Hash.new) track_opt = .fetch(:track, nil) if @current_track if @current_track.stopped? # Duplicate and start. @current_track = @current_track.dup @current_track.start() add_track(@current_track) else raise TrackError, "Cannot continue Track #{@current_track.short_id}, is already running." end else unless track_opt raise TaskError, 'No Track given.' end # Duplicate and start. @current_track = track_opt.dup @current_track.start() add_track(@current_track) end @current_track end |
#duration(options = Hash.new) ⇒ Object
Consumed duration.
Options:
-
‘:billed` (Boolean)
643 644 645 646 647 648 649 650 651 652 653 |
# File 'lib/timr/model/task.rb', line 643 def duration( = Hash.new) billed_opt = .fetch(:billed, nil) duration = Duration.new @tracks.each do |track_id, track| if billed_opt.nil? || (billed_opt && track.is_billed) || (!billed_opt && !track.is_billed) duration += track.duration() end end duration end |
#end_datetime(options = Hash.new) ⇒ Object
Uses ‘tracks()` with `options` to filter.
Options:
-
‘:to`
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
# File 'lib/timr/model/task.rb', line 370 def end_datetime( = Hash.new) to_opt = .fetch(:to, nil) # Cache # if @end_datetime # return @end_datetime # end # Cannot use this cache because of :from :to range limitation. # It needs always to be direct from child Tracks, because the # cache does not know when the begin and end datetimes of the # child Tracks change. # Do not sort. We only need to sort the tracks # by end_datetime and take the last. [:sort] = false last_track = tracks() .select{ |track_id, track| track.end_datetime } # filter nil .sort_by{ |track_id, track| track.end_datetime } .to_h # sort_by makes [[]] .values # no keys to take the last .last if last_track edt = last_track.end_datetime() end if to_opt && edt && to_opt < edt edt = to_opt end edt end |
#end_datetime_s(options = Hash.new) ⇒ Object
Options:
-
‘:format`
407 408 409 410 411 412 413 414 415 416 |
# File 'lib/timr/model/task.rb', line 407 def end_datetime_s( = Hash.new) format_opt = .fetch(:format, HUMAN_DATETIME_FOMRAT) edt = end_datetime() if edt edt.strftime(format_opt) else '---' end end |
#eql?(task) ⇒ Boolean
Are two Tasks equal?
Uses ID for comparision.
767 768 769 770 771 772 773 |
# File 'lib/timr/model/task.rb', line 767 def eql?(task) unless task.is_a?(Task) raise TaskError, "task variable must be a Task instance. #{task.class} given." end self.id == task.id end |
#estimated_budge ⇒ Object
Calculate the budge based on estimation.
512 513 514 515 516 517 518 |
# File 'lib/timr/model/task.rb', line 512 def estimated_budge if @hourly_rate estimation.to_i.to_f / 3600.0 * @hourly_rate else 0.0 end end |
#estimation ⇒ Object
Get estimation.
469 470 471 |
# File 'lib/timr/model/task.rb', line 469 def estimation @estimation end |
#estimation=(estimation) ⇒ Object
Set estimation.
Either using a Duration instance, Integer or a String like ‘2h 30m`. Estimation is parsed by [chronic_duration](github.com/henrypoydar/chronic_duration).
Examples:
-
‘-e 2:10:5`
Sets Estimation to 2h 10m 5s.
-
‘-e ’2h 10m 5s’‘
Sets Estimation to 2h 10m 5s.
Use ‘+` or `-` to calculate with Estimation Times:
-
‘-e ’-45m’‘
Subtracts 45 minutes from the original Estimation.
-
‘-e ’+1h 30m’‘
Adds 1 hour 30 minutes to the original Estimation.
See [chronic_duration](github.com/henrypoydar/chronic_duration) for more examples.
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/timr/model/task.rb', line 439 def estimation=(estimation) case estimation when String # Cannot use estimation.strip! because frozen. estimation = estimation.strip if estimation[0] == '+' estimation = estimation[1..-1] @estimation += Duration.parse(estimation) elsif estimation[0] == '-' estimation = estimation[1..-1] @estimation -= Duration.parse(estimation) else @estimation = Duration.parse(estimation) end when Integer @estimation = Duration.new(estimation) when Duration @estimation = estimation when nil @estimation = estimation else raise TaskError, "estimation needs to be an instance of String, Integer, Duration or nil, #{estimation.class} given." end # Mark Task as changed. changed end |
#estimation_s ⇒ Object
Get estimation as String.
474 475 476 477 478 479 480 |
# File 'lib/timr/model/task.rb', line 474 def estimation_s if @estimation @estimation.to_human_s else '---' end end |
#find_track_by_id(track_id) ⇒ Object
Find a Track by ID even if the ID is not 40 characters long. When the ID is 40 characters long ‘@tracks` is faster. ;)
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 |
# File 'lib/timr/model/task.rb', line 739 def find_track_by_id(track_id) track_id_len = track_id.length # puts "search track id '#{track_id}'" if track_id_len < 40 found_track_id = nil @tracks.keys.each do |key| if track_id == key[0, track_id_len] if found_track_id raise TrackError, "Track ID '#{track_id}' is not a unique identifier." else found_track_id = key # Do not break the loop here. # Iterate all keys to make sure the ID is unique. end end end track_id = found_track_id end @tracks[track_id] end |
#formatted(options = Hash.new) ⇒ Object
Return formatted String.
Options:
-
‘:format`
-
‘:prefix` - Default: `%`
Format:
-
‘%id` - ID
-
‘%sid` - Short ID
-
‘%fid` - Foreign ID
-
‘%n` - Name
-
‘%d` - Description
-
‘%ds` - Duration Seconds
-
‘%dh` - Duration Human Format
962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 |
# File 'lib/timr/model/task.rb', line 962 def formatted( = Hash.new) format = .fetch(:format, '') prefix = .fetch(:prefix, '%') formatted_s = format .gsub("#{prefix}id", self.id) .gsub("#{prefix}sid", self.short_id ? self.short_id : '') .gsub("#{prefix}fid", self.foreign_id ? self.foreign_id : '') .gsub("#{prefix}n", self.name ? self.name : '') .gsub("#{prefix}ds", self.duration().to_s) duration_human = self.duration().to_human if duration_human formatted_s.gsub!('%dh', duration_human) else formatted_s.gsub!('%dh', '') end # Must not before %dh and %ds. formatted_s.gsub!("#{prefix}d", self.description ? self.description : '') formatted_s end |
#id_foreign_or_short ⇒ Object
Get Foreign ID or Short ID.
33 34 35 |
# File 'lib/timr/model/task.rb', line 33 def id_foreign_or_short @foreign_id ? @foreign_id : short_id end |
#inspect ⇒ Object
986 987 988 |
# File 'lib/timr/model/task.rb', line 986 def inspect "#<Task_#{short_id} tracks=#{@tracks.count}>" end |
#is_billed=(is_billed) ⇒ Object
Set is_billed.
731 732 733 734 735 |
# File 'lib/timr/model/task.rb', line 731 def is_billed=(is_billed) @tracks.each do |track_id, track| track.is_billed = is_billed end end |
#loss_budge ⇒ Object
Calculates the budge loss when a Flat Rate is used and the consumed duration is greater than the estimation.
521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/timr/model/task.rb', line 521 def loss_budge if @has_flat_rate && @hourly_rate if duration > estimation (duration - estimation).to_i.to_f / 3600.0 * @hourly_rate else 0.0 end else 0.0 end end |
#move_track(track, target_task) ⇒ Object
Move a Track to another Task.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/timr/model/task.rb', line 107 def move_track(track, target_task) if eql?(target_task) return false end unless remove_track(track) return false end set_as_current_track = false if @current_track && @current_track.eql?(track) @current_track = nil set_as_current_track = true end target_task.add_track(track, set_as_current_track) true end |
#name(max_length = nil) ⇒ Object
Get name.
53 54 55 56 57 58 59 |
# File 'lib/timr/model/task.rb', line 53 def name(max_length = nil) name = @name if name && max_length && name.length > max_length + 2 name = name[0, max_length] << '...' end name end |
#name=(name) ⇒ Object
Set name.
45 46 47 48 49 50 |
# File 'lib/timr/model/task.rb', line 45 def name=(name) @name = name # Mark Task as changed. changed end |
#name_s(max_length = nil) ⇒ Object
Get name or ‘—` if name is not set.
62 63 64 65 66 67 68 69 |
# File 'lib/timr/model/task.rb', line 62 def name_s(max_length = nil) s = name(max_length) if s.nil? '---' else s end end |
#pause(options = Hash.new) ⇒ Object
Pauses a current running Track.
595 596 597 598 599 600 601 602 603 604 |
# File 'lib/timr/model/task.rb', line 595 def pause( = Hash.new) if @current_track @current_track.stop() # Mark Task as changed. changed @current_track end end |
#remaining_time ⇒ Object
Get the remaining Time of estimation.
Returns a Duration instance.
676 677 678 679 680 |
# File 'lib/timr/model/task.rb', line 676 def remaining_time if @estimation estimation - duration end end |
#remaining_time_percent ⇒ Object
Get the remaining Time as percent.
696 697 698 699 700 701 |
# File 'lib/timr/model/task.rb', line 696 def remaining_time_percent rmt = remaining_time if rmt && @estimation (rmt.to_i.to_f / @estimation.to_i.to_f) * 100.0 end end |
#remaining_time_percent_s ⇒ Object
Get the remaining Time Percent as String.
704 705 706 707 708 709 710 711 |
# File 'lib/timr/model/task.rb', line 704 def remaining_time_percent_s rmtp = remaining_time_percent if rmtp '%.1f %%' % [rmtp] else '---' end end |
#remaining_time_s ⇒ Object
Get the remaining Time as Human String.
-
Like ‘2h 30m`.
-
Or ‘—` when `@estimation` is `nil`.
686 687 688 689 690 691 692 693 |
# File 'lib/timr/model/task.rb', line 686 def remaining_time_s rmt = remaining_time if rmt rmt.to_human_s else '---' end end |
#remove_track(track) ⇒ Object
Remove a Track.
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/timr/model/task.rb', line 94 def remove_track(track) track.task = nil if @tracks.delete(track.id) # Mark Task as changed. changed else # Track is not assiged to this Task. false end end |
#reset ⇒ Object
127 128 129 130 131 132 133 134 |
# File 'lib/timr/model/task.rb', line 127 def reset if @current_track @current_track = nil # Mark Task as changed. changed end end |
#start(options = Hash.new) ⇒ Object
Start a new Track by given ‘options`.
Options:
-
‘:foreign_id` (String)
-
‘:track_id` (String)
-
‘:no_stop` (Boolean)
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
# File 'lib/timr/model/task.rb', line 540 def start( = Hash.new) foreign_id_opt = .fetch(:foreign_id, nil) track_id_opt = .fetch(:track_id, nil) # Used by Push. no_stop_opt = .fetch(:no_stop, false) unless no_stop_opt # End current Track before starting a new one. # Leave options empty here for stop(). stop end if foreign_id_opt && @foreign_id.nil? @foreign_id = foreign_id_opt end if track_id_opt found_track = find_track_by_id(track_id_opt) if found_track @current_track = found_track.dup else raise TrackError, "No Track found for Track ID '#{track_id_opt}'." end else @current_track = Track.new @current_track.task = self end @tracks[@current_track.id] = @current_track # Mark Task as changed. changed @current_track.start() @current_track end |
#status ⇒ Object
Get Task status as Status instance.
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 |
# File 'lib/timr/model/task.rb', line 714 def status stati = @tracks.map{ |track_id, track| track.status.short_status }.to_set if @tracks.count == 0 status = ?- elsif stati.include?(?R) status = ?R elsif stati.include?(?S) status = ?S else status = ?U end Status.new(status) end |
#stop(options = Hash.new) ⇒ Object
Stops a current running Track.
580 581 582 583 584 585 586 587 588 589 590 591 592 |
# File 'lib/timr/model/task.rb', line 580 def stop( = Hash.new) if @current_track @current_track.stop() # Reset current Track variable. @current_track = nil # Mark Task as changed. changed end nil end |
#to_compact_array ⇒ Object
Used to print informations to STDOUT.
806 807 808 809 810 811 812 813 814 815 816 817 818 |
# File 'lib/timr/model/task.rb', line 806 def to_compact_array full_id = self.foreign_id ? self.foreign_id : self.short_id to_ax = Array.new to_ax << 'Task: %s %s' % [full_id, self.name] if self.description to_ax << 'Description: %s' % [self.description] end if self.estimation to_ax << 'Estimation: %s' % [self.estimation.to_human_s] end to_ax end |
#to_compact_str ⇒ Object
Used to print informations to STDOUT.
801 802 803 |
# File 'lib/timr/model/task.rb', line 801 def to_compact_str to_compact_array.join("\n") end |
#to_detailed_array(options = Hash.new) ⇒ Object
Used to print informations to STDOUT.
Options:
-
‘:full_id` (Boolean) Show full Task ID.
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 |
# File 'lib/timr/model/task.rb', line 830 def to_detailed_array( = Hash.new) full_id_opt = .fetch(:full_id, false) full_id = full_id_opt ? self.id : self.short_id to_ax = Array.new to_ax << 'Task: %s' % [full_id] if self.foreign_id to_ax << 'Foreign ID: %s' % [self.foreign_id] end to_ax << 'Name: %s' % [self.name] if self.description to_ax << 'Description: %s' % [self.description] end # Duration duration_human = self.duration.to_human_s to_ax << 'Duration: %s' % [duration_human] duration_man_days = self.duration.to_man_days if duration_human != duration_man_days to_ax << 'Man Unit: %s' % [duration_man_days] end # Billed Duration billed_duration_human = self.billed_duration.to_human to_ax << 'Billed Duration: %s' % [billed_duration_human] # Unbilled Duration unbilled_duration_human = self.unbilled_duration.to_human to_ax << 'Unbilled Duration: %s' % [unbilled_duration_human] if self.estimation to_ax << 'Estimation: %s' % [self.estimation.to_human] to_ax << 'Time Remaining: %s (%s)' % [self.remaining_time_s, self.remaining_time_percent_s] = { :total => self.estimation.to_i, :progress => self.duration.to_i, :length => 50, :progress_mark => '#', :remainder_mark => '-', } = ProgressBar.new() to_ax << ' |%s|' % [.render] end if self.hourly_rate to_ax << 'Hourly Rate: %.2f' % [self.hourly_rate] to_ax << 'Flat Rate: %s' % [@has_flat_rate ? 'Yes' : 'No'] to_ax << 'Consumed Budge: %.2f' % [self.consumed_budge] if self.estimation to_ax << 'Estimated Budge: %.2f' % [self.estimated_budge] end if @has_flat_rate to_ax << 'Loss Budge: %.2f' % [self.loss_budge] end end tracks = self.tracks first_track = tracks .select{ |track_id, track| track.begin_datetime } .sort_by{ |track_id, track| track.begin_datetime } .to_h .values .first if first_track to_ax << 'Begin Track: %s %s' % [first_track.short_id, first_track.begin_datetime_s] end last_track = tracks .select{ |track_id, track| track.end_datetime } .sort_by{ |track_id, track| track.end_datetime } .to_h .values .last if last_track to_ax << 'End Track: %s %s' % [last_track.short_id, last_track.end_datetime_s] end status = self.status.colorized to_ax << 'Status: %s' % [status] if @current_track to_ax << 'Current Track: %s %s' % [@current_track.short_id, @current_track.title] end tracks_count = tracks.count to_ax << 'Tracks: %d' % [tracks_count] billed_tracks_count = tracks({:billed => true}).count to_ax << 'Billed Tracks: %d' % [billed_tracks_count] unbilled_tracks_count = tracks({:billed => false}).count to_ax << 'Unbilled Tracks: %d' % [unbilled_tracks_count] if tracks_count > 0 && @tracks_opt # --tracks to_ax << 'Track IDs: %s' % [tracks.map{ |track_id, track| track.short_id }.join(' ')] end if self.file_path to_ax << 'File path: %s' % [self.file_path] end to_ax end |
#to_detailed_str ⇒ Object
Used to print informations to STDOUT.
821 822 823 |
# File 'lib/timr/model/task.rb', line 821 def to_detailed_str to_detailed_array.join("\n") end |
#to_s ⇒ Object
To String
776 777 778 |
# File 'lib/timr/model/task.rb', line 776 def to_s "Task_#{short_id}" end |
#to_track_array(options = Hash.new) ⇒ Object
Use to print informations for Track.
Options:
-
‘:full_id` (Boolean) Show full Task ID.
785 786 787 788 789 790 791 792 793 794 795 796 797 798 |
# File 'lib/timr/model/task.rb', line 785 def to_track_array( = Hash.new) full_id_opt = .fetch(:full_id, false) # @TODO full_id unit test full_id = full_id_opt ? self.id : ( self.foreign_id ? self.foreign_id : self.short_id ) name_a = ['Task:', full_id] if self.name name_a << self.name end to_ax = Array.new to_ax << name_a.join(' ') to_ax end |
#tracks(options = Hash.new) ⇒ Object
Select Track by Time Range and/or Status.
Options:
-
‘:from`, `:to` limit the begin and end datetimes to a specific range.
-
‘:status` filter Tracks by Short Status.
-
‘:billed` filter Tracks by is_billed flag.
- ‘true` filter billed Tracks. - `false` filter unbilled Tracks. - `nil` filter off.
Fixed Start and End (‘from != nil && to != nil`)
“‘ Selected Range |———-| Track A -----------------
Track B ------
Track C ------------
Track D ----
Track E ---
Track F ---
“`
-
Track A is bigger then the Options range. Take it.
-
Track B ends in the Options range. Take it.
-
Track C starts in the Options range. Take it.
-
Track D starts and ends within the Options range. Definitely take this.
-
Track E is out-of-score. Ignore it.
-
Track F is out-of-score. Ignore it.
Open End (‘to == nil`)
Take all except Track E.
“‘ Selected Range |———-> Track A -----------------
Track B ------
Track C ------------
Track D ----
Track E ---
Track F ---
“`
Open Start (‘from == nil`)
Take all except Track F.
“‘ Selected Range <———-| Track A -----------------
Track B ------
Track C ------------
Track D ----
Track E ---
Track F ---
“`
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/timr/model/task.rb', line 195 def tracks( = Hash.new) from_opt = .fetch(:from, nil) to_opt = .fetch(:to, nil) status_opt = .fetch(:status, nil) sort_opt = .fetch(:sort, true) billed_opt = .fetch(:billed, nil) if status_opt case status_opt when String status_opt = [status_opt] when Array # OK else raise TaskError, ":status needs to be an instance of String or Array, #{status_opt.class} given." end end if from_opt && to_opt && from_opt > to_opt raise TaskError, 'From cannot be bigger than To.' end filtered_tracks = Hash.new if from_opt.nil? && to_opt.nil? # Take all Tracks. filtered_tracks = @tracks.select{ |track_id, track| # Filter Tracks with no Begin DateTime. # This can happen when 'timr track add' without any DateTime. !track.begin_datetime.nil? } elsif !from_opt.nil? && to_opt.nil? # Open End (to_opt == nil) filtered_tracks = @tracks.select{ |track_id, track| bdt = track.begin_datetime edt = track.end_datetime || Time.now bdt && ( \ # Track A, B bdt < from_opt && edt > from_opt || \ # Track C, D, F bdt >= from_opt && edt >= from_opt ) } elsif from_opt.nil? && !to_opt.nil? # Open Start (from_opt == nil) filtered_tracks = @tracks.select{ |track_id, track| bdt = track.begin_datetime edt = track.end_datetime || Time.now bdt && ( \ # Track B, D, E bdt < to_opt && edt <= to_opt || \ # Track A, C bdt < to_opt && edt > to_opt ) } elsif !from_opt.nil? && !to_opt.nil? # Fixed Start and End (from_opt != nil && to_opt != nil) filtered_tracks = @tracks.select{ |track_id, track| bdt = track.begin_datetime edt = track.end_datetime || Time.now bdt && ( \ # Track D bdt >= from_opt && edt <= to_opt || \ # Track A bdt < from_opt && edt > to_opt || \ # Track B bdt < from_opt && edt <= to_opt && edt > from_opt || \ # Track C bdt >= from_opt && edt > to_opt && bdt < to_opt ) } else raise ThisShouldNeverHappenError, 'Should never happen, bug shit happens.' end if status_opt filtered_tracks.select!{ |track_id, track| status_opt.include?(track.status.short_status) } end unless billed_opt.nil? if billed_opt filtered_tracks.select!{ |track_id, track| track.is_billed } else filtered_tracks.select!{ |track_id, track| !track.is_billed } end end if sort_opt filtered_tracks.sort{ |t1, t2| t1 = t1.last t2 = t2.last cmp1 = t1.begin_datetime <=> t2.begin_datetime if cmp1.nil? || cmp1 == 0 t1.end_datetime <=> t2.end_datetime else cmp1 end }.to_h else filtered_tracks end end |
#unbilled_duration(options = Hash.new) ⇒ Object
Alias for ‘duration` method.
Options:
-
‘:billed` (Boolean)
669 670 671 |
# File 'lib/timr/model/task.rb', line 669 def unbilled_duration( = Hash.new) duration(.merge({:billed => false})) end |