def update_company_from_dnb( dh_company, dnb_company, user=None, fields_to_update=None, update_descriptor='', ): """ Updates `dh_company` with new data from `dnb_company` while setting `modified_by` to the given user (if specified) and creating a revision. If `fields_to_update` is specified, only the fields specified will be synced with DNB. `fields_to_update` should be an iterable of strings representing DNBCompanySerializer field names. If `update_descriptor` is specified, the descriptor will be injected in to the comment for this revision. Raises serializers.ValidationError if data is invalid. """ fields_to_update = fields_to_update or ALL_DNB_UPDATED_SERIALIZER_FIELDS # Set dnb_company data to only include the fields in fields_to_update dnb_company = {field: dnb_company[field] for field in fields_to_update} company_serializer = DNBCompanySerializer( dh_company, data=dnb_company, partial=True, ) try: company_serializer.is_valid(raise_exception=True) except serializers.ValidationError: logger.error( 'Data from D&B did not pass the Data Hub validation checks.', extra={ 'dnb_company': dnb_company, 'errors': company_serializer.errors }, ) raise with reversion.create_revision(): company_kwargs = { 'pending_dnb_investigation': False, 'dnb_modified_on': now(), } if user: company_kwargs['modified_by'] = user reversion.set_user(user) company_serializer.save(**company_kwargs) else: # Call a method to update the fields changed on the serializer only; this prevents # us from modifying modified_on - which should only be set through saves initiated by # a user company_serializer.partial_save(**company_kwargs) update_comment = 'Updated from D&B' if update_descriptor: update_comment = f'{update_comment} [{update_descriptor}]' reversion.set_comment(update_comment)
def test_dnb_company_serializer_partial_save_serializer_not_partial(db): """ Test DNBCompanySerializer.partial_save() method raises an error when the serializer is not partial. """ dh_company = CompanyFactory() serializer = DNBCompanySerializer( dh_company, data={'name': 'foobar'}, ) serializer.is_valid() with pytest.raises(SerializerNotPartial): serializer.partial_save(duns_number='123456789')
def test_dnb_company_serializer_partial_save(db): """ Test DNBCompanySerializer.partial_save() method. """ dh_company = CompanyFactory() original_company = Company.objects.get(id=dh_company.id) serializer = DNBCompanySerializer( dh_company, data={'name': 'foobar'}, partial=True, ) serializer.is_valid() serializer.partial_save(duns_number='123456789') dh_company.refresh_from_db() assert dh_company.name == 'foobar' assert dh_company.duns_number == '123456789' assert dh_company.modified_on == original_company.modified_on
def post(self, request): """ Given a duns_number, get the data for the company from dnb-service and create a record in DataHub. """ duns_serializer = DUNSNumberSerializer(data=request.data) duns_serializer.is_valid(raise_exception=True) duns_number = duns_serializer.validated_data['duns_number'] try: dnb_company = get_company(duns_number) except (DNBServiceConnectionError, DNBServiceError, DNBServiceInvalidResponse) as exc: raise APIUpstreamException(str(exc)) except DNBServiceInvalidRequest as exc: raise APIBadRequestException(str(exc)) company_serializer = DNBCompanySerializer(data=dnb_company, ) try: company_serializer.is_valid(raise_exception=True) except serializers.ValidationError: message = 'Company data from DNB failed DH serializer validation' extra_data = { 'formatted_dnb_company_data': dnb_company, 'dh_company_serializer_errors': company_serializer.errors, } logger.error(message, extra=extra_data) raise datahub_company = company_serializer.save( created_by=request.user, modified_by=request.user, dnb_modified_on=now(), ) statsd.incr(f'dnb.create.company') return Response( company_serializer.to_representation(datahub_company), )