spree_abandoned_cart 0.3.0 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -0
  3. data/.gitlab-ci.yml +15 -0
  4. data/.rspec +1 -0
  5. data/Gemfile +8 -0
  6. data/LICENSE +26 -0
  7. data/README.md +69 -0
  8. data/Rakefile +15 -0
  9. data/app/controllers/spree/admin/abandoned_orders_controller.rb +35 -0
  10. data/app/mailers/spree/abandoned_cart_mailer.rb +20 -0
  11. data/app/models/order_decorator.rb +38 -0
  12. data/app/models/order_updater_decorator.rb +25 -0
  13. data/app/models/spree/abandoned_cart_email_configuration.rb +5 -0
  14. data/app/models/spree/abandoned_order.rb +30 -0
  15. data/app/overrides/add_button_to_orders_tab_for_abandoned_index_page.rb +8 -0
  16. data/app/views/spree/abandoned_cart_mailer/abandoned_email.html.erb +145 -0
  17. data/app/views/spree/abandoned_cart_mailer/abandoned_second_email.html.erb +145 -0
  18. data/app/views/spree/abandoned_cart_mailer/abandoned_third_email.html.erb +145 -0
  19. data/app/views/spree/admin/abandoned_orders/_filters_bar.html.haml +49 -0
  20. data/app/views/spree/admin/abandoned_orders/_list.html.haml +22 -0
  21. data/app/views/spree/admin/abandoned_orders/_list_respond.js.erb +1 -0
  22. data/app/views/spree/admin/abandoned_orders/_order_summary.html.haml +16 -0
  23. data/app/views/spree/admin/abandoned_orders/_titles.html.haml +6 -0
  24. data/app/views/spree/admin/abandoned_orders/index.html.haml +3 -0
  25. data/app/views/spree/admin/abandoned_orders/index.js.haml +1 -0
  26. data/app/views/spree/admin/abandoned_orders/show.html.haml +2 -0
  27. data/config/initializers/load_preferences.rb +5 -0
  28. data/config/locales/en.yml +17 -0
  29. data/config/locales/ru.yml +17 -0
  30. data/config/routes.rb +9 -0
  31. data/db/migrate/20130722151112_add_abandoned_email_sent_at_to_spree_orders.rb +5 -0
  32. data/db/migrate/20150825122125_create_spree_abandoned_orders.rb +12 -0
  33. data/lib/generators/spree_abandoned_cart/install/install_generator.rb +21 -0
  34. data/lib/spree_abandoned_cart.rb +3 -0
  35. data/lib/spree_abandoned_cart/engine.rb +22 -0
  36. data/lib/spree_abandoned_cart/factories.rb +6 -0
  37. data/script/rails +7 -0
  38. data/spec/models/order_spec.rb +35 -0
  39. data/spec/spec_helper.rb +86 -0
  40. data/spree_abandoned_cart.gemspec +38 -0
  41. metadata +68 -16
@@ -0,0 +1,145 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+ <title><%= Spree.t("abandoned_cart.email.subject") %></title>
6
+ <style type="text/css">
7
+ #outlook a{padding:0;} /* Force Outlook to provide a "view in browser" button. */
8
+ body{width:100% !important;} .ReadMsgBody{width:100%;} .ExternalClass{width:100%;} /* Force Hotmail to display emails at full width */
9
+ body{-webkit-text-size-adjust:none;} /* Prevent Webkit platforms from changing default text sizes. */
10
+
11
+ body{font-family:Arial;margin:0; padding:0;}
12
+ img{border:0; height:auto; line-height:100%; outline:none; text-decoration:none;}
13
+ table td{border-collapse:collapse;}
14
+ #backgroundTable{height:100% !important; margin:0; padding:0; width:100% !important;}
15
+
16
+ body, #backgroundTable{
17
+ background-color:#FAFAFA;
18
+ }
19
+
20
+ #templateContainer{
21
+ border: 1px solid #DDDDDD;
22
+ margin-top: 10px;
23
+ padding: 20px;
24
+ }
25
+
26
+ h1, .h1{
27
+ color:#202020;
28
+ display:block;
29
+ font-family:Arial;
30
+ font-size:34px;
31
+ font-weight:bold;
32
+ line-height:100%;
33
+ margin-top:0;
34
+ margin-right:0;
35
+ margin-bottom:10px;
36
+ margin-left:0;
37
+ text-align:left;
38
+ }
39
+
40
+ h2, .h2{
41
+ color:#202020;
42
+ display:block;
43
+ font-family:Arial;
44
+ font-size:30px;
45
+ font-weight:bold;
46
+ line-height:100%;
47
+ margin-top:0;
48
+ margin-right:0;
49
+ margin-bottom:10px;
50
+ margin-left:0;
51
+ text-align:left;
52
+ }
53
+
54
+ h3, .h3{
55
+ color:#202020;
56
+ display:block;
57
+ font-family:Arial;
58
+ font-size:26px;
59
+ font-weight:bold;
60
+ line-height:100%;
61
+ margin-top:0;
62
+ margin-right:0;
63
+ margin-bottom:10px;
64
+ margin-left:0;
65
+ text-align:left;
66
+ }
67
+
68
+ h4, .h4{
69
+ color:#202020;
70
+ display:block;
71
+ font-family:Arial;
72
+ font-size:22px;
73
+ font-weight:bold;
74
+ line-height:100%;
75
+ margin-top:0;
76
+ margin-right:0;
77
+ margin-bottom:10px;
78
+ margin-left:0;
79
+ text-align:left;
80
+ }
81
+
82
+ #templateContainer, .bodyContent{
83
+ background-color:#FFFFFF;
84
+ }
85
+
86
+ .bodyContent div{
87
+ color:#505050;
88
+ font-family:Arial;
89
+ font-size:14px;
90
+ line-height:150%;
91
+ text-align:left;
92
+ }
93
+
94
+ .bodyContent div a:link, .bodyContent div a:visited, /* Yahoo! Mail Override */ .bodyContent div a .yshortcuts /* Yahoo! Mail Override */{
95
+ color:#336699;
96
+ font-weight:normal;
97
+ text-decoration:underline;
98
+ }
99
+
100
+ .bodyContent img{
101
+ display:inline;
102
+ height:auto;
103
+ }
104
+
105
+ #items {
106
+ margin: 10px 0;
107
+ }
108
+ </style>
109
+ </head>
110
+ <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
111
+ <center>
112
+ <table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="backgroundTable">
113
+ <tr>
114
+ <td align="center" valign="top">
115
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateContainer">
116
+ <tr>
117
+ <td align="center" valign="top">
118
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateBody">
119
+ <tr>
120
+ <td valign="top" class="bodyContent">
121
+ We noticed you still have some things in your shopping cart — if you need help with sizes or have questions, please call, email, or chat and we'll do our best.
122
+
123
+ <table cellpadding="0" cellspacing="0" border="0" align="center" id="items">
124
+ <% @order.line_items.each do |line_item| %>
125
+ <% variant = line_item.variant %>
126
+ <tr>
127
+ <td class="cart-item-description" data-hook="cart_item_description">
128
+ <strong><%= link_to variant.product.name, spree.product_url(variant.product) %></strong>
129
+ </td>
130
+ </tr>
131
+ <% end %>
132
+ </table>
133
+ </td>
134
+ </tr>
135
+ </table>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+ <br />
140
+ </td>
141
+ </tr>
142
+ </table>
143
+ </center>
144
+ </body>
145
+ </html>
@@ -0,0 +1,145 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
5
+ <title><%= Spree.t("abandoned_cart.email.subject") %></title>
6
+ <style type="text/css">
7
+ #outlook a{padding:0;} /* Force Outlook to provide a "view in browser" button. */
8
+ body{width:100% !important;} .ReadMsgBody{width:100%;} .ExternalClass{width:100%;} /* Force Hotmail to display emails at full width */
9
+ body{-webkit-text-size-adjust:none;} /* Prevent Webkit platforms from changing default text sizes. */
10
+
11
+ body{font-family:Arial;margin:0; padding:0;}
12
+ img{border:0; height:auto; line-height:100%; outline:none; text-decoration:none;}
13
+ table td{border-collapse:collapse;}
14
+ #backgroundTable{height:100% !important; margin:0; padding:0; width:100% !important;}
15
+
16
+ body, #backgroundTable{
17
+ background-color:#FAFAFA;
18
+ }
19
+
20
+ #templateContainer{
21
+ border: 1px solid #DDDDDD;
22
+ margin-top: 10px;
23
+ padding: 20px;
24
+ }
25
+
26
+ h1, .h1{
27
+ color:#202020;
28
+ display:block;
29
+ font-family:Arial;
30
+ font-size:34px;
31
+ font-weight:bold;
32
+ line-height:100%;
33
+ margin-top:0;
34
+ margin-right:0;
35
+ margin-bottom:10px;
36
+ margin-left:0;
37
+ text-align:left;
38
+ }
39
+
40
+ h2, .h2{
41
+ color:#202020;
42
+ display:block;
43
+ font-family:Arial;
44
+ font-size:30px;
45
+ font-weight:bold;
46
+ line-height:100%;
47
+ margin-top:0;
48
+ margin-right:0;
49
+ margin-bottom:10px;
50
+ margin-left:0;
51
+ text-align:left;
52
+ }
53
+
54
+ h3, .h3{
55
+ color:#202020;
56
+ display:block;
57
+ font-family:Arial;
58
+ font-size:26px;
59
+ font-weight:bold;
60
+ line-height:100%;
61
+ margin-top:0;
62
+ margin-right:0;
63
+ margin-bottom:10px;
64
+ margin-left:0;
65
+ text-align:left;
66
+ }
67
+
68
+ h4, .h4{
69
+ color:#202020;
70
+ display:block;
71
+ font-family:Arial;
72
+ font-size:22px;
73
+ font-weight:bold;
74
+ line-height:100%;
75
+ margin-top:0;
76
+ margin-right:0;
77
+ margin-bottom:10px;
78
+ margin-left:0;
79
+ text-align:left;
80
+ }
81
+
82
+ #templateContainer, .bodyContent{
83
+ background-color:#FFFFFF;
84
+ }
85
+
86
+ .bodyContent div{
87
+ color:#505050;
88
+ font-family:Arial;
89
+ font-size:14px;
90
+ line-height:150%;
91
+ text-align:left;
92
+ }
93
+
94
+ .bodyContent div a:link, .bodyContent div a:visited, /* Yahoo! Mail Override */ .bodyContent div a .yshortcuts /* Yahoo! Mail Override */{
95
+ color:#336699;
96
+ font-weight:normal;
97
+ text-decoration:underline;
98
+ }
99
+
100
+ .bodyContent img{
101
+ display:inline;
102
+ height:auto;
103
+ }
104
+
105
+ #items {
106
+ margin: 10px 0;
107
+ }
108
+ </style>
109
+ </head>
110
+ <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
111
+ <center>
112
+ <table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="backgroundTable">
113
+ <tr>
114
+ <td align="center" valign="top">
115
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateContainer">
116
+ <tr>
117
+ <td align="center" valign="top">
118
+ <table border="0" cellpadding="0" cellspacing="0" width="600" id="templateBody">
119
+ <tr>
120
+ <td valign="top" class="bodyContent">
121
+ We noticed you still have some things in your shopping cart — if you need help with sizes or have questions, please call, email, or chat and we'll do our best.
122
+
123
+ <table cellpadding="0" cellspacing="0" border="0" align="center" id="items">
124
+ <% @order.line_items.each do |line_item| %>
125
+ <% variant = line_item.variant %>
126
+ <tr>
127
+ <td class="cart-item-description" data-hook="cart_item_description">
128
+ <strong><%= link_to variant.product.name, spree.product_url(variant.product) %></strong>
129
+ </td>
130
+ </tr>
131
+ <% end %>
132
+ </table>
133
+ </td>
134
+ </tr>
135
+ </table>
136
+ </td>
137
+ </tr>
138
+ </table>
139
+ <br />
140
+ </td>
141
+ </tr>
142
+ </table>
143
+ </center>
144
+ </body>
145
+ </html>
@@ -0,0 +1,49 @@
1
+ - content_for :table_filter do
2
+ %div{"data-hook" => "admin_orders_index_search"}
3
+ = search_form_for [:admin, @search] do |f|
4
+ .row
5
+ .date-range-filter.col-md-8
6
+ .form-group
7
+ = label_tag :q_created_at, Spree.t('abandoned_cart.date_range_created')
8
+ .row.no-padding-bottom
9
+ .col-md-6
10
+ .input-group
11
+ = f.text_field :created_at_gt, class: 'datepicker datepicker-from form-control', value: params[:q][:created_at_gt], placeholder: Spree.t(:start)
12
+ %span.input-group-addon
13
+ %i.icon.icon-calendar
14
+ .col-md-6
15
+ .input-group
16
+ = f.text_field :created_at_lt, class: 'datepicker datepicker-to form-control', value: params[:q][:created_at_lt], placeholder: Spree.t(:stop)
17
+ %span.input-group-addon
18
+ %i.icon.icon-calendar
19
+ .row
20
+ .date-range-filter.col-md-8
21
+ .form-group
22
+ = label_tag :q_updated_at, Spree.t('abandoned_cart.date_range_sent_emails')
23
+ .row.no-padding-bottom
24
+ .col-md-6
25
+ .input-group
26
+ = f.text_field :updated_at_gt, class: 'datepicker datepicker-to form-control', value: params[:q][:updated_at_gt], placeholder: Spree.t(:start)
27
+ %span.input-group-addon
28
+ %i.icon.icon-calendar
29
+ .col-md-6
30
+ .input-group
31
+ = f.text_field :updated_at_lt, class: 'datepicker datepicker-to form-control', value: params[:q][:updated_at_lt], placeholder: Spree.t(:stop)
32
+ %span.input-group-addon
33
+ %i.icon.icon-calendar
34
+ .row
35
+ .col-md-4
36
+ .form-group
37
+ = label_tag :q_send_emails_count, Spree.t(:email)
38
+ = f.select :send_emails_count_eq, [[Spree.t('abandoned_cart.filters.attempt_one'), 1],
39
+ [Spree.t('abandoned_cart.filters.attempt_two'), 2],
40
+ [Spree.t('abandoned_cart.filters.attempt_three'), 3]],
41
+ {include_blank: true}, class: 'select2 js-filterable'
42
+ .col-md-4
43
+ .form-group
44
+ .checkbox
45
+ = label_tag 'q_completed_at_not_null' do
46
+ = f.check_box :order_accomplished_eq, {checked: false }
47
+ = Spree.t(:show_only_accomplished)
48
+ .form-actions{"data-hook" => "admin_orders_index_search_buttons"}
49
+ = button Spree.t(:filter_results), 'search'
@@ -0,0 +1,22 @@
1
+ %table#listing_abandoned_carts.table{'data-hook' => '', 'data-sortable-link' => update_positions_admin_abandoned_orders_path}
2
+ %thead
3
+ %tr{'data-hook' => 'abandoned_carts_header'}
4
+ %th Order number
5
+ %th Emails sent
6
+ %th Last email sent at
7
+ %th Accomplished
8
+ %th Accomplished at
9
+ %th Campaign
10
+ %th.actions
11
+ %tbody
12
+ - abandoned_carts.each do |abandoned_cart|
13
+ %tr{ class: "state-#{abandoned_cart.order.state.downcase} #{cycle('odd', 'even')}", 'data-hook' => 'abandoned_cart_row', id: abandoned_cart.id}
14
+ %td= link_to abandoned_cart.order.number, admin_abandoned_order_path(abandoned_cart)
15
+ %td= abandoned_cart.send_emails_count
16
+ %td= abandoned_cart.updated_at
17
+ %td= abandoned_cart.order_accomplished
18
+ %td= abandoned_cart.accomplished_at
19
+ %td Base
20
+ %td.actions.actions-1
21
+ = link_to_with_icon 'trash', Spree.t(:delete), admin_abandoned_order_path(abandoned_cart), { method: :delete, data: { confirm:'Are you sure?' }, no_text: true, remote: true}
22
+ = paginate abandoned_carts
@@ -0,0 +1 @@
1
+ $('table#listing_abandoned_carts').html('<%= j(render('list', abandoned_carts: @abandoned_carts))%>');
@@ -0,0 +1,16 @@
1
+ - @order = @abandoned_cart.order
2
+ = render 'spree/admin/shared/order_tabs', current: :cart
3
+ %div{"data-hook" => "admin_order_edit_header"}
4
+ = render 'spree/admin/shared/error_messages', target: @order
5
+ - if @order.payments.exists? && @order.considered_risky?
6
+ = render 'spree/admin/orders/risk_analysis', latest_payment: @order.payments.order("created_at DESC").first
7
+ = render 'spree/admin/orders/add_line_item' if can?(:update, @order)
8
+ - if @order.line_items.empty?
9
+ .alert.alert-warning
10
+ = Spree.t(:your_order_is_empty_add_product)
11
+ %div{"data-hook" => "admin_order_edit_form"}
12
+ #order-form-wrapper
13
+ = render 'spree/admin/orders/line_items_edit_form', order: @order
14
+ - content_for :head do
15
+ = javascript_tag 'var expand_variants = true;'
16
+ = render 'spree/admin/shared/order_summary'
@@ -0,0 +1,6 @@
1
+ - content_for :page_title do
2
+ = Spree.t(:abandoned_index)
3
+ - content_for :page_actions do
4
+ - unless current_page?(admin_abandoned_orders_path)
5
+ %li
6
+ = button_link_to Spree.t(:abandoned_index), admin_abandoned_orders_path, icon: 'arrow-left'
@@ -0,0 +1,3 @@
1
+ = render 'titles'
2
+ = render 'filters_bar'
3
+ = render 'list', abandoned_carts: @abandoned_carts
@@ -0,0 +1 @@
1
+ = render 'list_respond'
@@ -0,0 +1,2 @@
1
+ = render 'titles'
2
+ = render 'order_summary', abandoned_cart: @abandoned_cart
@@ -0,0 +1,5 @@
1
+ module Spree
2
+ module AbandonedCartEmailConfig
3
+ Config = Spree::AbandonedCartEmailConfiguration.new
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ en:
2
+ spree:
3
+ abandoned_index: Abandoned carts
4
+ show_only_accomplished: Show only accomplished
5
+ abandoned_cart:
6
+ date_range_created: Date range - created
7
+ date_range_sent_emails: Date range - emails sending
8
+ email:
9
+ subject: There are still items in your shopping cart!
10
+ subject_second: We remind you that you have forgotten your cart!
11
+ subject_third: Last chance to pick up your goods!
12
+ filters:
13
+ abandoned: Abandoned
14
+ success: Success
15
+ attempt_one: Sent 1 email
16
+ attempt_two: Sent 2 emails
17
+ attempt_three: Sent 3 emails
@@ -0,0 +1,17 @@
1
+ ru:
2
+ spree:
3
+ abandoned_index: Брошенные корзины
4
+ show_only_accomplished: Показать только выполненые
5
+ abandoned_cart:
6
+ date_range_created: Диапазон дат - создано
7
+ date_range_sent_emails: Диапазон дат - последняя отправка
8
+ email:
9
+ subject: В вашей корзине остались товары!
10
+ subject_second: Напомним вам, что вы забыли товары!
11
+ subject_third: Последний шанс, чтобы забрать ваши товары!
12
+ filters:
13
+ abandoned: Брошена
14
+ success: Куплена
15
+ attempt_one: Отослано 1 письмо
16
+ attempt_two: Отослано 2 письма
17
+ attempt_three: Отослано 3 письма