{"record":{"id":"760b1d5c941e2508","repo":"odoo/odoo","slug":"a-fiscal-position-with-a-foreign-vat-already-exist","errorCode":null,"errorMessage":"A fiscal position with a foreign VAT already exists in this country.","messagePattern":"A fiscal position with a foreign VAT already exists in this country\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"addons/account/models/partner.py","lineNumber":139,"sourceCode":"            if record.foreign_vat:\n                if not record.country_id:\n                    raise ValidationError(_(\"The country of the foreign VAT number could not be detected. Please assign a country to the fiscal position.\"))\n                if record.country_id == record.company_id.account_fiscal_country_id:\n                    if not record.state_ids:\n                        if record.company_id.account_fiscal_country_id.state_ids:\n                            raise ValidationError(_(\"You cannot create a fiscal position with a foreign VAT within your fiscal country without assigning it a state.\"))\n                if record.country_group_id and record.country_id:\n                    if record.country_id not in record.country_group_id.country_ids:\n                        raise ValidationError(_(\"You cannot create a fiscal position with a country outside of the selected country group.\"))\n\n                similar_fpos_count = self.env['account.fiscal.position'].search_count([\n                    *self.env['account.fiscal.position']._check_company_domain(record.company_id),\n                    ('foreign_vat', 'not in', (False, record.foreign_vat)),\n                    ('id', '!=', record.id),\n                    ('country_id', '=', record.country_id.id),\n                ])\n                if similar_fpos_count:\n                    raise ValidationError(_(\"A fiscal position with a foreign VAT already exists in this country.\"))\n\n    @api.onchange('country_id', 'foreign_vat')\n    def _onchange_foreign_vat(self):\n        self.foreign_vat, _country_code = self.env['res.partner']._run_vat_checks(self.country_id, self.foreign_vat, validation=False)\n\n    def _inverse_foreign_vat(self):\n        for record in self:\n            if not record.foreign_vat:\n                continue\n\n            if record.country_id:\n                fp_label = _(\"fiscal position [%s]\", record.name)\n                record.foreign_vat, _country_code = self.env['res.partner']._run_vat_checks(record.country_id, record.foreign_vat, partner_name=fp_label)\n\n    def map_tax(self, taxes):\n        if not self:\n            return taxes\n        if not self.tax_ids:","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/odoo/odoo/blob/1e661df964b1b264c9cef3ab28430d4785be3fda/addons/account/models/partner.py#L121-L157","documentation":"Constraint on account.fiscal.position: at most one fiscal position per company may declare a given foreign_vat country. It counts sibling positions (same company domain, same country_id, any different foreign_vat value, excluding self) and raises ValidationError on duplicates, keeping the foreign-VAT registry unambiguous.","triggerScenarios":"create()/write() producing a second account.fiscal.position with the same country_id and a foreign_vat, in the same company; e.g. adding 'DE VAT #2' when 'DE VAT' already exists.","commonSituations":"Duplicate onboarding runs creating positions per registration; imports re-run without dedupe; two users creating the same foreign registration concurrently.","solutions":["Reuse the existing fiscal position for that country (update its tax/account mappings) instead of creating another.","Delete or archive the obsolete duplicate, then save the new one.","Dedupe in imports: search_count first, and skip when a position for that country exists."],"exampleFix":"# before\nenv['account.fiscal.position'].create({'name': 'DE 2', 'country_id': de.id, 'foreign_vat': 'DE987'})  # ValidationError\n\n# after\nexisting = env['account.fiscal.position'].search([\n    ('company_id', '=', company.id), ('country_id', '=', de.id),\n    ('foreign_vat', '!=', False)], limit=1)\nfpos = existing or env['account.fiscal.position'].create({...})","handlingStrategy":"validation","validationCode":"def no_duplicate_fpos(env, company, country_id, exclude_id=None):\n    return not env['account.fiscal.position'].search_count([\n        *env['account.fiscal.position']._check_company_domain(company),\n        ('foreign_vat', 'not in', (False, False)),\n        ('id', '!=', exclude_id), ('country_id', '=', country_id)])","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Search for an existing same-country foreign-VAT position before creating one.","Make onboarding wizards idempotent (reuse instead of duplicate)."],"tags":["odoo","accounting","fiscal-position","vat","duplicates"],"backgroundTag":null,"analyzedSha":"1e661df964b1b264c9cef3ab28430d4785be3fda","analyzedAt":"2026-08-15T05:22:16.142Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}