Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/2.14.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
jwalgran committed Oct 11, 2019
2 parents c1e98d5 + 6168d11 commit 34c716b
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 9 deletions.
13 changes: 8 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Security

## [2.14.0] - 2019-10-11
### Added
- Add facility list items uploaded report [#865](https://github.com/open-apparel-registry/open-apparel-registry/pull/865)
- Implement Source model [#856](https://github.com/open-apparel-registry/open-apparel-registry/pull/856)

## [2.13.0] - 2019-10-07
### Added
- Add facility history API endpoint [#830](https://github.com/open-apparel-registry/open-apparel-registry/pull/830)
Expand All @@ -27,13 +32,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Include facility claim data in facility history list [#852](https://github.com/open-apparel-registry/open-apparel-registry/pull/852)
- Enable Waffle switches when running resetdb [#859](https://github.com/open-apparel-registry/open-apparel-registry/pull/859)

### Deprecated

### Removed

### Fixed
- Check geocoded_point is not None when serializing other locations [#861](https://github.com/open-apparel-registry/open-apparel-registry/pull/861)
- Remove duplicate entries from other locations data [#860](https://github.com/open-apparel-registry/open-apparel-registry/pull/860)
- Fix facility history entry order [#862](https://github.com/open-apparel-registry/open-apparel-registry/pull/862)

### Security

Expand Down Expand Up @@ -272,7 +274,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Initial release.

[Unreleased]: https://github.com/open-apparel-registry/open-apparel-registry/compare/2.13.0...HEAD
[Unreleased]: https://github.com/open-apparel-registry/open-apparel-registry/compare/2.14.0...HEAD
[2.14.0]: https://github.com/open-apparel-registry/open-apparel-registry/releases/tag/2.14.0
[2.13.0]: https://github.com/open-apparel-registry/open-apparel-registry/releases/tag/2.13.0
[2.12.0]: https://github.com/open-apparel-registry/open-apparel-registry/releases/tag/2.12.0
[2.11.0]: https://github.com/open-apparel-registry/open-apparel-registry/releases/tag/2.11.0
Expand Down
8 changes: 4 additions & 4 deletions src/django/api/facility_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def processing_results_has_split_action_for_oar_id(list_item, facility_id):
def create_facility_claim_entry(claim):
if claim.status == FacilityClaim.REVOKED:
return {
'updated_at': str(claim.updated_at),
'updated_at': str(claim.history_date),
'action': FacilityHistoryActions.CLAIM_REVOKE,
'detail': 'Claim on facility {} by {} was revoked'.format(
claim.facility.id,
Expand All @@ -176,7 +176,7 @@ def create_facility_claim_entry(claim):
if claim.status == FacilityClaim.APPROVED \
and claim.prev_record.status == FacilityClaim.PENDING:
return {
'updated_at': str(claim.updated_at),
'updated_at': str(claim.history_date),
'action': FacilityHistoryActions.CLAIM,
'detail': 'Facility {} was claimed by {}'.format(
claim.facility.id,
Expand Down Expand Up @@ -210,7 +210,7 @@ def create_facility_claim_entry(claim):

if any(public_changes):
return {
'updated_at': str(claim.updated_at),
'updated_at': str(claim.history_date),
'action': FacilityHistoryActions.CLAIM_UPDATE,
'detail': 'Facility {} claim public data was updated'.format(
claim.facility.id,
Expand Down Expand Up @@ -248,7 +248,7 @@ def create_facility_history_list(entries, facility_id):

facility_match_entries = [
{
'updated_at': str(m.updated_at),
'updated_at': str(m.history_date),
'action': FacilityHistoryActions.ASSOCIATE
if m.is_active else FacilityHistoryActions.DISSOCIATE,
'detail': create_associate_match_entry_detail(m, facility_id)
Expand Down
42 changes: 42 additions & 0 deletions src/django/api/management/commands/liststosources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.core.management.base import (BaseCommand)
from django.db import transaction

from api.models import FacilityList, FacilityListItem, Source


@transaction.atomic
def list_to_source(facility_list):
source_qs = Source.objects.filter(
source_type=Source.LIST, facility_list=facility_list)
if source_qs.exists():
source = source_qs.first()
else:
source = Source(source_type=Source.LIST,
facility_list=facility_list)

source.contributor = facility_list.contributor
source.is_public = facility_list.is_public
source.is_active = facility_list.is_active
source.save()

# Override auto_now values by using a queryset update
Source.objects.filter(pk=source.pk).update(
created_at=facility_list.created_at,
updated_at=facility_list.updated_at)

FacilityListItem.objects \
.filter(facility_list=facility_list) \
.update(source=source)


def lists_to_sources():
for facility_list in FacilityList.objects.all():
list_to_source(facility_list)


class Command(BaseCommand):
help = ('Create/update Source records from FacilityList records and '
'connect the Source records to FacilityListItem records.')

def handle(self, *args, **options):
lists_to_sources()
33 changes: 33 additions & 0 deletions src/django/api/migrations/0036_add_source_20190926_2048.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 2.2.3 on 2019-10-01 15:31

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0035_add_facility_history_switch'),
]

operations = [
migrations.CreateModel(
name='Source',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('source_type', models.CharField(choices=[('LIST', 'LIST'), ('SINGLE', 'SINGLE')], help_text='Did the the facility data arrive in a list or a single item', max_length=6)),
('is_active', models.BooleanField(default=True, help_text='True if items from the source should be shown as being associated with the contributor')),
('is_public', models.BooleanField(default=True, help_text='True if the public can see factories from this list are associated with the contributor.')),
('create', models.BooleanField(default=True, help_text='Should a facility or facility match be created from the facility data')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('contributor', models.ForeignKey(help_text='The contributor who submitted the facility data', null=True, on_delete=django.db.models.deletion.SET_NULL, to='api.Contributor')),
('facility_list', models.OneToOneField(help_text='The related list if the type of the source is LIST.', null=True, on_delete=django.db.models.deletion.PROTECT, to='api.FacilityList')),
],
),
migrations.AddField(
model_name='facilitylistitem',
name='source',
field=models.ForeignKey(blank=True, help_text='The source from which this item was created.', null=True, on_delete=django.db.models.deletion.PROTECT, to='api.Source'),
),
]
60 changes: 60 additions & 0 deletions src/django/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,59 @@ def did_register_and_confirm_email(self):
return True


class Source(models.Model):
LIST = 'LIST'
SINGLE = 'SINGLE'

SOURCE_TYPE_CHOICES = (
(LIST, LIST),
(SINGLE, SINGLE),
)

contributor = models.ForeignKey(
'Contributor',
null=True,
on_delete=models.SET_NULL,
help_text='The contributor who submitted the facility data'
)
source_type = models.CharField(
null=False,
max_length=6,
choices=SOURCE_TYPE_CHOICES,
help_text='Did the the facility data arrive in a list or a single item'
)
facility_list = models.OneToOneField(
'FacilityList',
null=True,
on_delete=models.PROTECT,
help_text='The related list if the type of the source is LIST.'
)
is_active = models.BooleanField(
null=False,
default=True,
help_text=('True if items from the source should be shown as being '
'associated with the contributor')
)
is_public = models.BooleanField(
null=False,
default=True,
help_text=('True if the public can see factories from this list '
'are associated with the contributor.')
)
create = models.BooleanField(
null=False,
default=True,
help_text=('Should a facility or facility match be created from the '
'facility data')
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self):
return '{0} ({1})'.format(
self.contributor.name, self.id)


class FacilityList(models.Model):
"""
Metadata for an uploaded list of facilities.
Expand Down Expand Up @@ -320,6 +373,13 @@ class Meta:
'FacilityList',
on_delete=models.CASCADE,
help_text='The list that this line item is a part of.')
source = models.ForeignKey(
'Source',
null=True,
blank=True,
on_delete=models.PROTECT,
help_text='The source from which this item was created.'
)
row_index = models.IntegerField(
null=False,
editable=False,
Expand Down
13 changes: 13 additions & 0 deletions src/django/api/reports/facility_list_items_uploaded.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- Count the number of facility list CSV rows uploaded each month.

SELECT
CAST (date_part('month', i.created_at) AS int) AS month,
CASE WHEN u.email LIKE '%openapparel.org%' THEN 'y' ELSE 'n' END AS is_public_list,
COUNT(*) AS item_count
FROM api_facilitylistitem i
JOIN api_facilitylist l on i.facility_list_id = l.id
JOIN api_contributor c ON l.contributor_id = c.id
JOIN api_user u ON u.id = c.admin_id
WHERE date_part('month', i.created_at) != date_part('month', now())
GROUP BY date_part('month', i.created_at), is_public_list
ORDER BY date_part('month', i.created_at), is_public_list;
28 changes: 28 additions & 0 deletions src/django/api/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4039,6 +4039,34 @@ def test_includes_association_for_automatic_match(self):
2,
)

@override_switch('facility_history', active=True)
def test_associate_appears_after_create_in_history_data(self):
history_response = self.client.get(
self.history_url,
)

self.assertEqual(
history_response.status_code,
200,
)

data = json.loads(history_response.content)

self.assertEqual(
data[0]['action'],
'ASSOCIATE',
)

self.assertEqual(
data[1]['action'],
'CREATE',
)

self.assertEqual(
len(data),
2,
)

@override_switch('facility_history', active=True)
def test_includes_association_for_confirmed_match(self):
self.client.logout()
Expand Down

0 comments on commit 34c716b

Please sign in to comment.