<commit_before>require 'morpheus/cli/cli_command'

# CLI command for the Service Catalog (Persona): Dashboard / Catalog / Inventory
# Inventory Items are the main actions, list, get, remove
# The add command adds to the cart and checkout places an order with the cart.
# The add-order command allows submitting a new order at once.
class Morpheus::Cli::CatalogCommand
  include Morpheus::Cli::CliCommand
  include Morpheus::Cli::ProvisioningHelper
  include Morpheus::Cli::OptionSourceHelper

  # set_command_name :'service-catalog'
  set_command_name :'catalog'
  set_command_description "Service Catalog Persona: View catalog and manage inventory"

  # dashboard
  register_subcommands :dashboard
  # catalog (catalogItemTypes)
  register_subcommands :'list-types' => :list_types
  register_subcommands :'get-type' => :get_type
  alias_subcommand :types, :'list-types'
  
  # inventory (items) IS the main crud here
  register_subcommands :list, :get, :remove

  # cart / orders
  register_subcommands :cart => :get_cart
  register_subcommands :'update-cart' => :update_cart
  register_subcommands :add
  #register_subcommands :'update-cart-item' => :update_cart_item
  register_subcommands :'remove-cart-item' => :remove_cart_item
  register_subcommands :'clear-cart' => :clear_cart
  register_subcommands :checkout

  # create and submit cart in one action
  # maybe call this place-order instead?
  register_subcommands :'add-order' => :add_order

  def connect(opts)
    @api_client = establish_remote_appliance_connection(opts)
    @service_catalog_interface = @api_client.catalog
    @instances_interface = @api_client.instances
    @servers_interface = @api_client.servers # should not be required here!
    @option_types_interface = @api_client.option_types
  end

  def handle(args)
    handle_subcommand(args)
  end

  def dashboard(args)
    params = {}
    options = {}
    optparse = Morpheus::Cli::OptionParser.new do |opts|
      opts.banner = subcommand_usage()
      build_standard_get_options(opts, options)
      opts.footer = <<-EOT
View service catalog dashboard.
Provides an overview of available catalog item types, recent orders and inventory.
EOT
    end
    optparse.parse!(args)
    verify_args!(args:args, optparse:optparse, max:0)
    connect(options)
  
    params.merge!(parse_list_options(options))
    @service_catalog_interface.setopts(options)
    if options[:dry_run]
      print_dry_run @service_catalog_interface.dry.dashboard(params)
      return
    end
    json_response = @service_catalog_interface.dashboard(params)
    catalog_item_types = json_response['catalogItemTypes']
    catalog_meta = json_response['catalogMeta'] || {}
    recent_items = json_response['recentItems'] || {}
    featured_items = json_response['featuredItems'] || []
    inventory_items = json_response['inventoryItems'] || []
    inventory_meta = json_response['inventoryMeta'] || {}
    cart = json_response['cart'] || {}
    cart_items = cart['items'] || []
    cart_stats = cart['stats'] || {}
    current_invoice = json_response['currentInvoice']
    
    render_response(json_response, options, catalog_item_type_object_key) do
      print_h1 "Catalog Dashboard", [], options
      print cyan
      
      # dashboard_columns = [
      #   {"TYPES" => lambda {|it| catalog_meta['total'] } },
      #   {"INVENTORY" => lambda {|it| inventory_items.size rescue '' } },
      #   {"CART" => lambda {|it| it['cart']['items'].size rescue '' } },
      # ]
      # print as_pretty_table([json_response], dashboard_columns, options)

      print_h2 "Catalog Items"
      print as_pretty_table(catalog_item_types, {
        "NAME" => lambda {|it| it['name'] },
        "DESCRIPTION" => lambda {|it| it['description'] },
        "FEATURED" => lambda {|it| format_boolean it['featured'] },
      }, options)
      # print reset,"\n"

      if recent_items && recent_items.size() > 0
        print_h2 "Recently Ordered"
        print as_pretty_table(recent_items, {
          #"ID" => lambda {|it| it['id'] },
          #"NAME" => lambda {|it| it['name'] },
          "TYPE" => lambda {|it| it['type']['name'] rescue '' },
          #"QTY" => lambda {|it| it['quantity'] },
          "ORDER DATE" => lambda {|it| format_local_dt(it['orderDate']) },
          # "STATUS" => lambda {|it| format_catalog_item_status(it) },
          # "CONFIG" => lambda {|it| truncate_string(format_name_values(it['config']), 50) },
        }, options)
        # print reset,"\n"
      end

      if recent_items && recent_items.size() > 0
        print_h2 "Inventory"
        print as_pretty_table(inventory_items, {
          "ID" => lambda {|it| it['id'] },
          "NAME" => lambda {|it| it['name'] },
          "TYPE" => lambda {|it| it['type']['name'] rescue '' },
          #"QTY" => lambda {|it| it['quantity'] },
          "ORDER DATE" => lambda {|it| format_local_dt(it['orderDate']) },
          "STATUS" => lambda {|it| format_catalog_item_status(it) },
          # "CONFIG" => lambda {|it| format_name_values(it['config']) },
        }, options)
        print_results_pagination(inventory_meta)
      else
        # print_h2 "Inventory"
        # print cyan, "Inventory is empty", reset, "\n"
      end
      
      # print reset,"\n"

      # problematic right now, invoice has all user activity, not just catalog
      show_invoice = false
      if current_invoice && show_invoice
        print_h2 "Current Invoice"
        print cyan
        invoice_columns = {
          # todo: invoice needs to return a currency!!!
          "Compute" => lambda {|it| format_money(it['computePrice'], cart_stats['currency']) },
          "Storage" => lambda {|it| format_money(it['storagePrice'], cart_stats['currency']) },
          "Memory" => lambda {|it| format_money(it['memoryPrice'], cart_stats['currency']) },
          "Network" => lambda {|it| format_money(it['networkPrice'], cart_stats['currency']) },
          "Extra" => lambda {|it| format_money(it['extraPrice'], cart_stats['currency']) },
          "MTD" => lambda {|it| format_money(it['runningPrice'], cart_stats['currency']) },
          "Total (Projected)" => lambda {|it| format_money(it['totalPrice'], cart_stats['currency']) },
          #"Items" => lambda {|it| cart['items'].size },
          # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
          # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
        }
        invoice_columns.delete("Storage") unless current_invoice['storagePrice'] && current_invoice['storagePrice'].to_f > 0
        invoice_columns.delete("Memory") unless current_invoice['memoryPrice'] && current_invoice['memoryPrice'].to_f > 0
        invoice_columns.delete("Network") unless current_invoice['networkPrice'] && current_invoice['networkPrice'].to_f > 0
        invoice_columns.delete("Extra") unless current_invoice['extraPrice'] && current_invoice['extraPrice'].to_f > 0
        print as_pretty_table(current_invoice, invoice_columns.upcase_keys!, options)
      end

      show_cart = false
      if show_cart
        if cart
          
          # get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
          
          print_h2 "Cart"
          print cyan
          if cart['items'].size() > 0
            # cart_columns = {
            #   "Qty" => lambda {|it| cart['items'].sum {|cart_item| cart_item['quantity'] } },
            #   "Total" => lambda {|it| 
            #     begin
            #       format_money(cart_stats['price'], cart_stats['currency']) + (cart_stats['unit'].to_s.empty? ? "" : " / #{cart_stats['unit']}")
            #     rescue => ex
            #       raise ex
            #       # no cart stats eh?
            #     end
            #   },
            # }
            # print as_pretty_table(cart, cart_columns.upcase_keys!, options)


            cart_item_columns = [
              {"ID" => lambda {|it| it['id'] } },
              #{"NAME" => lambda {|it| it['name'] } },<commit_msg>catalog dashboard can show cart again<commit_after>require 'morpheus/cli/cli_command'

# CLI command for the Service Catalog (Persona): Dashboard / Catalog / Inventory
# Inventory Items are the main actions, list, get, remove
# The add command adds to the cart and checkout places an order with the cart.
# The add-order command allows submitting a new order at once.
class Morpheus::Cli::CatalogCommand
  include Morpheus::Cli::CliCommand
  include Morpheus::Cli::ProvisioningHelper
  include Morpheus::Cli::OptionSourceHelper

  # set_command_name :'service-catalog'
  set_command_name :'catalog'
  set_command_description "Service Catalog Persona: View catalog and manage inventory"

  # dashboard
  register_subcommands :dashboard
  # catalog (catalogItemTypes)
  register_subcommands :'list-types' => :list_types
  register_subcommands :'get-type' => :get_type
  alias_subcommand :types, :'list-types'
  
  # inventory (items) IS the main crud here
  register_subcommands :list, :get, :remove

  # cart / orders
  register_subcommands :cart => :get_cart
  register_subcommands :'update-cart' => :update_cart
  register_subcommands :add
  #register_subcommands :'update-cart-item' => :update_cart_item
  register_subcommands :'remove-cart-item' => :remove_cart_item
  register_subcommands :'clear-cart' => :clear_cart
  register_subcommands :checkout

  # create and submit cart in one action
  # maybe call this place-order instead?
  register_subcommands :'add-order' => :add_order

  def connect(opts)
    @api_client = establish_remote_appliance_connection(opts)
    @service_catalog_interface = @api_client.catalog
    @instances_interface = @api_client.instances
    @servers_interface = @api_client.servers # should not be required here!
    @option_types_interface = @api_client.option_types
  end

  def handle(args)
    handle_subcommand(args)
  end

  def dashboard(args)
    params = {}
    options = {}
    optparse = Morpheus::Cli::OptionParser.new do |opts|
      opts.banner = subcommand_usage()
      build_standard_get_options(opts, options)
      opts.footer = <<-EOT
View service catalog dashboard.
Provides an overview of available catalog item types, recent orders and inventory.
EOT
    end
    optparse.parse!(args)
    verify_args!(args:args, optparse:optparse, max:0)
    connect(options)
  
    params.merge!(parse_list_options(options))
    @service_catalog_interface.setopts(options)
    if options[:dry_run]
      print_dry_run @service_catalog_interface.dry.dashboard(params)
      return
    end
    json_response = @service_catalog_interface.dashboard(params)
    catalog_item_types = json_response['catalogItemTypes']
    catalog_meta = json_response['catalogMeta'] || {}
    recent_items = json_response['recentItems'] || {}
    featured_items = json_response['featuredItems'] || []
    inventory_items = json_response['inventoryItems'] || []
    inventory_meta = json_response['inventoryMeta'] || {}
    cart = json_response['cart'] || {}
    cart_items = cart['items'] || []
    cart_stats = cart['stats'] || {}
    current_invoice = json_response['currentInvoice']
    
    render_response(json_response, options, catalog_item_type_object_key) do
      print_h1 "Catalog Dashboard", [], options
      print cyan
      
      # dashboard_columns = [
      #   {"TYPES" => lambda {|it| catalog_meta['total'] } },
      #   {"INVENTORY" => lambda {|it| inventory_items.size rescue '' } },
      #   {"CART" => lambda {|it| it['cart']['items'].size rescue '' } },
      # ]
      # print as_pretty_table([json_response], dashboard_columns, options)

      print_h2 "Catalog Items"
      print as_pretty_table(catalog_item_types, {
        "NAME" => lambda {|it| it['name'] },
        "DESCRIPTION" => lambda {|it| it['description'] },
        "FEATURED" => lambda {|it| format_boolean it['featured'] },
      }, options)
      # print reset,"\n"

      if recent_items && recent_items.size() > 0
        print_h2 "Recently Ordered"
        print as_pretty_table(recent_items, {
          #"ID" => lambda {|it| it['id'] },
          #"NAME" => lambda {|it| it['name'] },
          "TYPE" => lambda {|it| it['type']['name'] rescue '' },
          #"QTY" => lambda {|it| it['quantity'] },
          "ORDER DATE" => lambda {|it| format_local_dt(it['orderDate']) },
          # "STATUS" => lambda {|it| format_catalog_item_status(it) },
          # "CONFIG" => lambda {|it| truncate_string(format_name_values(it['config']), 50) },
        }, options)
        # print reset,"\n"
      end

      if recent_items && recent_items.size() > 0
        print_h2 "Inventory"
        print as_pretty_table(inventory_items, {
          "ID" => lambda {|it| it['id'] },
          "NAME" => lambda {|it| it['name'] },
          "TYPE" => lambda {|it| it['type']['name'] rescue '' },
          #"QTY" => lambda {|it| it['quantity'] },
          "ORDER DATE" => lambda {|it| format_local_dt(it['orderDate']) },
          "STATUS" => lambda {|it| format_catalog_item_status(it) },
          # "CONFIG" => lambda {|it| format_name_values(it['config']) },
        }, options)
        print_results_pagination(inventory_meta)
      else
        # print_h2 "Inventory"
        # print cyan, "Inventory is empty", reset, "\n"
      end
      
      # print reset,"\n"

      # problematic right now, invoice has all user activity, not just catalog
      show_invoice = false
      if current_invoice && show_invoice
        print_h2 "Current Invoice"
        print cyan
        invoice_columns = {
          # todo: invoice needs to return a currency!!!
          "Compute" => lambda {|it| format_money(it['computePrice'], cart_stats['currency']) },
          "Storage" => lambda {|it| format_money(it['storagePrice'], cart_stats['currency']) },
          "Memory" => lambda {|it| format_money(it['memoryPrice'], cart_stats['currency']) },
          "Network" => lambda {|it| format_money(it['networkPrice'], cart_stats['currency']) },
          "Extra" => lambda {|it| format_money(it['extraPrice'], cart_stats['currency']) },
          "MTD" => lambda {|it| format_money(it['runningPrice'], cart_stats['currency']) },
          "Total (Projected)" => lambda {|it| format_money(it['totalPrice'], cart_stats['currency']) },
          #"Items" => lambda {|it| cart['items'].size },
          # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
          # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
        }
        invoice_columns.delete("Storage") unless current_invoice['storagePrice'] && current_invoice['storagePrice'].to_f > 0
        invoice_columns.delete("Memory") unless current_invoice['memoryPrice'] && current_invoice['memoryPrice'].to_f > 0
        invoice_columns.delete("Network") unless current_invoice['networkPrice'] && current_invoice['networkPrice'].to_f > 0
        invoice_columns.delete("Extra") unless current_invoice['extraPrice'] && current_invoice['extraPrice'].to_f > 0
        print as_pretty_table(current_invoice, invoice_columns.upcase_keys!, options)
      end

      show_cart = true
      if show_cart
        if cart
          
          # get_cart([] + (options[:remote] ? ["-r",options[:remote]] : []))
          
          print_h2 "Cart"
          print cyan
          if cart['items'].size() > 0
            # cart_columns = {
            #   "Qty" => lambda {|it| cart['items'].sum {|cart_item| cart_item['quantity'] } },
            #   "Total" => lambda {|it| 
            #     begin
            #       format_money(cart_stats['price'], cart_stats['currency']) + (cart_stats['unit'].to_s.empty? ? "" : " / #{cart_stats['unit']}")
            #     rescue => ex
            #       raise ex
            #       # no cart stats eh?
            #     end
            #   },
            # }
            # print as_pretty_table(cart, cart_columns.upcase_keys!, options)


            cart_item_columns = [
              {"ID" => lambda {|it| it['id'] } },
              #{"NAME" => lambda {|it| it['name'] } },
{'fraction_non_alphanumeric': 0.1422044188520999, 'fraction_numerical': 0.0021280590849345935, 'mean_word_length': 3.178347280334728, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1679814', 'n_tokens_mistral': 4925, 'n_tokens_neox': 4777, 'n_words': 1043}