Add name_of_asset field to receipt processing and update related logic in DocumentProcessor
This commit is contained in:
@@ -91,6 +91,7 @@ class DBReceipt(Base):
|
|||||||
receipt_location = Column(String, nullable=True)
|
receipt_location = Column(String, nullable=True)
|
||||||
calculated_tax = Column(Float, nullable=True)
|
calculated_tax = Column(Float, nullable=True)
|
||||||
is_depreciable = Column(String, nullable=True) # Store as string "True"/"False"
|
is_depreciable = Column(String, nullable=True) # Store as string "True"/"False"
|
||||||
|
name_of_asset = Column(String, nullable=True) # Name/description of the asset
|
||||||
cca_rate = Column(Float, nullable=True)
|
cca_rate = Column(Float, nullable=True)
|
||||||
useful_life = Column(Integer, nullable=True)
|
useful_life = Column(Integer, nullable=True)
|
||||||
residual_value = Column(Float, nullable=True)
|
residual_value = Column(Float, nullable=True)
|
||||||
|
|||||||
+6
-4
@@ -369,7 +369,9 @@ async def upload_multiple_documents(
|
|||||||
response_model=DocumentProcessResponse,
|
response_model=DocumentProcessResponse,
|
||||||
tags=["Document Processing"],
|
tags=["Document Processing"],
|
||||||
)
|
)
|
||||||
async def process_document(file_id: str, request: DocumentProcessRequest, db: db_dependency):
|
async def process_document(
|
||||||
|
file_id: str, request: DocumentProcessRequest, db: db_dependency
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Process a previously uploaded document to extract receipt information.
|
Process a previously uploaded document to extract receipt information.
|
||||||
|
|
||||||
@@ -383,9 +385,7 @@ async def process_document(file_id: str, request: DocumentProcessRequest, db: db
|
|||||||
# Get file info from database
|
# Get file info from database
|
||||||
db_uploaded_file = get_uploaded_file_from_db(db, file_id)
|
db_uploaded_file = get_uploaded_file_from_db(db, file_id)
|
||||||
if not db_uploaded_file:
|
if not db_uploaded_file:
|
||||||
raise HTTPException(
|
raise HTTPException(status_code=404, detail=f"File {file_id} not found")
|
||||||
status_code=404, detail=f"File {file_id} not found"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Process the file using the stored file path
|
# Process the file using the stored file path
|
||||||
receipt_data = await document_processor.process_file(
|
receipt_data = await document_processor.process_file(
|
||||||
@@ -423,6 +423,7 @@ async def process_document(file_id: str, request: DocumentProcessRequest, db: db
|
|||||||
is_depreciable=str(receipt_data.get("is_depreciable"))
|
is_depreciable=str(receipt_data.get("is_depreciable"))
|
||||||
if receipt_data.get("is_depreciable") is not None
|
if receipt_data.get("is_depreciable") is not None
|
||||||
else None,
|
else None,
|
||||||
|
name_of_asset=receipt_data.get("name_of_asset"),
|
||||||
cca_rate=receipt_data.get("cca_rate"),
|
cca_rate=receipt_data.get("cca_rate"),
|
||||||
useful_life=receipt_data.get("useful_life"),
|
useful_life=receipt_data.get("useful_life"),
|
||||||
residual_value=receipt_data.get("residual_value"),
|
residual_value=receipt_data.get("residual_value"),
|
||||||
@@ -448,6 +449,7 @@ async def process_document(file_id: str, request: DocumentProcessRequest, db: db
|
|||||||
receipt_location=receipt_data.get("location"),
|
receipt_location=receipt_data.get("location"),
|
||||||
calculated_tax=receipt_data.get("calculated_tax"),
|
calculated_tax=receipt_data.get("calculated_tax"),
|
||||||
is_depreciable=receipt_data.get("is_depreciable"),
|
is_depreciable=receipt_data.get("is_depreciable"),
|
||||||
|
name_of_asset=receipt_data.get("name_of_asset"),
|
||||||
cca_rate=receipt_data.get("cca_rate"),
|
cca_rate=receipt_data.get("cca_rate"),
|
||||||
useful_life=receipt_data.get("useful_life"),
|
useful_life=receipt_data.get("useful_life"),
|
||||||
residual_value=receipt_data.get("residual_value"),
|
residual_value=receipt_data.get("residual_value"),
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ class DocumentProcessResponse(BaseModel):
|
|||||||
)
|
)
|
||||||
calculated_tax: Optional[float] = None # Calculated sales tax if not clearly shown
|
calculated_tax: Optional[float] = None # Calculated sales tax if not clearly shown
|
||||||
is_depreciable: Optional[bool] = None # Whether item is a depreciable asset
|
is_depreciable: Optional[bool] = None # Whether item is a depreciable asset
|
||||||
|
name_of_asset: Optional[str] = None # Name/description of the asset if depreciable
|
||||||
cca_rate: Optional[float] = (
|
cca_rate: Optional[float] = (
|
||||||
None # CCA rate for tax depreciation (e.g., 0.30 for 30%)
|
None # CCA rate for tax depreciation (e.g., 0.30 for 30%)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class DocumentProcessor:
|
|||||||
"location": "Province/State, Country",
|
"location": "Province/State, Country",
|
||||||
"calculated_tax": 0.00,
|
"calculated_tax": 0.00,
|
||||||
"is_depreciable": false,
|
"is_depreciable": false,
|
||||||
|
"name_of_asset": null,
|
||||||
"cca_rate": null,
|
"cca_rate": null,
|
||||||
"useful_life": null,
|
"useful_life": null,
|
||||||
"residual_value": null
|
"residual_value": null
|
||||||
@@ -117,6 +118,7 @@ class DocumentProcessor:
|
|||||||
- Determine if item is a depreciable asset (vehicles, machinery, equipment, computers, furniture, buildings)
|
- Determine if item is a depreciable asset (vehicles, machinery, equipment, computers, furniture, buildings)
|
||||||
- Set is_depreciable to true only for capital assets, false for consumables/services
|
- Set is_depreciable to true only for capital assets, false for consumables/services
|
||||||
- If is_depreciable is true, provide:
|
- If is_depreciable is true, provide:
|
||||||
|
* name_of_asset: Specific name/model of the asset (e.g., "2024 Honda Accord", "Dell Laptop XPS 15", "Office Desk")
|
||||||
* cca_rate: CCA rate as decimal (e.g., 0.30 for 30%, 0.20 for 20%, 0.04 for 4%)
|
* cca_rate: CCA rate as decimal (e.g., 0.30 for 30%, 0.20 for 20%, 0.04 for 4%)
|
||||||
- Class 10 (Vehicles): 30%
|
- Class 10 (Vehicles): 30%
|
||||||
- Class 8 (Furniture, equipment): 20%
|
- Class 8 (Furniture, equipment): 20%
|
||||||
@@ -125,7 +127,7 @@ class DocumentProcessor:
|
|||||||
- Class 10.1 (Passenger vehicles >$30k): 30%
|
- Class 10.1 (Passenger vehicles >$30k): 30%
|
||||||
* useful_life: Expected years of use (e.g., 5 for computers, 8 for vehicles, 10 for furniture)
|
* useful_life: Expected years of use (e.g., 5 for computers, 8 for vehicles, 10 for furniture)
|
||||||
* residual_value: Estimated value at end of life (typically 10% of purchase price for equipment, 20% for vehicles)
|
* residual_value: Estimated value at end of life (typically 10% of purchase price for equipment, 20% for vehicles)
|
||||||
- If is_depreciable is false, set cca_rate, useful_life, and residual_value to null
|
- If is_depreciable is false, set name_of_asset, cca_rate, useful_life, and residual_value to null
|
||||||
|
|
||||||
Return only valid JSON.
|
Return only valid JSON.
|
||||||
"""
|
"""
|
||||||
@@ -233,6 +235,7 @@ class DocumentProcessor:
|
|||||||
"location": "Province/State, Country",
|
"location": "Province/State, Country",
|
||||||
"calculated_tax": 0.00,
|
"calculated_tax": 0.00,
|
||||||
"is_depreciable": false,
|
"is_depreciable": false,
|
||||||
|
"name_of_asset": null,
|
||||||
"cca_rate": null,
|
"cca_rate": null,
|
||||||
"useful_life": null,
|
"useful_life": null,
|
||||||
"residual_value": null
|
"residual_value": null
|
||||||
@@ -273,6 +276,7 @@ class DocumentProcessor:
|
|||||||
- Determine if item is a depreciable asset (vehicles, machinery, equipment, computers, furniture, buildings)
|
- Determine if item is a depreciable asset (vehicles, machinery, equipment, computers, furniture, buildings)
|
||||||
- Set is_depreciable to true only for capital assets, false for consumables/services
|
- Set is_depreciable to true only for capital assets, false for consumables/services
|
||||||
- If is_depreciable is true, provide:
|
- If is_depreciable is true, provide:
|
||||||
|
* name_of_asset: Specific name/model of the asset (e.g., "2024 Honda Accord", "Dell Laptop XPS 15", "Office Desk")
|
||||||
* cca_rate: CCA rate as decimal (e.g., 0.30 for 30%, 0.20 for 20%, 0.04 for 4%)
|
* cca_rate: CCA rate as decimal (e.g., 0.30 for 30%, 0.20 for 20%, 0.04 for 4%)
|
||||||
- Class 10 (Vehicles): 30%
|
- Class 10 (Vehicles): 30%
|
||||||
- Class 8 (Furniture, equipment): 20%
|
- Class 8 (Furniture, equipment): 20%
|
||||||
@@ -281,7 +285,7 @@ class DocumentProcessor:
|
|||||||
- Class 10.1 (Passenger vehicles >$30k): 30%
|
- Class 10.1 (Passenger vehicles >$30k): 30%
|
||||||
* useful_life: Expected years of use (e.g., 5 for computers, 8 for vehicles, 10 for furniture)
|
* useful_life: Expected years of use (e.g., 5 for computers, 8 for vehicles, 10 for furniture)
|
||||||
* residual_value: Estimated value at end of life (typically 10% of purchase price for equipment, 20% for vehicles)
|
* residual_value: Estimated value at end of life (typically 10% of purchase price for equipment, 20% for vehicles)
|
||||||
- If is_depreciable is false, set cca_rate, useful_life, and residual_value to null
|
- If is_depreciable is false, set name_of_asset, cca_rate, useful_life, and residual_value to null
|
||||||
|
|
||||||
Return only valid JSON.
|
Return only valid JSON.
|
||||||
"""
|
"""
|
||||||
@@ -349,6 +353,9 @@ class DocumentProcessor:
|
|||||||
is_depreciable_match = re.search(
|
is_depreciable_match = re.search(
|
||||||
r'"is_depreciable"\s*:\s*(true|false)', json_str
|
r'"is_depreciable"\s*:\s*(true|false)', json_str
|
||||||
)
|
)
|
||||||
|
name_of_asset_match = re.search(
|
||||||
|
r'"name_of_asset"\s*:\s*"([^"]*)"', json_str
|
||||||
|
)
|
||||||
cca_rate_match = re.search(
|
cca_rate_match = re.search(
|
||||||
r'"cca_rate"\s*:\s*([0-9.]+|null)', json_str
|
r'"cca_rate"\s*:\s*([0-9.]+|null)', json_str
|
||||||
)
|
)
|
||||||
@@ -388,6 +395,9 @@ class DocumentProcessor:
|
|||||||
"is_depreciable": is_depreciable_match.group(1) == "true"
|
"is_depreciable": is_depreciable_match.group(1) == "true"
|
||||||
if is_depreciable_match
|
if is_depreciable_match
|
||||||
else None,
|
else None,
|
||||||
|
"name_of_asset": name_of_asset_match.group(1)
|
||||||
|
if name_of_asset_match
|
||||||
|
else None,
|
||||||
"cca_rate": float(cca_rate_match.group(1))
|
"cca_rate": float(cca_rate_match.group(1))
|
||||||
if cca_rate_match and cca_rate_match.group(1) != "null"
|
if cca_rate_match and cca_rate_match.group(1) != "null"
|
||||||
else None,
|
else None,
|
||||||
@@ -414,6 +424,7 @@ class DocumentProcessor:
|
|||||||
"location": data.get("location"),
|
"location": data.get("location"),
|
||||||
"calculated_tax": data.get("calculated_tax"),
|
"calculated_tax": data.get("calculated_tax"),
|
||||||
"is_depreciable": data.get("is_depreciable"),
|
"is_depreciable": data.get("is_depreciable"),
|
||||||
|
"name_of_asset": data.get("name_of_asset"),
|
||||||
"cca_rate": data.get("cca_rate"),
|
"cca_rate": data.get("cca_rate"),
|
||||||
"useful_life": data.get("useful_life"),
|
"useful_life": data.get("useful_life"),
|
||||||
"residual_value": data.get("residual_value"),
|
"residual_value": data.get("residual_value"),
|
||||||
@@ -489,6 +500,7 @@ class DocumentProcessor:
|
|||||||
"location": None,
|
"location": None,
|
||||||
"calculated_tax": None,
|
"calculated_tax": None,
|
||||||
"is_depreciable": None,
|
"is_depreciable": None,
|
||||||
|
"name_of_asset": None,
|
||||||
"cca_rate": None,
|
"cca_rate": None,
|
||||||
"useful_life": None,
|
"useful_life": None,
|
||||||
"residual_value": None,
|
"residual_value": None,
|
||||||
@@ -508,6 +520,7 @@ class DocumentProcessor:
|
|||||||
"location": None,
|
"location": None,
|
||||||
"calculated_tax": None,
|
"calculated_tax": None,
|
||||||
"is_depreciable": None,
|
"is_depreciable": None,
|
||||||
|
"name_of_asset": None,
|
||||||
"cca_rate": None,
|
"cca_rate": None,
|
||||||
"useful_life": None,
|
"useful_life": None,
|
||||||
"residual_value": None,
|
"residual_value": None,
|
||||||
|
|||||||
Reference in New Issue
Block a user