-
Notifications
You must be signed in to change notification settings - Fork 0
/
correct.go
82 lines (73 loc) · 2.16 KB
/
correct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package internal
import (
"context"
"net/http"
"github.com/invopop/gobl"
"github.com/invopop/gobl/bill"
"github.com/invopop/gobl/cal"
"github.com/invopop/gobl/schema"
"github.com/labstack/echo/v4"
)
// CorrectOptions define all the basic options required to build a corrective
// document from the input.
type CorrectOptions struct {
// we don't need all of the parse options
*ParseOptions
OptionsSchema bool
Credit bool
Debit bool
Date cal.Date
Data []byte // raw json of correction options
}
// Correct takes a base document as input and builds a corrective document
// for the output. If the "ShowOptions" boolean is true, we'll attempt to determine
// what options are available.
func Correct(ctx context.Context, opts *CorrectOptions) (interface{}, error) {
obj, err := parseGOBLData(ctx, opts.ParseOptions)
if err != nil {
return nil, err
}
if opts.OptionsSchema {
if env, ok := obj.(*gobl.Envelope); ok {
return env.CorrectionOptionsSchema()
}
if doc, ok := obj.(*schema.Object); ok {
return doc.CorrectionOptionsSchema()
}
panic("input must be either an envelope or a document")
}
eopts := make([]schema.Option, 0)
if len(opts.Data) > 0 {
eopts = append(eopts, bill.WithData(opts.Data))
}
if opts.Credit {
eopts = append(eopts, bill.Credit)
}
if opts.Debit {
eopts = append(eopts, bill.Debit)
}
if !opts.Date.IsZero() {
eopts = append(eopts, bill.WithIssueDate(opts.Date))
}
if env, ok := obj.(*gobl.Envelope); ok {
e2, err := env.Correct(eopts...)
if err != nil {
return nil, echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error())
}
if err = e2.Validate(); err != nil {
return nil, echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error())
}
return e2, nil
}
if doc, ok := obj.(*schema.Object); ok {
// Documents are updated in place
if err := doc.Correct(eopts...); err != nil {
return nil, echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error())
}
if err = doc.Validate(); err != nil {
return nil, echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error())
}
return doc, nil
}
panic("input must be either an envelope or a document")
}