diff --git a/README.md b/README.md index e2c89f5c..73d1d130 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ GOBL makes it easy to create business documents, like invoices, but checkout som - [GOBL for Ruby](https://github.com/invopop/gobl.ruby) - Easily build or read GOBL documents in Ruby. Conversion to local formats + - [GOBL to FacturaE (Spain)](https://github.com/invopop/gobl.facturae) - convert into the [Spanish FacturaE](https://www.facturae.gob.es/Paginas/Index.aspx) format. - [GOBL to CFDI (Mexico)](https://github.com/invopop/gobl.cfdi) - convert into the Mexican CFDI format. - [GOBL to FatturaPA (Italy)](https://github.com/invopop/gobl.fatturapa) - convert into the [Italian FatturaPA](https://www.fatturapa.gov.it/it/index.html) format. @@ -139,3 +140,11 @@ if err := env.Insert(inv); err != nil { panic(err) } ``` + +## Development + +GOBL uses the `go generate` command to automatically generate JSON schemas, definitions, and some Go code output. After any changes, be sure to run: + +```bash +go generate . +``` diff --git a/currency/README.md b/currency/README.md index e2da82b5..5f4f8710 100644 --- a/currency/README.md +++ b/currency/README.md @@ -1,8 +1,7 @@ # Currency Reference Data -Data sourced from ISO website and providers. +Currency support in GOBL aims to cover most of the currencies in the world and provide methods to format and work with them. -## ISO 4217 - -Currency code data sourced from: https://www.iso.org/iso-4217-currency-codes.html +Much of the inspiration for this package and source data in the `/data/currency` directory originally came from the excellent and widely used [money gem in ruby](https://rubymoney.github.io/money/). A few alterations to source data have been made. +Currencies around the world change more often than expected, please [send a PR](https://github.com/invopop/gobl/pulls) if you spot anything that is out of date, along with a link that references the source of the change. diff --git a/currency/code.go b/currency/code.go index c31ce13e..676606a2 100644 --- a/currency/code.go +++ b/currency/code.go @@ -1,9 +1,9 @@ package currency import ( - "github.com/invopop/gobl/num" + "fmt" + "github.com/invopop/jsonschema" - "github.com/invopop/validation" ) // Code is the ISO currency code @@ -12,59 +12,25 @@ type Code string // CodeEmpty is used when there is no code. const CodeEmpty Code = "" -// Def provides a structure for the currencies -type Def struct { - Code Code `json:"code"` // three-letter currency code - Name string `json:"name"` // name of the currency - Num string `json:"num"` // three-digit currency code - Units uint32 `json:"units"` // how many cents are used for the currency -} - -func validCodes() []interface{} { - list := make([]interface{}, len(CodeDefinitions)) - for i, d := range CodeDefinitions { - list[i] = string(d.Code) - } - return list -} - -var isValidCode = validation.In(validCodes()...) - // Validate ensures the currency code is valid according // to the ISO 4217 three-letter list. func (c Code) Validate() error { - return validation.Validate(string(c), isValidCode) + return inDefinitions(c) } -// Def provides the currency definition for the code. -func (c Code) Def() Def { - d, _ := Get(c) - return d -} - -// Get provides the code's currency definition, or -// false if none is found. -func Get(c Code) (Def, bool) { - for _, d := range CodeDefinitions { - if d.Code == c { - return d, true - } +func inDefinitions(code Code) error { + if code == CodeEmpty { + return nil } - return Def{}, false -} - -// Zero provides the currency's zero amount which is pre-set with the -// minimum precision for the currency. -func (d Def) Zero() num.Amount { - return num.MakeAmount(0, d.Units) + if d := Get(code); d == nil { + return fmt.Errorf("currency code %s not defined", code) + } + return nil } -// BaseAmount provides a definition's zero amount with the correct decimal -// places so that it can be used as a base for calculating totals. -// -// Deprecated: please now use the Zero method instead. -func (d Def) BaseAmount() num.Amount { - return num.MakeAmount(0, d.Units) +// Def provides the currency definition for the code. +func (c Code) Def() *Def { + return Get(c) } // JSONSchema provides a representation of the struct for usage in Schema. @@ -72,12 +38,12 @@ func (Code) JSONSchema() *jsonschema.Schema { s := &jsonschema.Schema{ Title: "Currency Code", Type: "string", - OneOf: make([]*jsonschema.Schema, len(CodeDefinitions)), - Description: "ISO Currency Code", + OneOf: make([]*jsonschema.Schema, len(Definitions())), + Description: "Currency Code as defined in the GOBL source which is expected to be ISO or commonly used alternative.", } - for i, v := range CodeDefinitions { + for i, v := range Definitions() { s.OneOf[i] = &jsonschema.Schema{ - Const: v.Code, + Const: v.ISOCode, Title: v.Name, } } diff --git a/currency/code_test.go b/currency/code_test.go index fbbf5018..12264821 100644 --- a/currency/code_test.go +++ b/currency/code_test.go @@ -5,6 +5,7 @@ import ( "github.com/invopop/gobl/currency" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCode(t *testing.T) { @@ -13,4 +14,12 @@ func TestCode(t *testing.T) { d := c.Def() assert.Equal(t, d.Name, "Euro") + + c = currency.CodeEmpty + assert.NoError(t, c.Validate()) + + c = currency.Code("FOOO") + err := c.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), "currency code FOOO not defined") } diff --git a/currency/codes.go b/currency/codes.go index bb23829e..eaeca8eb 100644 --- a/currency/codes.go +++ b/currency/codes.go @@ -1,1177 +1,367 @@ -package currency +// Code generated by "go run ./currency/generate.go"; DO NOT EDIT. -// **** NOTICE! **** -// This file is auto-generated. Any manual changes will be overwritten. -// Generated on 2022-07-27 10:06:00.631266832 +0000 UTC -// ***************** +package currency -// List of ISO4217 currency codes. +// List of ISO4217 and common currency codes. const ( - AED Code = "AED" - AFN Code = "AFN" - ALL Code = "ALL" - AMD Code = "AMD" - ANG Code = "ANG" - AOA Code = "AOA" - ARS Code = "ARS" + // United States Dollar ($) + USD Code = "USD" + // Euro (€) + EUR Code = "EUR" + // British Pound (£) + GBP Code = "GBP" + // Australian Dollar ($) AUD Code = "AUD" - AWG Code = "AWG" + // Canadian Dollar ($) + CAD Code = "CAD" + // Japanese Yen (¥) + JPY Code = "JPY" + // Belarusian Ruble (Br) + BYR Code = "BYR" + // Macanese Pataca (P) + MOP Code = "MOP" + // Haitian Gourde (G) + HTG Code = "HTG" + // Azerbaijani Manat (₼) AZN Code = "AZN" + // Bosnia and Herzegovina Convertible Mark (КМ) BAM Code = "BAM" + // Barbadian Dollar ($) BBD Code = "BBD" + // Bangladeshi Taka (৳) BDT Code = "BDT" + // Bulgarian Lev (лв.) BGN Code = "BGN" + // Bahraini Dinar (د.ب) BHD Code = "BHD" + // Burundian Franc (Fr) BIF Code = "BIF" + // Bermudian Dollar ($) BMD Code = "BMD" + // Brunei Dollar ($) BND Code = "BND" + // Bolivian Boliviano (Bs.) BOB Code = "BOB" - BOV Code = "BOV" + // Brazilian Real (R$) BRL Code = "BRL" + // Bahamian Dollar ($) BSD Code = "BSD" + // Bhutanese Ngultrum (Nu.) BTN Code = "BTN" + // Botswana Pula (P) BWP Code = "BWP" + // Belarusian Ruble (Br) BYN Code = "BYN" + // Argentine Peso ($) + ARS Code = "ARS" + // Belize Dollar ($) BZD Code = "BZD" - CAD Code = "CAD" + // Angolan Kwanza (Kz) + AOA Code = "AOA" + // Congolese Franc (Fr) CDF Code = "CDF" - CHE Code = "CHE" + // Swiss Franc (CHF) CHF Code = "CHF" - CHW Code = "CHW" + // Unidad de Fomento (UF) CLF Code = "CLF" + // Chilean Peso ($) CLP Code = "CLP" + // Chinese Renminbi Yuan (¥) CNY Code = "CNY" + // Colombian Peso ($) COP Code = "COP" - COU Code = "COU" + // Costa Rican Colón (₡) CRC Code = "CRC" + // Cuban Convertible Peso ($) CUC Code = "CUC" + // Cuban Peso ($) CUP Code = "CUP" + // Cape Verdean Escudo ($) CVE Code = "CVE" + // Czech Koruna (Kč) CZK Code = "CZK" + // Djiboutian Franc (Fdj) DJF Code = "DJF" + // Danish Krone (kr.) DKK Code = "DKK" - DOP Code = "DOP" + // Mexican Peso ($) + MXN Code = "MXN" + // Algerian Dinar (د.ج) DZD Code = "DZD" + // Egyptian Pound (ج.م) EGP Code = "EGP" + // Eritrean Nakfa (Nfk) ERN Code = "ERN" + // Ethiopian Birr (Br) ETB Code = "ETB" - EUR Code = "EUR" + // Netherlands Antillean Gulden (ƒ) + ANG Code = "ANG" + // Fijian Dollar ($) FJD Code = "FJD" + // Falkland Pound (£) FKP Code = "FKP" - GBP Code = "GBP" + // Armenian Dram (դր.) + AMD Code = "AMD" + // Georgian Lari (₾) GEL Code = "GEL" + // Ghanaian Cedi (₵) GHS Code = "GHS" + // Gibraltar Pound (£) GIP Code = "GIP" + // Gambian Dalasi (D) GMD Code = "GMD" + // Guinean Franc (Fr) GNF Code = "GNF" + // Guatemalan Quetzal (Q) GTQ Code = "GTQ" + // Guyanese Dollar ($) GYD Code = "GYD" + // Hong Kong Dollar ($) HKD Code = "HKD" + // Honduran Lempira (L) HNL Code = "HNL" - HRK Code = "HRK" - HTG Code = "HTG" + // Malawian Kwacha (MK) + MWK Code = "MWK" + // Hungarian Forint (Ft) HUF Code = "HUF" + // Indonesian Rupiah (Rp) IDR Code = "IDR" + // Israeli New Sheqel (₪) ILS Code = "ILS" + // Indian Rupee (₹) INR Code = "INR" + // Iraqi Dinar (ع.د) IQD Code = "IQD" + // Iranian Rial (﷼) IRR Code = "IRR" + // Icelandic Króna (kr.) ISK Code = "ISK" + // Jamaican Dollar ($) JMD Code = "JMD" + // Jordanian Dinar (د.ا) JOD Code = "JOD" - JPY Code = "JPY" + // Albanian Lek (L) + ALL Code = "ALL" + // Kenyan Shilling (KSh) KES Code = "KES" + // Kyrgyzstani Som (som) KGS Code = "KGS" + // Cambodian Riel (៛) KHR Code = "KHR" + // Comorian Franc (Fr) KMF Code = "KMF" + // North Korean Won (₩) KPW Code = "KPW" + // South Korean Won (₩) KRW Code = "KRW" + // Kuwaiti Dinar (د.ك) KWD Code = "KWD" + // Cayman Islands Dollar ($) KYD Code = "KYD" + // Kazakhstani Tenge (₸) KZT Code = "KZT" + // Lao Kip (₭) LAK Code = "LAK" + // Lebanese Pound (ل.ل) LBP Code = "LBP" + // Sri Lankan Rupee (₨) LKR Code = "LKR" + // Liberian Dollar ($) LRD Code = "LRD" + // Lesotho Loti (L) LSL Code = "LSL" + // Libyan Dinar (ل.د) LYD Code = "LYD" + // Moroccan Dirham (د.م.) MAD Code = "MAD" + // Moldovan Leu (L) MDL Code = "MDL" + // Malagasy Ariary (Ar) MGA Code = "MGA" + // Macedonian Denar (ден) MKD Code = "MKD" + // Myanmar Kyat (K) MMK Code = "MMK" + // Mongolian Tögrög (₮) MNT Code = "MNT" - MOP Code = "MOP" + // United Arab Emirates Dirham (د.إ) + AED Code = "AED" + // Mauritanian Ouguiya (UM) MRU Code = "MRU" + // Mauritian Rupee (₨) MUR Code = "MUR" - MVR Code = "MVR" - MWK Code = "MWK" - MXN Code = "MXN" - MXV Code = "MXV" + // Polish Złoty (zł) + PLN Code = "PLN" + // Aruban Florin (ƒ) + AWG Code = "AWG" + // Dominican Peso ($) + DOP Code = "DOP" + // Malaysian Ringgit (RM) MYR Code = "MYR" + // Mozambican Metical (MTn) MZN Code = "MZN" + // Namibian Dollar ($) NAD Code = "NAD" + // Nigerian Naira (₦) NGN Code = "NGN" + // Nicaraguan Córdoba (C$) NIO Code = "NIO" + // Norwegian Krone (kr) NOK Code = "NOK" + // Nepalese Rupee (Rs.) NPR Code = "NPR" + // New Zealand Dollar ($) NZD Code = "NZD" + // Omani Rial (ر.ع.) OMR Code = "OMR" + // Panamanian Balboa (B/.) PAB Code = "PAB" + // Peruvian Sol (S/) PEN Code = "PEN" + // Papua New Guinean Kina (K) PGK Code = "PGK" + // Philippine Peso (₱) PHP Code = "PHP" + // Pakistani Rupee (₨) PKR Code = "PKR" - PLN Code = "PLN" + // Maldivian Rufiyaa (MVR) + MVR Code = "MVR" + // Paraguayan Guaraní (₲) PYG Code = "PYG" + // Qatari Riyal (ر.ق) QAR Code = "QAR" + // Romanian Leu (Lei) RON Code = "RON" + // Serbian Dinar (РСД) RSD Code = "RSD" + // Russian Ruble (₽) RUB Code = "RUB" + // Rwandan Franc (FRw) RWF Code = "RWF" + // Saudi Riyal (ر.س) SAR Code = "SAR" + // Solomon Islands Dollar ($) SBD Code = "SBD" + // Seychellois Rupee (₨) SCR Code = "SCR" + // Sudanese Pound (£) SDG Code = "SDG" + // Swedish Krona (kr) SEK Code = "SEK" + // Singapore Dollar ($) SGD Code = "SGD" + // Saint Helenian Pound (£) SHP Code = "SHP" + // Slovak Koruna (Sk) + SKK Code = "SKK" + // New Leone (Le) + SLE Code = "SLE" + // Sierra Leonean Leone (Le) SLL Code = "SLL" + // Somali Shilling (Sh) SOS Code = "SOS" + // Surinamese Dollar ($) SRD Code = "SRD" + // South Sudanese Pound (£) SSP Code = "SSP" + // São Tomé and Príncipe Dobra (Db) + STD Code = "STD" + // São Tomé and Príncipe Second Dobra (Db) STN Code = "STN" + // Salvadoran Colón (₡) SVC Code = "SVC" + // Syrian Pound (£S) SYP Code = "SYP" + // Swazi Lilangeni (E) SZL Code = "SZL" + // Thai Baht (฿) THB Code = "THB" + // Tajikistani Somoni (ЅМ) TJS Code = "TJS" + // Turkmenistani Manat (T) TMT Code = "TMT" + // Tunisian Dinar (د.ت) TND Code = "TND" + // Tongan Paʻanga (T$) TOP Code = "TOP" + // Turkish Lira (₺) TRY Code = "TRY" + // Trinidad and Tobago Dollar ($) TTD Code = "TTD" + // New Taiwan Dollar ($) TWD Code = "TWD" + // Tanzanian Shilling (Sh) TZS Code = "TZS" + // Ukrainian Hryvnia (₴) UAH Code = "UAH" + // Ugandan Shilling (USh) UGX Code = "UGX" - USD Code = "USD" - USN Code = "USN" - UYI Code = "UYI" + // Afghan Afghani (؋) + AFN Code = "AFN" + // Uruguayan Peso ($U) UYU Code = "UYU" - UYW Code = "UYW" + // Uzbekistan Som (so'm) UZS Code = "UZS" + // Venezuelan Bolívar Soberano (Bs) VES Code = "VES" + // Vietnamese Đồng (₫) VND Code = "VND" + // Vanuatu Vatu (Vt) VUV Code = "VUV" + // Samoan Tala (T) WST Code = "WST" + // Central African Cfa Franc (CFA) XAF Code = "XAF" + // Silver (Troy Ounce) (oz t) + XAG Code = "XAG" + // Gold (Troy Ounce) (oz t) + XAU Code = "XAU" + // European Composite Unit () + XBA Code = "XBA" + // European Monetary Unit () + XBB Code = "XBB" + // European Unit of Account 9 () + XBC Code = "XBC" + // European Unit of Account 17 () + XBD Code = "XBD" + // East Caribbean Dollar ($) XCD Code = "XCD" + // Special Drawing Rights (SDR) + XDR Code = "XDR" + // West African Cfa Franc (Fr) XOF Code = "XOF" + // Palladium (oz t) + XPD Code = "XPD" + // Cfp Franc (Fr) XPF Code = "XPF" + // Platinum (oz t) + XPT Code = "XPT" + // Codes specifically reserved for testing purposes () + XTS Code = "XTS" + // Yemeni Rial (﷼) YER Code = "YER" + // South African Rand (R) ZAR Code = "ZAR" + // Zambian Kwacha (ZK) + ZMK Code = "ZMK" + // Zambian Kwacha (K) ZMW Code = "ZMW" - ZWL Code = "ZWL" -) - -// CodeDefinitions lists all the currencies we know about -// with extra data. -var CodeDefinitions = []Def{ - { - Code: AED, - Name: "UAE Dirham", - Num: "784", - Units: 2, - }, - { - Code: AFN, - Name: "Afghani", - Num: "971", - Units: 2, - }, - { - Code: ALL, - Name: "Lek", - Num: "008", - Units: 2, - }, - { - Code: AMD, - Name: "Armenian Dram", - Num: "051", - Units: 2, - }, - { - Code: ANG, - Name: "Netherlands Antillean Guilder", - Num: "532", - Units: 2, - }, - { - Code: AOA, - Name: "Kwanza", - Num: "973", - Units: 2, - }, - { - Code: ARS, - Name: "Argentine Peso", - Num: "032", - Units: 2, - }, - { - Code: AUD, - Name: "Australian Dollar", - Num: "036", - Units: 2, - }, - { - Code: AWG, - Name: "Aruban Florin", - Num: "533", - Units: 2, - }, - { - Code: AZN, - Name: "Azerbaijan Manat", - Num: "944", - Units: 2, - }, - { - Code: BAM, - Name: "Convertible Mark", - Num: "977", - Units: 2, - }, - { - Code: BBD, - Name: "Barbados Dollar", - Num: "052", - Units: 2, - }, - { - Code: BDT, - Name: "Taka", - Num: "050", - Units: 2, - }, - { - Code: BGN, - Name: "Bulgarian Lev", - Num: "975", - Units: 2, - }, - { - Code: BHD, - Name: "Bahraini Dinar", - Num: "048", - Units: 3, - }, - { - Code: BIF, - Name: "Burundi Franc", - Num: "108", - Units: 0, - }, - { - Code: BMD, - Name: "Bermudian Dollar", - Num: "060", - Units: 2, - }, - { - Code: BND, - Name: "Brunei Dollar", - Num: "096", - Units: 2, - }, - { - Code: BOB, - Name: "Boliviano", - Num: "068", - Units: 2, - }, - { - Code: BOV, - Name: "Mvdol", - Num: "984", - Units: 2, - }, - { - Code: BRL, - Name: "Brazilian Real", - Num: "986", - Units: 2, - }, - { - Code: BSD, - Name: "Bahamian Dollar", - Num: "044", - Units: 2, - }, - { - Code: BTN, - Name: "Ngultrum", - Num: "064", - Units: 2, - }, - { - Code: BWP, - Name: "Pula", - Num: "072", - Units: 2, - }, - { - Code: BYN, - Name: "Belarusian Ruble", - Num: "933", - Units: 2, - }, - { - Code: BZD, - Name: "Belize Dollar", - Num: "084", - Units: 2, - }, - { - Code: CAD, - Name: "Canadian Dollar", - Num: "124", - Units: 2, - }, - { - Code: CDF, - Name: "Congolese Franc", - Num: "976", - Units: 2, - }, - { - Code: CHE, - Name: "WIR Euro", - Num: "947", - Units: 2, - }, - { - Code: CHF, - Name: "Swiss Franc", - Num: "756", - Units: 2, - }, - { - Code: CHW, - Name: "WIR Franc", - Num: "948", - Units: 2, - }, - { - Code: CLF, - Name: "Unidad de Fomento", - Num: "990", - Units: 4, - }, - { - Code: CLP, - Name: "Chilean Peso", - Num: "152", - Units: 0, - }, - { - Code: CNY, - Name: "Yuan Renminbi", - Num: "156", - Units: 2, - }, - { - Code: COP, - Name: "Colombian Peso", - Num: "170", - Units: 2, - }, - { - Code: COU, - Name: "Unidad de Valor Real", - Num: "970", - Units: 2, - }, - { - Code: CRC, - Name: "Costa Rican Colon", - Num: "188", - Units: 2, - }, - { - Code: CUC, - Name: "Peso Convertible", - Num: "931", - Units: 2, - }, - { - Code: CUP, - Name: "Cuban Peso", - Num: "192", - Units: 2, - }, - { - Code: CVE, - Name: "Cabo Verde Escudo", - Num: "132", - Units: 2, - }, - { - Code: CZK, - Name: "Czech Koruna", - Num: "203", - Units: 2, - }, - { - Code: DJF, - Name: "Djibouti Franc", - Num: "262", - Units: 0, - }, - { - Code: DKK, - Name: "Danish Krone", - Num: "208", - Units: 2, - }, - { - Code: DOP, - Name: "Dominican Peso", - Num: "214", - Units: 2, - }, - { - Code: DZD, - Name: "Algerian Dinar", - Num: "012", - Units: 2, - }, - { - Code: EGP, - Name: "Egyptian Pound", - Num: "818", - Units: 2, - }, - { - Code: ERN, - Name: "Nakfa", - Num: "232", - Units: 2, - }, - { - Code: ETB, - Name: "Ethiopian Birr", - Num: "230", - Units: 2, - }, - { - Code: EUR, - Name: "Euro", - Num: "978", - Units: 2, - }, - { - Code: FJD, - Name: "Fiji Dollar", - Num: "242", - Units: 2, - }, - { - Code: FKP, - Name: "Falkland Islands Pound", - Num: "238", - Units: 2, - }, - { - Code: GBP, - Name: "Pound Sterling", - Num: "826", - Units: 2, - }, - { - Code: GEL, - Name: "Lari", - Num: "981", - Units: 2, - }, - { - Code: GHS, - Name: "Ghana Cedi", - Num: "936", - Units: 2, - }, - { - Code: GIP, - Name: "Gibraltar Pound", - Num: "292", - Units: 2, - }, - { - Code: GMD, - Name: "Dalasi", - Num: "270", - Units: 2, - }, - { - Code: GNF, - Name: "Guinean Franc", - Num: "324", - Units: 0, - }, - { - Code: GTQ, - Name: "Quetzal", - Num: "320", - Units: 2, - }, - { - Code: GYD, - Name: "Guyana Dollar", - Num: "328", - Units: 2, - }, - { - Code: HKD, - Name: "Hong Kong Dollar", - Num: "344", - Units: 2, - }, - { - Code: HNL, - Name: "Lempira", - Num: "340", - Units: 2, - }, - { - Code: HRK, - Name: "Kuna", - Num: "191", - Units: 2, - }, - { - Code: HTG, - Name: "Gourde", - Num: "332", - Units: 2, - }, - { - Code: HUF, - Name: "Forint", - Num: "348", - Units: 2, - }, - { - Code: IDR, - Name: "Rupiah", - Num: "360", - Units: 2, - }, - { - Code: ILS, - Name: "New Israeli Sheqel", - Num: "376", - Units: 2, - }, - { - Code: INR, - Name: "Indian Rupee", - Num: "356", - Units: 2, - }, - { - Code: IQD, - Name: "Iraqi Dinar", - Num: "368", - Units: 3, - }, - { - Code: IRR, - Name: "Iranian Rial", - Num: "364", - Units: 2, - }, - { - Code: ISK, - Name: "Iceland Krona", - Num: "352", - Units: 0, - }, - { - Code: JMD, - Name: "Jamaican Dollar", - Num: "388", - Units: 2, - }, - { - Code: JOD, - Name: "Jordanian Dinar", - Num: "400", - Units: 3, - }, - { - Code: JPY, - Name: "Yen", - Num: "392", - Units: 0, - }, - { - Code: KES, - Name: "Kenyan Shilling", - Num: "404", - Units: 2, - }, - { - Code: KGS, - Name: "Som", - Num: "417", - Units: 2, - }, - { - Code: KHR, - Name: "Riel", - Num: "116", - Units: 2, - }, - { - Code: KMF, - Name: "Comorian Franc ", - Num: "174", - Units: 0, - }, - { - Code: KPW, - Name: "North Korean Won", - Num: "408", - Units: 2, - }, - { - Code: KRW, - Name: "Won", - Num: "410", - Units: 0, - }, - { - Code: KWD, - Name: "Kuwaiti Dinar", - Num: "414", - Units: 3, - }, - { - Code: KYD, - Name: "Cayman Islands Dollar", - Num: "136", - Units: 2, - }, - { - Code: KZT, - Name: "Tenge", - Num: "398", - Units: 2, - }, - { - Code: LAK, - Name: "Lao Kip", - Num: "418", - Units: 2, - }, - { - Code: LBP, - Name: "Lebanese Pound", - Num: "422", - Units: 2, - }, - { - Code: LKR, - Name: "Sri Lanka Rupee", - Num: "144", - Units: 2, - }, - { - Code: LRD, - Name: "Liberian Dollar", - Num: "430", - Units: 2, - }, - { - Code: LSL, - Name: "Loti", - Num: "426", - Units: 2, - }, - { - Code: LYD, - Name: "Libyan Dinar", - Num: "434", - Units: 3, - }, - { - Code: MAD, - Name: "Moroccan Dirham", - Num: "504", - Units: 2, - }, - { - Code: MDL, - Name: "Moldovan Leu", - Num: "498", - Units: 2, - }, - { - Code: MGA, - Name: "Malagasy Ariary", - Num: "969", - Units: 2, - }, - { - Code: MKD, - Name: "Denar", - Num: "807", - Units: 2, - }, - { - Code: MMK, - Name: "Kyat", - Num: "104", - Units: 2, - }, - { - Code: MNT, - Name: "Tugrik", - Num: "496", - Units: 2, - }, - { - Code: MOP, - Name: "Pataca", - Num: "446", - Units: 2, - }, - { - Code: MRU, - Name: "Ouguiya", - Num: "929", - Units: 2, - }, - { - Code: MUR, - Name: "Mauritius Rupee", - Num: "480", - Units: 2, - }, - { - Code: MVR, - Name: "Rufiyaa", - Num: "462", - Units: 2, - }, - { - Code: MWK, - Name: "Malawi Kwacha", - Num: "454", - Units: 2, - }, - { - Code: MXN, - Name: "Mexican Peso", - Num: "484", - Units: 2, - }, - { - Code: MXV, - Name: "Mexican Unidad de Inversion (UDI)", - Num: "979", - Units: 2, - }, - { - Code: MYR, - Name: "Malaysian Ringgit", - Num: "458", - Units: 2, - }, - { - Code: MZN, - Name: "Mozambique Metical", - Num: "943", - Units: 2, - }, - { - Code: NAD, - Name: "Namibia Dollar", - Num: "516", - Units: 2, - }, - { - Code: NGN, - Name: "Naira", - Num: "566", - Units: 2, - }, - { - Code: NIO, - Name: "Cordoba Oro", - Num: "558", - Units: 2, - }, - { - Code: NOK, - Name: "Norwegian Krone", - Num: "578", - Units: 2, - }, - { - Code: NPR, - Name: "Nepalese Rupee", - Num: "524", - Units: 2, - }, - { - Code: NZD, - Name: "New Zealand Dollar", - Num: "554", - Units: 2, - }, - { - Code: OMR, - Name: "Rial Omani", - Num: "512", - Units: 3, - }, - { - Code: PAB, - Name: "Balboa", - Num: "590", - Units: 2, - }, - { - Code: PEN, - Name: "Sol", - Num: "604", - Units: 2, - }, - { - Code: PGK, - Name: "Kina", - Num: "598", - Units: 2, - }, - { - Code: PHP, - Name: "Philippine Peso", - Num: "608", - Units: 2, - }, - { - Code: PKR, - Name: "Pakistan Rupee", - Num: "586", - Units: 2, - }, - { - Code: PLN, - Name: "Zloty", - Num: "985", - Units: 2, - }, - { - Code: PYG, - Name: "Guarani", - Num: "600", - Units: 0, - }, - { - Code: QAR, - Name: "Qatari Rial", - Num: "634", - Units: 2, - }, - { - Code: RON, - Name: "Romanian Leu", - Num: "946", - Units: 2, - }, - { - Code: RSD, - Name: "Serbian Dinar", - Num: "941", - Units: 2, - }, - { - Code: RUB, - Name: "Russian Ruble", - Num: "643", - Units: 2, - }, - { - Code: RWF, - Name: "Rwanda Franc", - Num: "646", - Units: 0, - }, - { - Code: SAR, - Name: "Saudi Riyal", - Num: "682", - Units: 2, - }, - { - Code: SBD, - Name: "Solomon Islands Dollar", - Num: "090", - Units: 2, - }, - { - Code: SCR, - Name: "Seychelles Rupee", - Num: "690", - Units: 2, - }, - { - Code: SDG, - Name: "Sudanese Pound", - Num: "938", - Units: 2, - }, - { - Code: SEK, - Name: "Swedish Krona", - Num: "752", - Units: 2, - }, - { - Code: SGD, - Name: "Singapore Dollar", - Num: "702", - Units: 2, - }, - { - Code: SHP, - Name: "Saint Helena Pound", - Num: "654", - Units: 2, - }, - { - Code: SLL, - Name: "Leone", - Num: "694", - Units: 2, - }, - { - Code: SOS, - Name: "Somali Shilling", - Num: "706", - Units: 2, - }, - { - Code: SRD, - Name: "Surinam Dollar", - Num: "968", - Units: 2, - }, - { - Code: SSP, - Name: "South Sudanese Pound", - Num: "728", - Units: 2, - }, - { - Code: STN, - Name: "Dobra", - Num: "930", - Units: 2, - }, - { - Code: SVC, - Name: "El Salvador Colon", - Num: "222", - Units: 2, - }, - { - Code: SYP, - Name: "Syrian Pound", - Num: "760", - Units: 2, - }, - { - Code: SZL, - Name: "Lilangeni", - Num: "748", - Units: 2, - }, - { - Code: THB, - Name: "Baht", - Num: "764", - Units: 2, - }, - { - Code: TJS, - Name: "Somoni", - Num: "972", - Units: 2, - }, - { - Code: TMT, - Name: "Turkmenistan New Manat", - Num: "934", - Units: 2, - }, - { - Code: TND, - Name: "Tunisian Dinar", - Num: "788", - Units: 3, - }, - { - Code: TOP, - Name: "Pa’anga", - Num: "776", - Units: 2, - }, - { - Code: TRY, - Name: "Turkish Lira", - Num: "949", - Units: 2, - }, - { - Code: TTD, - Name: "Trinidad and Tobago Dollar", - Num: "780", - Units: 2, - }, - { - Code: TWD, - Name: "New Taiwan Dollar", - Num: "901", - Units: 2, - }, - { - Code: TZS, - Name: "Tanzanian Shilling", - Num: "834", - Units: 2, - }, - { - Code: UAH, - Name: "Hryvnia", - Num: "980", - Units: 2, - }, - { - Code: UGX, - Name: "Uganda Shilling", - Num: "800", - Units: 0, - }, - { - Code: USD, - Name: "US Dollar", - Num: "840", - Units: 2, - }, - { - Code: USN, - Name: "US Dollar (Next day)", - Num: "997", - Units: 2, - }, - { - Code: UYI, - Name: "Uruguay Peso en Unidades Indexadas (UI)", - Num: "940", - Units: 0, - }, - { - Code: UYU, - Name: "Peso Uruguayo", - Num: "858", - Units: 2, - }, - { - Code: UYW, - Name: "Unidad Previsional", - Num: "927", - Units: 4, - }, - { - Code: UZS, - Name: "Uzbekistan Sum", - Num: "860", - Units: 2, - }, - { - Code: VES, - Name: "Bolívar Soberano", - Num: "928", - Units: 2, - }, - { - Code: VND, - Name: "Dong", - Num: "704", - Units: 0, - }, - { - Code: VUV, - Name: "Vatu", - Num: "548", - Units: 0, - }, - { - Code: WST, - Name: "Tala", - Num: "882", - Units: 2, - }, - { - Code: XAF, - Name: "CFA Franc BEAC", - Num: "950", - Units: 0, - }, - { - Code: XCD, - Name: "East Caribbean Dollar", - Num: "951", - Units: 2, - }, - { - Code: XOF, - Name: "CFA Franc BCEAO", - Num: "952", - Units: 0, - }, - { - Code: XPF, - Name: "CFP Franc", - Num: "953", - Units: 0, - }, - { - Code: YER, - Name: "Yemeni Rial", - Num: "886", - Units: 2, - }, - { - Code: ZAR, - Name: "Rand", - Num: "710", - Units: 2, - }, - { - Code: ZMW, - Name: "Zambian Kwacha", - Num: "967", - Units: 2, - }, - { - Code: ZWL, - Name: "Zimbabwe Dollar", - Num: "932", - Units: 2, - }, -} + // Bitcoin Cash (₿) + BCH Code = "BCH" + // Bitcoin (₿) + BTC Code = "BTC" + // Jersey Pound (£) + JEP Code = "JEP" + // Guernsey Pound (£) + GGP Code = "GGP" + // Isle of Man Pound (£) + IMP Code = "IMP" + // UIC Franc () + XFU Code = "XFU" + // British Penny () + GBX Code = "GBX" + // Chinese Renminbi Yuan Offshore (¥) + CNH Code = "CNH" + // USD Coin (USDC) + USDC Code = "USDC" +) \ No newline at end of file diff --git a/currency/currency.go b/currency/currency.go index 763c4299..e8af4c9b 100644 --- a/currency/currency.go +++ b/currency/currency.go @@ -1,9 +1,16 @@ // Package currency provides models for dealing with currencies. package currency -import "github.com/invopop/gobl/schema" +import ( + "github.com/invopop/gobl/data" + "github.com/invopop/gobl/schema" +) func init() { + definitions = new(defs) + if err := definitions.load(data.Content, "currency"); err != nil { + panic(err) + } schema.Register(schema.GOBL.Add("currency"), Code(""), ExchangeRate{}, diff --git a/currency/def.go b/currency/def.go new file mode 100644 index 00000000..fbcbd2f9 --- /dev/null +++ b/currency/def.go @@ -0,0 +1,212 @@ +package currency + +import ( + "fmt" + "io/fs" + "path/filepath" + "sort" + + "github.com/invopop/gobl/num" + "github.com/invopop/yaml" +) + +var definitions *defs + +// defs is used internally to load and access currency +// definitions. +type defs struct { + byCode map[Code]*Def + byPriority []*Def +} + +const ( + // DefaultCurrencyTemplate defines how to output currencies for most + // common use cases. + DefaultCurrencyTemplate = "%u%n" +) + +// Def helps define how to format a currency as is based on the +// [Ruby Money Gem's](https://rubymoney.github.io/money/) Currency model. +type Def struct { + // Priority is an arbitrary number used for ordering of currencies + // roughly based on popularity. + Priority int `json:"priority"` + // Standard ISO 4217 code + ISOCode Code `json:"iso_code"` + // ISO numeric code + ISONumeric string `json:"iso_numeric"` + // English name of the currency + Name string `json:"name"` + // Symbol representation + Symbol string `json:"symbol"` + // When presented alongside other currency's with potentially + // the same symbol, use this representation instead. + DisambiguateSymbol string `json:"disambiguate_symbol"` + // Alternative presentation symbols + AlternateSymbols []string `json:"alternate_symbols"` + // Name of the currency subunit + SubunitName string `json:"subunit_name"` + // Conversion amount to subunit + Subunits uint32 `json:"subunits"` + // Template determines how to layout the units and number + Template string `json:"template"` + // Decimal mark normally expected in output + DecimalMark string `json:"decimal_mark"` + // Thousands separator normally expected in output + ThousandsSeparator string `json:"thousands_separator"` + // Smallest acceptable amount of the currency + SmallestDenomination int `json:"smallest_denomination"` + // NumeralSystem defines how numbers should be printed out, by default this + // is 'western'. + NumeralSystem num.NumeralSystem `json:"numeral_system"` +} + +// FormatOption defines how to configure the formatter for common +// use cases and custom options. +type FormatOption func(*Def, num.Formatter) num.Formatter + +// WithDisambiguateSymbol will override the default symbol to use with one that +// is unique for the context. Lots of countries for example use "$" as their +// main currency symbol, using this option will ensure that `US$` is used +// in output instead. +func WithDisambiguateSymbol() FormatOption { + return func(d *Def, f num.Formatter) num.Formatter { + f.Unit = d.DisambiguateSymbol + if f.Unit == "" { + // fall back to symbol + f.Unit = d.Symbol + } + return f + } +} + +// WithNumeralSystem will override the default numeral system used to output +// numbers. +func WithNumeralSystem(ns num.NumeralSystem) FormatOption { + return func(d *Def, f num.Formatter) num.Formatter { + f.NumeralSystem = ns + return f + } +} + +// Formatter provides a number formatter for the currency definition. +func (d *Def) Formatter(opts ...FormatOption) num.Formatter { + f := num.Formatter{ + DecimalMark: d.DecimalMark, + ThousandsSeparator: d.ThousandsSeparator, + Unit: d.Symbol, + Template: d.Template, + } + if d.Template == "" { + f.Template = DefaultCurrencyTemplate + } + for _, opt := range opts { + f = opt(d, f) + } + return f +} + +// FormatAmount takes the provided amount and formats it according +// to the default rules of the currency definition. +func (d *Def) FormatAmount(amount num.Amount) string { + return d.Formatter().Amount(amount) +} + +// FormatPercentage takes the provided percentage and formats it +// according to the decimal and thousands rules of the currency +// definition. +func (d *Def) FormatPercentage(percentage num.Percentage) string { + return d.Formatter().Percentage(percentage) +} + +// Zero provides the currency's zero amount which is pre-set with the +// minimum precision for the currency. +func (d *Def) Zero() num.Amount { + return num.MakeAmount(0, d.Subunits) +} + +// Definitions provides an array of all currency definitions +// ordered by priority. +func Definitions() []*Def { + return definitions.all() +} + +// Get provides the code's currency definition, or +// nil if no match found. +func Get(c Code) *Def { + return definitions.get(c) +} + +// ByISONumber tries to find the currency definition by it's assigned ISO +// number. +func ByISONumber(n string) *Def { + for _, def := range definitions.all() { + if def.ISONumeric == n { + return def + } + } + return nil +} + +func (ds *defs) all() []*Def { + return ds.byPriority +} + +func (ds *defs) get(c Code) *Def { + if def, ok := ds.byCode[c]; ok { + return def + } + return nil +} + +// load attempts to ready all of the currency JSON definition +// files from the provided source and load them into memory. +func (ds *defs) load(src fs.FS, root string) error { + ds.byPriority = make([]*Def, 0) + ds.byCode = make(map[Code]*Def) + + err := fs.WalkDir(src, root, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("walking directory: %w", err) + } + + switch filepath.Ext(path) { + case ".yaml", ".yml", ".json": + // good + default: + return nil + } + + data, err := fs.ReadFile(src, path) + if err != nil { + return fmt.Errorf("reading file '%s': %w", path, err) + } + + list := make([]*Def, 0) + if err := yaml.Unmarshal(data, &list); err != nil { + return fmt.Errorf("unmarshalling file '%s': %w", path, err) + } + + for _, def := range list { + if _, ok := ds.byCode[def.ISOCode]; ok { + return fmt.Errorf("duplicate currency code: %s", def.ISOCode) + } + ds.byCode[def.ISOCode] = def + ds.byPriority = append(ds.byPriority, def) + } + + return nil + }) + + if err != nil { + return err + } + + // Sort the byPriority list by the priority field + // in ascending order. + sort.Slice(ds.byPriority, func(i, j int) bool { + return ds.byPriority[i].Priority < ds.byPriority[j].Priority + }) + + return nil +} diff --git a/currency/def_test.go b/currency/def_test.go new file mode 100644 index 00000000..389dffff --- /dev/null +++ b/currency/def_test.go @@ -0,0 +1,120 @@ +package currency_test + +import ( + "testing" + + "github.com/invopop/gobl/currency" + "github.com/invopop/gobl/num" + "github.com/stretchr/testify/assert" +) + +func TestDefAmount(t *testing.T) { + // make a test table + tests := []struct { + name string + currency currency.Code + amt num.Amount + exp string + }{ + { + name: "zero EUR", + currency: currency.EUR, + amt: num.MakeAmount(0, 2), + exp: "€0,00", + }, + { + name: "thousand EUR", + currency: currency.EUR, + amt: num.MakeAmount(123456, 2), + exp: "€1.234,56", + }, + { + name: "million EUR", + currency: currency.EUR, + amt: num.MakeAmount(123456789, 2), + exp: "€1.234.567,89", + }, + { + name: "zero USD", + currency: currency.USD, + amt: num.MakeAmount(0, 2), + exp: "$0.00", + }, + { + name: "thousand USD", + currency: currency.USD, + amt: num.MakeAmount(123456, 2), + exp: "$1,234.56", + }, + { + name: "million USD", + currency: currency.USD, + amt: num.MakeAmount(123456789, 2), + exp: "$1,234,567.89", + }, + { + name: "with template", + currency: currency.AED, + amt: num.MakeAmount(123456, 2), + exp: "1,234.56 د.إ", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + d := test.currency.Def() + assert.Equal(t, test.exp, d.FormatAmount(test.amt)) + }) + } +} + +func TestDefinitions(t *testing.T) { + list := currency.Definitions() + assert.NotEmpty(t, list) + assert.Equal(t, currency.USD, list[0].ISOCode) +} + +func TestDefFormat(t *testing.T) { + t.Run("with USD", func(t *testing.T) { + d := currency.USD.Def() + f := d.Formatter(currency.WithDisambiguateSymbol()) + a := num.MakeAmount(123456, 2) + assert.Equal(t, "US$1,234.56", f.Amount(a)) + }) + + t.Run("with EUR", func(t *testing.T) { + d := currency.EUR.Def() + f := d.Formatter(currency.WithDisambiguateSymbol()) + a := num.MakeAmount(123456, 2) + assert.Equal(t, "€1.234,56", f.Amount(a)) + }) +} + +func TestDefZero(t *testing.T) { + t.Run("with zero USD", func(t *testing.T) { + d := currency.USD.Def() + assert.Equal(t, "0.00", d.Zero().String()) + }) + t.Run("with zero CLP", func(t *testing.T) { + d := currency.CLP.Def() + assert.Equal(t, "0", d.Zero().String()) + }) + t.Run("with zero BTC", func(t *testing.T) { + d := currency.BTC.Def() + assert.Equal(t, "0.00000000", d.Zero().String()) + }) +} + +func TestDefByISONumber(t *testing.T) { + t.Run("with 978", func(t *testing.T) { + d := currency.ByISONumber("978") + assert.Equal(t, currency.EUR, d.ISOCode) + }) + t.Run("with 152", func(t *testing.T) { + d := currency.ByISONumber("152") + assert.Equal(t, currency.CLP, d.ISOCode) + }) + t.Run("with 0", func(t *testing.T) { + d := currency.ByISONumber("0") + assert.Nil(t, d) + }) +} diff --git a/currency/exchange_rate.go b/currency/exchange_rate.go index 422c105d..c09f735a 100644 --- a/currency/exchange_rate.go +++ b/currency/exchange_rate.go @@ -1,6 +1,9 @@ package currency -import "github.com/invopop/gobl/num" +import ( + "github.com/invopop/gobl/num" + "github.com/invopop/validation" +) // ExchangeRate contains data on the rate to be used when converting amounts from // the document's base currency to whatever is defined. @@ -12,8 +15,8 @@ import "github.com/invopop/gobl/num" // ExchangeRate instance may be defined and used as: // // rate := ¤cy.ExchangeRate{ -// Currency: currency.USD, -// Amount: "0.875967", +// Currency: currency.USD, +// Amount: "0.875967", // } // // val := "100.00" // USD @@ -24,3 +27,11 @@ type ExchangeRate struct { // How much is 1.00 of this currency worth in the documents currency. Amount num.Amount `json:"amount" jsonschema:"title=Amount"` } + +// Validate ensures the content of the exchange rate looks good. +func (er *ExchangeRate) Validate() error { + return validation.ValidateStruct(er, + validation.Field(&er.Currency, validation.Required), + validation.Field(&er.Amount, num.NotZero), + ) +} diff --git a/currency/exchange_rate_test.go b/currency/exchange_rate_test.go new file mode 100644 index 00000000..f87ad2d4 --- /dev/null +++ b/currency/exchange_rate_test.go @@ -0,0 +1,51 @@ +package currency_test + +import ( + "testing" + + "github.com/invopop/gobl/currency" + "github.com/invopop/gobl/num" + "github.com/stretchr/testify/assert" +) + +func TestExchangeRateValidation(t *testing.T) { + tests := []struct { + name string + rate currency.ExchangeRate + exp string + }{ + { + name: "valid", + rate: currency.ExchangeRate{ + Currency: currency.EUR, + Amount: num.MakeAmount(875967, 6), + }, + exp: "", + }, + { + name: "missing currency", + rate: currency.ExchangeRate{ + Amount: num.MakeAmount(875967, 6), + }, + exp: "currency: cannot be blank", + }, + { + name: "missing amount", + rate: currency.ExchangeRate{ + Currency: currency.EUR, + }, + exp: "amount: must not be zero", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.rate.Validate() + if test.exp == "" { + assert.NoError(t, err) + } else { + assert.ErrorContains(t, err, test.exp) + } + }) + } + +} diff --git a/currency/generate.go b/currency/generate.go new file mode 100644 index 00000000..01ee2d31 --- /dev/null +++ b/currency/generate.go @@ -0,0 +1,61 @@ +//go:build ignore + +package main + +import ( + "fmt" + "os" + "path/filepath" + "text/template" + + "github.com/invopop/gobl/currency" + "github.com/invopop/gobl/pkg/here" +) + +func main() { + if err := generateCodes(); err != nil { + fmt.Println(err) + } +} + +const ( + outDirectory = "./currency" +) + +var codeTemplate = here.Doc(` + // Code generated by "go run ./currency/generate.go"; DO NOT EDIT. + + package currency + + // List of ISO4217 and common currency codes. + const ( + {{- range .Defs }} + // {{ .Name }} ({{ .Symbol }}) + {{ .ISOCode }} Code = "{{ .ISOCode }}" + {{- end }} + ) +`) + +// generateCodes is a special tool function used to convert the source XML +// data into an array of currency definitions. +func generateCodes() error { + tmpl, err := template.New("codes").Parse(codeTemplate) + if err != nil { + return err + } + + fields := map[string]any{ + "Defs": currency.Definitions(), + } + + f, err := os.Create(filepath.Join(outDirectory, "codes.go")) + if err != nil { + return err + } + defer f.Close() // nolint:errcheck + if err := tmpl.Execute(f, fields); err != nil { + return err + } + + return nil +} diff --git a/data/currency/iso.json b/data/currency/iso.json new file mode 100644 index 00000000..7c0d7900 --- /dev/null +++ b/data/currency/iso.json @@ -0,0 +1,2378 @@ +[ + { + "priority": 100, + "iso_code": "AED", + "name": "United Arab Emirates Dirham", + "symbol": "د.إ", + "alternate_symbols": ["DH", "Dhs"], + "subunit_name": "Fils", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "784", + "smallest_denomination": 25 + }, + { + "priority": 100, + "iso_code": "AFN", + "name": "Afghan Afghani", + "symbol": "؋", + "alternate_symbols": ["Af", "Afs"], + "subunit_name": "Pul", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "971", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "ALL", + "name": "Albanian Lek", + "symbol": "L", + "disambiguate_symbol": "Lek", + "alternate_symbols": ["Lek"], + "subunit_name": "Qintar", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "008", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "AMD", + "name": "Armenian Dram", + "symbol": "դր.", + "alternate_symbols": ["dram"], + "subunit_name": "Luma", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "051", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "ANG", + "name": "Netherlands Antillean Gulden", + "symbol": "ƒ", + "alternate_symbols": ["NAƒ", "NAf", "f"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "532", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "AOA", + "name": "Angolan Kwanza", + "symbol": "Kz", + "alternate_symbols": [], + "subunit_name": "Cêntimo", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "973", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "ARS", + "name": "Argentine Peso", + "symbol": "$", + "disambiguate_symbol": "$m/n", + "alternate_symbols": ["$m/n", "m$n"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "032", + "smallest_denomination": 1 + }, + { + "priority": 4, + "iso_code": "AUD", + "name": "Australian Dollar", + "symbol": "$", + "disambiguate_symbol": "A$", + "alternate_symbols": ["A$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "036", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "AWG", + "name": "Aruban Florin", + "symbol": "ƒ", + "alternate_symbols": ["Afl"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "533", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "AZN", + "name": "Azerbaijani Manat", + "symbol": "₼", + "alternate_symbols": ["m", "man"], + "subunit_name": "Qəpik", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "944", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BAM", + "name": "Bosnia and Herzegovina Convertible Mark", + "symbol": "КМ", + "alternate_symbols": ["KM"], + "subunit_name": "Fening", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "977", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "BBD", + "name": "Barbadian Dollar", + "symbol": "$", + "disambiguate_symbol": "Bds$", + "alternate_symbols": ["Bds$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "052", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BDT", + "name": "Bangladeshi Taka", + "symbol": "৳", + "alternate_symbols": ["Tk"], + "subunit_name": "Paisa", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "050", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BGN", + "name": "Bulgarian Lev", + "symbol": "лв.", + "alternate_symbols": ["lev", "leva", "лев", "лева"], + "subunit_name": "Stotinka", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "975", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BHD", + "name": "Bahraini Dinar", + "symbol": "د.ب", + "alternate_symbols": ["BD"], + "subunit_name": "Fils", + "subunits": 3, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "048", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "BIF", + "name": "Burundian Franc", + "symbol": "Fr", + "disambiguate_symbol": "FBu", + "alternate_symbols": ["FBu"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "108", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "BMD", + "name": "Bermudian Dollar", + "symbol": "$", + "disambiguate_symbol": "BD$", + "alternate_symbols": ["BD$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "060", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BND", + "name": "Brunei Dollar", + "symbol": "$", + "disambiguate_symbol": "BND", + "alternate_symbols": ["B$"], + "subunit_name": "Sen", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "096", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BOB", + "name": "Bolivian Boliviano", + "symbol": "Bs.", + "alternate_symbols": ["Bs"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "068", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "BRL", + "name": "Brazilian Real", + "symbol": "R$", + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "986", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "BSD", + "name": "Bahamian Dollar", + "symbol": "$", + "disambiguate_symbol": "BSD", + "alternate_symbols": ["B$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "044", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BTN", + "name": "Bhutanese Ngultrum", + "symbol": "Nu.", + "alternate_symbols": ["Nu"], + "subunit_name": "Chertrum", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "064", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "BWP", + "name": "Botswana Pula", + "symbol": "P", + "alternate_symbols": [], + "subunit_name": "Thebe", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "072", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "BYN", + "name": "Belarusian Ruble", + "symbol": "Br", + "disambiguate_symbol": "BYN", + "alternate_symbols": ["бел. руб.", "б.р.", "руб.", "р."], + "subunit_name": "Kapeyka", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "933", + "smallest_denomination": 1 + }, + { + "priority": 50, + "iso_code": "BYR", + "name": "Belarusian Ruble", + "symbol": "Br", + "disambiguate_symbol": "BYR", + "alternate_symbols": ["бел. руб.", "б.р.", "руб.", "р."], + "subunit_name": null, + "subunits": 0, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "974", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "BZD", + "name": "Belize Dollar", + "symbol": "$", + "disambiguate_symbol": "BZ$", + "alternate_symbols": ["BZ$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "084", + "smallest_denomination": 1 + }, + { + "priority": 5, + "iso_code": "CAD", + "name": "Canadian Dollar", + "symbol": "$", + "disambiguate_symbol": "C$", + "alternate_symbols": ["C$", "CAD$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "124", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "CDF", + "name": "Congolese Franc", + "symbol": "Fr", + "disambiguate_symbol": "FC", + "alternate_symbols": ["FC"], + "subunit_name": "Centime", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "976", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "CHF", + "name": "Swiss Franc", + "symbol": "CHF", + "alternate_symbols": ["SFr", "Fr"], + "subunit_name": "Rappen", + "subunits": 2, + "template": "%u %n", + "decimal_mark": ".", + "thousands_separator": "'", + "iso_numeric": "756", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "CLF", + "name": "Unidad de Fomento", + "symbol": "UF", + "alternate_symbols": [], + "subunit_name": "Peso", + "subunits": 4, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "990" + }, + { + "priority": 100, + "iso_code": "CLP", + "name": "Chilean Peso", + "symbol": "$", + "disambiguate_symbol": "CLP", + "alternate_symbols": [], + "subunit_name": "Peso", + "subunits": 0, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "152", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "CNY", + "name": "Chinese Renminbi Yuan", + "symbol": "¥", + "alternate_symbols": ["CN¥", "元", "CN元"], + "subunit_name": "Fen", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "156", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "COP", + "name": "Colombian Peso", + "symbol": "$", + "disambiguate_symbol": "COL$", + "alternate_symbols": ["COL$"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "170", + "smallest_denomination": 20 + }, + { + "priority": 100, + "iso_code": "CRC", + "name": "Costa Rican Colón", + "symbol": "₡", + "alternate_symbols": ["¢"], + "subunit_name": "Céntimo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "188", + "smallest_denomination": 500 + }, + { + "priority": 100, + "iso_code": "CUC", + "name": "Cuban Convertible Peso", + "symbol": "$", + "disambiguate_symbol": "CUC$", + "alternate_symbols": ["CUC$"], + "subunit_name": "Centavo", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "931", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "CUP", + "name": "Cuban Peso", + "symbol": "$", + "disambiguate_symbol": "$MN", + "alternate_symbols": ["$MN"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "192", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "CVE", + "name": "Cape Verdean Escudo", + "symbol": "$", + "disambiguate_symbol": "Esc", + "alternate_symbols": ["Esc"], + "subunit_name": "Centavo", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "132", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "CZK", + "name": "Czech Koruna", + "symbol": "Kč", + "alternate_symbols": [], + "subunit_name": "Haléř", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "203", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "DJF", + "name": "Djiboutian Franc", + "symbol": "Fdj", + "alternate_symbols": [], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "262", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "DKK", + "name": "Danish Krone", + "symbol": "kr.", + "disambiguate_symbol": "DKK", + "alternate_symbols": [",-"], + "subunit_name": "Øre", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "208", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "DOP", + "name": "Dominican Peso", + "symbol": "$", + "disambiguate_symbol": "RD$", + "alternate_symbols": ["RD$"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "214", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "DZD", + "name": "Algerian Dinar", + "symbol": "د.ج", + "alternate_symbols": ["DA"], + "subunit_name": "Centime", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "012", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "EGP", + "name": "Egyptian Pound", + "symbol": "ج.م", + "alternate_symbols": ["LE", "E£", "L.E."], + "subunit_name": "Piastre", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "818", + "smallest_denomination": 25 + }, + { + "priority": 100, + "iso_code": "ERN", + "name": "Eritrean Nakfa", + "symbol": "Nfk", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "232", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "ETB", + "name": "Ethiopian Birr", + "symbol": "Br", + "disambiguate_symbol": "ETB", + "alternate_symbols": [], + "subunit_name": "Santim", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "230", + "smallest_denomination": 1 + }, + { + "priority": 2, + "iso_code": "EUR", + "name": "Euro", + "symbol": "€", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "978", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "FJD", + "name": "Fijian Dollar", + "symbol": "$", + "disambiguate_symbol": "FJ$", + "alternate_symbols": ["FJ$"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "242", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "FKP", + "name": "Falkland Pound", + "symbol": "£", + "disambiguate_symbol": "FK£", + "alternate_symbols": ["FK£"], + "subunit_name": "Penny", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "238", + "smallest_denomination": 1 + }, + { + "priority": 3, + "iso_code": "GBP", + "name": "British Pound", + "symbol": "£", + "alternate_symbols": [], + "subunit_name": "Penny", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "826", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GEL", + "name": "Georgian Lari", + "symbol": "₾", + "alternate_symbols": ["lari"], + "subunit_name": "Tetri", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "981", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GHS", + "name": "Ghanaian Cedi", + "symbol": "₵", + "alternate_symbols": ["GH¢", "GH₵"], + "subunit_name": "Pesewa", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "936", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GIP", + "name": "Gibraltar Pound", + "symbol": "£", + "disambiguate_symbol": "GIP", + "alternate_symbols": [], + "subunit_name": "Penny", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "292", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GMD", + "name": "Gambian Dalasi", + "symbol": "D", + "alternate_symbols": [], + "subunit_name": "Butut", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "270", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GNF", + "name": "Guinean Franc", + "symbol": "Fr", + "disambiguate_symbol": "FG", + "alternate_symbols": ["FG", "GFr"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "324", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "GTQ", + "name": "Guatemalan Quetzal", + "symbol": "Q", + "alternate_symbols": [], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "320", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GYD", + "name": "Guyanese Dollar", + "symbol": "$", + "disambiguate_symbol": "G$", + "alternate_symbols": ["G$"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "328", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "HKD", + "name": "Hong Kong Dollar", + "symbol": "$", + "disambiguate_symbol": "HK$", + "alternate_symbols": ["HK$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "344", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "HNL", + "name": "Honduran Lempira", + "symbol": "L", + "disambiguate_symbol": "HNL", + "alternate_symbols": [], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "340", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "HTG", + "name": "Haitian Gourde", + "symbol": "G", + "alternate_symbols": [], + "subunit_name": "Centime", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "332", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "HUF", + "name": "Hungarian Forint", + "symbol": "Ft", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "348", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "IDR", + "name": "Indonesian Rupiah", + "symbol": "Rp", + "alternate_symbols": [], + "subunit_name": "Sen", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "360", + "smallest_denomination": 5000 + }, + { + "priority": 100, + "iso_code": "ILS", + "name": "Israeli New Sheqel", + "symbol": "₪", + "alternate_symbols": ["ש״ח", "NIS"], + "subunit_name": "Agora", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "376", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "INR", + "name": "Indian Rupee", + "symbol": "₹", + "alternate_symbols": ["Rs", "৳", "૱", "௹", "रु", "₨"], + "subunit_name": "Paisa", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "356", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "IQD", + "name": "Iraqi Dinar", + "symbol": "ع.د", + "alternate_symbols": [], + "subunit_name": "Fils", + "subunits": 3, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "368", + "smallest_denomination": 50000 + }, + { + "priority": 100, + "iso_code": "IRR", + "name": "Iranian Rial", + "symbol": "﷼", + "alternate_symbols": [], + "subunit_name": null, + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "364", + "smallest_denomination": 5000 + }, + { + "priority": 100, + "iso_code": "ISK", + "name": "Icelandic Króna", + "symbol": "kr.", + "alternate_symbols": ["Íkr"], + "subunit_name": null, + "subunits": 0, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "352", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "JMD", + "name": "Jamaican Dollar", + "symbol": "$", + "disambiguate_symbol": "J$", + "alternate_symbols": ["J$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "388", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "JOD", + "name": "Jordanian Dinar", + "symbol": "د.ا", + "alternate_symbols": ["JD"], + "subunit_name": "Fils", + "subunits": 3, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "400", + "smallest_denomination": 5 + }, + { + "priority": 6, + "iso_code": "JPY", + "name": "Japanese Yen", + "symbol": "¥", + "alternate_symbols": ["円", "圓"], + "subunit_name": null, + "subunits": 0, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "392", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "KES", + "name": "Kenyan Shilling", + "symbol": "KSh", + "alternate_symbols": ["Sh"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "404", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "KGS", + "name": "Kyrgyzstani Som", + "symbol": "som", + "alternate_symbols": ["сом"], + "subunit_name": "Tyiyn", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "417", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "KHR", + "name": "Cambodian Riel", + "symbol": "៛", + "alternate_symbols": [], + "subunit_name": "Sen", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "116", + "smallest_denomination": 5000 + }, + { + "priority": 100, + "iso_code": "KMF", + "name": "Comorian Franc", + "symbol": "Fr", + "disambiguate_symbol": "CF", + "alternate_symbols": ["CF"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "174", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "KPW", + "name": "North Korean Won", + "symbol": "₩", + "alternate_symbols": [], + "subunit_name": "Chŏn", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "408", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "KRW", + "name": "South Korean Won", + "symbol": "₩", + "subunit_name": null, + "subunits": 0, + "alternate_symbols": [], + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "410", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "KWD", + "name": "Kuwaiti Dinar", + "symbol": "د.ك", + "alternate_symbols": ["K.D."], + "subunit_name": "Fils", + "subunits": 3, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "414", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "KYD", + "name": "Cayman Islands Dollar", + "symbol": "$", + "disambiguate_symbol": "CI$", + "alternate_symbols": ["CI$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "136", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "KZT", + "name": "Kazakhstani Tenge", + "symbol": "₸", + "alternate_symbols": [], + "subunit_name": "Tiyn", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "398", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "LAK", + "name": "Lao Kip", + "symbol": "₭", + "alternate_symbols": ["₭N"], + "subunit_name": "Att", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "418", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "LBP", + "name": "Lebanese Pound", + "symbol": "ل.ل", + "alternate_symbols": ["£", "L£"], + "subunit_name": "Piastre", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "422", + "smallest_denomination": 25000 + }, + { + "priority": 100, + "iso_code": "LKR", + "name": "Sri Lankan Rupee", + "symbol": "₨", + "disambiguate_symbol": "SLRs", + "alternate_symbols": ["රු", "ரூ", "SLRs", "/-"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "144", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "LRD", + "name": "Liberian Dollar", + "symbol": "$", + "disambiguate_symbol": "L$", + "alternate_symbols": ["L$"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "430", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "LSL", + "name": "Lesotho Loti", + "symbol": "L", + "disambiguate_symbol": "M", + "alternate_symbols": ["M"], + "subunit_name": "Sente", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "426", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "LYD", + "name": "Libyan Dinar", + "symbol": "ل.د", + "alternate_symbols": ["LD"], + "subunit_name": "Dirham", + "subunits": 3, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "434", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "MAD", + "name": "Moroccan Dirham", + "symbol": "د.م.", + "alternate_symbols": [], + "subunit_name": "Centime", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "504", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "MDL", + "name": "Moldovan Leu", + "symbol": "L", + "alternate_symbols": ["lei"], + "subunit_name": "Ban", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "498", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "MGA", + "name": "Malagasy Ariary", + "symbol": "Ar", + "alternate_symbols": [], + "subunit_name": "Iraimbilanja", + "subunits": 5, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "969", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "MKD", + "name": "Macedonian Denar", + "symbol": "ден", + "alternate_symbols": [], + "subunit_name": "Deni", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "807", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "MMK", + "name": "Myanmar Kyat", + "symbol": "K", + "disambiguate_symbol": "MMK", + "alternate_symbols": [], + "subunit_name": "Pya", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "104", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "MNT", + "name": "Mongolian Tögrög", + "symbol": "₮", + "alternate_symbols": [], + "subunit_name": "Möngö", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "496", + "smallest_denomination": 2000 + }, + { + "priority": 100, + "iso_code": "MOP", + "name": "Macanese Pataca", + "symbol": "P", + "alternate_symbols": ["MOP$"], + "subunit_name": "Avo", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "446", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "MRU", + "name": "Mauritanian Ouguiya", + "symbol": "UM", + "alternate_symbols": [], + "subunit_name": "Khoums", + "subunits": 5, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "929", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "MUR", + "name": "Mauritian Rupee", + "symbol": "₨", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "480", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "MVR", + "name": "Maldivian Rufiyaa", + "symbol": "MVR", + "alternate_symbols": ["MRF", "Rf", "/-", "ރ"], + "subunit_name": "Laari", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "462", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "MWK", + "name": "Malawian Kwacha", + "symbol": "MK", + "alternate_symbols": [], + "subunit_name": "Tambala", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "454", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "MXN", + "name": "Mexican Peso", + "symbol": "$", + "disambiguate_symbol": "MEX$", + "alternate_symbols": ["MEX$"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "484", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "MYR", + "name": "Malaysian Ringgit", + "symbol": "RM", + "alternate_symbols": [], + "subunit_name": "Sen", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "458", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "MZN", + "name": "Mozambican Metical", + "symbol": "MTn", + "alternate_symbols": ["MZN"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "943", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "NAD", + "name": "Namibian Dollar", + "symbol": "$", + "disambiguate_symbol": "N$", + "alternate_symbols": ["N$"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "516", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "NGN", + "name": "Nigerian Naira", + "symbol": "₦", + "alternate_symbols": [], + "subunit_name": "Kobo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "566", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "NIO", + "name": "Nicaraguan Córdoba", + "symbol": "C$", + "disambiguate_symbol": "NIO$", + "alternate_symbols": [], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "558", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "NOK", + "name": "Norwegian Krone", + "symbol": "kr", + "disambiguate_symbol": "NOK", + "alternate_symbols": [",-"], + "subunit_name": "Øre", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "578", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "NPR", + "name": "Nepalese Rupee", + "symbol": "Rs.", + "disambiguate_symbol": "NPR", + "alternate_symbols": ["Rs", "रू", "₨"], + "subunit_name": "Paisa", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "524", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "NZD", + "name": "New Zealand Dollar", + "symbol": "$", + "disambiguate_symbol": "NZ$", + "alternate_symbols": ["NZ$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "554", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "OMR", + "name": "Omani Rial", + "symbol": "ر.ع.", + "alternate_symbols": [], + "subunit_name": "Baisa", + "subunits": 3, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "512", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "PAB", + "name": "Panamanian Balboa", + "symbol": "B/.", + "alternate_symbols": [], + "subunit_name": "Centésimo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "590", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "PEN", + "name": "Peruvian Sol", + "symbol": "S/", + "alternate_symbols": [], + "subunit_name": "Céntimo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "604", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "PGK", + "name": "Papua New Guinean Kina", + "symbol": "K", + "disambiguate_symbol": "PGK", + "alternate_symbols": [], + "subunit_name": "Toea", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "598", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "PHP", + "name": "Philippine Peso", + "symbol": "₱", + "alternate_symbols": ["PHP", "PhP", "P"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "608", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "PKR", + "name": "Pakistani Rupee", + "symbol": "₨", + "disambiguate_symbol": "PKR", + "alternate_symbols": ["Rs"], + "subunit_name": "Paisa", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "586", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "PLN", + "name": "Polish Złoty", + "symbol": "zł", + "alternate_symbols": [], + "subunit_name": "Grosz", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "985", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "PYG", + "name": "Paraguayan Guaraní", + "symbol": "₲", + "alternate_symbols": [], + "subunit_name": "Céntimo", + "subunits": 0, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "600", + "smallest_denomination": 5000 + }, + { + "priority": 100, + "iso_code": "QAR", + "name": "Qatari Riyal", + "symbol": "ر.ق", + "alternate_symbols": ["QR"], + "subunit_name": "Dirham", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "634", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "RON", + "name": "Romanian Leu", + "symbol": "Lei", + "alternate_symbols": [], + "subunit_name": "Bani", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "946", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "RSD", + "name": "Serbian Dinar", + "symbol": "РСД", + "alternate_symbols": ["RSD", "din", "дин"], + "subunit_name": "Para", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "941", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "RUB", + "name": "Russian Ruble", + "symbol": "₽", + "alternate_symbols": ["руб.", "р."], + "subunit_name": "Kopeck", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "643", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "RWF", + "name": "Rwandan Franc", + "symbol": "FRw", + "alternate_symbols": ["RF", "R₣"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "646", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "SAR", + "name": "Saudi Riyal", + "symbol": "ر.س", + "alternate_symbols": ["SR", "﷼"], + "subunit_name": "Hallallah", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "682", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "SBD", + "name": "Solomon Islands Dollar", + "symbol": "$", + "disambiguate_symbol": "SI$", + "alternate_symbols": ["SI$"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "090", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "SCR", + "name": "Seychellois Rupee", + "symbol": "₨", + "disambiguate_symbol": "SRe", + "alternate_symbols": ["SRe", "SR"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "690", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SDG", + "name": "Sudanese Pound", + "symbol": "£", + "disambiguate_symbol": "SDG", + "alternate_symbols": [], + "subunit_name": "Piastre", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "938", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SEK", + "name": "Swedish Krona", + "symbol": "kr", + "disambiguate_symbol": "SEK", + "alternate_symbols": [":-"], + "subunit_name": "Öre", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "752", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "SGD", + "name": "Singapore Dollar", + "symbol": "$", + "disambiguate_symbol": "S$", + "alternate_symbols": ["S$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "702", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SHP", + "name": "Saint Helenian Pound", + "symbol": "£", + "disambiguate_symbol": "SHP", + "alternate_symbols": [], + "subunit_name": "Penny", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "654", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SKK", + "name": "Slovak Koruna", + "symbol": "Sk", + "alternate_symbols": [], + "subunit_name": "Halier", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "703", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "SLE", + "name": "New Leone", + "symbol": "Le", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "925", + "smallest_denomination": 1000 + }, + { + "priority": 100, + "iso_code": "SLL", + "name": "Sierra Leonean Leone", + "symbol": "Le", + "disambiguate_symbol": "SLL", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "694", + "smallest_denomination": 1000 + }, + { + "priority": 100, + "iso_code": "SOS", + "name": "Somali Shilling", + "symbol": "Sh", + "alternate_symbols": ["Sh.So"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "706", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SRD", + "name": "Surinamese Dollar", + "symbol": "$", + "disambiguate_symbol": "SRD", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "968", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SSP", + "name": "South Sudanese Pound", + "symbol": "£", + "disambiguate_symbol": "SSP", + "alternate_symbols": [], + "subunit_name": "piaster", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "728", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "STD", + "name": "São Tomé and Príncipe Dobra", + "symbol": "Db", + "alternate_symbols": [], + "subunit_name": "Cêntimo", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "678", + "smallest_denomination": 10000 + }, + { + "priority": 100, + "iso_code": "STN", + "name": "São Tomé and Príncipe Second Dobra", + "symbol": "Db", + "disambiguate_symbol": "STN", + "alternate_symbols": [], + "subunit_name": "Cêntimo", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "930", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "SVC", + "name": "Salvadoran Colón", + "symbol": "₡", + "alternate_symbols": ["¢"], + "subunit_name": "Centavo", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "222", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "SYP", + "name": "Syrian Pound", + "symbol": "£S", + "alternate_symbols": ["£", "ل.س", "LS", "الليرة السورية"], + "subunit_name": "Piastre", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "760", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "SZL", + "name": "Swazi Lilangeni", + "symbol": "E", + "disambiguate_symbol": "SZL", + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "748", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "THB", + "name": "Thai Baht", + "symbol": "฿", + "alternate_symbols": [], + "subunit_name": "Satang", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "764", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "TJS", + "name": "Tajikistani Somoni", + "symbol": "ЅМ", + "alternate_symbols": [], + "subunit_name": "Diram", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "972", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "TMT", + "name": "Turkmenistani Manat", + "symbol": "T", + "alternate_symbols": [], + "subunit_name": "Tenge", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "934", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "TND", + "name": "Tunisian Dinar", + "symbol": "د.ت", + "alternate_symbols": ["TD", "DT"], + "subunit_name": "Millime", + "subunits": 3, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "788", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "TOP", + "name": "Tongan Paʻanga", + "symbol": "T$", + "alternate_symbols": ["PT"], + "subunit_name": "Seniti", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "776", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "TRY", + "name": "Turkish Lira", + "symbol": "₺", + "alternate_symbols": ["TL"], + "subunit_name": "kuruş", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "949", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "TTD", + "name": "Trinidad and Tobago Dollar", + "symbol": "$", + "disambiguate_symbol": "TT$", + "alternate_symbols": ["TT$"], + "subunit_name": "Cent", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "780", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "TWD", + "name": "New Taiwan Dollar", + "symbol": "$", + "disambiguate_symbol": "NT$", + "alternate_symbols": ["NT$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "901", + "smallest_denomination": 50 + }, + { + "priority": 100, + "iso_code": "TZS", + "name": "Tanzanian Shilling", + "symbol": "Sh", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "834", + "smallest_denomination": 5000 + }, + { + "priority": 100, + "iso_code": "UAH", + "name": "Ukrainian Hryvnia", + "symbol": "₴", + "alternate_symbols": [], + "subunit_name": "Kopiyka", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "980", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "UGX", + "name": "Ugandan Shilling", + "symbol": "USh", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "800", + "smallest_denomination": 1000 + }, + { + "priority": 1, + "iso_code": "USD", + "name": "United States Dollar", + "symbol": "$", + "disambiguate_symbol": "US$", + "alternate_symbols": ["US$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "840", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "UYU", + "name": "Uruguayan Peso", + "symbol": "$U", + "alternate_symbols": ["$U"], + "subunit_name": "Centésimo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "858", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "UZS", + "name": "Uzbekistan Som", + "symbol": "so'm", + "alternate_symbols": ["so‘m", "сўм", "сум", "s", "с"], + "subunit_name": "Tiyin", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "860", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "VES", + "name": "Venezuelan Bolívar Soberano", + "symbol": "Bs", + "alternate_symbols": ["Bs.S"], + "subunit_name": "Céntimo", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "928", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "VND", + "name": "Vietnamese Đồng", + "symbol": "₫", + "alternate_symbols": [], + "subunit_name": "Hào", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ",", + "thousands_separator": ".", + "iso_numeric": "704", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "VUV", + "name": "Vanuatu Vatu", + "symbol": "Vt", + "alternate_symbols": [], + "subunit_name": null, + "subunits": 0, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "548", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "WST", + "name": "Samoan Tala", + "symbol": "T", + "disambiguate_symbol": "WS$", + "alternate_symbols": ["WS$", "SAT", "ST"], + "subunit_name": "Sene", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "882", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "XAF", + "name": "Central African Cfa Franc", + "symbol": "CFA", + "disambiguate_symbol": "FCFA", + "alternate_symbols": ["FCFA"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "950", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "XAG", + "name": "Silver (Troy Ounce)", + "symbol": "oz t", + "disambiguate_symbol": "XAG", + "alternate_symbols": [], + "subunit_name": "oz", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "961" + }, + { + "priority": 100, + "iso_code": "XAU", + "name": "Gold (Troy Ounce)", + "symbol": "oz t", + "disambiguate_symbol": "XAU", + "alternate_symbols": [], + "subunit_name": "oz", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "959" + }, + { + "priority": 100, + "iso_code": "XBA", + "name": "European Composite Unit", + "symbol": "", + "disambiguate_symbol": "XBA", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "955" + }, + { + "priority": 100, + "iso_code": "XBB", + "name": "European Monetary Unit", + "symbol": "", + "disambiguate_symbol": "XBB", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "956" + }, + { + "priority": 100, + "iso_code": "XBC", + "name": "European Unit of Account 9", + "symbol": "", + "disambiguate_symbol": "XBC", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "957" + }, + { + "priority": 100, + "iso_code": "XBD", + "name": "European Unit of Account 17", + "symbol": "", + "disambiguate_symbol": "XBD", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "958" + }, + { + "priority": 100, + "iso_code": "XCD", + "name": "East Caribbean Dollar", + "symbol": "$", + "disambiguate_symbol": "EX$", + "alternate_symbols": ["EC$"], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "951", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "XDR", + "name": "Special Drawing Rights", + "symbol": "SDR", + "alternate_symbols": ["XDR"], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "960" + }, + { + "priority": 100, + "iso_code": "XOF", + "name": "West African Cfa Franc", + "symbol": "Fr", + "disambiguate_symbol": "CFA", + "alternate_symbols": ["CFA"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "952", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "XPD", + "name": "Palladium", + "symbol": "oz t", + "disambiguate_symbol": "XPD", + "alternate_symbols": [], + "subunit_name": "oz", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "964" + }, + { + "priority": 100, + "iso_code": "XPF", + "name": "Cfp Franc", + "symbol": "Fr", + "alternate_symbols": ["F"], + "subunit_name": "Centime", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "953", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "XPT", + "name": "Platinum", + "symbol": "oz t", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "962", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "XTS", + "name": "Codes specifically reserved for testing purposes", + "symbol": "", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 0, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "963", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "YER", + "name": "Yemeni Rial", + "symbol": "﷼", + "alternate_symbols": [], + "subunit_name": "Fils", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "886", + "smallest_denomination": 100 + }, + { + "priority": 100, + "iso_code": "ZAR", + "name": "South African Rand", + "symbol": "R", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ",", + "thousands_separator": " ", + "iso_numeric": "710", + "smallest_denomination": 10 + }, + { + "priority": 100, + "iso_code": "ZMK", + "name": "Zambian Kwacha", + "symbol": "ZK", + "disambiguate_symbol": "ZMK", + "alternate_symbols": [], + "subunit_name": "Ngwee", + "subunits": 2, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "894", + "smallest_denomination": 5 + }, + { + "priority": 100, + "iso_code": "ZMW", + "name": "Zambian Kwacha", + "symbol": "K", + "disambiguate_symbol": "ZMW", + "alternate_symbols": [], + "subunit_name": "Ngwee", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "967", + "smallest_denomination": 5 + } +] diff --git a/data/currency/non-iso.json b/data/currency/non-iso.json new file mode 100644 index 00000000..0b817e6c --- /dev/null +++ b/data/currency/non-iso.json @@ -0,0 +1,128 @@ +[ + { + "priority": 100, + "iso_code": "BCH", + "name": "Bitcoin Cash", + "symbol": "₿", + "disambiguate_symbol": "₿CH", + "alternate_symbols": ["BCH"], + "subunit_name": "Satoshi", + "subunits": 8, + "template": "%n %u", + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "BTC", + "name": "Bitcoin", + "symbol": "₿", + "alternate_symbols": [], + "subunit_name": "Satoshi", + "subunits": 8, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "JEP", + "name": "Jersey Pound", + "symbol": "£", + "disambiguate_symbol": "JEP", + "alternate_symbols": [], + "subunit_name": "Penny", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GGP", + "name": "Guernsey Pound", + "symbol": "£", + "disambiguate_symbol": "GGP", + "alternate_symbols": [], + "subunit_name": "Penny", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "IMP", + "name": "Isle of Man Pound", + "symbol": "£", + "disambiguate_symbol": "IMP", + "alternate_symbols": ["M£"], + "subunit_name": "Penny", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "XFU", + "name": "UIC Franc", + "symbol": "", + "disambiguate_symbol": "XFU", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "GBX", + "name": "British Penny", + "symbol": "", + "disambiguate_symbol": "GBX", + "alternate_symbols": [], + "subunit_name": "", + "subunits": 1, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "CNH", + "name": "Chinese Renminbi Yuan Offshore", + "symbol": "¥", + "disambiguate_symbol": "CNH", + "alternate_symbols": ["CN¥", "元", "CN元"], + "subunit_name": "Fen", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + }, + { + "priority": 100, + "iso_code": "USDC", + "name": "USD Coin", + "symbol": "USDC", + "disambiguate_symbol": "USDC", + "alternate_symbols": [], + "subunit_name": "Cent", + "subunits": 2, + "decimal_mark": ".", + "thousands_separator": ",", + "iso_numeric": "", + "smallest_denomination": 1 + } +] diff --git a/data/data.go b/data/data.go index 85017c83..a492ab36 100644 --- a/data/data.go +++ b/data/data.go @@ -3,7 +3,7 @@ package data import "embed" -//go:embed regimes schemas +//go:embed currency regimes schemas // Content contains the generated regimes and schemes // ready to serve as an embed.FS. diff --git a/data/schemas/bill/correction-options.json b/data/schemas/bill/correction-options.json index 12ba5103..7ab83d52 100644 --- a/data/schemas/bill/correction-options.json +++ b/data/schemas/bill/correction-options.json @@ -40,6 +40,5 @@ ], "description": "CorrectionOptions defines a structure used to pass configuration options to correct a previous invoice." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/bill/invoice.json b/data/schemas/bill/invoice.json index c7f7a6eb..488ab1af 100644 --- a/data/schemas/bill/invoice.json +++ b/data/schemas/bill/invoice.json @@ -861,6 +861,5 @@ ], "description": "Totals contains the summaries of all calculations for the invoice." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cal/date-time.json b/data/schemas/cal/date-time.json index 1262208c..62cb3b86 100644 --- a/data/schemas/cal/date-time.json +++ b/data/schemas/cal/date-time.json @@ -9,6 +9,5 @@ "title": "Date Time", "description": "Civil date time in simplified ISO format with no time zone\ninformation, for example: 2021-05-26T13:45:00" } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cal/date.json b/data/schemas/cal/date.json index 1780cd58..bd9c9aa3 100644 --- a/data/schemas/cal/date.json +++ b/data/schemas/cal/date.json @@ -9,6 +9,5 @@ "title": "Date", "description": "Civil date in simplified ISO format, like 2021-05-26" } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cal/period.json b/data/schemas/cal/period.json index 0a546341..879daf12 100644 --- a/data/schemas/cal/period.json +++ b/data/schemas/cal/period.json @@ -28,6 +28,5 @@ ], "description": "Period represents two dates with a start and finish." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/code-definition.json b/data/schemas/cbc/code-definition.json index 94021c37..e844f563 100644 --- a/data/schemas/cbc/code-definition.json +++ b/data/schemas/cbc/code-definition.json @@ -32,6 +32,5 @@ ], "description": "CodeDefinition describes a specific code and how it maps to a human name and description if appropriate." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/code-map.json b/data/schemas/cbc/code-map.json index 88e2e268..244db38a 100644 --- a/data/schemas/cbc/code-map.json +++ b/data/schemas/cbc/code-map.json @@ -12,6 +12,5 @@ "type": "object", "description": "CodeMap is a map of keys to specific codes, useful to determine regime specific codes from their key counterparts." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/code.json b/data/schemas/cbc/code.json index ecb7bed4..1ec51271 100644 --- a/data/schemas/cbc/code.json +++ b/data/schemas/cbc/code.json @@ -11,6 +11,5 @@ "title": "Code", "description": "Alphanumerical text identifier with upper-case letters, no whitespace, nor symbols." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/key-definition.json b/data/schemas/cbc/key-definition.json index 25611c63..c3e0b993 100644 --- a/data/schemas/cbc/key-definition.json +++ b/data/schemas/cbc/key-definition.json @@ -59,6 +59,5 @@ ], "description": "KeyDefinition defines properties of a key that is specific for a regime." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/key.json b/data/schemas/cbc/key.json index 1373fd79..e8f3255f 100644 --- a/data/schemas/cbc/key.json +++ b/data/schemas/cbc/key.json @@ -11,6 +11,5 @@ "title": "Key", "description": "Text identifier to be used instead of a code for a more verbose but readable identifier." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/meta.json b/data/schemas/cbc/meta.json index 2b5d89bd..aaf003ad 100644 --- a/data/schemas/cbc/meta.json +++ b/data/schemas/cbc/meta.json @@ -12,6 +12,5 @@ "type": "object", "description": "Meta defines a structure for data about the data being defined." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/cbc/note.json b/data/schemas/cbc/note.json index 9b3dfe06..beea2aab 100644 --- a/data/schemas/cbc/note.json +++ b/data/schemas/cbc/note.json @@ -164,6 +164,5 @@ ], "description": "Note represents a free text of additional information that may be added to a document." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/currency/code.json b/data/schemas/currency/code.json index 17091e78..70b3844d 100644 --- a/data/schemas/currency/code.json +++ b/data/schemas/currency/code.json @@ -6,56 +6,56 @@ "Code": { "oneOf": [ { - "const": "AED", - "title": "UAE Dirham" + "const": "USD", + "title": "United States Dollar" }, { - "const": "AFN", - "title": "Afghani" + "const": "EUR", + "title": "Euro" }, { - "const": "ALL", - "title": "Lek" + "const": "GBP", + "title": "British Pound" }, { - "const": "AMD", - "title": "Armenian Dram" + "const": "AUD", + "title": "Australian Dollar" }, { - "const": "ANG", - "title": "Netherlands Antillean Guilder" + "const": "CAD", + "title": "Canadian Dollar" }, { - "const": "AOA", - "title": "Kwanza" + "const": "JPY", + "title": "Japanese Yen" }, { - "const": "ARS", - "title": "Argentine Peso" + "const": "BYR", + "title": "Belarusian Ruble" }, { - "const": "AUD", - "title": "Australian Dollar" + "const": "MOP", + "title": "Macanese Pataca" }, { - "const": "AWG", - "title": "Aruban Florin" + "const": "HTG", + "title": "Haitian Gourde" }, { "const": "AZN", - "title": "Azerbaijan Manat" + "title": "Azerbaijani Manat" }, { "const": "BAM", - "title": "Convertible Mark" + "title": "Bosnia and Herzegovina Convertible Mark" }, { "const": "BBD", - "title": "Barbados Dollar" + "title": "Barbadian Dollar" }, { "const": "BDT", - "title": "Taka" + "title": "Bangladeshi Taka" }, { "const": "BGN", @@ -67,7 +67,7 @@ }, { "const": "BIF", - "title": "Burundi Franc" + "title": "Burundian Franc" }, { "const": "BMD", @@ -79,11 +79,7 @@ }, { "const": "BOB", - "title": "Boliviano" - }, - { - "const": "BOV", - "title": "Mvdol" + "title": "Bolivian Boliviano" }, { "const": "BRL", @@ -95,40 +91,36 @@ }, { "const": "BTN", - "title": "Ngultrum" + "title": "Bhutanese Ngultrum" }, { "const": "BWP", - "title": "Pula" + "title": "Botswana Pula" }, { "const": "BYN", "title": "Belarusian Ruble" }, + { + "const": "ARS", + "title": "Argentine Peso" + }, { "const": "BZD", "title": "Belize Dollar" }, { - "const": "CAD", - "title": "Canadian Dollar" + "const": "AOA", + "title": "Angolan Kwanza" }, { "const": "CDF", "title": "Congolese Franc" }, - { - "const": "CHE", - "title": "WIR Euro" - }, { "const": "CHF", "title": "Swiss Franc" }, - { - "const": "CHW", - "title": "WIR Franc" - }, { "const": "CLF", "title": "Unidad de Fomento" @@ -139,23 +131,19 @@ }, { "const": "CNY", - "title": "Yuan Renminbi" + "title": "Chinese Renminbi Yuan" }, { "const": "COP", "title": "Colombian Peso" }, - { - "const": "COU", - "title": "Unidad de Valor Real" - }, { "const": "CRC", - "title": "Costa Rican Colon" + "title": "Costa Rican Colón" }, { "const": "CUC", - "title": "Peso Convertible" + "title": "Cuban Convertible Peso" }, { "const": "CUP", @@ -163,7 +151,7 @@ }, { "const": "CVE", - "title": "Cabo Verde Escudo" + "title": "Cape Verdean Escudo" }, { "const": "CZK", @@ -171,15 +159,15 @@ }, { "const": "DJF", - "title": "Djibouti Franc" + "title": "Djiboutian Franc" }, { "const": "DKK", "title": "Danish Krone" }, { - "const": "DOP", - "title": "Dominican Peso" + "const": "MXN", + "title": "Mexican Peso" }, { "const": "DZD", @@ -191,35 +179,35 @@ }, { "const": "ERN", - "title": "Nakfa" + "title": "Eritrean Nakfa" }, { "const": "ETB", "title": "Ethiopian Birr" }, { - "const": "EUR", - "title": "Euro" + "const": "ANG", + "title": "Netherlands Antillean Gulden" }, { "const": "FJD", - "title": "Fiji Dollar" + "title": "Fijian Dollar" }, { "const": "FKP", - "title": "Falkland Islands Pound" + "title": "Falkland Pound" }, { - "const": "GBP", - "title": "Pound Sterling" + "const": "AMD", + "title": "Armenian Dram" }, { "const": "GEL", - "title": "Lari" + "title": "Georgian Lari" }, { "const": "GHS", - "title": "Ghana Cedi" + "title": "Ghanaian Cedi" }, { "const": "GIP", @@ -227,7 +215,7 @@ }, { "const": "GMD", - "title": "Dalasi" + "title": "Gambian Dalasi" }, { "const": "GNF", @@ -235,11 +223,11 @@ }, { "const": "GTQ", - "title": "Quetzal" + "title": "Guatemalan Quetzal" }, { "const": "GYD", - "title": "Guyana Dollar" + "title": "Guyanese Dollar" }, { "const": "HKD", @@ -247,27 +235,23 @@ }, { "const": "HNL", - "title": "Lempira" - }, - { - "const": "HRK", - "title": "Kuna" + "title": "Honduran Lempira" }, { - "const": "HTG", - "title": "Gourde" + "const": "MWK", + "title": "Malawian Kwacha" }, { "const": "HUF", - "title": "Forint" + "title": "Hungarian Forint" }, { "const": "IDR", - "title": "Rupiah" + "title": "Indonesian Rupiah" }, { "const": "ILS", - "title": "New Israeli Sheqel" + "title": "Israeli New Sheqel" }, { "const": "INR", @@ -283,7 +267,7 @@ }, { "const": "ISK", - "title": "Iceland Krona" + "title": "Icelandic Króna" }, { "const": "JMD", @@ -294,8 +278,8 @@ "title": "Jordanian Dinar" }, { - "const": "JPY", - "title": "Yen" + "const": "ALL", + "title": "Albanian Lek" }, { "const": "KES", @@ -303,15 +287,15 @@ }, { "const": "KGS", - "title": "Som" + "title": "Kyrgyzstani Som" }, { "const": "KHR", - "title": "Riel" + "title": "Cambodian Riel" }, { "const": "KMF", - "title": "Comorian Franc " + "title": "Comorian Franc" }, { "const": "KPW", @@ -319,7 +303,7 @@ }, { "const": "KRW", - "title": "Won" + "title": "South Korean Won" }, { "const": "KWD", @@ -331,7 +315,7 @@ }, { "const": "KZT", - "title": "Tenge" + "title": "Kazakhstani Tenge" }, { "const": "LAK", @@ -343,7 +327,7 @@ }, { "const": "LKR", - "title": "Sri Lanka Rupee" + "title": "Sri Lankan Rupee" }, { "const": "LRD", @@ -351,7 +335,7 @@ }, { "const": "LSL", - "title": "Loti" + "title": "Lesotho Loti" }, { "const": "LYD", @@ -371,43 +355,39 @@ }, { "const": "MKD", - "title": "Denar" + "title": "Macedonian Denar" }, { "const": "MMK", - "title": "Kyat" + "title": "Myanmar Kyat" }, { "const": "MNT", - "title": "Tugrik" + "title": "Mongolian Tögrög" }, { - "const": "MOP", - "title": "Pataca" + "const": "AED", + "title": "United Arab Emirates Dirham" }, { "const": "MRU", - "title": "Ouguiya" + "title": "Mauritanian Ouguiya" }, { "const": "MUR", - "title": "Mauritius Rupee" + "title": "Mauritian Rupee" }, { - "const": "MVR", - "title": "Rufiyaa" - }, - { - "const": "MWK", - "title": "Malawi Kwacha" + "const": "PLN", + "title": "Polish Złoty" }, { - "const": "MXN", - "title": "Mexican Peso" + "const": "AWG", + "title": "Aruban Florin" }, { - "const": "MXV", - "title": "Mexican Unidad de Inversion (UDI)" + "const": "DOP", + "title": "Dominican Peso" }, { "const": "MYR", @@ -415,19 +395,19 @@ }, { "const": "MZN", - "title": "Mozambique Metical" + "title": "Mozambican Metical" }, { "const": "NAD", - "title": "Namibia Dollar" + "title": "Namibian Dollar" }, { "const": "NGN", - "title": "Naira" + "title": "Nigerian Naira" }, { "const": "NIO", - "title": "Cordoba Oro" + "title": "Nicaraguan Córdoba" }, { "const": "NOK", @@ -443,19 +423,19 @@ }, { "const": "OMR", - "title": "Rial Omani" + "title": "Omani Rial" }, { "const": "PAB", - "title": "Balboa" + "title": "Panamanian Balboa" }, { "const": "PEN", - "title": "Sol" + "title": "Peruvian Sol" }, { "const": "PGK", - "title": "Kina" + "title": "Papua New Guinean Kina" }, { "const": "PHP", @@ -463,19 +443,19 @@ }, { "const": "PKR", - "title": "Pakistan Rupee" + "title": "Pakistani Rupee" }, { - "const": "PLN", - "title": "Zloty" + "const": "MVR", + "title": "Maldivian Rufiyaa" }, { "const": "PYG", - "title": "Guarani" + "title": "Paraguayan Guaraní" }, { "const": "QAR", - "title": "Qatari Rial" + "title": "Qatari Riyal" }, { "const": "RON", @@ -491,7 +471,7 @@ }, { "const": "RWF", - "title": "Rwanda Franc" + "title": "Rwandan Franc" }, { "const": "SAR", @@ -503,7 +483,7 @@ }, { "const": "SCR", - "title": "Seychelles Rupee" + "title": "Seychellois Rupee" }, { "const": "SDG", @@ -519,11 +499,19 @@ }, { "const": "SHP", - "title": "Saint Helena Pound" + "title": "Saint Helenian Pound" + }, + { + "const": "SKK", + "title": "Slovak Koruna" + }, + { + "const": "SLE", + "title": "New Leone" }, { "const": "SLL", - "title": "Leone" + "title": "Sierra Leonean Leone" }, { "const": "SOS", @@ -531,19 +519,23 @@ }, { "const": "SRD", - "title": "Surinam Dollar" + "title": "Surinamese Dollar" }, { "const": "SSP", "title": "South Sudanese Pound" }, + { + "const": "STD", + "title": "São Tomé and Príncipe Dobra" + }, { "const": "STN", - "title": "Dobra" + "title": "São Tomé and Príncipe Second Dobra" }, { "const": "SVC", - "title": "El Salvador Colon" + "title": "Salvadoran Colón" }, { "const": "SYP", @@ -551,19 +543,19 @@ }, { "const": "SZL", - "title": "Lilangeni" + "title": "Swazi Lilangeni" }, { "const": "THB", - "title": "Baht" + "title": "Thai Baht" }, { "const": "TJS", - "title": "Somoni" + "title": "Tajikistani Somoni" }, { "const": "TMT", - "title": "Turkmenistan New Manat" + "title": "Turkmenistani Manat" }, { "const": "TND", @@ -571,7 +563,7 @@ }, { "const": "TOP", - "title": "Pa’anga" + "title": "Tongan Paʻanga" }, { "const": "TRY", @@ -591,67 +583,95 @@ }, { "const": "UAH", - "title": "Hryvnia" + "title": "Ukrainian Hryvnia" }, { "const": "UGX", - "title": "Uganda Shilling" + "title": "Ugandan Shilling" }, { - "const": "USD", - "title": "US Dollar" - }, - { - "const": "USN", - "title": "US Dollar (Next day)" - }, - { - "const": "UYI", - "title": "Uruguay Peso en Unidades Indexadas (UI)" + "const": "AFN", + "title": "Afghan Afghani" }, { "const": "UYU", - "title": "Peso Uruguayo" - }, - { - "const": "UYW", - "title": "Unidad Previsional" + "title": "Uruguayan Peso" }, { "const": "UZS", - "title": "Uzbekistan Sum" + "title": "Uzbekistan Som" }, { "const": "VES", - "title": "Bolívar Soberano" + "title": "Venezuelan Bolívar Soberano" }, { "const": "VND", - "title": "Dong" + "title": "Vietnamese Đồng" }, { "const": "VUV", - "title": "Vatu" + "title": "Vanuatu Vatu" }, { "const": "WST", - "title": "Tala" + "title": "Samoan Tala" }, { "const": "XAF", - "title": "CFA Franc BEAC" + "title": "Central African Cfa Franc" + }, + { + "const": "XAG", + "title": "Silver (Troy Ounce)" + }, + { + "const": "XAU", + "title": "Gold (Troy Ounce)" + }, + { + "const": "XBA", + "title": "European Composite Unit" + }, + { + "const": "XBB", + "title": "European Monetary Unit" + }, + { + "const": "XBC", + "title": "European Unit of Account 9" + }, + { + "const": "XBD", + "title": "European Unit of Account 17" }, { "const": "XCD", "title": "East Caribbean Dollar" }, + { + "const": "XDR", + "title": "Special Drawing Rights" + }, { "const": "XOF", - "title": "CFA Franc BCEAO" + "title": "West African Cfa Franc" + }, + { + "const": "XPD", + "title": "Palladium" }, { "const": "XPF", - "title": "CFP Franc" + "title": "Cfp Franc" + }, + { + "const": "XPT", + "title": "Platinum" + }, + { + "const": "XTS", + "title": "Codes specifically reserved for testing purposes" }, { "const": "YER", @@ -659,21 +679,56 @@ }, { "const": "ZAR", - "title": "Rand" + "title": "South African Rand" + }, + { + "const": "ZMK", + "title": "Zambian Kwacha" }, { "const": "ZMW", "title": "Zambian Kwacha" }, { - "const": "ZWL", - "title": "Zimbabwe Dollar" + "const": "BCH", + "title": "Bitcoin Cash" + }, + { + "const": "BTC", + "title": "Bitcoin" + }, + { + "const": "JEP", + "title": "Jersey Pound" + }, + { + "const": "GGP", + "title": "Guernsey Pound" + }, + { + "const": "IMP", + "title": "Isle of Man Pound" + }, + { + "const": "XFU", + "title": "UIC Franc" + }, + { + "const": "GBX", + "title": "British Penny" + }, + { + "const": "CNH", + "title": "Chinese Renminbi Yuan Offshore" + }, + { + "const": "USDC", + "title": "USD Coin" } ], "type": "string", "title": "Currency Code", - "description": "ISO Currency Code" + "description": "Currency Code as defined in the GOBL source which is expected to be ISO or commonly used alternative." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/currency/exchange-rate.json b/data/schemas/currency/exchange-rate.json index 00cb6845..61a14707 100644 --- a/data/schemas/currency/exchange-rate.json +++ b/data/schemas/currency/exchange-rate.json @@ -23,6 +23,5 @@ ], "description": "ExchangeRate contains data on the rate to be used when converting amounts from the document's base currency to whatever is defined." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/dsig/digest.json b/data/schemas/dsig/digest.json index ceeed2e5..b187e8c6 100644 --- a/data/schemas/dsig/digest.json +++ b/data/schemas/dsig/digest.json @@ -23,6 +23,5 @@ ], "description": "Digest defines a structure to hold a digest value including the algorithm used to generate it." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/dsig/signature.json b/data/schemas/dsig/signature.json index 9bb2da64..3ff2a962 100644 --- a/data/schemas/dsig/signature.json +++ b/data/schemas/dsig/signature.json @@ -8,6 +8,5 @@ "title": "Signature", "description": "JSON Web Signature in compact form." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/envelope.json b/data/schemas/envelope.json index 62ed4494..0a333500 100644 --- a/data/schemas/envelope.json +++ b/data/schemas/envelope.json @@ -37,6 +37,5 @@ ], "description": "Envelope wraps around a document adding headers and digital signatures." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/head/header.json b/data/schemas/head/header.json index df1a565c..dc9cff7a 100644 --- a/data/schemas/head/header.json +++ b/data/schemas/head/header.json @@ -54,6 +54,5 @@ ], "description": "Header defines the metadata of the body." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/head/stamp.json b/data/schemas/head/stamp.json index 705bed05..adda9445 100644 --- a/data/schemas/head/stamp.json +++ b/data/schemas/head/stamp.json @@ -23,6 +23,5 @@ ], "description": "Stamp defines an official seal of approval from a third party like a governmental agency or intermediary and should thus be included in any official envelopes." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/i18n/string.json b/data/schemas/i18n/string.json index f443f006..b5404342 100644 --- a/data/schemas/i18n/string.json +++ b/data/schemas/i18n/string.json @@ -14,6 +14,5 @@ "title": "Multi-language String", "description": "Map of 2-Letter language codes to their translations." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/l10n/code.json b/data/schemas/l10n/code.json index f55da4b2..c5e43032 100644 --- a/data/schemas/l10n/code.json +++ b/data/schemas/l10n/code.json @@ -9,6 +9,5 @@ "title": "Code", "description": "Code is used for short identifies like country or state codes." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/l10n/country-code.json b/data/schemas/l10n/country-code.json index 82fbb791..93ad09b0 100644 --- a/data/schemas/l10n/country-code.json +++ b/data/schemas/l10n/country-code.json @@ -1006,6 +1006,5 @@ "title": "Country Code", "description": "Defines an ISO 3166-2 country code" } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/note/message.json b/data/schemas/note/message.json index 10d3ca48..a5e89897 100644 --- a/data/schemas/note/message.json +++ b/data/schemas/note/message.json @@ -33,6 +33,5 @@ } ] } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/num/amount.json b/data/schemas/num/amount.json index 6e83e765..2b7641f0 100644 --- a/data/schemas/num/amount.json +++ b/data/schemas/num/amount.json @@ -9,6 +9,5 @@ "title": "Amount", "description": "Quantity with optional decimal places that determine accuracy." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/num/percentage.json b/data/schemas/num/percentage.json index f3a8988e..e8b118a8 100644 --- a/data/schemas/num/percentage.json +++ b/data/schemas/num/percentage.json @@ -9,6 +9,5 @@ "title": "Percentage", "description": "Similar to an Amount, but designed for percentages and includes % symbol in JSON output." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/address.json b/data/schemas/org/address.json index 18401ec4..1bc86a00 100644 --- a/data/schemas/org/address.json +++ b/data/schemas/org/address.json @@ -87,6 +87,5 @@ ], "description": "Address defines a globally acceptable set of attributes that describes a postal or fiscal address." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/coordinates.json b/data/schemas/org/coordinates.json index d472fd75..6ed28855 100644 --- a/data/schemas/org/coordinates.json +++ b/data/schemas/org/coordinates.json @@ -29,6 +29,5 @@ "type": "object", "description": "Coordinates describes an exact geographical location in the world." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/email.json b/data/schemas/org/email.json index 773b4d47..fb0b8c99 100644 --- a/data/schemas/org/email.json +++ b/data/schemas/org/email.json @@ -31,6 +31,5 @@ ], "description": "Email describes the electronic mailing details." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/identity.json b/data/schemas/org/identity.json index b10145f3..e95439b8 100644 --- a/data/schemas/org/identity.json +++ b/data/schemas/org/identity.json @@ -42,6 +42,5 @@ ], "description": "Identity is used to define a code for a specific context." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/image.json b/data/schemas/org/image.json index d8311b66..b553cee9 100644 --- a/data/schemas/org/image.json +++ b/data/schemas/org/image.json @@ -65,6 +65,5 @@ "type": "object", "description": "Image describes a logo or photo that represents an entity." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/inbox.json b/data/schemas/org/inbox.json index 5ed61744..34bdcaa4 100644 --- a/data/schemas/org/inbox.json +++ b/data/schemas/org/inbox.json @@ -37,6 +37,5 @@ ], "description": "Inbox is used to store data about a connection with a service that is responsible for potentially receiving copies of GOBL envelopes or other document formats defined locally." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/item.json b/data/schemas/org/item.json index e663ddcc..96c41669 100644 --- a/data/schemas/org/item.json +++ b/data/schemas/org/item.json @@ -76,6 +76,5 @@ ], "description": "Item is used to describe a single product or service." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/name.json b/data/schemas/org/name.json index 78725695..983f6229 100644 --- a/data/schemas/org/name.json +++ b/data/schemas/org/name.json @@ -58,6 +58,5 @@ ], "description": "Name represents what a human is called." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/party.json b/data/schemas/org/party.json index d5288a61..82a877d1 100644 --- a/data/schemas/org/party.json +++ b/data/schemas/org/party.json @@ -111,6 +111,5 @@ ], "description": "Party represents a person or business entity." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/person.json b/data/schemas/org/person.json index 22afcec0..7c700db7 100644 --- a/data/schemas/org/person.json +++ b/data/schemas/org/person.json @@ -56,6 +56,5 @@ ], "description": "Person represents a human, and how to contact them electronically." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/registration.json b/data/schemas/org/registration.json index e8d06c74..e4bf84a2 100644 --- a/data/schemas/org/registration.json +++ b/data/schemas/org/registration.json @@ -49,6 +49,5 @@ "type": "object", "description": "Registration is used in countries that require additional information to be associated with a company usually related to a specific registration office." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/telephone.json b/data/schemas/org/telephone.json index 74788cb7..62f2c43b 100644 --- a/data/schemas/org/telephone.json +++ b/data/schemas/org/telephone.json @@ -27,6 +27,5 @@ ], "description": "Telephone describes what is expected for a telephone number." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/unit.json b/data/schemas/org/unit.json index 3981359b..e630477d 100644 --- a/data/schemas/org/unit.json +++ b/data/schemas/org/unit.json @@ -302,6 +302,5 @@ "title": "Unit", "description": "Unit describes how the quantity of the product should be interpreted either using a GOBL key, or UN/ECE code." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/org/website.json b/data/schemas/org/website.json index 566af6c1..13e533bc 100644 --- a/data/schemas/org/website.json +++ b/data/schemas/org/website.json @@ -33,6 +33,5 @@ ], "description": "Website describes what is expected for a web address." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/pay/advance.json b/data/schemas/pay/advance.json index 911bc78d..5a8f2d19 100644 --- a/data/schemas/pay/advance.json +++ b/data/schemas/pay/advance.json @@ -190,6 +190,5 @@ "type": "object", "description": "CreditTransfer contains fields that can be used for making payments via a bank transfer or wire." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/pay/instructions.json b/data/schemas/pay/instructions.json index a5f6d068..c4be73eb 100644 --- a/data/schemas/pay/instructions.json +++ b/data/schemas/pay/instructions.json @@ -220,6 +220,5 @@ ], "description": "Online provides the details required to make a payment online using a website" } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/pay/terms.json b/data/schemas/pay/terms.json index d84f1dca..061cea7f 100644 --- a/data/schemas/pay/terms.json +++ b/data/schemas/pay/terms.json @@ -119,6 +119,5 @@ "type": "object", "description": "Terms defines when we expect the customer to pay, or have paid, for the contents of the document." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/regimes/mx/food-vouchers.json b/data/schemas/regimes/mx/food-vouchers.json index 07d917d9..0f879976 100644 --- a/data/schemas/regimes/mx/food-vouchers.json +++ b/data/schemas/regimes/mx/food-vouchers.json @@ -100,6 +100,5 @@ ], "description": "FoodVouchersLine represents a single food voucher issued to the e-wallet of one of the customer's employees." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/regimes/mx/fuel-account-balance.json b/data/schemas/regimes/mx/fuel-account-balance.json index cc78c0de..f0ee98fa 100644 --- a/data/schemas/regimes/mx/fuel-account-balance.json +++ b/data/schemas/regimes/mx/fuel-account-balance.json @@ -162,6 +162,5 @@ ], "description": "FuelAccountTax represents a single tax applied to a fuel purchase." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/schema/object.json b/data/schemas/schema/object.json index db40b43c..19323477 100644 --- a/data/schemas/schema/object.json +++ b/data/schemas/schema/object.json @@ -8,6 +8,5 @@ "title": "Object", "description": "Data object whose type is determined from the \u003ccode\u003e$schema\u003c/code\u003e property." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/tax/extensions.json b/data/schemas/tax/extensions.json index 9499aeb6..045b2baa 100644 --- a/data/schemas/tax/extensions.json +++ b/data/schemas/tax/extensions.json @@ -12,6 +12,5 @@ "type": "object", "description": "Extensions is a map of extension keys to values." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/tax/identity.json b/data/schemas/tax/identity.json index 21a9e5b1..88f1f902 100644 --- a/data/schemas/tax/identity.json +++ b/data/schemas/tax/identity.json @@ -42,6 +42,5 @@ ], "description": "Identity stores the details required to identify an entity for tax purposes." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/tax/regime.json b/data/schemas/tax/regime.json index b629941f..870af8a3 100644 --- a/data/schemas/tax/regime.json +++ b/data/schemas/tax/regime.json @@ -412,6 +412,5 @@ ], "description": "Source describes where the information for the taxes comes from." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/tax/set.json b/data/schemas/tax/set.json index e141ad26..03fcc173 100644 --- a/data/schemas/tax/set.json +++ b/data/schemas/tax/set.json @@ -46,6 +46,5 @@ "type": "array", "description": "Set defines a list of tax categories and their rates to be used alongside taxable items." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/tax/total.json b/data/schemas/tax/total.json index 1f797722..ef55ad06 100644 --- a/data/schemas/tax/total.json +++ b/data/schemas/tax/total.json @@ -117,6 +117,5 @@ ], "description": "Total contains a set of Category Totals which in turn contain all the accumulated taxes contained in the document." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/data/schemas/uuid/uuid.json b/data/schemas/uuid/uuid.json index 278c9bf1..22d5c8d2 100644 --- a/data/schemas/uuid/uuid.json +++ b/data/schemas/uuid/uuid.json @@ -9,6 +9,5 @@ "title": "UUID", "description": "Universally Unique Identifier. We only recommend using versions 1 and 4 within GOBL." } - }, - "$comment": "Generated with GOBL v0.70.0" + } } \ No newline at end of file diff --git a/gobl.go b/gobl.go index abf79756..187fc3ff 100644 --- a/gobl.go +++ b/gobl.go @@ -16,6 +16,10 @@ import ( "github.com/invopop/gobl/schema" ) +//go:generate go run ./schema/generate.go +//go:generate go run ./regimes/generate.go +//go:generate go run ./currency/generate.go + func init() { schema.Register(schema.GOBL, Envelope{}, diff --git a/internal/currency/codes.go.tmpl b/internal/currency/codes.go.tmpl deleted file mode 100644 index 87ed3b7e..00000000 --- a/internal/currency/codes.go.tmpl +++ /dev/null @@ -1,26 +0,0 @@ -package currency - -// **** NOTICE! **** -// This file is auto-generated. Any manual changes will be overwritten. -// Generated on {{ .Date }} -// ***************** - -// List of ISO4217 currency codes. -const ( - {{- range $key, $val := .Codes }} - {{ $val }} Code = "{{ $val }}" - {{- end }} -) - -// CodeDefinitions lists all the currencies we know about -// with extra data. -var CodeDefinitions = []Def{ - {{- range .Rows }} - { - Code: {{ .Code }}, - Name: "{{ .Name }}", - Num: "{{ .Num }}", - Units: {{ .Units }}, - }, - {{- end }} -} \ No newline at end of file diff --git a/internal/currency/currency.go b/internal/currency/currency.go deleted file mode 100644 index 2b047b62..00000000 --- a/internal/currency/currency.go +++ /dev/null @@ -1,102 +0,0 @@ -// Package currency is used internally to generate Go currency structures from -// a data source. -package currency - -import ( - "encoding/xml" - "fmt" - "io/ioutil" - "os" - "sort" - "strconv" - "text/template" - "time" - - "github.com/invopop/gobl/currency" -) - -// CurrencyDoc is a currency document -type CurrencyDoc struct { // nolint:revive - XMLName xml.Name `xml:"ISO_4217"` - Table *CurrencyTable `xml:"CcyTbl"` -} - -// CurrencyTable ... -type CurrencyTable struct { // nolint:revive - Rows []*CurrencyDef `xml:"CcyNtry"` -} - -// CurrencyDef ... -type CurrencyDef struct { // nolint:revive - Name string `xml:"CcyNm"` // name of the currency - Country string `xml:"CtryNm"` // name of the country it belongs to - Code string `xml:"Ccy"` // three-letter currency code - Num string `xml:"CcyNbr"` // three-digit currency code - Units string `xml:"CcyMnrUnts"` // how many cents are used for the currency -} - -// GenerateCodes is a special tool function used to convert the source XML -// data into an array of currency definitions. -func GenerateCodes() error { - data, err := ioutil.ReadFile("./internal/currency/data/iso4217.xml") - if err != nil { - return err - } - - d := new(CurrencyDoc) - if err := xml.Unmarshal(data, d); err != nil { - return err - } - - f, err := os.Create("./currency/codes.go") - if err != nil { - return err - } - defer f.Close() // nolint:errcheck - - tmpl, err := template.ParseFiles("./internal/currency/codes.go.tmpl") - if err != nil { - return err - } - - codeSet := make(map[string]int) - rows := make(map[string]*currency.Def) - for _, r := range d.Table.Rows { - u, err := strconv.Atoi(r.Units) - if err != nil { - fmt.Printf("skipping row: %v - %v\n", r.Name, r.Code) - continue - } - if _, ok := codeSet[r.Code]; ok { - codeSet[r.Code]++ - continue - } - codeSet[r.Code] = 1 - def := ¤cy.Def{ - Name: r.Name, - Code: currency.Code(r.Code), - Num: r.Num, - Units: uint32(u), - } - rows[r.Code] = def - } - - // Move codeSet to array and sort - codes := make([]string, len(codeSet)) - i := 0 - for k := range codeSet { - codes[i] = k - i++ - } - sort.Strings(codes) - - fields := make(map[string]interface{}) - fields["Rows"] = rows - fields["Codes"] = codes - fields["Date"] = time.Now().UTC().String() - if err := tmpl.Execute(f, fields); err != nil { - return err - } - - return nil -} diff --git a/internal/currency/data/iso4217.xml b/internal/currency/data/iso4217.xml deleted file mode 100644 index 42609efe..00000000 --- a/internal/currency/data/iso4217.xml +++ /dev/null @@ -1,1949 +0,0 @@ - - - - - AFGHANISTAN - Afghani - AFN - 971 - 2 - - - ÅLAND ISLANDS - Euro - EUR - 978 - 2 - - - ALBANIA - Lek - ALL - 008 - 2 - - - ALGERIA - Algerian Dinar - DZD - 012 - 2 - - - AMERICAN SAMOA - US Dollar - USD - 840 - 2 - - - ANDORRA - Euro - EUR - 978 - 2 - - - ANGOLA - Kwanza - AOA - 973 - 2 - - - ANGUILLA - East Caribbean Dollar - XCD - 951 - 2 - - - ANTARCTICA - No universal currency - - - ANTIGUA AND BARBUDA - East Caribbean Dollar - XCD - 951 - 2 - - - ARGENTINA - Argentine Peso - ARS - 032 - 2 - - - ARMENIA - Armenian Dram - AMD - 051 - 2 - - - ARUBA - Aruban Florin - AWG - 533 - 2 - - - AUSTRALIA - Australian Dollar - AUD - 036 - 2 - - - AUSTRIA - Euro - EUR - 978 - 2 - - - AZERBAIJAN - Azerbaijan Manat - AZN - 944 - 2 - - - BAHAMAS (THE) - Bahamian Dollar - BSD - 044 - 2 - - - BAHRAIN - Bahraini Dinar - BHD - 048 - 3 - - - BANGLADESH - Taka - BDT - 050 - 2 - - - BARBADOS - Barbados Dollar - BBD - 052 - 2 - - - BELARUS - Belarusian Ruble - BYN - 933 - 2 - - - BELGIUM - Euro - EUR - 978 - 2 - - - BELIZE - Belize Dollar - BZD - 084 - 2 - - - BENIN - CFA Franc BCEAO - XOF - 952 - 0 - - - BERMUDA - Bermudian Dollar - BMD - 060 - 2 - - - BHUTAN - Indian Rupee - INR - 356 - 2 - - - BHUTAN - Ngultrum - BTN - 064 - 2 - - - BOLIVIA (PLURINATIONAL STATE OF) - Boliviano - BOB - 068 - 2 - - - BOLIVIA (PLURINATIONAL STATE OF) - Mvdol - BOV - 984 - 2 - - - BONAIRE, SINT EUSTATIUS AND SABA - US Dollar - USD - 840 - 2 - - - BOSNIA AND HERZEGOVINA - Convertible Mark - BAM - 977 - 2 - - - BOTSWANA - Pula - BWP - 072 - 2 - - - BOUVET ISLAND - Norwegian Krone - NOK - 578 - 2 - - - BRAZIL - Brazilian Real - BRL - 986 - 2 - - - BRITISH INDIAN OCEAN TERRITORY (THE) - US Dollar - USD - 840 - 2 - - - BRUNEI DARUSSALAM - Brunei Dollar - BND - 096 - 2 - - - BULGARIA - Bulgarian Lev - BGN - 975 - 2 - - - BURKINA FASO - CFA Franc BCEAO - XOF - 952 - 0 - - - BURUNDI - Burundi Franc - BIF - 108 - 0 - - - CABO VERDE - Cabo Verde Escudo - CVE - 132 - 2 - - - CAMBODIA - Riel - KHR - 116 - 2 - - - CAMEROON - CFA Franc BEAC - XAF - 950 - 0 - - - CANADA - Canadian Dollar - CAD - 124 - 2 - - - CAYMAN ISLANDS (THE) - Cayman Islands Dollar - KYD - 136 - 2 - - - CENTRAL AFRICAN REPUBLIC (THE) - CFA Franc BEAC - XAF - 950 - 0 - - - CHAD - CFA Franc BEAC - XAF - 950 - 0 - - - CHILE - Chilean Peso - CLP - 152 - 0 - - - CHILE - Unidad de Fomento - CLF - 990 - 4 - - - CHINA - Yuan Renminbi - CNY - 156 - 2 - - - CHRISTMAS ISLAND - Australian Dollar - AUD - 036 - 2 - - - COCOS (KEELING) ISLANDS (THE) - Australian Dollar - AUD - 036 - 2 - - - COLOMBIA - Colombian Peso - COP - 170 - 2 - - - COLOMBIA - Unidad de Valor Real - COU - 970 - 2 - - - COMOROS (THE) - Comorian Franc - KMF - 174 - 0 - - - CONGO (THE DEMOCRATIC REPUBLIC OF THE) - Congolese Franc - CDF - 976 - 2 - - - CONGO (THE) - CFA Franc BEAC - XAF - 950 - 0 - - - COOK ISLANDS (THE) - New Zealand Dollar - NZD - 554 - 2 - - - COSTA RICA - Costa Rican Colon - CRC - 188 - 2 - - - CÔTE D'IVOIRE - CFA Franc BCEAO - XOF - 952 - 0 - - - CROATIA - Kuna - HRK - 191 - 2 - - - CUBA - Cuban Peso - CUP - 192 - 2 - - - CUBA - Peso Convertible - CUC - 931 - 2 - - - CURAÇAO - Netherlands Antillean Guilder - ANG - 532 - 2 - - - CYPRUS - Euro - EUR - 978 - 2 - - - CZECHIA - Czech Koruna - CZK - 203 - 2 - - - DENMARK - Danish Krone - DKK - 208 - 2 - - - DJIBOUTI - Djibouti Franc - DJF - 262 - 0 - - - DOMINICA - East Caribbean Dollar - XCD - 951 - 2 - - - DOMINICAN REPUBLIC (THE) - Dominican Peso - DOP - 214 - 2 - - - ECUADOR - US Dollar - USD - 840 - 2 - - - EGYPT - Egyptian Pound - EGP - 818 - 2 - - - EL SALVADOR - El Salvador Colon - SVC - 222 - 2 - - - EL SALVADOR - US Dollar - USD - 840 - 2 - - - EQUATORIAL GUINEA - CFA Franc BEAC - XAF - 950 - 0 - - - ERITREA - Nakfa - ERN - 232 - 2 - - - ESTONIA - Euro - EUR - 978 - 2 - - - ESWATINI - Lilangeni - SZL - 748 - 2 - - - ETHIOPIA - Ethiopian Birr - ETB - 230 - 2 - - - EUROPEAN UNION - Euro - EUR - 978 - 2 - - - FALKLAND ISLANDS (THE) [MALVINAS] - Falkland Islands Pound - FKP - 238 - 2 - - - FAROE ISLANDS (THE) - Danish Krone - DKK - 208 - 2 - - - FIJI - Fiji Dollar - FJD - 242 - 2 - - - FINLAND - Euro - EUR - 978 - 2 - - - FRANCE - Euro - EUR - 978 - 2 - - - FRENCH GUIANA - Euro - EUR - 978 - 2 - - - FRENCH POLYNESIA - CFP Franc - XPF - 953 - 0 - - - FRENCH SOUTHERN TERRITORIES (THE) - Euro - EUR - 978 - 2 - - - GABON - CFA Franc BEAC - XAF - 950 - 0 - - - GAMBIA (THE) - Dalasi - GMD - 270 - 2 - - - GEORGIA - Lari - GEL - 981 - 2 - - - GERMANY - Euro - EUR - 978 - 2 - - - GHANA - Ghana Cedi - GHS - 936 - 2 - - - GIBRALTAR - Gibraltar Pound - GIP - 292 - 2 - - - GREECE - Euro - EUR - 978 - 2 - - - GREENLAND - Danish Krone - DKK - 208 - 2 - - - GRENADA - East Caribbean Dollar - XCD - 951 - 2 - - - GUADELOUPE - Euro - EUR - 978 - 2 - - - GUAM - US Dollar - USD - 840 - 2 - - - GUATEMALA - Quetzal - GTQ - 320 - 2 - - - GUERNSEY - Pound Sterling - GBP - 826 - 2 - - - GUINEA - Guinean Franc - GNF - 324 - 0 - - - GUINEA-BISSAU - CFA Franc BCEAO - XOF - 952 - 0 - - - GUYANA - Guyana Dollar - GYD - 328 - 2 - - - HAITI - Gourde - HTG - 332 - 2 - - - HAITI - US Dollar - USD - 840 - 2 - - - HEARD ISLAND AND McDONALD ISLANDS - Australian Dollar - AUD - 036 - 2 - - - HOLY SEE (THE) - Euro - EUR - 978 - 2 - - - HONDURAS - Lempira - HNL - 340 - 2 - - - HONG KONG - Hong Kong Dollar - HKD - 344 - 2 - - - HUNGARY - Forint - HUF - 348 - 2 - - - ICELAND - Iceland Krona - ISK - 352 - 0 - - - INDIA - Indian Rupee - INR - 356 - 2 - - - INDONESIA - Rupiah - IDR - 360 - 2 - - - INTERNATIONAL MONETARY FUND (IMF)  - SDR (Special Drawing Right) - XDR - 960 - N.A. - - - IRAN (ISLAMIC REPUBLIC OF) - Iranian Rial - IRR - 364 - 2 - - - IRAQ - Iraqi Dinar - IQD - 368 - 3 - - - IRELAND - Euro - EUR - 978 - 2 - - - ISLE OF MAN - Pound Sterling - GBP - 826 - 2 - - - ISRAEL - New Israeli Sheqel - ILS - 376 - 2 - - - ITALY - Euro - EUR - 978 - 2 - - - JAMAICA - Jamaican Dollar - JMD - 388 - 2 - - - JAPAN - Yen - JPY - 392 - 0 - - - JERSEY - Pound Sterling - GBP - 826 - 2 - - - JORDAN - Jordanian Dinar - JOD - 400 - 3 - - - KAZAKHSTAN - Tenge - KZT - 398 - 2 - - - KENYA - Kenyan Shilling - KES - 404 - 2 - - - KIRIBATI - Australian Dollar - AUD - 036 - 2 - - - KOREA (THE DEMOCRATIC PEOPLE’S REPUBLIC OF) - North Korean Won - KPW - 408 - 2 - - - KOREA (THE REPUBLIC OF) - Won - KRW - 410 - 0 - - - KUWAIT - Kuwaiti Dinar - KWD - 414 - 3 - - - KYRGYZSTAN - Som - KGS - 417 - 2 - - - LAO PEOPLE’S DEMOCRATIC REPUBLIC (THE) - Lao Kip - LAK - 418 - 2 - - - LATVIA - Euro - EUR - 978 - 2 - - - LEBANON - Lebanese Pound - LBP - 422 - 2 - - - LESOTHO - Loti - LSL - 426 - 2 - - - LESOTHO - Rand - ZAR - 710 - 2 - - - LIBERIA - Liberian Dollar - LRD - 430 - 2 - - - LIBYA - Libyan Dinar - LYD - 434 - 3 - - - LIECHTENSTEIN - Swiss Franc - CHF - 756 - 2 - - - LITHUANIA - Euro - EUR - 978 - 2 - - - LUXEMBOURG - Euro - EUR - 978 - 2 - - - MACAO - Pataca - MOP - 446 - 2 - - - NORTH MACEDONIA - Denar - MKD - 807 - 2 - - - MADAGASCAR - Malagasy Ariary - MGA - 969 - 2 - - - MALAWI - Malawi Kwacha - MWK - 454 - 2 - - - MALAYSIA - Malaysian Ringgit - MYR - 458 - 2 - - - MALDIVES - Rufiyaa - MVR - 462 - 2 - - - MALI - CFA Franc BCEAO - XOF - 952 - 0 - - - MALTA - Euro - EUR - 978 - 2 - - - MARSHALL ISLANDS (THE) - US Dollar - USD - 840 - 2 - - - MARTINIQUE - Euro - EUR - 978 - 2 - - - MAURITANIA - Ouguiya - MRU - 929 - 2 - - - MAURITIUS - Mauritius Rupee - MUR - 480 - 2 - - - MAYOTTE - Euro - EUR - 978 - 2 - - - MEMBER COUNTRIES OF THE AFRICAN DEVELOPMENT BANK GROUP - ADB Unit of Account - XUA - 965 - N.A. - - - MEXICO - Mexican Peso - MXN - 484 - 2 - - - MEXICO - Mexican Unidad de Inversion (UDI) - MXV - 979 - 2 - - - MICRONESIA (FEDERATED STATES OF) - US Dollar - USD - 840 - 2 - - - MOLDOVA (THE REPUBLIC OF) - Moldovan Leu - MDL - 498 - 2 - - - MONACO - Euro - EUR - 978 - 2 - - - MONGOLIA - Tugrik - MNT - 496 - 2 - - - MONTENEGRO - Euro - EUR - 978 - 2 - - - MONTSERRAT - East Caribbean Dollar - XCD - 951 - 2 - - - MOROCCO - Moroccan Dirham - MAD - 504 - 2 - - - MOZAMBIQUE - Mozambique Metical - MZN - 943 - 2 - - - MYANMAR - Kyat - MMK - 104 - 2 - - - NAMIBIA - Namibia Dollar - NAD - 516 - 2 - - - NAMIBIA - Rand - ZAR - 710 - 2 - - - NAURU - Australian Dollar - AUD - 036 - 2 - - - NEPAL - Nepalese Rupee - NPR - 524 - 2 - - - NETHERLANDS (THE) - Euro - EUR - 978 - 2 - - - NEW CALEDONIA - CFP Franc - XPF - 953 - 0 - - - NEW ZEALAND - New Zealand Dollar - NZD - 554 - 2 - - - NICARAGUA - Cordoba Oro - NIO - 558 - 2 - - - NIGER (THE) - CFA Franc BCEAO - XOF - 952 - 0 - - - NIGERIA - Naira - NGN - 566 - 2 - - - NIUE - New Zealand Dollar - NZD - 554 - 2 - - - NORFOLK ISLAND - Australian Dollar - AUD - 036 - 2 - - - NORTHERN MARIANA ISLANDS (THE) - US Dollar - USD - 840 - 2 - - - NORWAY - Norwegian Krone - NOK - 578 - 2 - - - OMAN - Rial Omani - OMR - 512 - 3 - - - PAKISTAN - Pakistan Rupee - PKR - 586 - 2 - - - PALAU - US Dollar - USD - 840 - 2 - - - PALESTINE, STATE OF - No universal currency - - - PANAMA - Balboa - PAB - 590 - 2 - - - PANAMA - US Dollar - USD - 840 - 2 - - - PAPUA NEW GUINEA - Kina - PGK - 598 - 2 - - - PARAGUAY - Guarani - PYG - 600 - 0 - - - PERU - Sol - PEN - 604 - 2 - - - PHILIPPINES (THE) - Philippine Peso - PHP - 608 - 2 - - - PITCAIRN - New Zealand Dollar - NZD - 554 - 2 - - - POLAND - Zloty - PLN - 985 - 2 - - - PORTUGAL - Euro - EUR - 978 - 2 - - - PUERTO RICO - US Dollar - USD - 840 - 2 - - - QATAR - Qatari Rial - QAR - 634 - 2 - - - RÉUNION - Euro - EUR - 978 - 2 - - - ROMANIA - Romanian Leu - RON - 946 - 2 - - - RUSSIAN FEDERATION (THE) - Russian Ruble - RUB - 643 - 2 - - - RWANDA - Rwanda Franc - RWF - 646 - 0 - - - SAINT BARTHÉLEMY - Euro - EUR - 978 - 2 - - - SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA - Saint Helena Pound - SHP - 654 - 2 - - - SAINT KITTS AND NEVIS - East Caribbean Dollar - XCD - 951 - 2 - - - SAINT LUCIA - East Caribbean Dollar - XCD - 951 - 2 - - - SAINT MARTIN (FRENCH PART) - Euro - EUR - 978 - 2 - - - SAINT PIERRE AND MIQUELON - Euro - EUR - 978 - 2 - - - SAINT VINCENT AND THE GRENADINES - East Caribbean Dollar - XCD - 951 - 2 - - - SAMOA - Tala - WST - 882 - 2 - - - SAN MARINO - Euro - EUR - 978 - 2 - - - SAO TOME AND PRINCIPE - Dobra - STN - 930 - 2 - - - SAUDI ARABIA - Saudi Riyal - SAR - 682 - 2 - - - SENEGAL - CFA Franc BCEAO - XOF - 952 - 0 - - - SERBIA - Serbian Dinar - RSD - 941 - 2 - - - SEYCHELLES - Seychelles Rupee - SCR - 690 - 2 - - - SIERRA LEONE - Leone - SLL - 694 - 2 - - - SINGAPORE - Singapore Dollar - SGD - 702 - 2 - - - SINT MAARTEN (DUTCH PART) - Netherlands Antillean Guilder - ANG - 532 - 2 - - - SISTEMA UNITARIO DE COMPENSACION REGIONAL DE PAGOS "SUCRE" - Sucre - XSU - 994 - N.A. - - - SLOVAKIA - Euro - EUR - 978 - 2 - - - SLOVENIA - Euro - EUR - 978 - 2 - - - SOLOMON ISLANDS - Solomon Islands Dollar - SBD - 090 - 2 - - - SOMALIA - Somali Shilling - SOS - 706 - 2 - - - SOUTH AFRICA - Rand - ZAR - 710 - 2 - - - SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS - No universal currency - - - SOUTH SUDAN - South Sudanese Pound - SSP - 728 - 2 - - - SPAIN - Euro - EUR - 978 - 2 - - - SRI LANKA - Sri Lanka Rupee - LKR - 144 - 2 - - - SUDAN (THE) - Sudanese Pound - SDG - 938 - 2 - - - SURINAME - Surinam Dollar - SRD - 968 - 2 - - - SVALBARD AND JAN MAYEN - Norwegian Krone - NOK - 578 - 2 - - - SWEDEN - Swedish Krona - SEK - 752 - 2 - - - SWITZERLAND - Swiss Franc - CHF - 756 - 2 - - - SWITZERLAND - WIR Euro - CHE - 947 - 2 - - - SWITZERLAND - WIR Franc - CHW - 948 - 2 - - - SYRIAN ARAB REPUBLIC - Syrian Pound - SYP - 760 - 2 - - - TAIWAN (PROVINCE OF CHINA) - New Taiwan Dollar - TWD - 901 - 2 - - - TAJIKISTAN - Somoni - TJS - 972 - 2 - - - TANZANIA, UNITED REPUBLIC OF - Tanzanian Shilling - TZS - 834 - 2 - - - THAILAND - Baht - THB - 764 - 2 - - - TIMOR-LESTE - US Dollar - USD - 840 - 2 - - - TOGO - CFA Franc BCEAO - XOF - 952 - 0 - - - TOKELAU - New Zealand Dollar - NZD - 554 - 2 - - - TONGA - Pa’anga - TOP - 776 - 2 - - - TRINIDAD AND TOBAGO - Trinidad and Tobago Dollar - TTD - 780 - 2 - - - TUNISIA - Tunisian Dinar - TND - 788 - 3 - - - TURKEY - Turkish Lira - TRY - 949 - 2 - - - TURKMENISTAN - Turkmenistan New Manat - TMT - 934 - 2 - - - TURKS AND CAICOS ISLANDS (THE) - US Dollar - USD - 840 - 2 - - - TUVALU - Australian Dollar - AUD - 036 - 2 - - - UGANDA - Uganda Shilling - UGX - 800 - 0 - - - UKRAINE - Hryvnia - UAH - 980 - 2 - - - UNITED ARAB EMIRATES (THE) - UAE Dirham - AED - 784 - 2 - - - UNITED KINGDOM OF GREAT BRITAIN AND NORTHERN IRELAND (THE) - Pound Sterling - GBP - 826 - 2 - - - UNITED STATES MINOR OUTLYING ISLANDS (THE) - US Dollar - USD - 840 - 2 - - - UNITED STATES OF AMERICA (THE) - US Dollar - USD - 840 - 2 - - - UNITED STATES OF AMERICA (THE) - US Dollar (Next day) - USN - 997 - 2 - - - URUGUAY - Peso Uruguayo - UYU - 858 - 2 - - - URUGUAY - Uruguay Peso en Unidades Indexadas (UI) - UYI - 940 - 0 - - - URUGUAY - Unidad Previsional - UYW - 927 - 4 - - - UZBEKISTAN - Uzbekistan Sum - UZS - 860 - 2 - - - VANUATU - Vatu - VUV - 548 - 0 - - - VENEZUELA (BOLIVARIAN REPUBLIC OF) - Bolívar Soberano - VES - 928 - 2 - - - VIET NAM - Dong - VND - 704 - 0 - - - VIRGIN ISLANDS (BRITISH) - US Dollar - USD - 840 - 2 - - - VIRGIN ISLANDS (U.S.) - US Dollar - USD - 840 - 2 - - - WALLIS AND FUTUNA - CFP Franc - XPF - 953 - 0 - - - WESTERN SAHARA - Moroccan Dirham - MAD - 504 - 2 - - - YEMEN - Yemeni Rial - YER - 886 - 2 - - - ZAMBIA - Zambian Kwacha - ZMW - 967 - 2 - - - ZIMBABWE - Zimbabwe Dollar - ZWL - 932 - 2 - - - ZZ01_Bond Markets Unit European_EURCO - Bond Markets Unit European Composite Unit (EURCO) - XBA - 955 - N.A. - - - ZZ02_Bond Markets Unit European_EMU-6 - Bond Markets Unit European Monetary Unit (E.M.U.-6) - XBB - 956 - N.A. - - - ZZ03_Bond Markets Unit European_EUA-9 - Bond Markets Unit European Unit of Account 9 (E.U.A.-9) - XBC - 957 - N.A. - - - ZZ04_Bond Markets Unit European_EUA-17 - Bond Markets Unit European Unit of Account 17 (E.U.A.-17) - XBD - 958 - N.A. - - - ZZ06_Testing_Code - Codes specifically reserved for testing purposes - XTS - 963 - N.A. - - - ZZ07_No_Currency - The codes assigned for transactions where no currency is involved - XXX - 999 - N.A. - - - ZZ08_Gold - Gold - XAU - 959 - N.A. - - - ZZ09_Palladium - Palladium - XPD - 964 - N.A. - - - ZZ10_Platinum - Platinum - XPT - 962 - N.A. - - - ZZ11_Silver - Silver - XAG - 961 - N.A. - - - \ No newline at end of file diff --git a/mage.go b/mage.go index 72987d43..eb40cd85 100644 --- a/mage.go +++ b/mage.go @@ -3,58 +3,14 @@ package main -import ( - "encoding/json" - "fmt" - "io/ioutil" - "path/filepath" - "strings" - - "github.com/invopop/gobl/internal/currency" - "github.com/invopop/gobl/internal/schemas" - "github.com/invopop/gobl/schema" - "github.com/invopop/gobl/tax" -) +import "errors" // Schema generates the JSON Schema from the base models func Schema() error { - return schemas.Generate() + return errors.New("please now run `go generate .` instead") } // Regimes generates JSON version of each regimes's data. func Regimes() error { - for _, r := range tax.AllRegimes() { - doc, err := schema.NewObject(r) - if err != nil { - return err - } - data, err := json.MarshalIndent(doc, "", " ") - if err != nil { - return err - } - n := string(r.Country) - if r.Zone != "" { - n = n + "_" + string(r.Zone) - } - n = strings.ToLower(n) - f := filepath.Join("data", "regimes", n+".json") - if err := ioutil.WriteFile(f, data, 0644); err != nil { - return err - } - fmt.Printf("Processed %v\n", f) - } - return nil -} - -// Currencies generates the Go definition files from the raw list of -// XML ISO data. -func Currencies() error { - return currency.GenerateCodes() -} - -// Samples runs through all the `.yaml` samples and generates complete GOBL -// Envelopes of each in `.json` files. -func Samples() error { - - return nil + return errors.New("please now run `go generate .` instead") } diff --git a/num/formatter.go b/num/formatter.go new file mode 100644 index 00000000..8b4336f3 --- /dev/null +++ b/num/formatter.go @@ -0,0 +1,143 @@ +package num + +import "strings" + +const ( + // DefaultFormatterTemplate is the default template used to + // format numbers for output. + DefaultFormatterTemplate = "%n%u" // e.g. "12%" +) + +// NumeralSystem describes how to output numbers. +type NumeralSystem string + +const ( + // NumeralWestern defines the Western Arabic numeral + // system, and is the default. + NumeralWestern NumeralSystem = "western" + // NumeralArabic can be used to output numbers using the + // Arabic numeral system. + NumeralArabic NumeralSystem = "arabic" +) + +// Formatter is used to define how an amount should be formatted +// alongside a unit if necessary. +type Formatter struct { + // DecimalMark is the character used to separate the whole + // number from the decimal part. + DecimalMark string + // ThousandsSeparator is the character used to separate + // thousands in the whole number. + ThousandsSeparator string + // Unit is the string representation or symbol of the unit. + Unit string + // Template is the string used to present the number and unit + // together with two simple placeholders, `%n` for the number and + // `%u` for the unit. + Template string + // NumeralSystem determines how numbers should be output. By default + // this is 'western'. + NumeralSystem NumeralSystem +} + +var ( + formatArabicReplacer = strings.NewReplacer( + "0", "٠", + "1", "١", + "2", "٢", + "3", "٣", + "4", "٤", + "5", "٥", + "6", "٦", + "7", "٧", + "8", "٨", + "9", "٩", + ) +) + +// MakeFormatter prepares a new formatter with the two main configuration +// options, decimal and thousands separators. +func MakeFormatter(decimalMark, thousandsSeparator string) Formatter { + return Formatter{ + DecimalMark: decimalMark, + ThousandsSeparator: thousandsSeparator, + } +} + +// WithUnit providers a formatter with a unit set. +func (f Formatter) WithUnit(unit string) Formatter { + f.Unit = unit + return f +} + +// WithoutUnit provides a formatter without a unit set. +func (f Formatter) WithoutUnit() Formatter { + f.Unit = "" + return f +} + +// WithTemplate sets the template for use with formatting with +// units. +func (f Formatter) WithTemplate(template string) Formatter { + f.Template = template + return f +} + +// WithNumeralSystem overrides the default western numeral system +// with that defined. +func (f Formatter) WithNumeralSystem(ns NumeralSystem) Formatter { + f.NumeralSystem = ns + return f +} + +// Amount takes the provided amount and formats it according to +// the rules of the formatter. +func (f Formatter) Amount(amount Amount) string { + n := f.formatNumber(amount.String()) + return f.formatWithUnits(n) +} + +// Percentage tries to format the percentage value according to the +// rules of the formatter, but replacing the unit with a percentage +// symbol, and using the default template. +func (f Formatter) Percentage(percent Percentage) string { + n := f.formatNumber(percent.StringWithoutSymbol()) + return f.WithUnit("%").WithTemplate("").formatWithUnits(n) +} + +func (f Formatter) formatWithUnits(n string) string { + if f.Unit == "" { + return n + } + t := f.Template + if t == "" { + t = DefaultFormatterTemplate + } + t = strings.Replace(t, "%u", f.Unit, 1) + t = strings.Replace(t, "%n", n, 1) + return t +} + +func (f Formatter) formatNumber(n string) string { + p := strings.Split(n, ".") + n = p[0] + // split the main part with thousands separator + for i := len(n) - 3; i > 0; i = i - 3 { + n = n[:i] + f.ThousandsSeparator + n[i:] + } + if len(p) == 2 { + n = n + f.DecimalMark + p[1] + } + n = f.formatNumberForSystem(n) + return n +} + +func (f Formatter) formatNumberForSystem(n string) string { + switch f.NumeralSystem { + case NumeralArabic: + // Support for Arabic numbers is somewhat experimental, feedback welcome! + return formatArabicReplacer.Replace(n) + default: + return n + } +} diff --git a/num/formatter_test.go b/num/formatter_test.go new file mode 100644 index 00000000..56ae84d2 --- /dev/null +++ b/num/formatter_test.go @@ -0,0 +1,150 @@ +package num_test + +import ( + "testing" + + "github.com/invopop/gobl/num" + "github.com/stretchr/testify/assert" +) + +func TestFormatterAmount(t *testing.T) { + // make a test table + tests := []struct { + name string + f num.Formatter + amt num.Amount + exp string + }{ + { + name: "no unit: zero", + f: num.MakeFormatter(".", ","), + amt: num.MakeAmount(0, 2), + exp: "0.00", + }, + { + name: "no unit: zero eu", + f: num.MakeFormatter(",", "."), + amt: num.MakeAmount(0, 2), + exp: "0,00", + }, + { + name: "no unit: thousands", + f: num.MakeFormatter(".", ","), + amt: num.MakeAmount(123456, 2), + exp: "1,234.56", + }, + { + name: "no unit: thousands eu", + f: num.MakeFormatter(",", "."), + amt: num.MakeAmount(123456, 2), + exp: "1.234,56", + }, + { + name: "no unit: millions", + f: num.MakeFormatter(".", ","), + amt: num.MakeAmount(123456789, 2), + exp: "1,234,567.89", + }, + { + name: "with unit default format zero", + f: num.MakeFormatter(".", ",").WithUnit("%"), + amt: num.MakeAmount(0, 2), + exp: "0.00%", + }, + { + name: "with unit default format thousands", + f: num.MakeFormatter(".", ",").WithUnit("%"), + amt: num.MakeAmount(123456, 2), + exp: "1,234.56%", + }, + { + name: "with unit default format millions", + f: num.MakeFormatter(".", ",").WithUnit("%"), + amt: num.MakeAmount(123456789, 2), + exp: "1,234,567.89%", + }, + { + name: "with custom template format zero", + f: num.MakeFormatter(".", ","). + WithUnit("$"). + WithTemplate("%u%n"), + amt: num.MakeAmount(0, 2), + exp: "$0.00", + }, + { + name: "with custom template format thousands", + f: num.MakeFormatter(".", ",").WithUnit("$").WithTemplate("%u%n"), + amt: num.MakeAmount(123456, 2), + exp: "$1,234.56", + }, + { + name: "with custom template format millions", + f: num.MakeFormatter(",", ".").WithUnit("€").WithTemplate("%n %u"), + amt: num.MakeAmount(123456789, 2), + exp: "1.234.567,89 €", + }, + { + name: "with custom template format millions", + f: num.MakeFormatter(",", ".").WithUnit("€").WithTemplate("%n %u").WithoutUnit(), + amt: num.MakeAmount(123456789, 2), + exp: "1.234.567,89", + }, + { + name: "with arabic numbers", + f: num.MakeFormatter(",", ".").WithNumeralSystem(num.NumeralArabic), + amt: num.MakeAmount(123456, 2), + exp: "١.٢٣٤,٥٦", + }, + { + name: "with arabic numbers and unit", + f: num.MakeFormatter(",", ".").WithNumeralSystem(num.NumeralArabic).WithUnit("د.إ"), + amt: num.MakeAmount(123456, 2), + exp: `١.٢٣٤,٥٦د.إ`, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.exp, test.f.Amount(test.amt)) + }) + } +} + +func TestFormatterPercentage(t *testing.T) { + tests := []struct { + name string + f num.Formatter + p num.Percentage + exp string + }{ + { + name: "default format zero", + f: num.MakeFormatter(".", ","), + p: num.MakePercentage(0, 2), + exp: "0%", + }, + { + name: "default format 16%", + f: num.MakeFormatter(".", ","), + p: num.MakePercentage(160, 3), + exp: "16.0%", + }, + { + name: "default format with unit to ignore", + f: num.MakeFormatter(".", ",").WithUnit("XX"), + p: num.MakePercentage(160, 3), + exp: "16.0%", + }, + { + name: "default with format to ignore", + f: num.MakeFormatter(".", ",").WithTemplate("%u%n"), + p: num.MakePercentage(160, 3), + exp: "16.0%", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.exp, test.f.Percentage(test.p)) + }) + } + +} diff --git a/regimes/generate.go b/regimes/generate.go new file mode 100644 index 00000000..ef0eb08f --- /dev/null +++ b/regimes/generate.go @@ -0,0 +1,44 @@ +//go:build ignore + +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/invopop/gobl/schema" + "github.com/invopop/gobl/tax" +) + +func main() { + if error := generate(); error != nil { + panic(error) + } +} + +func generate() error { + for _, r := range tax.AllRegimes() { + doc, err := schema.NewObject(r) + if err != nil { + return err + } + data, err := json.MarshalIndent(doc, "", " ") + if err != nil { + return err + } + n := string(r.Country) + if r.Zone != "" { + n = n + "_" + string(r.Zone) + } + n = strings.ToLower(n) + f := filepath.Join("data", "regimes", n+".json") + if err := os.WriteFile(f, data, 0644); err != nil { + return err + } + fmt.Printf("Processed %v\n", f) + } + return nil +} diff --git a/internal/schemas/schemas.go b/schema/generate.go similarity index 85% rename from internal/schemas/schemas.go rename to schema/generate.go index 687c7484..45881ebf 100644 --- a/internal/schemas/schemas.go +++ b/schema/generate.go @@ -1,5 +1,6 @@ -// Package schemas helps generate JSON Schema files from the main GOBL packages. -package schemas +//go:build ignore + +package main import ( "encoding/json" @@ -9,7 +10,7 @@ import ( "reflect" "strings" - "github.com/invopop/gobl" + _ "github.com/invopop/gobl" // load everything "github.com/invopop/gobl/schema" "github.com/invopop/jsonschema" ) @@ -17,7 +18,13 @@ import ( const outPath = "./data/schemas" // Generate is used to generate a set of schema files from the GOBL bases. -func Generate() error { +func main() { + if err := generate(); err != nil { + panic(err) + } +} + +func generate() error { r := new(jsonschema.Reflector) r.AllowAdditionalProperties = true @@ -34,8 +41,6 @@ func Generate() error { return jsonschema.EmptyID } - comment := fmt.Sprintf("Generated with GOBL %v", gobl.VERSION) - // Cleanup the old if err := os.RemoveAll(outPath); err != nil { return fmt.Errorf("unable to remove old data: %w", err) @@ -44,7 +49,6 @@ func Generate() error { for t, id := range schema.Types() { fmt.Printf("processing %v... ", id) s := r.ReflectFromType(t) - s.Comments = comment f := strings.TrimPrefix(id.String(), schema.GOBL.String()) + ".json" f = filepath.Join(outPath, f) diff --git a/tax/regime.go b/tax/regime.go index cab87c90..807ca450 100644 --- a/tax/regime.go +++ b/tax/regime.go @@ -227,11 +227,7 @@ func (r *Regime) CalculateObject(obj interface{}) error { // CurrencyDef provides the currency definition object for the region. func (r *Regime) CurrencyDef() *currency.Def { - d, ok := currency.Get(r.Currency) - if !ok { - return nil - } - return &d + return currency.Get(r.Currency) } // ScenarioSet returns a single scenario set instance for the provided