Exemple #1
0
class InterestPollSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    project = SimpleProjectSerializer()
    user = SimplestUserSerializer()

    class Meta:
        model = InterestPoll
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')

    def nested_save_override(self, validated_data, instance=None):
        initial_status = None
        initial_approval_status = None

        if instance:
            initial_status = instance.status
            initial_approval_status = instance.approval_status

        instance = super(InterestPollSerializer, self).nested_save_override(validated_data, instance=instance)

        if instance:
            if initial_status != instance.status:
                post_field_update.send(sender=InterestPoll, instance=instance, field='status')
            if initial_approval_status != instance.approval_status:
                post_field_update.send(sender=InterestPoll, instance=instance, field='approval_status')
        return instance
Exemple #2
0
class SimpleInterestPollSerializer(SimpleModelSerializer):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    user = SimplestUserSerializer()

    class Meta:
        model = InterestPoll
        exclude = ('project',)
Exemple #3
0
class ConnectionSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer):
    from_user = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    to_user = SimplestUserSerializer(required=False, read_only=False)

    class Meta:
        model = Connection
        fields = '__all__'
Exemple #4
0
class InvoiceSerializer(NestedModelSerializer,
                        ContentTypeAnnotatedModelSerializer):
    created_by = SimplestUserSerializer(required=False,
                                        read_only=True,
                                        default=CreateOnlyCurrentUserDefault())
    updated_by = SimplestUserSerializer(required=False,
                                        read_only=True,
                                        default=CurrentUserDefault())
    project = NestedProjectSerializer()
    user = SimplestUserSerializer()
    full_title = serializers.CharField(read_only=True)
    milestone = SimpleProgressEventSerializer(required=False, allow_null=True)
    tax_amount = serializers.DecimalField(max_digits=17,
                                          decimal_places=2,
                                          read_only=True)
    subtotal = serializers.DecimalField(max_digits=17,
                                        decimal_places=2,
                                        read_only=True)
    total_amount = serializers.DecimalField(max_digits=17,
                                            decimal_places=2,
                                            read_only=True)
    download_url = serializers.CharField(read_only=True)
    due_at = serializers.DateTimeField(read_only=True)
    is_overdue = serializers.BooleanField(read_only=True)

    class Meta:
        model = Invoice
        fields = '__all__'
Exemple #5
0
class NestedProjectSerializer(SimpleModelSerializer):
    user = SimplestUserSerializer(required=False, read_only=True)
    owner = SimplestUserSerializer(required=False, read_only=True)
    pm = SimplestUserSerializer(required=False, read_only=True)

    class Meta:
        model = Project
        fields = '__all__'
Exemple #6
0
class ParticipationSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    project = SimpleProjectSerializer()
    user = SimplestUserSerializer()

    class Meta:
        model = Participation
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')
Exemple #7
0
class ProjectSerializer(
    NestedModelSerializer, ContentTypeAnnotatedModelSerializer, GetCurrentUserAnnotatedSerializerMixin
):
    user = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    owner = SimplestUserSerializer(required=False, allow_null=True)
    pm = SimplestUserSerializer(required=False, allow_null=True)
    skills = SimpleSkillSerializer(required=False, many=True)
    participation = SimpleParticipationSerializer(required=False, many=True, source='participation_set')
    documents = SimpleDocumentSerializer(required=False, many=True, source='document_set')
    progress_events = SimpleProgressEventSerializer(required=False, many=True, source='progressevent_set')
    meta = SimpleProjectMetaSerializer(required=False, many=True, source='projectmeta_set')
    change_log = serializers.JSONField(required=False, write_only=True)
    margin = serializers.ReadOnlyField()
    interest_polls = SimpleInterestPollSerializer(required=False, many=True, source='interestpoll_set')
    expected_duration = serializers.CharField(required=True, read_only=False,
                                     allow_null=False, allow_blank=False)
    category = serializers.CharField(required=True, read_only=False,
                                     allow_null=False, allow_blank=False)

    class Meta:
        model = Project
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')

    def nested_save_override(self, validated_data, instance=None):
        initial_stage = None
        initial_archived = None

        if instance:
            initial_stage = instance.stage
            initial_archived = instance.archived

        instance = super(ProjectSerializer, self).nested_save_override(validated_data, instance=instance)

        if instance:
            if initial_stage != instance.stage:
                post_field_update.send(sender=Project, instance=instance, field='stage')

            if type(initial_archived) == bool and instance.archived and not initial_archived:
                complete_exact_sync.delay(instance.id)

        return instance

    def save_nested_skills(self, data, instance, created=False):
        if data is not None:
            instance.skills = ', '.join([skill.get('name', '') for skill in data])
            instance.save()

    def save_nested_change_log(self, data, instance, created=False):
        if data is not None:
            for item in data:
                FieldChangeLog.objects.create(content_object=instance, created_by=self.get_current_user(), **item)
Exemple #8
0
class SimpleDocumentSerializer(SimpleModelSerializer):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    download_url = serializers.CharField(read_only=True)

    class Meta:
        model = Document
        exclude = ('project',)
Exemple #9
0
class NestedProgressEventSerializer(SimpleModelSerializer):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    project = SimpleProjectSerializer(required=False, read_only=True)

    class Meta:
        model = ProgressEvent
        fields = '__all__'
Exemple #10
0
class CompanySerializer(NestedModelSerializer,
                        ContentTypeAnnotatedModelSerializer):
    user = SimplestUserSerializer(required=False, read_only=False)
    city = serializers.CharField(required=False,
                                 allow_blank=True,
                                 allow_null=True)
    skills = SimpleSkillSerializer(required=False, many=True)
    country = CountryField(required=False)
    country_name = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = Company
        fields = '__all__'

    def save_nested_user(self, data, instance, created=False):
        user = instance.user
        if user:
            user.first_name = data.get('first_name', user.first_name)
            user.last_name = data.get('last_name', user.last_name)
            image = data.get('image', None)
            if image:
                user.image = image
            user.save()

    def save_nested_skills(self, data, instance, created=False):
        if data is not None:
            instance.skills = ', '.join(
                [skill.get('name', '') for skill in data])
            instance.save()

    def save_nested_city(self, data, instance, created=False):
        if data:
            instance.city = data
            instance.save()
Exemple #11
0
class UploadSerializer(serializers.ModelSerializer):
    user = SimplestUserSerializer(required=False,
                                  read_only=True,
                                  default=CreateOnlyCurrentUserDefault())
    url = serializers.CharField(required=False,
                                read_only=True,
                                source='file.url')
    name = serializers.SerializerMethodField(required=False, read_only=True)
    size = serializers.IntegerField(required=False,
                                    read_only=True,
                                    source='file.size')
    display_size = serializers.SerializerMethodField(required=False,
                                                     read_only=True)

    class Meta:
        model = Upload
        fields = '__all__'

    def get_name(self, obj):
        return obj.file.name.split('/')[-1]

    def get_display_size(self, obj):
        filesize = obj.file.size
        converter = {'KB': 10**3, 'MB': 10**6, 'GB': 10**9, 'TB': 10**12}
        units = ['TB', 'GB', 'MB', 'KB']

        for label in units:
            conversion = converter[label]
            if conversion and filesize > conversion:
                return '%s %s' % (round(filesize / conversion, 2), label)
        return '%s %s' % (filesize, 'bytes')
class SimpleProgressEventSerializer(SimpleModelSerializer):
    created_by = SimplestUserSerializer(required=False,
                                        read_only=True,
                                        default=CreateOnlyCurrentUserDefault())

    class Meta:
        model = ProgressEvent
        exclude = ('project', )
class NotificationReadLogSerializer(serializers.ModelSerializer):
    user = SimplestUserSerializer(required=False,
                                  read_only=True,
                                  default=CreateOnlyCurrentUserDefault())

    class Meta:
        model = NotificationReadLog
        fields = '__all__'
Exemple #14
0
class SimpleProgressReportSerializer(SimpleModelSerializer):
    user = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    status_display = serializers.CharField(required=False, read_only=True, source='get_status_display')
    stuck_reason_display = serializers.CharField(required=False, read_only=True, source='get_stuck_reason_display')

    class Meta:
        model = ProgressReport
        exclude = ('event',)
Exemple #15
0
class ProfileSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer):
    user = SimplestUserSerializer(required=False)
    city = serializers.CharField(required=False, allow_blank=True, allow_null=True)
    skills = SimpleSkillSerializer(required=False, many=True)
    skills_details = SkillsDetailsSerializer(required=False, read_only=True)
    country = CountryField(required=False)
    country_name = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = UserProfile
        fields = '__all__'

    def nested_save_override(self, validated_data, instance=None):
        initial_bio = None
        initial_location = None
        initial_skills = None

        if instance:
            initial_bio = instance.bio
            initial_location = instance.location
            initial_skills = [skill.name for skill in instance.skills.all()]
            list.sort(initial_skills)

        instance = super(ProfileSerializer, self).nested_save_override(validated_data, instance=instance)

        final_skills = [skill.name for skill in instance.skills.all()]
        list.sort(final_skills)
        if not instance or initial_bio != instance.bio or initial_location != instance.location or initial_skills != final_skills:
            user_profile_updated.send(sender=UserProfile, profile=instance)
        return instance

    def save_nested_user(self, data, instance, created=False):
        user = instance.user
        if user:
            user.first_name = data.get('first_name', user.first_name)
            user.last_name = data.get('last_name', user.last_name)
            image = data.get('image', None)
            if image:
                user.image = image
            user.save()

    def save_nested_skills(self, data, instance, created=False):
        if data is not None:
            instance.skills = ', '.join([skill.get('name', '') for skill in data])
            instance.save()

            for skill in data:
                try:
                    category = skill.get('type', None)
                    if category:
                        Skill.objects.filter(name=skill.get('name', ''), type=SKILL_TYPE_OTHER).update(type=category)
                except:
                    pass

    def save_nested_city(self, data, instance, created=False):
        if data:
            instance.city = data
            instance.save()
Exemple #16
0
class DocumentSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    project = SimpleProjectSerializer()
    download_url = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = Document
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')
Exemple #17
0
class PaymentSerializer(NestedModelSerializer,
                        ContentTypeAnnotatedModelSerializer):
    created_by = SimplestUserSerializer(required=False,
                                        read_only=True,
                                        default=CreateOnlyCurrentUserDefault())
    invoice = SimpleInvoiceSerializer()

    class Meta:
        model = Payment
        fields = '__all__'
class CommentSerializer(serializers.ModelSerializer):
    user = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    uploads = UploadSerializer(read_only=True, required=False, many=True)
    text_body = serializers.CharField(required=False, read_only=True)
    html_body = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = Comment
        fields = '__all__'
        read_only_fields = ('created_at',)
class MessageSerializer(serializers.ModelSerializer, GetCurrentUserAnnotatedSerializerMixin):
    user = SimplestUserSerializer(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)
    text_body = serializers.CharField(required=False, read_only=True)
    html_body = serializers.CharField(required=False, read_only=True)

    class Meta:
        model = Message
        exclude = ('alt_user', 'source', 'extra')
        read_only_fields = ('created_at',)
Exemple #20
0
class SimpleInvoiceSerializer(SimpleModelSerializer):
    created_by = SimplestUserSerializer(required=False,
                                        read_only=True,
                                        default=CreateOnlyCurrentUserDefault())
    updated_by = SimplestUserSerializer(required=False,
                                        read_only=True,
                                        default=CurrentUserDefault())
    user = SimplestUserSerializer()
    full_title = serializers.CharField(read_only=True)
    tax_amount = serializers.DecimalField(max_digits=17,
                                          decimal_places=2,
                                          read_only=True)
    total_amount = serializers.DecimalField(max_digits=17,
                                            decimal_places=2,
                                            read_only=True)
    download_url = serializers.CharField(read_only=True)
    due_at = serializers.DateTimeField(read_only=True)
    is_overdue = serializers.BooleanField(read_only=True)

    class Meta:
        model = Invoice
        exclude = ('project', )
class FieldChangeLogSerializer(serializers.ModelSerializer):
    target_type = serializers.SerializerMethodField()
    target = GenericRelatedField(
        {
            Project: ProjectSerializer(),
            ProgressEvent: ProgressEventSerializer(),
        },
        source='content_object')
    created_by = SimplestUserSerializer()

    class Meta:
        model = FieldChangeLog
        fields = '__all__'

    def get_target_type(self, obj):
        return get_instance_type(obj.content_object)
Exemple #22
0
class ProgressEventSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer,
                              GetCurrentUserAnnotatedSerializerMixin):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    project = SimpleProjectSerializer()
    progress_reports = SimpleProgressReportSerializer(
        required=False, read_only=True, many=True, source='progressreport_set'
    )
    change_log = serializers.JSONField(required=False, write_only=True)

    class Meta:
        model = ProgressEvent
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')

    def save_nested_change_log(self, data, instance, created=False):
        if data is not None:
            for item in data:
                FieldChangeLog.objects.create(content_object=instance, created_by=self.get_current_user(), **item)
class ChannelSerializer(NestedModelSerializer, GetCurrentUserAnnotatedSerializerMixin):
    created_by = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    display_type = serializers.CharField(required=False, read_only=True, source='get_type_display')
    participants = SimplestUserSerializer(required=True, many=True)
    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')

    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
class SimpleChannelSerializer(serializers.ModelSerializer):
    created_by = SimplestUserSerializer()

    class Meta:
        model = Channel
        exclude = ('participants',)
Exemple #25
0
class ProgressReportSerializer(NestedModelSerializer, ContentTypeAnnotatedModelSerializer,
                               GetCurrentUserAnnotatedSerializerMixin):
    user = SimplestUserSerializer(required=False, read_only=True, default=CreateOnlyCurrentUserDefault())
    event = NestedProgressEventSerializer()
    status_display = serializers.CharField(required=False, read_only=True, source='get_status_display')
    stuck_reason_display = serializers.CharField(required=False, read_only=True, source='get_stuck_reason_display')

    class Meta:
        model = ProgressReport
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')

    def validate(self, attrs):
        errors = dict()

        current_user = self.get_current_user()
        if current_user.is_authenticated():
            BOOLEANS = (True, False)
            required_fields = []

            status_schema = (
                'status', [status_item[0] for status_item in PROGRESS_REPORT_STATUS_CHOICES],
                [
                    (
                        [PROGRESS_REPORT_STATUS_BEHIND_AND_STUCK, PROGRESS_REPORT_STATUS_STUCK],
                        'stuck_reason',
                        [stuck_reason_item[0] for stuck_reason_item in PROGRESS_REPORT_STUCK_REASON_CHOICES]
                    )
                ]
            )
            rate_deliverables_schema = ('rate_deliverables', list(range(1, 6)))  # 1...5

            if current_user.is_developer:
                required_fields = [
                    status_schema,
                    'started_at',
                    ('percentage', list(range(0, 101))),  # 0...100
                    'accomplished',
                    rate_deliverables_schema,
                    'todo',
                    'next_deadline',
                    (
                        'next_deadline_meet', BOOLEANS,
                        [
                            (False, 'next_deadline_fail_reason')
                        ]
                    )
                ]
            elif current_user.is_project_manager:
                required_fields = [
                    status_schema,
                    (
                        'last_deadline_met', BOOLEANS,
                        [
                            (False, 'deadline_miss_communicated', BOOLEANS),
                            (False, 'deadline_report')
                        ]
                    ),
                    'percentage', 'accomplished', 'todo',
                    'next_deadline',
                    (
                        'next_deadline_meet', BOOLEANS,
                        [
                            (False, 'next_deadline_fail_reason')
                        ]
                    ),
                    'team_appraisal'
                ]
            elif current_user.is_project_owner:
                required_fields = [
                    (
                        'last_deadline_met', BOOLEANS,
                        [
                            (False, 'deadline_miss_communicated', BOOLEANS)
                        ]
                    ),
                    ('deliverable_satisfaction', BOOLEANS),
                    rate_deliverables_schema,
                    ('pm_communication', BOOLEANS)
                ]

            errors.update(validate_field_schema(required_fields, attrs, raise_exception=False))

        if errors:
            raise ValidationError(errors)
        return attrs