ish_models 0.0.33.304 → 3.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +15 -0
  5. data/app/assets/config/ish_models_manifest.js +1 -0
  6. data/app/assets/stylesheets/ish_models/application.css +15 -0
  7. data/app/controllers/ish_models/application_controller.rb +4 -0
  8. data/app/helpers/ish_models/application_helper.rb +4 -0
  9. data/app/jobs/ish_models/application_job.rb +4 -0
  10. data/app/mailers/ish_models/application_mailer.rb +6 -0
  11. data/app/models/ish_models/application_record.rb +5 -0
  12. data/app/views/layouts/ish_models/application.html.erb +15 -0
  13. data/config/routes.rb +2 -0
  14. data/lib/ish_models/engine.rb +5 -0
  15. data/lib/ish_models/version.rb +3 -0
  16. data/lib/ish_models.rb +4 -89
  17. data/lib/tasks/ish_models_tasks.rake +4 -0
  18. data/lib/{office/admin_message.rb → wco/profile.rb} +2 -5
  19. metadata +32 -221
  20. data/lib/address.rb +0 -20
  21. data/lib/feature.rb +0 -32
  22. data/lib/gallery.rb +0 -66
  23. data/lib/gameui/asset3d.rb +0 -35
  24. data/lib/gameui/map.rb +0 -260
  25. data/lib/gameui/map_bookmark.rb +0 -9
  26. data/lib/gameui/marker.rb +0 -128
  27. data/lib/iro/alert.rb-bk +0 -72
  28. data/lib/ish/cache_key.rb +0 -14
  29. data/lib/ish/configuration.rb +0 -11
  30. data/lib/ish/crawler.rb +0 -26
  31. data/lib/ish/email_campaign.rb +0 -55
  32. data/lib/ish/email_context.rb +0 -113
  33. data/lib/ish/email_template.rb +0 -115
  34. data/lib/ish/email_unsubscribe.rb +0 -19
  35. data/lib/ish/event.rb +0 -20
  36. data/lib/ish/image_asset.rb +0 -38
  37. data/lib/ish/invoice.rb +0 -130
  38. data/lib/ish/lorem_ipsum.rb +0 -30
  39. data/lib/ish/meeting.rb +0 -31
  40. data/lib/ish/payment.rb +0 -29
  41. data/lib/ish/premium_item.rb +0 -13
  42. data/lib/ish/railtie.rb +0 -8
  43. data/lib/ish/user_profile.rb +0 -146
  44. data/lib/ish/utils.rb +0 -45
  45. data/lib/mongoid/votable.rb +0 -247
  46. data/lib/mongoid/voter.rb +0 -96
  47. data/lib/newsitem.rb +0 -94
  48. data/lib/office/action.rb +0 -32
  49. data/lib/office/action_tie.rb +0 -16
  50. data/lib/office/directmail_envelope.rb +0 -51
  51. data/lib/office/email_action.rb +0 -34
  52. data/lib/office/email_action_tie.rb +0 -18
  53. data/lib/office/email_attachment.rb +0 -12
  54. data/lib/office/email_conversation.rb +0 -86
  55. data/lib/office/email_conversation_lead.rb +0 -11
  56. data/lib/office/email_conversation_tag.rb +0 -14
  57. data/lib/office/email_filter.rb +0 -45
  58. data/lib/office/email_message.rb +0 -229
  59. data/lib/office/email_message_stub.rb +0 -22
  60. data/lib/office/lead_action.rb +0 -24
  61. data/lib/office/lead_action_template.rb +0 -47
  62. data/lib/office/obfuscated_redirect.rb +0 -12
  63. data/lib/office/scheduled_email_action.rb +0 -62
  64. data/lib/photo.rb +0 -87
  65. data/lib/report.rb +0 -65
  66. data/lib/video.rb +0 -91
  67. data/lib/wco/appliance.rb +0 -43
  68. data/lib/wco/appliance_tmpl.rb +0 -36
  69. data/lib/wco/leadset.rb +0 -17
  70. data/lib/wco/price.rb +0 -30
  71. data/lib/wco/product.rb +0 -35
  72. data/lib/wco/serverhost.rb +0 -100
  73. data/lib/wco/subscription.rb +0 -25
@@ -1,51 +0,0 @@
1
- require 'prawn'
2
-
3
- class Office::DirectmailEnvelope
4
- include Mongoid::Document
5
- include Mongoid::Timestamps
6
-
7
-
8
- ## 72 points per inch
9
- ## 72 ppi
10
- def self.list_to_envelopes props
11
- from = props[:from]
12
-
13
- pdf = Prawn::Document.new({ page_size: [ 9.5*72, 4.12*72 ], :margin => [0,0,0,0] })
14
-
15
- pdf.canvas do
16
-
17
- props[:tos].each_with_index do |to, idx|
18
- print '.'
19
-
20
- pdf.bounding_box( [ 0.5*72, 3.5*72 ], width: 3*72, height: 2*72 ) do
21
- # pdf.transparent(0.5) { pdf.stroke_bounds }
22
-
23
- pdf.text from[:name]
24
- pdf.text from[:address_1]
25
- pdf.text from[:address_2]
26
- pdf.text from[:address_3]
27
- end
28
-
29
- pdf.bounding_box( [ 4*72, 2.5*72 ], width: 4*72, height: 2*72 ) do
30
- # pdf.transparent(0.5) { pdf.stroke_bounds }
31
-
32
- pdf.text to[:name]
33
- pdf.text to[:address_1]
34
- pdf.text to[:address_2]
35
- pdf.text to[:address_3]
36
- end
37
-
38
- if idx+1 != props[:tos].length
39
- pdf.start_new_page
40
- end
41
-
42
- end
43
-
44
- end
45
-
46
- return pdf
47
- end
48
-
49
- end
50
- ODE = ::Office::DirectmailEnvelope
51
-
@@ -1,34 +0,0 @@
1
-
2
- ##
3
- ## 2023-03-04 _vp_ When I receive one.
4
- ## 2023-03-04 _vp_ When I send one, forever.
5
- ##
6
- class Office::EmailAction
7
- include Mongoid::Document
8
- include Mongoid::Timestamps
9
-
10
- field :slug, type: :string
11
- validates :slug, uniqueness: true, allow_nil: true
12
-
13
- field :descr, type: :string ## optional, can remove
14
-
15
- belongs_to :email_template, class_name: '::Ish::EmailTemplate'
16
- def tmpl; email_template; end
17
-
18
- has_many :scheduled_email_actions, class_name: '::Office::ScheduledEmailAction'
19
- def schs; scheduled_email_actions; end
20
-
21
- has_many :ties, class_name: '::Office::EmailActionTie', inverse_of: :email_action
22
- has_many :prev_ties, class_name: '::Office::EmailActionTie', inverse_of: :next_email_action
23
- accepts_nested_attributes_for :ties
24
-
25
- has_many :email_filters, class_name: 'Office::EmailFilter', inverse_of: :email_action
26
-
27
- field :deleted_at, default: nil, type: :time
28
-
29
- def self.list
30
- [[nil,nil]] + Office::EmailAction.where({ :deleted_at => nil }).map { |a| [ a.slug, a.id ] }
31
- end
32
-
33
- end
34
- EAct = Office::EmailAction
@@ -1,18 +0,0 @@
1
-
2
- ##
3
- ## act = Act.new ; tie = Actie.new; act.ties.push( tie )
4
- ##
5
- class Office::EmailActionTie
6
- include Mongoid::Document
7
- include Mongoid::Timestamps
8
-
9
- attr_accessor :to_delete
10
-
11
- belongs_to :email_action, class_name: '::Office::EmailAction', inverse_of: :ties
12
- belongs_to :next_email_action, class_name: '::Office::EmailAction', inverse_of: :prev_ties
13
-
14
- field :next_at_exe, type: :string
15
- validates :next_at_exe, presence: true
16
-
17
- end
18
- EActie = Office::EmailActionTie
@@ -1,12 +0,0 @@
1
-
2
- class Office::EmailAttachment
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
-
6
- belongs_to :email_message, class_name: 'Office::EmailMessage', inverse_of: :email_attachments
7
-
8
- field :content
9
- field :content_type
10
- field :filename
11
-
12
- end
@@ -1,86 +0,0 @@
1
-
2
- class Office::EmailConversation
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
- include Mongoid::Paranoia
6
-
7
- STATE_UNREAD = 'state_unread'
8
- STATE_READ = 'state_read'
9
- STATES = [ STATE_UNREAD, STATE_READ ]
10
- field :state
11
-
12
- field :subject
13
- index({ subject: -1 })
14
-
15
- field :latest_at
16
- index({ latest_at: -1 })
17
-
18
- field :from_emails, type: :array, default: []
19
- index({ from_emails: -1 })
20
-
21
- field :preview, default: ''
22
-
23
- has_many :lead_ties, class_name: 'Office::EmailConversationLead'
24
- # def lead_ids
25
- # email_conversation_leads.map( &:lead_id )
26
- # end
27
- # field :lead_ids, type: :array, default: []
28
- def leads
29
- Lead.find( lead_ties.map( &:lead_id ) )
30
- end
31
-
32
- has_many :email_messages, class_name: 'Office::EmailMessage'
33
- has_many :email_conversation_tags, class_name: 'Office::EmailConversationTag'
34
-
35
- def wp_term_ids ## @TODO: remove _vp_ 2023-09-23
36
- email_conversation_tags.map( &:wp_term_id )
37
- end
38
-
39
- def tags
40
- WpTag.find( email_conversation_tags.map( &:wp_term_id ) )
41
- end
42
-
43
- ## Tested manually ok, does not pass the spec. @TODO: hire to make pass spec? _vp_ 2023-03-07
44
- def add_tag which
45
- tag = WpTag.iso_get which
46
- # puts!( tag.slug, "Adding tag" ) if DEBUG
47
- Office::EmailConversationTag.find_or_create_by!({
48
- email_conversation_id: id,
49
- wp_term_id: tag.id,
50
- })
51
- end
52
-
53
- def remove_tag which
54
- tag = WpTag.iso_get which
55
- # puts!( tag.slug, "Removing tag" ) if DEBUG
56
- Office::EmailConversationTag.where({
57
- email_conversation_id: id,
58
- wp_term_id: tag.id,
59
- }).first&.delete
60
- end
61
- ## @deprecated, do not use. _vp_ 2023-10-29
62
- def rmtag which; remove_tag which; end
63
-
64
- def in_emailtag? which
65
- tag = WpTag.iso_get( which )
66
- email_conversation_tags.where({ wp_term_id: tag.id }).present?
67
- end
68
-
69
- def self.in_emailtag which
70
- tag = WpTag.iso_get( which )
71
- email_conversation_tags = Office::EmailConversationTag.where({ wp_term_id: tag.id })
72
- where({ :id.in => email_conversation_tags.map(&:email_conversation_id) })
73
- end
74
-
75
- def self.not_in_emailtag which
76
- tag = WpTag.iso_get( which )
77
- email_conversation_tags = Office::EmailConversationTag.where({ wp_term_id: tag.id })
78
- where({ :id.nin => email_conversation_tags.map(&:email_conversation_id) })
79
- end
80
-
81
-
82
-
83
-
84
-
85
- end
86
- Conv = Office::EmailConversation
@@ -1,11 +0,0 @@
1
-
2
- class Office::EmailConversationLead
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
-
6
- belongs_to :email_conversation, class_name: 'Office::EmailConversation'
7
-
8
- field :lead_id, type: :integer
9
- validates :lead_id, uniqueness: { scope: :email_conversation_id }, presence: true
10
-
11
- end
@@ -1,14 +0,0 @@
1
-
2
- class Office::EmailConversationTag
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
-
6
- belongs_to :email_conversation, class_name: 'Office::EmailConversation'
7
-
8
- field :wp_term_id, type: :integer
9
- validates :wp_term_id, uniqueness: { scope: :email_conversation_id }, presence: true
10
- index({ wp_term_id: -1 })
11
- index({ wp_term_id: -1, latest_at: -1 })
12
-
13
-
14
- end
@@ -1,45 +0,0 @@
1
-
2
- ##
3
- ## 2023-03-04 _vp_ When I receive one.
4
- ##
5
- class Office::EmailFilter
6
- include Mongoid::Document
7
- include Mongoid::Timestamps
8
-
9
- field :from_regex
10
- field :from_exact
11
- field :subject_regex
12
- field :subject_exact
13
- field :body_regex
14
- field :body_exact
15
-
16
-
17
- KIND_AUTORESPOND_TMPL = 'autorespond-template'
18
- KIND_AUTORESPOND_EACT = 'autorespond-email-action'
19
- KIND_REMOVE_TAG = 'remove-tag'
20
- KIND_ADD_TAG = 'add-tag'
21
- KIND_DESTROY_SCHS = 'destroy-schs'
22
-
23
- KIND_AUTORESPOND = 'autorespond' # @deprecated, DO NOT USE!
24
- KIND_DELETE = 'delete' # @deprecated, use add-tag
25
- KIND_SKIP_INBOX = 'skip-inbox' # @deprecated, use remove-tag
26
-
27
- KINDS = [ nil, KIND_AUTORESPOND_TMPL, KIND_AUTORESPOND_EACT, KIND_ADD_TAG, KIND_REMOVE_TAG, KIND_DESTROY_SCHS]
28
- field :kind
29
-
30
- STATE_ACTIVE = 'active'
31
- STATE_INACTIVE = 'inactive'
32
- STATES = [ STATE_ACTIVE, STATE_INACTIVE ]
33
- field :state, type: :string, default: STATE_ACTIVE
34
- scope :active, ->{ where( state: STATE_ACTIVE ) }
35
-
36
- belongs_to :email_template, class_name: 'Ish::EmailTemplate', optional: true
37
- belongs_to :email_action, class_name: 'Office::EmailAction', optional: true
38
-
39
- field :wp_term_id, type: :integer
40
- def category
41
- self.wp_term_id && WpTag.find( self.wp_term_id )
42
- end
43
-
44
- end
45
-
@@ -1,229 +0,0 @@
1
-
2
- require 'action_view'
3
-
4
- ##
5
- ## When I receive one.
6
- ##
7
- class Office::EmailMessage
8
- include Mongoid::Document
9
- include Mongoid::Timestamps
10
-
11
- field :raw, type: :string
12
- def the_mail
13
- Mail.new( raw )
14
- end
15
-
16
- field :message_id, type: :string # MESSAGE-ID
17
- validates_uniqueness_of :message_id
18
- index({ message_id: 1 }, { unique: true, name: "id_idx" })
19
-
20
- field :in_reply_to_id, type: :string
21
-
22
- field :object_key, type: :string ## aka 'filename', use with bucket name + prefix. I need this!
23
- # validates_presence_of :object_key
24
- field :object_path, type: :string ## A routable s3 url
25
-
26
- field :subject
27
- field :part_html
28
- field :part_txt
29
-
30
- def lead
31
- Lead.find_by email: from
32
- end
33
-
34
- field :from, type: :string
35
- field :froms, type: Array, default: []
36
- field :to, type: :string
37
- field :tos, type: Array, default: []
38
- field :cc, type: :string
39
- field :ccs, type: Array, default: []
40
- def all_ccs; (tos||[]) + (ccs||[]) + (froms||[]); end
41
- field :bcc, type: :string
42
- field :bccs, type: Array, default: []
43
-
44
- field :logs, type: Array, default: []
45
-
46
- field :date, type: DateTime
47
- def received_at
48
- date
49
- end
50
-
51
- belongs_to :email_conversation, class_name: 'Office::EmailConversation'
52
- def conv
53
- email_conversation
54
- end
55
-
56
- has_many :email_attachments, class_name: 'Office::EmailAttachment', inverse_of: :email_message
57
- has_many :asset3ds, class_name: 'Gameui::Asset3d', inverse_of: :email_message
58
- has_many :attachments, class_name: 'Photo'
59
-
60
-
61
-
62
- def apply_filter filter
63
- case filter.kind
64
-
65
- when ::Office::EmailFilter::KIND_DESTROY_SCHS
66
- conv.add_tag ::WpTag::TRASH
67
- conv.remove_tag ::WpTag::INBOX
68
- lead.schs.each do |sch|
69
- sch.update_attributes({ state: ::Sch::STATE_TRASH })
70
- end
71
-
72
- when ::Office::EmailFilter::KIND_ADD_TAG
73
- conv.add_tag filter.wp_term_id
74
- if ::WpTag::TRASH == ::WpTag.find( filter.wp_term_id ).slug
75
- conv.remove_tag ::WpTag::INBOX
76
- end
77
-
78
- when ::Office::EmailFilter::KIND_REMOVE_TAG
79
- conv.remove_tag filter.wp_term_id
80
-
81
- when ::Office::EmailFilter::KIND_AUTORESPOND_TMPL
82
- Ish::EmailContext.create({
83
- email_template: filter.email_template,
84
- lead_id: lead.id,
85
- send_at: Time.now + 22.minutes,
86
- })
87
-
88
- when ::Office::EmailFilter::KIND_AUTORESPOND_EACT
89
- ::Sch.create({
90
- email_action: filter.email_action,
91
- state: ::Sch::STATE_ACTIVE,
92
- lead_id: lead.id,
93
- perform_at: Time.now + 22.minutes,
94
- })
95
-
96
- else
97
- raise "unknown filter kind: #{filter.kind}"
98
- end
99
- end
100
-
101
- ## From: https://stackoverflow.com/questions/24672834/how-do-i-remove-emoji-from-string/24673322
102
- def self.strip_emoji(text)
103
- text = '' if text.blank?
104
- text = text.force_encoding('utf-8').encode
105
- clean = ""
106
-
107
- # symbols & pics
108
- regex = /[\u{1f300}-\u{1f5ff}]/
109
- clean = text.gsub regex, ""
110
-
111
- # enclosed chars
112
- regex = /[\u{2500}-\u{2BEF}]/ # I changed this to exclude chinese char
113
- clean = clean.gsub regex, ""
114
-
115
- # emoticons
116
- regex = /[\u{1f600}-\u{1f64f}]/
117
- clean = clean.gsub regex, ""
118
-
119
- #dingbats
120
- regex = /[\u{2702}-\u{27b0}]/
121
- clean = clean.gsub regex, ""
122
- end
123
-
124
- ## For recursive parts of type `related`.
125
- ## Content dispositions:
126
- # "inline; creation-date=\"Tue, 11 Apr 2023 19:39:42 GMT\"; filename=image005.png; modification-date=\"Tue, 11 Apr 2023 19:47:53 GMT\"; size=14916",
127
- #
128
- ## Content Types:
129
- # "application/pdf; name=\"Securities Forward Agreement -- HaulHub Inc -- Victor Pudeyev -- 2021-10-26.docx.pdf\""
130
- # "image/jpeg; name=TX_DL_2.jpg"
131
- # "image/png; name=image005.png"
132
- # "multipart/alternative; boundary=_000_BL0PR10MB2913C560ADE059F0AB3A6D11829A9BL0PR10MB2913namp_",
133
- # "text/html; charset=utf-8"
134
- # "text/plain; charset=UTF-8"
135
- # "text/calendar; charset=utf-8; method=REQUEST"
136
- def churn_subpart part
137
- if part.content_disposition&.include?('attachment')
138
- save_attachment( part, filename: "subpart-attachment" )
139
- else
140
- if part.content_type.include?("multipart")
141
- part.parts.each do |subpart|
142
- churn_subpart( subpart )
143
- end
144
- else
145
- if part.content_type.include?('text/html')
146
- self.part_html = part.decoded
147
-
148
- elsif part.content_type.include?("text/plain")
149
- self.part_txt = part.decoded
150
-
151
- elsif part.content_type.include?("text/calendar")
152
- save_attachment( part, filename: 'subpart-calendar.ics' )
153
-
154
- elsif part.content_type.include?("application/pdf")
155
- save_attachment( part, filename: 'subpart.pdf' )
156
-
157
- elsif part.content_type.include?("image/jpeg")
158
- save_attachment( part, filename: 'subpart.jpg' )
159
-
160
- elsif part.content_type.include?("image/png")
161
- save_attachment( part, filename: 'subpart.png' )
162
-
163
- else
164
- save_attachment( part, filename: 'subpart-unspecified' )
165
- self.logs.push "444 No action for a part with content_type #{part.content_type}"
166
-
167
- end
168
- end
169
- end
170
- end
171
-
172
- def save_attachment att, filename: "no-filename-specified"
173
- content_type = att.content_type.split(';')[0]
174
- if content_type.include? 'image'
175
- photo = Photo.new({
176
- content_type: content_type,
177
- email_message_id: self.id,
178
- image_data: att.body.encoded,
179
- original_filename: att.content_type_parameters[:name],
180
- })
181
- photo.decode_base64_image
182
- photo.save
183
- else
184
-
185
- filename = CGI.escape( att.filename || filename )
186
- attachment = Office::EmailAttachment.new({
187
- content: att.body.decoded,
188
- content_type: att.content_type,
189
- email_message: self,
190
- filename: filename,
191
- })
192
- begin
193
- attachment.save
194
- rescue Encoding::UndefinedConversionError
195
- self.logs.push "Could not save an attachment"
196
- self.save
197
- end
198
-
199
- sio = StringIO.new att.body.decoded
200
- File.open("/tmp/#{filename}", 'w:UTF-8:ASCII-8BIT') do |f|
201
- f.puts(sio.read)
202
- end
203
- asset3d = ::Gameui::Asset3d.new({
204
- email_message: self,
205
- filename: filename,
206
- object: File.open("/tmp/#{filename}"),
207
- })
208
- if !asset3d.save
209
- self.logs.push "Could not save an asset3d"
210
- self.save
211
- end
212
-
213
- end
214
- end
215
-
216
- def body_sanitized
217
- ActionView::Base.full_sanitizer.sanitize( part_html||'' ).squish
218
- end
219
- def preview_str
220
- body_sanitized[0..200]
221
- end
222
-
223
-
224
- end
225
- ::Msg = Office::EmailMessage
226
-
227
-
228
-
229
-
@@ -1,22 +0,0 @@
1
-
2
- ##
3
- ## Only object_key, object_path, no validations.
4
- ##
5
- class Office::EmailMessageStub
6
- include Mongoid::Document
7
- include Mongoid::Timestamps
8
-
9
- STATE_PENDING = 'state_pending'
10
- STATE_PROCESSED = 'state_processed'
11
- STATES = [ STATE_PENDING, STATE_PROCESSED ]
12
- field :state, type: :string, default: STATE_PENDING
13
-
14
- field :object_key, type: :string ## aka 'filename', use with bucket name + prefix
15
- validates :object_key, presence: true, uniqueness: true
16
-
17
- # field :object_path, type: :string ## A routable s3 url ## @TODO: remove this field. _vp_ 2023-03-07
18
-
19
- # field :wp_term_ids, type: :array, default: []
20
-
21
- end
22
- MsgStub = EMS = Office::EmailMessageStub
@@ -1,24 +0,0 @@
1
-
2
- ##
3
- ## The obfuscated action
4
- ##
5
- class Office::LeadAction
6
- include Mongoid::Document
7
- include Mongoid::Timestamps
8
-
9
- belongs_to :lead_action_template, class_name: '::Office::LeadActionTemplate', inverse_of: :lead_actions, foreign_key: :tmpl_id
10
- def tmpl
11
- lead_action_template
12
- end
13
-
14
- field :lead_id, type: :integer
15
- validates :lead_id, presence: true
16
- def lead
17
- Lead.find( lead_id )
18
- end
19
-
20
- field :params, type: Object, default: '{}'
21
-
22
-
23
- end
24
-
@@ -1,47 +0,0 @@
1
-
2
- ##
3
- ##
4
- class Office::LeadActionTemplate
5
- include Mongoid::Document
6
- include Mongoid::Timestamps
7
-
8
- has_many :lead_actions, class_name: '::Office::LeadAction', inverse_of: :lead_action_templates
9
-
10
- field :slug
11
- validates :slug, presence: true
12
-
13
- field :action_exe, type: :string
14
- # validates :action_exe, presence: true
15
-
16
- field :config_json, type: Object, default: '{}'
17
-
18
- field :kind, type: :string
19
- KIND_UNSUBSCRIBE_TEMPLATE = 'kind-unsubscribe-template'
20
- KIND_UNSUBSCRIBE_CAMPAIGN = 'kind-unsubscribe-campaign'
21
- KINDS = [ KIND_UNSUBSCRIBE_TEMPLATE, KIND_UNSUBSCRIBE_CAMPAIGN ]
22
-
23
- def to_s
24
- "OLAT:#{slug}"
25
- end
26
-
27
- def unsubscribe_from_campaign
28
- end
29
-
30
- def unsubscribe_from_template
31
- template = EmailTemplate.find( ctx[:template_id] )
32
- subject = "Lead #{lead.full_name} unsubscribed from template #{template.slug}"
33
- out = Mailer.notify( 'poxlovi@gmail.com', subject )
34
- Rails.env.production? ? out.deliver_later : out.deliver_now
35
- Office::Unsubscribe.create({
36
- lead_id: lead_id,
37
- template_id: config_json['template_id'],
38
- })
39
- end
40
-
41
- def self.list
42
- [ [nil,nil] ] + all.map { |i| [ i.slug, i.id.to_s ] }
43
- end
44
-
45
-
46
- end
47
- OLAT = Office::LeadActionTemplate
@@ -1,12 +0,0 @@
1
-
2
- class Office::ObfuscatedRedirect
3
- include Mongoid::Document
4
- include Mongoid::Timestamps
5
-
6
- field :to, type: :string
7
- validates :to, presence: true
8
-
9
- field :visited_at, type: DateTime
10
- field :visits, type: :array, default: []
11
-
12
- end
@@ -1,62 +0,0 @@
1
-
2
- ##
3
- ## 2023-03-04 _vp_ An instance of an EmailAction.
4
- ##
5
- class Office::ScheduledEmailAction
6
- include Mongoid::Document
7
- include Mongoid::Timestamps
8
- include Mongoid::Paranoia
9
- store_in collection: 'office_scheduled_email_actions'
10
-
11
- field :lead_id, type: :integer
12
- def lead
13
- Lead.find( lead_id )
14
- end
15
-
16
- STATE_ACTIVE = 'active'
17
- STATE_INACTIVE = 'inactive'
18
- STATE_TRASH = 'trash'
19
- STATE_UNSUBSCRIBED = 'unsubscribed'
20
- STATES = [ STATE_ACTIVE, STATE_INACTIVE, STATE_UNSUBSCRIBED, STATE_TRASH ]
21
- field :state, type: :string
22
- scope :active, ->{ where( state: STATE_ACTIVE ) }
23
-
24
- belongs_to :email_action, class_name: '::Office::EmailAction'
25
- validates :email_action, uniqueness: { scope: :lead_id }
26
- def act; email_action; end
27
- def act= a; email_action= a; end
28
-
29
- has_many :email_contexts, class_name: '::Ish::EmailContext'
30
- def ctxs; email_contexts; end
31
-
32
- field :perform_at, type: :time
33
-
34
- def send_and_roll
35
- sch = self
36
- sch.update({ state: Sch::STATE_INACTIVE })
37
-
38
- # send now
39
- ctx = Ctx.create!({
40
- email_template_id: sch.act.tmpl.id,
41
- from_email: sch.act.tmpl.from_email,
42
- lead_id: sch.lead.id,
43
- scheduled_email_action_id: sch.act.id,
44
- send_at: Time.now,
45
- subject: sch.act.tmpl.subject,
46
- })
47
-
48
- # schedule next actions & update the action
49
- sch.act.ties.each do |tie|
50
- next_sch = Sch.find_or_initialize_by({
51
- lead_id: sch.lead_id,
52
- email_action_id: tie.next_email_action.id,
53
- })
54
- next_sch.perform_at = eval(tie.next_at_exe)
55
- next_sch.state = Sch::STATE_ACTIVE
56
- next_sch.save!
57
- end
58
- end
59
-
60
- end
61
- ::Sch = Office::ScheduledEmailAction
62
-