diff --git a/l10n_us_partner_zipcode/__init__.py b/l10n_us_partner_zipcode/__init__.py
new file mode 100644
index 00000000..0fbdfcf8
--- /dev/null
+++ b/l10n_us_partner_zipcode/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+from . import res_partner
diff --git a/l10n_us_partner_zipcode/__manifest__.py b/l10n_us_partner_zipcode/__manifest__.py
new file mode 100644
index 00000000..80ef4157
--- /dev/null
+++ b/l10n_us_partner_zipcode/__manifest__.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+#
+#
+# Author: Jared Kipe
+# Copyright 2017 Hibou Corp.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+#
+
+{
+ 'name': 'US ZIP Code to City/State',
+ 'summary': 'Determines the City and State from a provided ZIP code.',
+ 'version': '10.0.1.0.0',
+ 'author': "Hibou Corp.",
+ 'category': 'Localization',
+ 'license': 'AGPL-3',
+ 'complexity': 'easy',
+ 'images': [],
+ 'website': "https://hibou.io",
+ 'description': """
+US ZIP Code to City/State
+=========================
+
+Determines the City and State from a provided ZIP code. Requires the `uszipcode` python package.
+
+Does not require `base_geolocalize`, but will fill the related fields if possible.
+
+
+Contributors
+------------
+
+* Jared Kipe
+
+""",
+ 'depends': [
+ 'base',
+ ],
+ 'external_dependencies': {
+ 'python': ['uszipcode']
+ },
+ 'demo': [],
+ 'data': [
+ ],
+ 'auto_install': False,
+ 'installable': True,
+}
diff --git a/l10n_us_partner_zipcode/res_partner.py b/l10n_us_partner_zipcode/res_partner.py
new file mode 100644
index 00000000..7a2e4f14
--- /dev/null
+++ b/l10n_us_partner_zipcode/res_partner.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+import logging
+
+_logger = logging.getLogger(__name__)
+
+try:
+ from uszipcode import ZipcodeSearchEngine
+except ImportError:
+ _logger.warn('module "uszipcode" cannot be loaded, you will be unable to detect Cities and States by ZIP')
+ ZipcodeSearchEngine = None
+
+from odoo import api, fields, models
+
+
+class Partner(models.Model):
+ _inherit = 'res.partner'
+
+ @api.onchange('zip')
+ def _zip_to_city_state(self):
+ if ZipcodeSearchEngine and self.zip and not self.city:
+ country_us = self.env['res.country'].search([('code', '=', 'US')], limit=1)
+ state_obj = self.env['res.country.state']
+ if not self.country_id or self.country_id.id == country_us.id:
+ with ZipcodeSearchEngine() as search:
+ zipcode = search.by_zipcode(self.zip)
+ if zipcode:
+ if not self.country_id:
+ self.country_id = country_us
+
+ self.city = zipcode['City']
+ self.state_id = state_obj.search([
+ ('code', '=', zipcode['State']),
+ ('country_id', '=', country_us.id),
+ ], limit=1)
+
+ if hasattr(self, 'partner_latitude') and not self.partner_latitude:
+ self.partner_latitude = zipcode['Latitude']
+ self.partner_longitude = zipcode['Longitude']
+ self.date_localization = fields.Date.context_today(self)
+ return {}