So now it's time to create the main program to submit the CT600.
I think I'm going to want to be able to do "all" of the various operations - submit, see what's out there, check a submission, delete a submission - from a single program, and that means that I'm going to want an argument that is the "command". But most of the other arguments are going to be configuration files. That being the case, I'm going to work on the assumption that the command will have the syntax:
ct600 <operation> <config>...But for now, I'm just going to assume the operation "submit" (in fact, just transmitting and expecting an error) and only parse configuration files. I'm going to rejig what we did last time to accept these configuration files and then consolidate the configuration before attempting to generate a message and submit it.
Let's go!
A New Command
We already have a command to generate GnuCash files, so we're going to do something very similar. So similar, in fact, I am just going to copy it and then update it.package main
import (
"fmt"
"os"
"github.com/gmmapowell/ignorance/accounts/internal/ct600/config"
"github.com/gmmapowell/ignorance/accounts/internal/ct600/submission"
)
func main() {
conf := config.MakeBlankConfig()
for _, f := range os.Args[1:] {
err := config.IncludeConfig(conf, f)
if err != nil {
fmt.Printf("failed to read config %s: %v\n", f, err)
return
}
}
err := submission.Submit(conf)
if err != nil {
fmt.Printf("submission failed: %v\n", err)
return
}
}
CT600_MAIN_SUBMITTER:accounts/cmd/ct600/main.go
This is quite big for a cmd program, but I think at this moment I'm happy with it. We'll see how we do when we add multiple commands; I imagine I will want to put basically all of it somewhere else.So, as promised, I refactored the config stuff to make a blank configuration, then to incorporate each file we provide on the command line, and then we call Submit. I'm not going to review the configuration changes, but here is the submit code that has emerged from what was left of the test case (now deleted):
package submission
import (
"fmt"
"io"
"log"
"net/http"
"strings"
"github.com/gmmapowell/ignorance/accounts/internal/ct600/config"
)
func Submit(conf *config.Config) error {
send, err := Generate(conf)
if err != nil {
return err
}
return transmit(send)
}
func transmit(body io.Reader) error {
cli := &http.Client{}
resp, err := cli.Post("https://test-transaction-engine.tax.service.gov.uk/submission", "application/x-binary", body)
if err != nil {
log.Fatalf("error posting xml file: %v", err)
}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("error reading response: %v", err)
}
msg := string(respBody)
fmt.Printf("%s", msg)
if strings.Contains(msg, "GovTalkErrors") {
return fmt.Errorf("there was a GovTalkErrors block")
}
return nil
}
CT600_MAIN_SUBMITTER:accounts/internal/ct600/submission/submit.go
Submit calls the existing Generate function, and then calls transmit, which is the old code from the test to send to the government website. This still has some constants in it (like the URL) that we will want to extract to configuration at some point (we will then need a set of "test" credentials and a set of "live" credentials in separate configuration files, going along with the URL and the GatewayTest flag). But for now, this is enough to get us running.I put my valid credentials in a test file (of the same form as foo.json) and ran the ct600 script. And just like that, we have a "working" submission:
<?xml version="1.0" encoding="UTF-8"?>That is, my submission has been accepted for consideration. I imagine when I write the next line of code to go back and examine that submission, I imagine I will see that it was, in fact, rejected.
<GovTalkMessage xmlns="http://www.govtalk.gov.uk/CM/envelope">
<EnvelopeVersion>2.0</EnvelopeVersion>
<Header>
<MessageDetails>
<Class>HMRC-CT-CT600</Class>
<Qualifier>acknowledgement</Qualifier>
<Function>submit</Function>
<TransactionID></TransactionID>
<CorrelationID>8E73E73CD1F34678BBFDE9B6C1B9139C</CorrelationID>
<ResponseEndPoint PollInterval="10">https://test-transaction-engine.tax.service.gov.uk/poll</ResponseEndPoint>
<GatewayTimestamp>2025-05-30T20:34:21.066</GatewayTimestamp>
</MessageDetails>
<SenderDetails/>
</Header>
<GovTalkDetails>
<Keys/>
</GovTalkDetails>
<Body/>
</GovTalkMessage>
No comments:
Post a Comment