Skip to content

Commit

Permalink
Improve builder errors
Browse files Browse the repository at this point in the history
  • Loading branch information
printesoi committed Mar 25, 2024
1 parent 0b617a6 commit a086541
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 33 deletions.
44 changes: 22 additions & 22 deletions builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ func (b *InvoiceLineAllowanceChargeBuilder) WithAllowanceChargeReason(allowanceC

func (b InvoiceLineAllowanceChargeBuilder) Build() (allowanceCharge InvoiceLineAllowanceCharge, err error) {
if !b.amount.IsInitialized() {
err = NewBuilderErrorf("%v: amount not set", typeName(b))
err = newBuilderErrorf(b, "", "amount not set")
return
}
if b.currencyID == "" {
err = NewBuilderErrorf("%v: currency not set", typeName(b))
err = newBuilderErrorf(b, "", "currency not set")
return
}
allowanceCharge.ChargeIndicator = b.chargeIndicator
Expand Down Expand Up @@ -222,31 +222,31 @@ func (b *InvoiceLineBuilder) WithItemTaxCategory(taxCategory InvoiceLineTaxCateg

func (b InvoiceLineBuilder) Build() (line InvoiceLine, err error) {
if b.id == "" {
err = NewBuilderErrorf("%v: id not set", typeName(b))
err = newBuilderErrorf(b, "", "id not set")
return
}
if b.currencyID == "" {
err = NewBuilderErrorf("%v: id currency id not set", typeName(b))
err = newBuilderErrorf(b, "", "id currency id not set")
return
}
if !b.invoicedQuantity.IsInitialized() {
err = NewBuilderErrorf("%v: invoiced quantity not set", typeName(b))
err = newBuilderErrorf(b, "", "invoiced quantity not set")
return
}
if b.unitCode == "" {
err = NewBuilderErrorf("%v: unit code not set", typeName(b))
err = newBuilderErrorf(b, "", "unit code not set")
return
}
if !b.grossPriceAmount.IsInitialized() {
err = NewBuilderErrorf("%v: gross price amount not set", typeName(b))
err = newBuilderErrorf(b, "", "gross price amount not set")
return
}
if b.itemName == "" {
err = NewBuilderErrorf("%v: item name not set", typeName(b))
err = newBuilderErrorf(b, "", "item name not set")
return
}
if b.itemTaxCategory.ID == "" || b.itemTaxCategory.TaxScheme.ID == "" {
err = NewBuilderErrorf("%v: item tax category not set", typeName(b))
err = newBuilderErrorf(b, "", "item tax category not set")
return
}

Expand Down Expand Up @@ -308,7 +308,7 @@ func (b InvoiceLineBuilder) Build() (line InvoiceLine, err error) {
baseQuantity = *b.baseQuantity
}
if baseQuantity.IsZero() {
err = NewBuilderErrorf("%v: base quantity cannot be zero", typeName(b))
err = newBuilderErrorf(b, "", "base quantity cannot be zero")
return
}
netAmount := b.invoicedQuantity.Mul(netPriceAmount).Div(baseQuantity)
Expand Down Expand Up @@ -397,15 +397,15 @@ func (b *InvoiceDocumentAllowanceChargeBuilder) WithAllowanceChargeReason(allowa

func (b InvoiceDocumentAllowanceChargeBuilder) Build() (allowanceCharge InvoiceDocumentAllowanceCharge, err error) {
if !b.amount.IsInitialized() {
err = NewBuilderErrorf("%v: amount not set", typeName(b))
err = newBuilderErrorf(b, "", "amount not set")
return
}
if b.currencyID == "" {
err = NewBuilderErrorf("%v: current id not set", typeName(b))
err = newBuilderErrorf(b, "", "current id not set")
return
}
if b.taxCategory.ID == "" || b.taxCategory.TaxScheme.ID == "" {
err = NewBuilderErrorf("%v: item tax category not set", typeName(b))
err = newBuilderErrorf(b, "", "item tax category not set")
return
}
allowanceCharge.ChargeIndicator = b.chargeIndicator
Expand Down Expand Up @@ -612,19 +612,19 @@ func (b *InvoiceBuilder) WithExpectedTaxInclusiveAmount(amount Decimal) *Invoice

func (b InvoiceBuilder) Build() (retInvoice Invoice, err error) {
if b.id == "" {
err = NewBuilderErrorf("%v: id not set", typeName(b))
err = newBuilderErrorf(b, "", "id not set")
return
}
if !b.issueDate.IsInitialized() {
err = NewBuilderErrorf("%v: issue date not set", typeName(b))
err = newBuilderErrorf(b, "", "issue date not set")
return
}
if b.documentCurrencyID == "" {
err = NewBuilderErrorf("%v: document currency id not set", typeName(b))
err = newBuilderErrorf(b, "", "document currency id not set")
return
}
if b.taxCurrencyID != "" && b.taxCurrencyID != b.documentCurrencyID && !b.taxCurrencyExchangeRate.IsInitialized() {
err = NewBuilderErrorf("%v: document to tax currency exchange rate not set", typeName(b))
err = newBuilderErrorf(b, "", "document to tax currency exchange rate not set")
return
}

Expand Down Expand Up @@ -690,14 +690,14 @@ func (b InvoiceBuilder) Build() (retInvoice Invoice, err error) {
taxCategoryMap := make(taxCategoryMap)
for i, line := range invoice.InvoiceLines {
if line.LineExtensionAmount.CurrencyID != invoice.DocumentCurrencyCode {
err = NewBuilderErrorf("%v: invoice line %d: invalid currency id", typeName(b), i)
err = newBuilderErrorf(b, "", "invoice line %d: invalid currency id", i)
return
}

lineAmount := line.LineExtensionAmount.Amount
lineExtensionAmount = lineExtensionAmount.Add(lineAmount)
if !taxCategoryMap.addLineTaxCategory(line.Item.TaxCategory, lineAmount) {
err = NewBuilderErrorf("%v: invoice line %d: invalid tax category", typeName(b), i)
err = newBuilderErrorf(b, "", "invoice line %d: invalid tax category", i)
return
}
}
Expand All @@ -711,7 +711,7 @@ func (b InvoiceBuilder) Build() (retInvoice Invoice, err error) {
allowanceTotalAmount = allowanceTotalAmount.Add(allowanceCharge.Amount.Amount)
}
if !taxCategoryMap.addDocumentTaxCategory(allowanceCharge.TaxCategory, amount) {
err = NewBuilderErrorf("%v: invoice allowance/charge %d: invalid tax category", typeName(b), i)
err = newBuilderErrorf(b, "", "invoice allowance/charge %d: invalid tax category", i)
return
}
}
Expand Down Expand Up @@ -740,8 +740,8 @@ func (b InvoiceBuilder) Build() (retInvoice Invoice, err error) {

if subtotal.TaxCategory.ID.TaxRateExempted() && subtotal.TaxCategory.ID.ExemptionReasonRequired() {
if reason, rok := b.taxExeptionReasons[subtotal.TaxCategory.ID]; !rok {
err = NewBuilderErrorf("%v: tax category %s/%s: no exemption reason",
typeName(b), subtotal.TaxCategory.ID, subtotal.TaxCategory.Percent.String())
err = newBuilderErrorf(b, "", "tax category %s/%s: no exemption reason",
subtotal.TaxCategory.ID, subtotal.TaxCategory.Percent.String())
return
} else {
subtotal.TaxCategory.TaxExemptionReason = reason.reason
Expand Down
24 changes: 13 additions & 11 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,27 +77,29 @@ func (r *ErrorResponse) Error() string {
// BuilderError is an error returned by the builders.
type BuilderError struct {
error
Term *string
Builder string
Term *string
}

func NewBuilderErrorf(format string, a ...any) *BuilderError {
func newBuilderNameErrorf(builder, term string, format string, a ...any) *BuilderError {
return &BuilderError{
error: fmt.Errorf(format, a...),
error: fmt.Errorf(format, a...),
Builder: builder,
Term: ptrfyStringNotEmpty(term),
}
}

func NewBuilderTermErrorf(term string, format string, a ...any) *BuilderError {
return &BuilderError{
error: fmt.Errorf(format, a...),
}
func newBuilderErrorf(builder any, term string, format string, a ...any) *BuilderError {
return newBuilderNameErrorf(typeNameAddrPtr(builder), term, format, a...)
}

func (e *BuilderError) Error() string {
if e.Term == nil {
return e.error.Error()
errMsg := fmt.Sprintf("%s: ", e.Builder)
if e.Term != nil {
errMsg += fmt.Sprintf("term=%s: ", *e.Term)
}

return fmt.Sprintf("term: %s, error: %s", *e.Term, e.error.Error())
errMsg += e.error.Error()
return errMsg
}

// ValidateSignatureError is an error returned if the signature cannot be
Expand Down
15 changes: 15 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,21 @@ func ptrfyString(s string) *string {
return &s
}

func ptrfyStringNotEmpty(s string) *string {
if s != "" {
return &s
}
return nil
}

func typeName(v any) string {
return reflect.TypeOf(v).Name()
}

func typeNameAddrPtr(v any) string {
rt := reflect.TypeOf(v)
if rt.Kind() == reflect.Pointer {
rt = rt.Elem()
}
return rt.Name()
}

0 comments on commit a086541

Please sign in to comment.