134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
package database
|
|
|
|
import (
|
|
"Portifolio/internal/model"
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
func GetPeriodByID(db *sql.DB, periodID int) (model.Period, error) {
|
|
var p model.Period
|
|
var start, end string
|
|
err := db.QueryRow(
|
|
`SELECT type, year, idx, start_date, end_date FROM periods WHERE id = ?`,
|
|
periodID,
|
|
).Scan(&p.Type, &p.Year, &p.Index, &start, &end)
|
|
if err == sql.ErrNoRows {
|
|
return p, fmt.Errorf("period %d not found", periodID)
|
|
}
|
|
if err != nil {
|
|
return p, fmt.Errorf("get period by id: %w", err)
|
|
}
|
|
p.Start, _ = time.Parse("2006-01-02", start)
|
|
p.End, _ = time.Parse("2006-01-02", end)
|
|
return p, nil
|
|
}
|
|
|
|
func GetRevenueByPeriod(db *sql.DB, companyID int, periodID int) ([]model.Revenue, error) {
|
|
rows, err := db.Query(
|
|
`SELECT id, company_id, currency_id, period_id, value FROM revenue_entries WHERE company_id = ? AND period_id = ?`,
|
|
companyID, periodID,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query revenue by period: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var revenues []model.Revenue
|
|
for rows.Next() {
|
|
var rc model.Revenue
|
|
if err := rows.Scan(&rc.ID, &rc.Company, &rc.Currency, &rc.Period, &rc.Value); err != nil {
|
|
return nil, fmt.Errorf("scan revenue row: %w", err)
|
|
}
|
|
revenues = append(revenues, rc)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, fmt.Errorf("iterate revenue rows: %w", err)
|
|
}
|
|
if len(revenues) == 0 {
|
|
return nil, fmt.Errorf("revenue by company %d and period_id %d not found", companyID, periodID)
|
|
}
|
|
|
|
return revenues, nil
|
|
}
|
|
|
|
func GetRevenueByCategory(db *sql.DB, companyID int, categoryID int) ([]model.Revenue, error) {
|
|
rows, err := db.Query(
|
|
`SELECT id, company_id, currency_id, category_id, value FROM revenue_entries WHERE company_id = ? AND category_id = ?`,
|
|
companyID, categoryID,
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query revenue by category: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var revenues []model.Revenue
|
|
for rows.Next() {
|
|
var rc model.Revenue
|
|
if err := rows.Scan(&rc.ID, &rc.Company, &rc.Currency, &rc.Category, &rc.Value); err != nil {
|
|
return nil, fmt.Errorf("scan revenue row: %w", err)
|
|
}
|
|
revenues = append(revenues, rc)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, fmt.Errorf("iterate revenue rows: %w", err)
|
|
}
|
|
if len(revenues) == 0 {
|
|
return nil, fmt.Errorf("revenue by company %d and category_id %d not found", companyID, categoryID)
|
|
}
|
|
|
|
return revenues, nil
|
|
}
|
|
|
|
func InsertRevenue(db *sql.DB, rev model.RevenueInsert) error {
|
|
_, err := GetCompanyByID(db, rev.CompanyID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = GetCurrencyByID(db, rev.CurrencyID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// checking if period is in db, in case not will insert
|
|
_, err = GetPeriodByID(db, rev.Period.ID)
|
|
if err != nil {
|
|
err = rev.Period.Insert(db)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
// Getting Category, if error, trying to insert the category with the company.
|
|
category, err := GetCategoryByName(db, rev.CompanyID, rev.CategoryName)
|
|
if err != nil {
|
|
err := InsertCategory(db, model.RevenueCategory{
|
|
CompanyID: rev.CompanyID,
|
|
ParentID: &rev.ParentID,
|
|
Name: rev.CategoryName,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
}
|
|
category, err = GetCategoryByName(db, rev.CompanyID, rev.CategoryName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = db.Exec(
|
|
`INSERT INTO revenue_entries (company_id, currency_id, category_id, period_id, value)
|
|
VALUES (?, ?, ?, ?, ?)`,
|
|
rev.CompanyID, rev.CurrencyID, category.ID, rev.Period.ID, rev.Value,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("insert revenue_entries: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|