wco_models 3.1.0.270 → 3.1.0.271

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.txt +10 -12
  3. data/app/assets/stylesheets/wco/main.scss +24 -0
  4. data/app/assets/stylesheets/wco/newsvideos.scss +45 -0
  5. data/app/controllers/wco/api_controller.rb +2 -2
  6. data/app/controllers/wco/application_controller.rb +45 -0
  7. data/app/controllers/wco/leads_controller.rb +0 -2
  8. data/app/controllers/wco/newspartials_controller.rb +1 -1
  9. data/app/controllers/wco/newsvideos_controller.rb +3 -2
  10. data/app/controllers/wco/publishers_controller.rb +12 -4
  11. data/app/controllers/wco/reports_controller.rb +140 -0
  12. data/app/controllers/wco/tags_controller.rb +18 -5
  13. data/app/controllers/wco/videos_controller.rb +4 -0
  14. data/app/mailers/wco_email/application_mailer.rb +1 -1
  15. data/app/models/ability.rb +3 -0
  16. data/app/models/iro/option.rb +2 -3
  17. data/app/models/iro/position.rb +67 -13
  18. data/app/models/iro/purse.rb +1 -2
  19. data/app/models/iro/stock.rb +20 -0
  20. data/app/models/iro/strategy.rb +57 -40
  21. data/app/models/tda/option.rb +1 -1
  22. data/app/models/wco/lead.rb +6 -5
  23. data/app/models/wco/newspartial.rb +7 -2
  24. data/app/models/wco/newsvideo.rb +2 -0
  25. data/app/models/wco/photo.rb +2 -0
  26. data/app/models/wco/profile.rb +6 -0
  27. data/app/models/wco/publisher.rb +3 -3
  28. data/app/models/wco/report.rb +6 -3
  29. data/app/models/wco/site.rb +2 -2
  30. data/app/models/wco/tag.rb +3 -0
  31. data/app/models/wco/video.rb +28 -3
  32. data/app/models/wco_email/email_filter.rb +1 -1
  33. data/app/models/wco_email/email_filter_action.rb +2 -0
  34. data/app/models/wco_email/email_filter_condition.rb +29 -14
  35. data/app/models/wco_email/message_stub.rb +2 -1
  36. data/app/views/wco/_main_footer.haml +4 -3
  37. data/app/views/wco/_main_header.haml +1 -0
  38. data/app/views/wco/_sidebar.haml +21 -0
  39. data/app/views/wco/newsoverlays/_show_in_newsvideo.haml +7 -5
  40. data/app/views/wco/newspartials/_show_in_newsvideo.haml +35 -28
  41. data/app/views/wco/newspartials/edit.haml +4 -0
  42. data/app/views/wco/newsvideos/_form.haml +10 -3
  43. data/app/views/wco/newsvideos/show.haml +20 -3
  44. data/app/views/wco/profiles/_form.haml +33 -13
  45. data/app/views/wco/publishers/_post_with.haml +7 -0
  46. data/app/views/wco/reports/_form.haml +11 -2
  47. data/app/views/wco/reports/_to_facebook.html +23 -0
  48. data/app/views/wco/reports/show.haml +15 -0
  49. data/app/views/wco/tags/_index_table.haml +4 -1
  50. data/app/views/wco/tags/_index_tree.haml +2 -1
  51. data/app/views/wco/tags/new_for_sidebar.haml +9 -0
  52. data/app/views/wco/tags/show.haml +54 -42
  53. data/app/views/wco/tags/show.haml-bk +63 -0
  54. data/config/initializers/08_integrations.rb +0 -15
  55. data/config/routes.rb +11 -2
  56. data/lib/wco/facebook_poster.rb +17 -0
  57. metadata +23 -3
  58. data/app/views/wco/newspartials/index.haml-trash +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 021150c40e30bb02fb18567bf718130b52075e9fa8bcb999e231f95c80413ed9
4
- data.tar.gz: 52f7e91b77c3ead85ced22ccd64f4267cfc96d3fddf59671fa115ce413c13267
3
+ metadata.gz: b6ada52987a4f58f060e2b8104870700dad094fb51db42ed715ce24ec6f04577
4
+ data.tar.gz: '0905e9664dc97846574e75a1e5770d2af1b3d4ac2dcde4e355980f73416f5067'
5
5
  SHA512:
6
- metadata.gz: dbfe2e00671a9ca7dc6c232186993e45f00c7afd6e74f4f2140d0902c19e29c5e709462dfef1d41112a2f9652e04c6b367fc5b878ce32ffc8d07d11245aafc07
7
- data.tar.gz: 2160353727634f5e7df835689ab93192d6e95dc42f37d600ef346a840d1221d5812c9c790d0e480dbf0312dfd8c6d3bb83b033bf66ca1877143eb3b3b4b59b50
6
+ metadata.gz: fc75d66a19e349914126d525aab2b56715b0abe93fc1c5301a2d17529925ba5244d02a10c6ea159667de670c72fe8201b5af7433aa000c7317b4c81c6bf9af4d
7
+ data.tar.gz: f225faf92e792a5f7c10236ec38c35d955821d11149f3d0cf16d9c88f50252904badab3b386d023a19a318d50cbc0e932ac5222aedb470cc4bb3e200f0f54e06
data/README.txt CHANGED
@@ -1,25 +1,23 @@
1
1
 
2
2
  WasyaCo Models. The functionality shared across all (most) projects, including:
3
- * The ActiveRecord models
4
- * some stylesheets,
5
- * some javascript.
3
+ * the ActiveRecord models
4
+ * some stylesheets
5
+ * some javascript
6
+ * some controllers and views
6
7
 
7
- == Setup ==
8
+ = Setup =
8
9
 
9
- Docker is reqiured for development. It is used for mongo, and localstack.
10
+ Docker is reqiured for development. It is used for mongo (?), and localstack.
10
11
 
11
- Some infrastructure is driven by ansible - therefore, local python is required:
12
+ Some infrastructure is driven by ansible - therefore, local python3 and ansible are required:
12
13
 
13
14
  python3 -m venv zenv
14
15
  . zenv/bin/activate
16
+ pip install -r requirements.txt
15
17
 
16
- == Test ==
18
+ = Test =
17
19
 
18
- Login to the localstack container, then:
19
-
20
- awslocal s3api put-object --bucket wco-email-ses-development \
21
- --key 00nn652jk1395ujdr3l11ib06jam0oevjqv2o4g1 \
22
- --body /opt/tmp/00nn652jk1395ujdr3l11ib06jam0oevjqv2o4g1
20
+ See doc/localstack.txt
23
21
 
24
22
  In ruby console:
25
23
 
@@ -3,6 +3,10 @@
3
3
  // display: block;
4
4
  // }
5
5
 
6
+ // .tmp-1 {
7
+ // float: right;
8
+ // }
9
+
6
10
  hr {
7
11
  border-top: 1px solid red;
8
12
  }
@@ -16,6 +20,14 @@ textarea {
16
20
  min-height: 300px;
17
21
  }
18
22
 
23
+ /* A */
24
+
25
+ .absolute {
26
+ border: 1px solid pink;
27
+ position: absolute;
28
+ background: pink;
29
+ }
30
+
19
31
  /* B */
20
32
 
21
33
  .blue {
@@ -70,6 +82,13 @@ table.bordered {
70
82
  }
71
83
  }
72
84
 
85
+ table.no-padding {
86
+ td {
87
+ padding: 0;
88
+ }
89
+ }
90
+
91
+
73
92
 
74
93
  /* C */
75
94
 
@@ -208,6 +227,11 @@ input[type=file] {
208
227
  font-size: 0.75em;
209
228
  }
210
229
  .mini-inputs {
230
+ border: 1px solid gray;
231
+ padding: 0.5em;
232
+
233
+ display: inline-block;
234
+
211
235
  input[type='number'] {
212
236
  width: 4em;
213
237
  }
@@ -1,10 +1,44 @@
1
1
 
2
+ .zero-height {
3
+ position: absolute;
4
+ }
5
+
6
+ .timeline-stamps {
7
+ border: 1px solid red;
8
+ width: 50px;
9
+
10
+ position: absolute;
11
+ top: 3px; // border
12
+
13
+ height: 100%;
14
+
15
+ .tick {
16
+ position: absolute;
17
+ left: 0;
18
+ font-size: 10px;
19
+ transform: translateY(-50%);
20
+ border-top: 1px solid black;
21
+ height: 5px;
22
+ background: white;
23
+ }
24
+
25
+ }
26
+
27
+
28
+
29
+
30
+
2
31
  .NewsoverlayTimeline {
3
32
  border: 5px solid green;
4
33
  position: absolute;
5
34
  left: 230px;
6
35
  }
7
36
 
37
+ .NewspartialTimelineW {
38
+ position: relative;
39
+ min-height: 50px;
40
+ }
41
+
8
42
  .NewspartialTimeline {
9
43
  border: 1px solid blue;
10
44
  position: relative;
@@ -28,9 +62,20 @@
28
62
  min-width: 300px;
29
63
  }
30
64
 
65
+ .full-textC {
66
+ z-index: 4;
67
+ position: relative;
68
+ background: white;
69
+ padding: 10px;
70
+ border: 1px solid black;
71
+ border-radius: 10px;
72
+ }
73
+
31
74
  }
32
75
 
33
76
  .main {
77
+
78
+
34
79
  width: 200px;
35
80
  }
36
81
 
@@ -17,8 +17,8 @@ class Wco::ApiController < ActionController::Base
17
17
  end
18
18
 
19
19
  def decode_simple_api_key
20
- if params[:api_key] === SIMPLE_API_KEY &&
21
- params[:api_secret] === SIMPLE_API_SECRET
20
+ if params[:api_key] === WCO_SIMPLE_API_KEY &&
21
+ params[:api_secret] === WCO_SIMPLE_API_SECRET
22
22
  user = User.find_by({ email: 'piousbox@gmail.com' })
23
23
  sign_in user
24
24
  else
@@ -29,6 +29,47 @@ class Wco::ApplicationController < ActionController::Base
29
29
  render layout: false
30
30
  end
31
31
 
32
+ def linkedin_cb
33
+ authorize! :open_permission, Wco
34
+ code = params[:code]
35
+ pi = Wco::Profile.pi
36
+
37
+ uri = URI("https://www.linkedin.com/oauth/v2/accessToken")
38
+ res = Net::HTTP.post_form(uri, {
39
+ grant_type: 'authorization_code',
40
+ code: code,
41
+ redirect_uri: linkedin_cb_url,
42
+ client_id: pi.linkedin_client_id,
43
+ client_secret: pi.linkedin_client_secret,
44
+ })
45
+ data = JSON.parse(res.body)
46
+ pi.update({ linkedin_access_token: data['access_token'] })
47
+ flash[:notice] = 'Ok.'
48
+ redirect_to '/'
49
+ end
50
+
51
+ def linkedin_sync
52
+ authorize! :open_permission, Wco
53
+
54
+ pi = Wco::Profile.pi
55
+ redirect_uri = linkedin_cb_url
56
+
57
+ base_url = "https://www.linkedin.com/oauth/v2/authorization"
58
+
59
+ params = {
60
+ response_type: "code",
61
+ client_id: pi.linkedin_client_id,
62
+ redirect_uri: redirect_uri,
63
+
64
+ scope: "openid profile email w_member_social" ## r_organization_admin w_organization_social
65
+ }
66
+
67
+ url = "#{base_url}?#{URI.encode_www_form(params)}"
68
+
69
+ puts! url, "linkedin_oauth_url"
70
+
71
+ redirect_to url, allow_other_host: true
72
+ end
32
73
 
33
74
  ##
34
75
  ## private
@@ -83,6 +124,10 @@ class Wco::ApplicationController < ActionController::Base
83
124
  end
84
125
 
85
126
  def set_lists
127
+ @new_tag = Wco::Tag.new
128
+ @sidebar_tags = @current_profile.sidebar_tags
129
+ @tags = Wco::Tag.all.order_by( slug: :asc )
130
+ @tags_list = Wco::Tag.list
86
131
  end
87
132
 
88
133
  end
@@ -46,11 +46,9 @@ class Wco::LeadsController < Wco::ApplicationController
46
46
  lead = Wco::Lead.find_by( email: lead_attrs[:email] ) rescue nil
47
47
  lead ||= Wco::Lead.create!(lead_attrs)
48
48
 
49
- # Assign selected tags
50
49
  selected_tag_ids.each do |tag_id|
51
50
  lead.tags << Wco::Tag.find(tag_id)
52
51
  end
53
- # lead.save!
54
52
  end
55
53
 
56
54
  redirect_to wco.leads_path, notice: "Leads imported successfully"
@@ -84,7 +84,7 @@ class Wco::NewspartialsController < Wco::ApplicationController
84
84
  else
85
85
  flash_alert "Cannot update newspartial: #{@newspartial.errors.messages}"
86
86
  end
87
- redirect_to action: 'index'
87
+ redirect_to newsvideo_path(@newspartial.newsvideo_id)
88
88
  end
89
89
 
90
90
  ##
@@ -86,13 +86,14 @@ class Wco::NewsvideosController < Wco::ApplicationController
86
86
 
87
87
  sentences = PragmaticSegmenter::Segmenter.new(text: @newsvideo.body).segment
88
88
  phrases = sentences_to_phrases(sentences)
89
- # puts! phrases, 'phrases'
89
+ puts! phrases, 'phrases'
90
+
90
91
  phrases.each do |phrase|
91
92
  newspartial = Wco::Newspartial.new body: phrase, newsvideo: @newsvideo
92
93
  newspartial.save!
93
94
  end
94
95
 
95
- flash_notice 'All done.'
96
+ flash_notice 'Done spliting the video.'
96
97
  redirect_to request.referrer
97
98
  end
98
99
 
@@ -1,10 +1,6 @@
1
1
 
2
- # require 'httparty'
3
-
4
2
  class Wco::PublishersController < Wco::ApplicationController
5
3
 
6
- ## Alphabetized : )
7
-
8
4
  def create
9
5
  @publisher = Wco::Publisher.new params[:publisher].permit!
10
6
  authorize! :create, @publisher
@@ -16,6 +12,7 @@ class Wco::PublishersController < Wco::ApplicationController
16
12
  redirect_to action: 'index'
17
13
  end
18
14
 
15
+ ## this is becoming obsolete - try using do_run_any
19
16
  def do_run
20
17
  @publisher = Wco::Publisher.find params[:id]
21
18
  authorize! :do_run, @publisher
@@ -29,6 +26,17 @@ class Wco::PublishersController < Wco::ApplicationController
29
26
  redirect_to action: 'index'
30
27
  end
31
28
 
29
+ def do_run_any
30
+ @publisher = Wco::Publisher.find params[:id]
31
+ authorize! :do_run, @publisher
32
+
33
+ @publisher.props = OpenStruct.new( JSON.parse params[:props] )
34
+ @publisher.do_run
35
+
36
+ flash_notice "Probably ok"
37
+ redirect_to request.referrer || { action: 'index' }
38
+ end
39
+
32
40
  def edit
33
41
  @publisher = Wco::Publisher.find params[:id]
34
42
  authorize! :edit, @publisher
@@ -8,7 +8,15 @@ class Wco::ReportsController < Wco::ApplicationController
8
8
 
9
9
  @report = Wco::Report.new params[:report].permit!
10
10
  authorize! :create, @report
11
+
11
12
  @report.author = current_profile
13
+
14
+ if params[:report][:image_thumb]&.[](:image).present?
15
+ thumb = @report.image_thumb || @report.build_image_thumb
16
+ thumb.image = params[:report][:image_thumb_attributes][:image]
17
+ thumb.save
18
+ end
19
+
12
20
  if @report.save
13
21
  flash_notice "created report"
14
22
  else
@@ -51,16 +59,148 @@ class Wco::ReportsController < Wco::ApplicationController
51
59
  @report = Wco::Report.unscoped.find params[:id]
52
60
  authorize! :show, @report
53
61
 
62
+ @publishers_list = Wco::Publisher.list
63
+
54
64
  # @config = JSON.parse( @report.config_json )
55
65
  # @duration_ms = @config['vtimes'].last.to_i + @config['vdurations'].last.to_i
56
66
  end
57
67
 
68
+ ## not working, no access
69
+ def to_company_linkedin
70
+ @report = Wco::Report.unscoped.find params[:id]
71
+ authorize! :edit, @report
72
+ pi = Wco::Profile.pi
73
+
74
+ response = HTTParty.get(
75
+ "https://api.linkedin.com/v2/organizationAcls?q=roleAssignee",
76
+ headers: {
77
+ "Authorization" => "Bearer #{pi.linkedin_access_token}"
78
+ }
79
+ )
80
+ org = JSON.parse(response.body)
81
+ puts! org, 'org'
82
+
83
+ uri = URI("https://api.linkedin.com/v2/ugcPosts")
84
+
85
+ req = Net::HTTP::Post.new(uri)
86
+ req["Authorization"] = "Bearer #{pi.linkedin_access_token}"
87
+ req["Content-Type"] = "application/json"
88
+ req["X-Restli-Protocol-Version"] = "2.0.0"
89
+
90
+ body = {
91
+ author: "urn:li:organization:#{org['id']}",
92
+ lifecycleState: "PUBLISHED",
93
+ specificContent: {
94
+ "com.linkedin.ugc.ShareContent": {
95
+ shareCommentary: {
96
+ text: "#{@report.title} #{@report.body}",
97
+ },
98
+ shareMediaCategory: "NONE"
99
+ }
100
+ },
101
+ visibility: {
102
+ "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
103
+ }
104
+ }
105
+
106
+ req.body = body.to_json
107
+
108
+ res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
109
+ http.request(req)
110
+ end
111
+
112
+ puts res.body
113
+ end
114
+
115
+ def to_facebook
116
+ @report = Wco::Report.unscoped.find params[:id]
117
+ authorize! :edit, @report
118
+ pi = Wco::Profile.pi
119
+
120
+ text = @report.body
121
+ text.gsub!(%r{</p\s*>}i, "\n")
122
+ text.gsub!(%r{<p\s*/?>}i, "")
123
+ text.gsub!(%r{<[^>]*>}, "")
124
+ text.strip.gsub(/\n{3,}/, "\n\n")
125
+
126
+ Wco::FacebookPoster.new.post("#{@report.title}\n\n#{text}")
127
+ flash_notice 'Probably ok.'
128
+ redirect_to request.referrer
129
+ end
130
+
131
+ def to_linkedin
132
+ @report = Wco::Report.unscoped.find params[:id]
133
+ authorize! :edit, @report
134
+ pi = Wco::Profile.pi
135
+
136
+ uri = URI("https://api.linkedin.com/v2/userinfo")
137
+ req = Net::HTTP::Get.new(uri)
138
+ req['Authorization'] = "Bearer #{pi.linkedin_access_token}"
139
+
140
+ res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
141
+ profile = JSON.parse(res.body)
142
+ puts! profile, 'profile'
143
+ user_id = profile['sub']
144
+
145
+ # Create post
146
+ post_uri = URI("https://api.linkedin.com/v2/ugcPosts")
147
+ post_req = Net::HTTP::Post.new(post_uri)
148
+
149
+ post_req['Authorization'] = "Bearer #{pi.linkedin_access_token}"
150
+ post_req['Content-Type'] = "application/json"
151
+ post_req['X-Restli-Protocol-Version'] = "2.0.0"
152
+
153
+
154
+ text = @report.body
155
+ text.gsub!(%r{</p\s*>}i, "\n")
156
+ text.gsub!(%r{<p\s*/?>}i, "")
157
+ text.gsub!(%r{<[^>]*>}, "")
158
+ text.strip.gsub(/\n{3,}/, "\n\n")
159
+
160
+ body = {
161
+ author: "urn:li:person:#{user_id}",
162
+ lifecycleState: "PUBLISHED",
163
+ specificContent: {
164
+ "com.linkedin.ugc.ShareContent": {
165
+ shareCommentary: {
166
+ text: "#{@report.title}\n\n#{text}",
167
+ },
168
+ shareMediaCategory: "NONE"
169
+ }
170
+ },
171
+ visibility: {
172
+ "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
173
+ }
174
+ }
175
+
176
+ post_req.body = body.to_json
177
+
178
+ post_res = Net::HTTP.start(post_uri.hostname, post_uri.port, use_ssl: true) do |http|
179
+ http.request(post_req)
180
+ end
181
+
182
+ render json: JSON.parse(post_res.body)
183
+ end
184
+
185
+
58
186
  def update
59
187
  params[:report][:tag_ids]&.delete ''
188
+ img_thumb_params = params[:report][:image_thumb]
189
+ params[:report].delete :image_thumb
190
+ # puts! img_thumb_params, 'img_thumb_params'
60
191
 
61
192
  @report = Wco::Report.unscoped.find params[:id]
62
193
  authorize! :update, @report
194
+
63
195
  if @report.update params[:report].permit!
196
+
197
+ if img_thumb_params.present?
198
+ @photo = Wco::Photo.new photo: img_thumb_params
199
+ @photo.save!
200
+ @report.image_thumb = @photo
201
+ end
202
+
203
+
64
204
  flash_notice "updated report"
65
205
  else
66
206
  flash_alert "Cannot update report: #{@report.errors.messages}"
@@ -22,7 +22,7 @@ class Wco::TagsController < Wco::ApplicationController
22
22
  else
23
23
  flash_alert 'No luck.'
24
24
  end
25
- redirect_to action: 'index'
25
+ redirect_to request.referrer
26
26
  end
27
27
 
28
28
  def edit
@@ -32,7 +32,7 @@ class Wco::TagsController < Wco::ApplicationController
32
32
 
33
33
  def index
34
34
  authorize! :index, Wco::Tag
35
- @tags = Wco::Tag.all
35
+ @tags = Wco::Tag.all.order_by( slug: :asc )
36
36
 
37
37
  tags = Wco::Tag.all.to_a.group_by(&:parent_id)
38
38
  build_tree = lambda do |parent_id|
@@ -50,6 +50,18 @@ class Wco::TagsController < Wco::ApplicationController
50
50
  authorize! :new, Wco::Tag
51
51
  end
52
52
 
53
+ def new_for_sidebar
54
+ authorize! :new, Wco::Tag
55
+ end
56
+ def create_for_sidebar
57
+ authorize! :create, Wco::Tag
58
+ @current_profile.sidebar_tags.push Wco::Tag.find(params[:tag_id])
59
+ @current_profile.save
60
+
61
+ flash_notice 'Ok'
62
+ redirect_to request.referrer
63
+ end
64
+
53
65
  def add_to
54
66
  @tag = Wco::Tag.find params[:id]
55
67
  resource = params[:resource].constantize.find params[:resource_id]
@@ -108,6 +120,8 @@ class Wco::TagsController < Wco::ApplicationController
108
120
  @leads = @tag.leads.page( params[::Wco::Lead::PAGE_PARAM_NAME] ).per( current_profile.per_page )
109
121
  @leadsets = @tag.leadsets.page( params[::Wco::Leadset::PAGE_PARAM_NAME] ).per( current_profile.per_page )
110
122
  @reports = @tag.reports.page( params[:reports_page] ).per( current_profile.per_page )
123
+
124
+ # render params['template'] || 'show'
111
125
  end
112
126
 
113
127
  def update
@@ -127,10 +141,9 @@ class Wco::TagsController < Wco::ApplicationController
127
141
  private
128
142
 
129
143
  def set_lists
130
- @new_tag = Wco::Tag.new
144
+ super
145
+
131
146
  @sites_list = Wco::Site.list
132
- @tags = Wco::Tag.all.order_by( slug: :asc )
133
- @tags_list = Wco::Tag.list
134
147
  end
135
148
 
136
149
 
@@ -9,6 +9,10 @@ class Wco::VideosController < Wco::ApplicationController
9
9
  @video = Wco::Video.new params[:video].permit!
10
10
  authorize! :create, @video
11
11
 
12
+ if !params[:video][:thumb]
13
+ @video.generate_thumbnail
14
+ end
15
+
12
16
  if @video.save
13
17
  flash[:notice] = 'Success'
14
18
  redirect_to videos_path
@@ -87,7 +87,7 @@ class WcoEmail::ApplicationMailer < ActionMailer::Base
87
87
  mail( from: @ctx.from_email,
88
88
  to: @ctx.to_email,
89
89
  cc: @ctx.cc,
90
- bcc: DEFAULT_BCC,
90
+ bcc: @ctx.from_email, # DEFAULT_BCC,
91
91
  subject: rendered_subject,
92
92
  body: rendered_str,
93
93
  content_type: "text/html",
@@ -13,6 +13,9 @@ class Ability
13
13
  if [ ENV['EMAIL'], 'piousbox@gmail.com' ].include? user.email
14
14
  can :manage, :all
15
15
  end
16
+ if Rails.env.test?
17
+ can :manage, :all
18
+ end
16
19
 
17
20
  end
18
21
 
@@ -17,8 +17,6 @@ class Iro::Option
17
17
  field :put_call, type: :string # 'PUT' or 'CALL'
18
18
  validates :put_call, presence: true
19
19
 
20
- field :delta, type: :float
21
-
22
20
  field :strike, type: :float
23
21
  validates :strike, presence: true
24
22
 
@@ -52,9 +50,10 @@ class Iro::Option
52
50
  field :end_price, type: :float
53
51
  field :end_delta, type: :float
54
52
 
55
-
56
53
  has_one :pos_of_outer, class_name: 'Iro::Position', inverse_of: :outer
57
54
  has_one :pos_of_inner, class_name: 'Iro::Position', inverse_of: :inner
55
+ belongs_to :poss_of_inner, class_name: 'Iro::Position', inverse_of: :inners, optional: true
56
+ belongs_to :poss_of_outer, class_name: 'Iro::Position', inverse_of: :outers, optional: true
58
57
 
59
58
  field :last, type: :float
60
59