stall 0.3.1 → 0.3.2

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.
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