gestion 1.9.12

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 (233) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +48 -0
  3. data/.project +14 -0
  4. data/Binaries/adduser_to_buzz +15 -0
  5. data/Binaries/backup +7 -0
  6. data/Binaries/check_gestion +8 -0
  7. data/Binaries/gestion.gnumail +22 -0
  8. data/Binaries/gestion.logrotate +34 -0
  9. data/Binaries/gestion.service +12 -0
  10. data/Binaries/gestion_update.rb +183 -0
  11. data/Binaries/gestion_update.service +10 -0
  12. data/Binaries/get_compta +11 -0
  13. data/Binaries/kill_gestion +16 -0
  14. data/Binaries/ldap/add_indexes +51 -0
  15. data/Binaries/ldap/backup +2 -0
  16. data/Binaries/ldap/install_ldap +92 -0
  17. data/Binaries/ldap/restore +7 -0
  18. data/Binaries/lib_backup +5 -0
  19. data/Binaries/log_scan_errors +8 -0
  20. data/Binaries/loop_gestion +64 -0
  21. data/Binaries/onetimers/sync_courses_from_compta.rb +74 -0
  22. data/Binaries/onetimers/transfer_cash_from_ldap_to_csv +26 -0
  23. data/Binaries/reboot +5 -0
  24. data/Binaries/restore +3 -0
  25. data/Binaries/restore_do +22 -0
  26. data/Binaries/sort_events +31 -0
  27. data/Binaries/start_gestion +18 -0
  28. data/Binaries/swipe_gestion +18 -0
  29. data/Binaries/update_africompta +21 -0
  30. data/Binaries/update_users +3 -0
  31. data/Diplomas.src/accredited.odg +0 -0
  32. data/Diplomas.src/diploma.odg +0 -0
  33. data/Diplomas.src/label.odg +0 -0
  34. data/Diplomas.src/presence_sheet.ods +0 -0
  35. data/Diplomas.src/presence_sheet_small.ods +0 -0
  36. data/Diplomas.src/student_card.odg +0 -0
  37. data/Doc/130514-it-ideas.odt +0 -0
  38. data/Doc/Compta-cash.mm +179 -0
  39. data/Doc/General.odt +0 -0
  40. data/Entities/AccessGroups.rb +117 -0
  41. data/Entities/Activity.rb +178 -0
  42. data/Entities/ChatMsg.rb +142 -0
  43. data/Entities/Classroom.rb +11 -0
  44. data/Entities/Client.rb +19 -0
  45. data/Entities/Computer.rb +21 -0
  46. data/Entities/ConfigBase.rb +280 -0
  47. data/Entities/Course.rb +1588 -0
  48. data/Entities/CourseType.rb +171 -0
  49. data/Entities/DFiles.rb +466 -0
  50. data/Entities/FilesManage.rb +226 -0
  51. data/Entities/Grade.rb +186 -0
  52. data/Entities/Internet.rb +300 -0
  53. data/Entities/Netdev.rb +10 -0
  54. data/Entities/Person.rb +1175 -0
  55. data/Entities/Plug.rb +98 -0
  56. data/Entities/Quiz.rb +33 -0
  57. data/Entities/Recharges.rb +37 -0
  58. data/Entities/Report.rb +136 -0
  59. data/Entities/Room.rb +12 -0
  60. data/Entities/SMS.rb +30 -0
  61. data/Entities/ScheduleType.rb +33 -0
  62. data/Entities/Share.rb +120 -0
  63. data/Entities/Task.rb +51 -0
  64. data/Entities/Ticket.rb +72 -0
  65. data/Entities/Usage.rb +143 -0
  66. data/Entities/Worker.rb +29 -0
  67. data/Files/apache-profeda.conf +36 -0
  68. data/Files/label.erb +121 -0
  69. data/Files/label_notfound.erb +64 -0
  70. data/Files/label_notpassed.erb +84 -0
  71. data/Files/mobileinfo.erb +115 -0
  72. data/Files/smb.conf +333 -0
  73. data/Files/timetable.html +36 -0
  74. data/Files/timetable.js +239 -0
  75. data/Gemfile +12 -0
  76. data/Gemfile.dev +12 -0
  77. data/Gemfile.dev.lock +127 -0
  78. data/Gemfile.lock +127 -0
  79. data/Gemfile.prod +8 -0
  80. data/Gestion +35 -0
  81. data/Gestion.rb +220 -0
  82. data/INSTALL +40 -0
  83. data/Images/connection.xcf +0 -0
  84. data/Images/connection_no.png +0 -0
  85. data/Images/connection_wait.png +0 -0
  86. data/Images/connection_yes.png +0 -0
  87. data/Paths/Exas.rb +13 -0
  88. data/Paths/Files.rb +19 -0
  89. data/Paths/GetDiplomas.rb +20 -0
  90. data/Paths/Info.rb +114 -0
  91. data/Paths/Label.rb +187 -0
  92. data/Paths/MobileInfo.rb +19 -0
  93. data/Paths/internetCash.rb +34 -0
  94. data/Paths/internetWifi.rb +54 -0
  95. data/README.md +60 -0
  96. data/Rakefile +13 -0
  97. data/TODO +1391 -0
  98. data/Test/.gitignore +3 -0
  99. data/Test/Diplomas/base_gestion.odt +0 -0
  100. data/Test/Diplomas/base_report.odt +0 -0
  101. data/Test/Diplomas/carte_etudiant.odg +0 -0
  102. data/Test/Diplomas/exam_language.odt +0 -0
  103. data/Test/Diplomas/label.odg +0 -0
  104. data/Test/Diplomas/presence_sheet.ods +0 -0
  105. data/Test/Diplomas/presence_sheet_small.ods +0 -0
  106. data/Test/Diplomas/student_card.odg +0 -0
  107. data/Test/Manual/testMerge +18 -0
  108. data/Test/config_test.yaml +26 -0
  109. data/Test/db.testGestion +0 -0
  110. data/Test/dfiles/descs/avg-rescue.desc +10 -0
  111. data/Test/dfiles/descs/avg.desc +8 -0
  112. data/Test/dfiles/descs/driver.desc +8 -0
  113. data/Test/dfiles/descs/linuxmint.desc +7 -0
  114. data/Test/dfiles/files/avg-160203.exe +1 -0
  115. data/Test/dfiles/files/avg.iso +1 -0
  116. data/Test/dfiles/files/driver.exe +1 -0
  117. data/Test/dfiles/index_post.html +3 -0
  118. data/Test/dfiles/index_pre.html +8 -0
  119. data/Test/dfiles/priorities +5 -0
  120. data/Test/ge_activity.rb +124 -0
  121. data/Test/ge_chat.rb +106 -0
  122. data/Test/ge_compta.rb +67 -0
  123. data/Test/ge_configbase.rb +54 -0
  124. data/Test/ge_course.rb +1114 -0
  125. data/Test/ge_dfiles.rb +121 -0
  126. data/Test/ge_filesmanage.rb +180 -0
  127. data/Test/ge_info.rb +27 -0
  128. data/Test/ge_internet.rb +246 -0
  129. data/Test/ge_login.rb +55 -0
  130. data/Test/ge_person.rb +373 -0
  131. data/Test/ge_qvinfo.rb +28 -0
  132. data/Test/ge_report.rb +97 -0
  133. data/Test/ge_share.rb +27 -0
  134. data/Test/ge_sms.rb +34 -0
  135. data/Test/ge_tasks.rb +19 -0
  136. data/Test/ge_usage.rb +168 -0
  137. data/Test/ge_view.rb +46 -0
  138. data/Test/multiconf-captive +29 -0
  139. data/Test/test.conf +7 -0
  140. data/Test/test.rb +49 -0
  141. data/Test/test_bytes.png +0 -0
  142. data/VERSION +140 -0
  143. data/Views/Admin/Backup.rb +91 -0
  144. data/Views/Admin/Configuration.rb +44 -0
  145. data/Views/Admin/Credit.rb +32 -0
  146. data/Views/Admin/FilesManage.rb +219 -0
  147. data/Views/Admin/Function.rb +39 -0
  148. data/Views/Admin/Power.rb +49 -0
  149. data/Views/Admin/Printer.rb +37 -0
  150. data/Views/Admin/Server.rb +252 -0
  151. data/Views/Admin/Tabs.rb +5 -0
  152. data/Views/Admin/Update.rb +73 -0
  153. data/Views/Admin/UpdateSystem.rb +26 -0
  154. data/Views/Cashbox/Activity.rb +191 -0
  155. data/Views/Cashbox/Course.rb +141 -0
  156. data/Views/Cashbox/Credit.rb +79 -0
  157. data/Views/Cashbox/Report.rb +115 -0
  158. data/Views/Cashbox/Service.rb +105 -0
  159. data/Views/Cashbox/Tabs.rb +10 -0
  160. data/Views/Compta/Accounts.rb +36 -0
  161. data/Views/Compta/Course.rb +96 -0
  162. data/Views/Compta/Show.rb +6 -0
  163. data/Views/Compta/Transfer.rb +66 -0
  164. data/Views/Course/Diploma.rb +203 -0
  165. data/Views/Course/Grade.rb +401 -0
  166. data/Views/Course/Modify.rb +447 -0
  167. data/Views/Course/Print.rb +94 -0
  168. data/Views/Course/Responsible.rb +44 -0
  169. data/Views/Course/Stats.rb +76 -0
  170. data/Views/Course/Students.rb +92 -0
  171. data/Views/Course/Tabs.rb +220 -0
  172. data/Views/Internet/Access.rb +134 -0
  173. data/Views/Internet/ClassEdit.rb +24 -0
  174. data/Views/Internet/ClassUsers.rb +81 -0
  175. data/Views/Internet/Config.rb +32 -0
  176. data/Views/Internet/Mobile.rb +213 -0
  177. data/Views/Internet/Recharges.rb +49 -0
  178. data/Views/Internet/Tabs.rb +6 -0
  179. data/Views/Inventory/Computer.rb +24 -0
  180. data/Views/Inventory/Room.rb +18 -0
  181. data/Views/Inventory/Tabs.rb +9 -0
  182. data/Views/Inventory/TicketClosed.rb +7 -0
  183. data/Views/Inventory/TicketOpen.rb +23 -0
  184. data/Views/Library/Person.rb +36 -0
  185. data/Views/Library/Tabs.rb +7 -0
  186. data/Views/Network/Block.rb +87 -0
  187. data/Views/Network/Netdevs.rb +21 -0
  188. data/Views/Network/Restriction.rb +37 -0
  189. data/Views/Network/Share.rb +167 -0
  190. data/Views/Network/Tables.rb +28 -0
  191. data/Views/Network/Tabs.rb +6 -0
  192. data/Views/Person/Admin.rb +99 -0
  193. data/Views/Person/Center.rb +48 -0
  194. data/Views/Person/Course.rb +72 -0
  195. data/Views/Person/Modify.rb +153 -0
  196. data/Views/Person/Tabs.rb +162 -0
  197. data/Views/Report/ComptaExecutive.rb +221 -0
  198. data/Views/Report/ComptaFlat.rb +79 -0
  199. data/Views/Report/ReportCourse.rb +47 -0
  200. data/Views/Report/Tabs.rb +8 -0
  201. data/Views/Report/Usage.rb +52 -0
  202. data/Views/Report/UsageCases.rb +59 -0
  203. data/Views/Self/Cash.rb +67 -0
  204. data/Views/Self/Chat.rb +55 -0
  205. data/Views/Self/Concours.rb +109 -0
  206. data/Views/Self/Email.rb +34 -0
  207. data/Views/Self/Internet.rb +255 -0
  208. data/Views/Self/Results.rb +17 -0
  209. data/Views/Self/Services.rb +85 -0
  210. data/Views/Self/Show.rb +47 -0
  211. data/Views/Self/Tabs.rb +5 -0
  212. data/Views/Special/DFileEdit.rb +13 -0
  213. data/Views/Special/PlugEdit.rb +56 -0
  214. data/Views/Special/Tabs.rb +6 -0
  215. data/Views/Special/Vnc.rb +39 -0
  216. data/Views/Task/Client.rb +21 -0
  217. data/Views/Task/Edit.rb +33 -0
  218. data/Views/Task/List.rb +55 -0
  219. data/Views/Task/Tabs.rb +9 -0
  220. data/Views/Task/Worker.rb +30 -0
  221. data/Views/Template/Activity.rb +33 -0
  222. data/Views/Template/CourseType.rb +63 -0
  223. data/Views/Template/ScheduleType.rb +29 -0
  224. data/Views/Template/Tabs.rb +5 -0
  225. data/Views/Welcome.rb +121 -0
  226. data/config.yaml.default +36 -0
  227. data/po/Gestion-ar.po +2356 -0
  228. data/po/Gestion-en.mo +0 -0
  229. data/po/Gestion-en.po +4363 -0
  230. data/po/Gestion-fr.mo +0 -0
  231. data/po/Gestion-fr.po +4345 -0
  232. data/po/traduction-ar.rtf +76 -0
  233. metadata +381 -0
@@ -0,0 +1,178 @@
1
+ class Activities < Entities
2
+
3
+ PAYMENTS = %w( daily weekly monthly yearly )
4
+ START = %w( payment period period_overlap )
5
+
6
+ def setup_data
7
+ value_str :name
8
+
9
+ value_block :show
10
+ value_str :description
11
+ value_int :cost
12
+ value_list_drop :payment_period, 'Activities::PAYMENTS'
13
+ value_list_drop :start_type, 'Activities::START'
14
+ value_int :overlap
15
+
16
+ value_block :hidden
17
+ value_str :card_filename
18
+ value_list :tags, '%w( library internet club )'
19
+ value_entity_internetClass_empty_all :internet_limit, :drop, :name
20
+ end
21
+
22
+ def files
23
+ ConfigBase.templates.collect { |f| f.cut(/^.*\//) }
24
+ end
25
+
26
+ def tagged(*tags)
27
+ tags.inspect
28
+ Activities.search_all_.select { |a|
29
+ (tags - a.tags).length == 0
30
+ }
31
+ end
32
+
33
+ def tagged_users(tags, date = Date.today)
34
+ #dputs_func
35
+ tagged(tags).collect { |a|
36
+ aps = ActivityPayments.search_by_activity(a)
37
+ dputs(3) { "Found #{aps.inspect} for tag #{a}" }
38
+ ActivityPayments.active_now(aps, date).collect { |ap|
39
+ dputs(3) { "Found #{ap.inspect} active for now" }
40
+ ap.person_paid
41
+ }
42
+ }.flatten.uniq
43
+ end
44
+ end
45
+
46
+
47
+ class Activity < Entity
48
+ attr_accessor :print_card
49
+
50
+ def setup_instance
51
+ if card_filename != nil
52
+ @print_card = OpenPrint.new("#{ConfigBase.template_dir}/#{card_filename.first}")
53
+ end
54
+ end
55
+
56
+ def start_end(s, d = Date.today)
57
+ ActivityPayments.search_by_person_paid(s).select { |ap|
58
+ ap.date_start <= d && d <= ap.date_end && ap.activity == self
59
+ }.collect { |ap| [ap.date_start, ap.date_end] }.pop || [nil, nil]
60
+ end
61
+
62
+ def cost_mov
63
+ self._cost.to_i / 1000.0
64
+ end
65
+ end
66
+
67
+ class ActivityPayments < Entities
68
+ def setup_data
69
+ value_entity_activity :activity
70
+ value_entity_person :person_paid
71
+ value_entity_person :person_cashed
72
+ value_entity_movement :movement
73
+ value_date :date_start
74
+ value_date :date_end
75
+ end
76
+
77
+ def self.week_start(date)
78
+ date - date.cwday
79
+ end
80
+
81
+ def self.get_one_period(date, period, ceil = false)
82
+ [date,
83
+ case period.to_s
84
+ when /daily/
85
+ date + 1
86
+ when /weekly/
87
+ (ceil ? week_start(date) + 7 : date) + 7
88
+ when /monthly/
89
+ (ceil ? Date.new(date.year, date.month + 1) : date).next_month
90
+ when /yearly/
91
+ (ceil ? Date.new(date.year + 1) : date).next_year
92
+ else
93
+ raise("Unknown period #{period[0].to_s}!")
94
+ fail
95
+ end - 1]
96
+ end
97
+
98
+ # Get start and end of a period respecting overlap lesser periods before
99
+ def self.get_period(date, period, overlap=0)
100
+ case period.to_s
101
+ when /daily/
102
+ return [date - overlap, date]
103
+ when /weekly/
104
+ ceil = (date + overlap >= week_start(date) + 7)
105
+ start = ceil ? date : week_start(date)
106
+ when /monthly/
107
+ ceil = (date + overlap * 7 >= Date.new(date.year, date.month + 1))
108
+ start = ceil ? date : Date.new(date.year, date.month)
109
+ when /yearly/
110
+ ceil = (date.next_month(overlap) >= Date.new(date.year + 1))
111
+ start = ceil ? date : Date.new(date.year)
112
+ end
113
+ get_one_period(start, period, ceil)
114
+ end
115
+
116
+ def self.pay(act, p_paid, p_cashed, d_today = Date.today)
117
+ if !p_cashed.account_due
118
+ dputs(0) { "Couldn't make #{p_cashed} pay, as he doesn't have an account_due" }
119
+ return
120
+ end
121
+ mov = Movements.create("#{p_paid.login_name} paid #{p_cashed.login_name} #{act.cost} "+
122
+ "for #{act.name}", Date.today, act.cost_mov,
123
+ p_cashed.account_due, ConfigBase.account_activities)
124
+ date_start, date_end =
125
+ case act.start_type.to_s
126
+ when /payment/
127
+ get_one_period(d_today, act.payment_period)
128
+ when /period/, /period_overlap/
129
+ get_period(d_today, act.payment_period, act.overlap.to_i)
130
+ end
131
+
132
+ log_msg :ActivityPayments, "#{date_start} - #{date_end}: #{mov.inspect}"
133
+ ActivityPayments.create(activity: act, person_paid: p_paid, person_cashed: p_cashed,
134
+ movement: mov, date_start: date_start, date_end: date_end)
135
+ end
136
+
137
+ def self.active_now(actp, d = Date.today)
138
+ return [] unless actp
139
+ actp.select { |ap|
140
+ ap.date_start <= d and d <= ap.date_end
141
+ }
142
+ end
143
+
144
+ def self.active_for(s, d = Date.today)
145
+ active_now(for_user(s), d)
146
+ end
147
+
148
+ def self.for_user(s)
149
+ s == nil and return []
150
+ ActivityPayments.matches_by_person_paid(s)
151
+ end
152
+ end
153
+
154
+ class ActivityPayment < Entity
155
+ def date_start
156
+ Date.from_db(self._date_start)
157
+ end
158
+
159
+ def date_end
160
+ Date.from_db(self._date_end)
161
+ end
162
+
163
+ def print
164
+ st = person_paid
165
+ date = System.run_str('LC_ALL=fr_FR.UTF-8 date +"%d %B %Y"')
166
+ replace = {NAME1: st.first_name, NAME2: st.family_name,
167
+ BDAY: st.birthday, ADDRESS: st.address, TOWN: st.town,
168
+ TEL: st.phone, UNAME: st.login_name, PASS: st.password_plain,
169
+ EMAIL: st.email, PROFESSION: st.profession, STUDY_LEVEL: st.school_grade,
170
+ DATE: date, PRICE: activity.cost,
171
+ DATE_START: date_start, DATE_END: date_end, ID: activitypayment_id}
172
+
173
+ fname = "#{st.person_id.to_s.rjust(6, '0')}-#{st.full_name.gsub(/ /, '_')}"
174
+ dputs(3) { "Replace is #{replace.inspect} - fname is #{fname}" }
175
+
176
+ activity.print_card.print_hash(replace, nil, fname)
177
+ end
178
+ end
@@ -0,0 +1,142 @@
1
+ class ChatMsgs < Entities
2
+ def setup_data
3
+ value_time :time
4
+ value_str :msg
5
+ value_entity_person :center
6
+ value_str :login
7
+
8
+ @max_msgs ||= 200
9
+ @static._client_times ||= {}
10
+ @wait_counter = 0
11
+ @wait_max = 5
12
+ end
13
+
14
+ # Pushes a message to the server and returns eventual new messages
15
+ # tr holds the following keys:
16
+ # center: hash with {login, pass} keys
17
+ # person: login-name of person
18
+ # msg: the message written
19
+ #
20
+ # It returns the results from icc_msg_pull
21
+ def icc_msg_push(tr)
22
+ return 'Error: no course_server' unless ConfigBase.has_function?(:course_server)
23
+ return unless tr && tr._center
24
+ center = Persons.check_login(tr._center._login, tr._center._pass)
25
+ if center && center.has_permission?(:center)
26
+ new_msg(tr._person, tr._msg, center)
27
+ else
28
+ return "Error: center #{center.inspect} has wrong password or is not a center"
29
+ end
30
+ icc_msg_pull(tr)
31
+ end
32
+
33
+ # Gets new messages since last call
34
+ # tr holds the following keys:
35
+ # center: hash with {login, pass} keys
36
+ def icc_msg_pull(tr)
37
+ return 'Error: not a server here' unless ConfigBase.has_function?(:course_server)
38
+ return unless tr && tr._center
39
+ center = Persons.check_login(tr._center._login, tr._center._pass)
40
+ if !center || !center.has_permission?(:center)
41
+ return "Error: center #{center.inspect} has wrong password or is not a center"
42
+ end
43
+ @static._client_times ||= {}
44
+ last_time = @static._client_times[center.login_name] || Time.new(2000, 1, 1)
45
+ @static._client_times[center.login_name] = Time.now
46
+ search_all_.
47
+ select { |msg| msg.time > last_time && msg.center != center }.
48
+ collect { |msg|
49
+ center = msg.center ? msg.center.login_name : Persons.master_center_login_name
50
+ msg.to_hash.merge(center: center)
51
+ }
52
+ end
53
+
54
+ def center_hash
55
+ return {} unless center = Persons.center
56
+ {center: {login: center.login_name, pass: center.password_plain}}
57
+ end
58
+
59
+ def add_remote_msg(ret)
60
+ dputs(3) { "Got reply #{ret.inspect}" }
61
+ if ret._code =~ /^error/i
62
+ dputs(0) { "Error #{ret._msg} while fetching chat-messages" }
63
+ else
64
+ ret._msg.each { |m|
65
+ dputs(2) { "Got message #{m.inspect}" }
66
+ new_msg("#{m._login}@#{m._center}", m._msg, nil, m._time)
67
+ }
68
+ end
69
+ end
70
+
71
+ def is_remote?
72
+ ConfigBase.has_function?(:remote_chat) &&
73
+ ConfigBase.server_url.to_s.length > 0 &&
74
+ (!ConfigBase.has_function?(:course_server))
75
+ end
76
+
77
+ def new_msg(person, msg, center = nil, time = Time.now)
78
+ create(time: time, msg: msg, center: center,
79
+ login: person)
80
+ log_msg :ChatMsgs, "#{person} from #{center ? center.login_name : 'here'} " +
81
+ "says - #{msg}"
82
+ if @data.length > @max_msgs
83
+ get_data_instance(@data.keys.first).delete
84
+ end
85
+ end
86
+
87
+ def new_msg_send(person, msg)
88
+ if is_remote?
89
+ log_msg :ChatMsgs, "Sending msg from #{person} to server"
90
+ arg = center_hash.merge(person: person, msg: msg)
91
+ # As we'll get the new messages, no need to fetch them again
92
+ wait_counter_reset
93
+ (!$MobileControl || $MobileControl.is_connected) and
94
+ add_remote_msg(ICC.get(:ChatMsgs, :msg_push, args: arg))
95
+ end
96
+ new_msg(person, msg)
97
+ end
98
+
99
+ def wait_max=(max)
100
+ @wait_max = max
101
+ end
102
+
103
+ # if @wait_counter is bigger or equal to @wait_counter, it checks for
104
+ # new messages.
105
+ # That way we save precious bandwith
106
+ def wait_counter_add
107
+ is_remote? or return
108
+ @wait_counter += 1
109
+ if @wait_counter >= @wait_max &&
110
+ (!$MobileControl || $MobileControl.is_connected)
111
+ add_remote_msg(ICC.get(:ChatMsgs, :msg_pull, args: center_hash))
112
+ wait_counter_reset
113
+ end
114
+ end
115
+
116
+ def wait_counter_reset
117
+ @wait_counter = 0
118
+ end
119
+
120
+ def show_list(max = 100)
121
+ date = ''
122
+ search_all_.reverse[0...max].collect { |cm|
123
+ t = cm.time.class == Time ? cm.time : Time.parse(cm.time)
124
+ name = (ConfigBase.has_function?(:course_server) && cm.center) ?
125
+ "#{cm.login}@#{cm.center.login_name}" : "#{cm.login}"
126
+ d = "#{t.strftime('%Y-%m-%d')}\n"
127
+ if d != date
128
+ date = d
129
+ else
130
+ d = ''
131
+ end
132
+ "#{d}#{t.strftime('%H:%M')} - #{name}: #{cm.msg}"
133
+ }.join("\n")
134
+ end
135
+
136
+ def load
137
+ super
138
+ ChatMsgs.search_all_.each { |cm|
139
+ cm.time = Time.parse(cm.time)
140
+ }
141
+ end
142
+ end
@@ -0,0 +1,11 @@
1
+ # A classroom has:
2
+ # - different courses
3
+ # - inventory (desks, blackboard, computers)
4
+
5
+ class Classrooms < Entities
6
+ def setup_data
7
+ value_str :name
8
+ value_int :max_students
9
+ value_int :computers
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ class Clients < Entities
2
+ def setup_data
3
+ value_block :name
4
+ value_str :name
5
+
6
+ value_block :address
7
+ value_str :addr1
8
+ value_str :addr2
9
+ value_str :country
10
+
11
+ value_block :prices
12
+ value_int :price_assistant
13
+ value_int :price_expert
14
+
15
+ value_block :contact
16
+ value_str :email
17
+ value_str :phone
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ # A classroom has:
2
+ # - different courses
3
+ # - inventory (desks, blackboard, computers)
4
+
5
+ class Computers < Entities
6
+ def setup_data
7
+ value_block :identity
8
+ value_str :name_service
9
+ value_entity_room_all :room, :drop, :name
10
+ value_str :name_place
11
+
12
+ value_block :performance
13
+ value_str :brand
14
+ value_int :RAM_MB
15
+ value_int :HD_GB
16
+ value_int :CPU_GHz
17
+
18
+ value_block :ticket
19
+ value_text :comment
20
+ end
21
+ end
@@ -0,0 +1,280 @@
1
+ class ConfigBases < Entities
2
+ self.needs %w(Accounts)
3
+
4
+ def add_config
5
+ @convert_values = true
6
+
7
+ value_block :vars_narrow
8
+ value_list_drop :show_passwords, '%w(always lesser students never)'
9
+ value_list_drop :autosave, '%w(true false)'
10
+ value_int :autosave_timer
11
+ value_list_drop :samba_simul, '%w(true false)'
12
+ value_str :samba_config
13
+ value_list_drop :persons_add_del_users, '%w(true false)'
14
+ value_str :persons_adduser_cmd
15
+ value_str :persons_addeduser_cmd
16
+
17
+ value_block :vars_wide
18
+ value_str :server_url
19
+ value_str :label_url
20
+ value_str :html_title
21
+ value_str :upload_files
22
+ value_str :connection_status_log
23
+
24
+ value_block :templates
25
+ value_str :template_dir
26
+ value_str :diploma_dir
27
+ value_str :exam_dir
28
+ value_str :presence_sheet
29
+ value_str :presence_sheet_small
30
+ value_str :card_student
31
+ value_str :card_responsible
32
+
33
+ value_block :captive_conn
34
+ value_str :keep_idle_free
35
+ value_str :keep_idle_minutes
36
+ value_str :captive_dev
37
+
38
+ value_block :captive
39
+ value_str :prerouting
40
+ value_str :http_proxy
41
+ value_str :allow_dst
42
+ value_str :internal_ips
43
+ value_str :captive_dnat
44
+ value_str :openvpn_allow_double
45
+ value_str :allow_src_direct
46
+ value_str :allow_src_proxy
47
+ value_str :allow_double
48
+
49
+ value_block :operator
50
+ value_int :cost_base
51
+ value_int :cost_shared
52
+ value_list_drop :allow_free, '%w(false true all)'
53
+ value_str :phone_main
54
+ value_str :start_loaded
55
+
56
+ value_block :internet
57
+ value_entity_internetClass_empty_all :iclass_default, :drop, :name
58
+
59
+ value_block :mobilecontrol
60
+ value_text :connection_cmds_up
61
+ value_text :connection_cmds_down
62
+ value_str :connection_services_up
63
+ value_str :connection_services_down
64
+ value_str :connection_vpns
65
+
66
+ value_block :accounts
67
+ value_entity_account :account_activities, :drop, :path
68
+ value_entity_account :account_services, :drop, :path
69
+ value_entity_account :account_lending, :drop, :path
70
+ value_entity_account :account_cash, :drop, :path
71
+
72
+ @@functions = %w( network share network_pro
73
+ courses course_server course_client
74
+ files_manage
75
+ internet internet_simple internet_captive
76
+ internet_free_course internet_free_staff
77
+ internet_cyber
78
+ internet_mobile internet_mobile_autocharge
79
+ inventory accounting quiz accounting_courses accounting_old
80
+ plug_admin special special_vnc remote_chat
81
+ cashbox email usage_report activities library ).sort.to_sym
82
+ @@functions_base = {:network => [:internet, :share, :internet_only, :email,
83
+ :internet_mobile, :network_pro],
84
+ :internet => [:internet_simple, :internet_captive,
85
+ :internet_free_course, :internet_free_staff,
86
+ :internet_mobile, :internet_cyber],
87
+ :courses => [:course_server, :course_client, :accounting_courses],
88
+ :accounting => [:accounting_courses, :cashbox],
89
+ :cashbox => [:accounting_courses, :internet_cyber, :activities],
90
+ :activities => [:library],
91
+ :special => [:plug_admin, :special_vnc],
92
+ :internet_mobile => [:internet_mobile_autocharge]
93
+ }
94
+ @@functions_conflict = [[:course_server, :course_client]]
95
+ end
96
+
97
+ def migration_10(c)
98
+ c.allow_free = [c.allow_free]
99
+ c.account_activities = c.account_services
100
+ end
101
+
102
+ def migration_9(c)
103
+ c.diploma_dir = get_config('Diplomas', :Entities, :Courses, :dir_diplomas)
104
+ c.template_dir = get_config('Diplomas', :Entities, :Courses, :dir_diplomas)
105
+ c.exam_dir = get_config('Exams', :Entities, :Courses, :dir_exas)
106
+ # Old installation had default directory of 'Exas'
107
+ File.exists?('Exas') && c.exam_dir != 'Exas' and FileUtils.mv('Exas', c.exam_dir)
108
+ c.presence_sheet = get_config('presence_sheet.ods',
109
+ :Entities, :Courses, :presence_sheet).to_a
110
+ c.presence_sheet_small = get_config('presence_sheet_small.ods',
111
+ :Entities, :Courses, :presence_sheet_small).to_a
112
+ c.card_student = get_config('student_card.odg', :Entities, :Persons, :student_card)
113
+ c.persons_adduser_cmd = get_config('', :Entities, :Persons, :adduser_cmd)
114
+ c.persons_addeduser_cmd = get_config('', :Entities, :Persons, :cmd_after_new)
115
+ c.dputs_logall = '/var/log/gestion/gestion.log'
116
+ c.dputs_logfile = '/var/log/gestion/events.log'
117
+ c.dputs_show_time = %w(min)
118
+ c.dputs_silent = %w(false)
119
+ c.dputs_terminal_width = 160
120
+ c.html_title = 'Gestion from Profeda'
121
+ c.autosave = %w(true)
122
+ c.autosave_timer = get_config(60, :autosave, :timer)
123
+ c.openprint_simul = %w(false)
124
+ c.openprint_search = get_config('.*', :OpenPrint, :search_remote)
125
+ c.upload_files = get_config('/tmp', :UploadFiles, :path)
126
+ c.captive_dev = ''
127
+ c.connection_cmds_up = "postqueue -f\n/usr/local/bin/dnsmasq-internet.sh"
128
+ c.connection_cmds_down = '/usr/local/bin/dnsmasq-catchall.sh'
129
+ c.connection_services_up = 'ntpd fetchmail'
130
+ c.connection_services_down = 'fetchmail'
131
+ c.connection_vpns = if (vpns = Dir.glob('/etc/openvpn/vpn-profeda*conf')).length > 0
132
+ vpns.collect { |v| File.basename v, '.conf' }.join(' ')
133
+ else
134
+ nil
135
+ end
136
+ end
137
+
138
+ def migration_8(c)
139
+ c.show_passwords = %w(lesser)
140
+ end
141
+
142
+ def migration_7(c)
143
+ c.replace_function(:sms_control, :internet_mobile)
144
+ c.replace_function(:sms_control_autocharge, :internet_mobile_autocharge)
145
+ end
146
+
147
+ def migration_6(c)
148
+ c._use_printing = c._use_printing.to_i > 0
149
+ end
150
+
151
+ def migration_5(c)
152
+ c.account_services = Accounts.get_by_path_or_create(
153
+ get_config('Root::Income::Services', :Accounting, :service))
154
+ c.account_lending = Accounts.get_by_path_or_create(
155
+ get_config('Root::Lending', :Accounting, :lending))
156
+ c.account_cash = Accounts.get_by_path_or_create(
157
+ get_config('Root::Cash', :Accounting, :cash))
158
+ #dp c
159
+ end
160
+
161
+ def migration_4(c)
162
+ if c._functions.index(:internet_libnet)
163
+ c._functions -= [:internet_libnet]
164
+ c._functions += [:internet_captive]
165
+ end
166
+ if !c.welcome_text || c.welcome_text == ''
167
+ c.welcome_text = get_config('', :welcome_text)
168
+ end
169
+ end
170
+
171
+ def migration_3(c)
172
+ c.cost_base = 0
173
+ c.cost_shared = 0
174
+ c.allow_free = 'false'
175
+ end
176
+
177
+ def migration_2(c)
178
+ c.keep_idle_free = 5
179
+ c.keep_idle_minutes = 3
180
+ c.server_url = 'icc.profeda.org'
181
+ c.label_url = 'label.profeda.org'
182
+ end
183
+
184
+ # Migration_1 is taken by QooxView-ConfigBase!
185
+ end
186
+
187
+ class ConfigBase < Entity
188
+ def send_config
189
+ save_block_to_object :captive, Network::Captive
190
+ Network::Captive.clean_config
191
+ ConfigBase.has_function?(:internet_captive) and Network::Captive.setup
192
+ save_block_to_object :operator, Network::Operator
193
+ Network::Operator.clean_config
194
+ if ConfigBase.samba_simul.to_s == "false"
195
+ if ConfigBase.has_function?(:share)
196
+ Platform.enable_start(:samba)
197
+ else
198
+ Platform.stop_disable(:samba)
199
+ end
200
+ end
201
+ if ConfigBase.has_function?(:internet_mobile)
202
+ start_mobile_control
203
+ save_block_to_object :mobilecontrol, $MobileControl
204
+ $MobileControl.autocharge = ConfigBase.has_function?(:internet_mobile_autocharge)
205
+ else
206
+ stop_mobile_control
207
+ end
208
+ if ConfigBase.has_function?(:accounting) && Entities.is_setup?(:Person)
209
+ Persons.search_by_permissions('secretary').each{|p|
210
+ p.update_accounts
211
+ }
212
+ end
213
+ end
214
+
215
+ def replace_function(old, new)
216
+ func = self.functions.to_sym
217
+ if func.index(old.to_sym)
218
+ func -= [old.to_sym]
219
+ func += [new.to_sym]
220
+ end
221
+ self.functions = func
222
+ end
223
+
224
+ def start_mobile_control
225
+ return if $MobileControl
226
+ dputs(1) { 'Starting mobile-control' }
227
+ $MobileControl = Network::MobileControl.new
228
+
229
+ @mobile_thread = Thread.new {
230
+ state = nil
231
+ loop {
232
+ rescue_all 'Error with MobileControl' do
233
+ $MobileControl.check_connection
234
+ if state != $MobileControl.state_to_s
235
+ dputs(2) { "#{Time.now.strftime('%y%m%d-%H%M')}: #{state = $MobileControl.state_to_s}" }
236
+ end
237
+ sleep 10
238
+ end
239
+ }
240
+ }
241
+ end
242
+
243
+ def stop_mobile_control
244
+ if @mobile_thread
245
+ @mobile_thread.kill
246
+ @mobile_thread.join
247
+ @mobile_thread = nil
248
+ end
249
+ $MobileControl = nil
250
+ end
251
+
252
+ def server_uri
253
+ server_url =~ /^http/ ? server_url : "http://#{server_url}"
254
+ end
255
+
256
+ def get_url(url)
257
+ if url.class == Symbol
258
+ url = ConfigBase.data_get(url)
259
+ end
260
+ url =~ /^https{0,1}:\/\// ? url : "http://#{url}"
261
+ end
262
+
263
+ def templates
264
+ Dir.glob("#{template_dir}/*.od?").
265
+ collect { |f| f.sub(/^.*\//, '') }.
266
+ sort
267
+ end
268
+
269
+ def template_path(t)
270
+ return '' unless template_dir && card_student && card_responsible
271
+ "#{template_dir}/" +
272
+ case t
273
+ when :card_student
274
+ card_student.first.to_s
275
+ when :card_responsible
276
+ card_responsible.first.to_s
277
+ end
278
+ end
279
+
280
+ end