Skip to content

Commit

Permalink
Fix #1001 -- Add relationships to party detail page
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverroick authored and amplifi committed Mar 4, 2017
1 parent fff14c6 commit 4485b2f
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 31 deletions.
70 changes: 66 additions & 4 deletions cadasta/party/tests/test_views_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from resources.tests.utils import clear_temp # noqa
from skivvy import ViewTestCase
from spatial.models import SpatialUnit
from spatial.tests.factories import SpatialUnitFactory
from tutelary.models import Policy, assign_user_policies
from questionnaires.tests import factories as q_factories

Expand Down Expand Up @@ -330,6 +331,54 @@ def test_get_with_with_questionnaire(self):
name='IN',
label={'en': 'Individual', 'de': 'Einzelperson'})

location_type_question = q_factories.QuestionFactory.create(
questionnaire=questionnaire,
name='location_type',
label={'en': 'Location type', 'de': 'Parzelle Typ'},
type='S1')

tenure_type_question = q_factories.QuestionFactory.create(
questionnaire=questionnaire,
name='tenure_type',
label={'en': 'Location type', 'de': 'Parzelle Typ'},
type='S1')
q_factories.QuestionOptionFactory.create(
question=tenure_type_question,
name='LH',
label={'en': 'Leasehold', 'de': 'Miete'})
q_factories.QuestionOptionFactory.create(
question=tenure_type_question,
name='WR',
label={'en': 'Water rights', 'de': 'Wasserecht'})

lh_ten = TenureRelationshipFactory.create(
tenure_type=TenureRelationshipType.objects.get(id='LH'),
party=self.party,
spatial_unit=SpatialUnitFactory(project=self.project, type='PA'),
project=self.project)
q_factories.QuestionOptionFactory.create(
question=location_type_question,
name='PA',
label={'en': 'Parcel', 'de': 'Parzelle'})
lh_ten.type_labels = ('data-label-de="Miete" '
'data-label-en="Leasehold"')
lh_ten.location_labels = ('data-label-de="Parzelle" '
'data-label-en="Parcel"')

wr_ten = TenureRelationshipFactory.create(
tenure_type=TenureRelationshipType.objects.get(id='WR'),
party=self.party,
spatial_unit=SpatialUnitFactory(project=self.project, type='BU'),
project=self.project)
q_factories.QuestionOptionFactory.create(
question=location_type_question,
name='BU',
label={'en': 'Building', 'de': 'Haus'})
wr_ten.type_labels = ('data-label-de="Wasserecht" '
'data-label-en="Water rights"')
wr_ten.location_labels = ('data-label-de="Haus" '
'data-label-en="Building"')

user = UserFactory.create()
assign_policies(user)
response = self.request(user=user)
Expand All @@ -342,7 +391,19 @@ def test_get_with_with_questionnaire(self):
type_choice_labels=('data-label-de="Einzelperson" '
'data-label-en="Individual"'),
form_lang_default='en',
form_langs=[('en', 'English'), ('de', 'German')])
form_langs=[('en', 'English'), ('de', 'German')],
relationships=[wr_ten, lh_ten])

def test_get_with_authorized_user_including_relationships(self):
TenureRelationshipFactory.create_batch(2,
party=self.party,
project=self.project)
user = UserFactory.create()
assign_policies(user)
response = self.request(user=user)
assert response.status_code == 200
assert response.content == self.render_content(
relationships=self.party.tenurerelationship_set.all())

def test_get_from_non_existend_project(self):
user = UserFactory.create()
Expand Down Expand Up @@ -401,7 +462,8 @@ def setup_template_context(self):
return {'object': self.project,
'party': self.party,
'form': forms.PartyForm(instance=self.party,
project=self.project)}
project=self.project),
'attributes': (('Test field', 'test'), )}

def setup_url_kwargs(self):
return {
Expand Down Expand Up @@ -726,7 +788,7 @@ def test_post_with_authorized_user(self):
assign_policies(user)
response = self.request(method='POST', user=user)
assert response.status_code == 302
assert response.location == self.expected_success_url
assert response.location == self.expected_success_url + '#resources'

party_resources = self.party.resources.all()
assert len(party_resources) == 2
Expand Down Expand Up @@ -851,7 +913,7 @@ def test_post_with_authorized_user(self):
assign_policies(user)
response = self.request(method='POST', user=user)
assert response.status_code == 302
assert response.location == self.expected_success_url
assert response.location == self.expected_success_url + '#resources'

assert self.party.resources.count() == 1

Expand Down
24 changes: 24 additions & 0 deletions cadasta/party/views/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class PartiesDetail(LoginPermissionRequiredMixin,

def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['relationships'] = self.object.tenurerelationship_set.all(
).select_related('spatial_unit').defer('spatial_unit__attributes')

project = context['object']
if project.current_questionnaire:
Expand All @@ -90,17 +92,39 @@ def get_context_data(self, *args, **kwargs):
context['type_choice_labels'] = template_xlang_labels(
option.label_xlat)

tenure_type = Question.objects.get(
name='tenure_type',
questionnaire_id=project.current_questionnaire)
tenure_opts = QuestionOption.objects.filter(question=tenure_type)
tenure_opts = dict(tenure_opts.values_list('name', 'label_xlat'))

location_type = Question.objects.get(
name='location_type',
questionnaire_id=project.current_questionnaire)
location_opts = QuestionOption.objects.filter(
question=location_type)
location_opts = dict(
location_opts.values_list('name', 'label_xlat'))

for rel in context['relationships']:
rel.type_labels = template_xlang_labels(
tenure_opts.get(rel.tenure_type_id))
rel.location_labels = template_xlang_labels(
location_opts.get(rel.spatial_unit.type))

return context


class PartiesEdit(LoginPermissionRequiredMixin,
JsonAttrsMixin,
mixins.PartyObjectMixin,
organization_mixins.ProjectAdminCheckMixin,
generic.UpdateView):
template_name = 'party/party_edit.html'
form_class = forms.PartyForm
permission_required = update_permissions('party.update')
permission_denied_message = error_messages.PARTY_UPDATE
attributes_field = 'attributes'

def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
Expand Down
2 changes: 1 addition & 1 deletion cadasta/party/views/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def get_content_object(self):
def get_success_url(self):
kwargs = self.kwargs
kwargs['party'] = self.get_object().id
return reverse('parties:detail', kwargs=kwargs)
return reverse('parties:detail', kwargs=kwargs) + '#resources'

def get_party(self):
if not hasattr(self, 'party_object'):
Expand Down
108 changes: 82 additions & 26 deletions cadasta/templates/party/party_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@ <h2 class="short">{% trans "Party detail" %}</h2>
</div>
</div>
<div class="panel panel-default">
<div class="panel-body">
<!-- Party information -->
<h3>{% trans "Details" %}</h3>
<div class="row">
<div class="col-md-6">
<div class="panel-body detail">

<h2><span>{% trans "Party" %} </span>{{ party.name }}</h2>

<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#overview" aria-controls="overview" role="tab" data-toggle="tab">{% trans "Overview" %}</a></li>
<li role="presentation"><a href="#relationships" aria-controls="relationships" role="tab" data-toggle="tab">{% trans "Relationships" %}</a></li>
<li role="presentation"><a href="#resources" aria-controls="resources" role="tab" data-toggle="tab">{% trans "Resources" %}</a></li>
</ul>

<div class="tab-content">
<!-- Party information -->
<div role="tabpanel" class="tab-pane active" id="overview">
<table class="table table-location">
<tbody>
<tr>
Expand All @@ -42,38 +50,86 @@ <h3>{% trans "Details" %}</h3>
</tbody>
</table>
</div>
</div>
<!-- /party information -->
<!-- Party resources -->
<h3>{% trans "Resources" %}</h3>
{% if resource_list %}
<div class="top-btn pull-right top-add">
{% if has_unattached_resources %}
<a class="btn btn-primary btn-sm" href="{% url 'parties:resource_add' object.organization.slug object.slug party.id %}">
{% else %}
<a class="btn btn-primary btn-sm" href="{% url 'parties:resource_new' object.organization.slug object.slug party.id %}">
{% endif %}
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> {% trans "Attach" %}</a>
<!-- /party information -->

<!-- Party relationships -->
<div role="tabpanel" class="tab-pane" id="relationships">
{% if relationships %}
<table class="table table-hover datatable" data-paging-type="simple">
<thead>
<tr>
<th>{% trans "Relationship" %}</th>
<th>{% trans "Location Type" %}</th>
</tr>
</thead>
<tbody>
{% for rel in relationships %}
{% url 'parties:relationship_detail' object.organization.slug object.slug rel.id as relationship_url %}
<tr class="linked" onclick="window.document.location='{{ relationship_url }}';">
<td><a href="{{ relationship_url }}" {{ rel.type_labels|safe }}>{{ rel.tenure_type_label }}</a></td>
<td><a href="{% url 'locations:detail' object.organization.slug object.slug rel.spatial_unit.id %}" {{ rel.location_labels|safe }}>{{ rel.spatial_unit.get_type_display }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div>
<p>{% trans "This party does not have any relationships and is not connected to any locations." %}</p>
</div>
{% endif %}
</div>
{% include 'resources/table.html' %}
{% else %}
<div>
<p>{% trans "This party does not have any attached resources. To attach a resource, select the button below." %}</p>
<div class="btn-full">
<!-- /party relationships -->

<!-- Party resources -->
<div role="tabpanel" class="tab-pane" id="resources">
{% if resource_list %}
<div class="top-btn pull-right top-add">
{% if has_unattached_resources %}
<a class="btn btn-primary" href="{% url 'parties:resource_add' object.organization.slug object.slug party.id %}">
<a class="btn btn-primary btn-sm" href="{% url 'parties:resource_add' object.organization.slug object.slug party.id %}">
{% else %}
<a class="btn btn-primary" href="{% url 'parties:resource_new' object.organization.slug object.slug party.id %}">
<a class="btn btn-primary btn-sm" href="{% url 'parties:resource_new' object.organization.slug object.slug party.id %}">
{% endif %}
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> {% trans "Attach" %}</a>
</div>
{% include 'resources/table.html' %}
{% else %}
<div>
<p>{% trans "This party does not have any attached resources. To attach a resource, select the button below." %}</p>
<div class="btn-full">
{% if has_unattached_resources %}
<a class="btn btn-primary" href="{% url 'parties:resource_add' object.organization.slug object.slug party.id %}">
{% else %}
<a class="btn btn-primary" href="{% url 'parties:resource_new' object.organization.slug object.slug party.id %}">
{% endif %}
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> {% trans "Attach" %}</a>
</div>
</div>
{% endif %}
</div>
{% endif %}
<!-- /party resources -->
<!-- /party resources -->
</div>
</div>
</div>
</div>
</div>
</div>

{% endblock %}

{% block extra_script %}
{{ block.super }}
<script type="text/javascript">
$(document).ready(function() {
if(location.hash) {
$('a[href=' + location.hash + ']').tab('show');
}
$(document.body).on("click", "a[data-toggle]", function(event) {
location.hash = this.getAttribute("href");
});
});
$(window).on('popstate', function() {
var anchor = location.hash || $("a[data-toggle=tab]").first().attr("href");
$('a[href=' + anchor + ']').tab('show');
});
</script>
{% endblock %}

0 comments on commit 4485b2f

Please sign in to comment.