Skip to content

Commit

Permalink
Develop (#58)
Browse files Browse the repository at this point in the history
* changed deprecated name for the number (#37)

#118468621

* update build process (#38)

* update build process

[DO NOT MERGE]

* build updates

* small tweaks

* small tweaks

* get around permissions

* update gitignore

* display spinner when waiting for map location search results (#27)

* display spinner when waiting for map location search results

* simplify loading spinner

* remove unneeded Icon file

* fix government ntervention implementation status

[Finishes #105550212]

* update Android / iOS builds (#41)

* set agreement start end dates based on signed dates and result structure (#34)

* set agreement start end dates based on signed dates and result structure

* move start end date auto population from model to form

* updated error messages

* added agreement form tests

* added start date validation and test

* fix-government-in-simple WIP

[WIP] [DO NOT MERGE]

* migration fixes

* fix-circle-ci-build (#50)

* fix-circle-ci-build

updated library fail

* correct spelling error

* small updates

* Added etools/github contribution best practices guide (#40)

* Added etools/github contribution best practices guide

A document introducing new developers to the eTools project workflow,
and best practices when contributing to the GitHub.

* docs(CONTRIBUTING): change file name

* docs(guide): add commit guidelines section 

Add section on committing message best practices
Add section headers dividing concept from practices

PR (#40)

* small tweaks

* HACT dashboard tweaks to show trips for government interventions

* small tweak

* Listing Trip's Action Points in email notification (#30)

* Fix small issues - BY Ali (#44)

* fix distribution items checkbox readonly

* Fix some issues

Result display name
Approve trip by supervisor
Do not send trip notification to PA if no budget owner

* Fix test sending  email to PA with budget owner

* tweaks

* migration add (#56)

* remove existing migration

* fix migration dependency

* gitingore update (#57)

* small tweaks

* add migration

IN DEV ROLL BACK TRIPS MIGRATIONS TO 16 AND RUN MIGRATIONS AGAIN

* ENJOY PERFORMANCE

Fix performance issue on compound queries

* fix locations latency

* planned cash transfers for non-gov

* planned visits for NGOs

* only show government partners if they have interventions

* fix unicode return

* formatting fix

* small tweaks

* refractor(templates/admin): change test environments to have more obvious headers (#53)

* refractor(templates/admin): change test environments to have more obvious headers

Remove "Testing Environment" top bar.
Change banner in localhost, etools-dev, and etools-staging to be red
and display "Local Testing Environment", "Develop Testing Environment",
and "Staging Testing Environment" on banner respectively.

* refractor(#header): obvious testing header for dashboard

Added change from 097f25c to etools dashboard

* docs(guide): new dev setup guide for linux/ubuntu (#54)
  • Loading branch information
robertavram authored Jul 22, 2016
1 parent fda7eb0 commit cbdf18d
Show file tree
Hide file tree
Showing 26 changed files with 772 additions and 82 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ wheelhouse

# Frontend
.frontend/
.fe/
.tmp
.editorconfig
Icon
Expand Down
103 changes: 103 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# eTools and GitHub Best Practices - Contributing Guide

##Concepts Overview

###GitFlow

[GitFlow](https://datasift.github.io/gitflow/IntroducingGitFlow.html) is a branching model for git designed to allow teams to collaborate and continuously develop new features while keeping finished work separate.

It involves 5 major components within the eTools project:

* Master branch
* Develop branch
* Feature branches
* Staging branch
* Hotfix branches

Feature branches are where the bulk of the work is done such as creating new features. Developers branch off of the develop branch, work on their feature(s) and submit a pull request to merge the feature back into the develop branch when it is complete. This is also where *continuous integration* is used.

Approximately every 2 weeks (every sprint) the project is merged into the staging branch. This is where the new features and fixes are QA tested. As QA finds problems and fixes are made, this branch is frequently merged back into develop so the fixes are not lost as new development continues off of that branch.

Every release, the staging branch is merged into master and tagged with the release version number. The master branch is the released product; only finished and vigorously tested code is put here and made available to consumers.

Hotfix branches are used for emergency fixes for problems found after a major release to master. Hotfixes are branched directly off master; the fix is made and then merged back into master (while also being tagged) and into staging and develop (to make sure developers are working with this fix so it doesn’t pop up again in a new release).

###Continuous Integration

[Continuous integration (CI)](https://www.thoughtworks.com/continuous-integration) is a development practice requiring developers to very frequently integrate code into the develop branch.

Each integration is built and tested by an automated CI server. If there are any issues with the build, the team is notified and solves them before any new commits are made.

The idea is to avoid situations involving lots of independent code developed over a long period of time being integrated together only to find many problems that require lots of backtracking to find and fix. Continuous integration methodology means problems are often identified and solved right away since they involve code which was just recently worked on.

After a pull request has been approved and the project builds successfully, it is automatically deployed to a production environment. This is called *continuous deployment* and it allows the team quickly move towards working software and view the eTools develop stage app in an actual production environment.

##Practices and Rituals

###Commiting

The following guidelines should be followed when writing commit messages to ensure readability when viewing project history. The formatting can be added conventionally in git/GitHub or through the use of a CLI wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `npm run commit` in your terminal after staging your changes in git.

Each commit message consists of a **header**, a **body** and a **footer**.

A typical commit message will look something like this... ![ExampleCommit](http://i.imgur.com/9SwquPt.png)
* `fix(copy): fix handling of typed subarrays` is the **header**. Each header consists of a **type**, a **scope** and a **subject**:
* `fix` is the **type**. The type is picked from a limited set of words that categorize the change. Must be one of the following:
* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
* `(copy)` is the **scope**, an optional field that specifies where in the application the change was made.
* `fix handling of typed subarrays` is the **subject**, a brief description of the change.
* use present tense: "change"
* don't capitalize the first letter
* no period at the end
* ``Previously, it would return a copy of the whole original typed array, not its slice. Now, the `byteOffset` and `length` are also preserved.`` This is the **body**. The body should include the motivation for the change and contrast this with previous behavior. Once again present tense is used.
* `Fixes #14842` and `Closes #14845` are both part of the **footer**. The footer is the place to
reference any GitHub issues or pull requests that this commit fixes/closes.

Any line of the commit message (including the header) should be no longer than 100 characters.

###Reverting a Commit

If the commit reverts a previous commit, the **type** should be `revert: ` followed by the entire header of the reverted commit in quotes. So to revert the example above you would write `revert: "fix(copy): fix handling of typed subarrays"`
In the body it should say: `This reverts commit <hash>.` where the hash is the SHA of the commit being reverted.

###Tagging

[Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging) is a process that happens whenever a new release (or a hotfix) is merged with master. The release is tagged with a version number like `v1.2.0`

Tagging is also used on commits to label their association with a certain version of the application. Searching for that tag then gets a list of all the commits that were tagged as part of that version.

###Issues and Labels

The eTools team uses [Pivotal Tracker](https://www.pivotaltracker.com/) for issue tracking. It’s a way for team members to keep track of not only bugs but new feature ideas, optimizations, and more general “to-dos” and have the rest of the team discuss these issues.

Issues often have a milestone associated with them, like a project version or a specific time period to which the issue is relevant. There’s also a section for assignee's, who have been tasked with fixing that specific issue. Finally there are labels, which act as a way to organize issues, make them easily searchable, and give people a quick idea of what the issue involves.

###Issues in GitHub

Since not all developers will have access to eTools' private Pivotal Tracker dashboard, we recommend that any issues identified by developers without access to Pivotal Tracker will be raised in GitHub prior to fixing them in the code and making a Pull Request.

###Labels in GitHub

Labels in GitHub are used in a color coded system. The color is a universal identifier for the team. It could specify a platform that the issue is relevant to, a problem in production, a desire for feedback or improvements, or a new addition. The actual text on the label is more specific. A *platform* label could have the text “python”, and now someone looking at the label knows the issue resides on the Python back-end of the app. Or maybe an *addition* label will have “feature” in the text, so this issue involves a brand new feature that has yet to be added.

This diagram outlines the labeling methodology

![LabelGuide](http://i.imgur.com/dWfLNeS.png)

###Sources

https://datasift.github.io/gitflow/IntroducingGitFlow.html
https://www.thoughtworks.com/continuous-integration
https://git-scm.com/book/en/v2/Git-Basics-Tagging
https://guides.github.com/features/issues/
https://robinpowered.com/blog/best-practice-system-for-organizing-and-tagging-github-issues/
https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md
13 changes: 11 additions & 2 deletions EquiTrack/EquiTrack/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
__author__ = 'jcranwellward'

from datetime import datetime, timedelta
from datetime import datetime, timedelta, date
from django.db.models.signals import post_save

import factory
Expand Down Expand Up @@ -126,7 +126,6 @@ class Meta:
model = partner_models.PartnerOrganization

name = factory.Sequence(lambda n: 'Partner {}'.format(n))

staff = factory.RelatedFactory(PartnerStaffFactory, 'partner')


Expand All @@ -138,6 +137,7 @@ class Meta:
agreement_type = u'PCA'



class PartnershipFactory(factory.django.DjangoModelFactory):
class Meta:
model = partner_models.PCA
Expand All @@ -149,6 +149,15 @@ class Meta:
initiation_date = datetime.today()


class ResultStructureFactory(factory.django.DjangoModelFactory):
class Meta:
model = report_models.ResultStructure

name = factory.Sequence(lambda n: 'RSSP {}'.format(n))
from_date = date(date.today().year, 1, 1)
to_date = date(date.today().year, 12, 31)


# class FundingCommitmentFactory(factory.django.DjangoModelFactory):
# class Meta:
# model = partner_models.FundingCommitment
Expand Down
4 changes: 2 additions & 2 deletions EquiTrack/EquiTrack/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ class HACTDashboardView(TemplateView):
def get_context_data(self, **kwargs):
return {
'partners': PartnerOrganization.objects.filter(
documents__status__in=[
Q(documents__status__in=[
PCA.ACTIVE,
PCA.IMPLEMENTED
]
]) | (Q(partner_type=u'Government') & Q(work_plans__isnull=False))
).distinct()
}
8 changes: 6 additions & 2 deletions EquiTrack/assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,10 @@ img {
}
#header .brand {
float: left;
width: 280px;
width: auto;
min-height: 60px;
padding: 0 0 0 10px;
position: relative;
background: #0099ff;
}

#header .logo {
Expand All @@ -91,6 +90,11 @@ img {
display: inline-block;
}

#header .logo #test-text {
display: none;
color: #e6e600;
}

#header .logoimg {
margin: 0px 0px 10px 5px;
}
Expand Down
8 changes: 8 additions & 0 deletions EquiTrack/funds/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ def __unicode__(self):
return self.name


class GrantManager(models.Manager):

def get_queryset(self):
return super(GrantManager, self).get_queryset().select_related('donor')


class Grant(models.Model):

donor = models.ForeignKey(Donor)
Expand All @@ -23,6 +29,8 @@ class Grant(models.Model):
class Meta:
ordering = ['donor']

objects = GrantManager()

def __unicode__(self):
return u"{}: {}".format(
self.donor.name,
Expand Down
8 changes: 8 additions & 0 deletions EquiTrack/locations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ class Meta:
ordering = ['name']


class LocationManager(models.Manager):

def get_queryset(self):
return super(LocationManager, self).get_queryset().select_related('gateway', 'locality')


class Location(MPTTModel):

name = models.CharField(max_length=254L)
Expand All @@ -115,6 +121,8 @@ class Location(MPTTModel):
point = models.PointField(null=True, blank=True)
objects = models.GeoManager()

objects = LocationManager()

def __unicode__(self):
#TODO: Make generic
return u'{} ({} {})'.format(
Expand Down
7 changes: 4 additions & 3 deletions EquiTrack/partners/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,10 @@ class GovernmentInterventionAdmin(admin.ModelAdmin):
)
inlines = [GovernmentInterventionResultAdminInline]

suit_form_includes = (
('admin/partners/government_funding.html', 'bottom'),
)
# government funding disabled temporarily. awaiting Vision API updates
# suit_form_includes = (
# ('admin/partners/government_funding.html', 'bottom'),
# )

def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.rel.to is PartnerOrganization:
Expand Down
47 changes: 44 additions & 3 deletions EquiTrack/partners/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,11 @@ def clean(self):

class AgreementForm(UserGroupForm):

ERROR_MESSAGES = {
'end_date': 'End date must be greater than start date',
'start_date_val': 'Start date must be greater than laatest of signed by partner/unicef date',
}

user_field = u'signed_by'
group_name = u'Senior Management Team'

Expand All @@ -310,14 +315,19 @@ def clean(self):
agreement_number = cleaned_data.get(u'agreement_number')
start = cleaned_data.get(u'start')
end = cleaned_data.get(u'end')
signed_by_partner_date = cleaned_data.get(u'signed_by_partner_date')
signed_by_unicef_date = cleaned_data.get(u'signed_by_unicef_date')

if partner and agreement_type == Agreement.PCA:
# Partner can only have one active PCA
# pca_ids = partner.agreement_set.filter(agreement_type=Agreement.PCA).values_list('id', flat=True)
# if (not self.instance.id and pca_ids) or \
# (self.instance.id and pca_ids and self.instance.id not in pca_ids):
if partner.get_last_agreement and partner.get_last_agreement != self.instance:
if not start > partner.get_last_agreement.start and not end > partner.get_last_agreement.end:
if start and end and \
partner.get_last_pca and \
partner.get_last_pca != self.instance:

if start < partner.get_last_pca.end:
err = u'This partner can only have one active {} agreement'.format(agreement_type)
raise ValidationError({'agreement_type': err})

Expand All @@ -341,6 +351,37 @@ def clean(self):
_(u'SSFA can not be more than a year')
)

if start and end and start > end:
raise ValidationError({'end': self.ERROR_MESSAGES['end_date']})

# check if start date is greater than or equal than greatest signed date
if signed_by_partner_date and signed_by_unicef_date and start:
if signed_by_partner_date > signed_by_unicef_date:
if start < signed_by_partner_date:
raise ValidationError({'start': self.ERROR_MESSAGES['start_date_val']})
else:
if start < signed_by_unicef_date:
raise ValidationError({'start': self.ERROR_MESSAGES['start_date_val']})

if self.instance.id and self.instance.agreement_type != agreement_type \
and signed_by_partner_date and signed_by_unicef_date:
raise ValidationError(
_(u'Agreement type can not be changed once signed by unicef and partner ')
)

# set start date to one of the signed dates
if start is None and agreement_type == Agreement.PCA:
# if both signed dates exist
if signed_by_partner_date and signed_by_unicef_date:
if signed_by_partner_date > signed_by_unicef_date:
self.cleaned_data[u'start'] = signed_by_partner_date
else:
self.cleaned_data[u'start'] = signed_by_unicef_date

# set end date to result structure end date
if end is None:
self.cleaned_data[u'end'] = ResultStructure.current().to_date

# TODO: prevent more than one agreement being created for the current period
# agreements = Agreement.objects.filter(
# partner=partner,
Expand Down Expand Up @@ -573,7 +614,7 @@ def clean(self):
signed_by_partner_date = cleaned_data[u'signed_by_partner_date']
start_date = cleaned_data[u'start_date']
end_date = cleaned_data[u'end_date']
initiation_date = cleaned_data[u'initiation_date']
initiation_date = cleaned_data.get(u'initiation_date')
submission_date = cleaned_data[u'submission_date']
review_date = cleaned_data[u'review_date']

Expand Down
19 changes: 19 additions & 0 deletions EquiTrack/partners/migrations/0060_auto_20160721_2313.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('partners', '0059_auto_20160621_2228'),
]

operations = [
migrations.AlterField(
model_name='pca',
name='number',
field=models.CharField(max_length=45L, null=True, verbose_name='Reference Number', blank=True),
),
]
Loading

0 comments on commit cbdf18d

Please sign in to comment.