gestion 1.9.12

Sign up to get free protection for your applications and to get access to all the features.
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