wco_models 3.1.0.249 → 3.1.0.250

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 811515dc851478aafef1a023f1d86f80eada380cbb8552d58aa7c4216e01a37f
4
- data.tar.gz: f0f5b2627f42b50f6b43cad2206eaf2808aa8cf1cf875abad63b238f1a14d898
3
+ metadata.gz: e5d5d8a2f6c49b59221969a2316d3d67b5ae66c1e05583557ae37dd699154678
4
+ data.tar.gz: 7118d503e0ebbdc81ab6c43530982fc25577adc45f99a24fcf64b086ffba4d3a
5
5
  SHA512:
6
- metadata.gz: 97ed822fabc86f2ca940e1bdbcd35242a7fdeffa80f94e79903e82bd781f275f78c2a9d141c54104841988b2d1347e4bae32f211a736a62f8faa30a2fe4b66c7
7
- data.tar.gz: 8c85be7260093d502de15b57f2d9ccb8886e32a34dd8e122fae0cd2324b5ea92b988e4de58eb4dc8224472a8e0eaadc8afa9a74efb00ad32c79036a8cfebdd83
6
+ metadata.gz: 844d93fa80db62810740823375f8f7aa7212867b0e06b48e61a2b40c486183ee0f8b991423019f93e5c3b374f04a607625b426f541bdcd718736ca0500926c92
7
+ data.tar.gz: 07fdc6450dc423173adfe7649978c3129abfb7dba440818f656c1625900f235add1a7fce531b5129d41beda7aa91d7dba182265e3c03293f7845e2738e1cfab7
@@ -199,7 +199,8 @@ input[type=file] {
199
199
  /* M */
200
200
 
201
201
  .maxwidth {
202
- max-width: 1000px; /* @TODO: this would be responsive by-breakpoint _vp_ 2024-04-23 */
202
+ width: 1200px;
203
+ max-width: 1200px; /* @TODO: this would be responsive by-breakpoint _vp_ 2024-04-23 */
203
204
  margin: auto;
204
205
  }
205
206
 
@@ -229,6 +230,13 @@ input[type=file] {
229
230
  margin: 15px; // bootstrap has 15px gutters
230
231
  }
231
232
 
233
+ table pre {
234
+ max-width: 50vw;
235
+ max-height: 50vh;
236
+ border: 1px solid #ccc;
237
+ padding: 1em;
238
+ }
239
+
232
240
  /* R */
233
241
 
234
242
  .red {
@@ -14,6 +14,17 @@ class WcoEmail::ApplicationMailer < ActionMailer::Base
14
14
  subject: "POX::#{@msg.subject}" )
15
15
  end
16
16
 
17
+ def notify_self params
18
+ subject = params[:subject] || 'default subject'
19
+ body = params[:body] || 'default body'
20
+ mail( from: DEFAULT_FROM,
21
+ to: DEFAULT_RECIPIENT,
22
+ subject: subject,
23
+ body: body,
24
+ content_type: "text/text",
25
+ );
26
+ end
27
+
17
28
  def option_alert option
18
29
  @option = option
19
30
  mail({
@@ -53,10 +64,10 @@ class WcoEmail::ApplicationMailer < ActionMailer::Base
53
64
 
54
65
  profile = Wco::Profile.find_by email: @ctx.from_email
55
66
  delivery_options = {
67
+ address: profile.smtp_host,
68
+ password: profile.smtp_password,
69
+ port: profile.smtp_port,
56
70
  user_name: profile.smtp_username,
57
- password: profile.smtp_password,
58
- address: profile.smtp_host,
59
- post: profile.smtp_port,
60
71
  };
61
72
 
62
73
  mail( from: @ctx.from_email,
@@ -14,7 +14,8 @@ class Wco::Lead
14
14
  field :name
15
15
  field :phone
16
16
  field :address
17
- field :comment
17
+ field :comment ## _TODO: replace with log?
18
+ field :memory, type: Hash, default: {}
18
19
 
19
20
  belongs_to :leadset, class_name: 'Wco::Leadset'
20
21
  before_validation :set_leadset, on: :create
@@ -81,7 +82,8 @@ class Wco::Lead
81
82
  end
82
83
 
83
84
  def to_s
84
- "#{name} <#{email}>"
85
+ # "`#{name}` <#{email}>"
86
+ email
85
87
  end
86
88
  def self.list
87
89
  [[nil,nil]] + all.map { |p| [ p.email, p.id ] }
@@ -20,31 +20,33 @@ class Wco::OfficeAction
20
20
  STATUSS = [ STATUS_ACTIVE, STATUS_INACTIVE ]
21
21
  field :status, type: :string
22
22
  scope :active, ->{ where( status: STATUS_ACTIVE ) }
23
+ attr_accessor :deactivate
23
24
 
24
25
  field :perform_at, type: :time
25
26
 
26
27
  def do_run
27
- sch = self
28
- sch.update!({ status: STATUS_INACTIVE })
28
+ @oa = self
29
+ @oa.update!({ status: STATUS_INACTIVE })
29
30
 
30
31
  begin
31
- eval( sch.tmpl.action_exe )
32
+ eval( @oa.tmpl.action_exe )
32
33
  rescue => err
33
34
  puts! err, "Wco::OfficeAction#do_run"
34
- ::ExceptionNotifier.notify_exception(
35
- err,
36
- data: { office_action: self }
37
- )
35
+ ::ExceptionNotifier.notify_exception( err, data: { office_action: self } )
38
36
  end
39
37
 
40
- # schedule next actions & update the action
41
- sch.tmpl.ties.each do |tie|
42
- next_sch = self.class.find_or_initialize_by({
43
- office_action_template_id: tie.next_tmpl.id,
44
- })
45
- next_sch.perform_at = eval(tie.next_at_exe)
46
- next_sch.status = STATUS_ACTIVE
47
- next_sch.save!
38
+ if @oa.deactivate
39
+ ; # nothing
40
+ else
41
+ # schedule next actions & update the action
42
+ @oa.tmpl.ties.each do |tie|
43
+ next_oa = self.class.find_or_initialize_by({
44
+ office_action_template_id: tie.next_tmpl.id,
45
+ })
46
+ next_oa.perform_at = eval(tie.next_at_exe)
47
+ next_oa.status = STATUS_ACTIVE
48
+ next_oa.save!
49
+ end
48
50
  end
49
51
  end
50
52
 
@@ -33,6 +33,8 @@ class Wco::OfficeActionTemplate
33
33
  # has_and_belongs_to_many :email_filters, class_name: WcoEmail::EmailFilter
34
34
  has_many :email_filters, class_name: '::WcoEmail::EmailFilter', inverse_of: :office_action_template
35
35
 
36
+ has_many :ajects, inverse_of: :aject ## email action object
37
+
36
38
  def to_s
37
39
  "#{slug}"
38
40
  end
@@ -15,13 +15,13 @@ class Wco::Tag
15
15
  belongs_to :site, class_name: '::Wco::Site', optional: true
16
16
  has_many :email_filters, class_name: '::WcoEmail::EmailFilter', inverse_of: :tag
17
17
  has_many :email_templates, class_name: '::WcoEmail::EmailTemplate', inverse_of: :tag
18
+ has_many :ajects, class_name: '::WcoEmail::EmailFilterAction', inverse_of: :aject
18
19
 
19
20
  has_and_belongs_to_many :conversations, class_name: '::WcoEmail::Conversation', index: true
20
21
  has_and_belongs_to_many :galleries, class_name: '::Wco::Gallery'
21
- has_and_belongs_to_many :headlines # , class_name: 'Headline'
22
22
  has_and_belongs_to_many :leads, class_name: '::Wco::Lead', index: true
23
23
  has_and_belongs_to_many :leadsets, class_name: '::Wco::Leadset'
24
- has_and_belongs_to_many :logs
24
+ has_many :logs, inverse_of: :obj
25
25
  has_and_belongs_to_many :message_stubs, class_name: '::WcoEmail::MessageStub'
26
26
  has_and_belongs_to_many :newsvideos, class_name: '::Wco::Newsvideo'
27
27
  has_and_belongs_to_many :reports, class_name: '::Wco::Report'
@@ -35,6 +35,10 @@ class WcoEmail::Conversation
35
35
 
36
36
  belongs_to :filter, class_name: 'WcoEmail::EmailFilter', inverse_of: :conversations, optional: true
37
37
 
38
+ =begin
39
+ current_profile = OpenStruct.new per_page: 25
40
+ params = { tagname: 'inbox' }
41
+ =end
38
42
  def self.load_conversations_messages_tag_by_params_and_profile params, current_profile
39
43
  @conversations = WcoEmail::Conversation.all
40
44
 
@@ -15,6 +15,8 @@ class WcoEmail::EmailActionTemplate
15
15
 
16
16
  belongs_to :email_template, class_name: 'EmailTemplate'
17
17
 
18
+ has_many :ajects, inverse_of: :aject ## email action object
19
+
18
20
  has_many :email_actions, class_name: 'EmailAction'
19
21
 
20
22
  has_many :ties, class_name: '::WcoEmail::EmailActionTemplateTie', inverse_of: :tmpl
@@ -5,12 +5,11 @@ class WcoEmail::EmailFilter
5
5
  include Mongoid::Paranoia
6
6
  store_in collection: 'office_email_filters' ## 'wco_email_email_filters'
7
7
 
8
- PAGE_PARAM_NAME = :filters_page
9
-
10
- FIELD_OPTS = [ 'subject', 'from', 'to', 'to_and_cc', 'body', ] ## 'lead_tag_id'
11
- MATCHTYPE_OPTS = [ 'regex', 'exact_insensitive' ]
8
+ field :descr, type: :string
12
9
 
10
+ PAGE_PARAM_NAME = :filters_page
13
11
 
12
+ ## @deprecated, use email_filter_conditions
14
13
  field :from_regex
15
14
  field :from_exact
16
15
  field :subject_regex
@@ -22,8 +21,13 @@ class WcoEmail::EmailFilter
22
21
  field :skip_from_regex
23
22
  field :skip_to_exact
24
23
 
24
+ STATUS_ACTIVE = 'active'
25
+ STATUS_INACTIVE = 'inactive'
26
+ field :status, type: :string, default: STATUS_ACTIVE
27
+ def self.active; where( :status.in => [ nil, STATUS_ACTIVE ] ); end
28
+
25
29
  has_many :actions, class_name: '::WcoEmail::EmailFilterAction', inverse_of: :email_filter
26
- accepts_nested_attributes_for :actions, allow_destroy: true
30
+ accepts_nested_attributes_for :actions, allow_destroy: true, reject_if: :all_blank
27
31
  # validate :validate_actions
28
32
  def validate_actions
29
33
  if actions.length == 0
@@ -33,11 +37,11 @@ class WcoEmail::EmailFilter
33
37
 
34
38
  ## 'and' - all conditions must match, for filter to match
35
39
  has_many :conditions, class_name: '::WcoEmail::EmailFilterCondition', inverse_of: :email_filter
36
- accepts_nested_attributes_for :conditions, allow_destroy: true
40
+ accepts_nested_attributes_for :conditions, allow_destroy: true, reject_if: :all_blank
37
41
 
38
42
  ## 'and' - all conditions must match, for filter to match
39
43
  has_many :skip_conditions, class_name: '::WcoEmail::EmailFilterCondition', inverse_of: :email_skip_filter
40
- accepts_nested_attributes_for :skip_conditions, allow_destroy: true
44
+ accepts_nested_attributes_for :skip_conditions, allow_destroy: true, reject_if: :all_blank
41
45
 
42
46
  # validate :validate_conditions
43
47
  def validate_conditions
@@ -48,7 +52,7 @@ class WcoEmail::EmailFilter
48
52
 
49
53
  has_and_belongs_to_many :leadsets, class_name: '::Wco::Leadset'
50
54
 
51
-
55
+ ## @deprecated 2026-04-02
52
56
  KIND_AUTORESPOND_TMPL = 'autorespond-template'
53
57
  KIND_AUTORESPOND_EACT = 'autorespond-email-action'
54
58
  KIND_REMOVE_TAG = 'remove-tag'
@@ -61,8 +65,8 @@ class WcoEmail::EmailFilter
61
65
  KIND_DELETE = 'delete' ## @deprecated, use add-tag
62
66
  KIND_SKIP_INBOX = 'skip-inbox' ## @deprecated, use remove-tag
63
67
 
64
- KINDS = [ nil, KIND_OAT, KIND_AUTORESPOND_TMPL, KIND_AUTORESPOND_EACT, KIND_ADD_TAG, KIND_REMOVE_TAG, KIND_DESTROY_SCHS]
65
- field :kind
68
+ KINDS = [ nil, KIND_OAT, KIND_AUTORESPOND_TMPL, KIND_AUTORESPOND_EACT, KIND_ADD_TAG, KIND_REMOVE_TAG, KIND_DESTROY_SCHS ]
69
+ field :kind ## @deprecated, use filter.action.aject.kind 2026-04-02
66
70
 
67
71
 
68
72
  belongs_to :email_template, class_name: '::WcoEmail::EmailTemplate', optional: true
@@ -71,7 +75,7 @@ class WcoEmail::EmailFilter
71
75
  ## no habtm please
72
76
  # has_and_belongs_to_many :action_tmpls, class_name: '::Wco::OfficeActionTemplate'
73
77
  belongs_to :office_action_template, class_name: '::Wco::OfficeActionTemplate', optional: true
74
- belongs_to :tag, class_name: '::Wco::Tag', optional: true, inverse_of: :email_filters
78
+ belongs_to :tag, class_name: '::Wco::Tag', optional: true, inverse_of: :email_filters
75
79
 
76
80
  ## @TODO: change to has_and_belongs_to_many, test-driven.
77
81
  has_many :conversations, class_name: '::WcoEmail::Conversation', inverse_of: :filter
@@ -84,11 +88,11 @@ class WcoEmail::EmailFilter
84
88
  # inn = "#{inn}#{conditions.map { |c| c.to_s_full }.join }" if conditions.present?
85
89
  # inn = "#{inn}#{skip_conditions.map { |c| c.to_s_full }.join }" if skip_conditions.present?
86
90
  out =<<-AOL
87
- <EmailFilter #{from_regex} #{from_exact}>
91
+ <EmailFilter >
88
92
  #{conditions.map { |c| c.to_s_full( indent: 2) }.join }
89
93
  #{skip_conditions.map { |c| c.to_s_full( indent: 2) }.join }
90
94
  #{actions.map { |c| c.to_s_full( indent: 2) }.join }
91
- </EmailFilter>"
95
+ </EmailFilter>
92
96
  AOL
93
97
  while out.match(/\n\n/) do
94
98
  out = out.gsub(/\n\n/, "\n")
@@ -6,42 +6,43 @@ class WcoEmail::EmailFilterAction
6
6
 
7
7
  belongs_to :email_filter
8
8
 
9
- KIND_EXE = 'exe'
10
- KIND_REMOVE_TAG = ::WcoEmail::ACTION_REMOVE_TAG
11
- KIND_ADD_TAG = ::WcoEmail::ACTION_ADD_TAG
12
- KIND_AUTORESPOND = ::WcoEmail::ACTION_AUTORESPOND
13
- KIND_SCHEDULE_EMAIL_ACTION = 'autorespond-email-action'
14
- KIND_REMOVE_EMAIL_ACTION = 'remove-email-action'
9
+ KIND_AUTORESPOND = 'autorespond-template'
10
+ # KIND_EXE_RB = 'exe-rb'
11
+ KIND_ADD_TAG = 'add-tag'
12
+ KIND_RM_TAG = 'remove-tag'
13
+ KIND_EAT = 'autorespond-email-action'
14
+ KIND_RM_EAT = 'rm-email-action'
15
+ KIND_OAT = 'office-action-template'
16
+ KIND_RM_OAT = 'rm-office-action-template'
17
+ KINDS = [ KIND_ADD_TAG, KIND_RM_TAG, KIND_AUTORESPOND, KIND_OAT, KIND_EAT, KIND_RM_EAT ]
15
18
  field :kind
16
- validates :kind, inclusion: ::WcoEmail::ACTIONS
19
+ validates :kind, inclusion: KINDS
17
20
 
18
- field :value # the id of a tag, or email template, or email action
21
+ ## for exe_rb only. otherwise, use aject
22
+ field :value
19
23
 
24
+ belongs_to :aject, polymorphic: true # , optional: true # eg tag, EAT, OAT
25
+ # validates :aject_id, presence: true
20
26
 
21
- before_validation :check_value
22
- def check_value
23
- case kind
24
- when KIND_AUTORESPOND
25
- existing = WcoEmail::EmailTemplate.where({ id: value }).first
26
- if !existing
27
- errors.add( :base, 'missing EmailTemplate id when creating an EmailFilterAction' )
28
- throw :abort
29
- end
30
- end
31
- end
27
+ ## 2026-04-02 not anymore.
28
+ # before_validation :check_value
29
+ # def check_value
30
+ # case kind
31
+ # when KIND_AUTORESPOND
32
+ # existing = WcoEmail::EmailTemplate.where({ id: value }).first
33
+ # if !existing
34
+ # errors.add( :base, 'missing EmailTemplate id when creating an EmailFilterAction' )
35
+ # throw :abort
36
+ # end
37
+ # end
38
+ # end
32
39
 
33
40
 
34
41
  def to_s
35
- "<EFA #{kind} #{value} />\n"
42
+ "<EFAction #{kind} #{aject} />\n"
36
43
  end
37
44
  def to_s_full indent: 0
38
- _value = value
39
- if [ KIND_ADD_TAG, KIND_REMOVE_TAG ].include?( kind )
40
- _value = Wco::Tag.find( value )
41
- end
42
- if [ KIND_AUTORESPOND ].include?( kind )
43
- _value = WcoEmail::EmailTemplate.find( value )
44
- end
45
- "#{" " * indent }<EFAction #{kind} `#{_value}` />\n"
45
+ "#{" " * indent }<EFAction #{kind} `#{aject}` />\n"
46
46
  end
47
+
47
48
  end
@@ -8,18 +8,33 @@ class WcoEmail::EmailFilterCondition
8
8
  belongs_to :email_filter, class_name: '::WcoEmail::EmailFilter', inverse_of: :conditions, optional: true
9
9
  belongs_to :email_skip_filter, class_name: '::WcoEmail::EmailFilter', inverse_of: :skip_conditions, optional: true
10
10
 
11
- ## see WcoEmail::FIELD_*
11
+ FIELD_BODY = 'body'
12
+ FIELD_FROM = 'from'
13
+ FIELD_TAGGED = 'leadset-tagged'
14
+ FIELD_NOT_TAGGED = 'leadset-not-tagged'
15
+ FIELD_SUBJECT = 'subject'
16
+ # FIELD_TO = 'to'
17
+ FIELD_TO_OR_CC = 'to-or-cc'
18
+ FIELD_OPTS = [ FIELD_SUBJECT, FIELD_FROM, FIELD_TO_OR_CC, FIELD_TAGGED, FIELD_NOT_TAGGED, FIELD_BODY ]
12
19
  field :field
13
- validates :field, presence: true
20
+ validates :field, presence: true, inclusion: FIELD_OPTS
14
21
 
15
- field :matchtype, type: String
16
- validates :matchtype, presence: true, inclusion: WcoEmail::EmailFilter::MATCHTYPE_OPTS
17
- def operator; matchtype; end
18
- def operator= a; matchtype = a; end
22
+ OPERATOR_EQUALS = 'eq-i'
23
+ # OPERATOR_HAS_TAG = 'has-tag'
24
+ # OPERATOR_NOT_HAS_TAG = 'not-has-tag'
25
+ OPERATOR_REGEX = 'regex'
26
+ OPERATOR_MATCH = 'match-i'
27
+ OPERATOR__ID = '_id'
28
+ OPERATOR_SLUG = 'slug'
29
+ OPERATOR_OPTS = [ OPERATOR_REGEX, OPERATOR_MATCH, OPERATOR__ID, OPERATOR_SLUG ]
30
+ field :operator
31
+ validates :operator, presence: true, inclusion: OPERATOR_OPTS
19
32
 
20
33
  field :value
21
34
  validates :value, presence: true
22
35
 
36
+ index({ email_filter_id: 1, field: 1, operator: 1, value: 1 }, unique: true )
37
+
23
38
  def apply leadset:, message:
24
39
  cond = self
25
40
  reason = nil
@@ -43,14 +58,11 @@ class WcoEmail::EmailFilterCondition
43
58
 
44
59
 
45
60
  def to_s
46
- "<EFC #{field} #{matchtype} #{value} />"
61
+ "<EF#{email_skip_filter ? 'Skip' : ''}Condition #{field} #{operator} `#{value}` />"
47
62
  end
48
63
  def to_s_full indent: 0
49
- _value = value
50
- if [ ::WcoEmail::OPERATOR_HAS_TAG, ::WcoEmail::OPERATOR_NOT_HAS_TAG ].include?( matchtype )
51
- _value = Wco::Tag.find( value )
52
- end
53
- "#{" " * indent }<EF#{email_skip_filter ? 'Skip' : ''}Condition #{field} #{matchtype} `#{_value}` />\n"
64
+ "#{" " * indent }<EF#{email_skip_filter ? 'Skip' : ''}Condition #{field} #{operator} `#{value}` />\n"
54
65
  end
66
+
55
67
  end
56
68
 
@@ -11,7 +11,7 @@ class WcoEmail::EmailTemplate
11
11
  validates :slug, presence: true, uniqueness: true
12
12
  index({ slug: 1 }, { unique: true, name: "slug_idx" })
13
13
  def to_s
14
- "Tmpl:#{slug}"
14
+ "#{slug}"
15
15
  end
16
16
 
17
17
  field :preview_str, type: :string
@@ -127,6 +127,7 @@ class WcoEmail::EmailTemplate
127
127
  has_many :email_contexts, class_name: '::WcoEmail::Context'
128
128
  has_many :email_filters, class_name: '::WcoEmail::EmailFilter'
129
129
  has_many :unsubscribes, class_name: '::WcoEmail::Unsubscribe'
130
+ has_many :ajects, inverse_of: :aject ## email action object
130
131
 
131
132
  belongs_to :tag, class_name: '::Wco::Tag', inverse_of: :email_templates, optional: true
132
133
 
@@ -117,7 +117,7 @@ class WcoEmail::MessageStub
117
117
 
118
118
  @conv.update_attributes({
119
119
  status: WcoEmail::Conversation::STATUS_UNREAD,
120
- latest_at: json['date'].to_s || Time.now.to_datetime,
120
+ latest_at: json['date'].to_time.to_s || Time.now.to_datetime,
121
121
  from_emails: ( @conv.from_emails + [ from ]).uniq,
122
122
  preview: @message.preview_str,
123
123
  })
@@ -0,0 +1,8 @@
1
+
2
+ -#
3
+ -# much lighter than _index
4
+ -#
5
+ .leads
6
+ %ul
7
+ - leads.each do |ls|
8
+ %li= link_to ls, wco.lead_path(ls)
@@ -24,6 +24,10 @@
24
24
  %li
25
25
  Comment:
26
26
  %pre.descr #{raw @lead.comment}
27
+ %li
28
+ memory:
29
+ = @lead.memory
30
+
27
31
 
28
32
  .col-md-6
29
33
  - if @lead.photo
@@ -13,7 +13,7 @@
13
13
  %label action_type
14
14
  = f.select :action_type, options_for_select( [ nil, 'js', 'rb', 'sh' ], selected: oat.action_type )
15
15
  .descr
16
- rb available vars: @conversations , @oat ,
16
+ rb available vars: @conversations , @oat , @oa ,
17
17
  .field
18
18
  %label action_exe
19
19
  = f.text_area :action_exe, class: :monospace
@@ -3,20 +3,21 @@
3
3
  .header
4
4
  %h5.title Office Action Templates
5
5
 
6
- %ul
6
+ .a
7
7
  - @oats.each do |oat|
8
- %li
9
- .d-flex
10
- = link_to '[~]', edit_office_action_template_path(oat)
11
- &nbsp;
12
- = button_to 'x', office_action_template_path(oat), method: :delete, data: { confirm: 'Are you sure?' }
13
- &nbsp;
14
- = link_to oat.slug, office_action_template_path(oat)
15
- &nbsp;
16
- = button_to 'Run w/convos', oat_perform_with_conversations_path(oat), data: { confirm: 'Are you sure?' }
17
-
18
- = render '/wco/office_action_templates/ties', ties: oat.ties, oat: oat
19
- -# = oat.inspect
8
+ .Oat.descr
9
+ .row
10
+ .col-6
11
+ .d-flex
12
+ = link_to '[~]', edit_office_action_template_path(oat)
13
+ &nbsp;
14
+ = button_to 'x', office_action_template_path(oat), method: :delete, data: { confirm: 'Are you sure?' }
15
+ &nbsp;
16
+ = link_to oat.slug, office_action_template_path(oat)
17
+ &nbsp;
18
+ = button_to 'Run w/convos', oat_perform_with_conversations_path(oat), data: { confirm: 'Are you sure?' }
19
+ .col-6
20
+ = render '/wco/office_action_templates/ties', ties: oat.ties, oat: oat
20
21
 
21
22
  %hr
22
23
  = render 'form', oat: @new_oat
@@ -6,7 +6,7 @@
6
6
  %th N Conv
7
7
  %th N Stubs
8
8
 
9
- %th N Headlines
9
+ -# %th N Headlines
10
10
 
11
11
  %th N Galleries
12
12
  %th N Reports
@@ -24,7 +24,7 @@
24
24
  = link_to tag.slug, tag_path(tag)
25
25
  %td= tag.conversations.length
26
26
  %td= tag.message_stubs.length
27
- %td= tag.headlines.length
27
+ -# %td= tag.headlines.length
28
28
  %td= tag.galleries.length
29
29
  %td= tag.reports.length
30
30
  %td= tag.videos.length
@@ -0,0 +1,125 @@
1
+
2
+ ##
3
+ ## skip: careers@wasya.co
4
+ ## skip: mishellduvrazka2023|wasteplacellc|smttest42|robincroom|acelec|rleer24|statusunknown03|claricefth|abogadooctavioarango|claudenicefh|email4gregory|morishitaarata|314658|alisa406|dawnmeverly|faizana1298|jandrews555|midwestksp|mj8712|msohaibhere|piousbox|poxlovi|snehagophane99|stephenkim79
5
+ ##
6
+ ## exceptions: finradrnm@finra.org
7
+ ##
8
+
9
+ filter = nil
10
+ WcoEmail::EmailFilter.active.each do |_filter|
11
+ filter = _filter
12
+ case filter.kind
13
+ when WcoEmail::EmailFilter::KIND_ADD_TAG,
14
+ WcoEmail::EmailFilter::KIND_REMOVE_TAG,
15
+ WcoEmail::EmailFilter::KIND_AUTORESPOND_TMPL,
16
+ WcoEmail::EmailFilter::KIND_AUTORESPOND_EACT
17
+
18
+ aject_id = case filter.kind
19
+ when WcoEmail::EmailFilter::KIND_ADD_TAG,
20
+ WcoEmail::EmailFilter::KIND_REMOVE_TAG
21
+ filter.tag_id
22
+ when WcoEmail::EmailFilter::KIND_AUTORESPOND_TMPL
23
+ filter.email_template_id
24
+ when WcoEmail::EmailFilter::KIND_AUTORESPOND_EACT
25
+ filter.email_action_template_id
26
+ end
27
+ # puts! aject_id, 'aject_id'
28
+
29
+ aject_type = case filter.kind
30
+ when WcoEmail::EmailFilter::KIND_ADD_TAG,
31
+ WcoEmail::EmailFilter::KIND_REMOVE_TAG
32
+ 'Wco::Tag'
33
+ when WcoEmail::EmailFilter::KIND_AUTORESPOND_TMPL
34
+ 'WcoEmail::EmailTemplate'
35
+ when WcoEmail::EmailFilter::KIND_AUTORESPOND_EACT
36
+ 'WcoEmail::EmailActionTemplate'
37
+ end
38
+ # puts! aject_type, 'aject_type'
39
+
40
+ aject_kind = filter.kind
41
+ # aject_kind = case filter.kind
42
+ # when WcoEmail::EmailFilter::KIND_AUTORESPOND_EACT
43
+ # filter.kind
44
+ # else
45
+ # filter.kind
46
+ # end
47
+ # puts! aject_kind, 'aject_kind'
48
+
49
+
50
+ action_ids = WcoEmail::EmailFilterAction.where({
51
+ kind: filter.kind,
52
+ aject_id: aject_id,
53
+ }).distinct(:email_filter_id)
54
+ new_filter = WcoEmail::EmailFilter.where( :id.in => action_ids ).first
55
+
56
+ if new_filter
57
+ puts "+++ filter exists"
58
+ else
59
+ new_filter = WcoEmail::EmailFilter.new({
60
+ actions_attributes: [{
61
+ kind: aject_kind,
62
+ aject_type: aject_type,
63
+ aject_id: aject_id,
64
+ }] })
65
+
66
+ new_filter.save!
67
+ puts "+++ created new filter #{new_filter.id}"
68
+ end
69
+
70
+ cond_field = WcoEmail::EmailFilterCondition::FIELD_FROM
71
+ cond_op = WcoEmail::EmailFilterCondition::OPERATOR_MATCH
72
+ cond_value = filter.from_exact
73
+ if cond_value.blank?
74
+ cond_field = WcoEmail::EmailFilterCondition::FIELD_SUBJECT
75
+ cond_value = filter.subject_exact
76
+ end
77
+ if cond_value.blank?
78
+ cond_field = WcoEmail::EmailFilterCondition::FIELD_FROM
79
+ cond_op = WcoEmail::EmailFilterCondition::OPERATOR_REGEX
80
+ cond_value = filter.from_regex
81
+ end
82
+ if cond_value.blank?
83
+ cond_field = WcoEmail::EmailFilterCondition::FIELD_SUBJECT
84
+ cond_op = WcoEmail::EmailFilterCondition::OPERATOR_REGEX
85
+ cond_value = filter.subject_regex
86
+ end
87
+ if cond_value.blank?
88
+ cond_field = WcoEmail::EmailFilterCondition::FIELD_BODY
89
+ cond_op = WcoEmail::EmailFilterCondition::OPERATOR_MATCH
90
+ cond_value = filter.body_exact
91
+ end
92
+ if cond_value.blank?
93
+ throw '+++ cond_value cannot be blank'
94
+ end
95
+ # puts! cond_field, 'cond_field'
96
+ # puts! cond_value, 'cond_value'
97
+
98
+ new_condition = WcoEmail::EmailFilterCondition.where({
99
+ email_filter_id: new_filter.id,
100
+ field: cond_field,
101
+ operator: cond_op,
102
+ value: cond_value,
103
+ }).first
104
+ if new_condition
105
+ puts "+++ condition exists"
106
+ else
107
+ new_condition = WcoEmail::EmailFilterCondition.new({
108
+ email_filter_id: new_filter.id,
109
+ field: cond_field,
110
+ operator: cond_op,
111
+ value: cond_value,
112
+ })
113
+ new_condition.save!
114
+ puts "+++ created new condition #{new_condition.id}"
115
+ end
116
+
117
+ filter.conversations.update_all( filter_id: new_filter.id )
118
+ filter.update( status: 'inactive' )
119
+
120
+ end
121
+
122
+ end
123
+
124
+
125
+
@@ -7,7 +7,7 @@ namespace :wco do
7
7
 
8
8
  desc 'run office actions'
9
9
  task run_office_actions: :environment do
10
- puts! "Starting wco_email:run_office_actions..."
10
+ puts! "Starting wco_email:run_office_actions in #{Rails.env}..."
11
11
  while true do
12
12
 
13
13
  schs = Wco::OfficeAction.active.where({ :perform_at.lte => Time.now })
data/lib/wco_models.rb CHANGED
@@ -34,29 +34,7 @@ module Iro; end
34
34
  module Tda; end
35
35
  module Wco; end
36
36
 
37
- module WcoEmail
38
- ACTION_ADD_TAG = 'add-tag'
39
- ACTION_AUTORESPOND = 'autorespond-template'
40
- ACTION_EXE = 'exe'
41
- ACTION_SCHEDULE_EMAIL_ACTION = 'autorespond-email-action'
42
- ACTION_REMOVE_EMAIL_ACTION = 'remove-email-action'
43
- ACTION_REMOVE_TAG = 'remove-tag'
44
- ACTIONS = [ 'add-tag', 'autorespond-email-action', 'autorespond-template', 'exe', 'remove-email-action', 'remove-tag' ]
45
-
46
- FIELD_BODY = 'body'
47
- FIELD_EXE = 'exe'
48
- FIELD_FROM = 'from'
49
- FIELD_LEADSET = 'leadset_id'
50
- FIELD_SUBJECT = 'subject'
51
- FIELD_TO = 'to'
52
-
53
- OPERATOR_EQUALS = 'equals'
54
- OPERATOR_HAS_TAG = 'has-tag'
55
- OPERATOR_NOT_HAS_TAG = 'not-has-tag'
56
- OPERATOR_TEXT_INPUT = 'text-input'
57
- OPERATORS = [ 'equals', 'has-tag', 'not-has-tag', 'text-input' ]
58
- end
59
-
37
+ module WcoEmail; end
60
38
  module WcoHosting; end
61
39
 
62
40
  class Wco::HTTParty
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wco_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0.249
4
+ version: 3.1.0.250
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Pudeyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-01 00:00:00.000000000 Z
11
+ date: 2026-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ahoy_matey
@@ -591,6 +591,7 @@ files:
591
591
  - app/views/wco/leads/_header.haml
592
592
  - app/views/wco/leads/_index.haml
593
593
  - app/views/wco/leads/_index_chips.haml
594
+ - app/views/wco/leads/_list.haml
594
595
  - app/views/wco/leads/_table.haml
595
596
  - app/views/wco/leads/edit.haml
596
597
  - app/views/wco/leads/index.haml
@@ -767,6 +768,7 @@ files:
767
768
  - config/initializers/ahoy.rb
768
769
  - config/initializers/assets.rb
769
770
  - config/routes.rb
771
+ - lib/20260402_tmp.rb
770
772
  - lib/shortcuts.rb
771
773
  - lib/tasks/db_tasks.rake
772
774
  - lib/tasks/migrate_tasks.rake