diff --git a/internal/bulk.go b/internal/bulk.go index 845215b..5c6e527 100644 --- a/internal/bulk.go +++ b/internal/bulk.go @@ -95,9 +95,8 @@ type KeygenResponse struct { // CorrectRequest is the payload used to generate a corrected document. type CorrectRequest struct { - Data []byte `json:"data"` - Credit bool `json:"credit"` - Debit bool `json:"debit"` + Data []byte `json:"data"` + Options []byte `json:"options"` } // Bulk processes a stream of bulk requests. @@ -229,8 +228,7 @@ func processRequest(ctx context.Context, req BulkRequest, seq int64, bulkOpts *B ParseOptions: &ParseOptions{ Input: bytes.NewReader(bld.Data), }, - Credit: bld.Credit, - Debit: bld.Debit, + Data: bld.Options, } env, err := Correct(ctx, opts) if err != nil { diff --git a/internal/bulk_test.go b/internal/bulk_test.go index 789e43d..5f61fdd 100644 --- a/internal/bulk_test.go +++ b/internal/bulk_test.go @@ -399,7 +399,8 @@ func TestBulk(t *testing.T) { "action": "correct", "req_id": "asdf", "payload": map[string]interface{}{ - "data": base64.StdEncoding.EncodeToString(payload), + "data": base64.StdEncoding.EncodeToString(payload), + "options": []byte(`{"credit":true,"correction_method":"complete","corrections":["line"]}`), }, }) if err != nil { diff --git a/internal/correct.go b/internal/correct.go index d5cd23d..80a4968 100644 --- a/internal/correct.go +++ b/internal/correct.go @@ -49,7 +49,7 @@ func Correct(ctx context.Context, opts *CorrectOptions) (interface{}, error) { if err != nil { return nil, echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error()) } - if err = env.Validate(); err != nil { + if err = e2.Validate(); err != nil { return nil, echo.NewHTTPError(http.StatusUnprocessableEntity, err.Error()) } return e2, nil diff --git a/internal/correct_test.go b/internal/correct_test.go index 7f5550f..c121cd0 100644 --- a/internal/correct_test.go +++ b/internal/correct_test.go @@ -26,10 +26,11 @@ func TestCorrect(t *testing.T) { Input: testFileReader(t, "testdata/success.json"), }, Date: cal.MakeDate(2023, 4, 17), + Data: []byte(`{"credit":true,"correction_method":"complete","corrections":["line"]}`), }, } }) - tests.Add("success with data", func(t *testing.T) interface{} { + tests.Add("error missing data", func(t *testing.T) interface{} { return tt{ opts: &CorrectOptions{ ParseOptions: &ParseOptions{ @@ -37,6 +38,30 @@ func TestCorrect(t *testing.T) { }, Data: []byte(`{"issue_date":"2023-04-17","credit":true}`), }, + err: "preceding: (0: (correction_method: cannot be blank; corrections: cannot be blank.).).", + } + }) + + tests.Add("success just invoice", func(t *testing.T) interface{} { + return tt{ + opts: &CorrectOptions{ + ParseOptions: &ParseOptions{ + Input: testFileReader(t, "testdata/invoice.json"), + }, + Date: cal.MakeDate(2023, 4, 17), + Data: []byte(`{"credit":true,"correction_method":"complete","corrections":["line"]}`), + }, + } + }) + tests.Add("error just invoice", func(t *testing.T) interface{} { + return tt{ + opts: &CorrectOptions{ + ParseOptions: &ParseOptions{ + Input: testFileReader(t, "testdata/invoice.json"), + }, + Date: cal.MakeDate(2023, 4, 17), + }, + err: "preceding: (0: (correction_method: cannot be blank; corrections: cannot be blank.).).", } }) @@ -47,7 +72,9 @@ func TestCorrect(t *testing.T) { if tt.err == "" { assert.Nil(t, err) } else { - assert.EqualError(t, err, tt.err) + if assert.Error(t, err) { + assert.Contains(t, err.Error(), tt.err) + } } if err != nil { return diff --git a/internal/testdata/TestCorrect_success b/internal/testdata/TestCorrect_success index 8ad6e90..ee28130 100644 --- a/internal/testdata/TestCorrect_success +++ b/internal/testdata/TestCorrect_success @@ -16,7 +16,7 @@ { "discounts": [ { - "amount": "180.00", + "amount": "-180.00", "percent": "10%", "reason": "Special discount" } @@ -27,8 +27,8 @@ "price": "90.00", "unit": "h" }, - "quantity": "20", - "sum": "1800.00", + "quantity": "-20", + "sum": "-1800.00", "taxes": [ { "cat": "VAT", @@ -40,7 +40,7 @@ "percent": "15.0%" } ], - "total": "1620.00" + "total": "-1620.00" } ], "payment": { @@ -60,6 +60,10 @@ "preceding": [ { "code": "SAMPLE-001", + "correction_method": "complete", + "corrections": [ + "line" + ], "issue_date": "2022-02-01" } ], @@ -95,49 +99,49 @@ } }, "totals": { - "payable": "1717.20", - "sum": "1620.00", - "tax": "97.20", + "payable": "-1717.20", + "sum": "-1620.00", + "tax": "-97.20", "taxes": { "categories": [ { - "amount": "340.20", + "amount": "-340.20", "code": "VAT", "rates": [ { - "amount": "340.20", - "base": "1620.00", + "amount": "-340.20", + "base": "-1620.00", "key": "standard", "percent": "21.0%" } ] }, { - "amount": "243.00", + "amount": "-243.00", "code": "IRPF", "rates": [ { - "amount": "243.00", - "base": "1620.00", + "amount": "-243.00", + "base": "-1620.00", "percent": "15.0%" } ], "retained": true } ], - "sum": "97.20" + "sum": "-97.20" }, - "total": "1620.00", - "total_with_tax": "1717.20" + "total": "-1620.00", + "total_with_tax": "-1717.20" }, "type": "corrective" }, "head": { "dig": { "alg": "sha256", - "val": "df3d5393b2dbcfb6cc67dfafe7aec9d6dec4135c78ca9cf2c1c6f2c19536336c" + "val": "b10481852757289928a9e28046e0866cc04fa63f83591f066bf63321a1f35819" }, "draft": true, - "uuid": "c544855a-19ba-11ee-a150-3e7e00ce5635" + "uuid": "e5be59dc-1b17-11ee-9228-3e7e00ce5635" } } \ No newline at end of file diff --git a/internal/testdata/TestCorrect_success_just_invoice b/internal/testdata/TestCorrect_success_just_invoice new file mode 100644 index 0000000..a713fd0 --- /dev/null +++ b/internal/testdata/TestCorrect_success_just_invoice @@ -0,0 +1,136 @@ +{ + "$schema": "https://gobl.org/draft-0/bill/invoice", + "code": "", + "currency": "EUR", + "customer": { + "name": "Sample Consumer", + "tax_id": { + "code": "54387763P", + "country": "ES" + } + }, + "issue_date": "2023-04-17", + "lines": [ + { + "discounts": [ + { + "amount": "-180.00", + "percent": "10%", + "reason": "Special discount" + } + ], + "i": 1, + "item": { + "name": "Development services", + "price": "90.00", + "unit": "h" + }, + "quantity": "-20", + "sum": "-1800.00", + "taxes": [ + { + "cat": "VAT", + "percent": "21.0%", + "rate": "standard" + }, + { + "cat": "IRPF", + "percent": "15.0%" + } + ], + "total": "-1620.00" + } + ], + "payment": { + "instructions": { + "credit_transfer": [ + { + "iban": "ES06 0128 0011 3901 0008 1391", + "name": "Bankinter" + } + ], + "key": "credit-transfer" + }, + "terms": { + "key": "instant" + } + }, + "preceding": [ + { + "code": "SAMPLE-001", + "correction_method": "complete", + "corrections": [ + "line" + ], + "issue_date": "2022-02-01" + } + ], + "supplier": { + "addresses": [ + { + "code": "23480", + "country": "ES", + "locality": "CANENA", + "num": "9", + "region": "JAÉN", + "street": "CAMÍ MADRID" + } + ], + "emails": [ + { + "addr": "billing@example.com" + } + ], + "name": "MªF. Services", + "people": [ + { + "name": { + "given": "MARIA FRANCISCA", + "surname": "MONTERO", + "surname2": "ESTEBAN" + } + } + ], + "tax_id": { + "code": "58384285G", + "country": "ES" + } + }, + "totals": { + "payable": "-1717.20", + "sum": "-1620.00", + "tax": "-97.20", + "taxes": { + "categories": [ + { + "amount": "-340.20", + "code": "VAT", + "rates": [ + { + "amount": "-340.20", + "base": "-1620.00", + "key": "standard", + "percent": "21.0%" + } + ] + }, + { + "amount": "-243.00", + "code": "IRPF", + "rates": [ + { + "amount": "-243.00", + "base": "-1620.00", + "percent": "15.0%" + } + ], + "retained": true + } + ], + "sum": "-97.20" + }, + "total": "-1620.00", + "total_with_tax": "-1717.20" + }, + "type": "corrective" +} \ No newline at end of file