lucadeal 0.4.2 → 0.5.1
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
- data/CHANGELOG.md +13 -0
- data/exe/luca-deal +69 -24
- data/lib/luca_deal/fee.rb +11 -12
- data/lib/luca_deal/invoice.rb +46 -21
- data/lib/luca_deal/templates/monthly-payment-list.html.erb +23 -0
- data/lib/luca_deal/version.rb +1 -1
- metadata +9 -9
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2f5f085a31ba8be8e56a772cb3d063a42407e84d2901078e56d09989c6e04109
         | 
| 4 | 
            +
              data.tar.gz: 15b4a9fe3f0dfc7ede51ab9557fbbe565bbbd3182733b7b6d4a1aca9b351e077
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 6f206506d1baa62b50c8a95e6cf0ded18ee6b4de6453f3a3d1a41d2b2c21060c846912dd85527ebe015816928804d87bfe70685fe380a06740ca402b1f6a4b73
         | 
| 7 | 
            +
              data.tar.gz: 0b4a9b3d469a89ee0216735ec97c0df8eb5a0c29bd0bd0835b8182268fcaa72215052c0b018c64f4a2f06de69790429a094c31d6c59412246feb06386c9a4e10
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,16 @@ | |
| 1 | 
            +
            ## LucaDeal 0.5.1
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Refine `luca-deal customer list` output: Limit columns to name, address and id.
         | 
| 4 | 
            +
            * Reworked global constants w/LucaRecord v0.7
         | 
| 5 | 
            +
            * Removed bundler from test suite avoiding casual native build
         | 
| 6 | 
            +
            * add `luca-deal version` subcommand
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            ## LucaDeal 0.5.0
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            * `luca-deal` command now searches valid sub directory.
         | 
| 11 | 
            +
            * `luca-deal invoices list` has `--full` option with additional settlement info.
         | 
| 12 | 
            +
              * `--mail --full` lists unsettled table.
         | 
| 13 | 
            +
             | 
| 1 14 | 
             
            ## LucaDeal 0.4.2
         | 
| 2 15 |  | 
| 3 16 | 
             
            * `luca-deal custoer|invoice|fee list`, `luca-deal reports balance` supports interactive `--explore` w/nushell.
         | 
    
        data/exe/luca-deal
    CHANGED
    
    | @@ -1,9 +1,12 @@ | |
| 1 1 | 
             
            #!/usr/bin/ruby
         | 
| 2 2 | 
             
            # frozen_string_literal: true
         | 
| 3 3 |  | 
| 4 | 
            +
            REQUIRED_DIR='customers'
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
            require 'date'
         | 
| 5 7 | 
             
            require 'optparse'
         | 
| 6 8 | 
             
            require 'luca_deal'
         | 
| 9 | 
            +
            require 'luca_cmd'
         | 
| 7 10 |  | 
| 8 11 | 
             
            class LucaCmd
         | 
| 9 12 | 
             
              class Customer < LucaCmd
         | 
| @@ -57,6 +60,7 @@ class LucaCmd | |
| 57 60 | 
             
                end
         | 
| 58 61 |  | 
| 59 62 | 
             
                def self.list(args = nil, params = {})
         | 
| 63 | 
            +
                  params[:col_order] = %w(name address id)
         | 
| 60 64 | 
             
                  render(LucaDeal::Customer.new.list_name, params)
         | 
| 61 65 | 
             
                end
         | 
| 62 66 | 
             
              end
         | 
| @@ -131,7 +135,7 @@ class LucaCmd | |
| 131 135 | 
             
                    LucaDeal::NoInvoice.new(date).monthly_invoice
         | 
| 132 136 | 
             
                    LucaDeal::Fee.new(date).monthly_fee if params[:fee]
         | 
| 133 137 | 
             
                    if params[:mail]
         | 
| 134 | 
            -
                      LucaDeal::Invoice.new(date).stats_email
         | 
| 138 | 
            +
                      LucaDeal::Invoice.new(date).stats_email(3, mode: 'full')
         | 
| 135 139 | 
             
                    end
         | 
| 136 140 | 
             
                  else
         | 
| 137 141 | 
             
                    date = "#{args[1]}-#{args[2]}-#{args[3] || '1'}" if !args.empty?
         | 
| @@ -178,9 +182,9 @@ class LucaCmd | |
| 178 182 | 
             
                    count = 3
         | 
| 179 183 | 
             
                  end
         | 
| 180 184 | 
             
                  if params[:mail]
         | 
| 181 | 
            -
                    LucaDeal::Invoice.new(date).stats_email
         | 
| 185 | 
            +
                    LucaDeal::Invoice.new(date).stats_email(3, mode: params[:mode])
         | 
| 182 186 | 
             
                  else
         | 
| 183 | 
            -
                    render(LucaDeal::Invoice.new(date).stats(count || 1), params)
         | 
| 187 | 
            +
                    render(LucaDeal::Invoice.new(date).stats(count || 1, mode: params[:mode]), params)
         | 
| 184 188 | 
             
                  end
         | 
| 185 189 | 
             
                end
         | 
| 186 190 |  | 
| @@ -274,7 +278,7 @@ class LucaCmd | |
| 274 278 | 
             
                when 'json'
         | 
| 275 279 | 
             
                  puts JSON.dump(dat)
         | 
| 276 280 | 
             
                when 'nu'
         | 
| 277 | 
            -
                  LucaSupport::View.nushell(dat, :expand)
         | 
| 281 | 
            +
                  LucaSupport::View.nushell(dat, :expand, params[:col_order] || [])
         | 
| 278 282 | 
             
                when 'explore'
         | 
| 279 283 | 
             
                  LucaSupport::View.nushell(dat, :explore)
         | 
| 280 284 | 
             
                when 'csv'
         | 
| @@ -293,7 +297,6 @@ def new_pj(args = nil, params = {}) | |
| 293 297 | 
             
              LucaDeal::Setup.create_project args[0]
         | 
| 294 298 | 
             
            end
         | 
| 295 299 |  | 
| 296 | 
            -
            LucaRecord::Base.valid_project?
         | 
| 297 300 | 
             
            cmd = ARGV.shift
         | 
| 298 301 | 
             
            params = {}
         | 
| 299 302 |  | 
| @@ -305,7 +308,9 @@ when /customers?/ | |
| 305 308 | 
             
                OptionParser.new do |opt|
         | 
| 306 309 | 
             
                  opt.banner = 'Usage: luca-deal customers create CustomerName'
         | 
| 307 310 | 
             
                  args = opt.parse(ARGV)
         | 
| 308 | 
            -
                  LucaCmd | 
| 311 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 312 | 
            +
                    LucaCmd::Customer.create(args, params)
         | 
| 313 | 
            +
                  end
         | 
| 309 314 | 
             
                end
         | 
| 310 315 | 
             
              when 'list'
         | 
| 311 316 | 
             
                OptionParser.new do |opt|
         | 
| @@ -314,7 +319,9 @@ when /customers?/ | |
| 314 319 | 
             
                  opt.on('--explore', 'explore table in nushell') { |_v| params[:output] = 'explore' }
         | 
| 315 320 | 
             
                  opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
         | 
| 316 321 | 
             
                  args = opt.parse(ARGV)
         | 
| 317 | 
            -
                  LucaCmd | 
| 322 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 323 | 
            +
                    LucaCmd::Customer.list(args, params)
         | 
| 324 | 
            +
                  end
         | 
| 318 325 | 
             
                end
         | 
| 319 326 | 
             
              when 'describe'
         | 
| 320 327 | 
             
                OptionParser.new do |opt|
         | 
| @@ -322,10 +329,14 @@ when /customers?/ | |
| 322 329 | 
             
                  opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
         | 
| 323 330 | 
             
                  opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
         | 
| 324 331 | 
             
                  args = opt.parse(ARGV)
         | 
| 325 | 
            -
                  LucaCmd | 
| 332 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 333 | 
            +
                    LucaCmd::Customer.describe(args, params)
         | 
| 334 | 
            +
                  end
         | 
| 326 335 | 
             
                end
         | 
| 327 336 | 
             
              when 'delete'
         | 
| 328 | 
            -
                LucaCmd | 
| 337 | 
            +
                LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 338 | 
            +
                  LucaCmd::Customer.delete(ARGV)
         | 
| 339 | 
            +
                end
         | 
| 329 340 | 
             
              else
         | 
| 330 341 | 
             
                puts 'Proper subcommand needed.'
         | 
| 331 342 | 
             
                puts
         | 
| @@ -346,7 +357,9 @@ when /contracts?/ | |
| 346 357 | 
             
                    params['category'] = 'sales_fee'
         | 
| 347 358 | 
             
                  end
         | 
| 348 359 | 
             
                  args = opt.parse(ARGV)
         | 
| 349 | 
            -
                  LucaCmd | 
| 360 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 361 | 
            +
                    LucaCmd::Contract.create(args, params)
         | 
| 362 | 
            +
                  end
         | 
| 350 363 | 
             
                end
         | 
| 351 364 | 
             
              when 'describe'
         | 
| 352 365 | 
             
                OptionParser.new do |opt|
         | 
| @@ -354,10 +367,14 @@ when /contracts?/ | |
| 354 367 | 
             
                  opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
         | 
| 355 368 | 
             
                  opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
         | 
| 356 369 | 
             
                  args = opt.parse(ARGV)
         | 
| 357 | 
            -
                  LucaCmd | 
| 370 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 371 | 
            +
                    LucaCmd::Contract.describe(args, params)
         | 
| 372 | 
            +
                  end
         | 
| 358 373 | 
             
                end
         | 
| 359 374 | 
             
              when 'delete'
         | 
| 360 | 
            -
                LucaCmd | 
| 375 | 
            +
                LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 376 | 
            +
                  LucaCmd::Contract.delete(ARGV)
         | 
| 377 | 
            +
                end
         | 
| 361 378 | 
             
              else
         | 
| 362 379 | 
             
                puts 'Proper subcommand needed.'
         | 
| 363 380 | 
             
                puts
         | 
| @@ -368,7 +385,9 @@ when /contracts?/ | |
| 368 385 | 
             
                exit 1
         | 
| 369 386 | 
             
              end
         | 
| 370 387 | 
             
            when 'export'
         | 
| 371 | 
            -
              LucaCmd | 
| 388 | 
            +
              LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 389 | 
            +
                LucaCmd::Invoice.export(ARGV)
         | 
| 390 | 
            +
              end
         | 
| 372 391 | 
             
            when /invoices?/, 'i'
         | 
| 373 392 | 
             
              subcmd = ARGV.shift
         | 
| 374 393 | 
             
              case subcmd
         | 
| @@ -379,10 +398,14 @@ when /invoices?/, 'i' | |
| 379 398 | 
             
                  opt.on('--monthly', 'generate monthly data') { |_v| params[:mode] = 'monthly' }
         | 
| 380 399 | 
             
                  opt.on('--with-fee', 'generate sales fee data after monthly invoice creation') { |_v| params[:fee] = true }
         | 
| 381 400 | 
             
                  args = opt.parse(ARGV)
         | 
| 382 | 
            -
                  LucaCmd | 
| 401 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 402 | 
            +
                    LucaCmd::Invoice.create(args, params)
         | 
| 403 | 
            +
                  end
         | 
| 383 404 | 
             
                end
         | 
| 384 405 | 
             
              when 'delete'
         | 
| 385 | 
            -
                LucaCmd | 
| 406 | 
            +
                LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 407 | 
            +
                  LucaCmd::Invoice.delete(ARGV)
         | 
| 408 | 
            +
                end
         | 
| 386 409 | 
             
              when 'list'
         | 
| 387 410 | 
             
                OptionParser.new do |opt|
         | 
| 388 411 | 
             
                  opt.banner = 'Usage: luca-deal invoices list [options] year month [date]'
         | 
| @@ -390,8 +413,11 @@ when /invoices?/, 'i' | |
| 390 413 | 
             
                  opt.on('--explore', 'explore table in nushell') { |_v| params[:output] = 'explore' }
         | 
| 391 414 | 
             
                  opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
         | 
| 392 415 | 
             
                  opt.on('--mail', 'send payment list by email') { |_v| params[:mail] = true }
         | 
| 416 | 
            +
                  opt.on('--full', 'add settlement info') { |_v| params[:mode] = 'full' }
         | 
| 393 417 | 
             
                  args = opt.parse(ARGV)
         | 
| 394 | 
            -
                  LucaCmd | 
| 418 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 419 | 
            +
                    LucaCmd::Invoice.list(args, params)
         | 
| 420 | 
            +
                  end
         | 
| 395 421 | 
             
                end
         | 
| 396 422 | 
             
              when 'mail'
         | 
| 397 423 | 
             
                OptionParser.new do |opt|
         | 
| @@ -405,7 +431,9 @@ when /invoices?/, 'i' | |
| 405 431 | 
             
                  opt.banner = 'Usage: luca-deal invoices print [options] <invoice_id | year month>'
         | 
| 406 432 | 
             
                  opt.on('--pdf', 'output PDF invoices. wkhtmlpdf is required') { |_v| params[:output] = :pdf }
         | 
| 407 433 | 
             
                  args = opt.parse(ARGV)
         | 
| 408 | 
            -
                  LucaCmd | 
| 434 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 435 | 
            +
                    LucaCmd::Invoice.print(args, params)
         | 
| 436 | 
            +
                  end
         | 
| 409 437 | 
             
                end
         | 
| 410 438 | 
             
              when 'settle'
         | 
| 411 439 | 
             
                params[:term] = 1
         | 
| @@ -413,7 +441,9 @@ when /invoices?/, 'i' | |
| 413 441 | 
             
                  opt.banner = 'Usage: luca-deal invoices settle [filepath]'
         | 
| 414 442 | 
             
                  opt.on('--search-term VAL', 'search invoice N months before payment date. default: 1') { |v| params[:term] = v.to_i }
         | 
| 415 443 | 
             
                  args = opt.parse(ARGV)
         | 
| 416 | 
            -
                  LucaCmd | 
| 444 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 445 | 
            +
                    LucaCmd::Invoice.settle(args, params)
         | 
| 446 | 
            +
                  end
         | 
| 417 447 | 
             
                end
         | 
| 418 448 | 
             
              else
         | 
| 419 449 | 
             
                puts 'Proper subcommand needed.'
         | 
| @@ -441,7 +471,9 @@ when /reports?/, 'r' | |
| 441 471 | 
             
                  opt.on('--detail', 'show detail info') { |_v| params[:detail] = true }
         | 
| 442 472 | 
             
                  opt.on('--force-due', 'respect due date over actual payment') { |_v| params[:due] = true }
         | 
| 443 473 | 
             
                  args = opt.parse(ARGV)
         | 
| 444 | 
            -
                  LucaCmd | 
| 474 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 475 | 
            +
                    LucaCmd::Invoice.report(args, params)
         | 
| 476 | 
            +
                  end
         | 
| 445 477 | 
             
                end
         | 
| 446 478 | 
             
              else
         | 
| 447 479 | 
             
                puts 'Proper subcommand needed.'
         | 
| @@ -465,12 +497,18 @@ when /fee/ | |
| 465 497 | 
             
                  opt.banner = 'Usage: luca-deal fee create [options] year month [date]'
         | 
| 466 498 | 
             
                  opt.on('--monthly', 'generate monthly data') { |_v| params[:mode] = 'monthly' }
         | 
| 467 499 | 
             
                  args = opt.parse(ARGV)
         | 
| 468 | 
            -
                  LucaCmd | 
| 500 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 501 | 
            +
                    LucaCmd::Fee.create(args, params)
         | 
| 502 | 
            +
                  end
         | 
| 469 503 | 
             
                end
         | 
| 470 504 | 
             
              when 'delete'
         | 
| 471 | 
            -
                LucaCmd | 
| 505 | 
            +
                LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 506 | 
            +
                  LucaCmd::Fee.delete(ARGV)
         | 
| 507 | 
            +
                end
         | 
| 472 508 | 
             
              when 'export'
         | 
| 473 | 
            -
                LucaCmd | 
| 509 | 
            +
                LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 510 | 
            +
                  LucaCmd::Fee.export(ARGV)
         | 
| 511 | 
            +
                end
         | 
| 474 512 | 
             
              when 'list'
         | 
| 475 513 | 
             
                OptionParser.new do |opt|
         | 
| 476 514 | 
             
                  opt.banner = 'Usage: luca-deal fee list [options] year month [date]'
         | 
| @@ -479,14 +517,18 @@ when /fee/ | |
| 479 517 | 
             
                  opt.on('-o', '--output VAL', 'output serialized data') { |v| params[:output] = v }
         | 
| 480 518 | 
             
                  opt.on('--html', 'output html invoices') { |_v| params[:html] = 'monthly' }
         | 
| 481 519 | 
             
                  args = opt.parse(ARGV)
         | 
| 482 | 
            -
                  LucaCmd | 
| 520 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 521 | 
            +
                    LucaCmd::Fee.list(args, params)
         | 
| 522 | 
            +
                  end
         | 
| 483 523 | 
             
                end
         | 
| 484 524 | 
             
              when 'mail'
         | 
| 485 525 | 
             
                OptionParser.new do |opt|
         | 
| 486 526 | 
             
                  opt.banner = 'Usage: luca-deal fee mail [options] year month [date]'
         | 
| 487 527 | 
             
                  opt.on('--preview', 'send to preview user') { |_v| params['mode'] = 'preview' }
         | 
| 488 528 | 
             
                  args = opt.parse(ARGV)
         | 
| 489 | 
            -
                  LucaCmd | 
| 529 | 
            +
                  LucaCmd.check_dir(REQUIRED_DIR) do
         | 
| 530 | 
            +
                    LucaCmd::Fee.mail(args, params)
         | 
| 531 | 
            +
                  end
         | 
| 490 532 | 
             
                end
         | 
| 491 533 | 
             
              else
         | 
| 492 534 | 
             
                puts 'Proper subcommand needed.'
         | 
| @@ -498,6 +540,9 @@ when /fee/ | |
| 498 540 | 
             
                puts '  mail: send mail with report'
         | 
| 499 541 | 
             
                exit 1
         | 
| 500 542 | 
             
              end
         | 
| 543 | 
            +
            when 'version'
         | 
| 544 | 
            +
              puts "luca-deal: version #{LucaDeal::VERSION}"
         | 
| 545 | 
            +
              exit 0
         | 
| 501 546 | 
             
            else
         | 
| 502 547 | 
             
              puts 'Proper subcommand needed.'
         | 
| 503 548 | 
             
              puts
         | 
    
        data/lib/luca_deal/fee.rb
    CHANGED
    
    | @@ -5,7 +5,6 @@ require 'json' | |
| 5 5 | 
             
            require 'yaml'
         | 
| 6 6 | 
             
            require 'pathname'
         | 
| 7 7 | 
             
            require 'bigdecimal'
         | 
| 8 | 
            -
            require 'luca_support/config'
         | 
| 9 8 | 
             
            require 'luca_support/mail'
         | 
| 10 9 | 
             
            require 'luca_deal'
         | 
| 11 10 |  | 
| @@ -67,7 +66,7 @@ module LucaDeal | |
| 67 66 | 
             
                end
         | 
| 68 67 |  | 
| 69 68 | 
             
                def deliver_mail(attachment_type = nil, mode: nil, skip_no_item: true)
         | 
| 70 | 
            -
                  attachment_type =  | 
| 69 | 
            +
                  attachment_type = CONST.config.dig('fee', 'attachment') || :html
         | 
| 71 70 | 
             
                  fees = self.class.asof(@date.year, @date.month)
         | 
| 72 71 | 
             
                  raise "No report for #{@date.year}/#{@date.month}" if fees.count.zero?
         | 
| 73 72 |  | 
| @@ -76,7 +75,7 @@ module LucaDeal | |
| 76 75 | 
             
                    next if skip_no_item && dat['items'].empty?
         | 
| 77 76 |  | 
| 78 77 | 
             
                    mail = compose_mail(dat, mode: mode, attachment: attachment_type.to_sym)
         | 
| 79 | 
            -
                    LucaSupport::Mail.new(mail,  | 
| 78 | 
            +
                    LucaSupport::Mail.new(mail, CONST.pjdir).deliver
         | 
| 80 79 | 
             
                    self.class.add_status!(path, 'mail_delivered') if mode.nil?
         | 
| 81 80 | 
             
                  end
         | 
| 82 81 | 
             
                end
         | 
| @@ -101,9 +100,9 @@ module LucaDeal | |
| 101 100 |  | 
| 102 101 | 
             
                  mail = Mail.new
         | 
| 103 102 | 
             
                  mail.to = dat.dig('customer', 'to') if mode.nil?
         | 
| 104 | 
            -
                  mail.subject =  | 
| 103 | 
            +
                  mail.subject = CONST.config.dig('fee', 'mail_subject') || 'Your Report is available'
         | 
| 105 104 | 
             
                  if mode == :preview
         | 
| 106 | 
            -
                    mail.cc =  | 
| 105 | 
            +
                    mail.cc = CONST.config.dig('mail', 'preview') || CONST.config.dig('mail', 'from')
         | 
| 107 106 | 
             
                    mail.subject = '[preview] ' + mail.subject
         | 
| 108 107 | 
             
                  end
         | 
| 109 108 | 
             
                  mail.text_part = Mail::Part.new(body: render_erb(search_template('fee-report-mail.txt.erb')), charset: 'UTF-8')
         | 
| @@ -224,10 +223,10 @@ module LucaDeal | |
| 224 223 | 
             
                  __dir__
         | 
| 225 224 | 
             
                end
         | 
| 226 225 |  | 
| 227 | 
            -
                # TODO: load labels from  | 
| 226 | 
            +
                # TODO: load labels from CONST.config before country defaults
         | 
| 228 227 | 
             
                #
         | 
| 229 228 | 
             
                def export_labels
         | 
| 230 | 
            -
                  case  | 
| 229 | 
            +
                  case CONST.confg['country']
         | 
| 231 230 | 
             
                  when 'jp'
         | 
| 232 231 | 
             
                    {
         | 
| 233 232 | 
             
                      debit: { fee: '支払手数料', tax: '支払手数料', deduction: '未払費用' },
         | 
| @@ -245,9 +244,9 @@ module LucaDeal | |
| 245 244 | 
             
                #
         | 
| 246 245 | 
             
                def set_company
         | 
| 247 246 | 
             
                  {}.tap do |h|
         | 
| 248 | 
            -
                    h['name'] =  | 
| 249 | 
            -
                    h['address'] =  | 
| 250 | 
            -
                    h['address2'] =  | 
| 247 | 
            +
                    h['name'] = CONST.config.dig('company', 'name')
         | 
| 248 | 
            +
                    h['address'] = CONST.config.dig('company', 'address')
         | 
| 249 | 
            +
                    h['address2'] = CONST.config.dig('company', 'address2')
         | 
| 251 250 | 
             
                  end
         | 
| 252 251 | 
             
                end
         | 
| 253 252 |  | 
| @@ -281,9 +280,9 @@ module LucaDeal | |
| 281 280 | 
             
                # load Tax Rate from config.
         | 
| 282 281 | 
             
                #
         | 
| 283 282 | 
             
                def load_tax_rate(name)
         | 
| 284 | 
            -
                  return 0 if  | 
| 283 | 
            +
                  return 0 if CONST.config.dig('tax_rate', name).nil?
         | 
| 285 284 |  | 
| 286 | 
            -
                  BigDecimal(take_current( | 
| 285 | 
            +
                  BigDecimal(take_current(CONST.config['tax_rate'], name).to_s)
         | 
| 287 286 | 
             
                end
         | 
| 288 287 |  | 
| 289 288 | 
             
                # Fees are unique contract_id in each month
         | 
    
        data/lib/luca_deal/invoice.rb
    CHANGED
    
    | @@ -6,7 +6,6 @@ require 'yaml' | |
| 6 6 | 
             
            require 'pathname'
         | 
| 7 7 | 
             
            require 'bigdecimal'
         | 
| 8 8 | 
             
            require 'luca_support/code'
         | 
| 9 | 
            -
            require 'luca_support/config'
         | 
| 10 9 | 
             
            require 'luca_support/mail'
         | 
| 11 10 | 
             
            require 'luca_deal/contract'
         | 
| 12 11 | 
             
            require 'luca_record'
         | 
| @@ -69,9 +68,9 @@ module LucaDeal | |
| 69 68 |  | 
| 70 69 | 
             
                  mail = Mail.new
         | 
| 71 70 | 
             
                  mail.to = dat.dig('customer', 'to') if mode.nil?
         | 
| 72 | 
            -
                  mail.subject =  | 
| 71 | 
            +
                  mail.subject = LucaRecord::CONST.config.dig('invoice', 'mail_subject') || 'Your Invoice is available'
         | 
| 73 72 | 
             
                  if mode == :preview
         | 
| 74 | 
            -
                    mail.cc =  | 
| 73 | 
            +
                    mail.cc = LucaRecord::CONST.config.dig('mail', 'preview') || LucaRecord::CONST.config.dig('mail', 'from')
         | 
| 75 74 | 
             
                    mail.subject = '[preview] ' + mail.subject
         | 
| 76 75 | 
             
                  end
         | 
| 77 76 | 
             
                  mail.text_part = Mail::Part.new(body: render_erb(search_template('invoice-mail.txt.erb')), charset: 'UTF-8')
         | 
| @@ -221,7 +220,7 @@ module LucaDeal | |
| 221 220 | 
             
                #     total: 100000
         | 
| 222 221 | 
             
                #     tax: 10000
         | 
| 223 222 | 
             
                #
         | 
| 224 | 
            -
                def stats(count = 1)
         | 
| 223 | 
            +
                def stats(count = 1, mode: nil)
         | 
| 225 224 | 
             
                  [].tap do |collection|
         | 
| 226 225 | 
             
                    scan_date = @date.next_month
         | 
| 227 226 | 
             
                    count.times do
         | 
| @@ -235,8 +234,13 @@ module LucaDeal | |
| 235 234 | 
             
                            'subtotal' => amount,
         | 
| 236 235 | 
             
                            'tax' => tax,
         | 
| 237 236 | 
             
                            'due' => invoice.dig('due_date'),
         | 
| 238 | 
            -
                            'mail' => invoice.dig('status')&.select { |a| a.keys.include?('mail_delivered') }&.first
         | 
| 239 | 
            -
                          }
         | 
| 237 | 
            +
                            'mail' => invoice.dig('status')&.select { |a| a.keys.include?('mail_delivered') }&.first,
         | 
| 238 | 
            +
                          }.tap do |r|
         | 
| 239 | 
            +
                            if mode == 'full'
         | 
| 240 | 
            +
                              r['settled'] = invoice.dig('settled', 'amount')
         | 
| 241 | 
            +
                              r['settle_date'] = invoice.dig('settled', 'date')
         | 
| 242 | 
            +
                            end
         | 
| 243 | 
            +
                          end
         | 
| 240 244 | 
             
                        end
         | 
| 241 245 | 
             
                        stat['issue_date'] = scan_date.to_s
         | 
| 242 246 | 
             
                        stat['count'] = stat['records'].count
         | 
| @@ -250,14 +254,25 @@ module LucaDeal | |
| 250 254 |  | 
| 251 255 | 
             
                # send payment list to preview address or from address.
         | 
| 252 256 | 
             
                #
         | 
| 253 | 
            -
                def stats_email
         | 
| 257 | 
            +
                def stats_email(count = 3, mode: nil)
         | 
| 254 258 | 
             
                  {}.tap do |res|
         | 
| 255 | 
            -
                    stats( | 
| 259 | 
            +
                    stats(count, mode: mode).each.with_index(1) do |stat, i|
         | 
| 256 260 | 
             
                      stat['records'].each do |record|
         | 
| 257 261 | 
             
                        res[record['customer']] ||= {}
         | 
| 258 262 | 
             
                        res[record['customer']]['customer_name'] ||= record['customer']
         | 
| 259 | 
            -
                        res[record['customer']]["amount#{i}"] ||= record['subtotal']
         | 
| 263 | 
            +
                        res[record['customer']]["amount#{i}"] ||= record['subtotal'].to_s
         | 
| 260 264 | 
             
                        res[record['customer']]["tax#{i}"] ||= record['tax']
         | 
| 265 | 
            +
                        next if mode != 'full' || ! record['settled']
         | 
| 266 | 
            +
             | 
| 267 | 
            +
                        diff = ['subtotal', 'tax', 'settled'].map { |k| record[k] }.compact.sum
         | 
| 268 | 
            +
                        mark = if diff == 0
         | 
| 269 | 
            +
                                 '[S]'
         | 
| 270 | 
            +
                               elsif diff > 0
         | 
| 271 | 
            +
                                 '[P]'
         | 
| 272 | 
            +
                               else
         | 
| 273 | 
            +
                                 '[O]'
         | 
| 274 | 
            +
                               end
         | 
| 275 | 
            +
                        res[record['customer']]["amount#{i}"].insert(0, mark)
         | 
| 261 276 | 
             
                      end
         | 
| 262 277 | 
             
                      if i == 1
         | 
| 263 278 | 
             
                        @issue_date = stat['issue_date']
         | 
| @@ -268,13 +283,23 @@ module LucaDeal | |
| 268 283 | 
             
                    end
         | 
| 269 284 | 
             
                    @invoices = res.values
         | 
| 270 285 | 
             
                  end
         | 
| 271 | 
            -
                  @company =  | 
| 286 | 
            +
                  @company = LucaRecord::CONST.config.dig('company', 'name')
         | 
| 287 | 
            +
                  @legend = if mode == 'full'
         | 
| 288 | 
            +
                              '[S] Settled, [P] Partially settled, [O] Overpaid'
         | 
| 289 | 
            +
                            else
         | 
| 290 | 
            +
                              ''
         | 
| 291 | 
            +
                            end
         | 
| 292 | 
            +
                  @unsettled = if mode == 'full'
         | 
| 293 | 
            +
                                 self.class.report(@date)
         | 
| 294 | 
            +
                               else
         | 
| 295 | 
            +
                                 []
         | 
| 296 | 
            +
                               end
         | 
| 272 297 |  | 
| 273 298 | 
             
                  mail = Mail.new
         | 
| 274 | 
            -
                  mail.to =  | 
| 299 | 
            +
                  mail.to = LucaRecord::CONST.config.dig('mail', 'preview') || LucaRecord::CONST.config.dig('mail', 'from')
         | 
| 275 300 | 
             
                  mail.subject = 'Check monthly payment list'
         | 
| 276 301 | 
             
                  mail.html_part = Mail::Part.new(body: render_erb(search_template('monthly-payment-list.html.erb')), content_type: 'text/html; charset=UTF-8')
         | 
| 277 | 
            -
                  LucaSupport::Mail.new(mail,  | 
| 302 | 
            +
                  LucaSupport::Mail.new(mail, LucaRecord::CONST.pjdir).deliver
         | 
| 278 303 | 
             
                end
         | 
| 279 304 |  | 
| 280 305 | 
             
                def export_json
         | 
| @@ -395,9 +420,9 @@ module LucaDeal | |
| 395 420 | 
             
                end
         | 
| 396 421 |  | 
| 397 422 | 
             
                def deliver_one(invoice, path, mode: nil, attachment_type: nil)
         | 
| 398 | 
            -
                  attachment_type ||=  | 
| 423 | 
            +
                  attachment_type ||= LucaRecord::CONST.config.dig('invoice', 'attachment') || :html
         | 
| 399 424 | 
             
                  mail = compose_mail(invoice, mode: mode, attachment: attachment_type.to_sym)
         | 
| 400 | 
            -
                  LucaSupport::Mail.new(mail,  | 
| 425 | 
            +
                  LucaSupport::Mail.new(mail, LucaRecord::CONST.pjdir).deliver
         | 
| 401 426 | 
             
                  self.class.add_status!(path, 'mail_delivered') if mode.nil?
         | 
| 402 427 | 
             
                end
         | 
| 403 428 |  | 
| @@ -405,10 +430,10 @@ module LucaDeal | |
| 405 430 | 
             
                  __dir__
         | 
| 406 431 | 
             
                end
         | 
| 407 432 |  | 
| 408 | 
            -
                # TODO: load labels from  | 
| 433 | 
            +
                # TODO: load labels from LucaRecord::CONST.config before country defaults
         | 
| 409 434 | 
             
                #
         | 
| 410 435 | 
             
                def export_labels
         | 
| 411 | 
            -
                  case  | 
| 436 | 
            +
                  case LucaRecord::CONST.config['country']
         | 
| 412 437 | 
             
                  when 'jp'
         | 
| 413 438 | 
             
                    {
         | 
| 414 439 | 
             
                      debit: { items: '売掛金', tax: '売掛金' },
         | 
| @@ -426,9 +451,9 @@ module LucaDeal | |
| 426 451 | 
             
                #
         | 
| 427 452 | 
             
                def set_company
         | 
| 428 453 | 
             
                  {}.tap do |h|
         | 
| 429 | 
            -
                    h['name'] =  | 
| 430 | 
            -
                    h['address'] =  | 
| 431 | 
            -
                    h['address2'] =  | 
| 454 | 
            +
                    h['name'] = LucaRecord::CONST.config.dig('company', 'name')
         | 
| 455 | 
            +
                    h['address'] = LucaRecord::CONST.config.dig('company', 'address')
         | 
| 456 | 
            +
                    h['address2'] = LucaRecord::CONST.config.dig('company', 'address2')
         | 
| 432 457 | 
             
                  end
         | 
| 433 458 | 
             
                end
         | 
| 434 459 |  | 
| @@ -451,9 +476,9 @@ module LucaDeal | |
| 451 476 | 
             
                # load Tax Rate from config.
         | 
| 452 477 | 
             
                #
         | 
| 453 478 | 
             
                def load_tax_rate(name)
         | 
| 454 | 
            -
                  return 0 if  | 
| 479 | 
            +
                  return 0 if LucaRecord::CONST.config.dig('tax_rate', name).nil?
         | 
| 455 480 |  | 
| 456 | 
            -
                  BigDecimal(take_current( | 
| 481 | 
            +
                  BigDecimal(take_current(LucaRecord::CONST.config['tax_rate'], name).to_s)
         | 
| 457 482 | 
             
                end
         | 
| 458 483 |  | 
| 459 484 | 
             
                def attachment_name(dat, type)
         | 
| @@ -50,5 +50,28 @@ | |
| 50 50 | 
             
                            </tr>
         | 
| 51 51 | 
             
                        </tbody>
         | 
| 52 52 | 
             
                    </table>
         | 
| 53 | 
            +
                    <div style="margin: 1em 0"><%= @legend %></div>
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    <% if ! @unsettled.empty? %>
         | 
| 56 | 
            +
                        <h3 style="margin: 1em 0">Unsettled</h3>
         | 
| 57 | 
            +
                        <table>
         | 
| 58 | 
            +
                            <thead>
         | 
| 59 | 
            +
                                <tr>
         | 
| 60 | 
            +
                                    <th>#</th>
         | 
| 61 | 
            +
                                    <th>Customer</th>
         | 
| 62 | 
            +
                                    <th>Balance</th>
         | 
| 63 | 
            +
                                </tr>
         | 
| 64 | 
            +
                            </thead>
         | 
| 65 | 
            +
                            <tbody>
         | 
| 66 | 
            +
                                <% @unsettled.each.with_index(1) do |record, i| %>
         | 
| 67 | 
            +
                                    <tr>
         | 
| 68 | 
            +
                                        <th><%= i %></th>
         | 
| 69 | 
            +
                                        <td><%= record['customer'] %></td>
         | 
| 70 | 
            +
                                        <td><%= record['unsettled'] %></td>
         | 
| 71 | 
            +
                                    </tr>
         | 
| 72 | 
            +
                                <% end %>
         | 
| 73 | 
            +
                            </tbody>
         | 
| 74 | 
            +
                        </table>
         | 
| 75 | 
            +
                    <% end %>
         | 
| 53 76 | 
             
                </body>
         | 
| 54 77 | 
             
            </html>
         | 
    
        data/lib/luca_deal/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: lucadeal
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.5.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Chuma Takahiro
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2024-01-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: lucarecord
         | 
| @@ -16,14 +16,14 @@ dependencies: | |
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version: 0. | 
| 19 | 
            +
                    version: 0.7.0
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 24 | 
             
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version: 0. | 
| 26 | 
            +
                    version: 0.7.0
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: bundler
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -103,7 +103,7 @@ metadata: | |
| 103 103 | 
             
              homepage_uri: https://github.com/chumaltd/luca/tree/master/lucadeal
         | 
| 104 104 | 
             
              source_code_uri: https://github.com/chumaltd/luca/tree/master/lucadeal
         | 
| 105 105 | 
             
              changelog_uri: https://github.com/chumaltd/luca/tree/master/lucadeal/CHANGELOG.md
         | 
| 106 | 
            -
            post_install_message: | 
| 106 | 
            +
            post_install_message:
         | 
| 107 107 | 
             
            rdoc_options: []
         | 
| 108 108 | 
             
            require_paths:
         | 
| 109 109 | 
             
            - lib
         | 
| @@ -111,15 +111,15 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 111 111 | 
             
              requirements:
         | 
| 112 112 | 
             
              - - ">="
         | 
| 113 113 | 
             
                - !ruby/object:Gem::Version
         | 
| 114 | 
            -
                  version:  | 
| 114 | 
            +
                  version: 3.0.0
         | 
| 115 115 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 116 116 | 
             
              requirements:
         | 
| 117 117 | 
             
              - - ">="
         | 
| 118 118 | 
             
                - !ruby/object:Gem::Version
         | 
| 119 119 | 
             
                  version: '0'
         | 
| 120 120 | 
             
            requirements: []
         | 
| 121 | 
            -
            rubygems_version: 3. | 
| 122 | 
            -
            signing_key: | 
| 121 | 
            +
            rubygems_version: 3.4.10
         | 
| 122 | 
            +
            signing_key:
         | 
| 123 123 | 
             
            specification_version: 4
         | 
| 124 124 | 
             
            summary: Deal with contracts
         | 
| 125 125 | 
             
            test_files: []
         |