order_calculator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []