stall 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -0
  3. data/app/assets/javascripts/stall.coffee +2 -0
  4. data/app/assets/javascripts/stall/cart-form.coffee +23 -0
  5. data/app/controllers/stall/application_controller.rb +10 -2
  6. data/app/controllers/stall/carts_controller.rb +31 -10
  7. data/app/controllers/stall/checkout/steps_controller.rb +36 -4
  8. data/app/controllers/stall/checkouts_controller.rb +12 -3
  9. data/app/controllers/stall/line_items_controller.rb +3 -3
  10. data/app/controllers/stall/payments_controller.rb +5 -3
  11. data/app/helpers/stall/add_to_cart_helper.rb +1 -1
  12. data/app/helpers/stall/checkout_helper.rb +22 -2
  13. data/app/helpers/stall/payments_helper.rb +8 -0
  14. data/app/mailers/stall/admin_mailer.rb +11 -0
  15. data/app/mailers/stall/base_mailer.rb +17 -0
  16. data/app/mailers/stall/customer_mailer.rb +13 -0
  17. data/app/models/address.rb +3 -0
  18. data/app/models/address_ownership.rb +3 -0
  19. data/app/models/adjustment.rb +3 -0
  20. data/app/models/cart.rb +3 -0
  21. data/app/models/customer.rb +3 -0
  22. data/app/models/line_item.rb +3 -0
  23. data/app/models/payment.rb +3 -0
  24. data/app/models/payment_method.rb +3 -0
  25. data/app/models/product_list.rb +3 -0
  26. data/app/models/shipment.rb +3 -0
  27. data/app/models/shipping_method.rb +3 -0
  28. data/app/models/stall/models.rb +4 -0
  29. data/app/models/stall/models/address.rb +45 -0
  30. data/app/models/stall/models/address_ownership.rb +26 -0
  31. data/app/models/stall/models/adjustment.rb +49 -0
  32. data/app/models/stall/models/cart.rb +37 -0
  33. data/app/models/stall/models/customer.rb +18 -0
  34. data/app/models/stall/models/line_item.rb +57 -0
  35. data/app/models/stall/models/payment.rb +33 -0
  36. data/app/models/stall/models/payment_method.rb +18 -0
  37. data/app/models/stall/models/product_list.rb +147 -0
  38. data/app/models/stall/models/shipment.rb +29 -0
  39. data/app/models/stall/models/shipping_method.rb +16 -0
  40. data/app/services/stall/add_to_cart_service.rb +11 -1
  41. data/app/services/stall/cart_update_service.rb +26 -0
  42. data/app/services/stall/payment_notification_service.rb +23 -9
  43. data/app/services/stall/shipping_fee_calculator_service.rb +13 -2
  44. data/app/views/checkout/steps/_informations.html.haml +3 -3
  45. data/app/views/checkout/steps/_payment.html.haml +25 -4
  46. data/app/views/checkout/steps/_payment_method.html.haml +1 -3
  47. data/app/views/checkout/steps/_payment_return.html.haml +6 -0
  48. data/app/views/checkout/steps/_shipping_method.html.haml +1 -1
  49. data/app/views/stall/admin_mailer/order_paid_email.html.haml +4 -0
  50. data/app/views/stall/carts/show.html.haml +36 -8
  51. data/app/views/stall/customer_mailer/order_paid_email.html.haml +8 -0
  52. data/app/views/stall/line_items/_added.html.haml +1 -1
  53. data/app/views/stall/shared/mailers/_address.html.haml +18 -0
  54. data/app/views/stall/shared/mailers/_cart.html.haml +114 -0
  55. data/config/locales/stall.fr.yml +90 -8
  56. data/db/migrate/20160304134849_change_all_json_columns_to_jsonb.rb +18 -0
  57. data/db/migrate/20160307142924_add_state_to_stall_addresses.rb +5 -0
  58. data/db/migrate/20160308142713_create_adjustments.rb +16 -0
  59. data/db/migrate/20160309165136_add_identifier_to_stall_product_lists.rb +5 -0
  60. data/db/migrate/20160316114649_add_data_to_stall_shipments.rb +5 -0
  61. data/db/migrate/20160317141632_add_state_to_stall_shipments.rb +5 -0
  62. data/db/migrate/20160629102943_add_active_to_stall_shipping_methods.rb +11 -0
  63. data/db/migrate/20160629104617_add_active_to_stall_payment_methods.rb +11 -0
  64. data/db/migrate/20160705110151_add_locale_to_stall_customers.rb +5 -0
  65. data/lib/generators/stall/checkout/step/templates/step.html.haml.erb +1 -1
  66. data/lib/generators/stall/checkout/step/templates/step.rb.erb +10 -2
  67. data/lib/generators/stall/checkout/wizard/templates/wizard.rb.erb +1 -1
  68. data/lib/generators/stall/install/templates/initializer.rb +85 -1
  69. data/lib/generators/stall/model/model_generator.rb +27 -0
  70. data/lib/generators/stall/service/service_generator.rb +39 -0
  71. data/lib/generators/stall/service/templates/service.rb.erb +16 -0
  72. data/lib/generators/stall/shipping/calculator/calculator_generator.rb +17 -0
  73. data/lib/generators/stall/shipping/calculator/templates/calculator.rb.erb +29 -0
  74. data/lib/stall.rb +4 -0
  75. data/lib/stall/addressable.rb +28 -2
  76. data/lib/stall/cart_helper.rb +84 -0
  77. data/lib/stall/carts_cleaner.rb +46 -0
  78. data/lib/stall/checkout.rb +2 -0
  79. data/lib/stall/checkout/informations_checkout_step.rb +3 -5
  80. data/lib/stall/checkout/payment_checkout_step.rb +3 -0
  81. data/lib/stall/checkout/payment_return_checkout_step.rb +11 -0
  82. data/lib/stall/checkout/shipping_method_checkout_step.rb +2 -1
  83. data/lib/stall/checkout/step.rb +47 -11
  84. data/lib/stall/checkout/step_form.rb +71 -0
  85. data/lib/stall/checkout/wizard.rb +15 -5
  86. data/lib/stall/config.rb +51 -0
  87. data/lib/stall/engine.rb +24 -2
  88. data/lib/stall/payable.rb +26 -0
  89. data/lib/stall/payments.rb +7 -3
  90. data/lib/stall/payments/config.rb +37 -0
  91. data/lib/stall/payments/fake_gateway_payment_notification.rb +34 -0
  92. data/lib/stall/payments/gateway.rb +19 -12
  93. data/lib/stall/payments/urls_config.rb +40 -0
  94. data/lib/stall/priceable.rb +7 -0
  95. data/lib/stall/rails/currency_helper.rb +1 -1
  96. data/lib/stall/routes.rb +17 -4
  97. data/lib/stall/sellable.rb +1 -2
  98. data/lib/stall/shipping.rb +3 -1
  99. data/lib/stall/shipping/calculator.rb +36 -3
  100. data/lib/stall/shipping/config.rb +17 -3
  101. data/lib/stall/shipping/country_weight_table_calculator.rb +1 -1
  102. data/lib/stall/shipping/free_shipping_calculator.rb +1 -1
  103. data/lib/stall/utils.rb +2 -2
  104. data/lib/stall/utils/config_dsl.rb +5 -1
  105. data/lib/stall/version.rb +1 -1
  106. data/lib/tasks/stall_tasks.rake +11 -0
  107. metadata +73 -15
  108. data/app/assets/javascripts/stall/application.js +0 -13
  109. data/app/assets/javascripts/stall/carts.js +0 -2
  110. data/app/helpers/stall/cart_helper.rb +0 -28
  111. data/app/models/stall/address.rb +0 -5
  112. data/app/models/stall/address_ownership.rb +0 -8
  113. data/app/models/stall/cart.rb +0 -31
  114. data/app/models/stall/customer.rb +0 -8
  115. data/app/models/stall/line_item.rb +0 -49
  116. data/app/models/stall/payment.rb +0 -14
  117. data/app/models/stall/payment_method.rb +0 -7
  118. data/app/models/stall/product_list.rb +0 -68
  119. data/app/models/stall/shipment.rb +0 -15
  120. data/app/models/stall/shipping_method.rb +0 -5
@@ -11,11 +11,16 @@ fr:
11
11
  success: "Votre panier a bien été mis à jour."
12
12
  error: "Votre panier n'a pu être mis à jour, merci de vérifier les champs."
13
13
  recap:
14
+ order_ref: "Commande n°%{ref}"
15
+ ordered_at: "Passée le %{at}"
16
+ subtotal: "Sous-total"
17
+ total_shipment_price: "Livraison"
14
18
  total_eot_price: "Prix total HT"
15
19
  total_vat: "Total TVA"
16
20
  total_price: "Prix total"
17
21
  update: "Mettre à jour le panier"
18
22
  validate: "Passer la commande"
23
+ paid_at: "Payée le %{at}"
19
24
 
20
25
  line_items:
21
26
  form:
@@ -29,6 +34,8 @@ fr:
29
34
  description: "Merci de vérifier que vous avez bien rempli la quantité avant d'ajouter le produit au panier."
30
35
 
31
36
  checkout:
37
+ shared:
38
+ not_checkoutable: "Aucun produit dans le panier, impossible de passer la commande."
32
39
  informations:
33
40
  title: "Vos informations"
34
41
  validate: "Valider mes adresses"
@@ -41,23 +48,72 @@ fr:
41
48
  validate: "Valider mon mode de paiement"
42
49
  payment:
43
50
  title: "Paiement"
51
+ error: |
52
+ Votre paiement n'a pas pu être pris en compte, vous pouvez réessayer
53
+ de payer avec le bouton : "Payer ma commande"
54
+ payment_return:
55
+ title: "Paiement effectué"
56
+ help: |
57
+ Votre paiement a bien été pris en compte et votre commande a été
58
+ validée. Celle-ci sera traitée dans les plus bref délais.
59
+ <br><br>
60
+ Un e-mail de confirmation vous a été envoyé.
61
+ <br><br>
62
+ Merci pour votre confiance !
63
+
64
+ back_to_shop: "Retour à la boutique"
44
65
 
45
66
  payments:
46
67
  gateway:
47
68
  pay: "Payer ma commande"
48
69
 
70
+ addresses:
71
+ civilities:
72
+ m: M.
73
+ mme: Mme.
74
+
75
+ mailers:
76
+ customer:
77
+ order_paid_email:
78
+ subject: "Le paiement de votre commande n°%{ref} a bien été effectué !"
79
+ intro: "Votre commande sera traitée dans les meilleurs délais."
80
+ admin:
81
+ order_paid_email:
82
+ subject: "Une nouvelle commande a été passée sur le site - %{ref}"
83
+
49
84
  activerecord:
85
+ enums:
86
+ shipment:
87
+ state:
88
+ pending: "En attente"
89
+ shipped: "Expédié"
90
+ payment:
91
+ state:
92
+ pending: "En attente"
93
+ shipped: "Payé"
94
+ models:
95
+ line_item: "Produit"
96
+ customer: "Client"
97
+ address: "Adresse"
98
+ cart: "Panier"
99
+ shipment: "Livraison"
100
+ payment: "Paiement"
50
101
  attributes:
51
- stall/line_item:
52
- name: "Produit"
53
- unit_price: "Prix unitaire"
54
- unit_eot_price: "Prix unitaire HT"
55
- price: "Prix"
56
- eot_price: "Prix HT"
102
+ line_item:
103
+ sellable: "Produit source"
104
+ name: "Nom du produit"
57
105
  quantity: "Quantité"
58
- stall/customer:
106
+ unit_eot_price: "Prix unitaire HT"
107
+ unit_price: "Prix unitaire TTC"
108
+ eot_price: "Prix total HT"
109
+ price: "Prix total TTC"
110
+ vat_rate: "Taux de TVA"
111
+ weight: "Poids"
112
+ customer:
59
113
  email: "Adresse e-mail"
60
- stall/address:
114
+ shipping_address: "Adresse de livraison"
115
+ billing_address: "Adresse de facturation"
116
+ address:
61
117
  civility: "Civilité"
62
118
  first_name: "Prénom"
63
119
  last_name: "Nom"
@@ -67,3 +123,29 @@ fr:
67
123
  city: "Ville"
68
124
  country: "Pays"
69
125
  phone: "Téléphone"
126
+ state: "État"
127
+ product_list:
128
+ reference: "Référence"
129
+ customer: "Client"
130
+ created_at: "Date"
131
+ line_items: "Produits"
132
+ cart:
133
+ state: "Étape du panier"
134
+ total_price: "Montant total"
135
+ payment: "Paiement"
136
+ shipment: "Livraison"
137
+ shipping_address: "Adresse de livraison"
138
+ billing_address: "Adresse de facturation"
139
+ shipment:
140
+ price: "Prix"
141
+ eot_price: "Prix HT"
142
+ vat_rate: "Taux de TVA"
143
+ sent_at: "Expédié le"
144
+ shipping_method: "Mode de livraison"
145
+ tracking_code: "Code de suivi"
146
+ state: "État"
147
+ payment:
148
+ payment_method: "Mode de paiement"
149
+ paid_at: "Payé le"
150
+ transaction_id: "Numéro de transaction"
151
+ state: "État"
@@ -0,0 +1,18 @@
1
+ # This allows to avoid SELECT DISTINCT errors where JSON field type would throw
2
+ # a PG::UndefinedFunction error
3
+ #
4
+ # See : https://github.com/activerecord-hackery/ransack/issues/453
5
+ #
6
+ class ChangeAllJsonColumnsToJsonb < ActiveRecord::Migration
7
+ def up
8
+ change_column :stall_line_items, :data, 'jsonb USING CAST(data AS jsonb)'
9
+ change_column :stall_payments, :data, 'jsonb USING CAST(data AS jsonb)'
10
+ change_column :stall_product_lists, :data, 'jsonb USING CAST(data AS jsonb)'
11
+ end
12
+
13
+ def down
14
+ change_column :stall_line_items, :data, 'json USING CAST(data AS json)'
15
+ change_column :stall_payments, :data, 'json USING CAST(data AS json)'
16
+ change_column :stall_product_lists, :data, 'json USING CAST(data AS json)'
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class AddStateToStallAddresses < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_addresses, :state, :string
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ class CreateAdjustments < ActiveRecord::Migration
2
+ def change
3
+ create_table :stall_adjustments do |t|
4
+ t.string :name, null: false
5
+ t.monetize :eot_price, null: false, currency: { present: false }
6
+ t.monetize :price, null: false, currency: { present: false }
7
+ t.decimal :vat_rate, null: false
8
+ t.string :type
9
+ t.references :cart, index: true
10
+
11
+ t.timestamps null: false
12
+ end
13
+
14
+ add_foreign_key :stall_adjustments, :stall_product_lists, column: :cart_id
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class AddIdentifierToStallProductLists < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_product_lists, :identifier, :string, null: false, default: 'default'
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddDataToStallShipments < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_shipments, :data, :jsonb
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddStateToStallShipments < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_shipments, :state, :integer, default: 0
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class AddActiveToStallShippingMethods < ActiveRecord::Migration
2
+ def up
3
+ add_column :stall_shipping_methods, :active, :boolean, default: true
4
+
5
+ ShippingMethod.update_all(active: true)
6
+ end
7
+
8
+ def down
9
+ remove_column :stall_shipping_methods, :active
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class AddActiveToStallPaymentMethods < ActiveRecord::Migration
2
+ def up
3
+ add_column :stall_payment_methods, :active, :boolean, default: true
4
+
5
+ PaymentMethod.update_all(active: true)
6
+ end
7
+
8
+ def down
9
+ remove_column :stall_payment_methods, :active
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddLocaleToStallCustomers < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_customers, :locale, :string, default: I18n.default_locale
4
+ end
5
+ end
@@ -1,6 +1,6 @@
1
1
  %h1= t('stall.checkout.<%= base_file_name %>.title')
2
2
 
3
- = simple_form_for cart, as: :cart, url: step_path(cart) do |form|
3
+ = simple_form_for cart, as: :cart, url: step_path do |form|
4
4
 
5
5
  %button.btn.btn-primary{ type: 'submit' }
6
6
  = t('stall.checkout.<%= base_file_name %>.validate')
@@ -1,13 +1,21 @@
1
1
  class <%= class_name %> < Stall::Checkout::Step
2
+ # Declare your step validations here
3
+ # Those validations will be run against the cart object
4
+ #
5
+ # validations do
6
+ # validates :foo, presence: true
7
+ # end
8
+
2
9
  # Prepare the `cart` before showing your view
3
10
  #
4
11
  # def prepare
5
12
  # end
6
13
 
7
- # Process `params` here, defaults to updating the cart with `cart_params`
8
- # (params[:cart])
14
+ # Process `params` here, defaults to assigning the cart with `cart_params`
15
+ # (params[:cart]) to the cart, running the step validations
9
16
  #
10
17
  # def process
18
+ # save
11
19
  # end
12
20
 
13
21
  # Handle the case where the step should be skipped by returning true from
@@ -1,3 +1,3 @@
1
1
  class <%= class_name %> < Stall::Checkout::Wizard
2
- steps :informations, :shipping_method, :payment_method, :payment
2
+ steps :informations, :shipping_method, :payment_method, :payment, :payment_return
3
3
  end
@@ -1,4 +1,30 @@
1
1
  Stall.configure do |config|
2
+ # Store name used by the system when a human readable identifier for your
3
+ # store is needed, e.g. for payment gateways
4
+ #
5
+ config.store_name = "My stall (Change me in config/initializers/stall.rb)"
6
+
7
+ # Configure the admin e-mail to which order notifications will be sent
8
+ #
9
+ # Either set the `STALL_ADMIN_EMAIL` env var or use the below config.
10
+ #
11
+ # You can also set that param as a proc / lambda that will get the cart
12
+ # as argument, allowing you to dynamically define which e-mail to send
13
+ # notifications *to*
14
+ #
15
+ # config.admin_email = ENV['STALL_ADMIN_EMAIL']
16
+
17
+ # Configure the e-mail address used to send e-mails to customers for
18
+ # order notifications
19
+ #
20
+ # Either set the `STALL_SENDER_EMAIL` env var or use the below config
21
+ #
22
+ # You can also set that param as a proc / lambda that will get the cart
23
+ # as argument, allowing you to dynamically define which e-mail to send
24
+ # notifications *from*
25
+ #
26
+ # config.sender_email = ENV['STALL_SENDER_EMAIL']
27
+
2
28
  # Global default VAT rate, can be overrided by products
3
29
  #
4
30
  # config.vat_rate = BigDecimal.new('20.0')
@@ -11,6 +37,19 @@ Stall.configure do |config|
11
37
  #
12
38
  # config.application_controller_ancestor = '::ApplicationController'
13
39
 
40
+ # Set a layout to use in the checkouts controllers
41
+ #
42
+ # The default is set to nil, which will make the controllers inherit from the
43
+ # layout of the controller set in `config.application_controller_ancestor`
44
+ #
45
+ # config.default_layout = nil
46
+
47
+ # Defines the parent mailer for the Stall customer and admin mailers
48
+ #
49
+ # If commented out, ActionMailer::Base will be used
50
+ #
51
+ config.mailers_parent_class = 'ApplicationMailer'
52
+
14
53
  # Default currency used in the app for money objects.
15
54
  #
16
55
  # Note : If you need multi currency support in your app, you'll have to ensure
@@ -19,6 +58,15 @@ Stall.configure do |config|
19
58
  #
20
59
  # param :default_currency, 'EUR'
21
60
 
61
+ # Default app domain use for building URLs in payment gateway forms and in
62
+ # e-mails.
63
+ #
64
+ # Add the `APP_DOMAIN` environment variable, or modify the parameter below.
65
+ #
66
+ # Ex : 'localhost:3000', 'www.example.com'
67
+ #
68
+ # config.default_app_domain = ENV['APP_DOMAIN']
69
+
22
70
  # Defined the default checkout wizard used for checking carts out in the
23
71
  # shop process.
24
72
  #
@@ -39,12 +87,30 @@ Stall.configure do |config|
39
87
 
40
88
  # Allows configuring which countries are available for free shipping offers
41
89
  #
42
- # Accepts an array of country codes or a proc with a Stall::Address argument
90
+ # Accepts an array of country codes or a proc with an Address argument
43
91
  #
44
92
  # Defaults to nil, which means all countries are available
45
93
  #
46
94
  # config.shipping.free_shipping.available = nil
47
95
 
96
+ # Register custom shipping methods and calculators
97
+ #
98
+ # If no existing shipping method / calculator cover your needs, you can
99
+ # create one by subclassing Stall::Shipping::Calculator
100
+ #
101
+ # Read more at : https://github.com/rails-stall/stall/wiki/Shipping-methods
102
+ #
103
+ # config.shipping.register_calculator :my_calculator, 'MyCalculator'
104
+
105
+ # Register custom payment methods and gateways
106
+ #
107
+ # If no existing payment method / gateway cover your needs, you can
108
+ # create one by subclassing Stall::Payments::Gateway
109
+ #
110
+ # Read more at : https://github.com/rails-stall/stall/wiki/Payment-methods
111
+ #
112
+ # config.payment.register_gateway :my_gateway, 'MyGateway'
113
+
48
114
  # Allows hooking into checkout steps initialization in the steps controller
49
115
  # to inject dependencies to all or a specific step
50
116
  #
@@ -54,4 +120,22 @@ Stall.configure do |config|
54
120
  # # Only inject in the :some step :
55
121
  # step.inject(:ip, request.remote_ip) if SomeCheckoutStep === step
56
122
  # end
123
+
124
+ # Configure app services to override default Stall services and add
125
+ # functionalities to existing ones
126
+ #
127
+ # config.services = {
128
+ # payment_notification: 'PaymentNotificationService'
129
+ # }
130
+
131
+ # Delay before empty carts are cleaned with the `stall:carts:clean` task
132
+ #
133
+ # config.empty_carts_expires_after = 1.day
134
+
135
+ # Delay before aborted carts are cleaned with the `stall:carts:clean` task
136
+ #
137
+ # Aborted carts are controlled with a scope on the cart model. To change
138
+ # the `aborted` behavior, you can override the `.aborted` scope in your model.
139
+ #
140
+ # config.aborted_carts_expires_after = 14.days
57
141
  end
@@ -0,0 +1,27 @@
1
+ module Stall
2
+ class ModelGenerator < ::Rails::Generators::NamedBase
3
+ class ModelModelNotFound < StandardError; end
4
+
5
+ MODELS_DIR = File.expand_path('../../../../../app/models', __FILE__)
6
+ source_root MODELS_DIR
7
+
8
+ def copy_model_template
9
+ if File.exist?(source_path)
10
+ template source_path, "app/models/#{ file_path_with_ext }"
11
+ else
12
+ raise ModelModelNotFound,
13
+ "Could not find any stall model for #{ class_name }"
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def source_path
20
+ @source_path ||= File.join(MODELS_DIR, file_path_with_ext)
21
+ end
22
+
23
+ def file_path_with_ext
24
+ @file_path_with_ext ||= "#{ file_path }.rb"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ module Stall
2
+ class ServiceGenerator < ::Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def store_services_folder_existence
6
+ @services_folder_existed = File.exist?('app/services')
7
+ end
8
+
9
+ def copy_service_template
10
+ template 'service.rb.erb', "app/services/#{ service_file_path }.rb"
11
+ end
12
+
13
+ def post_template_message
14
+ puts "\n" +
15
+ "Service class generated. Please add the service to the " +
16
+ "`config.services` hash in your config/initializers/stall.rb file\n\n"
17
+
18
+ return if @services_folder_existed
19
+
20
+ puts " * Warning : app/services folder was just created, \n" +
21
+ " * please restart your server to let Rails know that it should\n" +
22
+ " * autoload this folder.\n\n"
23
+ end
24
+
25
+ private
26
+
27
+ def service_class_name
28
+ @service_class_name ||= service_file_path.camelize
29
+ end
30
+
31
+ def stall_service_class_name
32
+ @stall_service_class_name ||= ['Stall', service_class_name.demodulize].join('::')
33
+ end
34
+
35
+ def service_file_path
36
+ @service_file_path ||= [file_path.gsub(/service$/, ''), 'service'].join('_')
37
+ end
38
+ end
39
+ end