507 lines
21 KiB
Ruby
507 lines
21 KiB
Ruby
require 'spec_helper'
|
|
require 'webmock/rspec'
|
|
|
|
xdescribe "User Subscriptions" do
|
|
|
|
let(:user1) {FactoryBot.create(:user)}
|
|
let(:client) { RecurlyClient.new }
|
|
|
|
it "empty results" do
|
|
user1.touch
|
|
|
|
User.subscription_sync
|
|
|
|
user1.reload
|
|
|
|
user1.subscription_sync_code.should == 'no_recurly_account'
|
|
user1.subscription_last_checked_at.should_not be_nil
|
|
end
|
|
|
|
it "user not in trial" do
|
|
user1.subscription_plan_code = SubscriptionDefinitions::JAM_PLATINUM
|
|
user1.subscription_trial_ends_at = 1.days.ago
|
|
|
|
client.sync_subscription(user1)
|
|
user1.reload
|
|
user1.subscription_sync_code.should == "trial_ended"
|
|
user1.subscription_last_checked_at.should_not be_nil
|
|
user1.subscription_plan_code.should be_nil
|
|
|
|
user1.subscription_trial_ends_at = 3.days.ago
|
|
user1.subscription_last_checked_at = 2.days.ago
|
|
user1.save!
|
|
|
|
User.subscription_sync
|
|
|
|
user1.reload
|
|
|
|
user1.subscription_sync_code.should == "trial_ended"
|
|
user1.subscription_last_checked_at.should_not be_nil
|
|
user1.subscription_plan_code.should be_nil
|
|
end
|
|
|
|
it "revert admin user down" do
|
|
user1.subscription_plan_code = SubscriptionDefinitions::JAM_PLATINUM
|
|
user1.subscription_trial_ends_at = 1.days.ago
|
|
user1.admin_override_plan_code = SubscriptionDefinitions::JAM_PLATINUM
|
|
user1.admin_override_ends_at = 10.days.from_now
|
|
user1.save!
|
|
|
|
User.subscription_sync
|
|
|
|
user1.reload
|
|
|
|
user1.subscription_sync_code.should == "admin_control"
|
|
user1.subscription_last_checked_at.should_not be_nil
|
|
user1.subscription_plan_code.should == SubscriptionDefinitions::JAM_PLATINUM
|
|
|
|
user1.subscription_trial_ends_at = 3.days.ago
|
|
user1.admin_override_ends_at = 10.days.ago
|
|
user1.subscription_last_checked_at = 2.days.ago
|
|
user1.save!
|
|
|
|
User.subscription_sync
|
|
user1.reload
|
|
|
|
user1.subscription_sync_code.should == "trial_ended"
|
|
user1.subscription_last_checked_at.should_not be_nil
|
|
user1.subscription_plan_code.should be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
xdescribe 'Subscription transactions sync' do
|
|
let(:client) { RecurlyClient.new }
|
|
let(:affiliate_partner) { FactoryBot.create(:affiliate_partner) }
|
|
let(:user) { FactoryBot.create(:user, affiliate_referral: affiliate_partner) }
|
|
let(:user2) { FactoryBot.create(:user, affiliate_referral: affiliate_partner) }
|
|
let(:transaction_response){
|
|
transaction_response_xml(user)
|
|
}
|
|
let(:billing_info) {
|
|
info = {}
|
|
info[:first_name] = user.first_name
|
|
info[:last_name] = user.last_name
|
|
info[:address1] = 'Test Address 1'
|
|
info[:address2] = 'Test Address 2'
|
|
info[:city] = user.city
|
|
info[:state] = user.state
|
|
info[:country] = user.country
|
|
info[:zip] = '12345'
|
|
info[:number] = '4111-1111-1111-1111'
|
|
info[:month] = '08'
|
|
info[:year] = '2025'
|
|
info[:verification_value] = '111'
|
|
info
|
|
}
|
|
describe "using recurly API over internet" do
|
|
it "fetches transactions created after GenericState.recurly_transactions_last_sync_at" do
|
|
# pending("test this directly on recurly without stubbing. [maybe can omit as it tests recurly api?]")
|
|
last_sync_at = Time.now
|
|
WebMock.allow_net_connect!
|
|
|
|
# create user account and subscription in recurly
|
|
account1 = client.find_or_create_account(user, billing_info)
|
|
subscription1 = client.create_subscription(user, 'jamsubgold', account1, starts_at = nil)
|
|
subscription1.should_not be_nil
|
|
|
|
expect { client.sync_transactions({ begin_time: last_sync_at.iso8601 }) }.to change(AffiliateDistribution, :count).by(1)
|
|
AffiliateDistribution.order(:created_at).last.external_id.should_not be_nil
|
|
AffiliateDistribution.order(:created_at).last.product_code.should_not be_nil
|
|
|
|
GenericState.singleton.reload
|
|
|
|
new_last_sync_at = GenericState.recurly_transactions_last_sync_at
|
|
expect(last_sync_at < new_last_sync_at).to be true
|
|
|
|
# create second user account and subscription in recurly
|
|
account2 = client.find_or_create_account(user2, billing_info)
|
|
subscription2 = client.create_subscription(user2, 'jamsubplatinumyearly', account2, starts_at = nil)
|
|
|
|
GenericState.singleton.update_attribute(:recurly_transactions_last_sync_at, new_last_sync_at)
|
|
expect { client.sync_transactions({ begin_time: new_last_sync_at.iso8601 }) }.to change(AffiliateDistribution, :count).by(1)
|
|
AffiliateDistribution.order(:created_at).last.external_id.should_not be_nil
|
|
AffiliateDistribution.order(:created_at).last.product_code.should_not be_nil
|
|
end
|
|
end
|
|
describe "using mocked recurly" do
|
|
before(:each) do
|
|
#allow(recurly_transaction).to receive(:find_each).and_return(transaction) #works in rspec >=2.14
|
|
|
|
WebMock.stub_request(:get, /recurly.com\/v2\/transactions\?\S+/).
|
|
to_return(status: 200, body: transaction_response, headers: {})
|
|
|
|
Recurly::Transaction.any_instance.stub(:subscriptions).and_return([
|
|
Recurly::Subscription.new
|
|
])
|
|
|
|
Recurly::Subscription.any_instance.stub(:plan).and_return(Recurly::Plan.new(plan_code: "jamsubgold"))
|
|
end
|
|
|
|
it "creates AffiliateDistribution records for successful recurring transactions" do
|
|
expect { client.sync_transactions }.to change(AffiliateDistribution, :count).by(2)
|
|
end
|
|
|
|
# it "error out for when same transaction data been fetched" do
|
|
# expect { client.sync_transactions }.to change(AffiliateDistribution, :count).by(2)
|
|
# expect { client.sync_transactions }.to raise_error(ActiveRecord::RecordNotUnique)
|
|
# end
|
|
|
|
it "does not create AffiliateDistribution for same transaction previously been created" do
|
|
expect { client.sync_transactions }.to change(AffiliateDistribution, :count).by(2)
|
|
expect { client.sync_transactions }.to change(AffiliateDistribution, :count).by(0)
|
|
end
|
|
|
|
it "does not create AffiliateDistribution records when there is no affiliate partner" do
|
|
user.affiliate_referral = nil
|
|
user.save!
|
|
AffiliateDistribution.delete_all
|
|
transaction_response = transaction_response_xml(user)
|
|
WebMock.stub_request(:get, /recurly.com\/v2\/transactions\?\S+/).
|
|
to_return(status: 200, body: transaction_response, headers: {})
|
|
expect { client.sync_transactions }.to change(AffiliateDistribution, :count).by(0)
|
|
end
|
|
|
|
it "does not create AffiliateDistribution if out of affiliate window" do
|
|
AffiliateDistribution.delete_all
|
|
transaction_response = lapse_transaction_response_xml(user)
|
|
WebMock.stub_request(:get, /recurly.com\/v2\/transactions\?\S+/).
|
|
to_return(status: 200, body: transaction_response, headers: {})
|
|
#expect { client.sync_transactions }.to change(AffiliateDistribution, :count).by(0)
|
|
client.sync_transactions
|
|
end
|
|
|
|
it "assigns correct affiliate partner" do
|
|
client.sync_transactions
|
|
AffiliateDistribution.all.each do |affiliate_distribution|
|
|
expect(affiliate_distribution.affiliate_referral).to_not eq(nil)
|
|
expect(affiliate_distribution.affiliate_referral).to eq(affiliate_partner)
|
|
end
|
|
end
|
|
|
|
it "updates affiliate referral fee" do
|
|
client.sync_transactions
|
|
most_recently_created = AffiliateDistribution.order(created_at: :desc).first
|
|
expect(most_recently_created.affiliate_referral_fee_in_cents).to_not eq(nil)
|
|
expect(most_recently_created.affiliate_referral_fee_in_cents).to eq(27)
|
|
end
|
|
|
|
it "change affiliate rate and updates referral fee" do
|
|
affiliate_partner.rate = 0.20
|
|
affiliate_partner.save!
|
|
client.sync_transactions
|
|
most_recently_created = AffiliateDistribution.order(created_at: :desc).first
|
|
expect(most_recently_created.affiliate_referral_fee_in_cents).to eq(18)
|
|
end
|
|
|
|
it "sets subscription product_type" do
|
|
client.sync_transactions
|
|
AffiliateDistribution.all.each do |affiliate_distribution|
|
|
expect(affiliate_distribution.product_type).to_not eq(nil)
|
|
expect(affiliate_distribution.product_type).to eq('Subscription')
|
|
end
|
|
end
|
|
|
|
it "sets subscription product_code" do
|
|
client.sync_transactions
|
|
AffiliateDistribution.all.each do |affiliate_distribution|
|
|
expect(affiliate_distribution.product_code).to_not eq(nil)
|
|
expect(affiliate_distribution.product_code).to eq('jamsubgold')
|
|
end
|
|
end
|
|
|
|
it "does not error out if begin_time is nil" do
|
|
expect{ client.sync_transactions( { begin_time: nil } ) }.not_to raise_error
|
|
end
|
|
|
|
it "changes GenericState.recurly_transactions_last_sync_at" do
|
|
before_time = GenericState.recurly_transactions_last_sync_at
|
|
client.sync_transactions
|
|
after_time = GenericState.recurly_transactions_last_sync_at
|
|
expect(before_time).not_to eq(after_time)
|
|
end
|
|
end
|
|
|
|
|
|
end
|
|
|
|
def transaction_response_xml(user)
|
|
<<-XMLDATA
|
|
<transactions type="array">
|
|
<transaction href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4381" type="credit_card">
|
|
<account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
|
|
<invoice href="https://your-subdomain.recurly.com/v2/invoices/1005"/>
|
|
<subscriptions href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4381/subscriptions"/>
|
|
<uuid>374adcf4d716c1afc7b0b64bb79d4381</uuid>
|
|
<action>purchase</action>
|
|
<amount_in_cents type="integer">100</amount_in_cents>
|
|
<tax_in_cents type="integer">9</tax_in_cents>
|
|
<currency>USD</currency>
|
|
<status>success</status>
|
|
<payment_method>credit_card</payment_method>
|
|
<reference>2216615</reference>
|
|
<source>subscription</source>
|
|
<recurring type="boolean">true</recurring>
|
|
<test type="boolean">true</test>
|
|
<voidable type="boolean">true</voidable>
|
|
<refundable type="boolean">true</refundable>
|
|
<ip_address>127.0.0.1</ip_address>
|
|
<cvv_result code="" nil="nil"/>
|
|
<avs_result code="D">Street address and postal code match.</avs_result>
|
|
<avs_result_street nil="nil"/>
|
|
<avs_result_postal nil="nil"/>
|
|
<created_at type="datetime">#{10.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</created_at>
|
|
<updated_at type="datetime">#{10.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</updated_at>
|
|
<details>
|
|
<account>
|
|
<account_code>#{user.id}</account_code>
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<company>New Company Name</company>
|
|
<email>verena@example.com</email>
|
|
<billing_info type="credit_card">
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<address1>123 Main St.</address1>
|
|
<address2 nil="nil"/>
|
|
<city>San Francisco</city>
|
|
<state>CA</state>
|
|
<zip>94105</zip>
|
|
<country>US</country>
|
|
<phone nil="nil"/>
|
|
<vat_number nil="nil"/>
|
|
<card_type>Visa</card_type>
|
|
<year type="integer">2019</year>
|
|
<month type="integer">12</month>
|
|
<first_six>411111</first_six>
|
|
<last_four>1111</last_four>
|
|
</billing_info>
|
|
</account>
|
|
</details>
|
|
<a name="refund" href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4381" method="delete"/>
|
|
</transaction>
|
|
|
|
<transaction href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4382" type="credit_card">
|
|
<account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
|
|
<invoice href="https://your-subdomain.recurly.com/v2/invoices/1005"/>
|
|
<subscriptions href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4382/subscriptions"/>
|
|
<uuid>374adcf4d716c1afc7b0b64bb79d4382</uuid>
|
|
<action>purchase</action>
|
|
<amount_in_cents type="integer">200</amount_in_cents>
|
|
<tax_in_cents type="integer">9</tax_in_cents>
|
|
<currency>USD</currency>
|
|
<status>success</status>
|
|
<payment_method>credit_card</payment_method>
|
|
<reference>2216615</reference>
|
|
<source>subscription</source>
|
|
<recurring type="boolean">true</recurring>
|
|
<test type="boolean">true</test>
|
|
<voidable type="boolean">true</voidable>
|
|
<refundable type="boolean">true</refundable>
|
|
<ip_address>127.0.0.1</ip_address>
|
|
<cvv_result code="" nil="nil"/>
|
|
<avs_result code="D">Street address and postal code match.</avs_result>
|
|
<avs_result_street nil="nil"/>
|
|
<avs_result_postal nil="nil"/>
|
|
<created_at type="datetime">#{20.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</created_at>
|
|
<updated_at type="datetime">#{20.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</updated_at>
|
|
<details>
|
|
<account>
|
|
<account_code>#{user.id}</account_code>
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<company>New Company Name</company>
|
|
<email>verena@example.com</email>
|
|
<billing_info type="credit_card">
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<address1>123 Main St.</address1>
|
|
<address2 nil="nil"/>
|
|
<city>San Francisco</city>
|
|
<state>CA</state>
|
|
<zip>94105</zip>
|
|
<country>US</country>
|
|
<phone nil="nil"/>
|
|
<vat_number nil="nil"/>
|
|
<card_type>Visa</card_type>
|
|
<year type="integer">2019</year>
|
|
<month type="integer">12</month>
|
|
<first_six>411111</first_six>
|
|
<last_four>1111</last_four>
|
|
</billing_info>
|
|
</account>
|
|
</details>
|
|
<a name="refund" href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4382" method="delete"/>
|
|
</transaction>
|
|
|
|
|
|
<transaction href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4383" type="credit_card">
|
|
<account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
|
|
<invoice href="https://your-subdomain.recurly.com/v2/invoices/1005"/>
|
|
<subscriptions href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4383/subscriptions"/>
|
|
<uuid>374adcf4d716c1afc7b0b64bb79d4383</uuid>
|
|
<action>purchase</action>
|
|
<amount_in_cents type="integer">200</amount_in_cents>
|
|
<tax_in_cents type="integer">9</tax_in_cents>
|
|
<currency>USD</currency>
|
|
<status>failed</status>
|
|
<payment_method>credit_card</payment_method>
|
|
<reference>2216615</reference>
|
|
<source>transaction</source>
|
|
<recurring type="boolean">true</recurring>
|
|
<test type="boolean">true</test>
|
|
<voidable type="boolean">true</voidable>
|
|
<refundable type="boolean">true</refundable>
|
|
<ip_address>127.0.0.1</ip_address>
|
|
<cvv_result code="" nil="nil"/>
|
|
<avs_result code="D">Street address and postal code match.</avs_result>
|
|
<avs_result_street nil="nil"/>
|
|
<avs_result_postal nil="nil"/>
|
|
<created_at type="datetime">#{20.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</created_at>
|
|
<updated_at type="datetime">#{20.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</updated_at>
|
|
<details>
|
|
<account>
|
|
<account_code>#{user.id}</account_code>
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<company>New Company Name</company>
|
|
<email>verena@example.com</email>
|
|
<billing_info type="credit_card">
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<address1>123 Main St.</address1>
|
|
<address2 nil="nil"/>
|
|
<city>San Francisco</city>
|
|
<state>CA</state>
|
|
<zip>94105</zip>
|
|
<country>US</country>
|
|
<phone nil="nil"/>
|
|
<vat_number nil="nil"/>
|
|
<card_type>Visa</card_type>
|
|
<year type="integer">2019</year>
|
|
<month type="integer">12</month>
|
|
<first_six>411111</first_six>
|
|
<last_four>1111</last_four>
|
|
</billing_info>
|
|
</account>
|
|
</details>
|
|
<a name="refund" href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4383" method="delete"/>
|
|
</transaction>
|
|
|
|
<transaction href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4384" type="credit_card">
|
|
<account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
|
|
<invoice href="https://your-subdomain.recurly.com/v2/invoices/1005"/>
|
|
<subscriptions href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4384/subscriptions"/>
|
|
<uuid>374adcf4d716c1afc7b0b64bb79d4384</uuid>
|
|
<action>purchase</action>
|
|
<amount_in_cents type="integer">200</amount_in_cents>
|
|
<tax_in_cents type="integer">9</tax_in_cents>
|
|
<currency>USD</currency>
|
|
<status>success</status>
|
|
<payment_method>credit_card</payment_method>
|
|
<reference>2216615</reference>
|
|
<source>transaction</source>
|
|
<recurring type="boolean">false</recurring>
|
|
<test type="boolean">true</test>
|
|
<voidable type="boolean">true</voidable>
|
|
<refundable type="boolean">true</refundable>
|
|
<ip_address>127.0.0.1</ip_address>
|
|
<cvv_result code="" nil="nil"/>
|
|
<avs_result code="D">Street address and postal code match.</avs_result>
|
|
<avs_result_street nil="nil"/>
|
|
<avs_result_postal nil="nil"/>
|
|
<created_at type="datetime">#{20.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</created_at>
|
|
<updated_at type="datetime">#{20.minutes.ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</updated_at>
|
|
<details>
|
|
<account>
|
|
<account_code>#{user.id}</account_code>
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<company>New Company Name</company>
|
|
<email>verena@example.com</email>
|
|
<billing_info type="credit_card">
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<address1>123 Main St.</address1>
|
|
<address2 nil="nil"/>
|
|
<city>San Francisco</city>
|
|
<state>CA</state>
|
|
<zip>94105</zip>
|
|
<country>US</country>
|
|
<phone nil="nil"/>
|
|
<vat_number nil="nil"/>
|
|
<card_type>Visa</card_type>
|
|
<year type="integer">2019</year>
|
|
<month type="integer">12</month>
|
|
<first_six>411111</first_six>
|
|
<last_four>1111</last_four>
|
|
</billing_info>
|
|
</account>
|
|
</details>
|
|
<a name="refund" href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4384" method="delete"/>
|
|
</transaction>
|
|
|
|
</transactions>
|
|
XMLDATA
|
|
end
|
|
|
|
def lapse_transaction_response_xml(user)
|
|
<<-XMLDATA
|
|
<transactions type="array">
|
|
<transaction href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4385" type="credit_card">
|
|
<account href="https://your-subdomain.recurly.com/v2/accounts/1"/>
|
|
<invoice href="https://your-subdomain.recurly.com/v2/invoices/1005"/>
|
|
<subscriptions href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4385/subscriptions"/>
|
|
<uuid>374adcf4d716c1afc7b0b64bb79d4385</uuid>
|
|
<action>purchase</action>
|
|
<amount_in_cents type="integer">100</amount_in_cents>
|
|
<tax_in_cents type="integer">9</tax_in_cents>
|
|
<currency>USD</currency>
|
|
<status>success</status>
|
|
<payment_method>credit_card</payment_method>
|
|
<reference>2216615</reference>
|
|
<source>transaction</source>
|
|
<recurring type="boolean">true</recurring>
|
|
<test type="boolean">true</test>
|
|
<voidable type="boolean">true</voidable>
|
|
<refundable type="boolean">true</refundable>
|
|
<ip_address>127.0.0.1</ip_address>
|
|
<cvv_result code="" nil="nil"/>
|
|
<avs_result code="D">Street address and postal code match.</avs_result>
|
|
<avs_result_street nil="nil"/>
|
|
<avs_result_postal nil="nil"/>
|
|
<created_at type="datetime">#{(365.days + 1.day).ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</created_at>
|
|
<updated_at type="datetime">#{(365.days + 1.day).ago.strftime('%Y-%m-%dT%H:%M:%SZ')}</updated_at>
|
|
<details>
|
|
<account>
|
|
<account_code>#{user.id}</account_code>
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<company>New Company Name</company>
|
|
<email>verena@example.com</email>
|
|
<billing_info type="credit_card">
|
|
<first_name>Verena</first_name>
|
|
<last_name>Example</last_name>
|
|
<address1>123 Main St.</address1>
|
|
<address2 nil="nil"/>
|
|
<city>San Francisco</city>
|
|
<state>CA</state>
|
|
<zip>94105</zip>
|
|
<country>US</country>
|
|
<phone nil="nil"/>
|
|
<vat_number nil="nil"/>
|
|
<card_type>Visa</card_type>
|
|
<year type="integer">2019</year>
|
|
<month type="integer">12</month>
|
|
<first_six>411111</first_six>
|
|
<last_four>1111</last_four>
|
|
</billing_info>
|
|
</account>
|
|
</details>
|
|
<a name="refund" href="https://your-subdomain.recurly.com/v2/transactions/374adcf4d716c1afc7b0b64bb79d4385" method="delete"/>
|
|
</transaction>
|
|
|
|
</transactions>
|
|
XMLDATA
|
|
end |