We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Wrong AddressForm for Ireland
### What I'm trying to achieve
I tried to use address form validation for Ireland. Unfortunately, our API returns for that country that `country_area` is not required, but `AddressFormIE` requires it. 

### Steps to reproduce the problem
1. Send `CheckoutShippingAddressUpdate` without `country_area` - API returns validation error.

Another way to expect that problem is adding `IE` to the `test_address_form_for_country` test function - it fails.

### What I expected to happen
API and form validation should be consistent - if `i18naddress` says that field is not required, it is not required.

### Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->
n/a

**System information**
Operating system: n/a
Browser: n/a


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `saleor/account/i18n.py`
Content:
```
1 from collections import defaultdict
2 
3 import i18naddress
4 from django import forms
5 from django.core.exceptions import ValidationError
6 from django.forms.forms import BoundField
7 from django.utils.translation import pgettext_lazy
8 from django_countries import countries
9 
10 from .models import Address
11 from .validators import validate_possible_number
12 from .widgets import DatalistTextWidget, PhonePrefixWidget
13 
14 COUNTRY_FORMS = {}
15 UNKNOWN_COUNTRIES = set()
16 
17 AREA_TYPE_TRANSLATIONS = {
18     "area": pgettext_lazy("Address field", "Area"),
19     "county": pgettext_lazy("Address field", "County"),
20     "department": pgettext_lazy("Address field", "Department"),
21     "district": pgettext_lazy("Address field", "District"),
22     "do_si": pgettext_lazy("Address field", "Do/si"),
23     "eircode": pgettext_lazy("Address field", "Eircode"),
24     "emirate": pgettext_lazy("Address field", "Emirate"),
25     "island": pgettext_lazy("Address field", "Island"),
26     "neighborhood": pgettext_lazy("Address field", "Neighborhood"),
27     "oblast": pgettext_lazy("Address field", "Oblast"),
28     "parish": pgettext_lazy("Address field", "Parish"),
29     "pin": pgettext_lazy("Address field", "PIN"),
30     "postal": pgettext_lazy("Address field", "Postal code"),
31     "prefecture": pgettext_lazy("Address field", "Prefecture"),
32     "province": pgettext_lazy("Address field", "Province"),
33     "state": pgettext_lazy("Address field", "State"),
34     "suburb": pgettext_lazy("Address field", "Suburb"),
35     "townland": pgettext_lazy("Address field", "Townland"),
36     "village_township": pgettext_lazy("Address field", "Village/township"),
37     "zip": pgettext_lazy("Address field", "ZIP code"),
38 }
39 
40 
41 class PossiblePhoneNumberFormField(forms.CharField):
42     """A phone input field."""
43 
44     def __init__(self, *args, **kwargs):
45         super().__init__(*args, **kwargs)
46         self.widget.input_type = "tel"
47 
48 
49 class CountryAreaChoiceField(forms.ChoiceField):
50     widget = DatalistTextWidget
51 
52     def valid_value(self, value):
53         return True
54 
55 
56 class AddressMetaForm(forms.ModelForm):
57     # This field is never visible in UI
58     preview = forms.BooleanField(initial=False, required=False)
59 
60     class Meta:
61         model = Address
62         fields = ["country", "preview"]
63         labels = {"country": pgettext_lazy("Country", "Country")}
64 
65     def clean(self):
66         data = super().clean()
67         if data.get("preview"):
68             self.data = self.data.copy()
69             self.data["preview"] = False
70         return data
71 
72 
73 class AddressForm(forms.ModelForm):
74 
75     AUTOCOMPLETE_MAPPING = [
76         ("first_name", "given-name"),
77         ("last_name", "family-name"),
78         ("company_name", "organization"),
79         ("street_address_1", "address-line1"),
80         ("street_address_2", "address-line2"),
81         ("city", "address-level2"),
82         ("postal_code", "postal-code"),
83         ("country_area", "address-level1"),
84         ("country", "country"),
85         ("city_area", "address-level3"),
86         ("phone", "tel"),
87         ("email", "email"),
88     ]
89 
90     class Meta:
91         model = Address
92         exclude = []
93         labels = {
94             "first_name": pgettext_lazy("Personal name", "Given name"),
95             "last_name": pgettext_lazy("Personal name", "Family name"),
96             "company_name": pgettext_lazy(
97                 "Company or organization", "Company or organization"
98             ),
99             "street_address_1": pgettext_lazy("Address", "Address"),
100             "street_address_2": "",
101             "city": pgettext_lazy("City", "City"),
102             "city_area": pgettext_lazy("City area", "District"),
103             "postal_code": pgettext_lazy("Postal code", "Postal code"),
104             "country": pgettext_lazy("Country", "Country"),
105             "country_area": pgettext_lazy("Country area", "State or province"),
106             "phone": pgettext_lazy("Phone number", "Phone number"),
107         }
108         placeholders = {
109             "street_address_1": pgettext_lazy(
110                 "Address", "Street address, P.O. box, company name"
111             ),
112             "street_address_2": pgettext_lazy(
113                 "Address", "Apartment, suite, unit, building, floor, etc"
114             ),
115         }
116 
117     phone = PossiblePhoneNumberFormField(widget=PhonePrefixWidget, required=False)
118 
119     def __init__(self, *args, **kwargs):
120         autocomplete_type = kwargs.pop("autocomplete_type", None)
121         super().__init__(*args, **kwargs)
122         # countries order was taken as defined in the model,
123         # not being sorted accordingly to the selected language
124         self.fields["country"].choices = sorted(
125             COUNTRY_CHOICES, key=lambda choice: choice[1]
126         )
127         autocomplete_dict = defaultdict(lambda: "off", self.AUTOCOMPLETE_MAPPING)
128         for field_name, field in self.fields.items():
129             if autocomplete_type:
130                 autocomplete = "%s %s" % (
131                     autocomplete_type,
132                     autocomplete_dict[field_name],
133                 )
134             else:
135                 autocomplete = autocomplete_dict[field_name]
136             field.widget.attrs["autocomplete"] = autocomplete
137             field.widget.attrs["placeholder"] = (
138                 field.label if not hasattr(field, "placeholder") else field.placeholder
139             )
140 
141     def clean(self):
142         data = super().clean()
143         phone = data.get("phone")
144         country = data.get("country")
145         if phone:
146             try:
147                 data["phone"] = validate_possible_number(phone, country)
148             except forms.ValidationError as error:
149                 self.add_error("phone", error)
150         return data
151 
152 
153 class CountryAwareAddressForm(AddressForm):
154 
155     I18N_MAPPING = [
156         ("name", ["first_name", "last_name"]),
157         ("street_address", ["street_address_1", "street_address_2"]),
158         ("city_area", ["city_area"]),
159         ("country_area", ["country_area"]),
160         ("company_name", ["company_name"]),
161         ("postal_code", ["postal_code"]),
162         ("city", ["city"]),
163         ("sorting_code", []),
164         ("country_code", ["country"]),
165     ]
166 
167     class Meta:
168         model = Address
169         exclude = []
170 
171     def add_field_errors(self, errors):
172         field_mapping = dict(self.I18N_MAPPING)
173         for field_name, error_code in errors.items():
174             local_fields = field_mapping[field_name]
175             for field in local_fields:
176                 try:
177                     error_msg = self.fields[field].error_messages[error_code]
178                 except KeyError:
179                     error_msg = pgettext_lazy(
180                         "Address form", "This value is invalid for selected country"
181                     )
182                 self.add_error(field, ValidationError(error_msg, code=error_code))
183 
184     def validate_address(self, data):
185         try:
186             data["country_code"] = data.get("country", "")
187             if data["street_address_1"] or data["street_address_2"]:
188                 data["street_address"] = "%s\n%s" % (
189                     data["street_address_1"],
190                     data["street_address_2"],
191                 )
192             data = i18naddress.normalize_address(data)
193             del data["sorting_code"]
194         except i18naddress.InvalidAddress as exc:
195             self.add_field_errors(exc.errors)
196         return data
197 
198     def clean(self):
199         data = super().clean()
200         return self.validate_address(data)
201 
202 
203 def get_address_form_class(country_code):
204     return COUNTRY_FORMS[country_code]
205 
206 
207 def get_form_i18n_lines(form_instance):
208     country_code = form_instance.i18n_country_code
209     try:
210         fields_order = i18naddress.get_field_order({"country_code": country_code})
211     except ValueError:
212         fields_order = i18naddress.get_field_order({})
213     field_mapping = dict(form_instance.I18N_MAPPING)
214 
215     def _convert_to_bound_fields(form, i18n_field_names):
216         bound_fields = []
217         for field_name in i18n_field_names:
218             local_fields = field_mapping[field_name]
219             for local_name in local_fields:
220                 local_field = form_instance.fields[local_name]
221                 bound_field = BoundField(form, local_field, local_name)
222                 bound_fields.append(bound_field)
223         return bound_fields
224 
225     if fields_order:
226         return [_convert_to_bound_fields(form_instance, line) for line in fields_order]
227 
228 
229 def update_base_fields(form_class, i18n_rules):
230     for field_name, label_value in AddressForm.Meta.labels.items():
231         field = form_class.base_fields[field_name]
232         field.label = label_value
233 
234     for field_name, placeholder_value in AddressForm.Meta.placeholders.items():
235         field = form_class.base_fields[field_name]
236         field.placeholder = placeholder_value
237 
238     if i18n_rules.country_area_choices:
239         form_class.base_fields["country_area"] = CountryAreaChoiceField(
240             choices=i18n_rules.country_area_choices
241         )
242 
243     labels_map = {
244         "country_area": i18n_rules.country_area_type,
245         "postal_code": i18n_rules.postal_code_type,
246         "city_area": i18n_rules.city_area_type,
247     }
248 
249     for field_name, area_type in labels_map.items():
250         field = form_class.base_fields[field_name]
251         field.label = AREA_TYPE_TRANSLATIONS[area_type]
252 
253     hidden_fields = i18naddress.KNOWN_FIELDS - i18n_rules.allowed_fields
254     for field_name in hidden_fields:
255         if field_name in form_class.base_fields:
256             form_class.base_fields[field_name].widget = forms.HiddenInput()
257 
258     country_field = form_class.base_fields["country"]
259     country_field.choices = COUNTRY_CHOICES
260 
261 
262 def construct_address_form(country_code, i18n_rules):
263     class_name = "AddressForm%s" % country_code
264     base_class = CountryAwareAddressForm
265     form_kwargs = {
266         "Meta": type(str("Meta"), (base_class.Meta, object), {}),
267         "formfield_callback": None,
268     }
269     class_ = type(base_class)(str(class_name), (base_class,), form_kwargs)
270     update_base_fields(class_, i18n_rules)
271     class_.i18n_country_code = country_code
272     class_.i18n_fields_order = property(get_form_i18n_lines)
273     return class_
274 
275 
276 for country in countries.countries.keys():
277     try:
278         country_rules = i18naddress.get_validation_rules({"country_code": country})
279     except ValueError:
280         country_rules = i18naddress.get_validation_rules({})
281         UNKNOWN_COUNTRIES.add(country)
282 
283 COUNTRY_CHOICES = [
284     (code, label)
285     for code, label in countries.countries.items()
286     if code not in UNKNOWN_COUNTRIES
287 ]
288 # Sort choices list by country name
289 COUNTRY_CHOICES = sorted(COUNTRY_CHOICES, key=lambda choice: choice[1])
290 
291 for country, label in COUNTRY_CHOICES:
292     country_rules = i18naddress.get_validation_rules({"country_code": country})
293     COUNTRY_FORMS[country] = construct_address_form(country, country_rules)
294
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/saleor/account/i18n.py b/saleor/account/i18n.py
--- a/saleor/account/i18n.py
+++ b/saleor/account/i18n.py
@@ -236,8 +236,9 @@
         field.placeholder = placeholder_value
 
     if i18n_rules.country_area_choices:
+        required = "country_area" in i18n_rules.required_fields
         form_class.base_fields["country_area"] = CountryAreaChoiceField(
-            choices=i18n_rules.country_area_choices
+            choices=i18n_rules.country_area_choices, required=required
         )
 
     labels_map = {

{"golden_diff": "diff --git a/saleor/account/i18n.py b/saleor/account/i18n.py\n--- a/saleor/account/i18n.py\n+++ b/saleor/account/i18n.py\n@@ -236,8 +236,9 @@\n         field.placeholder = placeholder_value\n \n     if i18n_rules.country_area_choices:\n+        required = \"country_area\" in i18n_rules.required_fields\n         form_class.base_fields[\"country_area\"] = CountryAreaChoiceField(\n-            choices=i18n_rules.country_area_choices\n+            choices=i18n_rules.country_area_choices, required=required\n         )\n \n     labels_map = {\n", "issue": "Wrong AddressForm for Ireland\n### What I'm trying to achieve\r\nI tried to use address form validation for Ireland. Unfortunately, our API returns for that country that `country_area` is not required, but `AddressFormIE` requires it. \r\n\r\n### Steps to reproduce the problem\r\n1. Send `CheckoutShippingAddressUpdate` without `country_area` - API returns validation error.\r\n\r\nAnother way to expect that problem is adding `IE` to the `test_address_form_for_country` test function - it fails.\r\n\r\n### What I expected to happen\r\nAPI and form validation should be consistent - if `i18naddress` says that field is not required, it is not required.\r\n\r\n### Screenshots\r\n<!-- If applicable, add screenshots to help explain your problem. -->\r\nn/a\r\n\r\n**System information**\r\nOperating system: n/a\r\nBrowser: n/a\r\n\n", "before_files": [{"content": "from collections import defaultdict\n\nimport i18naddress\nfrom django import forms\nfrom django.core.exceptions import ValidationError\nfrom django.forms.forms import BoundField\nfrom django.utils.translation import pgettext_lazy\nfrom django_countries import countries\n\nfrom .models import Address\nfrom .validators import validate_possible_number\nfrom .widgets import DatalistTextWidget, PhonePrefixWidget\n\nCOUNTRY_FORMS = {}\nUNKNOWN_COUNTRIES = set()\n\nAREA_TYPE_TRANSLATIONS = {\n    \"area\": pgettext_lazy(\"Address field\", \"Area\"),\n    \"county\": pgettext_lazy(\"Address field\", \"County\"),\n    \"department\": pgettext_lazy(\"Address field\", \"Department\"),\n    \"district\": pgettext_lazy(\"Address field\", \"District\"),\n    \"do_si\": pgettext_lazy(\"Address field\", \"Do/si\"),\n    \"eircode\": pgettext_lazy(\"Address field\", \"Eircode\"),\n    \"emirate\": pgettext_lazy(\"Address field\", \"Emirate\"),\n    \"island\": pgettext_lazy(\"Address field\", \"Island\"),\n    \"neighborhood\": pgettext_lazy(\"Address field\", \"Neighborhood\"),\n    \"oblast\": pgettext_lazy(\"Address field\", \"Oblast\"),\n    \"parish\": pgettext_lazy(\"Address field\", \"Parish\"),\n    \"pin\": pgettext_lazy(\"Address field\", \"PIN\"),\n    \"postal\": pgettext_lazy(\"Address field\", \"Postal code\"),\n    \"prefecture\": pgettext_lazy(\"Address field\", \"Prefecture\"),\n    \"province\": pgettext_lazy(\"Address field\", \"Province\"),\n    \"state\": pgettext_lazy(\"Address field\", \"State\"),\n    \"suburb\": pgettext_lazy(\"Address field\", \"Suburb\"),\n    \"townland\": pgettext_lazy(\"Address field\", \"Townland\"),\n    \"village_township\": pgettext_lazy(\"Address field\", \"Village/township\"),\n    \"zip\": pgettext_lazy(\"Address field\", \"ZIP code\"),\n}\n\n\nclass PossiblePhoneNumberFormField(forms.CharField):\n    \"\"\"A phone input field.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.widget.input_type = \"tel\"\n\n\nclass CountryAreaChoiceField(forms.ChoiceField):\n    widget = DatalistTextWidget\n\n    def valid_value(self, value):\n        return True\n\n\nclass AddressMetaForm(forms.ModelForm):\n    # This field is never visible in UI\n    preview = forms.BooleanField(initial=False, required=False)\n\n    class Meta:\n        model = Address\n        fields = [\"country\", \"preview\"]\n        labels = {\"country\": pgettext_lazy(\"Country\", \"Country\")}\n\n    def clean(self):\n        data = super().clean()\n        if data.get(\"preview\"):\n            self.data = self.data.copy()\n            self.data[\"preview\"] = False\n        return data\n\n\nclass AddressForm(forms.ModelForm):\n\n    AUTOCOMPLETE_MAPPING = [\n        (\"first_name\", \"given-name\"),\n        (\"last_name\", \"family-name\"),\n        (\"company_name\", \"organization\"),\n        (\"street_address_1\", \"address-line1\"),\n        (\"street_address_2\", \"address-line2\"),\n        (\"city\", \"address-level2\"),\n        (\"postal_code\", \"postal-code\"),\n        (\"country_area\", \"address-level1\"),\n        (\"country\", \"country\"),\n        (\"city_area\", \"address-level3\"),\n        (\"phone\", \"tel\"),\n        (\"email\", \"email\"),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n        labels = {\n            \"first_name\": pgettext_lazy(\"Personal name\", \"Given name\"),\n            \"last_name\": pgettext_lazy(\"Personal name\", \"Family name\"),\n            \"company_name\": pgettext_lazy(\n                \"Company or organization\", \"Company or organization\"\n            ),\n            \"street_address_1\": pgettext_lazy(\"Address\", \"Address\"),\n            \"street_address_2\": \"\",\n            \"city\": pgettext_lazy(\"City\", \"City\"),\n            \"city_area\": pgettext_lazy(\"City area\", \"District\"),\n            \"postal_code\": pgettext_lazy(\"Postal code\", \"Postal code\"),\n            \"country\": pgettext_lazy(\"Country\", \"Country\"),\n            \"country_area\": pgettext_lazy(\"Country area\", \"State or province\"),\n            \"phone\": pgettext_lazy(\"Phone number\", \"Phone number\"),\n        }\n        placeholders = {\n            \"street_address_1\": pgettext_lazy(\n                \"Address\", \"Street address, P.O. box, company name\"\n            ),\n            \"street_address_2\": pgettext_lazy(\n                \"Address\", \"Apartment, suite, unit, building, floor, etc\"\n            ),\n        }\n\n    phone = PossiblePhoneNumberFormField(widget=PhonePrefixWidget, required=False)\n\n    def __init__(self, *args, **kwargs):\n        autocomplete_type = kwargs.pop(\"autocomplete_type\", None)\n        super().__init__(*args, **kwargs)\n        # countries order was taken as defined in the model,\n        # not being sorted accordingly to the selected language\n        self.fields[\"country\"].choices = sorted(\n            COUNTRY_CHOICES, key=lambda choice: choice[1]\n        )\n        autocomplete_dict = defaultdict(lambda: \"off\", self.AUTOCOMPLETE_MAPPING)\n        for field_name, field in self.fields.items():\n            if autocomplete_type:\n                autocomplete = \"%s %s\" % (\n                    autocomplete_type,\n                    autocomplete_dict[field_name],\n                )\n            else:\n                autocomplete = autocomplete_dict[field_name]\n            field.widget.attrs[\"autocomplete\"] = autocomplete\n            field.widget.attrs[\"placeholder\"] = (\n                field.label if not hasattr(field, \"placeholder\") else field.placeholder\n            )\n\n    def clean(self):\n        data = super().clean()\n        phone = data.get(\"phone\")\n        country = data.get(\"country\")\n        if phone:\n            try:\n                data[\"phone\"] = validate_possible_number(phone, country)\n            except forms.ValidationError as error:\n                self.add_error(\"phone\", error)\n        return data\n\n\nclass CountryAwareAddressForm(AddressForm):\n\n    I18N_MAPPING = [\n        (\"name\", [\"first_name\", \"last_name\"]),\n        (\"street_address\", [\"street_address_1\", \"street_address_2\"]),\n        (\"city_area\", [\"city_area\"]),\n        (\"country_area\", [\"country_area\"]),\n        (\"company_name\", [\"company_name\"]),\n        (\"postal_code\", [\"postal_code\"]),\n        (\"city\", [\"city\"]),\n        (\"sorting_code\", []),\n        (\"country_code\", [\"country\"]),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n\n    def add_field_errors(self, errors):\n        field_mapping = dict(self.I18N_MAPPING)\n        for field_name, error_code in errors.items():\n            local_fields = field_mapping[field_name]\n            for field in local_fields:\n                try:\n                    error_msg = self.fields[field].error_messages[error_code]\n                except KeyError:\n                    error_msg = pgettext_lazy(\n                        \"Address form\", \"This value is invalid for selected country\"\n                    )\n                self.add_error(field, ValidationError(error_msg, code=error_code))\n\n    def validate_address(self, data):\n        try:\n            data[\"country_code\"] = data.get(\"country\", \"\")\n            if data[\"street_address_1\"] or data[\"street_address_2\"]:\n                data[\"street_address\"] = \"%s\\n%s\" % (\n                    data[\"street_address_1\"],\n                    data[\"street_address_2\"],\n                )\n            data = i18naddress.normalize_address(data)\n            del data[\"sorting_code\"]\n        except i18naddress.InvalidAddress as exc:\n            self.add_field_errors(exc.errors)\n        return data\n\n    def clean(self):\n        data = super().clean()\n        return self.validate_address(data)\n\n\ndef get_address_form_class(country_code):\n    return COUNTRY_FORMS[country_code]\n\n\ndef get_form_i18n_lines(form_instance):\n    country_code = form_instance.i18n_country_code\n    try:\n        fields_order = i18naddress.get_field_order({\"country_code\": country_code})\n    except ValueError:\n        fields_order = i18naddress.get_field_order({})\n    field_mapping = dict(form_instance.I18N_MAPPING)\n\n    def _convert_to_bound_fields(form, i18n_field_names):\n        bound_fields = []\n        for field_name in i18n_field_names:\n            local_fields = field_mapping[field_name]\n            for local_name in local_fields:\n                local_field = form_instance.fields[local_name]\n                bound_field = BoundField(form, local_field, local_name)\n                bound_fields.append(bound_field)\n        return bound_fields\n\n    if fields_order:\n        return [_convert_to_bound_fields(form_instance, line) for line in fields_order]\n\n\ndef update_base_fields(form_class, i18n_rules):\n    for field_name, label_value in AddressForm.Meta.labels.items():\n        field = form_class.base_fields[field_name]\n        field.label = label_value\n\n    for field_name, placeholder_value in AddressForm.Meta.placeholders.items():\n        field = form_class.base_fields[field_name]\n        field.placeholder = placeholder_value\n\n    if i18n_rules.country_area_choices:\n        form_class.base_fields[\"country_area\"] = CountryAreaChoiceField(\n            choices=i18n_rules.country_area_choices\n        )\n\n    labels_map = {\n        \"country_area\": i18n_rules.country_area_type,\n        \"postal_code\": i18n_rules.postal_code_type,\n        \"city_area\": i18n_rules.city_area_type,\n    }\n\n    for field_name, area_type in labels_map.items():\n        field = form_class.base_fields[field_name]\n        field.label = AREA_TYPE_TRANSLATIONS[area_type]\n\n    hidden_fields = i18naddress.KNOWN_FIELDS - i18n_rules.allowed_fields\n    for field_name in hidden_fields:\n        if field_name in form_class.base_fields:\n            form_class.base_fields[field_name].widget = forms.HiddenInput()\n\n    country_field = form_class.base_fields[\"country\"]\n    country_field.choices = COUNTRY_CHOICES\n\n\ndef construct_address_form(country_code, i18n_rules):\n    class_name = \"AddressForm%s\" % country_code\n    base_class = CountryAwareAddressForm\n    form_kwargs = {\n        \"Meta\": type(str(\"Meta\"), (base_class.Meta, object), {}),\n        \"formfield_callback\": None,\n    }\n    class_ = type(base_class)(str(class_name), (base_class,), form_kwargs)\n    update_base_fields(class_, i18n_rules)\n    class_.i18n_country_code = country_code\n    class_.i18n_fields_order = property(get_form_i18n_lines)\n    return class_\n\n\nfor country in countries.countries.keys():\n    try:\n        country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    except ValueError:\n        country_rules = i18naddress.get_validation_rules({})\n        UNKNOWN_COUNTRIES.add(country)\n\nCOUNTRY_CHOICES = [\n    (code, label)\n    for code, label in countries.countries.items()\n    if code not in UNKNOWN_COUNTRIES\n]\n# Sort choices list by country name\nCOUNTRY_CHOICES = sorted(COUNTRY_CHOICES, key=lambda choice: choice[1])\n\nfor country, label in COUNTRY_CHOICES:\n    country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    COUNTRY_FORMS[country] = construct_address_form(country, country_rules)\n", "path": "saleor/account/i18n.py"}], "after_files": [{"content": "from collections import defaultdict\n\nimport i18naddress\nfrom django import forms\nfrom django.core.exceptions import ValidationError\nfrom django.forms.forms import BoundField\nfrom django.utils.translation import pgettext_lazy\nfrom django_countries import countries\n\nfrom .models import Address\nfrom .validators import validate_possible_number\nfrom .widgets import DatalistTextWidget, PhonePrefixWidget\n\nCOUNTRY_FORMS = {}\nUNKNOWN_COUNTRIES = set()\n\nAREA_TYPE_TRANSLATIONS = {\n    \"area\": pgettext_lazy(\"Address field\", \"Area\"),\n    \"county\": pgettext_lazy(\"Address field\", \"County\"),\n    \"department\": pgettext_lazy(\"Address field\", \"Department\"),\n    \"district\": pgettext_lazy(\"Address field\", \"District\"),\n    \"do_si\": pgettext_lazy(\"Address field\", \"Do/si\"),\n    \"eircode\": pgettext_lazy(\"Address field\", \"Eircode\"),\n    \"emirate\": pgettext_lazy(\"Address field\", \"Emirate\"),\n    \"island\": pgettext_lazy(\"Address field\", \"Island\"),\n    \"neighborhood\": pgettext_lazy(\"Address field\", \"Neighborhood\"),\n    \"oblast\": pgettext_lazy(\"Address field\", \"Oblast\"),\n    \"parish\": pgettext_lazy(\"Address field\", \"Parish\"),\n    \"pin\": pgettext_lazy(\"Address field\", \"PIN\"),\n    \"postal\": pgettext_lazy(\"Address field\", \"Postal code\"),\n    \"prefecture\": pgettext_lazy(\"Address field\", \"Prefecture\"),\n    \"province\": pgettext_lazy(\"Address field\", \"Province\"),\n    \"state\": pgettext_lazy(\"Address field\", \"State\"),\n    \"suburb\": pgettext_lazy(\"Address field\", \"Suburb\"),\n    \"townland\": pgettext_lazy(\"Address field\", \"Townland\"),\n    \"village_township\": pgettext_lazy(\"Address field\", \"Village/township\"),\n    \"zip\": pgettext_lazy(\"Address field\", \"ZIP code\"),\n}\n\n\nclass PossiblePhoneNumberFormField(forms.CharField):\n    \"\"\"A phone input field.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.widget.input_type = \"tel\"\n\n\nclass CountryAreaChoiceField(forms.ChoiceField):\n    widget = DatalistTextWidget\n\n    def valid_value(self, value):\n        return True\n\n\nclass AddressMetaForm(forms.ModelForm):\n    # This field is never visible in UI\n    preview = forms.BooleanField(initial=False, required=False)\n\n    class Meta:\n        model = Address\n        fields = [\"country\", \"preview\"]\n        labels = {\"country\": pgettext_lazy(\"Country\", \"Country\")}\n\n    def clean(self):\n        data = super().clean()\n        if data.get(\"preview\"):\n            self.data = self.data.copy()\n            self.data[\"preview\"] = False\n        return data\n\n\nclass AddressForm(forms.ModelForm):\n\n    AUTOCOMPLETE_MAPPING = [\n        (\"first_name\", \"given-name\"),\n        (\"last_name\", \"family-name\"),\n        (\"company_name\", \"organization\"),\n        (\"street_address_1\", \"address-line1\"),\n        (\"street_address_2\", \"address-line2\"),\n        (\"city\", \"address-level2\"),\n        (\"postal_code\", \"postal-code\"),\n        (\"country_area\", \"address-level1\"),\n        (\"country\", \"country\"),\n        (\"city_area\", \"address-level3\"),\n        (\"phone\", \"tel\"),\n        (\"email\", \"email\"),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n        labels = {\n            \"first_name\": pgettext_lazy(\"Personal name\", \"Given name\"),\n            \"last_name\": pgettext_lazy(\"Personal name\", \"Family name\"),\n            \"company_name\": pgettext_lazy(\n                \"Company or organization\", \"Company or organization\"\n            ),\n            \"street_address_1\": pgettext_lazy(\"Address\", \"Address\"),\n            \"street_address_2\": \"\",\n            \"city\": pgettext_lazy(\"City\", \"City\"),\n            \"city_area\": pgettext_lazy(\"City area\", \"District\"),\n            \"postal_code\": pgettext_lazy(\"Postal code\", \"Postal code\"),\n            \"country\": pgettext_lazy(\"Country\", \"Country\"),\n            \"country_area\": pgettext_lazy(\"Country area\", \"State or province\"),\n            \"phone\": pgettext_lazy(\"Phone number\", \"Phone number\"),\n        }\n        placeholders = {\n            \"street_address_1\": pgettext_lazy(\n                \"Address\", \"Street address, P.O. box, company name\"\n            ),\n            \"street_address_2\": pgettext_lazy(\n                \"Address\", \"Apartment, suite, unit, building, floor, etc\"\n            ),\n        }\n\n    phone = PossiblePhoneNumberFormField(widget=PhonePrefixWidget, required=False)\n\n    def __init__(self, *args, **kwargs):\n        autocomplete_type = kwargs.pop(\"autocomplete_type\", None)\n        super().__init__(*args, **kwargs)\n        # countries order was taken as defined in the model,\n        # not being sorted accordingly to the selected language\n        self.fields[\"country\"].choices = sorted(\n            COUNTRY_CHOICES, key=lambda choice: choice[1]\n        )\n        autocomplete_dict = defaultdict(lambda: \"off\", self.AUTOCOMPLETE_MAPPING)\n        for field_name, field in self.fields.items():\n            if autocomplete_type:\n                autocomplete = \"%s %s\" % (\n                    autocomplete_type,\n                    autocomplete_dict[field_name],\n                )\n            else:\n                autocomplete = autocomplete_dict[field_name]\n            field.widget.attrs[\"autocomplete\"] = autocomplete\n            field.widget.attrs[\"placeholder\"] = (\n                field.label if not hasattr(field, \"placeholder\") else field.placeholder\n            )\n\n    def clean(self):\n        data = super().clean()\n        phone = data.get(\"phone\")\n        country = data.get(\"country\")\n        if phone:\n            try:\n                data[\"phone\"] = validate_possible_number(phone, country)\n            except forms.ValidationError as error:\n                self.add_error(\"phone\", error)\n        return data\n\n\nclass CountryAwareAddressForm(AddressForm):\n\n    I18N_MAPPING = [\n        (\"name\", [\"first_name\", \"last_name\"]),\n        (\"street_address\", [\"street_address_1\", \"street_address_2\"]),\n        (\"city_area\", [\"city_area\"]),\n        (\"country_area\", [\"country_area\"]),\n        (\"company_name\", [\"company_name\"]),\n        (\"postal_code\", [\"postal_code\"]),\n        (\"city\", [\"city\"]),\n        (\"sorting_code\", []),\n        (\"country_code\", [\"country\"]),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n\n    def add_field_errors(self, errors):\n        field_mapping = dict(self.I18N_MAPPING)\n        for field_name, error_code in errors.items():\n            local_fields = field_mapping[field_name]\n            for field in local_fields:\n                try:\n                    error_msg = self.fields[field].error_messages[error_code]\n                except KeyError:\n                    error_msg = pgettext_lazy(\n                        \"Address form\", \"This value is invalid for selected country\"\n                    )\n                self.add_error(field, ValidationError(error_msg, code=error_code))\n\n    def validate_address(self, data):\n        try:\n            data[\"country_code\"] = data.get(\"country\", \"\")\n            if data[\"street_address_1\"] or data[\"street_address_2\"]:\n                data[\"street_address\"] = \"%s\\n%s\" % (\n                    data[\"street_address_1\"],\n                    data[\"street_address_2\"],\n                )\n            data = i18naddress.normalize_address(data)\n            del data[\"sorting_code\"]\n        except i18naddress.InvalidAddress as exc:\n            self.add_field_errors(exc.errors)\n        return data\n\n    def clean(self):\n        data = super().clean()\n        return self.validate_address(data)\n\n\ndef get_address_form_class(country_code):\n    return COUNTRY_FORMS[country_code]\n\n\ndef get_form_i18n_lines(form_instance):\n    country_code = form_instance.i18n_country_code\n    try:\n        fields_order = i18naddress.get_field_order({\"country_code\": country_code})\n    except ValueError:\n        fields_order = i18naddress.get_field_order({})\n    field_mapping = dict(form_instance.I18N_MAPPING)\n\n    def _convert_to_bound_fields(form, i18n_field_names):\n        bound_fields = []\n        for field_name in i18n_field_names:\n            local_fields = field_mapping[field_name]\n            for local_name in local_fields:\n                local_field = form_instance.fields[local_name]\n                bound_field = BoundField(form, local_field, local_name)\n                bound_fields.append(bound_field)\n        return bound_fields\n\n    if fields_order:\n        return [_convert_to_bound_fields(form_instance, line) for line in fields_order]\n\n\ndef update_base_fields(form_class, i18n_rules):\n    for field_name, label_value in AddressForm.Meta.labels.items():\n        field = form_class.base_fields[field_name]\n        field.label = label_value\n\n    for field_name, placeholder_value in AddressForm.Meta.placeholders.items():\n        field = form_class.base_fields[field_name]\n        field.placeholder = placeholder_value\n\n    if i18n_rules.country_area_choices:\n        required = \"country_area\" in i18n_rules.required_fields\n        form_class.base_fields[\"country_area\"] = CountryAreaChoiceField(\n            choices=i18n_rules.country_area_choices, required=required\n        )\n\n    labels_map = {\n        \"country_area\": i18n_rules.country_area_type,\n        \"postal_code\": i18n_rules.postal_code_type,\n        \"city_area\": i18n_rules.city_area_type,\n    }\n\n    for field_name, area_type in labels_map.items():\n        field = form_class.base_fields[field_name]\n        field.label = AREA_TYPE_TRANSLATIONS[area_type]\n\n    hidden_fields = i18naddress.KNOWN_FIELDS - i18n_rules.allowed_fields\n    for field_name in hidden_fields:\n        if field_name in form_class.base_fields:\n            form_class.base_fields[field_name].widget = forms.HiddenInput()\n\n    country_field = form_class.base_fields[\"country\"]\n    country_field.choices = COUNTRY_CHOICES\n\n\ndef construct_address_form(country_code, i18n_rules):\n    class_name = \"AddressForm%s\" % country_code\n    base_class = CountryAwareAddressForm\n    form_kwargs = {\n        \"Meta\": type(str(\"Meta\"), (base_class.Meta, object), {}),\n        \"formfield_callback\": None,\n    }\n    class_ = type(base_class)(str(class_name), (base_class,), form_kwargs)\n    update_base_fields(class_, i18n_rules)\n    class_.i18n_country_code = country_code\n    class_.i18n_fields_order = property(get_form_i18n_lines)\n    return class_\n\n\nfor country in countries.countries.keys():\n    try:\n        country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    except ValueError:\n        country_rules = i18naddress.get_validation_rules({})\n        UNKNOWN_COUNTRIES.add(country)\n\nCOUNTRY_CHOICES = [\n    (code, label)\n    for code, label in countries.countries.items()\n    if code not in UNKNOWN_COUNTRIES\n]\n# Sort choices list by country name\nCOUNTRY_CHOICES = sorted(COUNTRY_CHOICES, key=lambda choice: choice[1])\n\nfor country, label in COUNTRY_CHOICES:\n    country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    COUNTRY_FORMS[country] = construct_address_form(country, country_rules)\n", "path": "saleor/account/i18n.py"}]}