Skip to content

Commit 4d08738

Browse files
authored
Merge pull request #1402 from uktrade/company-address
Add company address fields
2 parents d2a2de4 + 832dafc commit 4d08738

File tree

7 files changed

+565
-119
lines changed

7 files changed

+565
-119
lines changed

changelog/company/address-fields.db

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
The following fields where added:
2+
3+
``"address_1" varchar(255)``
4+
5+
``"address_2" varchar(255)``
6+
7+
``"address_country_id" uuid``
8+
9+
``"address_county" varchar(255)``
10+
11+
``"address_postcode" varchar(255)``
12+
13+
``"address_town" varchar(255)``
14+
15+
The system will be migrated from using the ``registered_address_*`` and ``trading_address_*`` fields to ``address_*`` (main location for the business) and ``registered_address_*`` (official address) fields instead.
16+
However, you should not use the new address fields yet and migration steps will be communicated in future release notes.

datahub/company/admin/company.py

+14
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,21 @@ class CompanyAdmin(BaseModelAdminMixin, VersionAdmin):
126126
(
127127
'ADDRESS',
128128
{
129+
'description': (
130+
'The address fields are in the process of being migrated. '
131+
'Address is the main location for this business '
132+
'(could be trading, registered or a different address) '
133+
'whilst registered address is the official address '
134+
'(e.g. from companies house).'
135+
),
129136
'fields': (
137+
'address_1',
138+
'address_2',
139+
'address_town',
140+
'address_county',
141+
'address_postcode',
142+
'address_country',
143+
130144
'registered_address_1',
131145
'registered_address_2',
132146
'registered_address_town',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Generated by Django 2.1.5 on 2019-01-21 12:31
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('metadata', '0021_delete_companyclassification'),
11+
('company', '0061_remove_alias_from_database'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='company',
17+
name='address_1',
18+
field=models.CharField(blank=True, max_length=255, null=True),
19+
),
20+
migrations.AddField(
21+
model_name='company',
22+
name='address_2',
23+
field=models.CharField(blank=True, max_length=255, null=True),
24+
),
25+
migrations.AddField(
26+
model_name='company',
27+
name='address_country',
28+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='company_address_country', to='metadata.Country'),
29+
),
30+
migrations.AddField(
31+
model_name='company',
32+
name='address_county',
33+
field=models.CharField(blank=True, max_length=255, null=True),
34+
),
35+
migrations.AddField(
36+
model_name='company',
37+
name='address_postcode',
38+
field=models.CharField(blank=True, max_length=255, null=True),
39+
),
40+
migrations.AddField(
41+
model_name='company',
42+
name='address_town',
43+
field=models.CharField(blank=True, max_length=255, null=True),
44+
),
45+
]

datahub/company/models/company.py

+20
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,25 @@ class Company(ArchivableModel, BaseModel, CompanyAbstract):
168168
metadata_models.UKRegion, blank=True, null=True,
169169
on_delete=models.SET_NULL,
170170
)
171+
172+
# address is the main location for the business, it could be the trading address
173+
# or the registered address or a completely different address
174+
# TODO make address CharFields NOT NULL
175+
address_1 = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
176+
address_2 = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
177+
address_town = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
178+
address_county = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
179+
address_country = models.ForeignKey(
180+
metadata_models.Country,
181+
blank=True,
182+
null=True,
183+
on_delete=models.PROTECT,
184+
related_name='company_address_country',
185+
)
186+
address_postcode = models.CharField(max_length=MAX_LENGTH, blank=True, null=True, default='')
187+
188+
# will eventually become obsolete when the migration to solely address and registered
189+
# address is completed
171190
trading_address_1 = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
172191
trading_address_2 = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
173192
trading_address_town = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
@@ -180,6 +199,7 @@ class Company(ArchivableModel, BaseModel, CompanyAbstract):
180199
related_name='company_trading_address_country',
181200
)
182201
trading_address_postcode = models.CharField(max_length=MAX_LENGTH, blank=True, null=True)
202+
183203
headquarter_type = models.ForeignKey(
184204
metadata_models.HeadquarterType, blank=True, null=True,
185205
on_delete=models.SET_NULL,

datahub/company/serializers.py

+59
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,26 @@ class CompanySerializer(PermittedFieldsModelSerializer):
275275
have to enter company numbers for UK establishments manually.
276276
"""
277277

278+
# TODO: delete after the migration to address and registered address is completed
279+
ADDRESS_FIELDS_MAPPING = {
280+
'trading': {
281+
'address_1': 'trading_address_1',
282+
'address_2': 'trading_address_2',
283+
'address_town': 'trading_address_town',
284+
'address_county': 'trading_address_county',
285+
'address_postcode': 'trading_address_postcode',
286+
'address_country': 'trading_address_country',
287+
},
288+
'registered': {
289+
'address_1': 'registered_address_1',
290+
'address_2': 'registered_address_2',
291+
'address_town': 'registered_address_town',
292+
'address_county': 'registered_address_county',
293+
'address_postcode': 'registered_address_postcode',
294+
'address_country': 'registered_address_country',
295+
},
296+
}
297+
278298
default_error_messages = {
279299
'invalid_uk_establishment_number_prefix': ugettext_lazy(
280300
'This must be a valid UK establishment number, beginning with BR.',
@@ -382,8 +402,47 @@ def validate(self, data):
382402
'headquarter_type': message,
383403
})
384404

405+
self._populate_address_fields(combiner, data)
406+
385407
return data
386408

409+
def _populate_address_fields(self, combiner, data):
410+
"""
411+
Populates the address_* fields with the values from trading address or
412+
registered address whichever is defined.
413+
414+
It's only triggered when any of the address fields are specified so that we don't
415+
accidentally run this logic when changing any other field.
416+
Doing this will allow us to implement a variant that updates the addresses
417+
in a different way.
418+
419+
TODO: delete after the migration to address and registered address is completed
420+
"""
421+
all_address_field_names = {
422+
field
423+
for mapping in self.ADDRESS_FIELDS_MAPPING.values()
424+
for field in mapping.values()
425+
}
426+
427+
# was any address field specified?
428+
if not all_address_field_names & data.keys():
429+
return
430+
431+
trading_fields_mapping = Company.TRADING_ADDRESS_VALIDATION_MAPPING
432+
433+
has_valid_trading_address = all(
434+
combiner.get_value(field_name)
435+
for field_name, rules in trading_fields_mapping.items()
436+
if rules['required']
437+
)
438+
439+
mapping_source = 'trading' if has_valid_trading_address else 'registered'
440+
441+
mapping = self.ADDRESS_FIELDS_MAPPING[mapping_source]
442+
for target_field_name, source_field_name in mapping.items():
443+
target_value = combiner.get_value(source_field_name)
444+
data[target_field_name] = target_value
445+
387446
def validate_headquarter_type(self, headquarter_type):
388447
"""Raises an exception if company is a global hq and has subsidiaries."""
389448
if self.instance is None:

datahub/company/test/factories.py

+10
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,22 @@ class CompanyFactory(factory.django.DjangoModelFactory):
4141
factory.Faker('company'),
4242
factory.Faker('company'),
4343
])
44+
4445
registered_address_1 = factory.Sequence(lambda n: f'{n} Foo st.')
4546
registered_address_town = 'London'
47+
registered_address_postcode = factory.Faker('postcode')
4648
registered_address_country_id = constants.Country.united_kingdom.value.id
49+
4750
trading_address_1 = factory.Sequence(lambda x: f'{x} Fake Lane')
4851
trading_address_town = 'Woodside'
52+
trading_address_postcode = factory.Faker('postcode')
4953
trading_address_country_id = constants.Country.united_kingdom.value.id
54+
55+
address_1 = factory.SelfAttribute('.trading_address_1')
56+
address_town = factory.SelfAttribute('.trading_address_town')
57+
address_postcode = factory.SelfAttribute('.trading_address_postcode')
58+
address_country_id = factory.SelfAttribute('.trading_address_country_id')
59+
5060
business_type_id = BusinessTypeConstant.private_limited_company.value.id
5161
sector_id = constants.Sector.aerospace_assembly_aircraft.value.id
5262
archived = False

0 commit comments

Comments
 (0)