@@ -1553,7 +1553,10 @@ class FoodPurchase(LivelihoodActivity):
15531553
15541554 # unit_multiple has names like wt_of_measure in the BSS.
15551555 unit_multiple = models .PositiveSmallIntegerField (
1556- verbose_name = _ ("Unit Multiple" ), help_text = _ ("Multiple of the unit of measure in a single purchase" )
1556+ blank = True ,
1557+ null = True ,
1558+ verbose_name = _ ("Unit Multiple" ),
1559+ help_text = _ ("Multiple of the unit of measure in a single purchase" ),
15571560 )
15581561 # This is a float field because data may be captured as "once per week",
15591562 # which equates to "52 per year", which is "4.33 per month".
@@ -1565,17 +1568,25 @@ class FoodPurchase(LivelihoodActivity):
15651568 help_text = _ ("Number of months in a year that the product is purchased" ),
15661569 )
15671570 times_per_year = models .PositiveSmallIntegerField (
1571+ blank = True ,
1572+ null = True ,
15681573 verbose_name = _ ("Times per year" ),
15691574 help_text = _ ("Number of times in a year that the purchase is made" ),
15701575 )
15711576
15721577 def validate_quantity_produced (self ):
1573- if self .quantity_produced != self .unit_multiple * self .times_per_month * self .months_per_year :
1574- raise ValidationError (
1575- _ (
1576- "Quantity produced for a Food Purchase must be purchase amount * purchases per month * months per year" # NOQA: E501
1578+ if (
1579+ self .quantity_produced is not None
1580+ and self .unit_multiple is not None
1581+ and self .times_per_month is not None
1582+ and self .months_per_year is not None
1583+ ):
1584+ if self .quantity_produced != self .unit_multiple * self .times_per_month * self .months_per_year :
1585+ raise ValidationError (
1586+ _ (
1587+ "Quantity produced for a Food Purchase must be purchase amount * purchases per month * months per year" # NOQA: E501
1588+ )
15771589 )
1578- )
15791590
15801591 class Meta :
15811592 verbose_name = LivelihoodStrategyType .FOOD_PURCHASE .label
@@ -1598,15 +1609,23 @@ class PaymentInKind(LivelihoodActivity):
15981609 help_text = _ ("Amount of item received each time the labor is performed" ),
15991610 )
16001611 people_per_household = models .PositiveSmallIntegerField (
1601- verbose_name = _ ("People per household" ), help_text = _ ("Number of household members who perform the labor" )
1612+ blank = True ,
1613+ null = True ,
1614+ verbose_name = _ ("People per household" ),
1615+ help_text = _ ("Number of household members who perform the labor" ),
16021616 )
16031617 # This is a float field because data may be captured as "once per week",
16041618 # which equates to "52 per year", which is "4.33 per month".
16051619 times_per_month = models .FloatField (blank = True , null = True , verbose_name = _ ("Labor per month" ))
16061620 months_per_year = models .PositiveSmallIntegerField (
1607- verbose_name = _ ("Months per year" ), help_text = _ ("Number of months in a year that the labor is performed" )
1621+ blank = True ,
1622+ null = True ,
1623+ verbose_name = _ ("Months per year" ),
1624+ help_text = _ ("Number of months in a year that the labor is performed" ),
16081625 )
16091626 times_per_year = models .PositiveSmallIntegerField (
1627+ blank = True ,
1628+ null = True ,
16101629 verbose_name = _ ("Times per year" ),
16111630 help_text = _ ("Number of times in a year that the labor is performed" ),
16121631 )
@@ -1621,15 +1640,21 @@ def clean(self):
16211640
16221641 def validate_quantity_produced (self ):
16231642 if (
1624- self .quantity_produced
1625- and self .quantity_produced
1626- != self .payment_per_time * self .people_per_household * self .times_per_month * self .months_per_year
1643+ self .quantity_produced is not None
1644+ and self .payment_per_time is not None
1645+ and self .people_per_household is not None
1646+ and self .times_per_month is not None
1647+ and self .months_per_year is not None
16271648 ):
1628- raise ValidationError (
1629- _ (
1630- "Quantity produced for Payment In Kind must be payment per time * number of people * labor per month * months per year" # NOQA: E501
1649+ if (
1650+ self .quantity_produced
1651+ != self .payment_per_time * self .people_per_household * self .times_per_month * self .months_per_year
1652+ ):
1653+ raise ValidationError (
1654+ _ (
1655+ "Quantity produced for Payment In Kind must be payment per time * number of people * labor per month * months per year" # NOQA: E501
1656+ )
16311657 )
1632- )
16331658
16341659 class Meta :
16351660 verbose_name = LivelihoodStrategyType .PAYMENT_IN_KIND .label
@@ -1647,7 +1672,10 @@ class ReliefGiftOther(LivelihoodActivity):
16471672 # Production calculation /validation is `unit_of_measure * unit_multiple * times_per_year`
16481673 # Also used for the number of children receiving school meals.
16491674 unit_multiple = models .PositiveSmallIntegerField (
1650- verbose_name = _ ("Unit Multiple" ), help_text = _ ("Multiple of the unit of measure received each time" )
1675+ blank = True ,
1676+ null = True ,
1677+ verbose_name = _ ("Unit Multiple" ),
1678+ help_text = _ ("Multiple of the unit of measure received each time" ),
16511679 )
16521680 # This is a float field because data may be captured as "once per week",
16531681 # which equates to "52 per year", which is "4.33 per month".
@@ -1661,14 +1689,18 @@ class ReliefGiftOther(LivelihoodActivity):
16611689 help_text = _ ("Number of months in a year that the item is received" ),
16621690 )
16631691 times_per_year = models .PositiveSmallIntegerField (
1664- verbose_name = _ ("Times per year" ), help_text = _ ("Number of times in a year that the item is received" )
1692+ blank = True ,
1693+ null = True ,
1694+ verbose_name = _ ("Times per year" ),
1695+ help_text = _ ("Number of times in a year that the item is received" ),
16651696 )
16661697
16671698 def validate_quantity_produced (self ):
1668- if self .quantity_produced != self .unit_multiple * self .times_per_year :
1669- raise ValidationError (
1670- _ ("Quantity produced for Relief, Gifts, Other must be amount received * times per year" )
1671- )
1699+ if self .quantity_produced is not None and self .unit_multiple is not None and self .times_per_year is not None :
1700+ if self .quantity_produced != self .unit_multiple * self .times_per_year :
1701+ raise ValidationError (
1702+ _ ("Quantity produced for Relief, Gifts, Other must be amount received * times per year" )
1703+ )
16721704
16731705 class Meta :
16741706 verbose_name = LivelihoodStrategyType .RELIEF_GIFT_OTHER .label
@@ -1752,6 +1784,8 @@ class OtherCashIncome(LivelihoodActivity):
17521784 help_text = _ ("Number of months in a year that the labor is performed" ),
17531785 )
17541786 times_per_year = models .PositiveSmallIntegerField (
1787+ blank = True ,
1788+ null = True ,
17551789 verbose_name = _ ("Times per year" ),
17561790 help_text = _ ("Number of times in a year that the income is received" ),
17571791 )
@@ -1766,19 +1800,24 @@ def clean(self):
17661800
17671801 def validate_income (self ):
17681802 if (
1769- self .people_per_household
1770- and self .income
1771- != self .payment_per_time * self .people_per_household * self .times_per_month * self .months_per_year
1803+ self .people_per_household is not None
1804+ and self .income is not None
1805+ and self .payment_per_time is not None
1806+ and self .times_per_month is not None
1807+ and self .months_per_year is not None
17721808 ):
1773- raise ValidationError (
1774- _ (
1775- "Quantity produced for Other Cash Income must be payment per time * number of people * labor per month * months per year" # NOQA: E501
1809+ if (
1810+ self .income
1811+ != self .payment_per_time * self .people_per_household * self .times_per_month * self .months_per_year
1812+ ):
1813+ raise ValidationError (
1814+ _ (
1815+ "Quantity produced for Other Cash Income must be payment per time * number of people * labor per month * months per year" # NOQA: E501
1816+ )
17761817 )
1777- )
1778- if self .income != self .payment_per_time * self .times_per_year :
1779- raise ValidationError (
1780- _ ("Quantity produced for Other Cash Income must be payment per time * times per year" )
1781- )
1818+ if self .income is not None and self .payment_per_time is not None and self .times_per_year is not None :
1819+ if self .income != self .payment_per_time * self .times_per_year :
1820+ raise ValidationError (_ ("Income for 'Other Cash Income' must be payment per time * times per year" ))
17821821
17831822 def calculate_fields (self ):
17841823 self .times_per_year = self .people_per_household * self .times_per_month * self .months_per_year
@@ -1817,21 +1856,40 @@ class OtherPurchase(LivelihoodActivity):
18171856 help_text = _ ("Number of months in a year that the product is purchased" ),
18181857 )
18191858 times_per_year = models .PositiveSmallIntegerField (
1859+ blank = True ,
1860+ null = True ,
18201861 verbose_name = _ ("Times per year" ),
18211862 help_text = _ ("Number of times in a year that the product is purchased" ),
18221863 )
18231864
18241865 def validate_expenditure (self ):
1825- if (
1826- self .times_per_month
1827- and self .months_per_year
1828- and self .times_per_month * self .months_per_year != self .times_per_year
1829- ):
1830- raise ValidationError (_ ("Times per year must be times per month * months per year" ))
1831- if self .expenditure != self .price * self .unit_multiple * self .times_per_year :
1832- raise ValidationError (
1833- _ ("Expenditure for Other Purchases must be price * unit multiple * purchases per year" )
1834- )
1866+ errors = []
1867+ if self .times_per_month is not None and self .months_per_year is not None :
1868+ expected_times_per_year = self .times_per_month * self .months_per_year
1869+ if self .times_per_year is not None and self .times_per_year != expected_times_per_year :
1870+ errors .append (
1871+ _ (
1872+ "Times per year must be times per month * months per year. Expected: %(expected)s, Found: %(found)s"
1873+ )
1874+ % {
1875+ "expected" : expected_times_per_year ,
1876+ "found" : self .times_per_year ,
1877+ }
1878+ )
1879+ if self .price is not None and self .unit_multiple is not None and self .times_per_year is not None :
1880+ expected_expenditure = self .price * self .unit_multiple * self .times_per_year
1881+ if self .expenditure is not None and self .expenditure != expected_expenditure :
1882+ errors .append (
1883+ _ (
1884+ "Expenditure for Other Purchases must be price * unit multiple * purchases per year. Expected: %(expected)s, Found: %(found)s"
1885+ )
1886+ % {
1887+ "expected" : expected_expenditure ,
1888+ "found" : self .expenditure ,
1889+ }
1890+ )
1891+ if errors :
1892+ raise ValidationError (errors )
18351893
18361894 class Meta :
18371895 verbose_name = LivelihoodStrategyType .OTHER_PURCHASE .label
0 commit comments