File size: 5,098 Bytes
0da497e
 
 
dbb7932
0da497e
dd4466b
 
ced18b6
dd4466b
 
 
 
0da497e
 
 
 
 
 
ced18b6
 
0da497e
 
 
 
ced18b6
 
 
0da497e
7cc204e
0da497e
 
 
 
dd4466b
0da497e
ced18b6
 
 
0da497e
ced18b6
 
 
 
 
 
 
dd4466b
ced18b6
dd4466b
ced18b6
 
 
 
 
 
 
0da497e
 
 
2bb9fdd
 
dd4466b
 
 
 
2bb9fdd
 
 
 
0da497e
 
 
 
 
7cc204e
0da497e
 
 
 
 
3784aa0
 
 
 
 
dbb7932
1d8dc03
 
dbb7932
1d8dc03
 
 
 
dd4466b
dbb7932
 
1d8dc03
 
dd4466b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import UserData, AIKey, AppVersion, Contact
from django.shortcuts import get_object_or_404
from .serializers import ContactSerializer, ExpenseRequestSerializer
from rest_framework.generics import CreateAPIView, GenericAPIView
import uuid
from .models import ExpenseLog
from django.apps import apps
import re


class UserDataPostView(APIView):
    def post(self, request):
        user_id = request.data.get("user_id")
        if not user_id:
            return Response(
                {"error": "user_id is required"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        obj, created = UserData.objects.get_or_create(user_id=user_id)

        # Always regenerate backup key
        obj.data_backup_key = str(uuid.uuid4())

        updated = False
        for key in ["expenses", "salary", "category", "user_data"]:
            if key in request.data and getattr(obj, key) != request.data[key]:
                setattr(obj, key, request.data[key])
                updated = True

        obj.save()  # Save once after changes

        # AI key logic
        if obj.has_ai_access:
            AI_KEY = get_object_or_404(AIKey, isActive=True).aikey
        else:
            AI_KEY = None

        return Response(
            {
                "message": (
                    "Data created successfully"
                    if created
                    else "Data updated successfully" if updated else "No changes made"
                ),
                "app_version": get_object_or_404(AppVersion, isActive=True).version,
                "has_music_url_access": obj.has_music_url_access,
                "has_ai_access": obj.has_ai_access,
                "ai_key": AI_KEY,
                "data_backup_key": obj.data_backup_key,
            },
            status=status.HTTP_201_CREATED if created else status.HTTP_200_OK,
        )


class GetFieldView(APIView):
    def get(self, request, field, identifier):
        # identifier can be user_id OR data_backup_key
        obj = (
            UserData.objects.filter(user_id=identifier).first()
            or UserData.objects.filter(data_backup_key=identifier).first()
        )

        if not obj:
            return Response({"error": "User not found"}, status=404)

        if field == "all":
            data = {
                "userData": obj.user_data,
                "expenseData": obj.expenses,
                "categoryData": obj.category,
                "salaryData": obj.salary,
            }
            return Response(data)
        if hasattr(obj, field):
            return Response({field: getattr(obj, field)})
        return Response({"error": "Invalid field"}, status=status.HTTP_400_BAD_REQUEST)


class ContactList1(CreateAPIView):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            return Response(
                {"message": "Contact saved successfully"},
                status=status.HTTP_201_CREATED,
            )

        return Response(
            {"message": "Validation failed", "errors": serializer.errors},
            status=status.HTTP_400_BAD_REQUEST,
        )


class CategorizeExpenseView(GenericAPIView):
    # 2. Assign the serializer class to automatically populate the Swagger schema
    serializer_class = ExpenseRequestSerializer

    def post(self, request):
        # 3. Validate input using the serializer
        serializer = self.get_serializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=400)

        expense_text = serializer.validated_data["text"]

        # 4. Extract Amount using Regex
        # Matches formats like 150, 1,500, 150.50, 1,500.50
        amount_match = re.search(r"\d+(?:,\d+)*(?:\.\d+)?", expense_text)
        extracted_amount = (
            float(amount_match.group().replace(",", "")) if amount_match else None
        )

        # 5. Use the safe Django app registry to fetch the pre-loaded AI model
        api_config = apps.get_app_config("api")

        result = api_config.classifier(
            expense_text,
            candidate_labels=api_config.categories,
            hypothesis_template="This expense is for {}.",
        )

        top_category = result["labels"][0]
        confidence_score = result["scores"][0]

        # 6. Save to database
        ExpenseLog.objects.create(
            text=expense_text,
            amount=extracted_amount,
            predicted_category=top_category,
            confidence_score=confidence_score,
        )

        return Response(
            {
                "expense": expense_text,
                "amount": extracted_amount,
                "category": top_category,
                "confidence": round(confidence_score * 100, 2),
            }
        )