InsuranceBizLogic 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,187 @@
1
+ # Copyright (c) 2007-2008 Orangery Technology Limited
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ module VPMSHelper
5
+ include REXML
6
+
7
+ def mergeIntoXMLDoc(xml,premiums)
8
+ doc = Document.new(xml)
9
+ #premiums is a named value pair array
10
+ premiums.each do |singleResult|
11
+ value = singleResult.pop
12
+ path = Array.new
13
+ insertionNode = nil
14
+ found_where_to_insert = false
15
+ singleResult.each do |a|
16
+ path.push("/#{a}")
17
+ nodes = XPath.match(doc,"/#{path}")
18
+ if (a != singleResult.last)
19
+ if nodes.length <= 0
20
+ path.pop
21
+ insertionNode = XPath.first(doc,"/#{path}")
22
+ insertionNode.insert_after insertionNode,Element.new(a)
23
+ path.push("/#{a}")
24
+ insertionNode = XPath.first(doc,"/#{path}")
25
+ elsif (nodes.length == 1)
26
+ insertionNode = nodes[0]
27
+ end
28
+ else
29
+ if nodes.length > 0
30
+ #leaf node already there and maybe with an old value from previous page
31
+ else
32
+ path.pop
33
+ e = Element.new(a)
34
+ e.text = value
35
+ insertionNode.insert_after insertionNode,e
36
+ end
37
+ end
38
+ end
39
+ end
40
+ doc.to_s
41
+ end
42
+
43
+ def parseVPMSresponse(response,product)
44
+ @premiums = Array.new
45
+ doc = Document.new(response)
46
+ nodes = XPath.match(doc,"//multiRef[returnCode=0]")
47
+ nodes.each do |node|
48
+ extractPremiums(node,product)
49
+ end
50
+ #display any VPMS issues
51
+ #probably won't result in runtime issue since IAB currently asks for more than VPMS will understand
52
+ #because VPMS schema built on product view of library and VPMS message is built from full library def of coverage
53
+ #at the mo
54
+ nodes = XPath.match(doc,"//multiRef[returnCode!=0]")
55
+ nodes.each do |node|
56
+ viewPremiumComputeErrors(node,product)
57
+ end
58
+ end
59
+
60
+ def viewPremiumComputeErrors(node,product) #:nodoc
61
+ value = ""
62
+ node.each_child do |child|
63
+ case child.node_type
64
+ when :element
65
+ key, value = child.expanded_name, extractPremiums(child,product)
66
+ #put out 'error' message text
67
+ puts "#{value}" if key == "message"
68
+ when :text
69
+ key, value = '$', unescape(child.to_s).strip
70
+ end
71
+ end
72
+ value
73
+ end
74
+
75
+ def extractPremiums(node,product) #:nodoc
76
+ #vpms will return the following nodes of interest
77
+ #message, name, reffield, returncode, value
78
+ #like this
79
+ #key=message,value=
80
+ #key=name,value=F_CommercialProperty_#{product}_ContentsCover_CoverDetail_PremiumQuoteBreakdown_GrossAmount
81
+ #key=refField,value=
82
+ #key=returnCode,value=0
83
+ #key=value,value=125.55
84
+ value = ""
85
+ node.each_child do |child|
86
+ case child.node_type
87
+ when :element
88
+ key, value = child.expanded_name, extractPremiums(child,product)
89
+ @premiums.push(value.gsub("F_CommercialProperty_","").gsub('CommercialProperty',product).split("_")) if (key == "name")
90
+ if (key == "value")
91
+ name = @premiums.pop
92
+ name.push(value)
93
+ @premiums.push(name)
94
+ end
95
+ when :text
96
+ key, value = '$', unescape(child.to_s).strip
97
+ end
98
+ end
99
+ value
100
+ end
101
+
102
+ def callVPMS(nvpxml)
103
+ headers = {
104
+ 'Content-Type' => 'text/xml',
105
+ 'SoapAction' => ""
106
+ }
107
+ Net::HTTP.start(APP_CONFIG['vpms_ip'], 8080) do |http|
108
+ response = http.post('/jvpms/services/ProductRequestProcessor',nvpxml,headers)
109
+ response.body
110
+ end
111
+ end
112
+
113
+ def buildVPMSMessage(product,package,brand,params)
114
+ @instructionBlock = ""
115
+
116
+ nvpxml = '<?xml version="1.0" encoding="utf-8"?>
117
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
118
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
119
+ xmlns:tns="http://com/csc/dip/webservice/core/"
120
+ xmlns:types="http://com/csc/dip/webservice/core/encodedTypes"
121
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
122
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
123
+ xmlns:q1="http://core.webservice.dip.csc.com">
124
+ <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
125
+ <tns:process>
126
+ <in0 href="#id1"/>
127
+ </tns:process>
128
+ <soapenc:Array id="id1" soapenc:arrayType="q1:ProductRequest[1]">
129
+ <Item href="#id3"/>
130
+ </soapenc:Array>
131
+ <q1:ProductRequest id="id3" xsi:type="q1:ProductRequest">
132
+ <productName xsi:type="xsd:string">CommercialPropertyProduct</productName>
133
+ <store xsi:type="xsd:boolean">false</store>
134
+ <traceMode xsi:type="xsd:boolean">false</traceMode>
135
+ <useUI xsi:type="xsd:boolean">false</useUI>
136
+ <actions href="#id5"/>
137
+ </q1:ProductRequest>'
138
+
139
+ @id=7
140
+ @instructionBlock << "<Item href=\"#id#{@id += 1}\"/>"
141
+ nvpxml << "<q1:SetAction id=\"id#{@id}\" xsi:type=\"q1:SetAction\">
142
+ <useUI xsi:type=\"xsd:boolean\">false</useUI>
143
+ <name xsi:type=\"xsd:string\">A_CommercialProperty_#{package}_Brand</name>
144
+ <value xsi:type=\"xsd:string\">#{brand}</value>
145
+ </q1:SetAction>"
146
+ @instructionBlock << "<Item href=\"#id#{@id += 1}\"/>"
147
+ nvpxml << "<q1:SetAction id=\"id#{@id}\" xsi:type=\"q1:SetAction\">
148
+ <useUI xsi:type=\"xsd:boolean\">false</useUI>
149
+ <name xsi:type=\"xsd:string\">A_CommercialProperty_#{package}_Package</name>
150
+ <value xsi:type=\"xsd:string\">#{product}</value>
151
+ </q1:SetAction>"
152
+
153
+
154
+ nvpxml << createXMLMessage(product,params,true) do |k,v|
155
+
156
+ @instructionBlock << "<Item href=\"#id#{@id += 1}\"/>"
157
+
158
+ "<q1:SetAction id=\"id#{@id}\" xsi:type=\"q1:SetAction\">
159
+ <useUI xsi:type=\"xsd:boolean\">false</useUI>
160
+ <name xsi:type=\"xsd:string\">A_CommercialProperty_#{package}_#{k}</name>
161
+ <value xsi:type=\"xsd:string\">#{v}</value>
162
+ </q1:SetAction>"
163
+ end
164
+
165
+ nvpxml << deriveComputes(package)
166
+ @instructionBlock << "<Item href=\"#id#{@id}\"/>"
167
+
168
+ nvpxml << "<soapenc:Array id=\"id5\" soapenc:arrayType=\"q1:VpmsAction[1]\">
169
+ #{@instructionBlock}
170
+ </soapenc:Array>"
171
+
172
+ nvpxml << "</soap:Body></soap:Envelope>"
173
+ nvpxml
174
+ end
175
+
176
+ def deriveComputes(package)
177
+ nvpxml = ""
178
+ @pqbNodes.each do |n|
179
+ nvpxml << "<q1:ComputeAction id=\"id#{@id += 1}\" xsi:type=\"q1:ComputeAction\">
180
+ <useUI xsi:type=\"xsd:boolean\">false</useUI>
181
+ <name xsi:type=\"xsd:string\">F_CommercialProperty_#{package}_#{n}</name>
182
+ </q1:ComputeAction>"
183
+ @instructionBlock << "<Item href=\"#id#{@id}\"/>"
184
+ end
185
+ nvpxml
186
+ end
187
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2007-2008 Orangery Technology Limited
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ module ApplyMTA
5
+ def applyMTA(startDateTime,endDateTime,policyKey,origImage,newImage)
6
+ appliedDateTime = Time.now.strftime('%Y-%m-%d') #TODO: add time into this
7
+ appliedDateTimeEpoch = Time.now.to_i
8
+
9
+ xmldiff = determineDiff(origImage,newImage)
10
+
11
+ doc = REXML::Document.new xmldiff
12
+
13
+ #remove the diff records of no interest to us
14
+ doc.elements.delete_all('//xupdate:append')
15
+ doc.elements.delete_all('//xupdate:remove')
16
+ doc.elements.delete_all('//xupdate:insert-after')
17
+ doc.elements.delete_all('//xupdate:insert-before')
18
+ doc.elements.delete_all('//xupdate:rename')
19
+
20
+ #the reduced doc
21
+ #puts doc.to_s
22
+
23
+ persist = Persist.instance
24
+ #add the MTA diff doc to the data store
25
+ key = persist.put('UUID',doc.to_s)
26
+ #puts "MTA diff doc key is #{key}"
27
+
28
+ #get the doc that holds the relationship between the policy and
29
+ #any MTA diff docs
30
+ #if it does not exist then get! will create it
31
+ mtas = persist.get!("#{policyKey}MTAS","<MTAS></MTAS>")
32
+ doc = REXML::Document.new mtas
33
+ mtasNode = REXML::XPath.first(doc, '//MTAS')
34
+
35
+ #check to see if any MTAs exist that start later than this one
36
+ #if so mark them as rolled back and store them in a
37
+ #reapply->hash
38
+ reapply = []
39
+
40
+ elems = doc.root.get_elements('//MTAS/MTA[@startDateTime]')
41
+ sorted = elems.map { |s| s.attributes["startDateTime"].to_s}.sort
42
+ #puts "This new MTA starting on #{startDateTime} yields out-of-sequence node(s):"
43
+ count = 0
44
+ sorted.each do |sd|
45
+ if (sd > startDateTime)
46
+ #roll these back
47
+ xpath = '//MTAS/MTA[@startDateTime = '+'"'+sd+'"]'
48
+ node = REXML::XPath.first(doc, xpath)
49
+ #puts node
50
+ #put into reapply-array providing of course not already rolled back
51
+ rb = node.attributes["rolledBack"]
52
+ if (rb != "true") then
53
+ reapply[count] = node.deep_clone
54
+ count = count + 1
55
+ #set current node to rolledBack
56
+ node.attributes["rolledBack"] = true
57
+ end
58
+ end
59
+ end
60
+ #puts "No nodes qualified." unless count > 0
61
+ #puts "\n"
62
+
63
+ #get first node and add element with meta data relating to the MTA diff doc added above
64
+ #meta data includes the key of the diff doc
65
+ mtasNode.add_element('MTA',{'key' => key , 'appliedDateTimeEpoch' => appliedDateTimeEpoch, 'appliedDateTime' => appliedDateTime, 'startDateTime' => startDateTime, 'endDateTime' => endDateTime, 'rolledBack' => false})
66
+
67
+ #check the reapply->array
68
+ #create new entries for any in the reapply->hash with new appliedDateTime attribute values appliedDateTime = Time.now.strftime('%Y-%m-%d') #TODO: add time into this
69
+ reapply.each do |n|
70
+ appliedDateTimeEpoch = appliedDateTimeEpoch + 1
71
+ n.attributes["appliedDateTime"] = appliedDateTime
72
+ n.attributes["appliedDateTimeEpoch"] = appliedDateTimeEpoch
73
+ n.attributes["rolledBack"] = false
74
+ mtasNode.add_element(n)
75
+ end
76
+ #puts "Final state of MTA meta data doc:"+doc.to_s
77
+
78
+ mtaKey = persist.put("#{policyKey}MTAS",doc.to_s)
79
+ #puts "MTAS key is still:#{mtaKey}"
80
+ doc.to_s
81
+ end
82
+ end
@@ -0,0 +1,8 @@
1
+ module RefineQuote
2
+ def integrateData(session,origData,newData)
3
+ #this piece of logica takes two xml documents that need to be merge, there will be new nodes
4
+ #and overlapping nodes as question answers for the quote are made available
5
+ result = origData.gsub("</#{session[:product]}>","")+newData.gsub("<#{session[:product]}>","")
6
+ result
7
+ end
8
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright (c) 2007-2008 Orangery Technology Limited
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+
5
+ module XMLDiff
6
+ def runCommand(cmd, inp='')
7
+ IO.popen(cmd, 'r+') do |io|
8
+ begin
9
+ io.write inp
10
+ io.close_write
11
+ return io.read
12
+ rescue Exception => e
13
+ e.message
14
+ end
15
+ end
16
+ end
17
+
18
+ def determineDiff(origImage,newImage)
19
+ before, after, result = nil, nil, nil
20
+ begin
21
+ before = Tempfile.new('iab')
22
+ before << origImage
23
+ before.close
24
+ after = Tempfile.new('iab')
25
+ after << newImage
26
+ after.close
27
+ result = Tempfile.new('iab')
28
+ cmd = "#{APP_CONFIG['python_xmldiff_path']} -x #{before.path} #{after.path} > #{result.path}"
29
+ runCommand(cmd)
30
+ xmlDiff = result.read
31
+ #identify only the update nodes - we do not need to know about nodes that have moved sequence
32
+ return xmlDiff
33
+ ensure
34
+ before.delete unless before == nil
35
+ after.delete unless after == nil
36
+ result.delete unless result == nil
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright (c) 2007-2008 Orangery Technology Limited
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # See doc/paypal_developer_info.txt
5
+ # See www.codyfauser.com
6
+
7
+ require 'active_merchant'
8
+
9
+ module Payment
10
+
11
+ include ActiveMerchant::Billing
12
+
13
+ # returns a url
14
+ def setup_payment(params)
15
+ amount = params[:payment_amount].to_i
16
+ if amount < 1
17
+ return params[:cancel_return_url]
18
+ else
19
+ setup_response = payment_gateway.setup_purchase(amount, :ip => params[:ip], :return_url => params[:return_url], :cancel_return_url => params[:cancel_return_url])
20
+ return payment_gateway.redirect_url_for(setup_response.token)
21
+ end
22
+ end
23
+
24
+ # returns a PaymentDetails
25
+ def get_gateway_payment_details(params)
26
+ details_response = payment_gateway.details_for(params[:token])
27
+ return PaymentDetails.new(details_response.success?, details_response.message, details_response.address)
28
+ end
29
+
30
+ class PaymentDetails
31
+ attr_reader :error_message, :address
32
+ def initialize(success, error_message, address)
33
+ @success = success
34
+ @error_message = error_message
35
+ @address = address
36
+ end
37
+ def success?
38
+ @success
39
+ end
40
+ end
41
+
42
+ # returns a PurchaseDetails
43
+ def complete_payment(params)
44
+ amount = params[:payment_amount].to_i
45
+ if amount < 1
46
+ #TODO localise error message
47
+ return PurchaseDetails.new(false, "Amount to pay must be greater than 0")
48
+ else
49
+ purchase = payment_gateway.purchase(amount, :ip => params[:ip], :payer_id => params[:payer_id], :token => params[:token])
50
+ return PurchaseDetails.new(purchase.success?, purchase.message)
51
+ end
52
+ end
53
+
54
+ class PurchaseDetails
55
+ attr_reader :error_message
56
+ def initialize(success, error_message)
57
+ @success = success
58
+ @error_message = error_message
59
+ end
60
+ def success?
61
+ @success
62
+ end
63
+ end
64
+
65
+ # private
66
+ # TODO this is the test paypal account, needs to come from configuration
67
+ def payment_gateway
68
+ @payment_gateway ||= @@gateway_creator.call
69
+ end
70
+
71
+ def self.gateway_creator=(creator)
72
+ @@gateway_creator = creator
73
+ end
74
+
75
+ end
76
+
77
+
78
+ #TODO THIS BELONGS IN A CONFIGURATION INCLUDE SOMEWHERE (which is why it looks funny here)
79
+
80
+ # Put ActiveMerchant in test mode
81
+ ActiveMerchant::Billing::Base.mode = :test
82
+
83
+ # Use the ActiveMerchant Paypal Express gateway with these sandbox account details
84
+ Payment.gateway_creator = lambda { ActiveMerchant::Billing::PaypalExpressGateway.new(
85
+ :login => 'kuboid_1208170947_biz_api1.gmail.com',
86
+ :password => '1208170953',
87
+ :signature => 'AMVR2Do.R-utyMm2sFyqPkqVzWDzAn4yKS9xT07kyzoyj5DFPG-wh53q'
88
+ ) }
@@ -0,0 +1,34 @@
1
+ # Copyright (c) 2007-2008 Orangery Technology Limited
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ module Search
5
+ def executeSearch(product,params)
6
+
7
+ mypredicate = ""
8
+ params.each do |k,v|
9
+ if (v.class.name == 'HashWithIndifferentAccess')
10
+ mypredicate << explodeHash(v)
11
+ end
12
+ end
13
+
14
+ open("#{File.dirname(__FILE__)}/xquery1") {|f| @query = f.read }
15
+ @query = @query.gsub("PRODUCT","#{product}").gsub("PREDICATE",mypredicate[0..-5])
16
+
17
+ persist = Persist.instance
18
+ result = persist.find(@query)
19
+ end
20
+
21
+ def explodeHash(h)
22
+ predicate = ""
23
+ h.each do |k,v|
24
+ if (v.class.name == 'HashWithIndifferentAccess')
25
+ predicate << explodeHash(v)
26
+ elsif (v.class.name == "String")
27
+ if (v.length > 0)
28
+ predicate << "$result//#{k} =\"#{v}\" and "
29
+ end
30
+ end
31
+ end
32
+ predicate
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ declare namespace xupdate="http://www.xmldb.org/xupdate";
2
+ for $result in collection("quotes.dbxml")/PRODUCT
3
+ where PREDICATE
4
+ return
5
+ (
6
+ concat(
7
+ "@rowHash = {",
8
+ "'companyname' => '",$result//Insured[1]//CompanyName/string(),"',",
9
+ "'postcode' => '",$result//Insured[1]//Postcode/string(),"',",
10
+ "'key' => '", $result/dbxml:metadata("dbxml:name"),"',"),
11
+ "'mtas' => [",
12
+ for $mtas in collection("quotes.dbxml")/MTAS/MTA,
13
+ $mta in collection("quotes.dbxml")
14
+ where $mtas/dbxml:metadata("dbxml:name") = concat($result/dbxml:metadata("dbxml:name"),"MTAS")
15
+ and $mta/dbxml:metadata("dbxml:name") = $mtas/@key
16
+ return (
17
+ concat(
18
+ "{",
19
+ "'AD' => '",$mtas/@appliedDateTime/string(),"',",
20
+ "'SD' => '",$mtas/@startDateTime/string(),"',",
21
+ "'ED' => '",$mtas/@endDateTime/string(),"',",
22
+ "'RB' => '",$mtas/@rolledBack/string(),"',",
23
+ "'Changes' => '",$mta//xupdate:update/@select," -to- ",$mta//xupdate:update/string(),"'",
24
+ "},"
25
+ )
26
+ ),
27
+ "]}"
28
+ )