84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
|
|
package service
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"database/sql"
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
"boc/repository"
|
||
|
|
)
|
||
|
|
|
||
|
|
// FinanceService handles business logic for finance operations
|
||
|
|
type FinanceService struct {
|
||
|
|
repo *repository.FinanceRepository
|
||
|
|
db *sql.DB
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewFinanceService(db *sql.DB) *FinanceService {
|
||
|
|
return &FinanceService{
|
||
|
|
repo: repository.NewFinanceRepository(db),
|
||
|
|
db: db,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListInvoices returns all invoices
|
||
|
|
func (s *FinanceService) ListInvoices(ctx context.Context) ([]repository.Invoice, error) {
|
||
|
|
return s.repo.ListInvoices(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListExpenses returns all expenses
|
||
|
|
func (s *FinanceService) ListExpenses(ctx context.Context) ([]repository.Expense, error) {
|
||
|
|
return s.repo.ListExpenses(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
// CreateExpense creates a new expense with validation
|
||
|
|
func (s *FinanceService) CreateExpense(ctx context.Context, e *repository.Expense) error {
|
||
|
|
if e.Category == "" {
|
||
|
|
return fmt.Errorf("expense category is required")
|
||
|
|
}
|
||
|
|
if e.Amount <= 0 {
|
||
|
|
return fmt.Errorf("expense amount must be positive")
|
||
|
|
}
|
||
|
|
if e.Status == "" {
|
||
|
|
e.Status = "pending"
|
||
|
|
}
|
||
|
|
return s.repo.CreateExpense(ctx, e)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetCashFlow returns income, outstanding, and expenses
|
||
|
|
func (s *FinanceService) GetCashFlow(ctx context.Context) (income, outstanding, expenses float64, err error) {
|
||
|
|
return s.repo.GetCashFlow(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetAccounts returns all ledger accounts
|
||
|
|
func (s *FinanceService) GetAccounts(ctx context.Context) ([]repository.Account, error) {
|
||
|
|
return s.repo.GetAccounts(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetBalanceSheet returns a simplified balance sheet
|
||
|
|
func (s *FinanceService) GetBalanceSheet(ctx context.Context) (map[string]interface{}, error) {
|
||
|
|
accounts, err := s.repo.GetAccounts(ctx)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
var assets, liabilities, equity float64
|
||
|
|
for _, a := range accounts {
|
||
|
|
switch a.Type {
|
||
|
|
case "asset":
|
||
|
|
assets += a.Balance
|
||
|
|
case "liability":
|
||
|
|
liabilities += a.Balance
|
||
|
|
case "equity":
|
||
|
|
equity += a.Balance
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return map[string]interface{}{
|
||
|
|
"assets": assets,
|
||
|
|
"liabilities": liabilities,
|
||
|
|
"equity": equity,
|
||
|
|
"accounts": accounts,
|
||
|
|
}, nil
|
||
|
|
}
|