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  }