Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Implement way to get country code and province code #44

Open
phantom-factotum opened this issue Sep 3, 2021 · 0 comments
Open

Implement way to get country code and province code #44

phantom-factotum opened this issue Sep 3, 2021 · 0 comments

Comments

@phantom-factotum
Copy link

I was looking to use node-sales-tax in a small expense tracking project and I wanted to automatically set the sales tax base on the user location. While reading the documentation, I found that the country code and province code are needed to get the sales tax, but I did not see any helpers for converting a location into these codes. After searching for a bit, I found the answer from the U.S. Customs and Border Patrol of all places. They provide an excel sheet that has the country and province code for 1637 provinces.

I wrote some code to download the xlsx and convert it to a json file ( I am a novice, so I apologize for all issues with the code):

const XLSX = require('xlsx')
const fs = require('fs')
const axios = require('axios')
const path = require('path')

let currentDir = process.cwd()
let xlsxFileName = path.join(currentDir,'./international-province-codes.xls')
let jsonFileName = path.join(currentDir,'./codes.json')
// excel sheet has 3 columns
const columns = {
	countryCode:'A',
	provinceCode:'B',
	provinceName:'C'
}
async function getFile(){
	// customs and border patrol provides a xlsx file with all international state/province codes
	let xlsxUrl = 'https://www.cbp.gov/sites/default/files/documents/codes_7.xls'
	const response = await axios.get(xlsxUrl,{
		responseType:'stream',
	})
	await response.data.pipe(fs.createWriteStream(xlsxFileName))
	return xlsxFileName
}
async function parseXlsx(){
	let sheet
	try{
		sheet = XLSX.readFile(await getFile())
	}catch(err){
		if(err.errno === -4058){
			console.error('Excel sheet not found')
			process.exit()
		}
	}
	sheet = sheet.Sheets.Sheet1
	// remove unnecessary keys
	let validKeys = Object.keys(sheet).filter(key=>
		// keys are a letter and a number e.g 'A1'
		key && sheet[key]?.w && (
			key[0] == columns.countryCode || 
			key[0] == columns.provinceCode ||
			key[0] == columns.provinceName
		)
	)
	// convert validKeys into json object
	let provinceCodes = {}
	validKeys.forEach(key=>{
		let rowNumber = parseInt(key.substring(1))
		let countryCell = columns.countryCode + rowNumber
		let provinceCell = columns.provinceCode + rowNumber
		let nameCell = columns.provinceName+rowNumber
		
		// even after filtering to make sure the cells exist
		// the cell values are sometimes null ???
		let countryCode = sheet[countryCell]?.w
		let provinceCode = sheet[provinceCell]?.w
		let provinceName = sheet[nameCell]?.w
		
		// remove diacritical/accent characters found solution here: 
	  // https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
		provinceName = provinceName?.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase()
		provinceCodes[provinceName] = { countryCode,provinceCode}
	})
	// write to file 
	fs.writeFileSync(jsonFileName,JSON.stringify(provinceCodes,null,2))
}
parseXlsx()

The resulting json should allow users to to use states/provinces to get both country and province codes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant