mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- Initialize git repository - Add comprehensive .gitignore for Go projects - Install golangci-lint v2.6.0 (latest v2) globally - Configure .golangci.yml with appropriate linters and formatters - Fix all formatting issues (gofmt) - Fix all errcheck issues (unchecked errors) - Adjust complexity threshold for validation functions - All checks passing: build, test, vet, lint
151 lines
4.9 KiB
Go
151 lines
4.9 KiB
Go
package models
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/damirmukimov/city_resource_graph/models/cost"
|
|
"github.com/damirmukimov/city_resource_graph/models/customer"
|
|
"github.com/damirmukimov/city_resource_graph/models/impact"
|
|
"github.com/damirmukimov/city_resource_graph/models/params"
|
|
"github.com/damirmukimov/city_resource_graph/models/profitability"
|
|
"github.com/damirmukimov/city_resource_graph/models/revenue"
|
|
"github.com/damirmukimov/city_resource_graph/models/unit"
|
|
"github.com/damirmukimov/city_resource_graph/models/validator"
|
|
)
|
|
|
|
// YearResult contains all calculated metrics for a single year.
|
|
type YearResult struct {
|
|
Year int `json:"year"`
|
|
Customer customer.CustomerMetrics `json:"customer"`
|
|
TierDist customer.TierDistribution `json:"tier_distribution"`
|
|
Revenue revenue.RevenueBreakdown `json:"revenue"`
|
|
Costs cost.CostBreakdown `json:"costs"`
|
|
Impact impact.ImpactMetrics `json:"impact"`
|
|
UnitEconomics unit.UnitEconomics `json:"unit_economics"`
|
|
Validation validator.ValidationResult `json:"validation"`
|
|
Profit float64 `json:"profit"`
|
|
Margin float64 `json:"margin"` // Percentage
|
|
ARPU float64 `json:"arpu"` // Average revenue per user
|
|
}
|
|
|
|
// ModelResult contains results for all years.
|
|
type ModelResult struct {
|
|
Years []YearResult `json:"years"`
|
|
Summary Summary `json:"summary"`
|
|
Profitability profitability.ProfitabilityMetrics `json:"profitability"`
|
|
}
|
|
|
|
// Summary contains aggregated metrics across all years.
|
|
type Summary struct {
|
|
TotalRevenue float64 `json:"total_revenue"`
|
|
TotalCosts float64 `json:"total_costs"`
|
|
TotalProfit float64 `json:"total_profit"`
|
|
TotalCO2Avoided float64 `json:"total_co2_avoided"`
|
|
TotalWaterReused float64 `json:"total_water_reused"`
|
|
TotalWasteDiverted float64 `json:"total_waste_diverted"`
|
|
}
|
|
|
|
// Calculate runs the complete mathematical model for all years specified in params.
|
|
func Calculate(p *params.Params) (*ModelResult, error) {
|
|
if err := p.Validate(); err != nil {
|
|
return nil, fmt.Errorf("invalid params: %w", err)
|
|
}
|
|
|
|
var yearResults []YearResult
|
|
|
|
for _, year := range p.Time.Years {
|
|
result, err := CalculateYear(year, p)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("year %d: %w", year, err)
|
|
}
|
|
yearResults = append(yearResults, *result)
|
|
}
|
|
|
|
summary := calculateSummary(yearResults)
|
|
|
|
// Calculate profitability metrics (IRR, NPV, payback period)
|
|
cashFlows := make([]float64, len(yearResults))
|
|
for i, year := range yearResults {
|
|
cashFlows[i] = year.Profit
|
|
}
|
|
profitabilityMetrics := profitability.CalculateProfitability(cashFlows, p.Profitability.DiscountRate)
|
|
|
|
return &ModelResult{
|
|
Years: yearResults,
|
|
Summary: summary,
|
|
Profitability: profitabilityMetrics,
|
|
}, nil
|
|
}
|
|
|
|
// CalculateYear computes all metrics for a single year.
|
|
func CalculateYear(year int, p *params.Params) (*YearResult, error) {
|
|
// 1. Customer metrics
|
|
custMetrics := customer.CalculateCustomerMetrics(year, p)
|
|
tierDist := customer.CalculateTierDistribution(year, custMetrics.PayingOrgs, p)
|
|
|
|
// 2. Revenue
|
|
revBreakdown := revenue.CalculateRevenue(year, custMetrics, tierDist, p)
|
|
|
|
// 3. Costs
|
|
costBreakdown := cost.CalculateCosts(year, p)
|
|
|
|
// 4. Impact
|
|
impactMetrics := impact.CalculateImpact(year, custMetrics, p)
|
|
|
|
// 5. Unit Economics
|
|
unitEconomics := unit.CalculateUnitEconomics(year, custMetrics, tierDist, revBreakdown, p)
|
|
|
|
// 6. Validation
|
|
validationResult := validator.Validate(year, custMetrics, revBreakdown, costBreakdown, impactMetrics)
|
|
|
|
// 7. Derived metrics
|
|
profit := revBreakdown.Total - costBreakdown.Total
|
|
var margin float64
|
|
if revBreakdown.Total > 0 {
|
|
margin = (profit / revBreakdown.Total) * 100
|
|
}
|
|
|
|
var arpu float64
|
|
if custMetrics.PayingOrgs > 0 {
|
|
arpu = revBreakdown.Total / float64(custMetrics.PayingOrgs)
|
|
}
|
|
|
|
return &YearResult{
|
|
Year: year,
|
|
Customer: custMetrics,
|
|
TierDist: tierDist,
|
|
Revenue: revBreakdown,
|
|
Costs: costBreakdown,
|
|
Impact: impactMetrics,
|
|
UnitEconomics: unitEconomics,
|
|
Validation: validationResult,
|
|
Profit: profit,
|
|
Margin: margin,
|
|
ARPU: arpu,
|
|
}, nil
|
|
}
|
|
|
|
// calculateSummary aggregates metrics across all years.
|
|
func calculateSummary(results []YearResult) Summary {
|
|
var totalRevenue, totalCosts, totalProfit float64
|
|
var totalCO2, totalWater, totalWaste float64
|
|
|
|
for _, result := range results {
|
|
totalRevenue += result.Revenue.Total
|
|
totalCosts += result.Costs.Total
|
|
totalProfit += result.Profit
|
|
totalCO2 += result.Impact.CO2Avoided
|
|
totalWater += result.Impact.WaterReused
|
|
totalWaste += result.Impact.WasteDiverted
|
|
}
|
|
|
|
return Summary{
|
|
TotalRevenue: totalRevenue,
|
|
TotalCosts: totalCosts,
|
|
TotalProfit: totalProfit,
|
|
TotalCO2Avoided: totalCO2,
|
|
TotalWaterReused: totalWater,
|
|
TotalWasteDiverted: totalWaste,
|
|
}
|
|
}
|