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

Commit

Permalink
usergroup payment moneyprovider moneypoolのユースケースとハンドラとドメインを実装
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfmagnate committed Nov 4, 2023
1 parent 670682e commit 8e16c3e
Show file tree
Hide file tree
Showing 14 changed files with 959 additions and 84 deletions.
10 changes: 10 additions & 0 deletions back/domain/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ type DB interface {
GetMoneyPool(id string) (MoneyPool, error)
GetMoneyPoolsByUserID(userID string) ([]MoneyPool, error)
UpdateMoneyPool(moneyPool MoneyPool) error
DeleteMoneyPool(id string) error
ShareMoneyPoolWithUserGroups(moneyPoolID string, shareUserGruopIDs []string) error

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

NewStore(store Store) (Store, error)
GetStore(id string) (Store, error)
Expand All @@ -47,7 +49,15 @@ type DB interface {
GetPayment(id string) (Payment, error)
GetPaymentsByMoneyPoolID(moneyPoolID string) ([]Payment, error)
UpdatePayment(payment Payment) error
DeletePayment(id string) error

GetMoneyPoolBalance(moneyPoolID string, includeExpceted bool) (float64, error) // transactionからマネープールの残高を計算する
GetMoneyPoolBalanceOfDate(moneyPoolID string, date time.Time, includeExpceted bool) (float64, error) // transactionからマネープールの残高を計算する(ある日までの)

NewUserGroup(userGroup UserGroup) (UserGroup, error)
GetUserGroups(userID string) ([]UserGroup, error)
GetUserGroup(id string) (UserGroup, error)
GetUserGroupMembers(id string) ([]User, error)
UpdateUserGroup(id string, name string, memberIDs []string) (UserGroup, error)
DeleteUserGroup(id string) error
}
19 changes: 19 additions & 0 deletions back/domain/moneypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,22 @@ func (d *dbImpl) ShareMoneyPoolWithUserGroups(moneyPoolID string, shareUserGroup

return tx.Commit()
}

func (d *dbImpl) DeleteMoneyPool(id string) error {
query := `DELETE FROM money_pool WHERE id = $1`
result, err := d.db.Exec(query, id)
if err != nil {
return fmt.Errorf("could not delete money pool: %v", err)
}

// Execの結果から影響を受けた行の数を確認します。Deleteが実行されなかった場合にはエラーを返すことも可能です。
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("could not determine rows affected: %v", err)
}
if rowsAffected == 0 {
return fmt.Errorf("no rows affected, nothing to delete")
}

return nil
}
25 changes: 23 additions & 2 deletions back/domain/moneyprovider.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package domain

import "github.com/pkg/errors"
import (
"fmt"
)

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{}, fmt.Errorf("failed to create new MoneyProvider: %v", err)
}
return moneyProvider, nil
}
Expand All @@ -35,3 +37,22 @@ func (d *dbImpl) UpdateMoneyProvider(moneyProvider MoneyProvider) error {
_, err := d.db.NamedExec(query, moneyProvider)
return err
}

func (d *dbImpl) DeleteMoneyProvider(id string) error {
query := `DELETE FROM money_providers WHERE id = $1`
result, err := d.db.Exec(query, id)
if err != nil {
return fmt.Errorf("could not delete money provider: %v", err)
}

// 結果から影響を受けた行の数を確認します。
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("could not determine rows affected: %v", err)
}
if rowsAffected == 0 {
return fmt.Errorf("no rows affected, perhaps the money provider with id %s does not exist", id)
}

return nil
}
25 changes: 25 additions & 0 deletions back/domain/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,28 @@ func (d *dbImpl) UpdatePayment(payment Payment) error {
}
return nil
}

func (d *dbImpl) DeletePayment(id string) error {
// DELETE SQL文を実行します。
query := `DELETE FROM payment WHERE id = $1`
result, err := d.db.Exec(query, id)
if err != nil {
// SQL実行エラーを返します。
return fmt.Errorf("error deleting payment with id %s: %v", id, err)
}

// 影響を受けた行の数を確認します。
rowsAffected, err := result.RowsAffected()
if err != nil {
// 影響を受けた行数の確認エラーを返します。
return fmt.Errorf("error getting rows affected during deletion of payment with id %s: %v", id, err)
}

if rowsAffected == 0 {
// 削除する行がなかった場合、エラーを返します。
return fmt.Errorf("no payment found with id %s", id)
}

// 削除が成功した場合、nilを返します。
return nil
}
114 changes: 114 additions & 0 deletions back/domain/usergroup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package domain

import "fmt"

func (d *dbImpl) NewUserGroup(userGroup UserGroup) (UserGroup, error) {
query := `INSERT INTO user_groups (name, creator_id) VALUES ($1, $2) RETURNING id`
err := d.db.QueryRow(query, userGroup.Name, userGroup.CreatorID).Scan(&userGroup.ID)
if err != nil {
return UserGroup{}, fmt.Errorf("failed to create user group: %v", err)
}
return userGroup, nil
}

func (d *dbImpl) GetUserGroups(userID string) ([]UserGroup, error) {
var userGroups []UserGroup
query := `SELECT id, name, creator_id FROM user_groups WHERE creator_id = $1`
err := d.db.Select(&userGroups, query, userID)
if err != nil {
return nil, fmt.Errorf("failed to get user groups for user %s: %v", userID, err)
}
return userGroups, nil
}

func (d *dbImpl) GetUserGroup(id string) (UserGroup, error) {
var userGroup UserGroup
query := `SELECT id, name, creator_id FROM user_groups WHERE id = $1`
err := d.db.Get(&userGroup, query, id)
if err != nil {
return UserGroup{}, fmt.Errorf("failed to get user group with id %s: %v", id, err)
}
return userGroup, nil
}

func (d *dbImpl) GetUserGroupMembers(groupID string) ([]User, error) {
var users []User
query := `SELECT u.id FROM users u
JOIN user_group_membership ugm ON u.id = ugm.user_id
WHERE ugm.group_id = $1`
err := d.db.Select(&users, query, groupID)
if err != nil {
return nil, fmt.Errorf("failed to get users for group %s: %v", groupID, err)
}
return users, nil
}

func (d *dbImpl) UpdateUserGroup(id string, name string, memberIDs []string) (UserGroup, error) {
// Transaction start
tx, err := d.db.Beginx()
if err != nil {
return UserGroup{}, fmt.Errorf("failed to start transaction: %v", err)
}

// Update the user group name
query := `UPDATE user_groups SET name = $2 WHERE id = $1`
_, err = tx.Exec(query, id, name)
if err != nil {
tx.Rollback()
return UserGroup{}, fmt.Errorf("failed to update user group name: %v", err)
}

// Clear existing membership
_, err = tx.Exec(`DELETE FROM user_group_membership WHERE group_id = $1`, id)
if err != nil {
tx.Rollback()
return UserGroup{}, fmt.Errorf("failed to clear user group membership: %v", err)
}

// Add new members
for _, userID := range memberIDs {
_, err = tx.Exec(`INSERT INTO user_group_membership (group_id, user_id) VALUES ($1, $2)`, id, userID)
if err != nil {
tx.Rollback()
return UserGroup{}, fmt.Errorf("failed to add user to group: %v", err)
}
}

// Commit transaction
err = tx.Commit()
if err != nil {
return UserGroup{}, fmt.Errorf("failed to commit user group update: %v", err)
}

return d.GetUserGroup(id) // Fetch and return the updated user group
}

func (d *dbImpl) DeleteUserGroup(id string) error {
// Transaction start
tx, err := d.db.Beginx()
if err != nil {
return fmt.Errorf("failed to start transaction: %v", err)
}

// Delete entries from user_group_membership table first to avoid foreign key constraint violation
_, err = tx.Exec(`DELETE FROM user_group_membership WHERE group_id = $1`, id)
if err != nil {
tx.Rollback() // rollback if any error occurs
return fmt.Errorf("failed to delete user group memberships for group %s: %v", id, err)
}

// Delete the user group
_, err = tx.Exec(`DELETE FROM user_groups WHERE id = $1`, id)
if err != nil {
tx.Rollback() // rollback if any error occurs
return fmt.Errorf("failed to delete user group with id %s: %v", id, err)
}

// Commit transaction
err = tx.Commit()
if err != nil {
return fmt.Errorf("failed to commit delete operation for user group %s: %v", id, err)
}

return nil
}
106 changes: 24 additions & 82 deletions back/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"time"

"github.com/gin-gonic/gin"
"github.com/walnuts1018/openchokin/back/domain"
"github.com/walnuts1018/openchokin/back/usecase"
)

Expand Down Expand Up @@ -35,13 +34,34 @@ func NewHandler(usecase *usecase.Usecase) (*gin.Engine, error) {
// /moneyinformation?date=2023-05-15
v1.GET("/moneyinformation", moneyInformationHandler)

// リクエストボディの構造体を適切に定義してください
v1.POST("/moneypools/:moneypool_id/payments", postPayment)

// クエリパラメータmonthが必須パラメータである
// /payments?month=2023-05
v1.GET("/payments", getMonthlyPayments)

// Paymentの追加・修正・削除
v1.POST("/moneypools/:moneypool_id/payments", postPayment)
v1.PATCH("/moneypools/:moneypool_id/payments/:payment_id", updatePaymentHandler)
v1.DELETE("/moneypools/:moneypool_id/payments/:payment_id", deletePaymentHandler)

// MoneyProviderの追加・修正・削除
v1.POST("/moneyproviders", createMoneyProviderHandler)
v1.PATCH("/moneyproviders/:moneyprovider_id", updateMoneyProviderHandler)
v1.DELETE("/moneyproviders/:moneyprovider_id", deleteMoneyProviderHandler)

// MoneyPoolの追加・修正・削除
v1.POST("/moneypools", createMoneyPool)
v1.PATCH("/moneypools/:moneypool_id", updateMoneyPool)
v1.DELETE("/moneypools/:moneypool_id", deleteMoneyPool)
// 公開範囲の設定(対象となるマネープールに対して、リクエストのjsonで指定されたユーザーグループに対して)
v1.POST("/moneypools/:moneypool_id/publicationscope", changePublicationScope)

// ユーザーグループの編集
// これだけで詳細情報を全部取得する
v1.GET("/usergroups", getUserGroups)
v1.POST("/usergroups", createUserGroup)
v1.PATCH("/usergroups/:usergroup_id", updateUserGroup)
v1.DELETE("/usergroups/:usergroup_id", deleteUserGroup)

}
return r, nil
}
Expand Down Expand Up @@ -145,81 +165,3 @@ func moneyInformationHandler(c *gin.Context) {
// 成功レスポンスを返す
c.JSON(http.StatusOK, response)
}

// POST /moneypools/:moneypool_id/payments
// 指定されたマネープールに新しい支払いを追加する
func postPayment(c *gin.Context) {
userID := c.MustGet("userID").(string) // 認証ユーザーのIDを取得
moneyPoolID := c.Param("moneypool_id") // パスパラメータからマネープールIDを取得

// リクエストボディの構造体
var paymentRequest struct {
Title string `json:"title"`
Amount float64 `json:"amount"`
Description string `json:"description"`
IsPlanned bool `json:"is_planned"`
}
if err := c.BindJSON(&paymentRequest); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
return
}

err := uc.AddNewPayment(userID, moneyPoolID, paymentRequest.Title, paymentRequest.Amount, paymentRequest.Description, paymentRequest.IsPlanned)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.Status(http.StatusCreated)
}

// GET /payments
// 指定された月の支払い情報を取得する
func getMonthlyPayments(c *gin.Context) {
userID := c.MustGet("userID").(string) // 認証ユーザーのIDを取得
monthStr := c.Query("month") // クエリパラメータから月を取得

// "YYYY-MM"の形式であることを確認し、time.Time型にパースする
month, err := time.Parse("2006-01", monthStr)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid month format"})
return
}

response, err := uc.GetMonthlyPayments(userID, month)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, response)
}

func AddNewUser(c *gin.Context) {
user, err := uc.NewUser()
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"user": user})
}

func GetUser(c *gin.Context) {
userID := c.Param("userid")
user, err := uc.GetUser(userID)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"user": user})
}

func UpdateUser(c *gin.Context) {
userID := c.Param("userid")
user := domain.User{ID: userID}
err := uc.UpdateUser(user)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
}
c.JSON(200, gin.H{"user": user})
}
Loading

0 comments on commit 8e16c3e

Please sign in to comment.