166 lines
3.8 KiB
Go
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
|
|
}
|