quickpep 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/quickpep.rb +104 -11
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: eee7a9fb38833422910265d318aa4637b98e426fdc39b0a50d4d8da5f987021f
         | 
| 4 | 
            +
              data.tar.gz: 0ed982bf1fcc5c01ab58616b20695716c365739d964f878b47c565bfac4bc92d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 754edefa43a185656451fcd3ddb948cd3cffebb8da581d379c4d752294634141271369dadb2929deff799f5d2b7bdbf16acc46c59cdb79038c2e36629cbaec93
         | 
| 7 | 
            +
              data.tar.gz: 18a9cc3eb80d9942c887f346699f993d237ddcd456a41db28107279ab2e1914b1d0530c09b4328e29709edad380f48c0489a9edd0d33bd8cacbc8c8baeb9baf5
         | 
    
        checksums.yaml.gz.sig
    CHANGED
    
    | Binary file | 
    
        data/lib/quickpep.rb
    CHANGED
    
    | @@ -11,16 +11,17 @@ require 'event_nlp' | |
| 11 11 | 
             
            class QuickPep
         | 
| 12 12 | 
             
              using ColouredText
         | 
| 13 13 |  | 
| 14 | 
            -
              attr_reader :to_s, :to_dx
         | 
| 14 | 
            +
              attr_reader :to_s, :to_dx, :input
         | 
| 15 15 |  | 
| 16 | 
            -
              def initialize(s, balance: 0, currency: '', today: Date.today, | 
| 16 | 
            +
              def initialize(s, balance: 0, currency: '', today: Date.today,
         | 
| 17 | 
            +
                             ignorewarnings: false, debug: false)
         | 
| 17 18 |  | 
| 18 19 | 
             
                @balance, @currency, @debug = balance, currency, debug
         | 
| 19 20 | 
             
                @today = today
         | 
| 20 21 | 
             
                @warnings = []
         | 
| 21 22 | 
             
                @to_s = calc_expenses(s)
         | 
| 22 23 |  | 
| 23 | 
            -
                warnings() if @warnings.any?
         | 
| 24 | 
            +
                warnings() if @warnings.any? and not ignorewarnings
         | 
| 24 25 |  | 
| 25 26 | 
             
              end
         | 
| 26 27 |  | 
| @@ -60,12 +61,51 @@ class QuickPep | |
| 60 61 |  | 
| 61 62 | 
             
              end
         | 
| 62 63 |  | 
| 63 | 
            -
               | 
| 64 | 
            +
              # Each expense annually as a percentage of total expenses
         | 
| 65 | 
            +
              #
         | 
| 66 | 
            +
              def breakdown()
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                tot = total_expenses().abs
         | 
| 69 | 
            +
                r = annual_costs()
         | 
| 70 | 
            +
                a = r.map {|title, cost| [title, (100 / (tot / cost.abs)).round] }
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def a.to_table()
         | 
| 73 | 
            +
                  TableFormatter.new(source: self,
         | 
| 74 | 
            +
                                    labels: %w(Item %:), markdown: true).display
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                return a
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              def costs_summary()
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                a = %i(year month day).map {|x| annual_costs x}.transpose\
         | 
| 83 | 
            +
                    .map do |x|
         | 
| 84 | 
            +
                  [x.first.first, *x.map {|y| "%s%0.2f" % [@currency, y.last.abs]}]
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
                TableFormatter.new(source: a, labels: %w(Title Year: Month: Day:),
         | 
| 87 | 
            +
                                   markdown: true).display
         | 
| 88 | 
            +
              end
         | 
| 64 89 |  | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 90 | 
            +
              def to_html(titlex="Personal Budget #{@today.year}", title: titlex)
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                dx = to_dx()
         | 
| 93 | 
            +
                t = dx.to_table
         | 
| 94 | 
            +
                t.labels =  %w(date: title debit: credit: balance: uid:)
         | 
| 67 95 | 
             
                table = t.display markdown: true
         | 
| 68 96 |  | 
| 97 | 
            +
                tot = year_end_balance().abs
         | 
| 98 | 
            +
                costs_per_interval = "
         | 
| 99 | 
            +
            * daily: #{"%s%0.2f" % [@currency, (tot / 365.0)]}
         | 
| 100 | 
            +
            * weekly: #{"%s%0.2f" % [@currency, (tot / 52.0)]}
         | 
| 101 | 
            +
            * monthly: #{"%s%0.2f" % [@currency, (tot / 12.0)]}
         | 
| 102 | 
            +
            * yearly: #{@currency + tot.to_s}
         | 
| 103 | 
            +
            "
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                t2 = @input.to_table
         | 
| 106 | 
            +
                t2.labels = %w(Title Amount: :Day: :Recurring: :Notes:)
         | 
| 107 | 
            +
                table2 = t2.display markdown: true
         | 
| 108 | 
            +
             | 
| 69 109 | 
             
                "<html>
         | 
| 70 110 | 
             
                  <head>
         | 
| 71 111 | 
             
                    <meta name='viewport' content='width=device-width, initial-scale=1'>
         | 
| @@ -82,32 +122,84 @@ class QuickPep | |
| 82 122 | 
             
                        }
         | 
| 83 123 |  | 
| 84 124 | 
             
                      }
         | 
| 125 | 
            +
                      table tr td, table thead th {padding: 0.3em; margin: 0.1em}
         | 
| 126 | 
            +
                      #input table {border: 4px;  background-color: #d3a;}
         | 
| 127 | 
            +
                      #input table thead {color: #131;}
         | 
| 128 | 
            +
                      #input table tr, #input table td {border: 1px solid green; padding: 3px;  background-color: #dea;}
         | 
| 129 | 
            +
                      #input table tr td {
         | 
| 130 | 
            +
                        text-align: center;
         | 
| 131 | 
            +
                      }
         | 
| 132 | 
            +
                      #summary div {background-color: transparent; float: left; margin: 0.3em; padding: 1.2em; border: 1px solid #18e}
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                      #breakdown table {background-color: transparent; width: 190px}
         | 
| 135 | 
            +
                      #breakdown table tr {background-color: transparent;}
         | 
| 136 | 
            +
                      #costsum table {background-color: transparent; width: 400px}
         | 
| 137 | 
            +
                      #costsum table tr {background-color: transparent; border-bottom: 1px solid #888;}
         | 
| 138 | 
            +
                      #costsum table tr td {background-color: transparent; padding: 1.0em 0.5em; margin: 0.4em 0.2em}
         | 
| 139 | 
            +
                      #summary div ul  {list-style-type: none; background-color: transparent; padding: 0.5em; }
         | 
| 140 | 
            +
                      .break {page-break-before: always}
         | 
| 141 | 
            +
                      #input {clear: both;}
         | 
| 142 | 
            +
                      footer {font-size: 0.8em; color: #888;}
         | 
| 85 143 | 
             
                    </style>
         | 
| 144 | 
            +
             | 
| 86 145 | 
             
                  </head>
         | 
| 87 146 | 
             
                  <body>
         | 
| 88 147 | 
             
                    <h1>#{title}</h1>
         | 
| 89 148 | 
             
                    #{RDiscount.new(table).to_html}
         | 
| 149 | 
            +
                    <div id='summary'>
         | 
| 150 | 
            +
                      <h2>Summary</h2>
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                      <div id='breakdown'>
         | 
| 153 | 
            +
                      <h3>Breakdown</h3>
         | 
| 154 | 
            +
                      #{RDiscount.new(breakdown().to_table()).to_html}
         | 
| 155 | 
            +
                      </div>
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                      <div id='costsum'>
         | 
| 158 | 
            +
                      <h3>Expense per item</h3>
         | 
| 159 | 
            +
                      #{RDiscount.new(costs_summary()).to_html}
         | 
| 160 | 
            +
                      </div>
         | 
| 161 | 
            +
                      <div>
         | 
| 162 | 
            +
                      <h3>Running expense</h3>
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                      #{RDiscount.new(costs_per_interval).to_html}
         | 
| 165 | 
            +
                      </div>
         | 
| 166 | 
            +
                    </div>
         | 
| 167 | 
            +
                    <div id='input'>
         | 
| 168 | 
            +
                      <h3>Input</h3>
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                      #{RDiscount.new(table2).to_html}
         | 
| 171 | 
            +
                    </div>
         | 
| 90 172 | 
             
                    <hr/>
         | 
| 91 | 
            -
                    <footer>Generated by QuickPEP</footer>
         | 
| 173 | 
            +
                    <footer>Generated by QuickPEP; #{Time.now.strftime("%d %b %Y")}</footer>
         | 
| 92 174 | 
             
                  </body>
         | 
| 93 175 | 
             
                </html>"
         | 
| 94 176 | 
             
              end
         | 
| 95 177 |  | 
| 178 | 
            +
              def total_expenses()
         | 
| 179 | 
            +
                to_dx().all.map {|x| x.debit.sub(/\D/,'').to_f}.sum
         | 
| 180 | 
            +
              end
         | 
| 181 | 
            +
             | 
| 96 182 | 
             
              def warnings()
         | 
| 97 183 | 
             
                @warnings.each {|warning| puts warning.warn }
         | 
| 98 184 | 
             
              end
         | 
| 99 185 |  | 
| 186 | 
            +
              def year_end_balance()
         | 
| 187 | 
            +
                to_dx().all.last.balance.sub(/[^-0-9]+/,'').to_f
         | 
| 188 | 
            +
              end
         | 
| 189 | 
            +
             | 
| 100 190 | 
             
              private
         | 
| 101 191 |  | 
| 102 192 | 
             
              def calc_expenses(s)
         | 
| 103 193 |  | 
| 104 | 
            -
                dx = Dynarex.new(s)
         | 
| 194 | 
            +
                @input = dx = Dynarex.new(s)
         | 
| 105 195 |  | 
| 106 196 | 
             
                @h = dx.all.map {|x| [x.title, x]}.to_h
         | 
| 197 | 
            +
                puts '@h: ' + @h.inspect if @debug
         | 
| 107 198 |  | 
| 108 199 | 
             
                date_events = dx.all.flat_map do |rx|
         | 
| 109 200 |  | 
| 110 | 
            -
                   | 
| 201 | 
            +
                  recurring = rx.recurring.gsub(/(?:yearly|annually)/,'')
         | 
| 202 | 
            +
                  title = [rx.title, rx.day, recurring].join(' ')
         | 
| 111 203 | 
             
                  puts '1. title: ' + title.inspect if @debug
         | 
| 112 204 | 
             
                  e = EventNlp.new(@today.to_time)
         | 
| 113 205 | 
             
                  e.project(title).map {|x| [x.to_date, e.parse(title).title]}
         | 
| @@ -133,7 +225,8 @@ class QuickPep | |
| 133 225 | 
             
                  end
         | 
| 134 226 |  | 
| 135 227 | 
             
                  credit, debit = 0.0, 0.0
         | 
| 136 | 
            -
                   | 
| 228 | 
            +
                  puts 'title: ' + title.inspect if @debug
         | 
| 229 | 
            +
                  amount = @h[title] ? @h[title].amount : ''
         | 
| 137 230 |  | 
| 138 231 | 
             
                  if amount[0] == '+' then
         | 
| 139 232 |  | 
| @@ -180,7 +273,7 @@ class QuickPep | |
| 180 273 | 
             
                  puts [title, debit, credit, balance].inspect if @debug
         | 
| 181 274 |  | 
| 182 275 | 
             
                  row = {
         | 
| 183 | 
            -
                    date: date. | 
| 276 | 
            +
                    date: date.strftime("%b %d"),
         | 
| 184 277 | 
             
                    title: title,
         | 
| 185 278 | 
             
                    debit: debit > 0 ? (@currency + "%.2f" % debit) : '',
         | 
| 186 279 | 
             
                    credit: credit > 0 ? (@currency + "%.2f" % credit) : '',
         | 
    
        data.tar.gz.sig
    CHANGED
    
    | Binary file | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: quickpep
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.2. | 
| 4 | 
            +
              version: 0.2.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - James Robertson
         | 
| @@ -35,7 +35,7 @@ cert_chain: | |
| 35 35 | 
             
              kmcJnzHNiVwSBry7rnILYU3ouLJeHEtQY1v/S4KqPXGNS1FPvas3Wb429Cui2LtB
         | 
| 36 36 | 
             
              CkYfvLZCZS1SZGB2dGilreNS
         | 
| 37 37 | 
             
              -----END CERTIFICATE-----
         | 
| 38 | 
            -
            date: 2022-05- | 
| 38 | 
            +
            date: 2022-05-04 00:00:00.000000000 Z
         | 
| 39 39 | 
             
            dependencies:
         | 
| 40 40 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 41 41 | 
             
              name: event_nlp
         | 
| @@ -46,7 +46,7 @@ dependencies: | |
| 46 46 | 
             
                    version: '0.6'
         | 
| 47 47 | 
             
                - - ">="
         | 
| 48 48 | 
             
                  - !ruby/object:Gem::Version
         | 
| 49 | 
            -
                    version: 0.6. | 
| 49 | 
            +
                    version: 0.6.8
         | 
| 50 50 | 
             
              type: :runtime
         | 
| 51 51 | 
             
              prerelease: false
         | 
| 52 52 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| @@ -56,7 +56,7 @@ dependencies: | |
| 56 56 | 
             
                    version: '0.6'
         | 
| 57 57 | 
             
                - - ">="
         | 
| 58 58 | 
             
                  - !ruby/object:Gem::Version
         | 
| 59 | 
            -
                    version: 0.6. | 
| 59 | 
            +
                    version: 0.6.8
         | 
| 60 60 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 61 61 | 
             
              name: dynarex
         | 
| 62 62 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
    
        metadata.gz.sig
    CHANGED
    
    | Binary file |