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,69 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::State::Invoices -- ydim -- 13.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/state/global_predefine'
5
+ require 'ydim/html/view/invoices'
6
+
7
+ module YDIM
8
+ module Html
9
+ module State
10
+ class AjaxInvoices < SBSM::State
11
+ VOLATILE = true
12
+ VIEW = Html::View::InvoiceList
13
+ end
14
+ module AjaxInvoiceMethods
15
+ def ajax_invoices(model=@model)
16
+ keys = [:payment_received, :unique_id, :deleted]
17
+ input = user_input(keys, [:unique_id])
18
+ id = input.delete(:unique_id).to_i
19
+ if(!error? && !input.empty? && (invoice = @session.invoice(id)))
20
+ input.each { |key, val|
21
+ invoice.send("#{key}=", val)
22
+ }
23
+ invoice.odba_store
24
+ model.delete_if { |info| info.unique_id == id }
25
+ end
26
+ AjaxInvoices.new(@session, model)
27
+ end
28
+ def ajax_status
29
+ AjaxInvoices.new(@session, load_invoices)
30
+ end
31
+ def currency_convert(invoices)
32
+ currency = Html.config.currency
33
+ converter = @session.currency_converter
34
+ invoices.each { |inv|
35
+ if(icur = inv.currency)
36
+ inv.total_netto = converter.convert(inv.total_netto, icur, currency)
37
+ inv.total_brutto = converter.convert(inv.total_brutto, icur, currency)
38
+ end
39
+ inv.currency = currency
40
+ }
41
+ end
42
+ def sort_invoices(invoices)
43
+ null_date = Date.new(9999)
44
+ invoices.sort_by { |inv|
45
+ [null_date - (inv.date || null_date), inv.description.to_s]
46
+ }
47
+ end
48
+ end
49
+ class Invoices < Global
50
+ include AjaxInvoiceMethods
51
+ VIEW = Html::View::Invoices
52
+ def init
53
+ super
54
+ invs = @session.invoice_infos('is_open')
55
+ invs.concat @session.invoice_infos('is_due')
56
+ @model = sort_invoices(currency_convert(invs))
57
+ end
58
+ def ajax_collect_garbage
59
+ @session.collect_garbage
60
+ AjaxInvoices.new(@session, [])
61
+ end
62
+ private
63
+ def load_invoices
64
+ @model = sort_invoices(currency_convert(@session.invoices))
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::State::Pdf -- ydim -- 17.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/pdf'
5
+
6
+ module YDIM
7
+ module Html
8
+ module State
9
+ class Pdf < SBSM::State
10
+ VOLATILE = true
11
+ VIEW = Html::View::Pdf
12
+ attr_accessor :sortby, :sort_reverse
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Custom::Lookandfeel -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/lookandfeel'
5
+
6
+ module YDIM
7
+ module Html
8
+ module Custom
9
+ class Lookandfeel < SBSM::Lookandfeel
10
+ DICTIONARIES = {
11
+ 'de' => {
12
+ :address_lines => 'Strasse/Nr.',
13
+ :autoinvoices => 'Vorlagen',
14
+ :CHF => 'CHF',
15
+ :collect_garbage => 'Papierkorb Leeren',
16
+ :comma => ', ',
17
+ :confirm_send_invoice0 => 'Die Rechnung wurde an folgende Email-Adressen verschickt: ',
18
+ :confirm_send_invoice1 => '.',
19
+ :contact => 'Name',
20
+ :contact_firstname => 'Vorname',
21
+ :contact_title => 'Titel',
22
+ :country => 'Land',
23
+ :cpr_link => ' ywesee GmbH',
24
+ :create_debitor => 'Neuer Kunde',
25
+ :create_autoinvoice => 'Neue Vorlage',
26
+ :create_invoice => 'Neue Rechnung',
27
+ :create_item => 'Neue Position',
28
+ :currency => 'W&auml;hrung',
29
+ :dash => '&nbsp;&ndash;&nbsp;',
30
+ :date => 'Rechnungsdatum',
31
+ :date_format => '%d.%m.%Y',
32
+ :debitors => 'Kunden',
33
+ :debitor_name => 'Kunde',
34
+ :debitor_type => 'Kundenart',
35
+ :delete => 'L�schen',
36
+ :description => 'Beschreibung',
37
+ :dt_consulting => 'Beratung',
38
+ :dt_doctor => 'Arzt',
39
+ :dt_health => 'Gesundheitsdienstleister',
40
+ :dt_hospital => 'Spital',
41
+ :dt_hosting => 'Hosting-Kunde',
42
+ :dt_info => 'ODDB.org-User',
43
+ :dt_insurance => 'Krankenkasse',
44
+ :dt_pharma => 'Pharma-Firma',
45
+ :dt_pharmacy => 'Apotheke',
46
+ :e_domainless_email_address => 'Wir akzeptieren keine lokalen Email-Adressen.',
47
+ :e_invalid_email_address => 'Die angegebene Email-Adresse ist ung�ltig.',
48
+ :e_invalid_numeric_format => 'Ung�ltiges Zahlenformat',
49
+ :e_invalid_phone => 'Die angegebene Telefonnummer ist ung�ltig.',
50
+ :e_too_many_emails => 'Es sind maximal 3 Email-Adressen erlaubt.',
51
+ :email => 'Email',
52
+ :emails => 'Email (max. 3)',
53
+ :e_bygone_date => 'Bitte geben Sie ein Datum an, welches in der Zukuft liegt.',
54
+ :e_missing0 => 'Bitte geben Sie das Feld "',
55
+ :e_missing1 => '" an.',
56
+ :EUR => 'EUR',
57
+ :Frau => 'Frau',
58
+ :generate_invoice => 'Generieren',
59
+ :Herr => 'Herr',
60
+ :html_title => 'YDIM',
61
+ :invoice_interval => 'Rechnungs-Intervall',
62
+ :inv_m => 'Nur Manuell',
63
+ :inv_3 => 'Viertelj�hrlich',
64
+ :inv_6 => 'Halbj�hrlich',
65
+ :inv_12 => 'J�hrlich',
66
+ :inv_24 => 'Alle zwei Jahre',
67
+ :invoices => 'Rechnungen',
68
+ :is_due => 'F&auml;llige Rechnungen',
69
+ :is_open => 'Offene Rechnungen',
70
+ :is_paid => 'Bezahlte Rechnungen',
71
+ :is_trash => 'Papierkorb',
72
+ :lgpl_license => 'LGPL',
73
+ :location => 'PLZ/Ort',
74
+ :login => 'Login',
75
+ :logout => 'Logout',
76
+ :name => 'Firma',
77
+ :pass => 'Passwort',
78
+ :payment_period0 => ' Zahlbar in ',
79
+ :payment_period1 => ' Tagen',
80
+ :pdf => 'PDF',
81
+ :phone => 'Telefon',
82
+ :precision => 'Kommastellen',
83
+ :reminder_body => 'Erinnerungsmail Text',
84
+ :reminder_date => 'Wird am %d.%m.%Y versendet',
85
+ :reminder_none => 'Es wird kein Erinnerungsmail versendet',
86
+ :reminder_subject => 'Erinnerungsmail Betreff',
87
+ :salutation => 'Anrede',
88
+ :send_invoice => 'Email Senden',
89
+ :suppress_vat => 'OHNE MwSt.',
90
+ :th_currency => 'W&auml;hrung',
91
+ :th_debitor_email => 'Email',
92
+ :th_debitor_name => 'Name',
93
+ :th_debitor_type => 'Kundenart',
94
+ :th_description => 'Beschreibung',
95
+ :th_domain => 'Domain',
96
+ :th_email => 'Email',
97
+ :th_formatted_date => 'Datum',
98
+ :th_name => 'Name',
99
+ :th_next_invoice_date => 'N�chste Rechnung',
100
+ :th_phone => 'Telefon',
101
+ :th_price => 'Preis',
102
+ :th_quantity => 'Anzahl',
103
+ :th_text => 'Positionstext',
104
+ :th_time => 'Zeit',
105
+ :th_toggle_payment_received => 'Status',
106
+ :th_total_brutto => 'Brutto',
107
+ :th_total_netto => 'Netto',
108
+ :th_unique_id => 'ID',
109
+ :th_unit => 'Einheit',
110
+ :time_format => '%d.%m.%Y %H:%M',
111
+ :toggle_deleted => 'l�schen',
112
+ :toggle_paid => 'offen',
113
+ :toggle_recovered => 'wiederherstellen',
114
+ :toggle_unpaid => 'bezahlt',
115
+ :total => 'Total',
116
+ :total_brutto => 'Total Brutto',
117
+ :total_netto => 'Total Netto',
118
+ :unique_id => 'ID',
119
+ :update => 'Speichern',
120
+ :vat => 'MwSt. (7.6%)',
121
+ :ydim => 'YDIM',
122
+ :ydim_version => 'Commit-ID',
123
+ },
124
+ }
125
+ RESOURCES = {
126
+ :css => 'ydim.css',
127
+ :javascript => 'javascript',
128
+ }
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::Server -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'openssl'
5
+ require 'sbsm/drbserver'
6
+ require 'ydim/html/util/session'
7
+ require 'ydim/html/util/validator'
8
+ require 'ydim/client'
9
+
10
+ module YDIM
11
+ module Html
12
+ module Util
13
+ class Server < SBSM::DRbServer
14
+ SESSION = Html::Util::Session
15
+ VALIDATOR = Html::Util::Validator
16
+ def initialize(server)
17
+ @server = server
18
+ @private_key = OpenSSL::PKey::DSA.new(File.read(Html.config.root_key))
19
+ @system = YDIM::Client.new(Html.config)
20
+ super(@system)
21
+ end
22
+ def login(email, pass_hash)
23
+ (email == Html.config.email) && (pass_hash == Html.config.md5_pass)
24
+ end
25
+ def method_missing(meth, *args)
26
+ @system.login(@server, @private_key)
27
+ begin
28
+ @system.send(meth, *args)
29
+ ensure
30
+ @system.logout
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::Session -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/session'
5
+ require 'ydim/html/state/global'
6
+ require 'ydim/html/util/lookandfeel'
7
+
8
+ module YDIM
9
+ module Html
10
+ module Util
11
+ class Session < SBSM::Session
12
+ DEFAULT_LANGUAGE = 'de'
13
+ DEFAULT_STATE = Html::State::Init
14
+ LOOKANDFEEL = Html::Custom::Lookandfeel
15
+ def login
16
+ @app.login(user_input(:email), user_input(:pass))
17
+ end
18
+ def invoices
19
+ @app.invoice_infos(user_input(:status) || 'is_open')
20
+ end
21
+ def method_missing(meth, *args)
22
+ @app.send(meth, *args)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::Validator -- ydim -- 12.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/validator'
5
+
6
+ module YDIM
7
+ module Html
8
+ module Util
9
+ class Validator < SBSM::Validator
10
+ BOOLEAN = [:payment_received, :deleted, :suppress_vat]
11
+ DATES = [:date, :hosting_invoice_date]
12
+ ALLOWED_TAGS = %{a b br div font h1 h2 h3 i img invoice li ol p pre span
13
+ strong u ul year}
14
+ ENUMS = {
15
+ :currency => [ 'CHF', 'EUR', ],
16
+ :debitor_type => [ nil, 'dt_hosting', 'dt_pharmacy', 'dt_pharma',
17
+ 'dt_insurance', 'dt_info', 'dt_hospital', 'dt_health', 'dt_doctor',
18
+ 'dt_consulting' ],
19
+ :invoice_interval => [ 'inv_12', 'inv_6', 'inv_3', 'inv_24', 'inv_m', ],
20
+ :salutation => [ nil, 'Frau', 'Herr', ],
21
+ :status => [ nil, 'is_open', 'is_due', 'is_paid', 'is_trash'],
22
+ }
23
+ EVENTS = [ :ajax_collect_garbage, :ajax_create_item, :ajax_debitor,
24
+ :ajax_delete_autoinvoice, :ajax_delete_item, :ajax_item,
25
+ :ajax_invoice, :ajax_invoices, :ajax_status, :autoinvoice,
26
+ :create_autoinvoice, :create_debitor, :create_invoice, :debitor,
27
+ :debitors, :generate_invoice, :invoice, :invoices, :login, :logout,
28
+ :pdf, :send_invoice, :sort, :update ]
29
+ STRINGS = [ :name, :contact, :contact_firstname, :contact_title,
30
+ :country, :description, :location, :sortvalue, :text, :unit ]
31
+ NUMERIC = [ :unique_id, :hosting_price, :index, :precision, :price,
32
+ :quantity ]
33
+ HTML = [ :reminder_body, :reminder_subject ]
34
+ def address_lines(value)
35
+ validate_string(value).split(/\r|\n|\r\n/)
36
+ end
37
+ def emails(value)
38
+ value.to_s.split(/\s*,\s*/).collect do |val| email(val) end
39
+ rescue SBSM::InvalidDataError => err
40
+ raise SBSM::InvalidDataError.new(err.message, :emails, value)
41
+ end
42
+ def phone(value)
43
+ str = value.to_s.strip
44
+ return if(str.empty?)
45
+ if(/^00[0-9 ]{10,}$/.match(str))
46
+ str
47
+ else
48
+ raise SBSM::InvalidDataError.new(:e_invalid_phone, :phone, str)
49
+ end
50
+ end
51
+ def validate_numeric(key, value)
52
+ match = /-?\d*(\.\d{1,2})?/.match(value)
53
+ if(match[1])
54
+ match[0].to_f
55
+ else
56
+ match[0].to_i
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::AjaxValues -- ydim -- 18.01.2006 -- hwyss@ywesee.com
3
+
4
+ require 'htmlgrid/component'
5
+ require 'cgi'
6
+
7
+ module YDIM
8
+ module Html
9
+ module View
10
+ class AjaxValues < HtmlGrid::Component
11
+ HTTP_HEADERS = {
12
+ 'Content-Type' => 'text/javascript; charset=ISO-8859-1',
13
+ }
14
+ def to_html(context)
15
+ "var ajaxResponse = {\n" << @model.collect { |key, val|
16
+ "'#{escape(key)}': '#{escape(val)}'"
17
+ }.join(",\n") << "\n};"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::AutoInvoice -- ydim -- 13.12.2006 -- hwyss@ywesee.com
3
+
4
+ require 'ydim/html/view/invoice'
5
+
6
+ module YDIM
7
+ module Html
8
+ module View
9
+ class AutoInvoiceInnerComposite < InvoiceInnerComposite
10
+ COMPONENTS = {
11
+ [0,0] => :unique_id,
12
+ [0,1,0] => :debitor_name,
13
+ [1,1,1] => 'dash',
14
+ [1,1,2] => :debitor_email,
15
+ [0,2] => :description,
16
+ [0,3] => :date,
17
+ [0,4] => :currency,
18
+ [0,5] => :precision,
19
+ [0,6] => :invoice_interval,
20
+ }
21
+ end
22
+ class AutoInvoiceReminderComposite < HtmlGrid::Composite
23
+ COMPONENTS = {
24
+ [0,0] => :reminder_subject,
25
+ [0,1] => :reminder_body,
26
+ [1,2] => :reminder_date,
27
+ }
28
+ CSS_MAP = {
29
+ [0,1] => 'top',
30
+ }
31
+ COMPONENT_CSS_MAP = {
32
+ [0,0] => 'extralarge',
33
+ }
34
+ LABELS = true
35
+ def reminder_body(model)
36
+ input = HtmlGrid::Textarea.new(:reminder_body, model, @session, self)
37
+ input.set_attribute('wrap', 'hard')
38
+ input.set_attribute('cols', '72')
39
+ input.set_attribute('style', 'font-family: fixed;')
40
+ input.label = true
41
+ input.unescaped = true
42
+ value = model.reminder_body
43
+ if(value.nil? || value.empty?)
44
+ input.value = @session.state.format_invoice
45
+ end
46
+ input
47
+ end
48
+ def reminder_date(model)
49
+ body = model.reminder_body.to_s.strip
50
+ subject = model.reminder_subject.to_s.strip
51
+ if(body.empty? || subject.empty? || !model.date)
52
+ @lookandfeel.lookup(:reminder_none)
53
+ else
54
+ (model.date << 1).strftime(@lookandfeel.lookup(:reminder_date))
55
+ end
56
+ end
57
+ end
58
+ class AutoInvoiceComposite < InvoiceComposite
59
+ COMPONENTS = {
60
+ [0,0] => AutoInvoiceInnerComposite,
61
+ [0,1] => :items,
62
+ [0,2] => InvoiceTotalComposite,
63
+ [0,3] => AutoInvoiceReminderComposite,
64
+ [0,4] => :submit,
65
+ [1,4] => :generate_invoice,
66
+ }
67
+ CSS_MAP = {
68
+ 4 => 'padded'
69
+ }
70
+ def generate_invoice(model)
71
+ button(:generate_invoice, model)
72
+ end
73
+ end
74
+ class AutoInvoice < Invoice
75
+ CONTENT = AutoInvoiceComposite
76
+ end
77
+ end
78
+ end
79
+ end