stall 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/para/stall/admin/carts_controller.rb +0 -8
  3. data/app/controllers/para/stall/admin/shipping_notes_controller.rb +33 -0
  4. data/app/mailers/stall/customer_mailer.rb +19 -0
  5. data/app/models/billing_address.rb +1 -0
  6. data/app/models/manufacturer.rb +3 -0
  7. data/app/models/shipping_address.rb +1 -0
  8. data/app/models/stall/models/address.rb +8 -0
  9. data/app/models/stall/models/billing_address.rb +9 -0
  10. data/app/models/stall/models/manufacturer.rb +18 -0
  11. data/app/models/stall/models/product.rb +7 -10
  12. data/app/models/stall/models/product_category.rb +4 -6
  13. data/app/models/stall/models/shipping_address.rb +9 -0
  14. data/app/models/stall/models/variant.rb +15 -1
  15. data/app/services/stall/credit_usage_service.rb +4 -0
  16. data/app/services/stall/shipping_notification_service.rb +41 -0
  17. data/app/views/admin/shipments/_fields.html.haml +7 -0
  18. data/app/views/para/stall/admin/shipping_notes/new.html.haml +22 -0
  19. data/app/views/para/stall/admin/shipping_notes/sent.html.haml +11 -0
  20. data/app/views/stall/addresses/_fields.html.haml +1 -1
  21. data/app/views/stall/credit_note_adjustments/_form.html.haml +1 -1
  22. data/app/views/stall/customer_mailer/order_shipped_email.html.haml +18 -0
  23. data/app/views/stall/shared/mailers/_cart.html.haml +11 -4
  24. data/app/views/stall/shared/mailers/_shipping_note.html.haml +52 -0
  25. data/config/locales/stall.fr.yml +35 -0
  26. data/db/migrate/20161129101956_add_type_to_stall_address_ownerships.rb +4 -4
  27. data/db/migrate/20161202080218_add_reference_to_product_lists.rb +3 -2
  28. data/db/migrate/20170206091211_add_name_to_stall_variants.rb +5 -0
  29. data/db/migrate/20170217142050_create_stall_manufacturers.rb +10 -0
  30. data/db/migrate/20170217143037_add_manufacturer_to_stall_products.rb +6 -0
  31. data/db/migrate/20170217153634_add_notification_email_sent_at_to_stall_shipments.rb +5 -0
  32. data/lib/generators/stall/shipping/calculator/templates/calculator.rb.erb +19 -0
  33. data/lib/para/stall/routes.rb +3 -1
  34. data/lib/stall/addressable.rb +20 -0
  35. data/lib/stall/checkout/informations_checkout_step.rb +1 -1
  36. data/lib/stall/engine.rb +3 -5
  37. data/lib/stall/shipping/calculator.rb +12 -0
  38. data/lib/stall/version.rb +1 -1
  39. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98069c4e8cde848ade9836933bf11f176aae37b5
4
- data.tar.gz: baf0ab5fd49de75964401f8b01003c03446e4663
3
+ metadata.gz: af3519db9164c6f4fd61e1e56f019ef90c3e6a5d
4
+ data.tar.gz: 9fad0f1035c6510b67c80865b6284f844e4686ca
5
5
  SHA512:
6
- metadata.gz: 2edc779f219c016fb3b1a440c1a53cd2b8c6954e09845381ae3a90e8dec033fc30761e2765523aa0e5953bc64cd2f5ecc0b3b7407a09055fcf7066e87d1c2143
7
- data.tar.gz: d27a12120af62029f503c481f3ca07d82630a1b5504ce7c39f9b06cc9bee5642c3879573c25600262a11b38cc4c1380245372b54abeae436e47634b4a7515071
6
+ metadata.gz: 31367405801aa97eca7302b4286ee0d39c46540ba389eff0c43a3a9461123217c0414afa82249d073b3ebef0f143a6f1fbc151a5e63235c0773681eb8e873861
7
+ data.tar.gz: 8114b8156abd5b6cd53d861d6c952347f01f09c49040c30a67c0c3224fd7c3297e2fa09248ac75d46ef4bacc2db9c14759d01420d84c865ea5971c496afe5df2
@@ -13,14 +13,6 @@ module Para
13
13
  # cleaned up by the rake task
14
14
  @resources = @resources.filled
15
15
  end
16
-
17
- private
18
-
19
- def shipment_params
20
- params.require(:shipment).permit(
21
- :carrier, :tracking_code, :point_of_sale_id
22
- )
23
- end
24
16
  end
25
17
  end
26
18
  end
@@ -0,0 +1,33 @@
1
+ module Para
2
+ module Stall
3
+ module Admin
4
+ class ShippingNotesController < ::Para::Admin::ComponentController
5
+ before_filter :load_cart
6
+ authorize_resource :cart
7
+ authorize_resource :shipment
8
+
9
+ def new
10
+ render layout: false
11
+ end
12
+
13
+ def create
14
+ service = ::Stall.config.service_for(:shipping_notification).new(@cart, params)
15
+
16
+ if service.call
17
+ render 'sent', layout: false
18
+ else
19
+ flash_message(:error)
20
+ render 'new', layout: false
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def load_cart
27
+ @cart = ProductList.find(params[:resource_id])
28
+ @shipment = @cart.shipment || @cart.build_shipment
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -9,5 +9,24 @@ module Stall
9
9
  subject: I18n.t('stall.mailers.customer.order_paid_email.subject', ref: cart.reference)
10
10
  end
11
11
  end
12
+
13
+ def order_shipped_email(cart)
14
+ I18n.with_locale(cart.customer.locale) do
15
+ @cart = cart
16
+
17
+ calculator_class = Stall::Shipping::Calculator.for(cart.shipment.shipping_method)
18
+ @calculator = calculator_class.new(cart, cart.shipment.shipping_method)
19
+
20
+ @tracking_url = if @calculator.trackable?
21
+ cart.shipment.tracking_code.presence && @calculator.tracking_url
22
+ end
23
+
24
+ subject = t('stall.mailers.customer.order_shipped_email.subject', ref: cart.reference)
25
+
26
+ mail from: sender_email_for(cart),
27
+ to: cart.customer.email,
28
+ subject: subject
29
+ end
30
+ end
12
31
  end
13
32
  end
@@ -1,2 +1,3 @@
1
1
  class BillingAddress < Address
2
+ include Stall::Models::BillingAddress
2
3
  end
@@ -0,0 +1,3 @@
1
+ class Manufacturer < ActiveRecord::Base
2
+ include Stall::Models::Manufacturer
3
+ end
@@ -1,2 +1,3 @@
1
1
  class ShippingAddress < Address
2
+ include Stall::Models::ShippingAddress
2
3
  end
@@ -30,6 +30,14 @@ module Stall
30
30
  iso_state['name'] if iso_state
31
31
  end
32
32
 
33
+ def billing?
34
+ false
35
+ end
36
+
37
+ def shipping?
38
+ false
39
+ end
40
+
33
41
  private
34
42
 
35
43
  def iso_country
@@ -0,0 +1,9 @@
1
+ module Stall
2
+ module Models
3
+ module BillingAddress
4
+ def billing?
5
+ true
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module Stall
2
+ module Models
3
+ module Manufacturer
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ self.table_name = 'stall_manufacturers'
8
+
9
+ has_many :products, dependent: :nullify
10
+
11
+ has_attached_file :logo
12
+ validates_attachment_content_type :logo, content_type: /\Aimage\/.*\Z/
13
+
14
+ validates :name, presence: true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -11,6 +11,7 @@ module Stall
11
11
  friendly_id :name, use: [:slugged, :finders]
12
12
 
13
13
  belongs_to :product_category
14
+ belongs_to :manufacturer
14
15
 
15
16
  has_many :variants, dependent: :destroy, inverse_of: :product
16
17
  accepts_nested_attributes_for :variants, allow_destroy: true
@@ -27,18 +28,14 @@ module Stall
27
28
  validates_attachment :image, content_type: { content_type: /\Aimage\/.*\z/ }
28
29
 
29
30
  scope :visible, -> { where(visible: true) }
31
+ end
30
32
 
31
- def should_generate_new_friendly_id?
32
- slug.blank?
33
- end
34
-
35
- def vat_rate
36
- Stall.config.vat_rate
37
- end
33
+ def vat_rate
34
+ Stall.config.vat_rate
35
+ end
38
36
 
39
- def price
40
- variants.map(&:price).min
41
- end
37
+ def price
38
+ variants.map(&:price).min
42
39
  end
43
40
  end
44
41
  end
@@ -11,20 +11,18 @@ module Stall
11
11
 
12
12
  extend FriendlyId
13
13
  friendly_id :name, use: [:slugged, :finders]
14
-
14
+
15
15
  has_many :products, dependent: :nullify
16
16
 
17
17
  validates :name, presence: true
18
18
 
19
19
  scope :ordered, -> { order(position: 'asc') }
20
+ end
20
21
 
21
- def self.max_depth
22
+ module ClassMethods
23
+ def max_depth
22
24
  2
23
25
  end
24
-
25
- def should_generate_new_friendly_id?
26
- slug.blank?
27
- end
28
26
  end
29
27
  end
30
28
  end
@@ -0,0 +1,9 @@
1
+ module Stall
2
+ module Models
3
+ module ShippingAddress
4
+ def shipping?
5
+ true
6
+ end
7
+ end
8
+ end
9
+ end
@@ -21,13 +21,27 @@ module Stall
21
21
 
22
22
  monetize :price_cents, with_model_currency: :currency, allow_nil: false
23
23
 
24
- delegate :name, :image, :image?, :vat_rate, to: :product, allow_nil: true
24
+ before_validation :refresh_name
25
+
26
+ delegate :image, :image?, :vat_rate, to: :product, allow_nil: true
25
27
 
26
28
  scope :published, -> { where(published: true) }
27
29
 
28
30
  def currency
29
31
  @currency ||= Money::Currency.new(Stall.config.default_currency)
30
32
  end
33
+
34
+ private
35
+
36
+ def refresh_name
37
+ product_name = product.try(:name)
38
+
39
+ properties = variant_property_values.map do |variant_property_value|
40
+ variant_property_value.property_value.name
41
+ end
42
+
43
+ self.name = [product_name, properties.join(' - ')].join(' / ')
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -1,5 +1,7 @@
1
1
  module Stall
2
2
  class CreditUsageService < Stall::BaseService
3
+ class CartAlreadyPaidError < StandardError; end
4
+
3
5
  attr_reader :cart, :params
4
6
 
5
7
  def initialize(cart, params = {})
@@ -8,6 +10,7 @@ module Stall
8
10
  end
9
11
 
10
12
  def call
13
+ raise CartAlreadyPaidError, "Cannot udpate credit note from paid cart"
11
14
  return false unless enough_credit?
12
15
 
13
16
  clean_credit_note_adjustments!
@@ -47,6 +50,7 @@ module Stall
47
50
  end
48
51
 
49
52
  def clean_credit_note_adjustments!
53
+ raise CartAlreadyPaidError, "Cannot remove credit note from paid cart"
50
54
  credit_note_adjustments.each do |adjustment|
51
55
  cart.adjustments.destroy(adjustment)
52
56
  end
@@ -0,0 +1,41 @@
1
+ module Stall
2
+ class ShippingNotificationService < Stall::BaseService
3
+ attr_reader :cart, :params
4
+
5
+ def initialize(cart, params = {})
6
+ @cart = cart
7
+ @params = params
8
+ end
9
+
10
+ def call
11
+ if shipment.update(shipment_params)
12
+ send_customer_email
13
+ update_shipment
14
+
15
+ true
16
+ else
17
+ false
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def shipment
24
+ @shipment ||= cart.shipment || cart.build_shipment
25
+ end
26
+
27
+ def shipment_params
28
+ params.require(:shipment).permit(:shipping_method_id, :tracking_code)
29
+ end
30
+
31
+ def send_customer_email
32
+ Stall::CustomerMailer.order_shipped_email(cart).deliver
33
+ end
34
+
35
+ def update_shipment
36
+ shipment.sent_at ||= Time.now
37
+ shipment.notification_email_sent_at = Time.now
38
+ shipment.shipped!
39
+ end
40
+ end
41
+ end
@@ -5,3 +5,10 @@
5
5
 
6
6
  = form.input :price
7
7
  = form.input :sent_at, wrapper: :horizontal_form
8
+
9
+ - if form.object.cart.persisted?
10
+ = form.input :shipping_note do
11
+ = link_to @component.relation_path(form.object.cart, :shipping_note, action: :new), class: 'btn btn-default', remote: true, data: { :'remote-modal-form' => true, :'refresh-on-close' => true } do
12
+ = fa_icon 'envelope'
13
+ = t('para.stall.shipping_note.create')
14
+
@@ -0,0 +1,22 @@
1
+ = modal id: "shipment-modal-#{ @cart.id }", fade: false do |modal|
2
+ = modal.header do
3
+ = t('para.stall.shipping_note.create')
4
+
5
+ = simple_form_for @shipment, url: @component.relation_path(@cart, :shipping_note), method: :post, remote: true do |form|
6
+ = modal.body do
7
+ - if @shipment.notification_email_sent_at
8
+ .alert.alert-warning
9
+ = t('para.stall.shipping_note.notification_already_sent_at', date: l(@shipment.notification_email_sent_at)).html_safe
10
+
11
+ .well
12
+ = t('para.stall.shipping_note.help').html_safe
13
+
14
+ = form.input :shipping_method, as: :selectize
15
+ = form.input :tracking_code, hint: t('para.stall.shipping_note.tracking_code_help').html_safe
16
+
17
+ = modal.footer do
18
+ %button.btn.btn-default{ type: 'button', data: { dismiss: 'modal' } }
19
+ = t('stall.shared.cancel')
20
+
21
+ %button.btn.btn-primary{ type: 'submit' }
22
+ = t('stall.shared.send')
@@ -0,0 +1,11 @@
1
+ = modal id: "shipment-modal-#{ @cart.id }", fade: false do |modal|
2
+ = modal.header do
3
+ = t('para.stall.shipping_note.sent')
4
+
5
+ = modal.body do
6
+ %p= t('para.stall.shipping_note.sent_description').html_safe
7
+
8
+ = modal.footer do
9
+ %button.btn.btn-default{ type: 'button', data: { dismiss: 'modal' } }
10
+ = t('stall.shared.close')
11
+
@@ -3,7 +3,7 @@
3
3
  = form.fields_for :shipping_address do |address_form|
4
4
  = render partial: 'stall/addresses/nested_fields', locals: { form: address_form }
5
5
 
6
- = form.input :use_another_address_for_billing, as: :boolean, input_html: { data: { :'use-another-address-for-billing' => true } }
6
+ = form.input :use_another_address_for_billing, as: :boolean, input_html: { checked: (params[:use_another_address_for_billing] || form.object.billing_address?), data: { :'use-another-address-for-billing' => true } }
7
7
 
8
8
  %fieldset{ class: ('hidden' unless params[:use_another_address_for_billing] == '1'), data: { :'address-form' => :billing } }
9
9
  = form.fields_for :billing_address do |address_form|
@@ -1,4 +1,4 @@
1
- - if stall_user_signed_in? && available_customer_credit_for?(cart)
1
+ - if stall_user_signed_in? && available_customer_credit_for?(cart) && !cart.paid?
2
2
  = simple_form_for cart, url: cart_credit_path(cart), method: (credit_used_for?(@cart) ? :delete : :patch), html: { class: 'cart-credit-form', data: { :'cart-credit-form' => true } } do |form|
3
3
  = hidden_field_tag :_return_to, request.fullpath
4
4
 
@@ -0,0 +1,18 @@
1
+ %table
2
+ %tr
3
+ %td
4
+ = t('stall.mailers.customer.order_shipped_email.intro', ref: @cart.reference, time: l(Date.today)).html_safe
5
+
6
+ - if @tracking_url
7
+ %br
8
+ %br
9
+ = t('stall.mailers.customer.order_shipped_email.shipping_method_name', name: @cart.shipment.shipping_method.name).html_safe
10
+ %br
11
+ = t('stall.mailers.customer.order_shipped_email.tracking_code', code: @cart.shipment.tracking_code).html_safe
12
+ %br
13
+ = t('stall.mailers.customer.order_shipped_email.tracking_url', link: link_to(@tracking_url, @tracking_url)).html_safe
14
+
15
+ %br
16
+ %br
17
+
18
+ = render partial: 'stall/shared/mailers/shipping_note', locals: { cart: @cart, line_items: @cart.line_items }
@@ -11,18 +11,25 @@
11
11
  %td
12
12
  = t('stall.carts.recap.ordered_at', at: l(cart.created_at))
13
13
 
14
+ %tr
15
+ %td{ height: 20 }
16
+
14
17
  %tr
15
18
  %td
16
- %table
19
+ %table{ width: '100%' }
17
20
  %tbody
18
21
  %tr
19
22
  %td
20
23
  %h2= Cart.human_attribute_name(:billing_address)
21
- = render partial: 'stall/shared/mailers/address', locals: { address: cart.billing_address || cart.shipping_address }
22
-
23
24
  %td
24
25
  %h2= Cart.human_attribute_name(:shipping_address)
25
- = render partial: 'stall/shared/mailers/address', locals: { address: cart.shipping_address }
26
+
27
+ %tr
28
+ %td= render partial: 'stall/shared/mailers/address', locals: { address: cart.billing_address }
29
+ %td= render partial: 'stall/shared/mailers/address', locals: { address: cart.shipping_address }
30
+
31
+ %tr
32
+ %td{ height: 20 }
26
33
 
27
34
  %tr
28
35
  %td
@@ -0,0 +1,52 @@
1
+ %table
2
+ %tbody
3
+ %tr
4
+ %td
5
+ %table
6
+ %tbody
7
+ %tr
8
+ %td
9
+ = t('stall.carts.recap.order_ref', ref: cart.reference)
10
+ %tr
11
+ %td
12
+ = t('stall.carts.recap.ordered_at', at: l(cart.created_at))
13
+
14
+ %tr
15
+ %td{ height: 20 }
16
+
17
+ %tr
18
+ %td
19
+ %table{ width: '100%' }
20
+ %tbody
21
+ %tr
22
+ %td
23
+ %h2= Cart.human_attribute_name(:billing_address)
24
+ %td
25
+ %h2= Cart.human_attribute_name(:shipping_address)
26
+
27
+ %tr
28
+ %td= render partial: 'stall/shared/mailers/address', locals: { address: cart.billing_address }
29
+ %td= render partial: 'stall/shared/mailers/address', locals: { address: cart.shipping_address }
30
+
31
+ %tr
32
+ %td{ height: 20 }
33
+
34
+ %tr
35
+ %td
36
+ %table
37
+ %thead
38
+ %tr
39
+ %th= LineItem.human_attribute_name(:name)
40
+ %th= LineItem.human_attribute_name(:quantity)
41
+
42
+ %tbody
43
+ - line_items.each do |line_item|
44
+ %tr
45
+ %td= line_item.name
46
+ %td= line_item.quantity
47
+
48
+ %tr
49
+ %td
50
+ %b= t('stall.carts.recap.total_quantity')
51
+ %td
52
+ %b= line_items.map(&:quantity).sum
@@ -12,6 +12,20 @@ fr:
12
12
  variant_select:
13
13
  property_placeholder: "Choisissez une option ..."
14
14
 
15
+ shipping_note:
16
+ create: "Notifier le client de l'expédition de sa commande"
17
+ notification_already_sent_at: "Un e-mail de notification de livraison a déjà été envoyé au client le %{date}"
18
+ help: |
19
+ Un e-mail va être envoyé au client pour le notifier de l'expédition de sa commande.
20
+ <br>
21
+ Merci de vérifier les informations de livraison ci-dessous et de cliquer sur "Envoyer"
22
+ tracking_code_help: |
23
+ Afin d'envoyer le lien pour le suivi de la livraison au client, merci
24
+ de renseigner le code de suivi. Si vous laissez ce champ vide, le mail
25
+ sera bien envoyé mais ne contiendra pas de lien de suivi.
26
+ sent: "Notification envoyée !"
27
+ sent_description: "Le client a bien été notifié de l'expédition de sa commande. "
28
+
15
29
  forms:
16
30
  tabs:
17
31
  cart:
@@ -23,7 +37,9 @@ fr:
23
37
 
24
38
  stall:
25
39
  shared:
40
+ cancel: "Annuler"
26
41
  close: "Fermer"
42
+ send: "Envoyer"
27
43
  sending: "Envoi en cours ..."
28
44
 
29
45
  carts:
@@ -45,6 +61,7 @@ fr:
45
61
  total_eot_price: "Prix total HT"
46
62
  total_vat: "Total TVA"
47
63
  total_price: "Prix total"
64
+ total_quantity: "Quantité totale"
48
65
  remainder: "Le montant suivant sera transformé en avoir"
49
66
  update: "Mettre à jour le panier"
50
67
  validate: "Passer la commande"
@@ -140,6 +157,18 @@ fr:
140
157
  order_paid_email:
141
158
  subject: "Le paiement de votre commande n°%{ref} a bien été effectué !"
142
159
  intro: "Votre commande sera traitée dans les meilleurs délais."
160
+
161
+ order_shipped_email:
162
+ subject: "Votre commande n°%{ref} a été expédiée"
163
+ intro: |
164
+ Votre commande n°%{ref} a bien été expédiée le
165
+ <strong>%{time}</strong>
166
+ shipping_method_name: "Votre colis vous a été envoyé via %{name}"
167
+ tracking_code: "Votre code de suivi est le suivant : %{code}"
168
+ tracking_url: |
169
+ Vous pouvez suivre la livraison de votre commande avec le lien
170
+ suivant :<br>%{link}
171
+
143
172
  admin:
144
173
  order_paid_email:
145
174
  subject: "Une nouvelle commande a été passée sur le site - %{ref}"
@@ -171,6 +200,7 @@ fr:
171
200
  product_category: "Catégorie"
172
201
  variant: "Déclinaison"
173
202
  product_detail: "Bloc de description"
203
+ manufacturer: "Fabricant"
174
204
 
175
205
  attributes:
176
206
  line_item:
@@ -222,6 +252,7 @@ fr:
222
252
  shipping_method: "Mode de livraison"
223
253
  tracking_code: "Code de suivi"
224
254
  state: "État"
255
+ shipping_note: "Notification"
225
256
  payment:
226
257
  payment_method: "Mode de paiement"
227
258
  paid_at: "Payé le"
@@ -244,6 +275,10 @@ fr:
244
275
  product_detail:
245
276
  name: "Titre"
246
277
  content: "Contenu"
278
+ manufacturer:
279
+ name: "Nom du fabricant"
280
+ logo: "Logo"
281
+ products: "Produits"
247
282
 
248
283
  simple_form:
249
284
  placeholders:
@@ -25,15 +25,15 @@ class AddTypeToStallAddressOwnerships < ActiveRecord::Migration
25
25
 
26
26
  if ownership.billing
27
27
  billing_address = BillingAddress.new(addressable: ownership.addressable)
28
- Stall::Addresses::Copy.new(address, billing_address)
28
+ Stall::Addresses::Copy.new(address, billing_address).copy
29
29
  billing_address.save!
30
30
  end
31
31
  elsif ownership.billing
32
32
  address.type = 'BillingAddress'
33
- ownership.save!
34
- else
35
- ownership.destroy
33
+ address.save!
36
34
  end
35
+
36
+ ownership.destroy
37
37
  end
38
38
 
39
39
  remove_column :stall_address_ownerships, :billing
@@ -5,9 +5,10 @@ class AddReferenceToProductLists < ActiveRecord::Migration
5
5
 
6
6
  # Migrate all references stored in the JSON data columns to the new
7
7
  # reference column
8
- Cart.update_all("reference = data->>'reference'")
8
+ ProductList.update_all("reference = data->>'reference'")
9
9
  # Remove all reference keys in the JSON data columns
10
- Cart.update_all("data = (data - 'reference')")
10
+ # This is not supported before PG 4.5 so we avoid using it
11
+ # ProductList.update_all("data = (data - 'reference')")
11
12
  end
12
13
 
13
14
  def down
@@ -0,0 +1,5 @@
1
+ class AddNameToStallVariants < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_variants, :name, :string
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ class CreateStallManufacturers < ActiveRecord::Migration
2
+ def change
3
+ create_table :stall_manufacturers do |t|
4
+ t.string :name
5
+ t.attachment :logo
6
+
7
+ t.timestamps null: false
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ class AddManufacturerToStallProducts < ActiveRecord::Migration
2
+ def change
3
+ add_reference :stall_products, :manufacturer, index: true
4
+ add_foreign_key :stall_products, :stall_manufacturers, column: :manufacturer_id
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddNotificationEmailSentAtToStallShipments < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_shipments, :notification_email_sent_at, :datetime
4
+ end
5
+ end
@@ -26,4 +26,23 @@ class <%= class_name %> < Stall::Shipping::Calculator
26
26
  # def vat_rate
27
27
  # Stall.config.vat_rate
28
28
  # end
29
+
30
+ # Allow shipping notification e-mails to embed a tracking URL for the shipping
31
+ # method, and when the `Shipment#tracking_code` is filled for the cart.
32
+ #
33
+ # Note : If you make a shipping method trackable, don't forget to define the
34
+ # #tracking_url method below
35
+ #
36
+ # def trackable?
37
+ # true
38
+ # end
39
+
40
+ # Return a URL that will be given to the customer when notified of the
41
+ # shipping of its order
42
+ #
43
+ # def tracking_url
44
+ # if (tracking_code = cart.shipment.try(:tracking_code)).present?
45
+ # "http://www.my-shipping-service.com/tracking/url?code=#{ tracking_code }"
46
+ # end
47
+ # end
29
48
  end
@@ -3,7 +3,9 @@ module Para
3
3
  class Routes < Para::Plugins::Routes
4
4
  def draw
5
5
  plugin :stall do
6
- crud_component controller: '/para/stall/admin/carts'
6
+ crud_component controller: '/para/stall/admin/carts' do
7
+ resource :shipping_note, only: [:new, :create]
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -20,5 +20,25 @@ module Stall
20
20
 
21
21
  attr_accessor :use_another_address_for_billing
22
22
  end
23
+
24
+ # Allow billing address to fall back to shipping address when not filled
25
+ def billing_address
26
+ association(:billing_address).load_target ||
27
+ association(:shipping_address).load_target
28
+ end
29
+
30
+ def billing_address?
31
+ billing_address.persisted? && billing_address.billing?
32
+ end
33
+
34
+ # Allow shipping address to fall back to billing address when not filled
35
+ def shipping_address
36
+ association(:shipping_address).load_target ||
37
+ association(:billing_address).load_target
38
+ end
39
+
40
+ def shipping_address?
41
+ shipping_address.persisted? && shipping_address.billing?
42
+ end
23
43
  end
24
44
  end
@@ -52,7 +52,7 @@ module Stall
52
52
  # the full permissions nested array
53
53
  #
54
54
  def cart_params(*attributes)
55
- @cart_params ||= params.require(:cart).permit(
55
+ @cart_params ||= super(
56
56
  *merge_arrays(
57
57
  [
58
58
  :use_another_address_for_billing, :terms,
@@ -18,11 +18,9 @@ module Stall
18
18
  end
19
19
  end
20
20
 
21
- initializer 'stall.include_cart_helper' do
22
- ActiveSupport.on_load(:action_controller) do
23
- include Stall::CartHelper
24
- include Stall::ArchivedPaidCartHelper
25
- end
21
+ config.to_prepare do
22
+ ::ApplicationController.send(:include, Stall::CartHelper)
23
+ ::ApplicationController.send(:include, Stall::ArchivedPaidCartHelper)
26
24
  end
27
25
 
28
26
  initializer 'stall.ensure_shipping_method_for_all_calculators' do
@@ -20,6 +20,18 @@ module Stall
20
20
  'the actual shipping price for the given cart'
21
21
  end
22
22
 
23
+ # Override this method in the shipping calculators to declare wether a
24
+ # shipping method provides a tracking URL or not.
25
+ def trackable?
26
+ false
27
+ end
28
+
29
+ def tracking_url
30
+ raise NoMethodError,
31
+ 'Trackable shipping calculators should override the #tracking_url ' \
32
+ 'method and return a tracking URL for the associated shipment.'
33
+ end
34
+
23
35
  def eot_price
24
36
  price / (1 + (vat_rate / 100.0))
25
37
  end
@@ -1,3 +1,3 @@
1
1
  module Stall
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stall
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - vala
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-05 00:00:00.000000000 Z
11
+ date: 2017-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -337,6 +337,7 @@ files:
337
337
  - app/assets/stylesheets/stall/application.css
338
338
  - app/assets/stylesheets/stall/carts.css
339
339
  - app/controllers/para/stall/admin/carts_controller.rb
340
+ - app/controllers/para/stall/admin/shipping_notes_controller.rb
340
341
  - app/controllers/stall/application_controller.rb
341
342
  - app/controllers/stall/cart_credits_controller.rb
342
343
  - app/controllers/stall/carts_controller.rb
@@ -363,6 +364,7 @@ files:
363
364
  - app/models/credit_note_usage.rb
364
365
  - app/models/customer.rb
365
366
  - app/models/line_item.rb
367
+ - app/models/manufacturer.rb
366
368
  - app/models/payment.rb
367
369
  - app/models/payment_method.rb
368
370
  - app/models/product.rb
@@ -377,6 +379,7 @@ files:
377
379
  - app/models/stall/models.rb
378
380
  - app/models/stall/models/address.rb
379
381
  - app/models/stall/models/adjustment.rb
382
+ - app/models/stall/models/billing_address.rb
380
383
  - app/models/stall/models/cart.rb
381
384
  - app/models/stall/models/cart_credit_note_adjustment.rb
382
385
  - app/models/stall/models/credit_note.rb
@@ -384,6 +387,7 @@ files:
384
387
  - app/models/stall/models/credit_note_usage.rb
385
388
  - app/models/stall/models/customer.rb
386
389
  - app/models/stall/models/line_item.rb
390
+ - app/models/stall/models/manufacturer.rb
387
391
  - app/models/stall/models/payment.rb
388
392
  - app/models/stall/models/payment_method.rb
389
393
  - app/models/stall/models/product.rb
@@ -393,6 +397,7 @@ files:
393
397
  - app/models/stall/models/property.rb
394
398
  - app/models/stall/models/property_value.rb
395
399
  - app/models/stall/models/shipment.rb
400
+ - app/models/stall/models/shipping_address.rb
396
401
  - app/models/stall/models/shipping_method.rb
397
402
  - app/models/stall/models/variant.rb
398
403
  - app/models/stall/models/variant_property_value.rb
@@ -407,6 +412,7 @@ files:
407
412
  - app/services/stall/payment_notification_service.rb
408
413
  - app/services/stall/product_list_staleness_handling_service.rb
409
414
  - app/services/stall/shipping_fee_calculator_service.rb
415
+ - app/services/stall/shipping_notification_service.rb
410
416
  - app/views/admin/addresses/_fields.html.haml
411
417
  - app/views/admin/carts/_filters.html.haml
412
418
  - app/views/admin/carts/_form.html.haml
@@ -425,6 +431,8 @@ files:
425
431
  - app/views/checkout/steps/_shipping_method.html.haml
426
432
  - app/views/layouts/stall/application.html.erb
427
433
  - app/views/para/admin/resources/_variant_row.html.haml
434
+ - app/views/para/stall/admin/shipping_notes/new.html.haml
435
+ - app/views/para/stall/admin/shipping_notes/sent.html.haml
428
436
  - app/views/para/stall/inputs/_variant_select.html.haml
429
437
  - app/views/para/stall/inputs/_variants_matrix.html.haml
430
438
  - app/views/stall/addresses/_fields.html.haml
@@ -437,6 +445,7 @@ files:
437
445
  - app/views/stall/checkout/steps/show.html.haml
438
446
  - app/views/stall/credit_note_adjustments/_form.html.haml
439
447
  - app/views/stall/customer_mailer/order_paid_email.html.haml
448
+ - app/views/stall/customer_mailer/order_shipped_email.html.haml
440
449
  - app/views/stall/customers/_fields.html.haml
441
450
  - app/views/stall/customers/_sign_in.html.haml
442
451
  - app/views/stall/line_items/_add_error.html.haml
@@ -446,6 +455,7 @@ files:
446
455
  - app/views/stall/payments/manual_payment_gateway/_form.html.haml
447
456
  - app/views/stall/shared/mailers/_address.html.haml
448
457
  - app/views/stall/shared/mailers/_cart.html.haml
458
+ - app/views/stall/shared/mailers/_shipping_note.html.haml
449
459
  - app/views/stall/shipments/_fields.html.haml
450
460
  - config/locales/stall.en.yml
451
461
  - config/locales/stall.fr.yml
@@ -482,6 +492,10 @@ files:
482
492
  - db/migrate/20170202165514_create_stall_properties.rb
483
493
  - db/migrate/20170202165516_create_stall_property_values.rb
484
494
  - db/migrate/20170202165518_create_stall_variant_property_values.rb
495
+ - db/migrate/20170206091211_add_name_to_stall_variants.rb
496
+ - db/migrate/20170217142050_create_stall_manufacturers.rb
497
+ - db/migrate/20170217143037_add_manufacturer_to_stall_products.rb
498
+ - db/migrate/20170217153634_add_notification_email_sent_at_to_stall_shipments.rb
485
499
  - lib/generators/stall/checkout/step/step_generator.rb
486
500
  - lib/generators/stall/checkout/step/templates/step.html.haml.erb
487
501
  - lib/generators/stall/checkout/step/templates/step.rb.erb