From 33d32f7cd32e5893ce5ee1d78e5203f7576a2559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luismi=20Cavall=C3=A9?= Date: Tue, 3 Oct 2023 08:01:06 +0000 Subject: [PATCH 1/4] Add food vouchers complement to MX regime --- .../mx/examples/food-vouchers-complement.yaml | 54 ++++++++ .../out/food-vouchers-complement.json | 123 ++++++++++++++++++ regimes/mx/food_vouchers_complement.go | 122 +++++++++++++++++ regimes/mx/food_vouchers_complement_test.go | 70 ++++++++++ regimes/mx/mx.go | 5 +- 5 files changed, 373 insertions(+), 1 deletion(-) create mode 100644 regimes/mx/examples/food-vouchers-complement.yaml create mode 100644 regimes/mx/examples/out/food-vouchers-complement.json create mode 100644 regimes/mx/food_vouchers_complement.go create mode 100644 regimes/mx/food_vouchers_complement_test.go diff --git a/regimes/mx/examples/food-vouchers-complement.yaml b/regimes/mx/examples/food-vouchers-complement.yaml new file mode 100644 index 00000000..0700a5a2 --- /dev/null +++ b/regimes/mx/examples/food-vouchers-complement.yaml @@ -0,0 +1,54 @@ +$schema: "https://gobl.org/draft-0/bill/invoice" +issue_date: "2023-07-10" +series: "TEST" +code: "00002" +supplier: + name: "ESCUELA KEMPER URGATE" + ext: + mx-cfdi-fiscal-regime: "601" + tax_id: + country: "MX" + code: "EKU9003173C9" + zone: "21000" +customer: + name: "UNIVERSIDAD ROBOTICA ESPAÑOLA" + ext: + mx-cfdi-fiscal-regime: "601" + mx-cfdi-use: "G01" + tax_id: + country: "MX" + code: "URE180429TM6" + zone: "86991" +lines: + - quantity: "1" + item: + name: "Comisión servicio de monedero electrónico" + price: "10.00" + ext: + mx-cfdi-prod-serv: "84141602" + taxes: + - cat: "VAT" + rate: "standard" +payment: + terms: + notes: "Condiciones de pago" + instructions: + key: "online+wallet" +complements: + - $schema: "https://gobl.org/draft-0/regimes/mx/food-vouchers-complement" + employer_registration: "12345678901234567890" + account_number: "0123456789" + lines: + - e_wallet_id: "ABC1234" + issue_date_time: "2022-07-19T10:20:30" + employee_tax_code: "JUFA7608212V6" + employee_curp: "JUFA760821MDFRRR00" + employee_name: "Adriana Juarez Fernández" + employee_social_security: "12345678901" + amount: 10.123 + - e_wallet_id: "BCD4321" + issue_date_time: "2022-08-20T11:20:30" + employee_tax_code: "KAHO641101B39" + employee_curp: "KAHO641101HDFRRR00" + employee_name: "Oscar Kala Haak" + amount: 20.4 diff --git a/regimes/mx/examples/out/food-vouchers-complement.json b/regimes/mx/examples/out/food-vouchers-complement.json new file mode 100644 index 00000000..8c3331d6 --- /dev/null +++ b/regimes/mx/examples/out/food-vouchers-complement.json @@ -0,0 +1,123 @@ +{ + "$schema": "https://gobl.org/draft-0/envelope", + "head": { + "uuid": "8a51fd30-2a27-11ee-be56-0242ac120002", + "dig": { + "alg": "sha256", + "val": "51b99ed26d97e48f28365eed31e5166c8ed8a68f52c9db47c1e7708e53592c56" + }, + "draft": true + }, + "doc": { + "$schema": "https://gobl.org/draft-0/bill/invoice", + "type": "standard", + "series": "TEST", + "code": "00002", + "issue_date": "2023-07-10", + "currency": "MXN", + "supplier": { + "name": "ESCUELA KEMPER URGATE", + "tax_id": { + "country": "MX", + "zone": "21000", + "code": "EKU9003173C9" + }, + "ext": { + "mx-cfdi-fiscal-regime": "601" + } + }, + "customer": { + "name": "UNIVERSIDAD ROBOTICA ESPAÑOLA", + "tax_id": { + "country": "MX", + "zone": "86991", + "code": "URE180429TM6" + }, + "ext": { + "mx-cfdi-fiscal-regime": "601", + "mx-cfdi-use": "G01" + } + }, + "lines": [ + { + "i": 1, + "quantity": "1", + "item": { + "name": "Comisión servicio de monedero electrónico", + "price": "10.00", + "ext": { + "mx-cfdi-prod-serv": "84141602" + } + }, + "sum": "10.00", + "taxes": [ + { + "cat": "VAT", + "rate": "standard", + "percent": "16.0%" + } + ], + "total": "10.00" + } + ], + "payment": { + "terms": { + "notes": "Condiciones de pago" + }, + "instructions": { + "key": "online+wallet" + } + }, + "totals": { + "sum": "10.00", + "total": "10.00", + "taxes": { + "categories": [ + { + "code": "VAT", + "rates": [ + { + "key": "standard", + "base": "10.00", + "percent": "16.0%", + "amount": "1.60" + } + ], + "amount": "1.60" + } + ], + "sum": "1.60" + }, + "tax": "1.60", + "total_with_tax": "11.60", + "payable": "11.60" + }, + "complements": [ + { + "$schema": "https://gobl.org/draft-0/regimes/mx/food-vouchers-complement", + "employer_registration": "12345678901234567890", + "account_number": "0123456789", + "total": "30.52", + "lines": [ + { + "e_wallet_id": "ABC1234", + "issue_date_time": "2022-07-19T10:20:30", + "employee_tax_code": "JUFA7608212V6", + "employee_curp": "JUFA760821MDFRRR00", + "employee_name": "Adriana Juarez Fernández", + "employee_social_security": "12345678901", + "amount": "10.12" + }, + { + "e_wallet_id": "BCD4321", + "issue_date_time": "2022-08-20T11:20:30", + "employee_tax_code": "KAHO641101B39", + "employee_curp": "KAHO641101HDFRRR00", + "employee_name": "Oscar Kala Haak", + "amount": "20.40" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/regimes/mx/food_vouchers_complement.go b/regimes/mx/food_vouchers_complement.go new file mode 100644 index 00000000..67e5b28c --- /dev/null +++ b/regimes/mx/food_vouchers_complement.go @@ -0,0 +1,122 @@ +package mx + +import ( + "regexp" + + "github.com/invopop/gobl/cal" + "github.com/invopop/gobl/cbc" + "github.com/invopop/gobl/num" + "github.com/invopop/validation" +) + +// Constants for the precision of the complement's amounts +const ( + FoodVouchersFinalPrecision = 2 +) + +// Complement's Codes Patterns +const ( + CURPPattern = "^[A-Z][A,E,I,O,U,X][A-Z]{2}[0-9]{2}[0-1][0-9][0-3][0-9][M,H][A-Z]{2}[B,C,D,F,G,H,J,K,L,M,N,Ñ,P,Q,R,S,T,V,W,X,Y,Z]{3}[0-9,A-Z][0-9]$" + SocialSecurityPattern = "^[0-9]{11}$" +) + +// Complement's Codes Regexps +var ( + CURPRegexp = regexp.MustCompile(CURPPattern) + SocialSecurityRegexp = regexp.MustCompile(SocialSecurityPattern) +) + +// FoodVouchersComplement carries the data to produce a CFDI's "Complemento de +// Vales de Despensa" (version 1.0) providing detailed information about food +// vouchers issued by an e-wallet supplier to its customer's employees. +// +// This struct maps to the `ValesDeDespensa` root node in the CFDI's complement. +type FoodVouchersComplement struct { + // Customer's employer registration number (maps to `registroPatronal`). + EmployerRegistration string `json:"employer_registration,omitempty" jsonschema:"title=Employer Registration"` + // Customer's account number (maps to `numeroDeCuenta`). + AccountNumber string `json:"account_number" jsonschema:"title=Account Number"` + // Sum of all line amounts (calculated, maps to `total`). + Total num.Amount `json:"total" jsonschema:"title=Total" jsonschema_extras:"calculated=true"` + // List of food vouchers issued to the customer's employees (maps to `Conceptos`). + Lines []*FoodVouchersLine `json:"lines" jsonschema:"title=Lines"` +} + +// FoodVouchersLine represents a single food voucher issued to the e-wallet of +// one of the customer's employees. It maps to one `Concepto` node in the CFDI's +// complement. +type FoodVouchersLine struct { + // Identifier of the e-wallet that received the food voucher (maps to `Identificador`). + EWalletID cbc.Code `json:"e_wallet_id" jsonschema:"title=E-wallet Identifier"` + // Date and time of the food voucher's issue (maps to `Fecha`). + IssueDateTime cal.DateTime `json:"issue_date_time" jsonschema:"title=Issue Date and Time"` + // Employee's tax identity code (maps to `rfc`). + EmployeeTaxCode cbc.Code `json:"employee_tax_code" jsonschema:"title=Employee's Tax Identity Code"` + // Employee's CURP ("Clave Única de Registro de Población", maps to `curp`). + EmployeeCURP cbc.Code `json:"employee_curp" jsonschema:"title=Employee's CURP"` + // Employee's name (maps to `nombre`). + EmployeeName string `json:"employee_name" jsonschema:"title=Employee's Name"` + // Employee's Social Security Number (maps to `numSeguridadSocial`). + EmployeeSocialSecurity cbc.Code `json:"employee_social_security,omitempty" jsonschema:"title=Employee's Social Security Number"` + // Amount of the food voucher (maps to `importe`). + Amount num.Amount `json:"amount" jsonschema:"title=Amount"` +} + +// Validate checks the FoodVouchersComplement data according to the SAT's +// rules for the "Complemento de Vales de Despensa". +func (fvc *FoodVouchersComplement) Validate() error { + return validation.ValidateStruct(fvc, + validation.Field(&fvc.EmployerRegistration, validation.Length(0, 20)), + validation.Field(&fvc.AccountNumber, + validation.Required, + validation.Length(0, 20), + ), + validation.Field(&fvc.Total, validation.Required), + validation.Field(&fvc.Lines, + validation.Required, + validation.Each(validation.By(validateFoodVouchersLine)), + ), + ) +} + +func validateFoodVouchersLine(value interface{}) error { + line := value.(*FoodVouchersLine) + if line == nil { + return nil + } + + return validation.ValidateStruct(line, + validation.Field(&line.EWalletID, + validation.Required, + validation.Length(0, 20), + ), + validation.Field(&line.IssueDateTime, cal.DateTimeNotZero()), + validation.Field(&line.EmployeeTaxCode, + validation.Required, + validation.By(validateTaxCode), + ), + validation.Field(&line.EmployeeCURP, + validation.Required, + validation.Match(CURPRegexp), + ), + validation.Field(&line.EmployeeName, + validation.Required, + validation.Length(0, 100), + ), + validation.Field(&line.EmployeeSocialSecurity, validation.Match(SocialSecurityRegexp)), + validation.Field(&line.Amount, validation.Required), + ) +} + +// Calculate performs the complement's calculations and normalisations. +func (fvc *FoodVouchersComplement) Calculate() error { + fvc.Total = num.MakeAmount(0, FoodVouchersFinalPrecision) + + for _, l := range fvc.Lines { + l.Amount = l.Amount.Rescale(FoodVouchersFinalPrecision) + + fvc.Total = fvc.Total.Add(l.Amount) + } + + return nil +} diff --git a/regimes/mx/food_vouchers_complement_test.go b/regimes/mx/food_vouchers_complement_test.go new file mode 100644 index 00000000..1d0d4a4f --- /dev/null +++ b/regimes/mx/food_vouchers_complement_test.go @@ -0,0 +1,70 @@ +package mx_test + +import ( + "testing" + + "github.com/invopop/gobl/num" + "github.com/invopop/gobl/regimes/mx" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestInvalidFoodVouchersComplement(t *testing.T) { + fvc := &mx.FoodVouchersComplement{} + + err := fvc.Validate() + + require.Error(t, err) + assert.Contains(t, err.Error(), "account_number: cannot be blank") + assert.Contains(t, err.Error(), "lines: cannot be blank") + + fvc.EmployerRegistration = "123456789012345678901" + fvc.AccountNumber = "012345678901234567891" + + err = fvc.Validate() + + require.Error(t, err) + assert.Contains(t, err.Error(), "employer_registration: the length must be no more than 20") + assert.Contains(t, err.Error(), "account_number: the length must be no more than 20") +} + +func TestInvalidFoodVouchersLine(t *testing.T) { + fvc := &mx.FoodVouchersComplement{Lines: []*mx.FoodVouchersLine{{}}} + + err := fvc.Validate() + + require.Error(t, err) + assert.Contains(t, err.Error(), "e_wallet_id: cannot be blank") + assert.Contains(t, err.Error(), "issue_date_time: required") + assert.Contains(t, err.Error(), "employee_tax_code: cannot be blank") + assert.Contains(t, err.Error(), "employee_curp: cannot be blank") + assert.Contains(t, err.Error(), "employee_name: cannot be blank") + + fvc.Lines[0].EWalletID = "123456789012345678901" + fvc.Lines[0].EmployeeTaxCode = "INVALID1" + fvc.Lines[0].EmployeeCURP = "INVALID2" + fvc.Lines[0].EmployeeSocialSecurity = "INVALID3" + + err = fvc.Validate() + + require.Error(t, err) + assert.Contains(t, err.Error(), "e_wallet_id: the length must be no more than 20") + assert.Contains(t, err.Error(), "employee_tax_code: invalid tax identity code") + assert.Contains(t, err.Error(), "employee_curp: must be in a valid format") + assert.Contains(t, err.Error(), "employee_social_security: must be in a valid format") +} + +func TestCalculateFoodVouchersComplement(t *testing.T) { + fvc := &mx.FoodVouchersComplement{ + Lines: []*mx.FoodVouchersLine{ + {Amount: num.MakeAmount(1234, 3)}, + {Amount: num.MakeAmount(4321, 3)}, + }, + } + + err := fvc.Calculate() + + require.NoError(t, err) + assert.Equal(t, num.MakeAmount(123, 2), fvc.Lines[0].Amount) + assert.Equal(t, num.MakeAmount(555, 2), fvc.Total) +} diff --git a/regimes/mx/mx.go b/regimes/mx/mx.go index 09a88c0a..5fbd38c0 100644 --- a/regimes/mx/mx.go +++ b/regimes/mx/mx.go @@ -17,7 +17,10 @@ func init() { tax.RegisterRegime(New()) // MX GOBL Schema Complements - schema.Register(schema.GOBL.Add("regimes/mx"), FuelAccountBalance{}) + schema.Register(schema.GOBL.Add("regimes/mx"), + FuelAccountBalance{}, + FoodVouchersComplement{}, + ) } // Custom keys used typically in meta or codes information. From 90eaae82147fe06b95f7322ecfb563971bf50cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luismi=20Cavall=C3=A9?= Date: Tue, 3 Oct 2023 09:47:30 +0000 Subject: [PATCH 2/4] Extract employee fields into separated struct --- .../mx/examples/food-vouchers-complement.yaml | 16 ++++--- .../out/food-vouchers-complement.json | 20 +++++---- regimes/mx/food_vouchers_complement.go | 45 ++++++++++++++----- regimes/mx/food_vouchers_complement_test.go | 32 +++++++++---- 4 files changed, 78 insertions(+), 35 deletions(-) diff --git a/regimes/mx/examples/food-vouchers-complement.yaml b/regimes/mx/examples/food-vouchers-complement.yaml index 0700a5a2..846f2080 100644 --- a/regimes/mx/examples/food-vouchers-complement.yaml +++ b/regimes/mx/examples/food-vouchers-complement.yaml @@ -41,14 +41,16 @@ complements: lines: - e_wallet_id: "ABC1234" issue_date_time: "2022-07-19T10:20:30" - employee_tax_code: "JUFA7608212V6" - employee_curp: "JUFA760821MDFRRR00" - employee_name: "Adriana Juarez Fernández" - employee_social_security: "12345678901" + employee: + tax_code: "JUFA7608212V6" + curp: "JUFA760821MDFRRR00" + name: "Adriana Juarez Fernández" + social_security: "12345678901" amount: 10.123 - e_wallet_id: "BCD4321" issue_date_time: "2022-08-20T11:20:30" - employee_tax_code: "KAHO641101B39" - employee_curp: "KAHO641101HDFRRR00" - employee_name: "Oscar Kala Haak" + employee: + tax_code: "KAHO641101B39" + curp: "KAHO641101HDFRRR00" + name: "Oscar Kala Haak" amount: 20.4 diff --git a/regimes/mx/examples/out/food-vouchers-complement.json b/regimes/mx/examples/out/food-vouchers-complement.json index 8c3331d6..4c3a5db1 100644 --- a/regimes/mx/examples/out/food-vouchers-complement.json +++ b/regimes/mx/examples/out/food-vouchers-complement.json @@ -4,7 +4,7 @@ "uuid": "8a51fd30-2a27-11ee-be56-0242ac120002", "dig": { "alg": "sha256", - "val": "51b99ed26d97e48f28365eed31e5166c8ed8a68f52c9db47c1e7708e53592c56" + "val": "91514018429e4d46deb1f689658d361ae4870ac5e5aa76133018086fb923e31b" }, "draft": true }, @@ -102,18 +102,22 @@ { "e_wallet_id": "ABC1234", "issue_date_time": "2022-07-19T10:20:30", - "employee_tax_code": "JUFA7608212V6", - "employee_curp": "JUFA760821MDFRRR00", - "employee_name": "Adriana Juarez Fernández", - "employee_social_security": "12345678901", + "employee": { + "tax_code": "JUFA7608212V6", + "curp": "JUFA760821MDFRRR00", + "name": "Adriana Juarez Fernández", + "social_security": "12345678901" + }, "amount": "10.12" }, { "e_wallet_id": "BCD4321", "issue_date_time": "2022-08-20T11:20:30", - "employee_tax_code": "KAHO641101B39", - "employee_curp": "KAHO641101HDFRRR00", - "employee_name": "Oscar Kala Haak", + "employee": { + "tax_code": "KAHO641101B39", + "curp": "KAHO641101HDFRRR00", + "name": "Oscar Kala Haak" + }, "amount": "20.40" } ] diff --git a/regimes/mx/food_vouchers_complement.go b/regimes/mx/food_vouchers_complement.go index 67e5b28c..9df2afc5 100644 --- a/regimes/mx/food_vouchers_complement.go +++ b/regimes/mx/food_vouchers_complement.go @@ -50,16 +50,24 @@ type FoodVouchersLine struct { EWalletID cbc.Code `json:"e_wallet_id" jsonschema:"title=E-wallet Identifier"` // Date and time of the food voucher's issue (maps to `Fecha`). IssueDateTime cal.DateTime `json:"issue_date_time" jsonschema:"title=Issue Date and Time"` + // Employee that received the food voucher. + Employee *FoodVouchersEmployee `json:"employee,omitempty" jsonschema:"title=Employee"` + // Amount of the food voucher (maps to `importe`). + Amount num.Amount `json:"amount" jsonschema:"title=Amount"` +} + +// FoodVouchersEmployee represents an employee that received a food voucher. It +// groups employee related field that appears under the `Concepto` node in the +// CFDI's complement. +type FoodVouchersEmployee struct { // Employee's tax identity code (maps to `rfc`). - EmployeeTaxCode cbc.Code `json:"employee_tax_code" jsonschema:"title=Employee's Tax Identity Code"` + TaxCode cbc.Code `json:"tax_code" jsonschema:"title=Employee's Tax Identity Code"` // Employee's CURP ("Clave Única de Registro de Población", maps to `curp`). - EmployeeCURP cbc.Code `json:"employee_curp" jsonschema:"title=Employee's CURP"` + CURP cbc.Code `json:"curp" jsonschema:"title=Employee's CURP"` // Employee's name (maps to `nombre`). - EmployeeName string `json:"employee_name" jsonschema:"title=Employee's Name"` + Name string `json:"name" jsonschema:"title=Employee's Name"` // Employee's Social Security Number (maps to `numSeguridadSocial`). - EmployeeSocialSecurity cbc.Code `json:"employee_social_security,omitempty" jsonschema:"title=Employee's Social Security Number"` - // Amount of the food voucher (maps to `importe`). - Amount num.Amount `json:"amount" jsonschema:"title=Amount"` + SocialSecurity cbc.Code `json:"social_security,omitempty" jsonschema:"title=Employee's Social Security Number"` } // Validate checks the FoodVouchersComplement data according to the SAT's @@ -91,20 +99,35 @@ func validateFoodVouchersLine(value interface{}) error { validation.Length(0, 20), ), validation.Field(&line.IssueDateTime, cal.DateTimeNotZero()), - validation.Field(&line.EmployeeTaxCode, + validation.Field(&line.Employee, + validation.Required, + validation.By(validateFoodVouchersEmployee)), + validation.Field(&line.Amount, validation.Required), + ) +} + +func validateFoodVouchersEmployee(value interface{}) error { + employee := value.(*FoodVouchersEmployee) + if employee == nil { + return nil + } + + return validation.ValidateStruct(employee, + validation.Field(&employee.TaxCode, validation.Required, validation.By(validateTaxCode), ), - validation.Field(&line.EmployeeCURP, + validation.Field(&employee.CURP, validation.Required, validation.Match(CURPRegexp), ), - validation.Field(&line.EmployeeName, + validation.Field(&employee.Name, validation.Required, validation.Length(0, 100), ), - validation.Field(&line.EmployeeSocialSecurity, validation.Match(SocialSecurityRegexp)), - validation.Field(&line.Amount, validation.Required), + validation.Field(&employee.SocialSecurity, + validation.Match(SocialSecurityRegexp), + ), ) } diff --git a/regimes/mx/food_vouchers_complement_test.go b/regimes/mx/food_vouchers_complement_test.go index 1d0d4a4f..b3e2651b 100644 --- a/regimes/mx/food_vouchers_complement_test.go +++ b/regimes/mx/food_vouchers_complement_test.go @@ -36,22 +36,36 @@ func TestInvalidFoodVouchersLine(t *testing.T) { require.Error(t, err) assert.Contains(t, err.Error(), "e_wallet_id: cannot be blank") assert.Contains(t, err.Error(), "issue_date_time: required") - assert.Contains(t, err.Error(), "employee_tax_code: cannot be blank") - assert.Contains(t, err.Error(), "employee_curp: cannot be blank") - assert.Contains(t, err.Error(), "employee_name: cannot be blank") + assert.Contains(t, err.Error(), "employee: cannot be blank") fvc.Lines[0].EWalletID = "123456789012345678901" - fvc.Lines[0].EmployeeTaxCode = "INVALID1" - fvc.Lines[0].EmployeeCURP = "INVALID2" - fvc.Lines[0].EmployeeSocialSecurity = "INVALID3" err = fvc.Validate() require.Error(t, err) assert.Contains(t, err.Error(), "e_wallet_id: the length must be no more than 20") - assert.Contains(t, err.Error(), "employee_tax_code: invalid tax identity code") - assert.Contains(t, err.Error(), "employee_curp: must be in a valid format") - assert.Contains(t, err.Error(), "employee_social_security: must be in a valid format") +} + +func TestInvalidFoodVouchersEmployee(t *testing.T) { + fvc := &mx.FoodVouchersComplement{Lines: []*mx.FoodVouchersLine{{Employee: &mx.FoodVouchersEmployee{}}}} + + err := fvc.Validate() + + require.Error(t, err) + assert.Contains(t, err.Error(), "tax_code: cannot be blank") + assert.Contains(t, err.Error(), "curp: cannot be blank") + assert.Contains(t, err.Error(), "name: cannot be blank") + + fvc.Lines[0].Employee.TaxCode = "INVALID1" + fvc.Lines[0].Employee.CURP = "INVALID2" + fvc.Lines[0].Employee.SocialSecurity = "INVALID3" + + err = fvc.Validate() + + require.Error(t, err) + assert.Contains(t, err.Error(), "tax_code: invalid tax identity code") + assert.Contains(t, err.Error(), "curp: must be in a valid format") + assert.Contains(t, err.Error(), "social_security: must be in a valid format") } func TestCalculateFoodVouchersComplement(t *testing.T) { From cf731682be406597e950f89374bba9a719243acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luismi=20Cavall=C3=A9?= Date: Tue, 3 Oct 2023 14:00:04 +0000 Subject: [PATCH 3/4] Simplify sub-struct validations --- regimes/mx/food_vouchers_complement.go | 41 ++++++++------------------ 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/regimes/mx/food_vouchers_complement.go b/regimes/mx/food_vouchers_complement.go index 9df2afc5..98f54c30 100644 --- a/regimes/mx/food_vouchers_complement.go +++ b/regimes/mx/food_vouchers_complement.go @@ -80,52 +80,37 @@ func (fvc *FoodVouchersComplement) Validate() error { validation.Length(0, 20), ), validation.Field(&fvc.Total, validation.Required), - validation.Field(&fvc.Lines, - validation.Required, - validation.Each(validation.By(validateFoodVouchersLine)), - ), + validation.Field(&fvc.Lines, validation.Required), ) } -func validateFoodVouchersLine(value interface{}) error { - line := value.(*FoodVouchersLine) - if line == nil { - return nil - } - - return validation.ValidateStruct(line, - validation.Field(&line.EWalletID, +func (fvl *FoodVouchersLine) Validate() error { + return validation.ValidateStruct(fvl, + validation.Field(&fvl.EWalletID, validation.Required, validation.Length(0, 20), ), - validation.Field(&line.IssueDateTime, cal.DateTimeNotZero()), - validation.Field(&line.Employee, - validation.Required, - validation.By(validateFoodVouchersEmployee)), - validation.Field(&line.Amount, validation.Required), + validation.Field(&fvl.IssueDateTime, cal.DateTimeNotZero()), + validation.Field(&fvl.Employee, validation.Required), + validation.Field(&fvl.Amount, validation.Required), ) } -func validateFoodVouchersEmployee(value interface{}) error { - employee := value.(*FoodVouchersEmployee) - if employee == nil { - return nil - } - - return validation.ValidateStruct(employee, - validation.Field(&employee.TaxCode, +func (fve *FoodVouchersEmployee) Validate() error { + return validation.ValidateStruct(fve, + validation.Field(&fve.TaxCode, validation.Required, validation.By(validateTaxCode), ), - validation.Field(&employee.CURP, + validation.Field(&fve.CURP, validation.Required, validation.Match(CURPRegexp), ), - validation.Field(&employee.Name, + validation.Field(&fve.Name, validation.Required, validation.Length(0, 100), ), - validation.Field(&employee.SocialSecurity, + validation.Field(&fve.SocialSecurity, validation.Match(SocialSecurityRegexp), ), ) From 19be3ea56506b2c84f06a2b00911e36869148b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luismi=20Cavall=C3=A9?= Date: Tue, 3 Oct 2023 14:03:22 +0000 Subject: [PATCH 4/4] Add missing comments to public methods --- regimes/mx/food_vouchers_complement.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/regimes/mx/food_vouchers_complement.go b/regimes/mx/food_vouchers_complement.go index 98f54c30..a9b45667 100644 --- a/regimes/mx/food_vouchers_complement.go +++ b/regimes/mx/food_vouchers_complement.go @@ -84,6 +84,7 @@ func (fvc *FoodVouchersComplement) Validate() error { ) } +// Validate checks the FoodVouchersLine data is valid. func (fvl *FoodVouchersLine) Validate() error { return validation.ValidateStruct(fvl, validation.Field(&fvl.EWalletID, @@ -96,6 +97,7 @@ func (fvl *FoodVouchersLine) Validate() error { ) } +// Validate checks the FoodVouchersEmployee data is valid. func (fve *FoodVouchersEmployee) Validate() error { return validation.ValidateStruct(fve, validation.Field(&fve.TaxCode,