Exemple #1
0
class TimeEntrySerializer(ContentTypeAnnotatedModelSerializer,
                          DetailAnnotatedModelSerializer):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())

    class Meta:
        model = TimeEntry
        exclude = ()
        read_only_fields = ('created_at', 'updated_at')
        details_serializer = TimeEntryDetailsSerializer
Exemple #2
0
class NestedProgressEventSerializer(ContentTypeAnnotatedModelSerializer):
    created_by = SimpleUserSerializer(required=False,
                                      read_only=True,
                                      default=CreateOnlyCurrentUserDefault())
    report = BasicProgressReportSerializer(read_only=True,
                                           required=False,
                                           source='progressreport')

    class Meta:
        model = ProgressEvent
        exclude = ('task', 'created_at')
Exemple #3
0
 def get(self, request):
     user = self.get_object(request)
     if user is None:
         return Response(
             {
                 'status': 'Unauthorized',
                 'message': 'You are not logged in'
             },
             status=status.HTTP_401_UNAUTHORIZED)
     serializer = SimpleUserSerializer(user)
     return Response(serializer.data)
Exemple #4
0
class ActivitySerializer(SimpleActivitySerializer):
    actor_type = serializers.SerializerMethodField()
    target_type = serializers.SerializerMethodField()
    actor = GenericRelatedField({
        get_user_model(): SimpleUserSerializer(),
        Integration: SimpleIntegrationSerializer()
    })
    target = GenericRelatedField({
        get_user_model():
        SimpleUserSerializer(),
        Comment:
        CommentSerializer(),
        Connection:
        ConnectionSerializer(),
        Task:
        SimpleTaskSerializer(),
        Application:
        ApplicationSerializer(),
        Participation:
        ParticipationSerializer(),
        TaskRequest:
        TaskRequestSerializer(),
        ProgressEvent:
        SimpleProgressEventSerializer(),
        ProgressReport:
        SimpleProgressReportSerializer(),
        Integration:
        SimpleIntegrationSerializer(),
        IntegrationActivity:
        SimpleIntegrationActivitySerializer()
    })

    class Meta(SimpleActivitySerializer.Meta):
        pass

    def get_actor_type(self, obj):
        return get_instance_type(obj.actor)

    def get_target_type(self, obj):
        return get_instance_type(obj.target)
class MessageSerializer(serializers.ModelSerializer,
                        GetCurrentUserAnnotatedSerializerMixin):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())
    excerpt = serializers.CharField(required=False, read_only=True)
    attachments = SimpleAttachmentSerializer(read_only=True,
                                             required=False,
                                             many=True)

    class Meta:
        model = Message
        read_only_fields = ('created_at', )
Exemple #6
0
class ProgressEventSerializer(ContentTypeAnnotatedModelSerializer,
                              DetailAnnotatedModelSerializer):
    created_by = SimpleUserSerializer(required=False,
                                      read_only=True,
                                      default=CreateOnlyCurrentUserDefault())
    report = SimpleProgressReportSerializer(read_only=True,
                                            required=False,
                                            source='progressreport')

    class Meta:
        model = ProgressEvent
        exclude = ()
        read_only_fields = ('created_at', )
        details_serializer = ProgressEventDetailsSerializer
Exemple #7
0
class TaskDetailsSerializer(ContentTypeAnnotatedModelSerializer):
    project = SimpleProjectSerializer()
    user = SimpleUserSerializer()
    skills = SkillSerializer(many=True)
    assignee = SimpleParticipationSerializer(required=False, read_only=True)
    applications = SimpleApplicationSerializer(many=True,
                                               source='application_set')
    participation = SimpleParticipationSerializer(many=True,
                                                  source='participation_set')

    class Meta:
        model = Task
        fields = ('project', 'user', 'skills', 'assignee', 'applications',
                  'participation')
Exemple #8
0
class MessageSerializer(serializers.ModelSerializer,
                        GetCurrentUserAnnotatedSerializerMixin):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())
    excerpt = serializers.CharField(required=False, read_only=True)
    attachments = UploadSerializer(read_only=True, required=False, many=True)
    sender = SenderSerializer(read_only=True, required=False)
    html_body = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = Message
        exclude = ('alt_user', 'source', 'extra')
        read_only_fields = ('created_at', )
Exemple #9
0
class ProgressReportSerializer(ContentTypeAnnotatedModelSerializer,
                               DetailAnnotatedModelSerializer):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())
    status_display = serializers.CharField(required=False,
                                           read_only=True,
                                           source='get_status_display')
    uploads = UploadSerializer(required=False, read_only=True, many=True)

    class Meta:
        model = ProgressReport
        exclude = ()
        read_only_fields = ('created_at', )
        details_serializer = ProgressReportDetailsSerializer
class BlogPostSerializer(serializers.ModelSerializer):
    created_by = SimpleUserSerializer(required=False,
                                      read_only=True,
                                      default=CreateOnlyCurrentUserDefault())

    class Meta:
        model = BlogPost
        fields = '__all__'
        extra_kwargs = {
            'slug': {
                'required': False,
                'allow_blank': True,
                'allow_null': True
            },
        }
Exemple #11
0
class ProjectSerializer(ContentTypeAnnotatedModelSerializer,
                        DetailAnnotatedModelSerializer):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())
    excerpt = serializers.CharField(required=False, read_only=True)
    deadline = serializers.DateTimeField(required=False, allow_null=True)
    tasks = serializers.PrimaryKeyRelatedField(required=False,
                                               read_only=True,
                                               many=True)

    class Meta:
        model = Project
        exclude = ()
        read_only_fields = ('created_at', )
        details_serializer = ProjectDetailsSerializer
class SimpleActivitySerializer(serializers.ModelSerializer):
    action = serializers.CharField(source='verb')
    activity_type = serializers.SerializerMethodField()
    activity = GenericRelatedField(
        {
            get_user_model(): SimpleUserSerializer(),
            Channel: ChannelSerializer(),
            ChannelUser: ChannelUserSerializer(),
            Message: MessageSerializer(),
            Comment: CommentSerializer(),
            LegacyUpload: LegacyUploadSerializer(),
            Connection: ConnectionSerializer(),
            Task: SimpleTaskSerializer(),
            Application: ApplicationSerializer(),
            LegacyParticipation: LegacyParticipationSerializer(),
            Estimate: SimpleEstimateSerializer(),
            Quote: SimpleQuoteSerializer(),
            Sprint: SimpleSprintSerializer(),
            LegacyProgressEvent: LegacySimpleProgressEventSerializer(),
            LegacyProgressReport: LegacyProgressReportSerializer(),
            Integration: SimpleIntegrationSerializer(),
            IntegrationActivity: SimpleIntegrationActivitySerializer(),
            Project: ProjectSerializer(),
            Document: DocumentSerializer(),
            Participation: ParticipationSerializer(),
            ProgressEvent: ProgressEventSerializer(),
            ProgressReport: ProgressReportSerializer(),
            Invoice: InvoiceSerializer(),
            Payment: PaymentSerializer(),
            Upload: UploadSerializer(),
            FieldChangeLog: FieldChangeLogSerializer(),
        },
        source='action_object')

    class Meta:
        model = Action
        exclude = ('verb', 'actor_object_id', 'actor_content_type',
                   'action_object_object_id', 'action_object_content_type',
                   'target_object_id', 'target_content_type')

    def get_activity_type(self, obj):
        return get_instance_type(obj.action_object)
Exemple #13
0
class ParticipationSerializer(ContentTypeAnnotatedModelSerializer,
                              DetailAnnotatedModelSerializer):
    created_by = SimpleUserSerializer(required=False,
                                      read_only=True,
                                      default=CreateOnlyCurrentUserDefault())

    class Meta:
        model = Participation
        exclude = ()
        read_only_fields = ('created_at', )
        details_serializer = ParticipationDetailsSerializer

    def update(self, instance, validated_data):
        initial_responded = instance.responded
        if validated_data.get('accepted'):
            validated_data['responded'] = True
            validated_data['activated_at'] = datetime.datetime.utcnow()
        instance = super(ParticipationSerializer,
                         self).update(instance, validated_data)
        if not initial_responded and instance.accepted or instance.responded:
            participation_response.send(sender=Participation,
                                        participation=instance)
        return instance
Exemple #14
0
class ApplicationSerializer(ContentTypeAnnotatedModelSerializer,
                            DetailAnnotatedModelSerializer):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())

    class Meta:
        model = Application
        exclude = ()
        details_serializer = ApplicationDetailsSerializer
        extra_kwargs = {
            'pitch': {
                'required': True,
                'allow_blank': False,
                'allow_null': False
            },
            'hours_needed': {
                'required': True,
                'allow_null': False
            },
            #'hours_available': {'required': True, 'allow_null': False},
            'deliver_at': {
                'required': True,
                'allow_null': False
            }
        }

    def update(self, instance, validated_data):
        initial_responded = instance.responded
        if validated_data.get('accepted'):
            validated_data['responded'] = True
        instance = super(ApplicationSerializer,
                         self).update(instance, validated_data)
        if not initial_responded and instance.accepted or instance.responded:
            application_response.send(sender=Application, application=instance)
        return instance
Exemple #15
0
class ChannelSerializer(DetailAnnotatedModelSerializer,
                        GetCurrentUserAnnotatedSerializerMixin):
    created_by = SimpleUserSerializer(required=False,
                                      read_only=True,
                                      default=CreateOnlyCurrentUserDefault())
    display_type = serializers.CharField(required=False,
                                         read_only=True,
                                         source='get_type_display')
    participants = serializers.PrimaryKeyRelatedField(
        required=True, many=True, queryset=get_user_model().objects.all())
    attachments = UploadSerializer(read_only=True,
                                   required=False,
                                   many=True,
                                   source='all_attachments')
    user = serializers.SerializerMethodField(read_only=True, required=False)
    new_messages = serializers.IntegerField(read_only=True, required=False)
    new = serializers.SerializerMethodField(read_only=True, required=False)
    last_read = serializers.SerializerMethodField(read_only=True,
                                                  required=False)
    alt_subject = serializers.CharField(required=False,
                                        read_only=True,
                                        source='get_alt_subject')

    class Meta:
        model = Channel
        exclude = ()
        read_only_fields = ('created_at', 'type')
        details_serializer = ChannelDetailsSerializer

    def validate_participants(self, value):
        error = 'Select some participants for this conversation'
        if not isinstance(value, list) or not value:
            raise ValidationError(error)
        participants = self.clean_participants(value)
        if not participants:
            raise ValidationError(error)
        return value

    def create(self, validated_data):
        participants = None
        if 'participants' in validated_data:
            participants = validated_data.pop('participants')
        participants = self.clean_participants(participants)
        subject = validated_data.get('subject', None)
        if not subject and isinstance(participants,
                                      list) and len(participants) == 1:
            # Create or get a direct channel
            # if only one other participant is given and no subject is stated for the communication
            current_user = self.get_current_user()
            channel = get_or_create_direct_channel(current_user,
                                                   participants[0])
        else:
            #if not subject:
            #    raise ValidationError({'subject': 'Enter a subject for this conversation'})
            channel = Channel.objects.create(**validated_data)
        self.save_participants(channel, participants)
        return channel

    def update(self, instance, validated_data):
        participants = None
        if 'participants' in validated_data:
            participants = validated_data.pop('participants')
        participants = self.clean_participants(participants)
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        subject = validated_data.get('subject', None)
        if not subject and isinstance(participants,
                                      list) and len(participants) > 1:
            raise ValidationError(
                {'subject': 'Enter a subject for this conversation'})
        instance.save()
        self.save_participants(instance, participants)
        return instance

    def clean_participants(self, participants):
        current_user = self.get_current_user()
        if isinstance(participants, (list, tuple)) and current_user:
            return [
                user_id for user_id in participants
                if user_id != current_user.id
            ]
        return participants

    def save_participants(self, instance, participants):
        if participants:
            participants.append(instance.created_by)
            for user in participants:
                try:
                    ChannelUser.objects.update_or_create(channel=instance,
                                                         user=user)
                except:
                    pass

    def get_user(self, obj):
        current_user = self.get_current_user()
        if current_user:
            receiver = obj.get_receiver(current_user)
            if receiver:
                return SimpleUserSerializer(receiver).data
        return None

    def get_new(self, obj):
        user = self.get_current_user()
        if user:
            return channel_activity_new_messages_filter(
                queryset=obj.target_actions.filter(
                    channels__channeluser__user=user),
                user=user).count()
        return 0

    def get_last_read(self, obj):
        user = self.get_current_user()
        if user:
            try:
                return obj.channeluser_set.get(user=user).last_read
            except:
                pass
        else:
            return obj.last_read
        return 0
Exemple #16
0
class ChannelDetailsSerializer(serializers.ModelSerializer):
    participants = SimpleUserSerializer(many=True)

    class Meta:
        model = Channel
        fields = ('participants', )
Exemple #17
0
class TaskSerializer(ContentTypeAnnotatedModelSerializer,
                     DetailAnnotatedModelSerializer,
                     GetCurrentUserAnnotatedSerializerMixin):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())
    pay = serializers.DecimalField(max_digits=19,
                                   decimal_places=4,
                                   required=False,
                                   read_only=True)
    display_fee = serializers.SerializerMethodField(required=False,
                                                    read_only=True)
    amount = serializers.JSONField(required=False, read_only=True)
    is_payable = serializers.BooleanField(required=False, read_only=True)
    is_project = serializers.BooleanField(required=False, read_only=True)
    is_task = serializers.BooleanField(required=False, read_only=True)
    is_developer_ready = serializers.BooleanField(required=False,
                                                  read_only=True)
    requires_estimate = serializers.BooleanField(required=False,
                                                 read_only=True)
    excerpt = serializers.CharField(required=False, read_only=True)
    skills = serializers.CharField(
        required=False,
        error_messages={
            'blank': 'Please specify the skills required for this task'
        })
    payment_status = serializers.CharField(required=False, read_only=True)
    deadline = serializers.DateTimeField(required=False, allow_null=True)
    can_apply = serializers.SerializerMethodField(read_only=True,
                                                  required=False)
    can_claim = serializers.SerializerMethodField(read_only=True,
                                                  required=False)
    can_return = serializers.SerializerMethodField(read_only=True,
                                                   required=False)
    can_save = serializers.SerializerMethodField(read_only=True,
                                                 required=False)
    is_participant = serializers.SerializerMethodField(read_only=True,
                                                       required=False)
    is_admin = serializers.SerializerMethodField(read_only=True,
                                                 required=False)
    my_participation = serializers.SerializerMethodField(read_only=True,
                                                         required=False)
    summary = serializers.CharField(read_only=True, required=False)
    assignee = SimpleParticipationSerializer(required=False, read_only=True)
    participants = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=get_user_model().objects.all(),
        required=False,
        write_only=True)
    update_schedule_display = serializers.CharField(required=False,
                                                    read_only=True)
    participation = NestedTaskParticipationSerializer(required=False,
                                                      read_only=False,
                                                      many=True)
    milestones = NestedProgressEventSerializer(required=False,
                                               read_only=False,
                                               many=True)
    progress_events = NestedProgressEventSerializer(required=False,
                                                    read_only=True,
                                                    many=True)
    ratings = SimpleRatingSerializer(required=False,
                                     read_only=False,
                                     many=True)
    uploads = UploadSerializer(required=False, read_only=True, many=True)
    all_uploads = UploadSerializer(required=False, read_only=True, many=True)
    invoice = TaskInvoiceSerializer(required=False, read_only=True)
    estimate = SimpleEstimateSerializer(required=False, read_only=True)
    quote = SimpleQuoteSerializer(required=False, read_only=True)
    pm = SimpleUserSerializer(required=False, read_only=True)

    class Meta:
        model = Task
        exclude = ('applicants', )
        read_only_fields = ('created_at', 'paid', 'paid_at', 'invoice_date',
                            'btc_address', 'btc_price', 'pay_distributed')
        extra_kwargs = {
            'type': {
                'required': True,
                'allow_blank': False,
                'allow_null': False
            },
            'scope': {
                'required': True,
                'allow_blank': False,
                'allow_null': False
            }
        }
        details_serializer = TaskDetailsSerializer

    def validate(self, attrs):
        has_parent = attrs.get('parent', None) or (self.instance
                                                   and self.instance.parent)
        scope = attrs.get('scope', None) or (self.instance
                                             and self.instance.scope)
        is_project = attrs.get(
            'is_project', None) or (self.instance and self.instance.is_project)
        has_requirements = attrs.get(
            'is_project', None) or (self.instance
                                    and self.instance.has_requirements)
        coders_needed = attrs.get('coders_needed', None)
        pm_required = attrs.get('pm_required', None)

        fee = attrs.get('fee', None)
        title = attrs.get('title', None)
        skills = attrs.get('skills', None)
        visibility = attrs.get('visibility', None)

        description = attrs.get('description', None)
        email = self.initial_data.get('email', None)
        first_name = self.initial_data.get('first_name', None)
        last_name = self.initial_data.get('last_name', None)

        current_user = self.get_current_user()

        errors = dict()

        if current_user and current_user.is_authenticated():
            if scope == TASK_SCOPE_TASK or has_parent:
                if not has_parent and fee:
                    MinValueValidator(
                        15, message='Minimum pledge amount is EUR 15')(fee)
                if not title and not self.partial:
                    errors.update({'title': 'This field is required.'})
                if not description and not self.partial:
                    errors.update({'description': 'This field is required.'})
                if not skills and not self.partial:
                    errors.update({'skills': 'This field is required.'})
                if visibility == VISIBILITY_CUSTOM and not (
                        attrs.get('participation', None)
                        or attrs.get('participants', None)):
                    errors.update({
                        'visibility':
                        'Please choose at least one developer for this task'
                    })
                if scope == TASK_SCOPE_TASK and description and self.partial and len(
                        description.split(' ')) <= 15:
                    errors.update({
                        'description':
                        'Please provide a more detailed description.'
                    })

            if scope == TASK_SCOPE_ONGOING:
                if not skills and not self.partial:
                    errors.update({'skills': 'This field is required.'})
                if not coders_needed and not self.partial:
                    errors.update({'coders_needed': 'This field is required.'})
            if scope == TASK_SCOPE_PROJECT:
                if not title and not self.partial:
                    errors.update({'title': 'This field is required.'})
                if not skills and not self.partial:
                    errors.update({'skills': 'This field is required.'})
                if not pm_required and not self.partial:
                    errors.update({'pm_required': 'This field is required.'})
        else:
            if not description:
                errors.update({'description': 'This field is required.'})
            if email:
                try:
                    get_user_model().objects.get(email=email)
                    errors.update({
                        'form':
                        'Looks like you already have a Tunga account. Please login to create new tasks.',
                        'email':
                        'This email address is already attached to an account on Tunga'
                    })
                except get_user_model().DoesNotExist:
                    pass
            else:
                errors.update({'email': 'This field is required.'})
            if not first_name:
                errors.update({'first_name': 'This field is required.'})
            if not last_name:
                errors.update({'last_name': 'This field is required.'})

        if errors:
            raise ValidationError(errors)

        return attrs

    def save_task(self, validated_data, instance=None):
        current_user = self.get_current_user()
        if current_user and current_user.is_authenticated(
        ) and not instance and not profile_check(current_user):
            ValidationError(
                'You need complete your profile before you can post tasks')

        if instance and 'fee' in validated_data and validated_data[
                'fee'] < instance.fee:
            raise ValidationError({
                'fee':
                'You cannot reduce the fee for the task, Please contact [email protected] for assistance'
            })

        skills = None
        participation = None
        milestones = None
        participants = None
        ratings = None
        if 'skills' in validated_data:
            skills = validated_data.pop('skills')
        if 'participation' in validated_data:
            participation = validated_data.pop('participation')
        if 'milestones' in validated_data:
            milestones = validated_data.pop('milestones')
        if 'participants' in validated_data:
            participants = validated_data.pop('participants')
        if 'ratings' in validated_data:
            ratings = validated_data.pop('ratings')

        initial_apply = True
        initial_closed = False
        initial_approved = False
        new_user = None
        is_update = bool(instance)

        if instance:
            initial_apply = instance.apply
            initial_closed = instance.closed
            initial_approved = instance.approved

            if not instance.closed and validated_data.get('closed'):
                validated_data['closed_at'] = datetime.datetime.utcnow()

            if not instance.paid and validated_data.get('paid'):
                validated_data['paid_at'] = datetime.datetime.utcnow()
            instance = super(TaskSerializer,
                             self).update(instance, validated_data)
        else:
            if not current_user or not current_user.is_authenticated():
                validated_data['source'] = TASK_SOURCE_NEW_USER
            if participation or participants:
                # Close applications if paticipants are provided when creating task
                validated_data['apply'] = False
                validated_data['apply_closed_at'] = datetime.datetime.utcnow()

            if not current_user or not current_user.is_authenticated():
                # Create user and add them as the creator or task, indicate if task was unauthenticated
                email = self.initial_data.get('email', None)
                first_name = self.initial_data.get('first_name', None)
                last_name = self.initial_data.get('last_name', None)

                new_user = get_user_model().objects.create_user(
                    username=email,
                    email=email,
                    password=get_user_model().objects.make_random_password(),
                    first_name=first_name,
                    last_name=last_name,
                    type=USER_TYPE_PROJECT_OWNER,
                    source=USER_SOURCE_TASK_WIZARD)
                if new_user:
                    validated_data.update({'user': new_user})
                    user_signed_up.send(sender=get_user_model(),
                                        request=None,
                                        user=new_user)

            instance = super(TaskSerializer, self).create(validated_data)

        self.save_skills(instance, skills)
        self.save_participants(instance, participants)
        self.save_participation(instance, participation)
        self.save_milestones(instance, milestones)
        self.save_ratings(instance, ratings)

        if is_update:
            if not initial_approved and instance.approved:
                task_approved.send(sender=Task, task=instance)

            if initial_apply and not instance.apply:
                task_applications_closed.send(sender=Task, task=instance)

            if not initial_closed and instance.closed:
                task_closed.send(sender=Task, task=instance)
        else:
            # Triggered here instead of in the post_save signal to allow skills to be attached first
            # TODO: Consider moving this trigger
            notify_new_task.delay(instance.id, new_user=bool(new_user))
        return instance

    def create(self, validated_data):
        return self.save_task(validated_data)

    def update(self, instance, validated_data):
        return self.save_task(validated_data, instance=instance)

    def save_skills(self, task, skills):
        if skills is not None:
            task.skills = skills
            task.save()

    def save_participation(self, task, participation):
        if participation:
            new_assignee = None
            for item in participation:
                if 'accepted' in item and item.get('accepted', False):
                    item['activated_at'] = datetime.datetime.utcnow()
                defaults = item
                if isinstance(defaults, dict):
                    current_user = self.get_current_user()
                    participation_creator = task.user
                    if current_user and current_user.is_authenticated(
                    ) and current_user != item.get('user', None):
                        participation_creator = current_user
                    defaults['created_by'] = participation_creator

                try:
                    participation_obj, created = Participation.objects.update_or_create(
                        task=task, user=item['user'], defaults=defaults)
                    if (not created) and 'accepted' in item:
                        participation_response.send(
                            sender=Participation,
                            participation=participation_obj)
                    if 'assignee' in item and item['assignee']:
                        new_assignee = item['user']
                except:
                    pass
            if new_assignee:
                Participation.objects.exclude(user=new_assignee).filter(
                    task=task).update(assignee=False)

    def save_milestones(self, task, milestones):
        if milestones:
            for item in milestones:
                event_type = item.get('type', PROGRESS_EVENT_TYPE_MILESTONE)
                if event_type != PROGRESS_EVENT_TYPE_MILESTONE:
                    continue
                defaults = {'created_by': self.get_current_user() or task.user}
                defaults.update(item)
                try:
                    ProgressEvent.objects.update_or_create(
                        task=task,
                        type=event_type,
                        due_at=item['due_at'],
                        defaults=defaults)
                except:
                    pass

    def save_ratings(self, task, ratings):
        if ratings:
            for item in ratings:
                try:
                    Rating.objects.update_or_create(
                        content_type=ContentType.objects.get_for_model(task),
                        object_id=task.id,
                        criteria=item['criteria'],
                        defaults=item)
                except:
                    pass

    def save_participants(self, task, participants):
        # TODO: Remove and move existing code to using save_participation
        if participants:
            assignee = self.initial_data.get('assignee', None)
            confirmed_participants = self.initial_data.get(
                'confirmed_participants', None)
            rejected_participants = self.initial_data.get(
                'rejected_participants', None)
            created_by = self.get_current_user() or task.user

            changed_assignee = False
            for user in participants:
                try:
                    defaults = {'created_by': created_by}
                    if assignee:
                        defaults['assignee'] = bool(user.id == assignee)
                    if rejected_participants and user.id in rejected_participants:
                        defaults['accepted'] = False
                        defaults['responded'] = True
                    if confirmed_participants and user.id in confirmed_participants:
                        defaults['accepted'] = True
                        defaults['responded'] = True
                        defaults['activated_at'] = datetime.datetime.utcnow()

                    participation_obj, created = Participation.objects.update_or_create(
                        task=task, user=user, defaults=defaults)
                    if (not created) and (user.id in rejected_participants or
                                          user.id in confirmed_participants):
                        participation_response.send(
                            sender=Participation,
                            participation=participation_obj)
                    if user.id == assignee:
                        changed_assignee = True
                except:
                    pass
            if assignee and changed_assignee:
                Participation.objects.exclude(user__id=assignee).filter(
                    task=task).update(assignee=False)

    def get_display_fee(self, obj):
        user = self.get_current_user()
        amount = None
        if not obj.pay:
            return None
        if user and user.is_developer:
            amount = obj.pay_dev * (1 - obj.tunga_ratio_dev)
        return obj.display_fee(amount=amount)

    def get_can_apply(self, obj):
        if obj.closed or not obj.apply or not obj.is_developer_ready:
            return False
        user = self.get_current_user()
        if user:
            if obj.user == user or not user.is_developer or user.pending or not profile_check(
                    user):
                return False
            return obj.applicants.filter(id=user.id).count() == 0 and \
                   obj.participation_set.filter(user=user).count() == 0
        return False

    def get_can_claim(self, obj):
        if obj.closed or obj.is_task:
            return False
        user = self.get_current_user()
        if user and user.is_authenticated() and (
                user.is_project_manager or user.is_admin) and not obj.pm and (
                    obj.pm_required or obj.source == TASK_SOURCE_NEW_USER):
            return True
        return False

    def get_can_return(self, obj):
        if obj.closed or obj.estimate:
            return False
        user = self.get_current_user()
        if user and user.is_authenticated() and obj.pm == user:
            return True
        return False

    def get_can_save(self, obj):
        return False

    def get_is_participant(self, obj):
        user = self.get_current_user()
        if user:
            return obj.subtask_participants_inclusive_filter.filter(
                (Q(accepted=True) | Q(responded=False)), user=user).count() > 0
        return False

    def get_is_admin(self, obj):
        user = self.get_current_user()
        return obj.has_admin_access(user)

    def get_my_participation(self, obj):
        user = self.get_current_user()
        if user:
            try:
                participation = obj.participation_set.get(user=user)
                return {
                    'id': participation.id,
                    'user': participation.user.id,
                    'assignee': participation.assignee,
                    'accepted': participation.accepted,
                    'responded': participation.responded
                }
            except:
                pass
        return None
Exemple #18
0
class SimpleChannelSerializer(serializers.ModelSerializer):
    created_by = SimpleUserSerializer()

    class Meta:
        model = Channel
        exclude = ('participants', )
Exemple #19
0
class ProfileDetailsSerializer(SimpleProfileSerializer):
    user = SimpleUserSerializer()

    class Meta:
        model = UserProfile
        fields = ('user', 'city', 'skills')
Exemple #20
0
class TungaTokenSerializer(TokenSerializer):
    user = SimpleUserSerializer(read_only=True, required=False)

    class Meta:
        model = TokenSerializer.Meta.model
        fields = ('key', 'user')
Exemple #21
0
class SimpleApplicationSerializer(ContentTypeAnnotatedModelSerializer):
    user = SimpleUserSerializer()

    class Meta:
        model = Application
        exclude = ('created_at', )
Exemple #22
0
class AbstractEstimateSerializer(ContentTypeAnnotatedModelSerializer,
                                 DetailAnnotatedModelSerializer,
                                 GetCurrentUserAnnotatedSerializerMixin):
    user = SimpleUserSerializer(required=False,
                                read_only=True,
                                default=CreateOnlyCurrentUserDefault())
    moderated_by = SimpleUserSerializer(required=False, read_only=True)
    activities = NestedWorkActivitySerializer(required=True,
                                              read_only=False,
                                              many=True)

    class Meta:
        model = AbstractEstimate
        fields = '__all__'
        read_only_fields = ('submitted_at', 'moderated_at', 'reviewed_at',
                            'created_at', 'updated_at')
        details_serializer = AbstractEstimateDetailsSerializer

    def validate_activities(self, value):
        if not value:
            raise ValidationError('This field is required')
        return value

    def pop_related_objects(self, validated_data, instance=None):
        self.activities = None
        if 'activities' in validated_data:
            self.activities = validated_data.pop('activities')

    def save_related_objects(self, instance):
        self.save_activities(instance, self.activities)

    def on_create_complete(self, instance):
        pass

    def on_status_change(self, instance):
        pass

    def save_estimate(self, validated_data, instance=None):
        self.pop_related_objects(validated_data, instance)

        initial_status = STATUS_INITIAL
        is_update = bool(instance)

        if is_update:
            initial_status = instance.status

            # Clone new estimate if previous was declined or rejected and reset useful defaults
            if instance.status in [STATUS_DECLINED, STATUS_REJECTED]:
                instance.pk = None
                instance.status = STATUS_INITIAL
                instance.moderated_by = None
                instance.moderated_at = None
                instance.reviewed_by = None
                instance.moderated_at = None
                instance.save()

            if initial_status != validated_data.get('status'):
                if validated_data.get('status') == STATUS_SUBMITTED:
                    validated_data['submitted_at'] = datetime.datetime.utcnow()
                if validated_data.get('status') in [
                        STATUS_APPROVED, STATUS_DECLINED
                ]:
                    validated_data['moderated_by'] = self.get_current_user(
                    ) or None
                    validated_data['moderated_at'] = datetime.datetime.utcnow()
                if validated_data.get('status') in [
                        STATUS_ACCEPTED, STATUS_REJECTED
                ]:
                    validated_data['reviewed_by'] = self.get_current_user(
                    ) or None
                    validated_data['reviewed_at'] = datetime.datetime.utcnow()

            instance = super(AbstractEstimateSerializer,
                             self).update(instance, validated_data)
        else:
            instance = super(AbstractEstimateSerializer,
                             self).create(validated_data)

        self.save_related_objects(instance)

        if is_update:
            if initial_status != instance.status:
                self.on_status_change(instance)
        else:
            # Triggered here instead of in the post_save signal to allow related objects to be attached first
            self.on_create_complete(instance)

        return instance

    def create(self, validated_data):
        return self.save_estimate(validated_data)

    def update(self, instance, validated_data):
        return self.save_estimate(validated_data, instance=instance)

    def save_activities(self, instance, activities):
        if activities:
            c_type = ContentType.objects.get_for_model(self.Meta.model)
            # Delete existing
            WorkActivity.objects.filter(content_type=c_type,
                                        object_id=instance.id).delete()
            for item in activities:
                try:
                    item['content_type'] = c_type
                    item['object_id'] = instance.id
                    item['user'] = self.get_current_user()
                    WorkActivity.objects.create(**item)
                except:
                    pass
Exemple #23
0
class IntegrationSerializer(ContentTypeAnnotatedModelSerializer,
                            GetCurrentUserAnnotatedSerializerMixin):
    created_by = SimpleUserSerializer(required=False,
                                      read_only=True,
                                      default=CreateOnlyCurrentUserDefault())
    events = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=IntegrationEvent.objects.all(),
        required=False,
        read_only=False)
    meta = NestedIntegrationMetaSerializer(required=False,
                                           read_only=False,
                                           many=True,
                                           source='integrationmeta_set')

    # Write Only
    repo = serializers.JSONField(required=False,
                                 write_only=True,
                                 allow_null=True)
    issue = serializers.JSONField(required=False,
                                  write_only=True,
                                  allow_null=True)
    project = serializers.JSONField(required=False,
                                    write_only=True,
                                    allow_null=True)
    team = serializers.JSONField(required=False,
                                 write_only=True,
                                 allow_null=True)
    channel = serializers.JSONField(required=False,
                                    write_only=True,
                                    allow_null=True)

    # Read Only
    repo_id = serializers.CharField(required=False, read_only=True)
    issue_id = serializers.CharField(required=False, read_only=True)
    project_id = serializers.CharField(required=False, read_only=True)
    project_task_id = serializers.CharField(required=False, read_only=True)
    team_id = serializers.CharField(required=False, read_only=True)
    team_name = serializers.CharField(required=False, read_only=True)
    channel_id = serializers.CharField(required=False, read_only=True)
    channel_name = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = Integration
        exclude = ('secret', )
        read_only_fields = ('created_at', 'updated_at')

    def send_creation_signal(self, instance):
        task_integration.send(sender=Integration, integration=instance)

    def save_integration(self, validated_data, instance=None):
        events = None
        if 'events' in validated_data:
            events = validated_data.pop('events')
        meta = None
        if 'meta' in validated_data:
            meta = validated_data.pop('meta')
        metadata_objects = dict()
        metadata_keys = ['repo', 'issue', 'project', 'team', 'channel']
        for key in metadata_keys:
            if key in validated_data:
                metadata_objects[key] = validated_data.pop(key)

        if instance:
            instance = super(IntegrationSerializer,
                             self).update(instance, validated_data)
        else:
            instance = super(IntegrationSerializer,
                             self).create(validated_data)
        self.save_events(instance, events)
        self.save_meta(instance, meta)
        for key in metadata_keys:
            self.save_meta_object(instance, metadata_objects.get(key, None),
                                  key)

        self.send_creation_signal(instance)
        return instance

    def create(self, validated_data):
        return self.save_integration(validated_data)

    def update(self, instance, validated_data):
        return self.save_integration(validated_data, instance=instance)

    def save_events(self, instance, events):
        if events:
            instance.events.clear()
            for item in events:
                try:
                    instance.events.add(item)
                except:
                    pass

    def save_meta(self, instance, meta):
        if meta:
            for item in meta:
                defaults = {
                    'created_by': self.get_current_user() or instance.user
                }
                defaults.update(item)
                try:
                    IntegrationMeta.objects.update_or_create(
                        integration=instance,
                        meta_key=item['meta_key'],
                        defaults=defaults)
                except:
                    pass

    def save_meta_object(self, instance, meta_object, prefix):
        if meta_object:
            for key in meta_object:
                defaults = {
                    'created_by': self.get_current_user() or instance.user,
                    'meta_key': '%s_%s' % (prefix, key),
                    'meta_value': clean_meta_value(meta_object[key])
                }
                try:
                    IntegrationMeta.objects.update_or_create(
                        integration=instance,
                        meta_key=defaults['meta_key'],
                        defaults=defaults)
                except:
                    pass
Exemple #24
0
class SimpleProjectSerializer(ContentTypeAnnotatedModelSerializer):
    user = SimpleUserSerializer()

    class Meta:
        model = Project
 def get_user(self, obj):
     return SimpleUserSerializer(obj.user).data
Exemple #26
0
class SimpleParticipationSerializer(BasicParticipationSerializer):
    user = SimpleUserSerializer()

    class Meta:
        model = Participation
        exclude = ('created_at', )
Exemple #27
0
class BasicProgressEventSerializer(ContentTypeAnnotatedModelSerializer):
    created_by = SimpleUserSerializer()

    class Meta:
        model = ProgressEvent
        fields = '__all__'