From 6adfdc41ef5370e20f6b4b57d194644c3855b1c9 Mon Sep 17 00:00:00 2001
From: "Gomez Goiri, Aitor" <aitor.gomez@tecnalia.com>
Date: Mon, 28 Feb 2022 17:45:19 +0100
Subject: [PATCH] Returning refined stats

---
 .../controller/stats/stats_controller.go      |  4 +-
 chaincode/controller/stats/stub.go            |  6 +--
 chaincode/middleware/stats.go                 |  4 +-
 chaincode/model/stats.go                      | 47 ++++++++++++++++++-
 4 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/chaincode/controller/stats/stats_controller.go b/chaincode/controller/stats/stats_controller.go
index 335d88d..e0c531a 100644
--- a/chaincode/controller/stats/stats_controller.go
+++ b/chaincode/controller/stats/stats_controller.go
@@ -33,7 +33,7 @@ func GetStatsOperation(stub shared.LedgerBuildrStubInterface, request shared.Led
 	if err != nil {
 		return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
 	}
-	ret.GlobalStats = *globalStat
+	ret.GlobalStats = *model.RefineStats(globalStat)
 
 	if len(*orgs) > 0 {
 		ret.PerCompany = make(map[string]model.Stats)
@@ -44,7 +44,7 @@ func GetStatsOperation(stub shared.LedgerBuildrStubInterface, request shared.Led
 		if err != nil {
 			return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
 		}
-		ret.PerCompany[org] = *orgStat
+		ret.PerCompany[org] = *model.RefineStats(orgStat)
     }
 
 	return api.NewAPIGenericResponsePtr(fnName, nil, ret).SendResponse()
diff --git a/chaincode/controller/stats/stub.go b/chaincode/controller/stats/stub.go
index f3763d4..94b2ee4 100644
--- a/chaincode/controller/stats/stub.go
+++ b/chaincode/controller/stats/stub.go
@@ -19,10 +19,10 @@ const ORG_LIST_KEY = "org_list"
 type OrgList []string
 
 
-func GetStats(stub shared.LedgerBuildrStubInterface, key string) (st *model.Stats, err error) {
+func GetStats(stub shared.LedgerBuildrStubInterface, key string) (st *model.RawStats, err error) {
 	value, err := stub.GetState(key)
 	if err != nil || len(value) == 0 {
-		st = new(model.Stats)
+		st = new(model.RawStats)
 	} else {
 		err = json.Unmarshal(value, &st)
 		if err != nil  {
@@ -33,7 +33,7 @@ func GetStats(stub shared.LedgerBuildrStubInterface, key string) (st *model.Stat
 	return st, nil
 }
 
-func PutStats(stub shared.LedgerBuildrStubInterface, key string, stats *model.Stats) (error) {
+func PutStats(stub shared.LedgerBuildrStubInterface, key string, stats *model.RawStats) (error) {
 	serialized, err := json.Marshal(stats)
 	if err != nil {
 		return err
diff --git a/chaincode/middleware/stats.go b/chaincode/middleware/stats.go
index d012f69..5dc9fb8 100644
--- a/chaincode/middleware/stats.go
+++ b/chaincode/middleware/stats.go
@@ -18,7 +18,7 @@ var (
 )
 
 
-func _retrieveExistingStats(stub shared.LedgerBuildrStubInterface) (*model.Stats, *model.Stats, error) {
+func _retrieveExistingStats(stub shared.LedgerBuildrStubInterface) (*model.RawStats, *model.RawStats, error) {
 	org, err := stub.GetOrganization()
 	if err != nil {
 		return nil, nil, err
@@ -37,7 +37,7 @@ func _retrieveExistingStats(stub shared.LedgerBuildrStubInterface) (*model.Stats
 	return globalStats, customStats, nil
 }
 
-func _upgradeStats(stub shared.LedgerBuildrStubInterface, globalStats *model.Stats, customStats *model.Stats) (error) {
+func _upgradeStats(stub shared.LedgerBuildrStubInterface, globalStats *model.RawStats, customStats *model.RawStats) (error) {
 	org, err := stub.GetOrganization()
 	if err != nil {
 		return err
diff --git a/chaincode/model/stats.go b/chaincode/model/stats.go
index d6d1f36..ec9739f 100644
--- a/chaincode/model/stats.go
+++ b/chaincode/model/stats.go
@@ -6,12 +6,57 @@
 
 package model
 
+type PercentageMetric struct {
+	Total float64 `json:"total"` // in tons
+	Percentage float64 `json:"percentage,omitempty"` // in %
+}
+
+type PriceMetric struct {
+	Minimum float64 `json:"min"`
+	Maximum float64 `json:"max"`
+	Average float64 `json:"avg"`
+}
+
 // Total or per company
+// Refined stats which will be returned
 type Stats struct {
+	TotalSlag float64 `json:"total"` // in tons
+	Reused PercentageMetric `json:"reused"`
+	Discarded PercentageMetric `json:"discarded"`
+	Price PriceMetric `json:"price"`
+}
+
+// Total or per company
+// Raw stored stats
+type RawStats struct {
 	TotalSlag float64 `json:"total"` // in tons
 	SlagReused float64 `json:"reused"` // in tons
 	SlagDiscarded float64 `json:"discarded"` // in tons
-	TotalPrice float64 `json:"price"` // in €
+	TotalPrice float64 `json:"totalPrice"` // in €
+	BidAmount uint32 `json:"bidAmount"` // in units
 	MinPrice float64 `json:"minPrice"` // in €
 	MaxPrice float64 `json:"maxPrice"` // in €
 }
+
+func RefineStats(raw *RawStats) (*Stats) {
+	ret := new(Stats)
+	ret.TotalSlag = raw.TotalSlag
+
+	ret.Reused.Total = raw.SlagReused
+	if ret.TotalSlag > 0 && ret.Reused.Total > 0 {
+		ret.Reused.Percentage = ret.Reused.Total / ret.TotalSlag
+	}
+
+	ret.Discarded.Total = raw.SlagDiscarded
+	if ret.TotalSlag > 0 && ret.Discarded.Total > 0 {
+		ret.Discarded.Percentage = ret.Discarded.Total / ret.TotalSlag
+	}
+
+	ret.Price.Minimum = raw.MinPrice
+	ret.Price.Maximum = raw.MaxPrice
+	if raw.BidAmount > 0 {
+		ret.Price.Average = raw.TotalPrice / float64(raw.BidAmount)
+	}
+
+	return ret
+}
-- 
GitLab