diff --git a/modules/claims_api/lib/bgs_service/vnp_atchms_service.rb b/modules/claims_api/lib/bgs_service/vnp_atchms_service.rb
new file mode 100644
index 00000000000..548350ef459
--- /dev/null
+++ b/modules/claims_api/lib/bgs_service/vnp_atchms_service.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module ClaimsApi
+ class VnpAtchmsService < ClaimsApi::LocalBGS
+ # Takes an object with a minimum of (other fields are camelized and passed to BGS):
+ # vnp_proc_id: BGS procID
+ # atchms_file_nm: File name
+ # atchms_descp: File description
+ # atchms_txt: Base64 encoded file or file path
+ def vnp_atchms_create(opts)
+ validate_opts! opts, %w[vnp_proc_id atchms_file_nm atchms_descp atchms_txt]
+
+ convert_file! opts
+ opts = jrn.merge(opts)
+ arg_strg = convert_nil_values(opts)
+ body = Nokogiri::XML::DocumentFragment.parse "#{arg_strg}"
+ make_request(endpoint: 'VnpAtchmsWebServiceBean/VnpAtchmsService', action: 'vnpAtchmsCreate', body:,
+ key: 'return')
+ end
+
+ private
+
+ def convert_file!(opts)
+ opts.deep_symbolize_keys!
+ txt = opts[:atchms_txt]
+ raise ArgumentError, 'File must be a string' unless txt.is_a? String
+
+ if File.exist?(txt)
+ file = File.read(txt)
+ opts[:atchms_txt] = Base64.encode64 file
+ end
+ end
+ end
+end
diff --git a/modules/claims_api/spec/lib/claims_api/vnp_atchms_service_spec.rb b/modules/claims_api/spec/lib/claims_api/vnp_atchms_service_spec.rb
new file mode 100644
index 00000000000..6260c7993a6
--- /dev/null
+++ b/modules/claims_api/spec/lib/claims_api/vnp_atchms_service_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'bgs_service/vnp_atchms_service'
+require Rails.root.join('modules', 'claims_api', 'spec', 'support', 'bgs_client_helpers.rb')
+
+metadata = {
+ bgs: {
+ service: 'vnp_atchms_service',
+ operation: 'vnp_atchms_create'
+ }
+}
+
+describe ClaimsApi::VnpAtchmsService, metadata do
+ describe '#vnp_atchms_create', run_at: '2024-04-01T18:48:27Z' do
+ subject { described_class.new external_uid: 'xUid', external_key: 'xKey' }
+
+ describe 'validation' do
+ # get a proc_id from vnp_proc_create
+ let(:vnp_proc_id) { '3854593' }
+ let(:expected_response) do
+ { vnp_proc_id:,
+ atchms_file_nm: 'test.pdf',
+ atchms_descp: 'test' }
+ end
+
+ context 'when missing required params' do
+ it 'raises an error' do
+ data = { asdf: 'qwerty' }
+ expect { subject.vnp_atchms_create(data) }.to(raise_error do |error|
+ expect(error).to be_a(ArgumentError)
+ expect(error.message).to eq('Missing required keys: vnp_proc_id, atchms_file_nm, atchms_descp, atchms_txt')
+ end)
+ end
+ end
+
+ describe 'when submitting valid data' do
+ context 'with a base64 string' do
+ it 'creates a attachment from data' do
+ data = {
+ vnp_proc_id:,
+ atchms_file_nm: 'test.pdf',
+ atchms_descp: 'test',
+ atchms_txt: 'base64here'
+ }
+ use_bgs_cassette('happy_path_base64') do
+ result = subject.vnp_atchms_create(data)
+ expect((expected_response.to_a & result.to_a).to_h).to eq expected_response
+ end
+ end
+ end
+
+ context 'with a file path' do
+ it 'creates a attachment from data' do
+ data = {
+ vnp_proc_id:,
+ atchms_file_nm: 'test.pdf',
+ atchms_descp: 'test',
+ atchms_txt: Rails.root.join('modules', 'claims_api', 'spec', 'fixtures', 'extras.pdf').to_s
+ }
+ use_bgs_cassette('happy_path_file') do
+ result = subject.vnp_atchms_create(data)
+ expect((expected_response.to_a & result.to_a).to_h).to eq expected_response
+ end
+ end
+ end
+ end
+
+ context 'when providing an invalid procId' do
+ it 'raises an error' do
+ data = {
+ vnp_proc_id: '1234abc',
+ atchms_file_nm: 'test.pdf',
+ atchms_descp: 'test',
+ atchms_txt: 'base64here'
+ }
+
+ use_bgs_cassette('invalid_procId') do
+ expect { subject.vnp_atchms_create(data) }.to raise_error(Common::Exceptions::ServiceError)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/happy_path_base64.yml b/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/happy_path_base64.yml
new file mode 100644
index 00000000000..1534176e186
--- /dev/null
+++ b/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/happy_path_base64.yml
@@ -0,0 +1,135 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: /VnpAtchmsWebServiceBean/VnpAtchmsService?WSDL
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v2.9.0
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Mon, 08 Apr 2024 18:00:15 GMT
+ Server:
+ - Apache
+ X-Frame-Options:
+ - SAMEORIGIN
+ Transfer-Encoding:
+ - chunked
+ Content-Type:
+ - text/xml;charset=utf-8
+ Strict-Transport-Security:
+ - max-age=16000000; includeSubDomains; preload;
+ body:
+ encoding: UTF-8
+ string: |-
+
+ recorded_at: Mon, 01 Apr 2024 18:48:27 GMT
+- request:
+ method: post
+ uri: /VnpAtchmsWebServiceBean/VnpAtchmsService
+ body:
+ encoding: UTF-8
+ string: |
+
+
+
+
+
+ VAgovAPI
+
+
+ 127.0.0.1
+ 281
+ VAgovAPI
+ xUid
+ xKey
+
+
+
+
+
+
+
+ 2024-04-01T18:48:27Z
+ 281
+ U
+ VAgovAPI
+ VAgovAPI
+ 3854593
+ test.pdf
+ test
+ base64here
+
+
+
+
+ headers:
+ User-Agent:
+ - Faraday v2.9.0
+ Content-Type:
+ - text/xml;charset=UTF-8
+ Host:
+ - ".vba.va.gov"
+ Soapaction:
+ - '"vnpAtchmsCreate"'
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Mon, 08 Apr 2024 18:00:15 GMT
+ Server:
+ - Apache
+ X-Frame-Options:
+ - SAMEORIGIN
+ Transfer-Encoding:
+ - chunked
+ Content-Type:
+ - text/xml; charset=utf-8
+ Strict-Transport-Security:
+ - max-age=16000000; includeSubDomains; preload;
+ body:
+ encoding: UTF-8
+ string: |-
+
+
+
+
+ rO0ABXdKABR3ZWJsb2dpYy5hcHAudm5wLWVhcgAAANYAAAAjd2VibG9naWMud29ya2FyZWEuU3RyaW5nV29ya0NvbnRleHQABTIuMC44AAA=
+
+
+
+
+ 64335
+ 3854593
+ test.pdf
+ test
+
+
+
+
+ recorded_at: Mon, 01 Apr 2024 18:48:27 GMT
+recorded_with: VCR 6.2.0
diff --git a/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/happy_path_file.yml b/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/happy_path_file.yml
new file mode 100644
index 00000000000..2e72aaa7898
--- /dev/null
+++ b/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/happy_path_file.yml
@@ -0,0 +1,140 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: /VnpAtchmsWebServiceBean/VnpAtchmsService?WSDL
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v2.9.0
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Mon, 08 Apr 2024 18:21:29 GMT
+ Server:
+ - Apache
+ X-Frame-Options:
+ - SAMEORIGIN
+ Transfer-Encoding:
+ - chunked
+ Content-Type:
+ - text/xml;charset=utf-8
+ Strict-Transport-Security:
+ - max-age=16000000; includeSubDomains; preload;
+ body:
+ encoding: UTF-8
+ string: |-
+
+ recorded_at: Mon, 01 Apr 2024 18:48:27 GMT
+- request:
+ method: post
+ uri: /VnpAtchmsWebServiceBean/VnpAtchmsService
+ body:
+ encoding: UTF-8
+ string: |
+
+
+
+
+
+ VAgovAPI
+
+
+ 127.0.0.1
+ 281
+ VAgovAPI
+ xUid
+ xKey
+
+
+
+
+
+
+
+ 2024-04-01T18:48:27Z
+ 281
+ U
+ VAgovAPI
+ VAgovAPI
+ 3854593
+ test.pdf
+ test
+ JVBERi0xLjMKJf////8KMSAwIG9iago8PCAvQ3JlYXRvciA8ZmVmZjAwNTAwMDcyMDA2MTAwNzcwMDZlPgovUHJvZHVjZXIgPGZlZmYwMDUwMDA3MjAwNjEwMDc3MDA2ZT4KPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cKL1BhZ2VzIDMgMCBSCj4+CmVuZG9iagozIDAgb2JqCjw8IC9UeXBlIC9QYWdlcwovQ291bnQgMQovS2lkcyBbNSAwIFJdCj4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggMjI4Cj4+CnN0cmVhbQpxCgpCVAozNi4wIDcxOS41MTIgVGQKL0YyLjAgMTYgVGYKWzw0MTY0PiAxMCA8NjQ2OTc0Njk2ZjZlNjE2YzIwNDk2ZTY2PiAyMCA8NmY3MjZkNjE3NDY5NmY2ZT5dIFRKCkVUCgoKQlQKMzYuMCA2OTMuMzQ0IFRkCi9GMi4wIDEyIFRmCls8MzE0MTJlMjA0NjZmNmYyMDRjNjk2ZTY1MjAzMjNhPl0gVEoKRVQKCgpCVAozNi4wIDY3OS4wNjQgVGQKL0YxLjAgMTIgVGYKWzw2MjYxNzI+XSBUSgpFVAoKUQoKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlCi9QYXJlbnQgMyAwIFIKL01lZGlhQm94IFswIDAgNjEyLjAgNzkyLjBdCi9Dcm9wQm94IFswIDAgNjEyLjAgNzkyLjBdCi9CbGVlZEJveCBbMCAwIDYxMi4wIDc5Mi4wXQovVHJpbUJveCBbMCAwIDYxMi4wIDc5Mi4wXQovQXJ0Qm94IFswIDAgNjEyLjAgNzkyLjBdCi9Db250ZW50cyA0IDAgUgovUmVzb3VyY2VzIDw8IC9Qcm9jU2V0IFsvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJXQovRm9udCA8PCAvRjIuMCA2IDAgUgovRjEuMCA3IDAgUgo+Pgo+Pgo+PgplbmRvYmoKNiAwIG9iago8PCAvVHlwZSAvRm9udAovU3VidHlwZSAvVHlwZTEKL0Jhc2VGb250IC9IZWx2ZXRpY2EtQm9sZAovRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZwo+PgplbmRvYmoKNyAwIG9iago8PCAvVHlwZSAvRm9udAovU3VidHlwZSAvVHlwZTEKL0Jhc2VGb250IC9IZWx2ZXRpY2EKL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcKPj4KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMTA5IDAwMDAwIG4gCjAwMDAwMDAxNTggMDAwMDAgbiAKMDAwMDAwMDIxNSAwMDAwMCBuIAowMDAwMDAwNDk0IDAwMDAwIG4gCjAwMDAwMDA3OTIgMDAwMDAgbiAKMDAwMDAwMDg5NCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDgKL1Jvb3QgMiAwIFIKL0luZm8gMSAwIFIKPj4Kc3RhcnR4cmVmCjk5MQolJUVPRgo=
+
+
+
+
+ headers:
+ User-Agent:
+ - Faraday v2.9.0
+ Content-Type:
+ - text/xml;charset=UTF-8
+ Host:
+ - ".vba.va.gov"
+ Soapaction:
+ - '"vnpAtchmsCreate"'
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Mon, 08 Apr 2024 18:21:30 GMT
+ Server:
+ - Apache
+ X-Frame-Options:
+ - SAMEORIGIN
+ Transfer-Encoding:
+ - chunked
+ Content-Type:
+ - text/xml; charset=utf-8
+ Strict-Transport-Security:
+ - max-age=16000000; includeSubDomains; preload;
+ body:
+ encoding: UTF-8
+ string: |-
+
+
+
+
+ rO0ABXdKABR3ZWJsb2dpYy5hcHAudm5wLWVhcgAAANYAAAAjd2VibG9naWMud29ya2FyZWEuU3RyaW5nV29ya0NvbnRleHQABTIuMC44AAA=
+
+
+
+
+ 64340
+ 3854593
+ test.pdf
+ test
+ 2024-04-01T18:48:27Z
+ 281
+ VAgovAPI
+ U
+ VAgovAPI
+
+
+
+
+ recorded_at: Mon, 01 Apr 2024 18:48:27 GMT
+recorded_with: VCR 6.2.0
diff --git a/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/invalid_procId.yml b/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/invalid_procId.yml
new file mode 100644
index 00000000000..fbbaa9e7dc3
--- /dev/null
+++ b/spec/support/vcr_cassettes/claims_api/bgs/vnp_atchms_service/vnp_atchms_create/invalid_procId.yml
@@ -0,0 +1,130 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: /VnpAtchmsWebServiceBean/VnpAtchmsService?WSDL
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ User-Agent:
+ - Faraday v2.9.0
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Mon, 08 Apr 2024 18:08:46 GMT
+ Server:
+ - Apache
+ X-Frame-Options:
+ - SAMEORIGIN
+ Transfer-Encoding:
+ - chunked
+ Content-Type:
+ - text/xml;charset=utf-8
+ Strict-Transport-Security:
+ - max-age=16000000; includeSubDomains; preload;
+ body:
+ encoding: UTF-8
+ string: |-
+
+ recorded_at: Mon, 01 Apr 2024 18:48:27 GMT
+- request:
+ method: post
+ uri: /VnpAtchmsWebServiceBean/VnpAtchmsService
+ body:
+ encoding: UTF-8
+ string: |-
+
+
+
+
+
+ VAgovAPI
+
+
+ 127.0.0.1
+ 281
+ VAgovAPI
+ xUid
+ xKey
+
+
+
+
+
+
+
+ 2024-04-01T18:48:27Z
+ 281
+ U
+ VAgovAPI
+ VAgovAPI
+ 1234abc
+ test.pdf
+ test
+ base64here
+
+
+
+
+ headers:
+ User-Agent:
+ - Faraday v2.9.0
+ Content-Type:
+ - text/xml;charset=UTF-8
+ Host:
+ - ".vba.va.gov"
+ Soapaction:
+ - '"vnpAtchmsCreate"'
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 500
+ message: Internal Server Error
+ headers:
+ Date:
+ - Mon, 08 Apr 2024 18:08:47 GMT
+ Server:
+ - Apache
+ X-Frame-Options:
+ - SAMEORIGIN
+ Transfer-Encoding:
+ - chunked
+ Content-Type:
+ - text/xml; charset=utf-8
+ Strict-Transport-Security:
+ - max-age=16000000; includeSubDomains; preload;
+ body:
+ encoding: UTF-8
+ string: |-
+
+
+
+
+ ns0:Server
+
+ Exception Description: The object [1234abc], of class [class java.lang.String], from mapping
+ [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[vnpProcId-->vnpProcId/text()]] with
+ descriptor [XMLDescriptor(gov.va.vba.vonapp.dto.VnpAtchmsDTO --> [])], could not be
+ converted to [class java.lang.Long].
+ Internal Exception: java.lang.NumberFormatException: For input string: "1234abc"
+
+
+
+ recorded_at: Mon, 01 Apr 2024 18:48:27 GMT
+recorded_with: VCR 6.2.0