Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addenda Mabe in MX regime #219

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions bill/delivery.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package bill

import (
"context"

"github.com/invopop/gobl/cal"
"github.com/invopop/gobl/cbc"
"github.com/invopop/gobl/org"
Expand All @@ -20,9 +22,14 @@ type Delivery struct {
Meta *cbc.Meta `json:"meta,omitempty" jsonschema:"title=Meta"`
}

// Validate the delivery details
// Validate checks the delivery details
func (d *Delivery) Validate() error {
return validation.ValidateStruct(d,
return d.ValidateWithContext(context.Background())
}

// ValidateWithContext checks the delivery details
func (d *Delivery) ValidateWithContext(ctx context.Context) error {
return validation.ValidateStructWithContext(ctx, d,
validation.Field(&d.Receiver),
validation.Field(&d.Date),
validation.Field(&d.Period),
Expand Down
4 changes: 4 additions & 0 deletions bill/invoice.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ type Invoice struct {
// Additional complementary objects that add relevant information to the invoice.
Complements []*schema.Object `json:"complements,omitempty" jsonschema:"title=Complements"`

// Extension code map for any additional regime specific codes that may be required.
Ext cbc.CodeMap `json:"ext,omitempty" jsonschema:"title=Ext"`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a good place to store Mabe's reference1 and reference2 fields so I added this Ext codeMap at invoice level. The content of reference1 is a bit ambiguous, and changes depending on the case:

image

In the case of reference2 this is what the doc says: "Referencia adicional para uso futuro o bien "NA" o "0"".

Suggestions on a better place to put this data are welcome!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the addenda-mabe.yaml below to see it in context


// Additional semi-structured data that doesn't fit into the body of the invoice.
Meta cbc.Meta `json:"meta,omitempty" jsonschema:"title=Meta"`
}
Expand Down Expand Up @@ -144,6 +147,7 @@ func (inv *Invoice) ValidateWithContext(ctx context.Context) error {
validation.Field(&inv.Totals, validation.Required),

validation.Field(&inv.Notes),
validation.Field(&inv.Ext, tax.InRegimeExtensions),
validation.Field(&inv.Meta),

validation.Field(&inv.Complements, validation.Each()),
Expand Down
59 changes: 59 additions & 0 deletions regimes/mx/examples/addenda-mabe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
$schema: https://gobl.org/draft-0/bill/invoice
type: standard
series: LMC
code: '0010'
issue_date: '2023-05-29'
currency: MXN
supplier:
name: ESCUELA KEMPER URGATE
tax_id:
country: MX
zone: '26015'
code: EKU9003173C9
ext:
mx-cfdi-fiscal-regime: '601'
mx-mabe-provider-code: '123456'
customer:
name: UNIVERSIDAD ROBOTICA ESPAÑOLA
tax_id:
country: MX
zone: '65000'
code: URE180429TM6
ext:
mx-cfdi-fiscal-regime: '601'
mx-cfdi-use: G01
lines:
- i: 1
quantity: '2'
item:
name: Cigarros
price: '100.00'
ext:
mx-cfdi-prod-serv: '50211502'
mx-mabe-item-code: CODE123
discounts:
- percent: 10.0%
taxes:
- cat: VAT
rate: standard
- cat: RVAT
percent: 10.6667%
- cat: ISR
percent: 10%
payment:
instructions:
key: credit-transfer
delivery:
receiver:
name: ESTUFAS 30
addresses:
- street: Calle 1
locality: Mexico D.F.
code: '12345'
ext:
mx-mabe-delivery-plant: S001
ordering:
code: '9100000000'
ext:
mx-mabe-reference-1: '123456'
mx-mabe-reference-2: '789'
155 changes: 155 additions & 0 deletions regimes/mx/examples/out/addenda-mabe.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"$schema": "https://gobl.org/draft-0/envelope",
"head": {
"uuid": "8a51fd30-2a27-11ee-be56-0242ac120002",
"dig": {
"alg": "sha256",
"val": "3aa3b38d147021722253109fa8a6a54cb543611b6ed7528cbdaa9030ecb21359"
},
"draft": true
},
"doc": {
"$schema": "https://gobl.org/draft-0/bill/invoice",
"type": "standard",
"series": "LMC",
"code": "0010",
"issue_date": "2023-05-29",
"currency": "MXN",
"supplier": {
"name": "ESCUELA KEMPER URGATE",
"tax_id": {
"country": "MX",
"zone": "26015",
"code": "EKU9003173C9"
},
"ext": {
"mx-cfdi-fiscal-regime": "601",
"mx-mabe-provider-code": "123456"
}
},
"customer": {
"name": "UNIVERSIDAD ROBOTICA ESPAÑOLA",
"tax_id": {
"country": "MX",
"zone": "65000",
"code": "URE180429TM6"
},
"ext": {
"mx-cfdi-fiscal-regime": "601",
"mx-cfdi-use": "G01"
}
},
"lines": [
{
"i": 1,
"quantity": "2",
"item": {
"name": "Cigarros",
"price": "100.00",
"ext": {
"mx-cfdi-prod-serv": "50211502",
"mx-mabe-item-code": "CODE123"
}
},
"sum": "200.00",
"discounts": [
{
"percent": "10.0%",
"amount": "20.00"
}
],
"taxes": [
{
"cat": "VAT",
"rate": "standard",
"percent": "16.0%"
},
{
"cat": "RVAT",
"percent": "10.6667%"
},
{
"cat": "ISR",
"percent": "10%"
}
],
"total": "180.00"
}
],
"ordering": {
"code": "9100000000"
},
"payment": {
"instructions": {
"key": "credit-transfer"
}
},
"delivery": {
"receiver": {
"name": "ESTUFAS 30",
"addresses": [
{
"street": "Calle 1",
"locality": "Mexico D.F.",
"code": "12345"
}
],
"ext": {
"mx-mabe-delivery-plant": "S001"
}
}
},
"totals": {
"sum": "180.00",
"total": "180.00",
"taxes": {
"categories": [
{
"code": "VAT",
"rates": [
{
"key": "standard",
"base": "180.00",
"percent": "16.0%",
"amount": "28.80"
}
],
"amount": "28.80"
},
{
"code": "RVAT",
"retained": true,
"rates": [
{
"base": "180.00",
"percent": "10.6667%",
"amount": "19.20"
}
],
"amount": "19.20"
},
{
"code": "ISR",
"retained": true,
"rates": [
{
"base": "180.00",
"percent": "10%",
"amount": "18.00"
}
],
"amount": "18.00"
}
],
"sum": "-8.40"
},
"tax": "-8.40",
"total_with_tax": "171.60",
"payable": "171.60"
},
"ext": {
"mx-mabe-reference-1": "123456",
"mx-mabe-reference-2": "789"
}
}
}
72 changes: 72 additions & 0 deletions regimes/mx/extensions.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mx

import (
"github.com/invopop/gobl/bill"
"github.com/invopop/gobl/i18n"
"github.com/invopop/gobl/tax"
)
Expand All @@ -13,6 +14,15 @@ const (
ExtKeyCFDIProdServ = "mx-cfdi-prod-serv" // name from XML field: ClaveProdServ
)

// Mabe Addendum extension keys
const (
ExtKeyMabeProviderCode = "mx-mabe-provider-code"
ExtKeyMabeDeliveryPlant = "mx-mabe-delivery-plant"
ExtKeyMabeItemCode = "mx-mabe-item-code"
ExtKeyMabeReference1 = "mx-mabe-reference-1"
ExtKeyMabeReference2 = "mx-mabe-reference-2"
)

var extensionKeys = []*tax.KeyDefinition{
{
Key: ExtKeyCFDIProdServ,
Expand Down Expand Up @@ -333,4 +343,66 @@ var extensionKeys = []*tax.KeyDefinition{
},
},
},

// Mabe Addendum Extension Key Definitions
{
Key: ExtKeyMabeProviderCode,
Name: i18n.String{
i18n.EN: "Mabe’s Provider Code",
i18n.ES: "Código de Proveedor de Mabe", //nolint:misspell
},
Desc: i18n.String{
i18n.EN: "Code used by Mabe to identify the supplier.",
i18n.ES: "Código con el que Mabe identifica al proveedor.", //nolint:misspell
},
},
{
Key: ExtKeyMabeDeliveryPlant,
Name: i18n.String{
i18n.EN: "Mabe’s Delivery Plant ID",
i18n.ES: "ID de Planta de Entrega de Mabe", //nolint:misspell
},
Desc: i18n.String{
i18n.EN: "ID identifying the plant to which the invoice is addressed.",
i18n.ES: "ID con el que se identifica la planta a la cual está dirigida la factura.", //nolint:misspell
},
},
{
Key: ExtKeyMabeItemCode,
Name: i18n.String{
i18n.EN: "Mabe’s Item Code",
i18n.ES: "Código de Artículo de Mabe", //nolint:misspell
},
Desc: i18n.String{
i18n.EN: "Code used by Mabe to identify the item.",
i18n.ES: "Código con el que Mabe identifica el artículo.", //nolint:misspell
},
},
{
Key: ExtKeyMabeReference1,
Name: i18n.String{
i18n.EN: "Mabe’s Reference 1",
i18n.ES: "Referencia 1 de Mabe", //nolint:misspell
},
Desc: i18n.String{
i18n.EN: "Reference 1 used by Mabe.",
i18n.ES: "Referencia 1 utilizada por Mabe.", //nolint:misspell
},
},
{
Key: ExtKeyMabeReference2,
Name: i18n.String{
i18n.EN: "Mabe’s Reference 2",
i18n.ES: "Referencia 2 de Mabe", //nolint:misspell
},
Desc: i18n.String{
i18n.EN: "Reference 2 used by Mabe.",
i18n.ES: "Referencia 2 utilizada por Mabe.", //nolint:misspell
},
},
}

// IsMabeSupplier returns true if the invoice is from a Mabe supplier.
func IsMabeSupplier(inv *bill.Invoice) bool {
return inv != nil && inv.Supplier != nil && inv.Supplier.Ext.Has(ExtKeyMabeProviderCode)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function encapsulates the criteria to decide whether a MX GOBL invoice will produce a Mabe Addendum: if the supplier provides it's Mabe Supplier code, GOBL will validate that all the data required to generate the Mabe Addendum is present and the CFDI library will generate and attach the addendum to the CFDI.

}
Loading
Loading