Skip to content
This repository has been archived by the owner on Dec 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #10 from walnuts1018/implDomain
Browse files Browse the repository at this point in the history
Impl domain
  • Loading branch information
walnuts1018 authored Nov 3, 2023
2 parents a21b801 + a7fea94 commit a902df4
Show file tree
Hide file tree
Showing 14 changed files with 477 additions and 74 deletions.
3 changes: 2 additions & 1 deletion back-dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM golang:1.21 as builder
WORKDIR /app

CMD ["go", "run","main.go"]
# CMD ["go", "run","main.go"]
CMD ["bash"]
46 changes: 46 additions & 0 deletions back/domain/calc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package domain

import "time"

// getMoneyPoolBalanceInternal is a helper function that constructs the SQL query for retrieving the money pool balance.
// It is used to avoid repetition in public methods.
func (d *dbImpl) getMoneyPoolBalanceInternal(moneyPoolID string, date *time.Time, includePlanned bool) (float64, error) {
var balance float64
query := `SELECT SUM(amount) FROM payment WHERE money_pool_id = $1`
args := []interface{}{moneyPoolID}

// Add date condition if it is provided
if date != nil {
query += ` AND date <= $2`
args = append(args, *date)
}

// Exclude planned payments if not included
if !includePlanned {
query += ` AND is_planned = false`
}

err := d.db.Get(&balance, query, args...)
if err != nil {
return 0, err
}

// Handle cases where SUM may return NULL if there are no rows
if balance == 0 {
return 0, nil
}

return balance, nil
}

// GetMoneyPoolBalance calculates the total amount of payments associated with the specified moneyPoolID.
// If includePlanned is true, it includes the planned payments in the calculation.
func (d *dbImpl) GetMoneyPoolBalance(moneyPoolID string, includePlanned bool) (float64, error) {
return d.getMoneyPoolBalanceInternal(moneyPoolID, nil, includePlanned)
}

// GetMoneyPoolBalanceOfDate calculates the total amount of payments for a moneyPoolID up to a certain date.
// If includePlanned is true, it includes the planned payments in the calculation.
func (d *dbImpl) GetMoneyPoolBalanceOfDate(moneyPoolID string, date time.Time, includePlanned bool) (float64, error) {
return d.getMoneyPoolBalanceInternal(moneyPoolID, &date, includePlanned)
}
35 changes: 25 additions & 10 deletions back/domain/db.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,52 @@
package domain

import "time"
import (
"time"

"github.com/jmoiron/sqlx"
)

type dbImpl struct {
db *sqlx.DB
}

// NewDB creates a new dbImpl and returns it as a DB interface.
func NewDB(db *sqlx.DB) DB {
return &dbImpl{
db: db,
}
}

type DB interface {
NewUser() (User, error)
GetUser(id string) (User, error)
UpdateUser(user User) error

NewMoneyPool(moneyPool MoneyPool) error
NewMoneyPool(moneyPool MoneyPool) (MoneyPool, error)
GetMoneyPool(id string) (MoneyPool, error)
GetMoneyPoolsByUserID(userID string) ([]MoneyPool, error)
UpdateMoneyPool(moneyPool MoneyPool) error
UpdateMoneyPoolShareUserIDs(moneyPoolID string, shareUserIDs []string) error
ShareMoneyPoolWithUserGroups(moneyPoolID string, shareUserGruopIDs []string) error

NewMoneyProvider(moneyProvider MoneyProvider) error
NewMoneyProvider(moneyProvider MoneyProvider) (MoneyProvider, error)
GetMoneyProvider(id string) (MoneyProvider, error)
GetMoneyProvidersByUserID(userID string) ([]MoneyProvider, error)
UpdateMoneyProvider(moneyProvider MoneyProvider) error

NewStore(store Store) error
NewStore(store Store) (Store, error)
GetStore(id string) (Store, error)
GetStoresByUserID(userID string) ([]Store, error)
UpdateStore(store Store) error

NewItem(item Item) error
NewItem(item Item) (Item, error)
GetItem(id string) (Item, error)
GetItemsByUserID(userID string) ([]Item, error)
UpdateItem(item Item) error

NewMoneyTransaction(moneyTransaction MoneyTransaction) error
GetMoneyTransaction(id string) (MoneyTransaction, error)
GetMoneyTransactionsByMoneyPoolID(moneyPoolID string) ([]MoneyTransaction, error)
UpdateMoneyTransaction(moneyTransaction MoneyTransaction) error
NewPayment(payment Payment) (Payment, error)
GetPayment(id string) (Payment, error)
GetPaymentsByMoneyPoolID(moneyPoolID string) ([]Payment, error)
UpdatePayment(payment Payment) error

GetMoneyPoolBalance(moneyPoolID string, includeExpceted bool) (float64, error) // transactionからマネープールの残高を計算する
GetMoneyPoolBalanceOfDate(moneyPoolID string, date time.Time, includeExpceted bool) (float64, error) // transactionからマネープールの残高を計算する(ある日までの)
Expand Down
48 changes: 48 additions & 0 deletions back/domain/item.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package domain

import (
"fmt"

"github.com/pkg/errors"
)

func (d *dbImpl) NewItem(item Item) (Item, error) {
query := `INSERT INTO item (name, creator_id)
VALUES (:name, :creator_id)
RETURNING id`
err := d.db.QueryRowx(query, item).StructScan(&item)
if err != nil {
return Item{}, errors.Wrap(err, "Failed to create new Item")
}
return item, nil
}

// GetItem retrieves an item by its ID.
func (d *dbImpl) GetItem(id string) (Item, error) {
var item Item
err := d.db.Get(&item, "SELECT * FROM item WHERE id = $1", id)
if err != nil {
return Item{}, fmt.Errorf("error fetching item: %v", err)
}
return item, nil
}

// GetItemsByUserID retrieves all items created by a specific user.
func (d *dbImpl) GetItemsByUserID(userID string) ([]Item, error) {
var items []Item
err := d.db.Select(&items, "SELECT * FROM item WHERE creator_id = $1", userID)
if err != nil {
return nil, err
}
return items, nil
}

// UpdateItem updates an existing item.
func (d *dbImpl) UpdateItem(item Item) error {
query := `UPDATE item SET name = :name, creator_id = :creator_id WHERE id = :id`
_, err := d.db.Exec(query, item)
if err != nil {
return fmt.Errorf("error updating item: %v", err)
}
return nil
}
104 changes: 104 additions & 0 deletions back/domain/moneypool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package domain

import (
"fmt"

"github.com/pkg/errors"
)

func (d *dbImpl) NewMoneyPool(moneyPool MoneyPool) (MoneyPool, error) {
query := `INSERT INTO money_pool (name, description, type, owner_id)
VALUES (:name, :description, :type, :owner_id)
RETURNING id`
err := d.db.QueryRowx(query, moneyPool).StructScan(&moneyPool)
if err != nil {
return MoneyPool{}, errors.Wrap(err, "Failed to create new MoneyPool")
}
return moneyPool, nil
}

func (d *dbImpl) GetMoneyPool(id string) (MoneyPool, error) {
var moneyPool MoneyPool
query := `SELECT * FROM money_pool WHERE id = $1`
err := d.db.Get(&moneyPool, query, id)
if err != nil {
return MoneyPool{}, fmt.Errorf("could not find money pool: %v", err)
}
return moneyPool, nil
}

func (d *dbImpl) GetMoneyPoolsByUserID(userID string) ([]MoneyPool, error) {
var moneyPools []MoneyPool
query := `SELECT * FROM money_pool WHERE owner_id = $1`
err := d.db.Select(&moneyPools, query, userID)
if err != nil {
return nil, fmt.Errorf("could not find money pools for user: %v", err)
}
return moneyPools, nil
}

func (d *dbImpl) UpdateMoneyPool(moneyPool MoneyPool) error {
tx, err := d.db.Beginx()
if err != nil {
return err
}

var currentType PublicType
err = tx.Get(&currentType, "SELECT type FROM money_pool WHERE id = $1", moneyPool.ID)
if err != nil {
tx.Rollback()
return err
}

if currentType == PublicTypeRestricted && moneyPool.Type != PublicTypeRestricted {
_, err := tx.Exec("DELETE FROM restricted_publication_scope WHERE pool_id = $1", moneyPool.ID)
if err != nil {
tx.Rollback()
return err
}
}

query := `UPDATE money_pool SET name = :name, description = :description, type = :type, owner_id = :owner_id WHERE id = :id`
_, err = tx.NamedExec(query, moneyPool)
if err != nil {
tx.Rollback()
return err
}

return tx.Commit()
}

func (d *dbImpl) ShareMoneyPoolWithUserGroups(moneyPoolID string, shareUserGroupIDs []string) error {
tx, err := d.db.Beginx()
if err != nil {
return err
}

var poolType PublicType
err = tx.Get(&poolType, "SELECT type FROM money_pool WHERE id = $1", moneyPoolID)
if err != nil {
tx.Rollback()
return err
}

if poolType != PublicTypeRestricted {
tx.Rollback()
return errors.New("money pool must be of type 'restricted' to share with user groups")
}

_, err = tx.Exec("DELETE FROM restricted_publication_scope WHERE pool_id = $1", moneyPoolID)
if err != nil {
tx.Rollback()
return err
}

for _, groupID := range shareUserGroupIDs {
_, err := tx.Exec("INSERT INTO restricted_publication_scope (pool_id, group_id) VALUES ($1, $2)", moneyPoolID, groupID)
if err != nil {
tx.Rollback()
return err
}
}

return tx.Commit()
}
37 changes: 37 additions & 0 deletions back/domain/moneyprovider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package domain

import "github.com/pkg/errors"

func (d *dbImpl) NewMoneyProvider(moneyProvider MoneyProvider) (MoneyProvider, error) {
query := `INSERT INTO money_providers (name, creator_id, balance)
VALUES (:name, :creator_id, :balance)
RETURNING id`
err := d.db.QueryRowx(query, moneyProvider).StructScan(&moneyProvider)
if err != nil {
return MoneyProvider{}, errors.Wrap(err, "Failed to create new MoneyProvider")
}
return moneyProvider, nil
}

// GetMoneyProvider retrieves a money provider by its ID.
func (d *dbImpl) GetMoneyProvider(id string) (MoneyProvider, error) {
var moneyProvider MoneyProvider
query := `SELECT id, name, creator_id, balance FROM money_provider WHERE id = $1`
err := d.db.Get(&moneyProvider, query, id)
return moneyProvider, err
}

// GetMoneyProvidersByUserID retrieves all money providers created by a specific user.
func (d *dbImpl) GetMoneyProvidersByUserID(userID string) ([]MoneyProvider, error) {
var moneyProviders []MoneyProvider
query := `SELECT id, name, creator_id, balance FROM money_provider WHERE creator_id = $1`
err := d.db.Select(&moneyProviders, query, userID)
return moneyProviders, err
}

// UpdateMoneyProvider updates an existing money provider in the database.
func (d *dbImpl) UpdateMoneyProvider(moneyProvider MoneyProvider) error {
query := `UPDATE money_provider SET name = :name, balance = :balance WHERE id = :id`
_, err := d.db.NamedExec(query, moneyProvider)
return err
}
46 changes: 46 additions & 0 deletions back/domain/payment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package domain

import "fmt"

func (d *dbImpl) NewPayment(payment Payment) (Payment, error) {
query := `INSERT INTO payment (money_pool_id, date, title, amount, description, is_planned, store_id)
VALUES (:money_pool_id, :transaction_date, :title, :amount, :description, :is_expectation, :store_id)
RETURNING id`
err := d.db.QueryRowx(query, payment).StructScan(&payment)
if err != nil {
return Payment{}, fmt.Errorf("failed to create new Payment: %v", err)
}
return payment, nil
}

// GetPayment retrieves a single payment by its ID.
func (d *dbImpl) GetPayment(id string) (Payment, error) {
var payment Payment
query := `SELECT id, money_pool_id, date, title, amount, description, is_planned, store_id FROM payment WHERE id = $1`
err := d.db.Get(&payment, query, id)
if err != nil {
return Payment{}, fmt.Errorf("error fetching payment: %v", err)
}
return payment, nil
}

// GetPaymentsByMoneyPoolID retrieves all payments associated with a specific money pool.
func (d *dbImpl) GetPaymentsByMoneyPoolID(moneyPoolID string) ([]Payment, error) {
var payments []Payment
query := `SELECT id, money_pool_id, date, title, amount, description, is_planned, store_id FROM payment WHERE money_pool_id = $1`
err := d.db.Select(&payments, query, moneyPoolID)
if err != nil {
return nil, fmt.Errorf("error fetching payments: %v", err)
}
return payments, nil
}

// UpdatePayment updates an existing payment's details.
func (d *dbImpl) UpdatePayment(payment Payment) error {
query := `UPDATE payment SET money_pool_id = $1, date = $2, title = $3, amount = $4, description = $5, is_planned = $6, store_id = $7 WHERE id = $8`
_, err := d.db.Exec(query, payment.MoneyPoolID, payment.Date, payment.Title, payment.Amount, payment.Description, payment.IsPlanned, payment.StoreID, payment.ID)
if err != nil {
return fmt.Errorf("error updating payment: %v", err)
}
return nil
}
Loading

0 comments on commit a902df4

Please sign in to comment.