def update_publish_status(request):
    research_id = request.POST.get('research_id', None)
    is_publish = request.POST.get('is_publish', 'false')
    if research_id:
        research = Research.objects.get(id=research_id)

        if is_publish == 'true':
            research.is_publish = True
        else:
            research.is_publish = False
        research.save()

        # If the research is not paid, redirect to payment page
        if research.is_publish and research.total_credit > 0 and research.is_paid is False:
            research.is_publish = False
            if research.payment_type == 'cash':
                research.is_paid = True
                research.save()
            else:
                research.save()
                if research.payment_type == 'paypal':
                    result = {'status': 'warning',
                              'redirect_url': '/scientist/research/%s/payment/paypal/' % research.id}
                elif research.payment_type == 'amazon':
                    result = {'status': 'warning',
                              'redirect_url': '/scientist/research/%s/payment/amazon/' % research.id}
        else:
            result = {'status': 'success'}
    else:
        result = {'status': 'fail', 'reason': 'Research id is none'}
    return json_result(request, result)
def assign_credit(request):
    try:
        scheme_id = request.POST.get('scheme_id', None)
        scientist_id = request.POST.get('scientist_id', None)
        assigned_credit = int(request.POST.get('assigned_credit', 0))

        scheme = CreditScheme.objects.get(id=scheme_id)
        scientist = ScientistCreditScheme.objects.get(id=scientist_id, credit_scheme=scheme)
        add_assigned_credit = assigned_credit - scientist.assigned_credit
        if add_assigned_credit > scheme.remain_credit:
            result = {'status': 'fail', 'reason': 'not enough remain credit',
                      'scientist_assigned_credit': scientist.assigned_credit}
        elif assigned_credit <= scientist.assigned_credit:
            result = {'status': 'fail', 'reason': 'credit can not be reduced',
                      'scientist_assigned_credit': scientist.assigned_credit}
        else:
            scheme.remain_credit -= add_assigned_credit
            scheme.save()
            scientist.remain_credit += add_assigned_credit
            scientist.assigned_credit = assigned_credit
            scientist.save()
            result = {'status': 'success', 'scientist_remain_credit': scientist.remain_credit,
                      'scientist_assigned_credit': scientist.assigned_credit,
                      'scheme_remain_credit': scheme.remain_credit}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}
    return json_result(request, result)
def scheme_assign_credit(request):
    try:
        scheme_id = request.POST.get('scheme_id', None)
        participant_id = request.POST.get('participant_id', None)
        assigned_credit = is_integer(request.POST.get('assigned_credit', 0))

        scheme = get_object_or_404(CreditScheme, id=scheme_id)
        scientist = get_object_or_404(ScientistCreditScheme, credit_scheme=scheme, scientist=request.user)
        participant = get_object_or_404(ParticipantCreditScheme, id=participant_id, credit_scheme=scheme)

        if assigned_credit < 0:
            result = {'status': 'fail', 'reason': 'remain credit can not assign to negative number'}
        elif assigned_credit > scientist.remain_credit:
            result = {'status': 'fail', 'reason': 'not enough remain credit'}
        else:
            scientist.remain_credit -= assigned_credit
            scientist.save()
            participant.incomplete_credit -= assigned_credit
            participant.save()
            SchemeCreditRecord(credit_scheme=scheme, scientist=scientist.scientist,
                               participant=participant.participant).save()
            result = {'status': 'success', 'scientist_remain_credit': scientist.remain_credit,
                      'participant_incomplete_credit': participant.incomplete_credit}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}
    return json_result(request, result)
def ajax_signup(request):
    if request.is_ajax() and request.method == 'POST':
        user_type = request.POST.get('user_type', USER_TYPE_PARTICIPANT)
        if user_type == USER_TYPE_SCIENTIST:
            form = ScientistSignupForm(request.POST)
        elif user_type == USER_TYPE_DEPARTMENT:
            form = DepartmentSignupForm(request.POST)
        else:
            form = ParticipantSignupForm(request.POST)
        if form.is_valid():
            user = form.save(request)
            request.session['user_type'] = user_type
            if not hasattr(user, 'backend'):
                user.backend = "django.contrib.auth.backends.ModelBackend"
            django_login(request, user)
            data = {'status': 'success'}
        else:
            data = json.loads(errors_to_json(form.errors))
        return json_result(request, data)
    else:
        user_type = request.REQUEST.get('user_type', USER_TYPE_PARTICIPANT)
        next = request.REQUEST.get('next', None)
        context = {
            'user_type': user_type if user_type else USER_TYPE_PARTICIPANT,
            'next': next,
        }
        return render_to_response("account/ajax_signup.html", context, context_instance=RequestContext(request))
def research_delete(request):
    research_id = request.POST.get('research_id', None)
    if research_id:
        Research.objects.get(id=research_id).delete()
        result = {'status': 'success'}
    else:
        result = {'status': 'fail', 'reason': 'research id is none'}
    return json_result(request, result)
def remove_all_scientist(request):
    scheme_id = request.POST.get('scheme_id', department=request.user)
    try:
        scheme = CreditScheme.objects.get(id=scheme_id)
        ScientistCreditScheme.objects.filter(credit_scheme=scheme).delete()
        result = {'status': 'success'}
    except CreditScheme.DoesNotExist:
        result = {'status': 'fail', 'reason': 'The credit scheme does not exist.'}
    return json_result(request, result)
def delete_participant(request):
    try:
        participant_id_list = request.POST.getlist('participant_id', [])
        ParticipantCreditScheme.objects.filter(id__in=participant_id_list,
                                               credit_scheme__department=request.user).delete()
        result = {'status': 'success'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}
    return json_result(request, result)
def get_research_event(request):
    event_id = request.POST.get('event_id', None)

    if event_id:
        event = ResearchEvent.objects.get(id=event_id)
        result = {'status': 'success', 'event': event.to_dict()}
    else:
        result = {'status': 'fail', 'reason': 'event does not exist'}

    return json_result(request, result)
def get_payment_info(request):
    participant_id = request.POST.get("participant_id", None)

    try:
        pr = ParticipantResearch.objects.get(id=participant_id)
        result = {"status": "success", "award_credit": pr.award_credit, "research_name": pr.research.name}
    except ParticipantResearch.DoesNotExist:
        result = {"status": "fail", "reason": "Participant id is not exist"}

    return json_result(request, result)
def ajax_login(request):
    if request.is_ajax() and request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            login(request, request.user)
            data = {'status': 'success'}
        else:
            data = json.loads(errors_to_json(form.errors))
        return json_result(request, data)
    else:
        return render_to_response("account/ajax_login.html", {}, context_instance=RequestContext(request))
def api_scientist_events(request):
    research_id = request.REQUEST.get('research_id', None)
    if research_id:
        research_list = ScientistResearch.objects.filter(research__id=research_id, scientist=request.user)
    else:
        research_list = ScientistResearch.objects.filter(scientist=request.user)
    event_list = []
    for research in research_list:
        event_list += [event.to_dict() for event in list(research.research.researchevent_set.all())]

    return json_result(request, event_list)
def message_undo(request):
    try:
        message_ids = request.POST.getlist('message_ids[]', [])
        messages = Message.objects.filter(id__in=message_ids)
        for message in messages:
            if message.sender == request.user:
                message.sender_deleted_at = None
            if message.recipient == request.user:
                message.recipient_deleted_at = None
            message.save()
        result = {'status': 'success'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}
    return json_result(request, result)
def update_research_duration(request):
    research_id = request.POST.get('research_id', None)
    start = request.POST.get('start', None)
    end = request.POST.get('end', None)

    try:
        research = Research.objects.get(id=research_id)
        research.start = start
        research.end = end
        research.save()
        result = {'status': 'success'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}

    return json_result(request, result)
def api_participant_events(request):
    research_ids = request.POST.getlist("research_ids", None)
    if research_ids and len(research_ids) > 0:
        research_list = Research.objects.filter(id__in=research_ids, is_publish=True)
    else:
        pr_list = ParticipantResearch.objects.filter(
            participant=request.user, confirmed=True, research__is_publish=True
        )
        research_list = [pr.research for pr in pr_list]

    event_list = []
    for research in research_list:
        event_list += [event.to_dict() for event in list(research.researchevent_set.all())]

    return json_result(request, event_list)
def confirmed_participant(request):
    research_id = request.POST.get('research_id', None)
    if research_id:
        research = get_object_or_404(Research, id=research_id)
        if not research.is_complete:
            participant_id_list = request.POST.getlist('participant_id', [])
            for participant_id in participant_id_list:
                participant_research = ParticipantResearch.objects.filter(id=participant_id, research=research,
                                                                          confirmed=False)
                if participant_research:
                    participant_research[0].confirmed = True
                    participant_research[0].save()
            result = {'status': 'success'}
    else:
        result = {'status': 'fail', 'reason': 'Research id is none'}
    return json_result(request, result)
def delete_scientist(request):
    try:
        scientist_id_list = request.POST.getlist('scientist_id', [])
        scheme_id = request.POST.get('scheme_id', None)

        scheme = get_object_or_404(CreditScheme, id=scheme_id, department=request.user)
        scientist_list = ScientistCreditScheme.objects.filter(id__in=scientist_id_list, credit_scheme=scheme)

        for scientist in scientist_list:
            scheme.remain_credit += scientist.remain_credit
            scheme.save()
            scientist.delete()

        result = {'status': 'success'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}
    return json_result(request, result)
def set_score(request, user_type):
    user_ids = []
    research_id = request.POST.get('research_id', None)
    user_id = request.POST.get('user_id', None)
    score = request.POST.get('score', 0)
    type = request.POST.get('type', None)

    if not user_id:
        participant_ids = request.POST.getlist('participant_id', None)
        scientist_ids = request.POST.getlist('scientist_id', None)
        if participant_ids:
            pr_list = ParticipantResearch.objects.filter(id__in=participant_ids)
            for pr in pr_list:
                user_ids.append(pr.participant.id)
        elif scientist_ids:
            sr_list = ScientistResearch.objects.filter(id__in=participant_ids)
            for sr in sr_list:
                user_ids.append(sr.scientist.id)
    else:
        user_ids.append(user_id)

    try:
        research = Research.objects.get(id=research_id)
        for to_user_id in user_ids:
            rating_list = StarRating.objects.filter(from_user=request.user, to_user__id=to_user_id,
                                                    research__id=research_id,
                                                    user_type=user_type)
            if rating_list:
                rating = rating_list[0]
            else:
                to_user = User.objects.get(id=to_user_id)
                rating = StarRating(from_user=request.user, to_user=to_user, research=research,
                                    user_type=user_type)
            if type == 'attitude':
                rating.attitude_score = score
            else:
                rating.time_score = score
            if not research.is_complete:
                rating.save()
                result = {'status': 'success'}
            else:
                result = {'status': 'fail', 'reason': 'This research has been completed and can not be rating'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}

    return json_result(request, result)
def get_score(request, user_type):
    research_id = request.POST.get('research_id', None)
    user_id = request.POST.get('user_id', None)
    type = request.POST.get('type', None)
    score = 0

    try:
        if research_id:
            rating_list = StarRating.objects.filter(to_user__id=user_id, research__id=research_id, user_type=user_type)
        else:
            rating_list = StarRating.objects.filter(to_user__id=user_id, user_type=user_type)

        if rating_list:
            score = calc_avg_score(rating_list, type)
        result = {'status': 'success', 'score': score, 'count': len(rating_list)}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}

    return json_result(request, result)
def delete_research_event(request):
    event_id = request.POST.get('event_id', None)

    if event_id:
        try:
            event = ResearchEvent.objects.get(id=event_id)
            participant_event_list = ParticipantResearchEvent.objects.filter(research_event=event)
            if len(participant_event_list) > 0:
                result = {'status': 'fail', 'reason': 'event has been participants'}
            else:
                participant_event_list.delete()
                event.delete()
                result = {'status': 'success'}
        except ResearchEvent.DoesNotExist:
            result = {'status': 'fail', 'reason': 'event does not exist'}
    else:
        result = {'status': 'fail', 'reason': 'event does not exist'}

    return json_result(request, result)
def reject_participant(request):
    research_id = request.POST.get('research_id', None)
    if research_id:
        count = 0
        research = get_object_or_404(Research, id=research_id)
        if not research.is_complete:
            participant_id_list = request.POST.getlist('participant_id', [])
            for participant_id in participant_id_list:
                participant_research = ParticipantResearch.objects.filter(id=participant_id, research=research,
                                                                          confirmed=False)
                if participant_research:
                    participant_research[0].delete()
                    count += 1
            if count > 0:
                result = {'status': 'success'}
            else:
                result = {'status': 'warn', 'reason': 'You can not reject already confirmed participant'}
    else:
        result = {'status': 'fail', 'reason': 'Research id is none'}
    return json_result(request, result)
def create_research_event(request):
    research_id = request.POST.get('research_id', None)
    start = request.POST.get('start', None)
    end = request.POST.get('end', None)
    event_id = request.POST.get('event_id', None)

    research = get_object_or_404(Research, id=research_id)
    is_validate = True

    start = start.replace('GMT', '')
    end = end.replace('GMT', '')
    d_start = parser.parse(start).replace(tzinfo=None)
    d_end = parser.parse(end).replace(tzinfo=None)

    if d_start > d_end:
        result = {'status': 'fail', 'reason': 'event end time can not be greater than the start time',
                  'target': 'id_end'}
        is_validate = False
    elif research.start > d_start:
        result = {'status': 'fail', 'reason': 'event start time can not before the start time of research',
                  'target': 'id_start'}
        is_validate = False
    elif d_end > research.end:
        result = {'status': 'fail', 'reason': 'event end time can not after the end time of research',
                  'target': 'id_end'}
        is_validate = False

    if is_validate:
        try:
            if event_id:
                event = ResearchEvent.objects.get(id=event_id)
                event.start = d_start
                event.end = d_end
                event.save()
            else:
                ResearchEvent(research=research, start=d_start, end=d_end).save()
            result = {'status': 'success'}
        except Exception as e:
            result = {'status': 'fail', 'reason': e.message}

    return json_result(request, result)
def set_required_credit(request):
    try:
        scheme_id = request.POST.get('scheme_id', None)
        participant_id = request.POST.get('participant_id', None)
        required_credit = int(request.POST.get('required_credit', 0))

        if required_credit > 0:
            participant = ParticipantCreditScheme.objects.get(id=participant_id, credit_scheme__id=scheme_id)
            if participant:
                space_required_credit = required_credit - participant.required_credit
                participant.required_credit = required_credit
                participant.incomplete_credit += space_required_credit
                participant.save()
                result = {'status': 'success', 'incomplete_credit': participant.incomplete_credit}
            else:
                result = {'status': 'fail', 'reason': 'participant does not exists'}
        else:
            result = {'status': 'fail', 'reason': 'required credit can not set to negative number'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}
    return json_result(request, result)
def take_part_event(request):
    event_id = request.POST.get("event_id", None)

    try:
        research_event = get_object_or_404(ResearchEvent, id=event_id)
        participant_event = ParticipantResearchEvent.objects.filter(
            participant=request.user, research_event=research_event
        )

        scientist_research = ScientistResearch.objects.filter(scientist=request.user, research=research_event.research)

        if participant_event:
            result = {"status": "fail", "reason": "You have participated in this event"}
        elif scientist_research:
            result = {"status": "fail", "reason": "Can not participate in own research"}
        else:
            ParticipantResearchEvent(participant=request.user, research_event=research_event).save()
            result = {"status": "success"}
    except Exception as e:
        result = {"status": "fail", "reason": e.message}

    return json_result(request, result)
def copy_research_event(request):
    event_id = request.POST.get('event_id', None)
    start = request.POST.get('start', None)
    research_id = request.POST.get('research_id', None)

    research = get_object_or_404(Research, id=research_id)
    is_validate = True

    if event_id and start:
        try:
            event = ResearchEvent.objects.get(id=event_id)
            event.id = None
            seconds = (event.end - event.start).seconds
            days = (event.end - event.start).days
            start = start.replace('GMT', '')
            d_start = parser.parse(start).replace(tzinfo=None)

            event.end = d_start + datetime.timedelta(days=days, seconds=seconds)
            event.start = d_start

            if research.start > d_start:
                result = {'status': 'fail', 'reason': 'event start time can not before the start time of research',
                          'target': 'id_start'}
                is_validate = False
            elif research.end < event.end:
                result = {'status': 'fail', 'reason': 'event end time can not after the end time of research',
                          'target': 'id_end'}
                is_validate = False

            if is_validate:
                event.save()
                result = {'status': 'success'}
        except ResearchEvent.DoesNotExis:
            result = {'status': 'fail', 'reason': 'event does not exist'}
    else:
        result = {'status': 'fail', 'reason': 'event does not exist'}

    return json_result(request, result)
def resize_research_event(request):
    research_id = request.POST.get('research_id', None)
    event_id = request.POST.get('event_id', None)
    start_delta = request.POST.get('start_delta', None)
    end_delta = request.POST.get('end_delta', None)

    try:
        research = get_object_or_404(Research, id=research_id)
        event = get_object_or_404(ResearchEvent, id=event_id)
        if start_delta:
            event.start += datetime.timedelta(minutes=is_integer(start_delta))
        if end_delta:
            event.end += datetime.timedelta(minutes=is_integer(end_delta))
        if research.start > event.start:
            result = {'status': 'fail', 'reason': 'event start time can not before the start time of research'}
        elif research.end < event.end:
            result = {'status': 'fail', 'reason': 'event end time can not after the end time of research'}
        else:
            event.save()
            result = {'status': 'success'}
    except Exception as e:
        result = {'status': 'fail', 'reason': e.message}

    return json_result(request, result)