-
Notifications
You must be signed in to change notification settings - Fork 3
/
creator.go
114 lines (95 loc) · 2.88 KB
/
creator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package importer
import (
"errors"
"github.com/envelope-zero/backend/v2/pkg/importer/types"
"github.com/envelope-zero/backend/v2/pkg/models"
"github.com/google/uuid"
"gorm.io/gorm"
)
func Create(db *gorm.DB, resources types.ParsedResources) (models.Budget, error) {
// Start a transaction so we can roll back all created resources if an error occurs
tx := db.Begin()
// Create the budget
budget := resources.Budget
err := tx.Create(&budget).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
// Create accounts
for name, r := range resources.Accounts {
// Set the Account ID & name and create the account
account := r.Model
account.AccountCreate.BudgetID = budget.ID
account.AccountCreate.Name = name
err := tx.Create(&account).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
// Update the account in the resources struct so that it also contains the ID
r.Model = account
resources.Accounts[name] = r
}
for cName, category := range resources.Categories {
category.Model.BudgetID = budget.ID
err := tx.Create(&category.Model).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
resources.Categories[cName] = category
// Add all envelopes
for eName, envelope := range category.Envelopes {
envelope.Model.CategoryID = category.Model.ID
err := tx.Create(&envelope.Model).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
resources.Categories[category.Model.Name].Envelopes[eName] = envelope
}
}
// Create transactions
for _, r := range resources.Transactions {
if r.Model.Amount.IsNegative() {
return models.Budget{}, errors.New("a transaction to be imported has a negative amount, this is invalid")
}
transaction := r.Model
transaction.BudgetID = budget.ID
transaction.SourceAccountID = resources.Accounts[r.SourceAccount].Model.ID
transaction.DestinationAccountID = resources.Accounts[r.DestinationAccount].Model.ID
envelopeID := resources.Categories[r.Category].Envelopes[r.Envelope].Model.ID
if envelopeID != uuid.Nil {
transaction.EnvelopeID = &envelopeID
}
err := tx.Create(&transaction).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
}
// Create allocations
for _, a := range resources.Allocations {
allocation := a.Model
allocation.AllocationCreate.EnvelopeID = resources.Categories[a.Category].Envelopes[a.Envelope].Model.ID
err := tx.Create(&allocation).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
}
// Create MonthConfigs
for _, m := range resources.MonthConfigs {
mConfig := m.Model
mConfig.EnvelopeID = resources.Categories[m.Category].Envelopes[m.Envelope].Model.ID
err := tx.Create(&mConfig).Error
if err != nil {
tx.Rollback()
return models.Budget{}, err
}
}
// No errors happened, commit the transaction
tx.Commit()
return budget, nil
}