wco_models 3.1.0.37 → 3.1.0.39

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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -13
  3. data/app/assets/config/wco_models_manifest.js +2 -0
  4. data/app/assets/javascripts/wco/application.js +43 -5
  5. data/app/assets/javascripts/wco/collapse-expand.js +1 -0
  6. data/app/assets/javascripts/wco/file_upload.js +32 -0
  7. data/app/assets/javascripts/wco/shared.js +22 -0
  8. data/app/assets/stylesheets/wco/application.css +23 -8
  9. data/app/assets/stylesheets/wco/utils.scss +57 -1
  10. data/app/controllers/wco/application_controller.rb +9 -0
  11. data/app/controllers/wco/galleries_controller.rb +143 -0
  12. data/app/controllers/wco/headlines_controller.rb +71 -0
  13. data/app/controllers/wco/leads_controller.rb +59 -0
  14. data/app/controllers/wco/leadsets_controller.rb +90 -0
  15. data/app/controllers/wco/logs_controller.rb +64 -0
  16. data/app/controllers/wco/office_action_templates_controller.rb +80 -0
  17. data/app/controllers/wco/office_actions_controller.rb +71 -0
  18. data/app/controllers/wco/photos_controller.rb +78 -0
  19. data/app/controllers/wco/profiles_controller.rb +26 -0
  20. data/app/controllers/wco/publishers_controller.rb +60 -0
  21. data/app/controllers/wco/reports_controller.rb +75 -0
  22. data/app/controllers/wco/sites_controller.rb +52 -0
  23. data/app/controllers/wco/tags_controller.rb +57 -0
  24. data/app/helpers/wco/application_helper.rb +42 -0
  25. data/app/models/wco/asset.rb +26 -0
  26. data/app/models/wco/gallery.rb +3 -3
  27. data/app/models/wco/headline.rb +19 -0
  28. data/app/models/wco/invoice.rb +127 -0
  29. data/app/models/wco/lead.rb +42 -0
  30. data/app/models/wco/leadset.rb +8 -2
  31. data/app/models/wco/log.rb +18 -0
  32. data/app/models/wco/newsitem.rb +1 -0
  33. data/app/models/wco/office_action.rb +17 -18
  34. data/app/models/wco/office_action_template.rb +41 -0
  35. data/app/models/wco/office_action_template_tie.rb +20 -0
  36. data/app/models/wco/photo.rb +10 -8
  37. data/app/models/wco/price.rb +2 -0
  38. data/app/models/wco/product.rb +2 -0
  39. data/app/models/wco/profile.rb +1 -0
  40. data/app/models/wco/publisher.rb +68 -3
  41. data/app/models/wco/report.rb +48 -0
  42. data/app/models/wco/site.rb +12 -1
  43. data/app/models/wco/subscription.rb +1 -0
  44. data/app/models/wco/tag.rb +17 -4
  45. data/app/models/wco_email/campaign.rb +7 -11
  46. data/app/models/wco_email/context.rb +15 -14
  47. data/app/models/wco_email/conversation.rb +13 -27
  48. data/app/models/wco_email/{scheduled_email_action.rb → email_action.rb} +24 -20
  49. data/app/models/wco_email/email_action_template.rb +35 -0
  50. data/app/models/wco_email/email_filter.rb +9 -12
  51. data/app/models/wco_email/email_template.rb +124 -0
  52. data/app/models/wco_email/message.rb +228 -0
  53. data/app/models/wco_email/message_stub.rb +107 -0
  54. data/app/models/wco_email/obfuscated_redirect.rb +13 -0
  55. data/app/models/wco_email/unsubscribe.rb +19 -0
  56. data/app/models/wco_hosting/appliance.rb +1 -0
  57. data/app/models/wco_hosting/appliance_tmpl.rb +1 -0
  58. data/app/models/wco_hosting/domain.rb +1 -0
  59. data/app/models/wco_hosting/serverhost.rb +1 -0
  60. data/app/views/layouts/wco/application.haml +30 -17
  61. data/app/views/wco/_main_footer.haml +43 -0
  62. data/app/views/wco/_main_header.haml +37 -0
  63. data/app/views/wco/_main_header.haml-bk +109 -0
  64. data/app/views/wco/_paginate.haml +8 -0
  65. data/app/views/wco/_search.haml +8 -0
  66. data/app/views/wco/application/_debug.haml +0 -0
  67. data/app/views/wco/galleries/_form.haml +24 -0
  68. data/app/views/wco/galleries/_header.haml +8 -0
  69. data/app/views/wco/galleries/_index.haml +40 -0
  70. data/app/views/wco/galleries/_menu.haml-trash +10 -0
  71. data/app/views/wco/galleries/_menu_secondary.haml +12 -0
  72. data/app/views/wco/galleries/_thumbs.haml +9 -0
  73. data/app/views/wco/galleries/_title.haml +16 -0
  74. data/app/views/wco/galleries/edit.haml +6 -0
  75. data/app/views/wco/galleries/new.haml +6 -0
  76. data/app/views/wco/galleries/show.haml +43 -0
  77. data/app/views/wco/headlines/_form.haml +17 -0
  78. data/app/views/wco/headlines/_header.haml +6 -0
  79. data/app/views/wco/headlines/_index.haml +20 -0
  80. data/app/views/wco/headlines/edit.haml +6 -0
  81. data/app/views/wco/headlines/new.haml +2 -0
  82. data/app/views/wco/invoices/_form.haml-trash +29 -0
  83. data/app/views/wco/invoices/_header.haml +6 -0
  84. data/app/views/wco/invoices/_index_list.haml +13 -0
  85. data/app/views/wco/invoices/_index_table.haml +20 -0
  86. data/app/views/wco/invoices/index.haml +3 -0
  87. data/app/views/wco/invoices/new_pdf.haml +18 -0
  88. data/app/views/wco/invoices/new_stripe.haml +50 -0
  89. data/app/views/wco/invoices/show.haml +23 -0
  90. data/app/views/wco/kaminari/_first_page.html.erb +11 -0
  91. data/app/views/wco/kaminari/_gap.html.erb +8 -0
  92. data/app/views/wco/kaminari/_last_page.html.erb +11 -0
  93. data/app/views/wco/kaminari/_next_page.html.erb +11 -0
  94. data/app/views/wco/kaminari/_page.html.erb +13 -0
  95. data/app/views/wco/kaminari/_paginator.html.erb +25 -0
  96. data/app/views/wco/kaminari/_prev_page.html.erb +11 -0
  97. data/app/views/wco/leads/_form.haml +45 -0
  98. data/app/views/wco/leads/_form_import.haml +11 -0
  99. data/app/views/wco/leads/_header.haml +7 -0
  100. data/app/views/wco/leads/_index.haml +75 -0
  101. data/app/views/wco/leads/_index_rows.haml +11 -0
  102. data/app/views/wco/leads/edit.haml +22 -0
  103. data/app/views/wco/leads/index.haml +7 -0
  104. data/app/views/wco/leads/new.haml +9 -0
  105. data/app/views/wco/leads/show.haml +85 -0
  106. data/app/views/wco/leadsets/_form.haml +28 -0
  107. data/app/views/wco/leadsets/_header.haml +6 -0
  108. data/app/views/wco/leadsets/edit.haml +4 -0
  109. data/app/views/wco/leadsets/index.haml +45 -0
  110. data/app/views/wco/leadsets/index_dataTables.haml +33 -0
  111. data/app/views/wco/leadsets/new.haml +6 -0
  112. data/app/views/wco/leadsets/show.haml +52 -0
  113. data/app/views/wco/logs/_form.haml +17 -0
  114. data/app/views/wco/logs/_header.haml +6 -0
  115. data/app/views/wco/logs/_index.haml +23 -0
  116. data/app/views/wco/logs/edit.haml +6 -0
  117. data/app/views/wco/logs/new.haml +2 -0
  118. data/app/views/wco/office_action_templates/_form.haml +46 -0
  119. data/app/views/wco/office_action_templates/_header.haml +8 -0
  120. data/app/views/wco/office_action_templates/_ties.haml +18 -0
  121. data/app/views/wco/office_action_templates/edit.haml +6 -0
  122. data/app/views/wco/office_action_templates/index.haml +17 -0
  123. data/app/views/wco/office_action_templates/new.haml +5 -0
  124. data/app/views/wco/office_action_templates/show.haml +22 -0
  125. data/app/views/wco/office_actions/_form.haml +22 -0
  126. data/app/views/wco/office_actions/_header.haml +6 -0
  127. data/app/views/wco/office_actions/_index.haml +15 -0
  128. data/app/views/wco/office_actions/edit.haml +5 -0
  129. data/app/views/wco/office_actions/index.haml +10 -0
  130. data/app/views/wco/office_actions/new.haml +4 -0
  131. data/app/views/wco/office_actions/show.haml +5 -0
  132. data/app/views/wco/photos/_form.haml +0 -0
  133. data/app/views/wco/photos/_index_thumbs.haml +7 -0
  134. data/app/views/wco/photos/_meta.haml +7 -0
  135. data/app/views/wco/photos/_meta_manager.haml +7 -0
  136. data/app/views/wco/photos/_multinew.haml +6 -0
  137. data/app/views/wco/photos/index.haml +3 -0
  138. data/app/views/wco/photos/new.haml +0 -0
  139. data/app/views/wco/photos/show.haml +6 -0
  140. data/app/views/wco/photos/without_gallery.haml +11 -0
  141. data/app/views/wco/prices/_form.haml +1 -1
  142. data/app/views/wco/products/_header.haml +6 -0
  143. data/app/views/wco/publishers/_form.haml +28 -0
  144. data/app/views/wco/publishers/_header.haml +6 -0
  145. data/app/views/wco/publishers/edit.haml +4 -0
  146. data/app/views/wco/publishers/index.haml +37 -0
  147. data/app/views/wco/publishers/new.haml +4 -0
  148. data/app/views/wco/reports/_form.haml +28 -0
  149. data/app/views/wco/reports/_header.haml +14 -0
  150. data/app/views/wco/reports/edit.haml +4 -0
  151. data/app/views/wco/reports/index.haml +17 -0
  152. data/app/views/wco/reports/index_table.haml +17 -0
  153. data/app/views/wco/reports/new.haml +4 -0
  154. data/app/views/wco/reports/show.haml +8 -0
  155. data/app/views/wco/sites/_form.haml +21 -0
  156. data/app/views/wco/sites/_header.haml +6 -0
  157. data/app/views/wco/sites/edit.haml +4 -0
  158. data/app/views/wco/sites/index.haml +24 -0
  159. data/app/views/wco/sites/new.haml +4 -0
  160. data/app/views/wco/tags/_form.haml +10 -0
  161. data/app/views/wco/tags/_header.haml +6 -0
  162. data/app/views/wco/tags/_index.haml +10 -0
  163. data/app/views/wco/tags/_index_inline.haml +8 -0
  164. data/app/views/wco/tags/edit.haml +0 -0
  165. data/app/views/wco/tags/index.haml +9 -0
  166. data/app/views/wco/tags/new.haml +0 -0
  167. data/app/views/wco/tags/show.haml +15 -0
  168. data/config/routes.rb +42 -0
  169. data/lib/tasks/db_tasks.rake +13 -0
  170. data/lib/tasks/office_tasks.rake +36 -0
  171. data/lib/tasks/scrape_tasks.rake-trash +22 -0
  172. data/lib/wco/ai_writer.rb +55 -0
  173. data/lib/wco/engine.rb +0 -1
  174. data/lib/wco/office_worker.rb +4 -0
  175. data/lib/wco/scrape_wsj.rb +29 -0
  176. data/lib/wco/scrape_wsj_capy.rb +44 -0
  177. data/lib/wco_models.rb +19 -2
  178. metadata +254 -45
  179. data/app/helpers/ish_models/application_helper.rb +0 -4
  180. data/app/models/wco_email/message_template.rb +0 -6
  181. data/lib/tasks/ish_models_tasks.rake +0 -4
  182. /data/app/views/wco/{application/_alerts_notices.haml → _alerts_notices.haml} +0 -0
@@ -0,0 +1,127 @@
1
+ require 'autoinc'
2
+ require 'prawn'
3
+ require 'prawn/table'
4
+
5
+ ##
6
+ ## Invoice - for wasya.co
7
+ ## 2017-10-31 _vp_ Start
8
+ ## 2023-08-18 _vp_ Continue
9
+ ##
10
+ class Wco::Invoice
11
+ include Mongoid::Document
12
+ include Mongoid::Timestamps
13
+ include Mongoid::Autoinc
14
+ include Mongoid::Paranoia
15
+ store_in collection: 'ish_invoice'
16
+
17
+ field :email, type: String
18
+
19
+ field :invoice_id, type: String # stripe
20
+
21
+ belongs_to :leadset, class_name: 'Wco::Leadset'
22
+
23
+ field :number, type: Integer
24
+
25
+ field :month_on, type: Date
26
+
27
+ has_one :asset, class_name: 'Wco::Asset' ## the pdf
28
+
29
+ def filename
30
+ "invoice-#{number}.pdf"
31
+ end
32
+
33
+ # field :amount_cents, type: Integer
34
+
35
+ field :description, type: String
36
+ field :items, type: Array # used by stripe
37
+
38
+
39
+
40
+ ## Prawn/pdf unit of measure is 1/72"
41
+ ## Canvas width: 612, height: 792
42
+ ##
43
+ ## tree image: 896 x 1159
44
+ ## tree image: 791 x 1024
45
+ ## tree image: 964 x 1248
46
+ ##
47
+ def generate_monthly_invoice
48
+ tree_img_url = "#{Rails.root.join('public')}/tree-#{number}.jpg"
49
+ wasya_co_logo_url = "#{Rails.root.join('public')}/259x66-WasyaCo-logo.png"
50
+
51
+ ## canvas width: 612, height: 792
52
+ pdf = Prawn::Document.new
53
+
54
+ pdf.canvas do
55
+ pdf.image tree_img_url, at: [ 0, 792 ], width: 612
56
+
57
+ pdf.fill_color 'ffffff'
58
+ pdf.transparent( 0.75 ) do
59
+ pdf.fill_rectangle [0, 792], 612, 792
60
+ end
61
+ pdf.fill_color '000000'
62
+
63
+ pdf.image wasya_co_logo_url, at: [252, 720], width: 108 ## 1.5"
64
+
65
+ pdf.bounding_box( [0.75*72, 9.25*72], width: 3.25*72, height: 0.75*72 ) do
66
+ pdf.text "From:"
67
+ pdf.text "Wasya Co"
68
+ pdf.text "victor@wasya.co"
69
+ end
70
+
71
+ pdf.bounding_box( [4.5*72, 9.25*72], width: 3.25*72, height: 0.75*72 ) do
72
+ pdf.text "Stats:"
73
+ pdf.text "Date: #{ Time.now.to_date.to_s }"
74
+ pdf.text "Invoice #: #{ number }"
75
+ end
76
+
77
+ pdf.bounding_box( [0.75*72, 8.25*72], width: 3.25*72, height: 0.75*72 ) do
78
+ pdf.text "To:"
79
+ pdf.text leadset.name
80
+ pdf.text leadset.email
81
+ end
82
+
83
+ pdf.bounding_box( [4.5*72, 8.25*72], width: 3.25*72, height: 0.75*72 ) do
84
+ pdf.text "Notes:"
85
+ pdf.text "Support & various tasks, for the month of #{ month_on.strftime('%B') }."
86
+ end
87
+
88
+ lineitems_with_header = [
89
+ [ 'Description', 'Per Unit', '# of Units', 'Subtotal' ]
90
+ ]
91
+ total = 0
92
+ leadset.subscriptions.each do |i|
93
+ subtotal = (i.price.amount_cents * i.quantity).to_f/100
94
+ lineitems_with_header.push([ i.price.product.name, i.price.name_simple, i.quantity, subtotal ])
95
+ total += subtotal
96
+ end
97
+
98
+
99
+ pdf.move_down 20
100
+ pdf.table(lineitems_with_header, {
101
+ position: :center,
102
+ width: 7.5*72,
103
+ cell_style: {
104
+ inline_format: true,
105
+ borders: [ :bottom ]
106
+ },
107
+ } )
108
+
109
+ pdf.table([
110
+ [ 'Total' ],
111
+ [ total ],
112
+ ], {
113
+ position: 7*72,
114
+ width: 1*72,
115
+ cell_style: {
116
+ inline_format: true,
117
+ borders: [ :bottom ]
118
+ },
119
+ } )
120
+
121
+ pdf.text_box "Thank you!", at: [ 3.25*72, 1.25*72 ], width: 2*72, height: 1*72, align: :center
122
+ end
123
+
124
+ return pdf
125
+ end
126
+
127
+ end
@@ -2,6 +2,48 @@
2
2
  class Wco::Lead
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'wco_leads'
6
7
 
8
+ field :email
9
+ validates :email, presence: true, uniqueness: true
10
+ index({ email: -1 })
11
+
12
+ field :name
13
+ field :phone
14
+ field :address
15
+
16
+ belongs_to :leadset, class_name: 'Wco::Leadset'
17
+ has_one :photo, class_name: 'Wco::Photo'
18
+
19
+ has_and_belongs_to_many :conversations, class_name: '::WcoEmail::Conversation'
20
+ def convs; conversations; end
21
+ has_many :email_contexts, class_name: '::WcoEmail::Context'
22
+ def ctxs; email_contexts; end
23
+ has_many :email_actions, class_name: '::WcoEmail::EmailAction'
24
+ # has_and_belongs_to_many :scheduled_email_actions, class_name: '::WcoEmail::ScheduledEmailAction'
25
+ def schs; email_actions; end
26
+ has_and_belongs_to_many :email_campaigns, class_name: '::WcoEmail::Campaign'
27
+ has_and_belongs_to_many :tags, class_name: '::Wco::Tag'
28
+
29
+ # has_many :galleries, class_name: 'Wco::Gallery'
30
+ # has_many :videos, class_name: 'Wco::Video'
31
+
32
+ def self.list
33
+ all.map { |p| [ p.id, p.email ] }
34
+ end
35
+
36
+ OP_DELETE = 'delete'
37
+ OP_ADD_TO_CAMPAIGN = 'add_to_campaign'
38
+ OPS = [ OP_DELETE, OP_ADD_TO_CAMPAIGN ]
39
+
40
+ has_many :unsubscribes, class_name: '::WcoEmail::Unsubscribe'
41
+ field :unsubscribe_token
42
+ def unsubscribe_token
43
+ if !self[:unsubscribe_token]
44
+ update_attributes({ unsubscribe_token: (0...8).map { (65 + rand(26)).chr }.join })
45
+ end
46
+ self[:unsubscribe_token]
47
+ end
48
+
7
49
  end
@@ -2,19 +2,25 @@
2
2
  class Wco::Leadset
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'wco_leadsets'
6
7
 
7
- field :company_url
8
+ field :company_url
8
9
  validates :company_url, presence: true, uniqueness: true
9
10
  index({ company_url: 1 }, { name: 'company_url' })
10
11
 
11
12
  field :email
12
13
  index({ email: 1 }, { name: 'email' })
13
- validates :email, presence: true # , uniqueness: true ## @TODO: should it be unique? _vp_ 2023-12-22
14
+ validates :email, uniqueness: { allow_nil: true } # presence: true
14
15
 
16
+ has_many :leads, class_name: 'Wco::Lead'
15
17
  has_many :profiles, class_name: 'Wco::Profile', inverse_of: :leadset
16
18
  has_many :appliances, class_name: 'WcoHosting::Appliance', inverse_of: :leadset
17
19
  has_many :subscriptions, class_name: 'Wco::Subscription', inverse_of: :leadset
20
+ has_and_belongs_to_many :tags, class_name: 'Wco::Tag'
21
+
22
+ has_many :invoices, class_name: 'Wco::Invoice'
23
+ field :next_invoice_number, type: :integer, default: 100
18
24
 
19
25
  has_and_belongs_to_many :serverhosts, class_name: 'WcoHosting::Serverhost' # , inverse_of: :leadset
20
26
  def next_serverhost
@@ -0,0 +1,18 @@
1
+
2
+
3
+ class Wco::Log
4
+ include Mongoid::Document
5
+ include Mongoid::Timestamps
6
+ include Mongoid::Paranoia
7
+ store_in collection: 'wco_logs'
8
+
9
+ field :message
10
+
11
+ field :class_name
12
+ field :object_id
13
+
14
+ field :raw_json, type: Object, default: '{}'
15
+
16
+ has_and_belongs_to_many :tags
17
+
18
+ end
@@ -3,6 +3,7 @@
3
3
  class Wco::Newsitem
4
4
  include Mongoid::Document
5
5
  include Mongoid::Timestamps
6
+ include Mongoid::Paranoia
6
7
  store_in collection: 'wco_newsitems'
7
8
 
8
9
  belongs_to :profile, class_name: 'Wco::Profile', optional: true
@@ -1,32 +1,31 @@
1
1
 
2
- ##
3
- ## 2023-09-13 _vp_ I don't know if it's even used.
4
- ##
5
2
  class Wco::OfficeAction
6
3
  include Mongoid::Document
7
4
  include Mongoid::Timestamps
8
- store_in collection: 'office_actions'
5
+ include Mongoid::Paranoia
6
+ store_in collection: 'wco_office_actions'
9
7
 
10
8
  field :slug, type: :string
11
9
  validates :slug, uniqueness: true, allow_nil: true
12
10
 
13
- field :descr, type: :string ## optional
11
+ # field :descr, type: :string ## optional
14
12
 
13
+ belongs_to :office_action_template, inverse_of: :office_action
14
+ def tmpl
15
+ office_action_template
16
+ end
15
17
 
16
- STATE_ACTIVE = 'active'
17
- STATE_INACTIVE = 'inactive'
18
- STATES = [ STATE_ACTIVE, STATE_INACTIVE ]
19
- field :state, type: :string
20
- scope :active, ->{ where( state: STATE_ACTIVE ) }
21
-
22
-
23
- has_many :ties, class_name: '::Office::ActionTie', inverse_of: :office_action
24
- has_many :prev_ties, class_name: '::Office::ActionTie', inverse_of: :next_office_action
25
- accepts_nested_attributes_for :ties
26
-
27
- field :action_exe, type: :string
18
+ STATUS_ACTIVE = 'active'
19
+ STATUS_INACTIVE = 'inactive'
20
+ STATUSS = [ STATUS_ACTIVE, STATUS_INACTIVE ]
21
+ field :status, type: :string
22
+ scope :active, ->{ where( status: STATUS_ACTIVE ) }
28
23
 
29
24
  field :perform_at, type: :time
30
25
 
26
+ def to_s
27
+ slug
28
+ end
29
+
31
30
  end
32
- OAct = Wco::OfficeAction
31
+
@@ -0,0 +1,41 @@
1
+
2
+ require 'wco/ai_writer'
3
+
4
+ ##
5
+ ## A Publisher is an OAT
6
+ ##
7
+ class Wco::OfficeActionTemplate
8
+ include Mongoid::Document
9
+ include Mongoid::Timestamps
10
+ include Mongoid::Paranoia
11
+ store_in collection: 'wco_office_action_templates'
12
+
13
+ field :slug
14
+ validates :slug, presence: true, uniqueness: true
15
+
16
+ belongs_to :from, polymorphic: true, optional: true
17
+ belongs_to :publisher, class_name: 'Wco::Publisher', optional: true
18
+
19
+ field :action_exe, type: :string
20
+ validates :action_exe, presence: true
21
+ def do_run
22
+ eval( action_exe )
23
+ end
24
+
25
+ has_many :office_actions, inverse_of: :office_action_template
26
+ def actions; office_actions; end
27
+
28
+ has_many :ties, class_name: 'OfficeActionTemplateTie', inverse_of: :office_action_template
29
+ has_many :prev_ties, class_name: 'OfficeActionTemplateTie', inverse_of: :next_office_action_template
30
+ accepts_nested_attributes_for :ties
31
+
32
+ def to_s
33
+ "#{slug}"
34
+ end
35
+
36
+ def self.list
37
+ [[nil,nil]] + all.map { |ttt| [ ttt.slug, ttt.id ] }
38
+ end
39
+
40
+ end
41
+ OAT = Wco::OfficeActionTemplate
@@ -0,0 +1,20 @@
1
+
2
+ class Wco::OfficeActionTemplateTie
3
+ include Mongoid::Document
4
+ include Mongoid::Timestamps
5
+ store_in collection: 'wco_office_action_template_ties'
6
+
7
+ attr_accessor :to_delete
8
+
9
+ belongs_to :office_action_template, class_name: 'OfficeActionTemplate', inverse_of: :ties
10
+ def oat; office_action_template; end
11
+
12
+ belongs_to :next_office_action_template, class_name: 'OfficeActionTemplate', inverse_of: :prev_ties
13
+ def next_oat; next_office_action_template; end
14
+ # def tmpl; next_office_action_template; end
15
+
16
+
17
+ field :next_at_exe, type: :string
18
+ validates :next_at_exe, presence: true
19
+
20
+ end
@@ -6,19 +6,21 @@ class Wco::Photo
6
6
  include Mongoid::Document
7
7
  include Mongoid::Timestamps
8
8
  include Mongoid::Paperclip
9
+ include Mongoid::Paranoia
9
10
  include Wco::Utils
11
+ store_in collection: 'wco_photos'
10
12
 
11
- # belongs_to :email_message, :optional => true, :class_name => 'Office::EmailMessage'
12
- # belongs_to :report, :optional => true
13
- belongs_to :gallery, class_name: 'Wco::Gallery', :optional => true
13
+ belongs_to :email_message, class_name: 'WcoEmail::Message', optional: true
14
+ belongs_to :gallery, class_name: 'Wco::Gallery', optional: true
15
+ belongs_to :lead, class_name: 'Wco::Lead', optional: true
14
16
  # belongs_to :newsitem, :optional => true
15
17
 
16
- # photo.photo.to_s.split('/').last.split('?').first
17
- field :name, :type => String
18
+ field :name
18
19
  def name
19
- return self[:name] if self[:name]
20
- update_attribute(:name, self.photo.to_s.split('/').last.split('?').first)
21
- name
20
+ if !self[:name]
21
+ update_attribute(:name, self.photo.to_s.split('/').last.split('?').first)
22
+ end
23
+ self[:name]
22
24
  end
23
25
 
24
26
  field :ordering, type: :integer
@@ -2,6 +2,8 @@
2
2
  class Wco::Price
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
6
+ store_in collection: 'wco_prices'
5
7
 
6
8
  # belongs_to :product, class_name: 'Wco::Product', inverse_of: :prices
7
9
  ## Wco::Product, WcoHosting::ApplianceTmpl:
@@ -2,6 +2,8 @@
2
2
  class Wco::Product
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
6
+ store_in collection: 'wco_products'
5
7
 
6
8
  field :name
7
9
 
@@ -2,6 +2,7 @@
2
2
  class Wco::Profile
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'ish_user_profiles'
6
7
 
7
8
  field :email
@@ -2,21 +2,86 @@
2
2
  class Wco::Publisher
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'wco_publishers'
6
7
 
7
- field :name
8
+ field :slug
9
+ validates :slug, presence: true, uniqueness: true
8
10
 
9
11
  KIND_ARTICLE = 'article'
10
12
  KIND_IMAGE = 'image'
11
13
  field :kind, type: :string
12
14
 
13
- belongs_to :to_site, class_name: 'Wco::Site'
14
-
15
+ belongs_to :site, class_name: 'Wco::Site'
15
16
 
16
17
  field :context_eval
18
+ field :after_eval
17
19
  field :post_body_tmpl
18
20
 
21
+ has_many :oats, class_name: 'Wco::OfficeActionTemplate'
22
+
23
+ ## @TODO: move to PublisherDrupal
24
+ def do_run
25
+ @report = report
26
+
27
+ @ctx = OpenStruct.new
28
+ eval( context_eval )
29
+ puts! @ctx, '@ctx'
30
+
31
+ tmpl = ERB.new post_body_tmpl
32
+ body = JSON.parse tmpl.result(binding)
33
+ puts! body, 'body'
34
+
35
+ headers = {}
36
+ if Wco::Site::KIND_DRUPAL == site.kind
37
+ headers['Content-Type'] = 'application/hal+json'
38
+ end
39
+
40
+ out = Wco::HTTParty.post( "#{site.origin}#{site.post_path}", {
41
+ body: body.to_json,
42
+ headers: headers,
43
+ basic_auth: { username: site.username, password: site.password },
44
+ })
45
+ puts! out.response, 'out'
46
+
47
+ eval( after_eval )
48
+ end
49
+
50
+ def publish_report report
51
+ @report = report
52
+ @site = site
53
+
54
+ @ctx = OpenStruct.new
55
+ eval( context_eval )
56
+ puts! @ctx, '@ctx'
57
+
58
+
59
+ tmpl = ERB.new post_body_tmpl
60
+ body = JSON.parse tmpl.result(binding)
61
+ puts! body, 'body'
62
+
63
+ headers = {}
64
+ if Wco::Site::KIND_DRUPAL == site.kind
65
+ headers['Content-Type'] = 'application/hal+json'
66
+ end
67
+
68
+ out = Wco::HTTParty.post( "#{site.origin}#{site.post_path}", {
69
+ body: body.to_json,
70
+ headers: headers,
71
+ basic_auth: { username: site.username, password: site.password },
72
+ })
73
+ puts! out.response, 'out'
74
+
75
+ eval( after_eval )
76
+ end
77
+
78
+ def to_s
79
+ "#{slug}: #{kind} => #{site}"
80
+ end
19
81
 
82
+ def self.list
83
+ [[nil,nil]] + all.map { |p| [p, p.id] }
84
+ end
20
85
 
21
86
  end
22
87
 
@@ -0,0 +1,48 @@
1
+
2
+ ##
3
+ ##
4
+ ##
5
+ # @report.body.split("\n\n").map { |ttt| "<p>#{ttt}</p>" }.join
6
+ #
7
+ class Wco::Report
8
+ include Mongoid::Document
9
+ include Mongoid::Timestamps
10
+ include Mongoid::Paranoia
11
+ include Wco::Utils
12
+ store_in collection: 'wco_reports'
13
+
14
+ field :title
15
+ validates :title, presence: true, uniqueness: true
16
+ index({ title: 1 }, { unique: true })
17
+
18
+ field :subtitle
19
+
20
+ field :slug
21
+ validates :slug, presence: true, uniqueness: true
22
+ index({ :slug => 1 }, { :unique => true })
23
+ before_validation :set_slug, :on => :create
24
+
25
+ field :body
26
+
27
+ # field :raw_json, type: :object, default: '{}'
28
+
29
+ # field :is_trash, :type => Boolean, :default => false
30
+ # index({ :is_trash => 1, :is_public => 1 })
31
+
32
+ # field :is_public, :type => Boolean, :default => true
33
+ # index({ :is_public => 1 })
34
+ # scope :public, ->{ where({ is_public: true }) }
35
+
36
+ field :x, :type => Float
37
+ field :y, :type => Float
38
+ field :z, :type => Float
39
+
40
+ # has_one :photo
41
+
42
+ def export_fields
43
+ %w| name descr |
44
+ end
45
+
46
+ has_and_belongs_to_many :tags
47
+
48
+ end
@@ -2,6 +2,7 @@
2
2
  class Wco::Site
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'wco_sites'
6
7
 
7
8
  KIND_DRUPAL = 'drupal'
@@ -13,13 +14,23 @@ class Wco::Site
13
14
  [nil] + KINDS
14
15
  end
15
16
 
16
- has_many :publishers, class_name: 'Wco::Publisher'
17
+ has_many :publishers # , class_name: 'Wco::Publisher'
18
+ has_many :headlines # , class_name: 'Wco::Newstitle'
19
+
20
+ field :slug
21
+ validates :slug, presence: true, uniqueness: true
17
22
 
18
23
  field :origin # http://pi.local
24
+ validates :origin, presence: true, uniqueness: true
25
+
19
26
  field :post_path # /node?_format=hal_json
20
27
  field :username
21
28
  field :password
22
29
 
30
+ def to_s
31
+ origin
32
+ end
33
+
23
34
  def self.list
24
35
  [[nil,nil]] + all.map { |s| [ s.origin, s.id ] }
25
36
  end
@@ -2,6 +2,7 @@
2
2
  class Wco::Subscription
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'wco_subscriptions'
6
7
 
7
8
  belongs_to :product, polymorphic: true # includes: Wco::Product , WcoHosting::ApplianceTmpl
@@ -2,15 +2,28 @@
2
2
  class Wco::Tag
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
+ include Mongoid::Paranoia
5
6
  store_in collection: 'wco_tags'
6
7
 
7
8
  field :slug
8
- # index
9
- # validate presence
10
- # validate uniqueness ?
9
+ validates :slug, presence: true, uniqueness: true
10
+ index({ slug: -1 })
11
11
 
12
12
  # parent-child
13
13
 
14
- has_and_belongs_to_many :email_conversations, class_name: 'WcoEmail::Conversation'
14
+ has_and_belongs_to_many :conversations, class_name: 'WcoEmail::Conversation'
15
+ has_and_belongs_to_many :message_stubs, class_name: 'WcoEmail::MessageStub'
16
+ has_and_belongs_to_many :headlines # , class_name: 'Headline'
17
+ has_and_belongs_to_many :leads # , class_name: 'Lead'
18
+ has_and_belongs_to_many :leadsets # , class_name: 'Leadset'
19
+ has_and_belongs_to_many :reports
20
+ has_and_belongs_to_many :logs
21
+
22
+ INBOX = 'inbox'
23
+ TRASH = 'trash'
24
+
25
+ def self.list
26
+ [[nil,nil]] + all.map { |p| [ p.slug, p.id ] }
27
+ end
15
28
 
16
29
  end
@@ -6,6 +6,7 @@
6
6
  class WcoEmail::Campaign
7
7
  include Mongoid::Document
8
8
  include Mongoid::Timestamps
9
+ include Mongoid::Paranoia
9
10
  store_in collection: 'ish_email_campaigns'
10
11
 
11
12
  field :slug
@@ -25,19 +26,10 @@ class WcoEmail::Campaign
25
26
  field :sent_at, type: DateTime
26
27
  field :send_at, type: DateTime
27
28
 
28
- has_many :unsubscribes, class_name: '::Ish::EmailUnsubscribe', inverse_of: :campaign
29
+ has_many :unsubscribes, class_name: 'WcoEmail::Unsubscribe', inverse_of: :campaign
30
+ has_and_belongs_to_many :leads, class_name: 'Wco::Lead'
29
31
 
30
- def campaign_leads
31
- return ::EmailCampaignLead.where( email_campaign_id: self.id.to_s ).includes( :lead )
32
- end
33
-
34
- def leads
35
- ::Lead.joins( :email_campaign_leads ).where( 'email_campaign_leads.email_campaign_id' => self.id.to_s )
36
- end
37
-
38
- ##
39
32
  ## For tracking
40
- ##
41
33
  attr_reader :tid
42
34
 
43
35
  def do_send
@@ -52,4 +44,8 @@ class WcoEmail::Campaign
52
44
  end
53
45
  end
54
46
 
47
+ def self.list
48
+ [[nil,nil]] + all.map { |p| [ p.slug, p.id ] }
49
+ end
50
+
55
51
  end