ydim_html 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/History.txt +6 -0
  2. data/LICENSE.txt +339 -0
  3. data/Manifest.txt +47 -0
  4. data/README.txt +21 -0
  5. data/Rakefile +28 -0
  6. data/bin/ydim-htmld +38 -0
  7. data/lib/ydim/html.rb +10 -0
  8. data/lib/ydim/html/config.rb +37 -0
  9. data/lib/ydim/html/state/ajax_values.rb +16 -0
  10. data/lib/ydim/html/state/autoinvoice.rb +93 -0
  11. data/lib/ydim/html/state/confirm.rb +15 -0
  12. data/lib/ydim/html/state/debitor.rb +81 -0
  13. data/lib/ydim/html/state/debitors.rb +23 -0
  14. data/lib/ydim/html/state/global.rb +99 -0
  15. data/lib/ydim/html/state/global_predefine.rb +13 -0
  16. data/lib/ydim/html/state/init.rb +20 -0
  17. data/lib/ydim/html/state/invoice.rb +179 -0
  18. data/lib/ydim/html/state/invoices.rb +69 -0
  19. data/lib/ydim/html/state/pdf.rb +16 -0
  20. data/lib/ydim/html/util/lookandfeel.rb +132 -0
  21. data/lib/ydim/html/util/server.rb +36 -0
  22. data/lib/ydim/html/util/session.rb +27 -0
  23. data/lib/ydim/html/util/validator.rb +62 -0
  24. data/lib/ydim/html/view/ajax_values.rb +22 -0
  25. data/lib/ydim/html/view/autoinvoice.rb +79 -0
  26. data/lib/ydim/html/view/autoinvoices.rb +41 -0
  27. data/lib/ydim/html/view/confirm.rb +27 -0
  28. data/lib/ydim/html/view/debitor.rb +111 -0
  29. data/lib/ydim/html/view/debitors.rb +44 -0
  30. data/lib/ydim/html/view/htmlgrid.rb +103 -0
  31. data/lib/ydim/html/view/init.rb +29 -0
  32. data/lib/ydim/html/view/invoice.rb +217 -0
  33. data/lib/ydim/html/view/invoices.rb +158 -0
  34. data/lib/ydim/html/view/navigation.rb +28 -0
  35. data/lib/ydim/html/view/pdf.rb +23 -0
  36. data/lib/ydim/html/view/template.rb +70 -0
  37. data/test/selenium.rb +1687 -0
  38. data/test/selenium/selenium-server.jar +0 -0
  39. data/test/selenium/test_autoinvoice.rb +318 -0
  40. data/test/selenium/test_debitor.rb +343 -0
  41. data/test/selenium/test_debitors.rb +46 -0
  42. data/test/selenium/test_init.rb +104 -0
  43. data/test/selenium/test_invoice.rb +295 -0
  44. data/test/selenium/test_invoices.rb +175 -0
  45. data/test/selenium/unit.rb +124 -0
  46. data/test/stub/http_server.rb +139 -0
  47. data/test/suite.rb +14 -0
  48. metadata +138 -0
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::AutoInvoices -- de.oddb.org -- 13.12.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/invoices'
5
+
6
+ module YDIM
7
+ module Html
8
+ module View
9
+ class AutoInvoiceList < InvoiceList
10
+ COMPONENTS = {
11
+ [0,0] => :unique_id,
12
+ [1,0] => :name,
13
+ [2,0] => :email,
14
+ [3,0] => :description,
15
+ [4,0] => :formatted_date,
16
+ [5,0] => :total_netto,
17
+ [6,0] => :total_brutto,
18
+ [7,0] => :currency,
19
+ [8,0] => :generate_invoice,
20
+ [9,0] => :delete,
21
+ }
22
+ CSS_ID = 'autoinvoices'
23
+ links :autoinvoice, :date, :unique_id, :description
24
+ def delete(model)
25
+ link = HtmlGrid::Link.new(:delete, model, @session, self)
26
+ url = @lookandfeel._event_url(:ajax_delete_autoinvoice,
27
+ [:unique_id, model.unique_id])
28
+ link.href = sprintf("javascript: reload_list('%s', '%s')",
29
+ css_id, url)
30
+ link
31
+ end
32
+ def generate_invoice(model)
33
+ link = HtmlGrid::Link.new(:generate_invoice, model, @session, self)
34
+ link.href = @lookandfeel._event_url(:generate_invoice,
35
+ {:unique_id => model.unique_id})
36
+ link
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Confirm -- ydim -- 18.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/template'
5
+ require 'htmlgrid/div'
6
+
7
+ module YDIM
8
+ module Html
9
+ module View
10
+ class ConfirmComponent < HtmlGrid::Div
11
+ CSS_ID = 'confirm'
12
+ def init
13
+ @value = @model
14
+ end
15
+ end
16
+ class Confirm < Template
17
+ CONTENT = ConfirmComponent
18
+ def http_headers
19
+ headers = super
20
+ url = @lookandfeel._event_url(:invoices)
21
+ headers.store('Refresh', "5; URL=#{url}")
22
+ headers
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Debitor -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/template'
5
+ require 'ydim/html/view/autoinvoices'
6
+ require 'ydim/html/view/invoices'
7
+ require 'htmlgrid/inputtext'
8
+ require 'htmlgrid/inputdate'
9
+ require 'htmlgrid/labeltext'
10
+ require 'htmlgrid/select'
11
+ require 'htmlgrid/textarea'
12
+
13
+ module YDIM
14
+ module Html
15
+ module View
16
+ class Textarea < HtmlGrid::Textarea
17
+ LABEL = true
18
+ end
19
+ class DebitorForm < HtmlGrid::Form
20
+ COMPONENTS = {
21
+ [0,0] => :unique_id,
22
+ [0,1] => :debitor_type,
23
+ [0,2] => :name,
24
+ [0,3] => :salutation,
25
+ [0,4] => :contact,
26
+ [0,5] => :contact_firstname,
27
+ [0,6] => :contact_title,
28
+ [0,7] => :address_lines,
29
+ [0,8] => :location,
30
+ [0,9] => :country,
31
+ [0,10] => :emails,
32
+ [0,11] => :phone,
33
+ [1,12] => :submit,
34
+ }
35
+ FORM_ID = 'debitor'
36
+ EVENT = :update
37
+ SYMBOL_MAP = {
38
+ :debitor_type => HtmlGrid::Select,
39
+ :unique_id => HtmlGrid::Value,
40
+ :salutation => HtmlGrid::Select,
41
+ }
42
+ def emails(model, session=@session)
43
+ input = HtmlGrid::InputText.new(:emails, model, @session, self)
44
+ if error = @session.error(:emails)
45
+ input.value = error.value
46
+ else
47
+ input.value = model.emails.join(', ')
48
+ end
49
+ input.css_class = 'extralarge'
50
+ input
51
+ end
52
+ def hidden_fields(context)
53
+ super << context.hidden('unique_id', @model.unique_id)
54
+ end
55
+ end
56
+ class DebitorComposite < HtmlGrid::DivComposite
57
+ COMPONENTS = {
58
+ [0,0] => DebitorForm,
59
+ [0,1] => :is_open,
60
+ [1,1] => :is_due,
61
+ [2,1] => :is_paid,
62
+ [3,1] => :is_trash,
63
+ [0,2] => :invoices,
64
+ [0,3] => :invoice_list,
65
+ [0,4] => :create_invoice,
66
+ [0,5] => :autoinvoices,
67
+ [0,6] => :autoinvoice_list,
68
+ [0,7] => :create_autoinvoice,
69
+ }
70
+ CSS_MAP = {
71
+ 1 => 'subnavigation',
72
+ 2 => 'padded',
73
+ 4 => 'padded',
74
+ 5 => 'padded',
75
+ 7 => 'padded',
76
+ }
77
+ SYMBOL_MAP = {
78
+ :invoices => HtmlGrid::LabelText,
79
+ :autoinvoices => HtmlGrid::LabelText,
80
+ }
81
+ def autoinvoice_list(model)
82
+ AutoInvoiceList.new(@session.state.autoinvoice_infos, @session, self)
83
+ end
84
+ def button(key, model)
85
+ if(model.unique_id)
86
+ button = HtmlGrid::Button.new(key, model, @session, self)
87
+ args = {:unique_id => model.unique_id}
88
+ url = @lookandfeel._event_url(key, args)
89
+ button.set_attribute('onClick', "document.location.href='#{url}'")
90
+ button
91
+ end
92
+ end
93
+ def create_autoinvoice(model)
94
+ button(:create_autoinvoice, model)
95
+ end
96
+ def create_invoice(model)
97
+ button(:create_invoice, model)
98
+ end
99
+ def invoice_list(model)
100
+ InvoiceList.new(@session.state.invoice_infos, @session, self)
101
+ end
102
+ end
103
+ class Debitor < Template
104
+ CONTENT = DebitorComposite
105
+ def subnavigation(model)
106
+ InvoicesSubnavigation.new(model, @session, self)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Debitors -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/template'
5
+ require 'htmlgrid/formlist'
6
+
7
+ module YDIM
8
+ module Html
9
+ module View
10
+ class DebitorList < HtmlGrid::FormList
11
+ COMPONENTS = {
12
+ [0,0] => :unique_id,
13
+ [1,0] => :name,
14
+ [2,0] => :email,
15
+ [3,0] => :phone,
16
+ [4,0] => :next_invoice_date,
17
+ [5,0] => :debitor_type,
18
+ }
19
+ EVENT = :create_debitor
20
+ SORT_DEFAULT = nil
21
+ def debitor_type(model)
22
+ @lookandfeel.lookup(model.debitor_type)
23
+ end
24
+ def next_invoice_date(model)
25
+ if(date = model.next_invoice_date)
26
+ @lookandfeel.format_date(date)
27
+ end
28
+ end
29
+ def phone(model)
30
+ if(phone = model.phone)
31
+ link = HtmlGrid::Link.new(:phone, model, @session, self)
32
+ link.href = "callto://#{phone.delete(' ')}"
33
+ link.value = phone
34
+ link
35
+ end
36
+ end
37
+ links :debitor, :name, :unique_id
38
+ end
39
+ class Debitors < Template
40
+ CONTENT = DebitorList
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+ # HtmlGrid -- ydim -- 13.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'htmlgrid/component'
5
+ require 'htmlgrid/composite'
6
+ require 'htmlgrid/errormessage'
7
+ require 'htmlgrid/form'
8
+ require 'htmlgrid/input'
9
+ require 'htmlgrid/inputtext'
10
+ require 'htmlgrid/list'
11
+ require 'htmlgrid/pass'
12
+
13
+ module HtmlGrid
14
+ class Component
15
+ HTTP_HEADERS = {
16
+ "Cache-Control" => "no-cache, max-age=3600, must-revalidate",
17
+ 'Content-Type' => 'text/html; charset=ISO-8859-1',
18
+ }
19
+ class << self
20
+ def escaped(*names)
21
+ names.each { |name|
22
+ define_method(name) { |model|
23
+ number_format escape(model.send(name))
24
+ }
25
+ }
26
+ end
27
+ def links(event, *names)
28
+ names.each { |name|
29
+ define_method(name) { |model|
30
+ link = HtmlGrid::Link.new(name, model, @session, self)
31
+ args = {:unique_id => model.unique_id}
32
+ link.href = @lookandfeel._event_url(event, args)
33
+ link.value = model.send(name)
34
+ link
35
+ }
36
+ }
37
+ end
38
+ end
39
+ def escape(value)
40
+ CGI.escape(format(value))
41
+ end
42
+ def format(value)
43
+ case value
44
+ when Float
45
+ sprintf("%1.#{self.precision}f", value)
46
+ else
47
+ value.to_s
48
+ end
49
+ end
50
+ def number_format(string)
51
+ string.reverse.gsub(/\d{3}(?=\d)(?!\d*\.)/) do |match|
52
+ match << "'"
53
+ end.reverse
54
+ end
55
+ def precision
56
+ mdl = @session.state.model
57
+ if(mdl.respond_to?(:precision))
58
+ mdl.precision
59
+ else
60
+ 2
61
+ end
62
+ end
63
+ end
64
+ class Composite
65
+ LEGACY_INTERFACE = false
66
+ end
67
+ class Form
68
+ include HtmlGrid::ErrorMessage
69
+ DEFAULT_CLASS = HtmlGrid::InputText
70
+ LABELS = true
71
+ def init
72
+ super
73
+ error_message
74
+ end
75
+ end
76
+ class InputText
77
+ CSS_CLASS = 'large'
78
+ end
79
+ class List
80
+ STRIPED_BG = false
81
+ def List.ajax_inputs(*keys)
82
+ keys.each { |key|
83
+ define_method(key) { |model|
84
+ name = "#{key}[#{model.index}]"
85
+ input = HtmlGrid::InputText.new(name, model, @session, self)
86
+ input.value = format(model.send(key))
87
+ input.css_id = name
88
+ args = [
89
+ :unique_id, @session.state.model.unique_id,
90
+ :index, model.index,
91
+ key, nil,
92
+ ]
93
+ url = @lookandfeel.event_url(:ajax_item, args)
94
+ input.set_attribute('onChange', "reload_data('#{url}' + sbsm_encode(this.value))")
95
+ input
96
+ }
97
+ }
98
+ end
99
+ end
100
+ class Pass
101
+ CSS_CLASS = 'large'
102
+ end
103
+ end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Init -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/template'
5
+ require 'htmlgrid/pass'
6
+ require 'htmlgrid/inputtext'
7
+
8
+ module YDIM
9
+ module Html
10
+ module View
11
+ class InitForm < HtmlGrid::Form
12
+ COMPONENTS = {
13
+ [0,0] => :email,
14
+ [0,1] => :pass,
15
+ [1,2] => :submit,
16
+ }
17
+ EVENT = :login
18
+ SYMBOL_MAP = {
19
+ :email => HtmlGrid::InputText,
20
+ :pass => HtmlGrid::Pass,
21
+ }
22
+ end
23
+ class Init < Template
24
+ CONTENT = InitForm
25
+ FOOT = nil
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Invoice -- ydim -- 16.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/template'
5
+ require 'htmlgrid/form'
6
+ require 'htmlgrid/inputcheckbox'
7
+ require 'htmlgrid/inputdate'
8
+ require 'htmlgrid/errormessage'
9
+ require 'htmlgrid/select'
10
+ require 'htmlgrid/textarea'
11
+
12
+ module YDIM
13
+ module Html
14
+ module View
15
+ class SpanValue < HtmlGrid::Value
16
+ def init
17
+ super
18
+ @attributes.store('id', @name)
19
+ end
20
+ def to_html(context)
21
+ context.span(@attributes) { number_format escape(@value) }
22
+ end
23
+ end
24
+ class ItemList < HtmlGrid::List
25
+ COMPONENTS = {
26
+ [0,0] => :time,
27
+ [1,0] => :text,
28
+ [2,0] => :quantity,
29
+ [3,0] => :unit,
30
+ [4,0] => :price,
31
+ [5,0] => :total_netto,
32
+ [6,0] => :delete,
33
+ }
34
+ CSS_ID = 'items'
35
+ CSS_MAP = {
36
+ [0,0] => 'standard-width',
37
+ [5,0] => 'right',
38
+ }
39
+ COMPONENT_CSS_MAP = {
40
+ [1,0] => 'extralarge',
41
+ [2,0] => 'small',
42
+ [3,0] => 'medium',
43
+ [4,0] => 'medium',
44
+ }
45
+ DEFAULT_CLASS = HtmlGrid::InputText
46
+ SORT_DEFAULT = nil
47
+ ajax_inputs :text, :quantity, :unit, :price
48
+ def compose_footer(offset)
49
+ link = HtmlGrid::Button.new(:create_item, @model, @session, self)
50
+ args = { :unique_id => @session.state.model.unique_id }
51
+ url = @lookandfeel.event_url(:ajax_create_item, args)
52
+ link.set_attribute('onClick', "reload_list('items', '#{url}');")
53
+ @grid.add(link, *offset)
54
+ end
55
+ def delete(model)
56
+ link = HtmlGrid::Link.new(:delete, model, @session, self)
57
+ args = {
58
+ :unique_id => @session.state.model.unique_id,
59
+ :index => model.index,
60
+ }
61
+ url = @lookandfeel.event_url(:ajax_delete_item, args)
62
+ link.href = "javascript: reload_list('items', '#{url}')"
63
+ link
64
+ end
65
+ def time(model)
66
+ if(time = model.time)
67
+ @lookandfeel.format_time(model.time)
68
+ end
69
+ end
70
+ def total_netto(model)
71
+ val = SpanValue.new(:total_netto, model, @session, self)
72
+ val.css_id = "total_netto#{model.index}"
73
+ val
74
+ end
75
+ end
76
+ class InvoiceTotalComposite < HtmlGrid::Composite
77
+ COMPONENTS = {
78
+ [0,0] => :total_netto,
79
+ [0,1] => :vat,
80
+ [0,2] => :total_brutto,
81
+ }
82
+ CSS_ID = 'total'
83
+ CSS_MAP = {
84
+ [1,0,1,3] => 'right',
85
+ }
86
+ DEFAULT_CLASS = SpanValue
87
+ LABELS = true
88
+ end
89
+ class InvoiceInnerComposite < HtmlGrid::Composite
90
+ include HtmlGrid::ErrorMessage
91
+ links :debitor, :name, :email
92
+ COMPONENTS = {
93
+ [0,0] => :unique_id,
94
+ [0,1,0] => :debitor_name,
95
+ [1,1,1] => 'dash',
96
+ [1,1,2] => :debitor_email,
97
+ [0,2] => :description,
98
+ [0,3] => :date,
99
+ [1,3] => :payment_period,
100
+ [0,4] => :currency,
101
+ [0,5] => :precision,
102
+ [0,6] => :suppress_vat,
103
+ }
104
+ COMPONENT_CSS_MAP = {
105
+ [0,2] => 'extralarge',
106
+ [0,5] => 'small',
107
+ }
108
+ DEFAULT_CLASS = HtmlGrid::Value
109
+ LABELS = true
110
+ SYMBOL_MAP = {
111
+ :date => HtmlGrid::InputDate,
112
+ :description => HtmlGrid::InputText,
113
+ :invoice_interval => HtmlGrid::Select,
114
+ :reminder_subject => HtmlGrid::InputText,
115
+ }
116
+ def init
117
+ super
118
+ error_message
119
+ end
120
+ def currency(model)
121
+ select = HtmlGrid::Select.new(:currency, model, @session, self)
122
+ if(model.unique_id)
123
+ select.set_attribute('onChange', "reload_form('invoice', 'ajax_invoice');")
124
+ end
125
+ select
126
+ end
127
+ def debitor_email(model)
128
+ email(model.debitor)
129
+ end
130
+ def debitor_name(model)
131
+ link = name(model.debitor)
132
+ link.label = true
133
+ link
134
+ end
135
+ def payment_period(model)
136
+ @lookandfeel.lookup(:payment_period, model.payment_period.to_i)
137
+ end
138
+ def precision(model)
139
+ input = HtmlGrid::InputText.new(:precision, model, @session, self)
140
+ if(model.unique_id)
141
+ input.set_attribute('onChange', "reload_form('invoice', 'ajax_invoice');")
142
+ end
143
+ input
144
+ end
145
+ def suppress_vat(model)
146
+ input = HtmlGrid::InputCheckbox.new(:suppress_vat, model, @session, self)
147
+ if(model.unique_id)
148
+ input.set_attribute('onClick', "reload_form('invoice', 'ajax_invoice');")
149
+ end
150
+ input
151
+ end
152
+ end
153
+ class InvoiceComposite < HtmlGrid::DivComposite
154
+ include HtmlGrid::FormMethods
155
+ FORM_ID = 'invoice'
156
+ COMPONENTS = {
157
+ [0,0] => InvoiceInnerComposite,
158
+ [0,1] => :items,
159
+ [0,2] => InvoiceTotalComposite,
160
+ [0,3] => :submit,
161
+ [1,3] => :pdf,
162
+ [2,3] => :send_invoice,
163
+ }
164
+ CSS_MAP = {
165
+ 3 => 'padded'
166
+ }
167
+ EVENT = :update
168
+ def init
169
+ if(@model.unique_id.nil?)
170
+ @components = {
171
+ [0,0] => components[[0,0]],
172
+ [0,1] => :submit,
173
+ }
174
+ @css_map = { 1 => 'padded' }
175
+ elsif(@model.items.empty?)
176
+ @components = {
177
+ [0,0] => components[[0,0]],
178
+ [0,1] => :items,
179
+ [0,2] => :submit,
180
+ }
181
+ @css_map = { 2 => 'padded' }
182
+ end
183
+ super
184
+ end
185
+ def hidden_fields(context)
186
+ super << context.hidden('unique_id', @model.unique_id)
187
+ end
188
+ def items(model)
189
+ ItemList.new(model.items, @session, self)
190
+ end
191
+ def pdf(model)
192
+ button = HtmlGrid::Button.new(:pdf, model, @session, self)
193
+ url = @lookandfeel._event_url(:pdf, {:unique_id => model.unique_id})
194
+ button.set_attribute('onClick', "document.location.href='#{url}'")
195
+ button
196
+ end
197
+ def send_invoice(model)
198
+ button(:send_invoice, model)
199
+ end
200
+ def button(key, model)
201
+ button = HtmlGrid::Button.new(key, model, @session, self)
202
+ url = @lookandfeel._event_url(key, {:unique_id => model.unique_id})
203
+ button.set_attribute('onClick',
204
+ "this.form.event.value='#{key}'; this.form.submit()")
205
+ button
206
+ end
207
+ end
208
+ class Invoice < Template
209
+ CONTENT = InvoiceComposite
210
+ def init
211
+ css_map[1] = @model.status
212
+ super
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end