Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

購入申請登録時にSlack通知 #845

Merged
merged 5 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 90 additions & 28 deletions api/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1605,6 +1605,29 @@ const docTemplate = `{
}
},
},
"/purchaseorders/send/{id}": {
"post": {
tags: ["purchase_order"],
"description": "IDで指定されたpurchase_orderのslackへメッセージ送信",
"parameters": [
{
"name": "id",
"in": "path",
"description": "id",
"required": true,
"type": "integer"
},
{
"in": "body",
"name": "purchase_items",
"type": "array",
"items":{
"$ref": "#/definitions/purchaseItem"
},
},
]
}
},
"/purchaseorders/details/unregistered/{year}": {
"get": {
tags: ["purchase_order"],
Expand Down Expand Up @@ -2890,6 +2913,73 @@ const docTemplate = `{
"purchaseOrderID"
},
},
"purchaseItem":{
"properties":{
"item":{
"type": "string",
"example": "name",
},
"price":{
"type": "int",
"example": 0,
},
"quantity":{
"type": "int",
"example": 0,
},
"detail":{
"type": "string",
"example": "",
},
"url":{
"type": "string",
"example": "",
},
"purchaseOrderID":{
"type": "int",
"example": 1,
},
"financeCheck":{
"type": "boolean",
"example": false,
},
},
"required":{
"item",
"price",
"quantity",
"financeCheck",
"purchaseOrderID"
},
},
"destroyTeacherIDs":{
"properties":{
"deleteIDs":{
"type": "array",
"items": {
"type": "number"
},
example: []
},
},
"required":{
"deleteIDs",
},
},
"destroyUserIDs":{
"properties":{
"deleteIDs":{
"type": "array",
"items": {
"type": "number"
},
example: []
},
},
"required":{
"deleteIDs",
},
},
"receipt":{
"properties":{
"purchaseReportID":{
Expand Down Expand Up @@ -2917,34 +3007,6 @@ const docTemplate = `{
"purchaseReportID",
},
},
"destroyTeacherIDs":{
"properties":{
"deleteIDs":{
"type": "array",
"items": {
"type": "number"
},
example: []
},
},
"required":{
"deleteIDs",
},
},
"destroyUserIDs":{
"properties":{
"deleteIDs":{
"type": "array",
"items": {
"type": "number"
},
example: []
},
},
"required":{
"deleteIDs",
},
},
"year_periods":{
"properties":{
"year":{
Expand Down
19 changes: 19 additions & 0 deletions api/externals/controller/purhcase_order_controller.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package controller

import (
"fmt"
"net/http"

"github.com/NUTFes/FinanSu/api/internals/domain"
"github.com/NUTFes/FinanSu/api/internals/usecase"
"github.com/labstack/echo/v4"
)
Expand All @@ -20,6 +22,7 @@ type PurchaseOrderController interface {
IndexOrderDetail(echo.Context) error
ShowOrderDetail(echo.Context) error
IndexOrderDetailByYear(echo.Context) error
NotifySlack(echo.Context) error
IndexUnregisteredOrderDetailByYear(echo.Context) error
}

Expand Down Expand Up @@ -111,6 +114,22 @@ func (p *purchaseOrderController) IndexOrderDetailByYear(c echo.Context) error {
return c.JSON(http.StatusOK, orderDetails)
}

//通知用API
// TODO いずれは購入申請と物品を一括送信してSlack通知をするようにフロント・バックのリファクタリングを行う
func (p *purchaseOrderController) NotifySlack(c echo.Context) error {
id := c.Param("id")
purchaseItems := new([]domain.PurchaseItem)
if err := c.Bind(purchaseItems); err != nil {
fmt.Println("err")
return err
}
err := p.u.NotifySlack(c.Request().Context(), id, *purchaseItems)
if err != nil {
return err
}
return c.JSON(http.StatusOK, err)
}

func (p *purchaseOrderController) IndexUnregisteredOrderDetailByYear(c echo.Context) error {
year := c.Param("year")
orderDetails, err := p.u.GetUnregisteredPurchaseOrderDetailsByYear(c.Request().Context(), year)
Expand Down
31 changes: 31 additions & 0 deletions api/externals/repository/purchase_order_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ package repository
import (
"context"
"database/sql"
"fmt"
"os"

"github.com/NUTFes/FinanSu/api/drivers/db"
"github.com/NUTFes/FinanSu/api/externals/repository/abstract"
"github.com/NUTFes/FinanSu/api/internals/domain"
"github.com/slack-go/slack"
)

type purchaseOrderRepository struct {
Expand All @@ -26,6 +30,7 @@ type PurchaseOrderRepository interface {
DeleteItems(context.Context, string) error
DeleteReport(context.Context, string) error
AllUserInfoByYear(context.Context, string) (*sql.Rows, error)
NotifySlack(context.Context, domain.PurchaseOrder, []domain.PurchaseItem, domain.User, domain.Bureau, domain.Expense) error
AllUnregisteredUserInfoByYear(context.Context, string) (*sql.Rows, error)
}

Expand Down Expand Up @@ -190,6 +195,32 @@ func (p *purchaseOrderRepository) AllUserInfoByYear(c context.Context, year stri
return p.crud.Read(c, query)
}

func (p *purchaseOrderRepository) NotifySlack(c context.Context, purchaseOrder domain.PurchaseOrder, purchaseItems []domain.PurchaseItem, user domain.User, bureau domain.Bureau, expense domain.Expense) error {
token := os.Getenv("BOT_USER_OAUTH_TOKEN")
channelName := os.Getenv("CHANNEL_NAME")

//メッセージ作成
sendMessage := "購入申請を受け付けました \n"
sendMessage += fmt.Sprintf("局・団体: %s", expense.Name) + " \n"
sendMessage += fmt.Sprintf("申請者: %s %s", bureau.Name, user.Name) + " \n"
sendMessage += "購入物品 \n"
//合計金額
sum := 0
//購入物品
for _, item := range purchaseItems{
sum += item.Price*item.Quantity
sendMessage += fmt.Sprintf("・%s %d円 %d個", item.Item, item.Price, item.Quantity) + " \n"
}
sendMessage += fmt.Sprintf("合計 %d円", sum)
client := slack.New(token)

_, _, err := client.PostMessage(channelName, slack.MsgOptionText(sendMessage, false))
if err != nil {
panic(err)
}
return err
}

func (p *purchaseOrderRepository) AllUnregisteredUserInfoByYear(c context.Context, year string) (*sql.Rows, error) {
query := `
SELECT
Expand Down
1 change: 1 addition & 0 deletions api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/pkg/errors v0.9.1
github.com/slack-go/slack v0.13.0
github.com/stretchr/testify v1.8.1 // indirect
github.com/swaggo/echo-swagger v1.3.5
github.com/swaggo/swag v1.8.1
Expand Down
10 changes: 10 additions & 0 deletions api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyr
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
Expand Down Expand Up @@ -77,11 +83,14 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/slack-go/slack v0.13.0 h1:7my/pR2ubZJ9912p9FtvALYpbt0cQPAqkRy2jaSI1PQ=
github.com/slack-go/slack v0.13.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand Down Expand Up @@ -179,6 +188,7 @@ golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
2 changes: 1 addition & 1 deletion api/internals/di/di.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func InitializeServer() db.Client {
mailAuthUseCase := usecase.NewMailAuthUseCase(mailAuthRepository, sessionRepository)
passwordResetTokenUseCase := usecase.NewPasswordResetTokenUseCase(passwordResetTokenRepository, userRepository, mailAuthRepository)
purchaseItemUseCase := usecase.NewPurchaseItemUseCase(purchaseItemRepository)
purchaseOrderUseCase := usecase.NewPurchaseOrderUseCase(purchaseOrderRepository)
purchaseOrderUseCase := usecase.NewPurchaseOrderUseCase(purchaseOrderRepository, bureauRepository, expenseRepository)
purchaseReportUseCase := usecase.NewPurchaseReportUseCase(purchaseReportRepository)
receiptUseCase := usecase.NewReceiptUseCase(receiptRepository)
sourceUseCase := usecase.NewSourceUseCase(sourceRepository)
Expand Down
61 changes: 59 additions & 2 deletions api/internals/usecase/purchase_order_usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

type purchaseOrderUseCase struct {
rep rep.PurchaseOrderRepository
bureauRep rep.BureauRepository
expenseRep rep.ExpenseRepository
}

type PurchaseOrderUseCase interface {
Expand All @@ -21,11 +23,12 @@ type PurchaseOrderUseCase interface {
GetPurchaseOrderDetails(context.Context) ([]domain.OrderDetail, error)
GetPurchaseOrderDetailByID(context.Context, string) (domain.OrderDetail, error)
GetPurchaseOrderDetailsByYear(context.Context, string) ([]domain.OrderDetail, error)
NotifySlack(context.Context, string, []domain.PurchaseItem) error
GetUnregisteredPurchaseOrderDetailsByYear(context.Context, string) ([]domain.OrderDetail, error)
}

func NewPurchaseOrderUseCase(rep rep.PurchaseOrderRepository) PurchaseOrderUseCase {
return &purchaseOrderUseCase{rep}
func NewPurchaseOrderUseCase(rep rep.PurchaseOrderRepository, bureauRep rep.BureauRepository, expenseRep rep.ExpenseRepository) PurchaseOrderUseCase {
return &purchaseOrderUseCase{rep, bureauRep, expenseRep}
}

// PurchaseOrdersの取得(Gets)
Expand Down Expand Up @@ -205,6 +208,7 @@ func (p *purchaseOrderUseCase) GetPurchaseOrderDetailByID(c context.Context, id
purchaseItem := domain.PurchaseItem{}
var purchaseItems []domain.PurchaseItem
row, err := p.rep.FindUserInfo(c, id)

err = row.Scan(
&orderDetail.PurchaseOrder.ID,
&orderDetail.PurchaseOrder.DeadLine,
Expand All @@ -224,6 +228,7 @@ func (p *purchaseOrderUseCase) GetPurchaseOrderDetailByID(c context.Context, id
if err != nil {
return orderDetail, nil
}

rows, err := p.rep.FindPurchaseItem(c, strconv.Itoa(int(orderDetail.PurchaseOrder.ID)))
for rows.Next() {
err := rows.Scan(
Expand Down Expand Up @@ -302,6 +307,58 @@ func (p *purchaseOrderUseCase) GetPurchaseOrderDetailsByYear(c context.Context,
return orderDetails, nil
}

func (p *purchaseOrderUseCase) NotifySlack(c context.Context, id string, purchaseItems []domain.PurchaseItem) error {
purchaseOrder := domain.PurchaseOrder{}
user := domain.User{}
bureau := domain.Bureau{}
expense := domain.Expense{}

//申請取得
row, err := p.rep.FindUserInfo(c, id)
err = row.Scan(
&purchaseOrder.ID,
&purchaseOrder.DeadLine,
&purchaseOrder.UserID,
&purchaseOrder.ExpenseID,
&purchaseOrder.FinanceCheck,
&purchaseOrder.CreatedAt,
&purchaseOrder.UpdatedAt,
&user.ID,
&user.Name,
&user.BureauID,
&user.RoleID,
&user.IsDeleted,
&user.CreatedAt,
&user.UpdatedAt,
)
if err != nil {
return err
}

//局取得
row, err = p.bureauRep.Find(c, strconv.Itoa(user.BureauID))
err = row.Scan(
&bureau.ID,
&bureau.Name,
&bureau.CreatedAt,
&bureau.UpdatedAt,
)

//支出取得
row, err = p.expenseRep.Find(c, strconv.Itoa(purchaseOrder.ExpenseID))
err = row.Scan(
&expense.ID,
&expense.Name,
&expense.TotalPrice,
&expense.YearID,
&expense.CreatedAt,
&expense.UpdatedAt,
)
err = p.rep.NotifySlack(c, purchaseOrder, purchaseItems, user, bureau, expense)

return err
}

// reports未登録の購入申請取得
func (p *purchaseOrderUseCase) GetUnregisteredPurchaseOrderDetailsByYear(c context.Context, year string) ([]domain.OrderDetail, error) {
orderDetail := domain.OrderDetail{}
Expand Down
1 change: 1 addition & 0 deletions api/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ func (r router) ProvideRouter(e *echo.Echo) {
e.GET("/purchaseorders", r.purchaseOrderController.IndexPurchaseOrder)
e.GET("/purchaseorders/:id", r.purchaseOrderController.ShowPurchaseOrder)
e.POST("/purchaseorders", r.purchaseOrderController.CreatePurchaseOrder)
e.POST("/purchaseorders/send/:id", r.purchaseOrderController.NotifySlack)
e.PUT("/purchaseorders/:id", r.purchaseOrderController.UpdatePurchaseOrder)
e.DELETE("/purchaseorders/:id", r.purchaseOrderController.DestroyPurchaseOrder)
e.GET("/purchaseorders/details", r.purchaseOrderController.IndexOrderDetail)
Expand Down
Loading
Loading