prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  User type should be able to return `created` and `lastLogin` fields
  There is no way to obtain information when a user was registered and when she/he logged last time.
  
  </issue>
  <code>
  [start of saleor/graphql/account/resolvers.py]
  1 from django.db.models import Q
  2 from i18naddress import get_validation_rules
  3 
  4 from ...account import models
  5 from ...core.utils import get_client_ip, get_country_by_ip
  6 from ..utils import filter_by_query_param
  7 from .types import AddressValidationData, ChoiceValue
  8 
  9 USER_SEARCH_FIELDS = (
  10     'email', 'default_shipping_address__first_name',
  11     'default_shipping_address__last_name', 'default_shipping_address__city',
  12     'default_shipping_address__country')
  13 
  14 
  15 def resolve_customers(info, query):
  16     qs = models.User.objects.filter(
  17         Q(is_staff=False) | (Q(is_staff=True) & Q(orders__isnull=False))
  18     ).prefetch_related('addresses')
  19     return filter_by_query_param(
  20         queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)
  21 
  22 
  23 def resolve_staff_users(info, query):
  24     qs = models.User.objects.filter(is_staff=True)
  25     return filter_by_query_param(
  26         queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)
  27 
  28 
  29 def resolve_address_validator(info, input):
  30     country_code = input['country_code']
  31     if not country_code:
  32         client_ip = get_client_ip(info.context)
  33         country = get_country_by_ip(client_ip)
  34         if country:
  35             country_code = country.code
  36         else:
  37             return None
  38     params = {
  39         'country_code': country_code,
  40         'country_area': input['country_area'],
  41         'city_area': input['city_area']}
  42     rules = get_validation_rules(params)
  43 
  44     return AddressValidationData(
  45         country_code=rules.country_code,
  46         country_name=rules.country_name,
  47         address_format=rules.address_format,
  48         address_latin_format=rules.address_latin_format,
  49         allowed_fields=rules.allowed_fields,
  50         required_fields=rules.required_fields,
  51         upper_fields=rules.upper_fields,
  52         country_area_type=rules.country_area_type,
  53         country_area_choices=[
  54             ChoiceValue(area[0], area[1])
  55             for area in rules.country_area_choices],
  56         city_type=rules.city_type,
  57         city_area_choices=[
  58             ChoiceValue(area[0], area[1]) for area in rules.city_area_choices],
  59         postal_code_type=rules.postal_code_type,
  60         postal_code_matchers=[
  61             compiled.pattern for compiled in rules.postal_code_matchers],
  62         postal_code_examples=rules.postal_code_examples,
  63         postal_code_prefix=rules.postal_code_prefix
  64     )
  65
  [end of saleor/graphql/account/resolvers.py]
  [start of saleor/graphql/account/types.py]
  1 import graphene
  2 from django.contrib.auth import get_user_model
  3 from graphene import relay
  4 
  5 from ...account import models
  6 from ...core.permissions import get_permissions
  7 from ..core.types.common import (
  8     CountableDjangoObjectType, CountryDisplay, PermissionDisplay)
  9 from ..utils import format_permissions_for_display
  10 
  11 
  12 class AddressInput(graphene.InputObjectType):
  13     first_name = graphene.String(description='Given name.')
  14     last_name = graphene.String(description='Family name.')
  15     company_name = graphene.String(description='Company or organization.')
  16     street_address_1 = graphene.String(description='Address.')
  17     street_address_2 = graphene.String(description='Address.')
  18     city = graphene.String(description='City.')
  19     city_area = graphene.String(description='District.')
  20     postal_code = graphene.String(description='Postal code.')
  21     country = graphene.String(description='Country.')
  22     country_area = graphene.String(description='State or province.')
  23     phone = graphene.String(description='Phone number.')
  24 
  25 
  26 class Address(CountableDjangoObjectType):
  27     country = graphene.Field(
  28         CountryDisplay, required=True, description='Default shop\'s country')
  29 
  30     class Meta:
  31         exclude_fields = ['user_set', 'user_addresses']
  32         description = 'Represents user address data.'
  33         interfaces = [relay.Node]
  34         model = models.Address
  35 
  36     def resolve_country(self, info):
  37         return CountryDisplay(
  38             code=self.country.code, country=self.country.name)
  39 
  40 
  41 class User(CountableDjangoObjectType):
  42     permissions = graphene.List(PermissionDisplay)
  43 
  44     class Meta:
  45         exclude_fields = [
  46             'date_joined', 'password', 'is_superuser',
  47             'OrderEvent_set', 'last_login']
  48         description = 'Represents user data.'
  49         interfaces = [relay.Node]
  50         model = get_user_model()
  51         filter_fields = ['is_staff']
  52 
  53     def resolve_permissions(self, info, **kwargs):
  54         if self.is_superuser:
  55             permissions = get_permissions()
  56         else:
  57             permissions = self.user_permissions.prefetch_related(
  58                 'content_type').order_by('codename')
  59         return format_permissions_for_display(permissions)
  60 
  61 
  62 class AddressValidationInput(graphene.InputObjectType):
  63     country_code = graphene.String()
  64     country_area = graphene.String()
  65     city_area = graphene.String()
  66 
  67 
  68 class ChoiceValue(graphene.ObjectType):
  69     raw = graphene.String()
  70     verbose = graphene.String()
  71 
  72 
  73 class AddressValidationData(graphene.ObjectType):
  74     country_code = graphene.String()
  75     country_name = graphene.String()
  76     address_format = graphene.String()
  77     address_latin_format = graphene.String()
  78     allowed_fields = graphene.List(graphene.String)
  79     required_fields = graphene.List(graphene.String)
  80     upper_fields = graphene.List(graphene.String)
  81     country_area_type = graphene.String()
  82     country_area_choices = graphene.List(ChoiceValue)
  83     city_type = graphene.String()
  84     city_area_choices = graphene.List(ChoiceValue)
  85     postal_code_type = graphene.String()
  86     postal_code_matchers = graphene.List(graphene.String)
  87     postal_code_examples = graphene.List(graphene.String)
  88     postal_code_prefix = graphene.String()
  89
  [end of saleor/graphql/account/types.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/saleor/graphql/account/resolvers.py b/saleor/graphql/account/resolvers.py
  --- a/saleor/graphql/account/resolvers.py
  +++ b/saleor/graphql/account/resolvers.py
  @@ -16,14 +16,16 @@
       qs = models.User.objects.filter(
           Q(is_staff=False) | (Q(is_staff=True) & Q(orders__isnull=False))
       ).prefetch_related('addresses')
  -    return filter_by_query_param(
  +    qs = filter_by_query_param(
           queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)
  +    return qs.distinct()
   
   
   def resolve_staff_users(info, query):
       qs = models.User.objects.filter(is_staff=True)
  -    return filter_by_query_param(
  +    qs = filter_by_query_param(
           queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)
  +    return qs.distinct()
   
   
   def resolve_address_validator(info, input):
  diff --git a/saleor/graphql/account/types.py b/saleor/graphql/account/types.py
  --- a/saleor/graphql/account/types.py
  +++ b/saleor/graphql/account/types.py
  @@ -42,9 +42,7 @@
       permissions = graphene.List(PermissionDisplay)
   
       class Meta:
  -        exclude_fields = [
  -            'date_joined', 'password', 'is_superuser',
  -            'OrderEvent_set', 'last_login']
  +        exclude_fields = ['password', 'is_superuser', 'OrderEvent_set']
           description = 'Represents user data.'
           interfaces = [relay.Node]
           model = get_user_model()
  
verification_info: {"golden_diff": "diff --git a/saleor/graphql/account/resolvers.py b/saleor/graphql/account/resolvers.py\n--- a/saleor/graphql/account/resolvers.py\n+++ b/saleor/graphql/account/resolvers.py\n@@ -16,14 +16,16 @@\n     qs = models.User.objects.filter(\n         Q(is_staff=False) | (Q(is_staff=True) & Q(orders__isnull=False))\n     ).prefetch_related('addresses')\n-    return filter_by_query_param(\n+    qs = filter_by_query_param(\n         queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)\n+    return qs.distinct()\n \n \n def resolve_staff_users(info, query):\n     qs = models.User.objects.filter(is_staff=True)\n-    return filter_by_query_param(\n+    qs = filter_by_query_param(\n         queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)\n+    return qs.distinct()\n \n \n def resolve_address_validator(info, input):\ndiff --git a/saleor/graphql/account/types.py b/saleor/graphql/account/types.py\n--- a/saleor/graphql/account/types.py\n+++ b/saleor/graphql/account/types.py\n@@ -42,9 +42,7 @@\n     permissions = graphene.List(PermissionDisplay)\n \n     class Meta:\n-        exclude_fields = [\n-            'date_joined', 'password', 'is_superuser',\n-            'OrderEvent_set', 'last_login']\n+        exclude_fields = ['password', 'is_superuser', 'OrderEvent_set']\n         description = 'Represents user data.'\n         interfaces = [relay.Node]\n         model = get_user_model()\n", "issue": "User type should be able to return `created` and `lastLogin` fields\nThere is no way to obtain information when a user was registered and when she/he logged last time.\n", "before_files": [{"content": "from django.db.models import Q\nfrom i18naddress import get_validation_rules\n\nfrom ...account import models\nfrom ...core.utils import get_client_ip, get_country_by_ip\nfrom ..utils import filter_by_query_param\nfrom .types import AddressValidationData, ChoiceValue\n\nUSER_SEARCH_FIELDS = (\n    'email', 'default_shipping_address__first_name',\n    'default_shipping_address__last_name', 'default_shipping_address__city',\n    'default_shipping_address__country')\n\n\ndef resolve_customers(info, query):\n    qs = models.User.objects.filter(\n        Q(is_staff=False) | (Q(is_staff=True) & Q(orders__isnull=False))\n    ).prefetch_related('addresses')\n    return filter_by_query_param(\n        queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)\n\n\ndef resolve_staff_users(info, query):\n    qs = models.User.objects.filter(is_staff=True)\n    return filter_by_query_param(\n        queryset=qs, query=query, search_fields=USER_SEARCH_FIELDS)\n\n\ndef resolve_address_validator(info, input):\n    country_code = input['country_code']\n    if not country_code:\n        client_ip = get_client_ip(info.context)\n        country = get_country_by_ip(client_ip)\n        if country:\n            country_code = country.code\n        else:\n            return None\n    params = {\n        'country_code': country_code,\n        'country_area': input['country_area'],\n        'city_area': input['city_area']}\n    rules = get_validation_rules(params)\n\n    return AddressValidationData(\n        country_code=rules.country_code,\n        country_name=rules.country_name,\n        address_format=rules.address_format,\n        address_latin_format=rules.address_latin_format,\n        allowed_fields=rules.allowed_fields,\n        required_fields=rules.required_fields,\n        upper_fields=rules.upper_fields,\n        country_area_type=rules.country_area_type,\n        country_area_choices=[\n            ChoiceValue(area[0], area[1])\n            for area in rules.country_area_choices],\n        city_type=rules.city_type,\n        city_area_choices=[\n            ChoiceValue(area[0], area[1]) for area in rules.city_area_choices],\n        postal_code_type=rules.postal_code_type,\n        postal_code_matchers=[\n            compiled.pattern for compiled in rules.postal_code_matchers],\n        postal_code_examples=rules.postal_code_examples,\n        postal_code_prefix=rules.postal_code_prefix\n    )\n", "path": "saleor/graphql/account/resolvers.py"}, {"content": "import graphene\nfrom django.contrib.auth import get_user_model\nfrom graphene import relay\n\nfrom ...account import models\nfrom ...core.permissions import get_permissions\nfrom ..core.types.common import (\n    CountableDjangoObjectType, CountryDisplay, PermissionDisplay)\nfrom ..utils import format_permissions_for_display\n\n\nclass AddressInput(graphene.InputObjectType):\n    first_name = graphene.String(description='Given name.')\n    last_name = graphene.String(description='Family name.')\n    company_name = graphene.String(description='Company or organization.')\n    street_address_1 = graphene.String(description='Address.')\n    street_address_2 = graphene.String(description='Address.')\n    city = graphene.String(description='City.')\n    city_area = graphene.String(description='District.')\n    postal_code = graphene.String(description='Postal code.')\n    country = graphene.String(description='Country.')\n    country_area = graphene.String(description='State or province.')\n    phone = graphene.String(description='Phone number.')\n\n\nclass Address(CountableDjangoObjectType):\n    country = graphene.Field(\n        CountryDisplay, required=True, description='Default shop\\'s country')\n\n    class Meta:\n        exclude_fields = ['user_set', 'user_addresses']\n        description = 'Represents user address data.'\n        interfaces = [relay.Node]\n        model = models.Address\n\n    def resolve_country(self, info):\n        return CountryDisplay(\n            code=self.country.code, country=self.country.name)\n\n\nclass User(CountableDjangoObjectType):\n    permissions = graphene.List(PermissionDisplay)\n\n    class Meta:\n        exclude_fields = [\n            'date_joined', 'password', 'is_superuser',\n            'OrderEvent_set', 'last_login']\n        description = 'Represents user data.'\n        interfaces = [relay.Node]\n        model = get_user_model()\n        filter_fields = ['is_staff']\n\n    def resolve_permissions(self, info, **kwargs):\n        if self.is_superuser:\n            permissions = get_permissions()\n        else:\n            permissions = self.user_permissions.prefetch_related(\n                'content_type').order_by('codename')\n        return format_permissions_for_display(permissions)\n\n\nclass AddressValidationInput(graphene.InputObjectType):\n    country_code = graphene.String()\n    country_area = graphene.String()\n    city_area = graphene.String()\n\n\nclass ChoiceValue(graphene.ObjectType):\n    raw = graphene.String()\n    verbose = graphene.String()\n\n\nclass AddressValidationData(graphene.ObjectType):\n    country_code = graphene.String()\n    country_name = graphene.String()\n    address_format = graphene.String()\n    address_latin_format = graphene.String()\n    allowed_fields = graphene.List(graphene.String)\n    required_fields = graphene.List(graphene.String)\n    upper_fields = graphene.List(graphene.String)\n    country_area_type = graphene.String()\n    country_area_choices = graphene.List(ChoiceValue)\n    city_type = graphene.String()\n    city_area_choices = graphene.List(ChoiceValue)\n    postal_code_type = graphene.String()\n    postal_code_matchers = graphene.List(graphene.String)\n    postal_code_examples = graphene.List(graphene.String)\n    postal_code_prefix = graphene.String()\n", "path": "saleor/graphql/account/types.py"}]}