blessedpug commited on
Commit
74f57ab
·
1 Parent(s): 8e65d73

Pre FastAPI

Browse files
data.json CHANGED
@@ -1,77 +1,6 @@
1
  [
2
  {
3
- "merchant": "TESCO SHREWSBURY CATTLE MARKET",
4
- "date": "17/10/22",
5
- "total_amount": 55.3,
6
- "items": [
7
- {
8
- "description": "TAPE MEASURE",
9
- "amount": 2.1
10
- },
11
- {
12
- "description": "PROTEIN COOKIE",
13
- "amount": 1.0
14
- },
15
- {
16
- "description": "PROTEIN COOKIE",
17
- "amount": 1.0
18
- },
19
- {
20
- "description": "CONDOMS",
21
- "amount": 7.0
22
- },
23
- {
24
- "description": "PROCECCO",
25
- "amount": 8.0
26
- },
27
- {
28
- "description": "PROCECCO",
29
- "amount": 8.0
30
- },
31
- {
32
- "description": "SAUVIGNON BLNC",
33
- "amount": 7.0
34
- },
35
- {
36
- "description": "SAUVIGNON BLNC",
37
- "amount": 7.0
38
- },
39
- {
40
- "description": "TAPE MEASURE",
41
- "amount": 2.1
42
- },
43
- {
44
- "description": "SAUVIGNON BLNC",
45
- "amount": 7.0
46
- },
47
- {
48
- "description": "PROTEIN COOKIE",
49
- "amount": 1.0
50
- },
51
- {
52
- "description": "PROTEIN COOKIE",
53
- "amount": 1.0
54
- },
55
- {
56
- "description": "PROTEIN COOKIE",
57
- "amount": 1.0
58
- },
59
- {
60
- "description": "SAUVIGNON BLNC",
61
- "amount": 7.0
62
- },
63
- {
64
- "description": "KRONENBOURG",
65
- "amount": 1.1
66
- },
67
- {
68
- "description": "KRONENBOURG",
69
- "amount": 1.0
70
- }
71
- ],
72
- "fraud_check": false
73
- },
74
- {
75
  "merchant": "TESCO",
76
  "date": "17/10/22",
77
  "total_amount": 55.3,
@@ -140,194 +69,25 @@
140
  "description": "KRONENBOURG",
141
  "amount": 4.6
142
  }
143
- ],
144
- "fraud_check": false
145
- },
146
- {
147
- "merchant": "TESCO SHREWSBURY CATTLE MARKET",
148
- "date": "17/10/22",
149
- "total_amount": 55.3,
150
- "items": [
151
- {
152
- "description": "TAPE MEASURE",
153
- "amount": 2.1
154
- },
155
- {
156
- "description": "PROTEIN COOKIE",
157
- "amount": 1.8
158
- },
159
- {
160
- "description": "PROTEIN COOKIE",
161
- "amount": 1.8
162
- },
163
- {
164
- "description": "CONDOMS",
165
- "amount": 10.0
166
- },
167
- {
168
- "description": "PROCECCO",
169
- "amount": 7.0
170
- },
171
- {
172
- "description": "PROCECCO",
173
- "amount": 7.0
174
- },
175
- {
176
- "description": "SAUVIGNON BLNC",
177
- "amount": 7.0
178
- },
179
- {
180
- "description": "SAUVIGNON BLNC",
181
- "amount": 7.0
182
- },
183
- {
184
- "description": "KRONENBOURG",
185
- "amount": 4.6
186
- },
187
- {
188
- "description": "TAPE MEASURE",
189
- "amount": 2.1
190
- },
191
- {
192
- "description": "PROTEIN COOKIE",
193
- "amount": 1.8
194
- },
195
- {
196
- "description": "PROTEIN COOKIE",
197
- "amount": 1.8
198
- },
199
- {
200
- "description": "CONDOMS",
201
- "amount": 10.0
202
- },
203
- {
204
- "description": "SAUVIGNON BLNC",
205
- "amount": 7.0
206
- },
207
- {
208
- "description": "SAUVIGNON BLNC",
209
- "amount": 7.0
210
- },
211
- {
212
- "description": "KRONENBOURG",
213
- "amount": 4.6
214
- }
215
- ],
216
- "fraud_check": false
217
- },
218
- {
219
- "fraud_check": false,
220
- "merchant": "TESCO SHREWSBURY CATTLE MARKET",
221
- "date": "17/10/22",
222
- "total_amount": 55.3,
223
- "items": [
224
- {
225
- "description": "TAPE MEASURE",
226
- "amount": 2.1
227
- },
228
- {
229
- "description": "PROTEIN COOKIE",
230
- "amount": 1.8
231
- },
232
- {
233
- "description": "PROTEIN COOKIE",
234
- "amount": 1.8
235
- },
236
- {
237
- "description": "CONDOMS",
238
- "amount": 10.0
239
- },
240
- {
241
- "description": "PROCECCO",
242
- "amount": 7.0
243
- },
244
- {
245
- "description": "PROCECCO",
246
- "amount": 7.0
247
- },
248
- {
249
- "description": "SAUVIGNON BLNC",
250
- "amount": 7.0
251
- },
252
- {
253
- "description": "SAUVIGNON BLNC",
254
- "amount": 7.0
255
- },
256
- {
257
- "description": "KRONENBOURG",
258
- "amount": 4.6
259
- }
260
  ]
261
  },
262
  {
263
- "fraud_check": false,
264
- "merchant": "Tesco",
265
- "date": "17/10/22",
266
- "total_amount": 55.3,
267
  "items": [
268
  {
269
- "description": "TAPE MEASURE",
270
- "amount": 2.1
271
- },
272
- {
273
- "description": "PROTEIN COOKIE",
274
- "amount": 1.8
275
- },
276
- {
277
- "description": "PROTEIN COOKIE",
278
- "amount": 1.8
279
- },
280
- {
281
- "description": "CONDOMS",
282
- "amount": 10.0
283
- },
284
- {
285
- "description": "PROCECCO",
286
- "amount": 7.0
287
- },
288
- {
289
- "description": "PROCECCO",
290
- "amount": 7.0
291
- },
292
- {
293
- "description": "SAUVIGNON BLNC",
294
- "amount": 7.0
295
- },
296
- {
297
- "description": "SAUVIGNON BLNC",
298
- "amount": 7.0
299
- },
300
- {
301
- "description": "KRONENBOURG",
302
- "amount": 4.6
303
  },
304
  {
305
- "description": "TAPE MEASURE",
306
- "amount": 2.1
307
- },
308
- {
309
- "description": "PROTEIN COOKIE",
310
- "amount": 1.8
311
- },
312
- {
313
- "description": "PROTEIN COOKIE",
314
- "amount": 1.8
315
  },
316
  {
317
- "description": "CONDOMS",
318
- "amount": 10.0
319
- },
320
- {
321
- "description": "SAUVIGNON BLNC",
322
- "amount": 7.0
323
- },
324
- {
325
- "description": "SAUVIGNON BLNC",
326
- "amount": 7.0
327
- },
328
- {
329
- "description": "KRONENBOURG",
330
- "amount": 4.6
331
  }
332
  ]
333
  }
 
1
  [
2
  {
3
+ "fraud_check": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  "merchant": "TESCO",
5
  "date": "17/10/22",
6
  "total_amount": 55.3,
 
69
  "description": "KRONENBOURG",
70
  "amount": 4.6
71
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  ]
73
  },
74
  {
75
+ "fraud_check": [],
76
+ "merchant": "Walmart",
77
+ "date": "01/26/21",
78
+ "total_amount": 29.73,
79
  "items": [
80
  {
81
+ "description": "BOYS CREW S# 028944",
82
+ "amount": 9.48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  },
84
  {
85
+ "description": "BOYS SOCKS",
86
+ "amount": 4.97
 
 
 
 
 
 
 
 
87
  },
88
  {
89
+ "description": "BOXER BRIEF",
90
+ "amount": 9.48
 
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
  ]
93
  }
fraud.py CHANGED
@@ -1,5 +1,6 @@
1
  import json
2
  import os
 
3
 
4
  DATA_FILE = 'data.json'
5
 
@@ -34,7 +35,7 @@ def save_receipts(receipts):
34
  json.dump(receipts, f, indent=4)
35
 
36
  def receipts_are_equal(receipt1, receipt2):
37
- """Check if two receipts are the same, comparing only basic fields."""
38
  print(f"\n=== COMPARING RECEIPTS ===")
39
  print(f"Receipt1 merchant: {receipt1.get('merchant')}")
40
  print(f"Receipt2 merchant: {receipt2.get('merchant')}")
@@ -44,22 +45,15 @@ def receipts_are_equal(receipt1, receipt2):
44
  print("One or both receipts are empty")
45
  return False
46
 
47
- # Check basic fields with special handling for merchant
48
- merchant1 = receipt1.get('merchant', '').lower()
49
- merchant2 = receipt2.get('merchant', '').lower()
50
  date1 = receipt1.get('date')
51
  date2 = receipt2.get('date')
52
  amount1 = receipt1.get('total_amount')
53
  amount2 = receipt2.get('total_amount')
54
 
55
- print(f"Comparing merchant (lowercase): '{merchant1}' vs '{merchant2}'")
56
  print(f"Comparing date: '{date1}' vs '{date2}'")
57
  print(f"Comparing total_amount: '{amount1}' vs '{amount2}'")
58
 
59
- if merchant1 != merchant2:
60
- print("Merchant field doesn't match")
61
- return False
62
-
63
  if date1 != date2:
64
  print("Date field doesn't match")
65
  return False
@@ -68,7 +62,7 @@ def receipts_are_equal(receipt1, receipt2):
68
  print("Total amount field doesn't match")
69
  return False
70
 
71
- print("All basic fields match - receipts are equal")
72
  return True
73
 
74
  def is_duplicate(new_receipt, receipts):
@@ -78,9 +72,6 @@ def is_duplicate(new_receipt, receipts):
78
 
79
  for i, old_receipt in enumerate(receipts):
80
  print(f"\nChecking against receipt {i}:")
81
- print(f" Stored: {old_receipt.get('merchant')} - {old_receipt.get('date')} - {old_receipt.get('total_amount')}")
82
- print(f" New: {new_receipt.get('merchant')} - {new_receipt.get('date')} - {new_receipt.get('total_amount')}")
83
-
84
  if receipts_are_equal(old_receipt, new_receipt):
85
  print(f"DUPLICATE FOUND at index {i}!")
86
  return True
@@ -102,11 +93,13 @@ def process_receipt(new_receipt):
102
 
103
  if is_duplicate(new_receipt, receipts):
104
  print("SETTING FRAUD CHECK TO TRUE")
105
- new_receipt['fraud_check'] = True
 
 
106
  # Do not save, just return
107
  else:
108
  print("SETTING FRAUD CHECK TO FALSE - SAVING RECEIPT")
109
- new_receipt['fraud_check'] = False
110
  receipts.append(new_receipt)
111
  save_receipts(receipts)
112
 
 
1
  import json
2
  import os
3
+ from models import FraudData
4
 
5
  DATA_FILE = 'data.json'
6
 
 
35
  json.dump(receipts, f, indent=4)
36
 
37
  def receipts_are_equal(receipt1, receipt2):
38
+ """Check if two receipts are the same, comparing only date and amount."""
39
  print(f"\n=== COMPARING RECEIPTS ===")
40
  print(f"Receipt1 merchant: {receipt1.get('merchant')}")
41
  print(f"Receipt2 merchant: {receipt2.get('merchant')}")
 
45
  print("One or both receipts are empty")
46
  return False
47
 
48
+ # Only compare date and amount
 
 
49
  date1 = receipt1.get('date')
50
  date2 = receipt2.get('date')
51
  amount1 = receipt1.get('total_amount')
52
  amount2 = receipt2.get('total_amount')
53
 
 
54
  print(f"Comparing date: '{date1}' vs '{date2}'")
55
  print(f"Comparing total_amount: '{amount1}' vs '{amount2}'")
56
 
 
 
 
 
57
  if date1 != date2:
58
  print("Date field doesn't match")
59
  return False
 
62
  print("Total amount field doesn't match")
63
  return False
64
 
65
+ print("Date and amount match - receipts are equal")
66
  return True
67
 
68
  def is_duplicate(new_receipt, receipts):
 
72
 
73
  for i, old_receipt in enumerate(receipts):
74
  print(f"\nChecking against receipt {i}:")
 
 
 
75
  if receipts_are_equal(old_receipt, new_receipt):
76
  print(f"DUPLICATE FOUND at index {i}!")
77
  return True
 
93
 
94
  if is_duplicate(new_receipt, receipts):
95
  print("SETTING FRAUD CHECK TO TRUE")
96
+ # Create FraudData object and convert to dict
97
+ fraud_data = FraudData(fraud_detected=True, fraud_type="duplicate")
98
+ new_receipt['fraud_check'] = [fraud_data.dict()]
99
  # Do not save, just return
100
  else:
101
  print("SETTING FRAUD CHECK TO FALSE - SAVING RECEIPT")
102
+ new_receipt['fraud_check'] = [] # Empty list means no fraud detected
103
  receipts.append(new_receipt)
104
  save_receipts(receipts)
105
 
models.py CHANGED
@@ -5,8 +5,12 @@ class ReceiptItem(BaseModel):
5
  description: str
6
  amount: float
7
 
 
 
 
 
8
  class ReceiptData(BaseModel):
9
- fraud_check: Optional[bool] = False # Optional field for fraud detection
10
  merchant: str
11
  date: str
12
  total_amount: float
 
5
  description: str
6
  amount: float
7
 
8
+ class FraudData(BaseModel):
9
+ fraud_detected: bool
10
+ fraud_type: Optional[str] = None # Type of fraud if detected, e.g., "duplicate", "suspicious"
11
+
12
  class ReceiptData(BaseModel):
13
+ fraud_check: Optional[List[FraudData]] = False # Optional field for fraud detection
14
  merchant: str
15
  date: str
16
  total_amount: float
outputs/filled_child_fee_form_6dfe1052f5be4bbc8a78711a456a3cc9.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:48066dd238b5a6eda1e8cd8647afc31074c61b7b95946e6b4329426f4a818331
3
+ size 115543
outputs/filled_child_fee_form_e3fba6d8482a476dade270c022cc64e2.pdf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fa5b02270d310e55abfdf36281e54e88928ad3b71d19f034b784b1616a2c9eb5
3
+ size 115542
pipeline.py CHANGED
@@ -20,8 +20,11 @@ reciept_system_prompt = (
20
  "class ReceiptItem(BaseModel):\n"
21
  " description: str\n"
22
  " amount: float\n\n"
 
 
 
23
  "class ReceiptData(BaseModel):\n"
24
- " fraud_check: Optional[bool] = False # Optional field for fraud detection, always set to false"
25
  " merchant: str #Only extract the brand name, not the branch name - Only the brand\n"
26
  " date: str\n"
27
  " total_amount: float\n #Try your hardest to find the accurate total amount\n"
@@ -29,6 +32,7 @@ reciept_system_prompt = (
29
  "- Extract only the above given information.\n"
30
  "- If a value is missing, set it to null, \"\", or an empty list as appropriate.\n"
31
  "- For the items field, provide a list of objects with description and amount.\n"
 
32
  "- Only return a valid JSON object matching the model above.\n"
33
  "- Do not add any explanation or extra text—only the JSON."
34
  )
@@ -166,4 +170,3 @@ def extract_child_fee_info(img_input, emp_name, emp_code, department):
166
  except Exception as e:
167
  print("ERROR:", e)
168
  return None # or f"Error: {str(e)}"
169
-
 
20
  "class ReceiptItem(BaseModel):\n"
21
  " description: str\n"
22
  " amount: float\n\n"
23
+ "class FraudData(BaseModel):\n"
24
+ " fraud_detected: bool \n"
25
+ " fraud_type: Optional[str] = None # Type of fraud if detected, e.g., \"duplicate\", \"suspicious\" \n\n"
26
  "class ReceiptData(BaseModel):\n"
27
+ " fraud_check: Optional[List[FraudData]] = [] # Optional field for fraud detection, always set to empty list\n"
28
  " merchant: str #Only extract the brand name, not the branch name - Only the brand\n"
29
  " date: str\n"
30
  " total_amount: float\n #Try your hardest to find the accurate total amount\n"
 
32
  "- Extract only the above given information.\n"
33
  "- If a value is missing, set it to null, \"\", or an empty list as appropriate.\n"
34
  "- For the items field, provide a list of objects with description and amount.\n"
35
+ "- For fraud_check, always set to an empty list [].\n"
36
  "- Only return a valid JSON object matching the model above.\n"
37
  "- Do not add any explanation or extra text—only the JSON."
38
  )
 
170
  except Exception as e:
171
  print("ERROR:", e)
172
  return None # or f"Error: {str(e)}"