class events(helpers.BaseField): def resolve(self, obj, info, search=None, filter=None, **pager): qs = models.Event.objects.all() if not info.context.user.is_staff: # only staff can access old anticafe events which might include personal data (phone numbers, emails) qs = qs.exclude_anticafe_dates() if search: qs = qs.filter( title__icontains=search ) # TODO - use wagtail/elastic search instead if filter: if 'event_type' in filter: qs = qs.filter(event_type=filter['event_type']) return qs.relay_page(order='start', **pager) permissions = [permissions.manage_events] FilterInput = g.InputObjectType( 'EventsFilterInput', g.input_fields({'event_type': Optional[str]}) ) args = {**helpers.connection_args(), 'search': Optional[str], 'filter': FilterInput} result = g.NN(types.EventConnection)
class ratioCreateOrder(helpers.UnionFieldMixin, helpers.BaseFieldWithInput): def resolve(self, _, info, input): ticket_type_id = input['ticket_type_id'] try: ticket_type = models.TicketType.objects.get(uuid=ticket_type_id) except models.TicketType.DoesNotExist: return GenericError('Тип билета не найден') try: order = models.Order.objects.create_order( ticket_type=ticket_type, email=input['email'], first_name=input.get('first_name', ''), last_name=input.get('last_name', ''), city=input.get('city', ''), promocode=input.get('promocode', ''), payer_email=input.get('payer', {}).get('email', ''), payer_first_name=input.get('payer', {}).get('first_name', ''), payer_last_name=input.get('payer', {}).get('last_name', ''), ) order.full_clean() # extra precaution, make sure that order is ok except ValidationError as e: return BoxedError(e) return order result_types = { models.Order: types.RatioOrder, BoxedError: kocherga.django.schema.types.ValidationError, GenericError: kocherga.django.schema.types.GenericError, } permissions = [] # anyone can create an order PayerInput = g.InputObjectType( 'RatioCreateOrderPayerInput', g.input_fields({ 'email': str, 'first_name': str, 'last_name': str, }), ) input = { 'ticket_type_id': 'ID!', # this is uuid, TicketType's pk is hidden 'email': str, 'first_name': Optional[str], 'last_name': Optional[str], 'city': Optional[str], 'promocode': Optional[str], 'payer': PayerInput, }
class ofdShifts(helpers.BaseField): def resolve(self, _, info, filter=None, **pager): qs = models.OfdShift.objects.all() if filter: if filter.get('open_only'): qs = qs.filter(close_dt__isnull=True) return qs.relay_page(**pager) permissions = [user_perm('kkm.ofd')] FilterInput = g.InputObjectType( 'OfdShiftsFilterInput', g.input_fields({'open_only': Optional[bool]})) args = {**helpers.connection_args(), 'filter': FilterInput} result = g.NN(types.OfdShiftConnection)
class ratioTrainings(helpers.BaseField): def resolve(self, _, info, filter=None, **pager): qs = models.Training.objects.all() if filter: if 'eternal' in filter: qs = qs.filter(date__isnull=filter['eternal']) return qs.relay_page(**pager) permissions = PERMISSIONS FilterInput = g.InputObjectType( 'RatioTrainingsFilterInput', g.input_fields({'eternal': Optional[bool]})) args = {**helpers.connection_args(), 'filter': FilterInput} result = g.NN(types.RatioTrainingConnection)
class communityInitiatives(helpers.BaseField): def resolve(self, _, info, filter=None, **pager): qs = models.Initiative.objects.all() if filter: if filter.get('status'): qs = qs.filter(status=filter['status']) return qs.relay_page(**pager) permissions = [permissions.manage_crm] FilterInput = g.InputObjectType( 'CommunityInitiativesFilterInput', g.input_fields({ 'status': types.CommunityInitiativeStatus, }), ) args = {**helpers.connection_args(), 'filter': FilterInput} result = g.NN(types.CommunityInitiativeConnection)
class communityLeads(helpers.BaseField): def resolve(self, _, info, filter=None, **pager): qs = models.Lead.objects.all() if filter: if filter.get('status'): qs = qs.filter(status=filter['status']) if filter.get('curated_by_me'): qs = qs.filter(curated_by=info.context.user) if filter.get('curated_by_empty'): qs = qs.filter(curated_by__isnull=True) if filter and filter.get('search'): s = get_search_backend() nodes = list(s.search(filter['search'], qs)) return RelayConnection( pageInfo=PageInfo( hasPreviousPage=False, hasNextPage=False, startCursor='search', endCursor='search', ), nodes=nodes, edges=[{ 'node': node } for node in nodes], ) return qs.relay_page(**pager) permissions = [permissions.manage_crm] FilterInput = g.InputObjectType( 'CommunityLeadsFilterInput', g.input_fields({ 'status': types.CommunityLeadStatus, 'curated_by_me': Optional[bool], 'curated_by_empty': Optional[bool], 'search': Optional[str], }), ) args = {**helpers.connection_args(), 'filter': FilterInput} result = g.NN(types.CommunityLeadConnection)
def emailSubscribeChannelCreate(_): @check_permissions([staffonly]) def resolve(_, info, params): slug = params['slug'] interest_ids = params['interest_ids'] interests = models.MailchimpInterest.objects.filter(pk__in=interest_ids).all() instance = models.SubscribeChannel.objects.create(slug=slug) instance.interests.set(interests) return True # input EmailSubscribeChannelCreateInput { # slug: String! # interest_ids: [ID!]! # } Input = g.InputObjectType( 'EmailSubscribeChannelCreateInput', g.input_fields({'slug': str, 'interest_ids': g.NNList(g.ID)}), ) # TODO - rename params -> input return g.Field( g.Boolean, args=g.arguments({'params': g.NN(Input)}), resolve=resolve )
class ratioTickets(helpers.BaseField): def resolve(self, _, info, filter=None, **pager): qs = models.Ticket.objects.all() if filter: if filter.get('with_missing_payments', False): qs = qs.with_missing_payments() if filter.get('with_unfiscalized_checks', False): qs = qs.with_unfiscalized_checks() if filter.get('without_notion_link', False): qs = qs.without_notion_link() return qs.relay_page(**pager) permissions = PERMISSIONS FilterInput = g.InputObjectType( 'RatioTicketsFilterInput', g.input_fields({ 'with_missing_payments': Optional[bool], 'with_unfiscalized_checks': Optional[bool], 'without_notion_link': Optional[bool], }), ) args = {**helpers.connection_args(), 'filter': FilterInput} result = g.NN(types.RatioTicketConnection)
class authLogin(helpers.BaseFieldWithInput): permissions = [] # Either `token` or `email`+`password` must be set. # (GraphQL doesn't support union inputs yet; # see https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md for details.) credentials_input = g.InputObjectType( 'AuthLoginCredentialsInput', g.input_fields({ 'email': Optional[str], 'password': Optional[str], 'token': Optional[str], }), ) input = { 'credentials': g.NN(credentials_input), # Must be `cookie`; other results, e.g. `access_token` or `jwt`, might be supported later. 'result': str, } result = g.NN( g.ObjectType( 'AuthLoginResult', g.fields({ 'error': Optional[str], 'user': types.AuthCurrentUser, 'registered': Optional[bool], }), )) def resolve(self, _, info, input): credentials = input['credentials'] if 'token' not in credentials and not ('email' in credentials and 'password' in credentials): return { 'error': 'One of `token` and `email`+`password` must be set', } if input['result'] != 'cookie': return { 'error': 'Only `cookie` result is supported', } request = info.context try: user = authenticate( request, username=credentials.get('email', None), password=credentials.get('password', None), token=credentials.get('token', None), ) except django.core.exceptions.ValidationError as e: return { 'error': e.message, } if not user: logger.info('bad credentials') return { 'error': 'Некорректные учетные данные.', } login(request, user) return { 'user': user, 'registered': getattr(request, 'registered', False), }