forked from KKGo-Software-engineering/workshop-summer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
185 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package summary | ||
|
||
import ( | ||
"database/sql" | ||
"errors" | ||
"github.com/KKGo-Software-engineering/workshop-summer/api/config" | ||
"github.com/kkgo-software-engineering/workshop/mlog" | ||
"github.com/labstack/echo/v4" | ||
"go.uber.org/zap" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
const ( | ||
typeExpense = "expense" | ||
typeIncome = "income" | ||
) | ||
|
||
var ( | ||
ErrInvalidSpender = errors.New("invalid spender") | ||
) | ||
|
||
type Err struct { | ||
Message string `json:"message"` | ||
} | ||
|
||
type Spender struct { | ||
ID int `param:"id"` | ||
} | ||
|
||
type RawData struct { | ||
Date time.Time | ||
SumAmount float64 | ||
CountExpenses int | ||
} | ||
|
||
type Summary struct { | ||
Total float64 `json:"total_amount"` | ||
Average float64 `json:"average_per_day"` | ||
Count int `json:"count_transaction"` | ||
} | ||
|
||
type handler struct { | ||
flag config.FeatureFlag | ||
db *sql.DB | ||
} | ||
|
||
func New(cfg config.FeatureFlag, db *sql.DB) *handler { | ||
return &handler{cfg, db} | ||
} | ||
|
||
func summary(data []RawData) Summary { | ||
if len(data) == 0 { | ||
return Summary{} | ||
} | ||
|
||
var total float64 | ||
var count int | ||
for _, d := range data { | ||
total += d.SumAmount | ||
count += d.CountExpenses | ||
} | ||
|
||
return Summary{ | ||
Total: total, | ||
Average: total / float64(len(data)), | ||
Count: count, | ||
} | ||
} | ||
|
||
const ( | ||
sumSQL = `SELECT | ||
date_trunc('day', date)::date AS transaction_date, | ||
SUM(amount) AS total_amount, | ||
COUNT(*) AS record_count | ||
FROM | ||
"transaction" | ||
WHERE | ||
transaction_type = $1 AND spender_id = $2 | ||
GROUP BY | ||
date_trunc('day', date)::date | ||
ORDER BY | ||
transaction_date;` | ||
) | ||
|
||
func getSummary(c echo.Context, db *sql.DB, tnxType string) error { | ||
logger := mlog.L(c) | ||
ctx := c.Request().Context() | ||
|
||
var spender Spender | ||
err := c.Bind(&spender) | ||
if err != nil { | ||
logger.Error(ErrInvalidSpender.Error(), zap.Error(err)) | ||
return c.JSON(http.StatusBadRequest, Err{Message: ErrInvalidSpender.Error()}) | ||
} | ||
|
||
stmt, err := db.PrepareContext(ctx, sumSQL) | ||
if err != nil { | ||
logger.Error("prepare statement error", zap.Error(err)) | ||
return c.JSON(http.StatusInternalServerError, Err{Message: "prepare statement error"}) | ||
} | ||
|
||
rows, err := stmt.QueryContext(ctx, tnxType, spender.ID) | ||
if err != nil { | ||
logger.Error("query error", zap.Error(err)) | ||
return c.JSON(http.StatusInternalServerError, Err{Message: "query error"}) | ||
} | ||
defer rows.Close() | ||
|
||
var raws []RawData | ||
for rows.Next() { | ||
var raw RawData | ||
err := rows.Scan(&raw.Date, &raw.SumAmount, &raw.CountExpenses) | ||
if err != nil { | ||
logger.Error("scan error", zap.Error(err)) | ||
return c.JSON(http.StatusInternalServerError, Err{Message: "scan error"}) | ||
} | ||
raws = append(raws, raw) | ||
} | ||
|
||
return c.JSON(http.StatusOK, summary(raws)) | ||
} | ||
|
||
func (h *handler) GetExpenseSummaryHandler(c echo.Context) error { | ||
return getSummary(c, h.db, typeExpense) | ||
} | ||
|
||
// | ||
//func (h *handler) GetIncomeSummaryHandler(c echo.Context) error { | ||
// return getSummary(c, h.db, typeIncome) | ||
//} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
INSERT INTO "transaction" (date, amount, category, transaction_type, note, image_url, spender_id) VALUES | ||
-- Day 1: 2024-05-01 | ||
('2024-05-01 10:15:00+00', 23, 'groceries', 'expense', 'Mock transaction 1', 'http://example.com/receipt1.jpg', 1), | ||
('2024-05-01 12:30:00+00', 45, 'rent', 'income', 'Mock transaction 2', 'http://example.com/receipt2.jpg', 1), | ||
('2024-05-01 15:45:00+00', 12, 'utilities', 'expense', 'Mock transaction 3', 'http://example.com/receipt3.jpg', 1), | ||
('2024-05-01 18:00:00+00', 67, 'entertainment', 'income', 'Mock transaction 4', 'http://example.com/receipt4.jpg', 1), | ||
('2024-05-01 20:15:00+00', 54, 'transport', 'expense', 'Mock transaction 5', 'http://example.com/receipt5.jpg', 1), | ||
|
||
-- Day 2: 2024-05-02 | ||
('2024-05-02 09:00:00+00', 31, 'groceries', 'income', 'Mock transaction 6', 'http://example.com/receipt6.jpg', 1), | ||
('2024-05-02 11:15:00+00', 29, 'rent', 'expense', 'Mock transaction 7', 'http://example.com/receipt7.jpg', 1), | ||
('2024-05-02 13:30:00+00', 46, 'utilities', 'income', 'Mock transaction 8', 'http://example.com/receipt8.jpg', 1), | ||
('2024-05-02 15:45:00+00', 18, 'entertainment', 'expense', 'Mock transaction 9', 'http://example.com/receipt9.jpg', 1), | ||
('2024-05-02 18:00:00+00', 39, 'transport', 'income', 'Mock transaction 10', 'http://example.com/receipt10.jpg', 1), | ||
|
||
-- Day 3: 2024-05-03 | ||
('2024-05-03 08:00:00+00', 22, 'groceries', 'expense', 'Mock transaction 11', 'http://example.com/receipt11.jpg', 1), | ||
('2024-05-03 10:15:00+00', 53, 'rent', 'income', 'Mock transaction 12', 'http://example.com/receipt12.jpg', 1), | ||
('2024-05-03 12:30:00+00', 44, 'utilities', 'expense', 'Mock transaction 13', 'http://example.com/receipt13.jpg', 1), | ||
('2024-05-03 14:45:00+00', 19, 'entertainment', 'income', 'Mock transaction 14', 'http://example.com/receipt14.jpg', 1), | ||
('2024-05-03 17:00:00+00', 61, 'transport', 'expense', 'Mock transaction 15', 'http://example.com/receipt15.jpg', 1), | ||
|
||
-- Day 4: 2024-05-04 | ||
('2024-05-04 07:00:00+00', 38, 'groceries', 'income', 'Mock transaction 16', 'http://example.com/receipt16.jpg', 1), | ||
('2024-05-04 09:15:00+00', 27, 'rent', 'expense', 'Mock transaction 17', 'http://example.com/receipt17.jpg', 1), | ||
('2024-05-04 11:30:00+00', 49, 'utilities', 'income', 'Mock transaction 18', 'http://example.com/receipt18.jpg', 1), | ||
('2024-05-04 13:45:00+00', 32, 'entertainment', 'expense', 'Mock transaction 19', 'http://example.com/receipt19.jpg', 1), | ||
('2024-05-04 16:00:00+00', 55, 'transport', 'income', 'Mock transaction 20', 'http://example.com/receipt20.jpg', 1), | ||
|
||
-- Day 5: 2024-05-05 | ||
('2024-05-05 06:00:00+00', 26, 'groceries', 'expense', 'Mock transaction 21', 'http://example.com/receipt21.jpg', 1), | ||
('2024-05-05 08:15:00+00', 48, 'rent', 'income', 'Mock transaction 22', 'http://example.com/receipt22.jpg', 1), | ||
('2024-05-05 10:30:00+00', 35, 'utilities', 'expense', 'Mock transaction 23', 'http://example.com/receipt23.jpg', 1), | ||
('2024-05-05 12:45:00+00', 43, 'entertainment', 'income', 'Mock transaction 24', 'http://example.com/receipt24.jpg', 1), | ||
('2024-05-05 15:00:00+00', 59, 'transport', 'expense', 'Mock transaction 25', 'http://example.com/receipt25.jpg', 1); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
SELECT | ||
date_trunc('day', date)::date AS transaction_date, | ||
SUM(amount) AS total_amount, | ||
COUNT(*) AS record_count | ||
FROM | ||
"transaction" | ||
WHERE | ||
transaction_type = 'expense' AND spender_id = 1 | ||
GROUP BY | ||
date_trunc('day', date)::date | ||
ORDER BY | ||
transaction_date; |