order_calculator 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8a257ab68c0dc81e951a16d7ccb24a0dbccdd65b
4
+ data.tar.gz: 89325c0f82e4b17b569a13197a0855e97889f376
5
+ SHA512:
6
+ metadata.gz: a908a2e551b109a4f8613cd15cace72fff8fbeb948c0f653f32e770cfc88d2cd8244112f0fdf79a33d695396b00e09b36352f500d476c3325d10281974fa2400
7
+ data.tar.gz: ac8702626f95b32629a0fbedceea35d1a5c125001f5214cd7db7c09397a32d31a9a4a2f42fb35ca641f20a18a47669a65dc26a85574ccfe8bdaa54e6edf06a0d
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ output.csv
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in order_calculator.gemspec
4
+ gemspec
5
+
6
+ gem 'guard-rspec'
7
+ gem 'pry'
data/Guardfile ADDED
@@ -0,0 +1,78 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ watch(%r{^lib/(.+).rb$}) do |m|
19
+ "spec/#{m[1]}_spec.rb"
20
+ end
21
+
22
+ watch(%r{^lib/order_calculator/(.+).rb$}) do |m|
23
+ "spec/order_calculator/#{m[1]}_spec.rb"
24
+ end
25
+
26
+ # Note: The cmd option is now required due to the increasing number of ways
27
+ # rspec may be run, below are examples of the most common uses.
28
+ # * bundler: 'bundle exec rspec'
29
+ # * bundler binstubs: 'bin/rspec'
30
+ # * spring: 'bin/rspec' (This will use spring if running and you have
31
+ # installed the spring binstubs per the docs)
32
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
33
+ # * 'just' rspec: 'rspec'
34
+
35
+ guard :rspec, cmd: "bundle exec rspec" do
36
+ require "guard/rspec/dsl"
37
+ dsl = Guard::RSpec::Dsl.new(self)
38
+
39
+ # Feel free to open issues for suggestions and improvements
40
+
41
+ # RSpec files
42
+ rspec = dsl.rspec
43
+ watch(rspec.spec_helper) { rspec.spec_dir }
44
+ watch(rspec.spec_support) { rspec.spec_dir }
45
+ watch(rspec.spec_files)
46
+
47
+ # Ruby files
48
+ ruby = dsl.ruby
49
+ dsl.watch_spec_files_for(ruby.lib_files)
50
+
51
+ # Rails files
52
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
53
+ dsl.watch_spec_files_for(rails.app_files)
54
+ dsl.watch_spec_files_for(rails.views)
55
+
56
+ watch(rails.controllers) do |m|
57
+ [
58
+ rspec.spec.("routing/#{m[1]}_routing"),
59
+ rspec.spec.("controllers/#{m[1]}_controller"),
60
+ rspec.spec.("acceptance/#{m[1]}")
61
+ ]
62
+ end
63
+
64
+ # Rails config changes
65
+ watch(rails.spec_helper) { rspec.spec_dir }
66
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
67
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
68
+
69
+ # Capybara features specs
70
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
71
+ watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
72
+
73
+ # Turnip features and steps
74
+ watch(%r{^spec/acceptance/(.+)\.feature$})
75
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
76
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
77
+ end
78
+ end
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # OrderCalculator
2
+
3
+ Um programa de linha de comando capaz de calcular o valor final de um pedido em um e-commerce.
4
+
5
+
6
+ Cálculo do Valor Final do Pedido
7
+
8
+ O valor total do pedido é a soma do valor dos produtos do pedido menos o Desconto. Cada pedido possui no máximo uma unidade de cada produto.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'order_calculator'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install order_calculator
25
+
26
+ ## Usage
27
+
28
+ Executar o comando 'exercicio' com os nomes dos quatro arquivos
29
+
30
+ ```bash
31
+ exercicio cupons.csv products.csv orders.csv order_items.csv totals.csv
32
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "order_calculator"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/exercicio ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "order_calculator"
4
+
5
+ puts "Processando..."
6
+
7
+ inputs = OrderCalculator::Files.config(ARGV)
8
+ output = OrderCalculator::Calculator.process(inputs)
9
+ OrderCalculator::Files.generate(output)
10
+
11
+ puts "Processamento finalizado, verifique o arquivo output.csv"
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,6 @@
1
+ require "version"
2
+ require "calculator"
3
+ require "files"
4
+ require "coupom"
5
+ require "discount"
6
+ require "manage_coupom"
@@ -0,0 +1,51 @@
1
+ module OrderCalculator
2
+ class Calculator
3
+
4
+ class << self
5
+ def process(data)
6
+ coupons = ManageCoupom.new data.coupons
7
+ data.orders.collect do |o|
8
+ coupom = coupons.find(o.last) unless o.last.nil?
9
+
10
+ prices = data
11
+ .order_items.collect { |c| c.last if c.first.eql?(o.first) }.compact
12
+ .collect { |i| data.products.find{|p| p.first.eql?(i)}.last }.compact
13
+
14
+ new(o.first, prices, coupom).to_a
15
+ end
16
+ end
17
+ end
18
+
19
+ def initialize(order, prices, coupom=[])
20
+ @order = order
21
+ @coupom = coupom
22
+ @prices = prices
23
+ end
24
+
25
+ def to_a
26
+ [@order, total.to_s]
27
+ end
28
+
29
+ private
30
+
31
+ def total
32
+ raw_price - discount
33
+ end
34
+
35
+ def discount
36
+ discount = Discount.apply(raw_price, @prices.count)
37
+ return discount if coupom_blank?
38
+ coupom = Coupom.new(@coupom).apply(raw_price)
39
+
40
+ discount > coupom ? discount : coupom
41
+ end
42
+
43
+ def raw_price
44
+ @prices.inject(0) { |a, e| a + e.to_f }
45
+ end
46
+
47
+ def coupom_blank?
48
+ @coupom.nil? || @coupom.empty?
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ module OrderCalculator
2
+ class Coupom
3
+ def initialize(coupom)
4
+ @coupom = coupom
5
+ end
6
+
7
+ def apply(value)
8
+ percent? ? calc_percent(value) : calc_abs(value)
9
+ end
10
+
11
+ private
12
+
13
+ def calc_percent(value)
14
+ value * discount / 100.0
15
+ end
16
+
17
+ def calc_abs(value)
18
+ discount
19
+ end
20
+
21
+ def discount
22
+ @coupom[1].to_i
23
+ end
24
+
25
+ def percent?
26
+ @coupom[2].eql? 'percent'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ module OrderCalculator
2
+ class Discount
3
+ def self.apply(value, quantity)
4
+ new(value, quantity).apply
5
+ end
6
+
7
+ def initialize(value, quantity)
8
+ @quantity = quantity
9
+ @value = value
10
+ end
11
+
12
+ def apply
13
+ return 0.0 if @quantity.eql? 1
14
+ @value * discount
15
+ end
16
+
17
+ private
18
+
19
+ def discount
20
+ case @quantity
21
+ when 2 then 0.10
22
+ when 3 then 0.15
23
+ when 4 then 0.20
24
+ when 5 then 0.25
25
+ when 6 then 0.30
26
+ when 7 then 0.35
27
+ else 0.40
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,42 @@
1
+ require 'csv'
2
+
3
+ module OrderCalculator
4
+ class Files
5
+ class << self
6
+ def config(files)
7
+ fail ArgumentError, 'É necessário 4 arquivos' unless files.size.eql?(4)
8
+ new files
9
+ end
10
+
11
+ def generate(output)
12
+ CSV.open('output.csv', 'wb') { |csv| output.map { |o| csv << o } }
13
+ end
14
+ end
15
+
16
+ def initialize(files)
17
+ @files = files
18
+ end
19
+
20
+ def coupons
21
+ @_c ||= read_file @files[0]
22
+ end
23
+
24
+ def products
25
+ @_p ||= read_file @files[1]
26
+ end
27
+
28
+ def orders
29
+ @_orders ||= read_file(@files[2])
30
+ end
31
+
32
+ def order_items
33
+ @_items ||= read_file(@files[3])
34
+ end
35
+
36
+ private
37
+
38
+ def read_file(file_name)
39
+ ::CSV.read file_name
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ require 'date'
2
+
3
+ module OrderCalculator
4
+ class ManageCoupom
5
+
6
+ def initialize(coupons)
7
+ @coupons = coupons
8
+ end
9
+
10
+ def find(coupom_id)
11
+ @coupons.find do |c|
12
+ if c.first.eql?(coupom_id) && c[4].to_i > 0 && validity_period?(c[3])
13
+ c[4]= c.last.to_i - 1
14
+ true
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def validity_period?(date)
22
+ Date.parse(date) >= Date.today
23
+ rescue
24
+ fail ArgumentError, 'Data inválida, verifique o arquivo de cupons'
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module OrderCalculator
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'order_calculator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "order_calculator"
8
+ spec.version = OrderCalculator::VERSION
9
+ spec.authors = ["Marco Moura"]
10
+ spec.email = ["marco.moura@gmail.com"]
11
+
12
+ spec.summary = %q{Order calculator exercise}
13
+ # spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "bin"
17
+ spec.executables = 'exercicio'
18
+ spec.require_paths = ["lib", 'lib/order_calculator']
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: order_calculator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Marco Moura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email:
57
+ - marco.moura@gmail.com
58
+ executables:
59
+ - exercicio
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - Guardfile
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/exercicio
71
+ - bin/setup
72
+ - lib/order_calculator.rb
73
+ - lib/order_calculator/calculator.rb
74
+ - lib/order_calculator/coupom.rb
75
+ - lib/order_calculator/discount.rb
76
+ - lib/order_calculator/files.rb
77
+ - lib/order_calculator/manage_coupom.rb
78
+ - lib/order_calculator/version.rb
79
+ - order_calculator.gemspec
80
+ homepage:
81
+ licenses: []
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ - lib/order_calculator
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.5.1
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Order calculator exercise
104
+ test_files: []