github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/internal/db/base/income.go (about) 1 package base 2 3 import ( 4 "context" 5 "time" 6 7 common "github.com/ShoshinNikita/budget-manager/internal/db" 8 "github.com/ShoshinNikita/budget-manager/internal/db/base/internal/sqlx" 9 "github.com/ShoshinNikita/budget-manager/internal/db/base/types" 10 "github.com/ShoshinNikita/budget-manager/internal/pkg/errors" 11 "github.com/ShoshinNikita/budget-manager/internal/pkg/money" 12 ) 13 14 type Income struct { 15 ID uint `db:"id"` 16 MonthID uint `db:"month_id"` 17 Title string `db:"title"` 18 Notes types.String `db:"notes"` 19 Income money.Money `db:"income"` 20 } 21 22 // ToCommon converts Income to common Income structure from 23 // "github.com/ShoshinNikita/budget-manager/internal/db" package 24 func (in Income) ToCommon(year int, month time.Month) common.Income { 25 return common.Income{ 26 ID: in.ID, 27 Year: year, 28 Month: month, 29 Title: in.Title, 30 Notes: string(in.Notes), 31 Income: in.Income, 32 } 33 } 34 35 // AddIncome adds a new income with passed params 36 func (db DB) AddIncome(ctx context.Context, args common.AddIncomeArgs) (id uint, err error) { 37 err = db.db.RunInTransaction(ctx, func(tx *sqlx.Tx) (err error) { 38 if !checkMonth(tx, args.MonthID) { 39 return common.ErrMonthNotExist 40 } 41 42 err = tx.Get( 43 &id, 44 `INSERT INTO incomes(month_id, title, notes, income) VALUES(?, ?, ?, ?) RETURNING id`, 45 args.MonthID, args.Title, args.Notes, args.Income, 46 ) 47 if err != nil { 48 return err 49 } 50 return db.recomputeAndUpdateMonth(tx, args.MonthID) 51 }) 52 if err != nil { 53 return 0, err 54 } 55 56 return id, nil 57 } 58 59 // EditIncome edits income with passed id, nil args are ignored 60 func (db DB) EditIncome(ctx context.Context, args common.EditIncomeArgs) error { 61 return db.db.RunInTransaction(ctx, func(tx *sqlx.Tx) error { 62 if !checkIncome(tx, args.ID) { 63 return common.ErrIncomeNotExist 64 } 65 66 monthID, err := db.selectIncomeMonthID(tx, args.ID) 67 if err != nil { 68 return err 69 } 70 71 query := newUpdateQueryBuilder("incomes", args.ID) 72 if args.Title != nil { 73 query.Set("title", *args.Title) 74 } 75 if args.Notes != nil { 76 query.Set("notes", *args.Notes) 77 } 78 if args.Income != nil { 79 query.Set("income", *args.Income) 80 } 81 if _, err := tx.ExecQuery(query); err != nil { 82 return err 83 } 84 85 if args.Income != nil { 86 // Recompute month only when income has been changed 87 return db.recomputeAndUpdateMonth(tx, monthID) 88 } 89 return nil 90 }) 91 } 92 93 // RemoveIncome removes income with passed id 94 func (db DB) RemoveIncome(ctx context.Context, id uint) error { 95 return db.db.RunInTransaction(ctx, func(tx *sqlx.Tx) error { 96 if !checkIncome(tx, id) { 97 return common.ErrIncomeNotExist 98 } 99 100 monthID, err := db.selectIncomeMonthID(tx, id) 101 if err != nil { 102 return err 103 } 104 105 _, err = tx.Exec(`DELETE FROM incomes WHERE id = ?`, id) 106 if err != nil { 107 return err 108 } 109 110 return db.recomputeAndUpdateMonth(tx, monthID) 111 }) 112 } 113 114 func (DB) selectIncomeMonthID(tx *sqlx.Tx, id uint) (monthID uint, err error) { 115 err = tx.Get(&monthID, `SELECT month_id FROM incomes WHERE id = ?`, id) 116 if err != nil { 117 return 0, errors.Wrap(err, "couldn't select month id of Income") 118 } 119 return monthID, nil 120 }