prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Allow 0 as value for funding amount in partnerships
  It should be possible to fill in 0 as a funding amount in the project editor, and then publish a project. This is based on Plan Finland feedback:
  
  "Are you able to give us an estimate on when the suggestions we made to Geert could be published (the changes to the results section and possibility for 0€ budget project)."
  
  
  </issue>
  <code>
  [start of akvo/rsr/models/publishing_status.py]
  1 # -*- coding: utf-8 -*-
  2 
  3 # Akvo RSR is covered by the GNU Affero General Public License.
  4 # See more details in the license.txt file located at the root folder of the Akvo RSR module.
  5 # For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
  6 
  7 from django.conf import settings
  8 from django.core.exceptions import ValidationError
  9 from django.core.mail import send_mail
  10 from django.db import models
  11 from django.db.models.signals import post_save
  12 from django.dispatch import receiver
  13 from django.utils.translation import ugettext_lazy as _
  14 from .partnership import Partnership
  15 
  16 from ..fields import ValidXMLCharField
  17 
  18 
  19 class PublishingStatus(models.Model):
  20     """Keep track of publishing status."""
  21     STATUS_PUBLISHED = 'published'
  22     STATUS_UNPUBLISHED = 'unpublished'
  23     PUBLISHING_STATUS = (
  24         (STATUS_UNPUBLISHED, _(u'Unpublished')),
  25         (STATUS_PUBLISHED, _(u'Published')),
  26     )
  27 
  28     project = models.OneToOneField('Project',)
  29     status = ValidXMLCharField(max_length=30,
  30                                choices=PUBLISHING_STATUS,
  31                                db_index=True, default=STATUS_UNPUBLISHED)
  32 
  33     def clean(self):
  34         """Projects can only be published, when several checks have been performed."""
  35         if self.status == 'published':
  36             validation_errors = []
  37 
  38             if not self.project.title:
  39                 validation_errors.append(
  40                     ValidationError(_('Project needs to have a title.'),
  41                                     code='title')
  42                 )
  43 
  44             if not self.project.subtitle:
  45                 validation_errors.append(
  46                     ValidationError(_('Project needs to have a subtitle.'),
  47                                     code='subtitle')
  48                 )
  49 
  50             if self.project.iati_status == '6':
  51                 validation_errors.append(
  52                     ValidationError(_('Project needs to have non-suspended status.'),
  53                                     code='status')
  54                 )
  55 
  56             if not (self.project.date_start_planned or self.project.date_start_actual):
  57                 validation_errors.append(
  58                     ValidationError(
  59                         _('Project needs to have the planned or actual start date field filled '
  60                           'in.'), code='start_date')
  61                 )
  62 
  63             if not self.project.current_image:
  64                 validation_errors.append(
  65                     ValidationError(_('Project needs to have a photo.'),
  66                                     code='current_image')
  67                 )
  68 
  69             if not self.project.partnerships.filter(
  70                     organisation__can_create_projects__exact=True).exists():
  71                 validation_errors.append(
  72                     ValidationError(
  73                         _('Project has no partner that is allowed to publish it.'),
  74                         code='partners'
  75                     )
  76                 )
  77 
  78             if not self.project.partnerships.filter(
  79                     iati_organisation_role__in=[Partnership.IATI_FUNDING_PARTNER,
  80                                                 Partnership.IATI_IMPLEMENTING_PARTNER,
  81                                                 Partnership.IATI_ACCOUNTABLE_PARTNER]
  82             ).exists():
  83                 validation_errors.append(
  84                     ValidationError(
  85                         _('Project needs to have at least one funding, implementing or accountable '
  86                           'partner.'),
  87                         code='partners'
  88                     )
  89                 )
  90             else:
  91                 for funding_partner in self.project.partnerships.filter(
  92                         iati_organisation_role=Partnership.IATI_FUNDING_PARTNER):
  93                     if not funding_partner.funding_amount:
  94                         validation_errors.append(
  95                             ValidationError(_('All funding partners should have a funding amount.'),
  96                                             code='partners'
  97                             )
  98                         )
  99                         break
  100 
  101             if not self.project.project_plan_summary:
  102                 validation_errors.append(
  103                     ValidationError(_('Project needs to have the project plan summary filled in.'),
  104                                     code='summary')
  105                 )
  106 
  107             if not self.project.goals_overview:
  108                 validation_errors.append(
  109                     ValidationError(_('Project needs to have the goals overview field filled in.'),
  110                                     code='goals_overview')
  111                 )
  112 
  113             if not self.project.locations.all():
  114                 validation_errors.append(
  115                     ValidationError(_('Project needs to have at least one location.'),
  116                                     code='location')
  117                 )
  118             else:
  119                 for location in self.project.locations.all():
  120                     if not (location.latitude and location.longitude):
  121                         validation_errors.append(
  122                             ValidationError(
  123                                 _('All locations need to have a latitude and longitude specified.'),
  124                                 code='location')
  125                         )
  126                         break
  127 
  128             if not self.project.budget_items.all():
  129                 validation_errors.append(
  130                     ValidationError(_('Project needs to have at least one budget item.'),
  131                                     code='budget_item')
  132                 )
  133             elif not self.project.budget_items.filter(amount__gt=0).exists():
  134                 validation_errors.append(
  135                     ValidationError(
  136                         _('Project needs to have at least one budget item with an amount.'),
  137                         code='budget_item'
  138                     )
  139                 )
  140 
  141             if validation_errors:
  142                 raise ValidationError(validation_errors)
  143 
  144     class Meta:
  145         app_label = 'rsr'
  146         verbose_name = _(u'publishing status')
  147         verbose_name_plural = _(u'publishing statuses')
  148         ordering = ('-status', 'project')
  149
  [end of akvo/rsr/models/publishing_status.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/akvo/rsr/models/publishing_status.py b/akvo/rsr/models/publishing_status.py
  --- a/akvo/rsr/models/publishing_status.py
  +++ b/akvo/rsr/models/publishing_status.py
  @@ -90,7 +90,7 @@
               else:
                   for funding_partner in self.project.partnerships.filter(
                           iati_organisation_role=Partnership.IATI_FUNDING_PARTNER):
  -                    if not funding_partner.funding_amount:
  +                    if not funding_partner.funding_amount and not funding_partner.funding_amount == 0:
                           validation_errors.append(
                               ValidationError(_('All funding partners should have a funding amount.'),
                                               code='partners'
  @@ -130,7 +130,7 @@
                       ValidationError(_('Project needs to have at least one budget item.'),
                                       code='budget_item')
                   )
  -            elif not self.project.budget_items.filter(amount__gt=0).exists():
  +            elif not self.project.budget_items.filter(amount__gte=0).exists():
                   validation_errors.append(
                       ValidationError(
                           _('Project needs to have at least one budget item with an amount.'),
  
verification_info: {"golden_diff": "diff --git a/akvo/rsr/models/publishing_status.py b/akvo/rsr/models/publishing_status.py\n--- a/akvo/rsr/models/publishing_status.py\n+++ b/akvo/rsr/models/publishing_status.py\n@@ -90,7 +90,7 @@\n             else:\n                 for funding_partner in self.project.partnerships.filter(\n                         iati_organisation_role=Partnership.IATI_FUNDING_PARTNER):\n-                    if not funding_partner.funding_amount:\n+                    if not funding_partner.funding_amount and not funding_partner.funding_amount == 0:\n                         validation_errors.append(\n                             ValidationError(_('All funding partners should have a funding amount.'),\n                                             code='partners'\n@@ -130,7 +130,7 @@\n                     ValidationError(_('Project needs to have at least one budget item.'),\n                                     code='budget_item')\n                 )\n-            elif not self.project.budget_items.filter(amount__gt=0).exists():\n+            elif not self.project.budget_items.filter(amount__gte=0).exists():\n                 validation_errors.append(\n                     ValidationError(\n                         _('Project needs to have at least one budget item with an amount.'),\n", "issue": "Allow 0 as value for funding amount in partnerships\nIt should be possible to fill in 0 as a funding amount in the project editor, and then publish a project. This is based on Plan Finland feedback:\n\n\"Are you able to give us an estimate on when the suggestions we made to Geert could be published (the changes to the results section and possibility for 0\u20ac budget project).\"\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Akvo RSR is covered by the GNU Affero General Public License.\n# See more details in the license.txt file located at the root folder of the Akvo RSR module.\n# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.\n\nfrom django.conf import settings\nfrom django.core.exceptions import ValidationError\nfrom django.core.mail import send_mail\nfrom django.db import models\nfrom django.db.models.signals import post_save\nfrom django.dispatch import receiver\nfrom django.utils.translation import ugettext_lazy as _\nfrom .partnership import Partnership\n\nfrom ..fields import ValidXMLCharField\n\n\nclass PublishingStatus(models.Model):\n    \"\"\"Keep track of publishing status.\"\"\"\n    STATUS_PUBLISHED = 'published'\n    STATUS_UNPUBLISHED = 'unpublished'\n    PUBLISHING_STATUS = (\n        (STATUS_UNPUBLISHED, _(u'Unpublished')),\n        (STATUS_PUBLISHED, _(u'Published')),\n    )\n\n    project = models.OneToOneField('Project',)\n    status = ValidXMLCharField(max_length=30,\n                               choices=PUBLISHING_STATUS,\n                               db_index=True, default=STATUS_UNPUBLISHED)\n\n    def clean(self):\n        \"\"\"Projects can only be published, when several checks have been performed.\"\"\"\n        if self.status == 'published':\n            validation_errors = []\n\n            if not self.project.title:\n                validation_errors.append(\n                    ValidationError(_('Project needs to have a title.'),\n                                    code='title')\n                )\n\n            if not self.project.subtitle:\n                validation_errors.append(\n                    ValidationError(_('Project needs to have a subtitle.'),\n                                    code='subtitle')\n                )\n\n            if self.project.iati_status == '6':\n                validation_errors.append(\n                    ValidationError(_('Project needs to have non-suspended status.'),\n                                    code='status')\n                )\n\n            if not (self.project.date_start_planned or self.project.date_start_actual):\n                validation_errors.append(\n                    ValidationError(\n                        _('Project needs to have the planned or actual start date field filled '\n                          'in.'), code='start_date')\n                )\n\n            if not self.project.current_image:\n                validation_errors.append(\n                    ValidationError(_('Project needs to have a photo.'),\n                                    code='current_image')\n                )\n\n            if not self.project.partnerships.filter(\n                    organisation__can_create_projects__exact=True).exists():\n                validation_errors.append(\n                    ValidationError(\n                        _('Project has no partner that is allowed to publish it.'),\n                        code='partners'\n                    )\n                )\n\n            if not self.project.partnerships.filter(\n                    iati_organisation_role__in=[Partnership.IATI_FUNDING_PARTNER,\n                                                Partnership.IATI_IMPLEMENTING_PARTNER,\n                                                Partnership.IATI_ACCOUNTABLE_PARTNER]\n            ).exists():\n                validation_errors.append(\n                    ValidationError(\n                        _('Project needs to have at least one funding, implementing or accountable '\n                          'partner.'),\n                        code='partners'\n                    )\n                )\n            else:\n                for funding_partner in self.project.partnerships.filter(\n                        iati_organisation_role=Partnership.IATI_FUNDING_PARTNER):\n                    if not funding_partner.funding_amount:\n                        validation_errors.append(\n                            ValidationError(_('All funding partners should have a funding amount.'),\n                                            code='partners'\n                            )\n                        )\n                        break\n\n            if not self.project.project_plan_summary:\n                validation_errors.append(\n                    ValidationError(_('Project needs to have the project plan summary filled in.'),\n                                    code='summary')\n                )\n\n            if not self.project.goals_overview:\n                validation_errors.append(\n                    ValidationError(_('Project needs to have the goals overview field filled in.'),\n                                    code='goals_overview')\n                )\n\n            if not self.project.locations.all():\n                validation_errors.append(\n                    ValidationError(_('Project needs to have at least one location.'),\n                                    code='location')\n                )\n            else:\n                for location in self.project.locations.all():\n                    if not (location.latitude and location.longitude):\n                        validation_errors.append(\n                            ValidationError(\n                                _('All locations need to have a latitude and longitude specified.'),\n                                code='location')\n                        )\n                        break\n\n            if not self.project.budget_items.all():\n                validation_errors.append(\n                    ValidationError(_('Project needs to have at least one budget item.'),\n                                    code='budget_item')\n                )\n            elif not self.project.budget_items.filter(amount__gt=0).exists():\n                validation_errors.append(\n                    ValidationError(\n                        _('Project needs to have at least one budget item with an amount.'),\n                        code='budget_item'\n                    )\n                )\n\n            if validation_errors:\n                raise ValidationError(validation_errors)\n\n    class Meta:\n        app_label = 'rsr'\n        verbose_name = _(u'publishing status')\n        verbose_name_plural = _(u'publishing statuses')\n        ordering = ('-status', 'project')\n", "path": "akvo/rsr/models/publishing_status.py"}]}