ydim-html 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.travis.yml +29 -0
  4. data/Gemfile +12 -0
  5. data/History.txt +11 -0
  6. data/LICENSE.txt +339 -0
  7. data/Manifest.txt +47 -0
  8. data/Rakefile +21 -0
  9. data/bin/ydim-htmld +38 -0
  10. data/doc/favicon.ico +0 -0
  11. data/doc/index.rbx +16 -0
  12. data/doc/resources/javascript/dojo.js +5940 -0
  13. data/doc/resources/javascript/iframe_history.html +53 -0
  14. data/doc/resources/javascript/ydim.js +67 -0
  15. data/doc/resources/ydim/ydim.css +113 -0
  16. data/lib/ydim/html.rb +10 -0
  17. data/lib/ydim/html/config.rb +37 -0
  18. data/lib/ydim/html/state/ajax_values.rb +17 -0
  19. data/lib/ydim/html/state/autoinvoice.rb +94 -0
  20. data/lib/ydim/html/state/confirm.rb +16 -0
  21. data/lib/ydim/html/state/debitor.rb +82 -0
  22. data/lib/ydim/html/state/debitors.rb +24 -0
  23. data/lib/ydim/html/state/global.rb +100 -0
  24. data/lib/ydim/html/state/global_predefine.rb +14 -0
  25. data/lib/ydim/html/state/init.rb +21 -0
  26. data/lib/ydim/html/state/invoice.rb +180 -0
  27. data/lib/ydim/html/state/invoices.rb +70 -0
  28. data/lib/ydim/html/state/pdf.rb +17 -0
  29. data/lib/ydim/html/util/lookandfeel.rb +133 -0
  30. data/lib/ydim/html/util/server.rb +37 -0
  31. data/lib/ydim/html/util/session.rb +29 -0
  32. data/lib/ydim/html/util/validator.rb +63 -0
  33. data/lib/ydim/html/version.rb +7 -0
  34. data/lib/ydim/html/view/ajax_values.rb +27 -0
  35. data/lib/ydim/html/view/autoinvoice.rb +80 -0
  36. data/lib/ydim/html/view/autoinvoices.rb +42 -0
  37. data/lib/ydim/html/view/confirm.rb +28 -0
  38. data/lib/ydim/html/view/debitor.rb +118 -0
  39. data/lib/ydim/html/view/debitors.rb +45 -0
  40. data/lib/ydim/html/view/htmlgrid.rb +104 -0
  41. data/lib/ydim/html/view/init.rb +30 -0
  42. data/lib/ydim/html/view/invoice.rb +218 -0
  43. data/lib/ydim/html/view/invoices.rb +159 -0
  44. data/lib/ydim/html/view/navigation.rb +29 -0
  45. data/lib/ydim/html/view/pdf.rb +24 -0
  46. data/lib/ydim/html/view/template.rb +71 -0
  47. data/readme.md +28 -0
  48. data/spec/smoketest_spec.rb +234 -0
  49. data/spec/spec_helper.rb +117 -0
  50. data/spec/stub/http_server.rb +157 -0
  51. data/test/selenium.rb +1690 -0
  52. data/test/selenium/selenium-server.jar +0 -0
  53. data/test/selenium/test_autoinvoice.rb +319 -0
  54. data/test/selenium/test_debitor.rb +344 -0
  55. data/test/selenium/test_debitors.rb +47 -0
  56. data/test/selenium/test_init.rb +105 -0
  57. data/test/selenium/test_invoice.rb +296 -0
  58. data/test/selenium/test_invoices.rb +176 -0
  59. data/test/selenium/unit.rb +125 -0
  60. data/test/stub/http_server.rb +141 -0
  61. data/test/suite.rb +15 -0
  62. data/ydim-html.gemspec +36 -0
  63. metadata +302 -0
@@ -0,0 +1,53 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <title>The Dojo Toolkit</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
8
+ <script type="text/javascript">
9
+ // <!--
10
+ var noInit = false;
11
+ var domain = "";
12
+ // document.domain = "localhost";
13
+ function init(){
14
+ // parse the query string if there is one to try to get args that
15
+ // we can act on
16
+ var sparams = document.location.search;
17
+ if(sparams.length >= 0){
18
+ if(sparams.charAt(0) == "?"){
19
+ sparams = sparams.substring(1);
20
+ }
21
+ var ss = (sparams.indexOf("&amp;") >= 0) ? "&amp;" : "&";
22
+ sparams = sparams.split(ss);
23
+ for(var x=0; x<sparams.length; x++){
24
+ var tp = sparams[x].split("=");
25
+ if(typeof window[tp[0]] != "undefined"){
26
+ window[tp[0]] = ((tp[1]=="true")||(tp[1]=="false")) ? eval(tp[1]) : tp[1];
27
+ }
28
+ }
29
+ }
30
+
31
+ if(noInit){ return; }
32
+ if(domain.length > 0){
33
+ document.domain = domain;
34
+ }
35
+ if((window.parent != window)&&(window.parent["dojo"])){
36
+ var pdj = window.parent.dojo;
37
+ if((pdj["io"])&&(pdj["io"]["XMLHTTPTransport"])){
38
+ pdj.io.XMLHTTPTransport.iframeLoaded(null, window.location);
39
+ }
40
+ }
41
+ }
42
+ // -->
43
+ </script>
44
+ </head>
45
+ <!--
46
+ <body onload="try{ init(); }catch(e){ alert(e); }">
47
+ -->
48
+ <body>
49
+ <h4>The Dojo Toolkit -- iframe_history.html</h4>
50
+
51
+ <p>This file is used in Dojo's back/fwd button management.</p>
52
+ </body>
53
+ </html>
@@ -0,0 +1,67 @@
1
+ function sbsm_encode(value)
2
+ {
3
+ // this function provides an Encoding-Hack: because encodeURIComponent returns
4
+ // UTF-8 encoded values and because for some reasone we need to encode twice
5
+ // anyway, we first encode in native charset.
6
+ value = dojo.string.encodeAscii(value);
7
+ value = value.replace(/\//g, '%2f')
8
+ value = encodeURIComponent(value);
9
+ return value;
10
+ }
11
+
12
+ function reload_form(form_id, server_event)
13
+ {
14
+ document.body.style.cursor = 'wait';
15
+ var form;
16
+ var evt_field;
17
+ if((form = dojo.byId(form_id)) && (evt_field = dojo.byId("event")))
18
+ {
19
+ evt_field.value = server_event;
20
+ dojo.io.bind({
21
+ url: form.action,
22
+ formNode: form,
23
+ load: function(type, data, event) {
24
+ form.parentNode.innerHTML = data;
25
+ document.body.style.cursor = 'auto';
26
+ },
27
+ mimetype: "text/html"
28
+ });
29
+ }
30
+ }
31
+ function reload_list(list_id, url)
32
+ {
33
+ var list;
34
+ if(list = dojo.byId(list_id))
35
+ {
36
+ dojo.io.bind({
37
+ url: url,
38
+ load: function(type, data, event) {
39
+ list.parentNode.innerHTML = data;
40
+ },
41
+ mimetype: "text/html"
42
+ });
43
+ }
44
+ }
45
+ function reload_data(url)
46
+ {
47
+ dojo.io.bind({
48
+ url: url,
49
+ load: function(type, data, event) {
50
+ var key, val, item;
51
+ for(key in ajaxResponse) {
52
+ if(item = dojo.byId(key))
53
+ {
54
+ if(item.value)
55
+ {
56
+ item.value = ajaxResponse[key];
57
+ }
58
+ else
59
+ {
60
+ item.innerHTML = ajaxResponse[key];
61
+ }
62
+ }
63
+ }
64
+ },
65
+ mimetype: "text/javascript"
66
+ });
67
+ }
@@ -0,0 +1,113 @@
1
+ body, textarea {
2
+ font-family: Frutiger, Helvetica, Verdana, Arial, sans-serif;
3
+ }
4
+ body {
5
+ color: #306;
6
+ background-color: #FFC;
7
+ }
8
+ label, th {
9
+ font-weight: bold;
10
+ text-align: left;
11
+ }
12
+ td.standard-width {
13
+ width: 150px;
14
+ }
15
+ label {
16
+ width: 150px;
17
+ display: block;
18
+ }
19
+ label.error {
20
+ color: #C00;
21
+ }
22
+ td, th {
23
+ padding: 4px;
24
+ }
25
+ td.unpadded {
26
+ padding: 0px;
27
+ }
28
+ td.processingerror {
29
+ color: #C00;
30
+ font-weight: bold;
31
+ }
32
+ td.top {
33
+ vertical-align: top;
34
+ }
35
+ textarea {
36
+ width: 500px;
37
+ height: 400px;
38
+ }
39
+ th {
40
+ text-align: left;
41
+ background-color: #FC6;
42
+ }
43
+ tr.is_due, div.is_due {
44
+ background-color: #FAA;
45
+ }
46
+ tr.is_paid, div.is_paid {
47
+ background-color: #AFA;
48
+ }
49
+ tr.is_open, div.is_open {
50
+ background-color: #FFA;
51
+ }
52
+ tr.is_trash, div.is_trash {
53
+ background-color: #DADADA;
54
+ }
55
+ a {
56
+ text-decoration: none;
57
+ color: #40A;
58
+ }
59
+ div#subnavigation {
60
+ float: right;
61
+ }
62
+ div#subnavigation a, div#navigation a {
63
+ padding: 0px 4px;
64
+ border-left: thin solid #306;
65
+ }
66
+ div#subnavigation > a:first-child, div#navigation > a:first-child {
67
+ border-left: 0px;
68
+ }
69
+ input.extralarge {
70
+ width: 500px;
71
+ }
72
+ input.large {
73
+ width: 240px;
74
+ }
75
+ input.medium {
76
+ width: 120px;
77
+ }
78
+ input.small {
79
+ width: 60px;
80
+ }
81
+ div#confirm {
82
+ font-weight: bold;
83
+ font-size: 14px;
84
+ padding: 8px;
85
+ }
86
+ div.head {
87
+ border-color: #A00;
88
+ border-style: solid;
89
+ border-width: thin 0px 0px thin;
90
+ background-color: #F88;
91
+ padding: 4px 0px;
92
+ min-height: 15px;
93
+ }
94
+ div.foot {
95
+ background-color: #F88;
96
+ padding: 4px;
97
+ border-color: #A00;
98
+ border-style: solid;
99
+ border-width: 0px thin thin 0px;
100
+ }
101
+ div.padded {
102
+ padding: 4px;
103
+ }
104
+ td.right {
105
+ text-align: right;
106
+ }
107
+ span#total_brutto {
108
+ font-weight: bold;
109
+ }
110
+ span#version {
111
+ display: inline;
112
+ float: right;
113
+ }
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # Html -- ydim -- 14.12.2006 -- hwyss@ywesee.com
4
+ module YDIM
5
+ module Html
6
+ class << self
7
+ attr_accessor :config, :logger
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'rclconf'
5
+ require 'ydim/html'
6
+
7
+ module YDIM
8
+ module Html
9
+ ydim_default_dir = '/var/ydim/'
10
+ if(home = ENV['HOME'])
11
+ ydim_default_dir = File.join(home, '.ydim')
12
+ end
13
+ default_config_files = [
14
+ 'etc/ydim-htmld.yml',
15
+ File.join(ydim_default_dir, 'ydim-htmld.yml'),
16
+ '/etc/ydim/ydim-htmld.yml',
17
+ ]
18
+ defaults = {
19
+ 'client_url' => 'druby://localhost:0',
20
+ 'config' => default_config_files,
21
+ 'currency' => 'CHF',
22
+ 'email' => nil,
23
+ 'html_url' => 'druby://localhost:12376',
24
+ 'http_server' => 'http://localhost',
25
+ 'log_file' => $stdout,
26
+ 'log_level' => 'DEBUG',
27
+ 'md5_pass' => nil,
28
+ 'proxy_url' => 'druby://localhost:0',
29
+ 'server_url' => 'druby://localhost:12375',
30
+ 'root_key' => nil,
31
+ 'user' => nil,
32
+ 'ydim_dir' => ydim_default_dir,
33
+ }
34
+ @config = RCLConf::RCLConf.new(ARGV, defaults)
35
+ @config.load(@config.config)
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # Html::State::AjaxValues -- ydim -- 18.01.2006 -- hwyss@ywesee.com
4
+
5
+ require 'sbsm/state'
6
+ require 'ydim/html/view/ajax_values'
7
+
8
+ module YDIM
9
+ module Html
10
+ module State
11
+ class AjaxValues < SBSM::State
12
+ VOLATILE = true
13
+ VIEW = Html::View::AjaxValues
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # Html::State::AutoInvoice -- ydim -- 13.12.2006 -- hwyss@ywesee.com
4
+
5
+ require 'ydim/html/state/invoice'
6
+ require 'ydim/html/view/autoinvoice'
7
+
8
+ module YDIM
9
+ module Html
10
+ module State
11
+ class AjaxAutoInvoice < SBSM::State
12
+ VOLATILE = true
13
+ VIEW = Html::View::AutoInvoiceComposite
14
+ end
15
+ module AutoInvoiceKeys
16
+ def invoice_key
17
+ :autoinvoice
18
+ end
19
+ def invoice_keys
20
+ super + [ :date, :reminder_body, :reminder_subject ]
21
+ end
22
+ def invoice_mandatory
23
+ [ :description, :currency, :invoice_interval ]
24
+ end
25
+ end
26
+ class CreateAutoInvoice < CreateInvoice
27
+ include AutoInvoiceKeys
28
+ VIEW = Html::View::AutoInvoice
29
+ def update
30
+ _update(AutoInvoice)
31
+ end
32
+ end
33
+ class AutoInvoice < Invoice
34
+ include AutoInvoiceKeys
35
+ VIEW = Html::View::AutoInvoice
36
+ def ajax_invoice
37
+ _do_update
38
+ AjaxAutoInvoice.new(@session, @model)
39
+ end
40
+ def format_invoice
41
+ lnf = @session.lookandfeel
42
+ total = lnf.lookup(:total_netto)
43
+ item_widths = [total.length]
44
+ qty_widths = []
45
+ float = false
46
+ @model.items.each do |item|
47
+ item_widths.push item.text.length
48
+ qty = item.quantity
49
+ qty_widths.push qty.to_i.to_s.length
50
+ float ||= (qty.to_i != qty.to_f)
51
+ end
52
+ item_width = item_widths.max.to_i.next
53
+ qty_width = qty_widths.max.to_i
54
+ total_width = ("%3.2f" % @model.total_netto).length
55
+ fmt = if float
56
+ qty_width += 3
57
+ "%#{qty_width}.2f x %-#{item_width}s %s %#{total_width}.2f\n"
58
+ else
59
+ "%#{qty_width}i x %-#{item_width}s %s %#{total_width}.2f\n"
60
+ end
61
+ invoice = "<invoice>\n"
62
+ currency = @model.currency
63
+ @model.items.each { |item|
64
+ invoice << sprintf(fmt, item.quantity.to_f, item.text,
65
+ currency, item.total_netto)
66
+ }
67
+ fmt = "%#{qty_width + 2}s %-#{item_width}s %s %#{total_width}.2f\n"
68
+ invoice << sprintf(fmt, '', total,
69
+ currency, @model.total_netto)
70
+ invoice << "</invoice>"
71
+ end
72
+ def generate_invoice
73
+ _do_update
74
+ if((id = @session.user_input(:unique_id)) \
75
+ && @model.unique_id == id.to_i)
76
+ Invoice.new(@session, @session.generate_invoice(id))
77
+ end
78
+ end
79
+ def _do_update_invoice(input)
80
+ ptrn = %r{<invoice>.*</invoice>}m
81
+ if(body = input[:reminder_body])
82
+ test = body.gsub(ptrn, "").strip
83
+ if(test.empty?)
84
+ input.store(:reminder_body, nil)
85
+ else
86
+ input.store(:reminder_body, body.gsub(ptrn, format_invoice))
87
+ end
88
+ end
89
+ super(input)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # Html::State::Confirm -- ydim -- 18.01.2006 -- hwyss@ywesee.com
4
+
5
+ require 'ydim/html/state/global_predefine'
6
+ require 'ydim/html/view/confirm'
7
+
8
+ module YDIM
9
+ module Html
10
+ module State
11
+ class Confirm < Global
12
+ VIEW = Html::View::Confirm
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # Html::State::Debitor -- ydim -- 12.01.2006 -- hwyss@ywesee.com
4
+
5
+ require 'ydim/html/state/global_predefine'
6
+ require 'ydim/html/state/ajax_values'
7
+ require 'ydim/html/state/invoices'
8
+ require 'ydim/html/view/debitor'
9
+
10
+ module YDIM
11
+ module Html
12
+ module State
13
+ class AjaxAutoInvoices < SBSM::State
14
+ VOLATILE = true
15
+ VIEW = Html::View::AutoInvoiceList
16
+ end
17
+ class Debitor < Global
18
+ include AjaxInvoiceMethods
19
+ attr_reader :model, :autoinvoice_infos, :invoice_infos
20
+ VIEW = Html::View::Debitor
21
+ def init
22
+ super
23
+ load_autoinvoices
24
+ load_invoices
25
+ end
26
+ def ajax_collect_garbage
27
+ @session.collect_garbage(@model.unique_id)
28
+ AjaxInvoices.new(@session, [])
29
+ end
30
+ def ajax_delete_autoinvoice
31
+ if(id = @session.user_input(:unique_id))
32
+ @session.delete_autoinvoice(id)
33
+ end
34
+ AjaxAutoInvoices.new(@session, load_autoinvoices)
35
+ end
36
+ def ajax_invoices
37
+ super(@invoice_infos)
38
+ end
39
+ def generate_invoice
40
+ if(id = @session.user_input(:unique_id))
41
+ Invoice.new(@session, @session.generate_invoice(id.to_i))
42
+ end
43
+ end
44
+ def update
45
+ mandatory = [ :contact, :debitor_type, :emails,
46
+ :location, :name, ]
47
+ defaults = {}
48
+ keys = mandatory.dup.push(:address_lines, :contact_firstname,
49
+ :contact_title, :country, :salutation, :phone)
50
+ input = defaults.update(user_input(keys, mandatory))
51
+ mails = input[:emails]
52
+ if mails && mails.size > 3
53
+ @errors.store :emails, create_error('e_too_many_emails',
54
+ :emails, mails.join(', '))
55
+ input[:emails] = mails[0,3]
56
+ end
57
+ unless(error? || @model.unique_id)
58
+ @model = @session.create_debitor
59
+ end
60
+ update_model(input)
61
+ self
62
+ end
63
+ private
64
+ def load_autoinvoices
65
+ invoices = @model.autoinvoice_infos
66
+ @autoinvoice_infos = sort_invoices(currency_convert(invoices))
67
+ end
68
+ def load_invoices
69
+ invoices = @model.invoice_infos(@session.user_input(:status) \
70
+ || 'is_open')
71
+ @invoice_infos = sort_invoices(currency_convert(invoices))
72
+ end
73
+ def update_model(input)
74
+ input.each { |key, val|
75
+ @model.send("#{key}=".to_sym, val)
76
+ }
77
+ @model.odba_store if(@model.unique_id)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end