Source code for akvo.rsr.models.crs_add

# -*- coding: utf-8 -*-

# Akvo RSR is covered by the GNU Affero General Public License.
# See more details in the license.txt file located at the root folder of the Akvo RSR module.
# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.


from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _

from ..fields import ValidXMLCharField

from akvo.codelists.models import (CRSAddOtherFlags, LoanRepaymentType, LoanRepaymentPeriod,
                                   Currency, CRSChannelCode)
from akvo.codelists.store.default_codelists import (C_R_S_ADD_OTHER_FLAGS, LOAN_REPAYMENT_TYPE,
                                                    LOAN_REPAYMENT_PERIOD, CURRENCY,
                                                    C_R_S_CHANNEL_CODE)
from akvo.utils import codelist_choices, codelist_value


[docs]class CrsAdd(models.Model): """ Items specific to CRS++ reporting. Can only occur once per project. """ project = models.OneToOneField('Project', on_delete=models.CASCADE, primary_key=True) loan_terms_rate1 = models.DecimalField( _('loan terms rate 1'), blank=True, null=True, max_digits=5, decimal_places=2, validators=[MaxValueValidator(100), MinValueValidator(0)], help_text=_('Interest Rate. If an ODA loan with variable interest rate, report the ' 'variable rate here and the reference fixed rate as rate 2.') ) loan_terms_rate2 = models.DecimalField( _('loan terms rate 2'), blank=True, null=True, max_digits=5, decimal_places=2, validators=[MaxValueValidator(100), MinValueValidator(0)], help_text=_('Second Interest Rate. If an ODA loan with variable interest rate, report the ' 'variable rate as rate 1 and the reference fixed rate here.') ) repayment_type = ValidXMLCharField( _('loan terms repayment type'), max_length=1, choices=codelist_choices(LOAN_REPAYMENT_TYPE), blank=True, help_text=_('An IATI codelist tabulating CRS-specified values for the type of Repayment. ' 'See the <a href="http://iatistandard.org/202/codelists/LoanRepaymentType/" ' 'target="_blank">IATI codelist</a>.') ) repayment_plan = ValidXMLCharField( _('loan terms repayment plan'), max_length=2, choices=codelist_choices(LOAN_REPAYMENT_PERIOD), blank=True, help_text=_('An IATI codelist tabulating CRS-specified values for the number of ' 'repayments per annum. See the <a href="http://iatistandard.org/202/codelists/' 'LoanRepaymentPeriod/" target="_blank">IATI codelist</a>.') ) commitment_date = models.DateField( _('loan terms commitment date'), null=True, blank=True, help_text=_('The CRS++ reported commitment date.') ) repayment_first_date = models.DateField( _('loan terms first repayment date'), null=True, blank=True, help_text=_('The CRS++ reported first repayment date.') ) repayment_final_date = models.DateField( _('loan terms final repayment date'), null=True, blank=True, help_text=_('The CRS++ reported final repayment date.') ) loan_status_year = models.PositiveIntegerField( _('loan status year'), blank=True, null=True, help_text=_('CRS reporting year (CRS++ Column 1).') ) loan_status_currency = ValidXMLCharField( _('loan status currency'), blank=True, max_length=3, choices=codelist_choices(CURRENCY) ) loan_status_value_date = models.DateField( _('loan status value date'), blank=True, null=True, help_text=_('Enter the specific date (DD/MM/YYYY) for the loan status values.') ) interest_received = models.DecimalField( _('loan status interest received'), max_digits=10, decimal_places=2, blank=True, null=True, help_text=_('Interest received during the reporting year.') ) principal_outstanding = models.DecimalField( _('loan status principal outstanding'), max_digits=10, decimal_places=2, blank=True, null=True, help_text=_('The amount of principal owed on the loan at the end of the ' 'reporting year.') ) principal_arrears = models.DecimalField( _('loan status principal arrears'), max_digits=10, decimal_places=2, blank=True, null=True, help_text=_('Arrears of principal at the end of the year. Included in principal ' 'outstanding.') ) interest_arrears = models.DecimalField( _('loan status interest arrears'), max_digits=10, decimal_places=2, blank=True, null=True, help_text=_('Arrears of interest at the end of the year.') ) channel_code = ValidXMLCharField( _('channel code'), blank=True, max_length=5, choices=codelist_choices(C_R_S_CHANNEL_CODE), help_text=_('The CRS channel code for this activity. The codelist contains both ' 'organisation types and names of organisations. For non-CRS purposes these ' 'should be reported using participating organisations. See the <a ' 'href="http://iatistandard.org/202/codelists/CRSChannelCode/" ' 'target="_blank">IATI codelist</a>.') ) def __str__(self): return 'CRS++'
[docs] def iati_repayment_type(self): return codelist_value(LoanRepaymentType, self, 'repayment_type')
[docs] def iati_repayment_type_unicode(self): return str(self.iati_repayment_type())
[docs] def iati_repayment_plan(self): return codelist_value(LoanRepaymentPeriod, self, 'repayment_plan')
[docs] def iati_repayment_plan_unicode(self): return str(self.iati_repayment_plan())
[docs] def iati_currency(self): return codelist_value(Currency, self, 'loan_status_currency')
[docs] def iati_currency_unicode(self): return str(self.iati_currency())
[docs] def iati_channel_code(self): return codelist_value(CRSChannelCode, self, 'channel_code')
[docs] def iati_channel_code_unicode(self): return str(self.iati_channel_code())
class Meta: app_label = 'rsr' verbose_name = _('CRS reporting') verbose_name_plural = _('CRS reporting') ordering = ('pk',)
[docs]class CrsAddOtherFlag(models.Model): """ Other flag of CRS++ reporting. """ crs = models.ForeignKey('CrsAdd', on_delete=models.CASCADE, verbose_name='crs', related_name='other_flags') code = ValidXMLCharField( _('code'), max_length=1, choices=codelist_choices(C_R_S_ADD_OTHER_FLAGS), help_text=_('An IATI code describing the equivalent CRS++ columns. See the <a ' 'href="http://iatistandard.org/202/codelists/CRSAddOtherFlags/" ' 'target="_blank">IATI codelist</a>.') ) significance = models.BooleanField( _('significance'), null=True, blank=True, help_text=_('Indicate whether the flag applies or not.') ) def __str__(self): if self.code: try: return self.iati_code().name except AttributeError: return self.iati_code() else: return '%s' % _('No other flag code specified')
[docs] def iati_code(self): return codelist_value(CRSAddOtherFlags, self, 'code')
[docs] def iati_code_unicode(self): return str(self.iati_code())
class Meta: app_label = 'rsr' verbose_name = _('CRS other flag') verbose_name_plural = _('CRS other flags') ordering = ('pk',)