budget-go/database/model/transaction.go
Simon Vieille 96c3c822cd
fix importation of transaction (type of request)
add importer for Banque Populaire transactions
2025-04-09 08:51:26 +02:00

166 lines
3.8 KiB
Go

package model
import (
"fmt"
"regexp"
"strings"
"time"
"gitnet.fr/deblan/budget/database/manager"
)
type Transaction struct {
ID uint `gorm:"primaryKey" json:"id"`
ShortLabel string `gorm:"not null" json:"short_label"`
Label string `gorm:"not null" json:"label"`
Reference string `gorm:"not null" json:"reference"`
Information string `json:"information"`
OperationType string `gorm:"not null" json:"operation_type"`
AccountedAt time.Time `json:"accounted_at"`
BankCategory string `json:"bank_category"`
BankSubCategory string `json:"bank_sub_category"`
Debit float64 `json:"debit"`
Credit float64 `json:"credit"`
Date time.Time `json:"date"`
BankAccountID int `gorm:"not null" json:"-"`
BankAccount *BankAccount `json:"bank_account"`
CategoryID *int `json:"-"`
Category *Category `json:"category"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func NewTransaction(label string) *Transaction {
transaction := Transaction{}
return &transaction
}
func (t *Transaction) MatchRule(rule CategoryRule) (bool, int) {
match := true
counter := 0
if rule.Contain != nil {
v := strings.ToLower(*rule.Contain)
match = strings.Contains(strings.ToLower(t.Label), v) || strings.Contains(strings.ToLower(t.ShortLabel), v) || strings.Contains(strings.ToLower(t.Reference), v)
if match {
counter += 8
}
}
if rule.Match != nil {
res, _ := regexp.MatchString(*rule.Match, t.Label)
match = match && res
if match {
counter += 8
}
}
if rule.BankCategory != nil {
v := strings.ToLower(*rule.BankCategory)
match = match && (strings.Contains(strings.ToLower(t.BankCategory), v) || strings.Contains(strings.ToLower(t.BankSubCategory), v))
if match {
counter += 6
}
}
if rule.Amount != nil {
match = match && t.Debit == *rule.Amount
if match {
counter += 4
}
}
if rule.DateFrom != nil {
match = match && t.Date.After(*rule.DateFrom)
if match {
counter += 2
}
}
if rule.DateTo != nil {
match = match && t.Date.Before(*rule.DateTo)
if match {
counter += 2
}
}
if match {
fmt.Printf("%+v\n", match)
}
return match, counter
}
func (t *Transaction) MatchCategory(category Category) (bool, int) {
maxCounter := 0
match := false
for _, rule := range category.Rules {
m, c := t.MatchRule(rule)
if m {
match = true
if c > maxCounter {
maxCounter = c
}
}
}
return match, maxCounter
}
func ImportTransactions(content string, bankAccountID int, format string) ([]Transaction, error) {
var datas []Transaction
var err error
if format == "revolut" {
datas, err = ImportRevolutTransactions(content, bankAccountID)
} else if format == "banque_populaire" {
datas, err = ImportBanquePopulaireTransactions(content, bankAccountID)
} else if format == "caisse_epargne" {
datas, err = ImportCaisseEpargneTransactions(content, bankAccountID)
}
UpdateTransactionsCategories()
return datas, err
}
func UpdateTransactionsCategories() []Transaction {
var categories []Category
var transactions []Transaction
var datas []Transaction
manager.Get().Db.Model(Category{}).Preload("Rules").Find(&categories)
manager.Get().Db.Model(Transaction{}).Find(&transactions)
for _, transaction := range transactions {
transaction.CategoryID = nil
maxCounter := -1
for _, category := range categories {
match, counter := transaction.MatchCategory(category)
if match && counter > maxCounter {
maxCounter = counter
var id int
id = int(category.ID)
transaction.CategoryID = &id
}
}
manager.Get().Db.Model(Transaction{}).Where("id = ?", transaction.ID).Save(&transaction)
datas = append(datas, transaction)
}
return datas
}