Added quickbooks data

This commit is contained in:
bolade
2025-10-23 19:37:50 +01:00
parent 01aa2efa43
commit 7296d09319
3 changed files with 170 additions and 24 deletions
+14
View File
@@ -82,6 +82,20 @@ class DBTransaction(Base):
categorisation_id = Column(String, nullable=True)
user_id = Column(String, nullable=True)
# Additional QuickBooks CSV columns
TxnId = Column(String, nullable=True)
AccountType = Column(String, nullable=True)
AccountNumber = Column(String, nullable=True)
TransactionDate = Column(String, nullable=True)
TransactionType = Column(String, nullable=True)
ChequeNumber = Column(String, nullable=True)
Description1 = Column(String, nullable=True)
Description2 = Column(String, nullable=True)
VendorId = Column(String, nullable=True)
VendorName = Column(String, nullable=True)
AccountId = Column(String, nullable=True)
AccountName = Column(String, nullable=True)
# Uploaded Files table
class DBUploadedFile(Base):
+114 -24
View File
@@ -133,46 +133,75 @@ async def import_transactions_csv(
errors = []
for idx, row in enumerate(reader):
try:
# Use correct headers and strip whitespace
account_number = row.get("Account Number") or row.get(
"Account Number ".strip()
# Extract all CSV columns with proper header handling
txn_id = row.get("TxnId", "").strip()
account_type = row.get("Account Type", "").strip()
account_number = row.get("Account Number", "").strip()
transaction_date = row.get("Transaction Date", "").strip()
transaction_type = row.get("Transaction Type", "").strip()
cheque_number = row.get("Cheque Number", "").strip()
description_1 = row.get("Description 1", "").strip()
description_2 = row.get("Description 2", "").strip()
amount_raw = row.get("Amount", "").strip()
vendor_id = row.get("VendorId", "").strip()
vendor_name = row.get("VendorName", "").strip()
account_id = row.get("AccountId", "").strip()
account_name = row.get("AccountName", "").strip()
# Compose internal ID
internal_txn_id = (
f"{account_number}_{idx + 1}"
if account_number
else f"txn_{idx + 1}"
)
txn_date_raw = row.get("Transaction Date") or row.get(
"Transaction Date ".strip() or row.get("Date")
)
amount_raw = row.get("Amount") or row.get("Amount ".strip())
payee_name = row.get("Description 2") or row.get(
"Description 2 ".strip()
)
memo = f"{row.get('Account Type', '').strip()} {row.get('Cheque Number', '').strip()} {row.get('Description 1', '').strip()}".strip()
# Compose ID
txn_id = f"{account_number}_{idx + 1}"
# Parse date (try multiple formats)
txn_date_str = txn_date_raw.strip()
txn_date = None
for fmt in ("%m/%d/%y", "%m/%d/%Y"):
for fmt in ("%m/%d/%y", "%m/%d/%Y", "%Y-%m-%d"):
try:
txn_date = datetime.strptime(txn_date_str, fmt).strftime(
txn_date = datetime.strptime(transaction_date, fmt).strftime(
"%Y-%m-%d"
)
break
except Exception:
continue
if not txn_date:
raise ValueError(f"Could not parse date: {txn_date_str}")
# Parse amount
amount = float(amount_raw.replace(",", "").strip())
raise ValueError(f"Could not parse date: {transaction_date}")
# Create database transaction object
# Parse amount
amount = (
float(amount_raw.replace(",", "").strip()) if amount_raw else 0.0
)
# Use vendor_name (Description 2) as the vendor, fallback to description_2
vendor = vendor_name if vendor_name else description_2
# Compose description/memo from multiple fields
memo = f"{account_type} {cheque_number} {description_1}".strip()
# Create database transaction object with all QuickBooks fields
txn_date_obj = datetime.strptime(txn_date, "%Y-%m-%d")
db_transaction = DBTransaction(
transaction_id=txn_id,
transaction_id=internal_txn_id,
amount=amount,
date=txn_date_obj,
vendor=payee_name.strip(),
vendor=vendor,
description=memo,
categorisation_id=categorization_id,
user_id=user_id,
# QuickBooks CSV columns
TxnId=txn_id,
AccountType=account_type,
AccountNumber=account_number,
TransactionDate=transaction_date,
TransactionType=transaction_type,
ChequeNumber=cheque_number,
Description1=description_1,
Description2=description_2,
VendorId=vendor_id,
VendorName=vendor_name,
AccountId=account_id,
AccountName=account_name,
)
# Add to database
@@ -180,13 +209,26 @@ async def import_transactions_csv(
transactions.append(
{
"id": txn_id,
"id": internal_txn_id,
"txn_date": txn_date,
"amount": amount,
"payee_name": payee_name.strip(),
"payee_name": vendor,
"memo": memo,
"categorization_id": categorization_id,
"user_id": user_id,
# Include QuickBooks fields in response
"TxnId": txn_id,
"AccountType": account_type,
"AccountNumber": account_number,
"TransactionDate": transaction_date,
"TransactionType": transaction_type,
"ChequeNumber": cheque_number,
"Description1": description_1,
"Description2": description_2,
"VendorId": vendor_id,
"VendorName": vendor_name,
"AccountId": account_id,
"AccountName": account_name,
}
)
except Exception as e:
@@ -572,6 +614,19 @@ async def match_specific_receipts(request: MatchSpecificRequest, db: db_dependen
amount=db_txn.amount,
vendor=db_txn.vendor,
notes=db_txn.description or "",
# QuickBooks CSV fields
TxnId=db_txn.TxnId,
AccountType=db_txn.AccountType,
AccountNumber=db_txn.AccountNumber,
TransactionDate=db_txn.TransactionDate,
TransactionType=db_txn.TransactionType,
ChequeNumber=db_txn.ChequeNumber,
Description1=db_txn.Description1,
Description2=db_txn.Description2,
VendorId=db_txn.VendorId,
VendorName=db_txn.VendorName,
AccountId=db_txn.AccountId,
AccountName=db_txn.AccountName,
)
transactions.append(transaction)
except Exception as e:
@@ -697,6 +752,41 @@ async def match_specific_receipts(request: MatchSpecificRequest, db: db_dependen
tax_analysis=result.tax_analysis,
flag_for_review=flag_for_review,
auto_approve=auto_approve,
# QuickBooks CSV fields
TxnId=result.transaction.TxnId if result.transaction else None,
AccountType=result.transaction.AccountType
if result.transaction
else None,
AccountNumber=result.transaction.AccountNumber
if result.transaction
else None,
TransactionDate=result.transaction.TransactionDate
if result.transaction
else None,
TransactionType=result.transaction.TransactionType
if result.transaction
else None,
ChequeNumber=result.transaction.ChequeNumber
if result.transaction
else None,
Description1=result.transaction.Description1
if result.transaction
else None,
Description2=result.transaction.Description2
if result.transaction
else None,
VendorId=result.transaction.VendorId
if result.transaction
else None,
VendorName=result.transaction.VendorName
if result.transaction
else None,
AccountId=result.transaction.AccountId
if result.transaction
else None,
AccountName=result.transaction.AccountName
if result.transaction
else None,
)
match_responses.append(match_response)
+42
View File
@@ -44,6 +44,20 @@ class Transaction:
currency: str = "CAD"
fx_rate: Optional[float] = None
# QuickBooks CSV fields
TxnId: Optional[str] = None
AccountType: Optional[str] = None
AccountNumber: Optional[str] = None
TransactionDate: Optional[str] = None
TransactionType: Optional[str] = None
ChequeNumber: Optional[str] = None
Description1: Optional[str] = None
Description2: Optional[str] = None
VendorId: Optional[str] = None
VendorName: Optional[str] = None
AccountId: Optional[str] = None
AccountName: Optional[str] = None
@dataclass
class Asset:
@@ -102,6 +116,20 @@ class TransactionRequest(BaseModel):
currency: str = "CAD"
fx_rate: Optional[float] = None
# QuickBooks CSV fields
TxnId: Optional[str] = None
AccountType: Optional[str] = None
AccountNumber: Optional[str] = None
TransactionDate: Optional[str] = None
TransactionType: Optional[str] = None
ChequeNumber: Optional[str] = None
Description1: Optional[str] = None
Description2: Optional[str] = None
VendorId: Optional[str] = None
VendorName: Optional[str] = None
AccountId: Optional[str] = None
AccountName: Optional[str] = None
class AssetRequest(BaseModel):
id: str
@@ -135,6 +163,20 @@ class MatchResponse(BaseModel):
flag_for_review: Optional[bool] = None
auto_approve: Optional[bool] = None
# QuickBooks CSV fields from transaction
TxnId: Optional[str] = None
AccountType: Optional[str] = None
AccountNumber: Optional[str] = None
TransactionDate: Optional[str] = None
TransactionType: Optional[str] = None
ChequeNumber: Optional[str] = None
Description1: Optional[str] = None
Description2: Optional[str] = None
VendorId: Optional[str] = None
VendorName: Optional[str] = None
AccountId: Optional[str] = None
AccountName: Optional[str] = None
class MatchingResponse(BaseModel):
matches: List[MatchResponse]