Skip to content
Snippets Groups Projects
Commit 934d88cc authored by Gomez Goiri, Aitor's avatar Gomez Goiri, Aitor
Browse files

Stats: getting and calculating total slag registered in the platform

parent e0649db6
Branches
No related tags found
No related merge requests found
......@@ -11,7 +11,6 @@ import (
"git.code.tecnalia.com/ledgerbuilder/sdk/core/api"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/controller"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/fabric/protos"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/util/logging"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
"github.com/mitchellh/mapstructure"
......@@ -53,7 +52,6 @@ type Bid struct {
}
var (
log = logging.NewGoLogger("controller/transfer")
errInvalidInputData = errors.New("failed to read model")
errParamsMissing = errors.New("missing split params. assetId and splitParams config must be send in split request")
errChildrenMissmatch = errors.New("number of requested childs and proposed id count mismatch")
......
......@@ -21,6 +21,7 @@ import (
"git.code.tecnalia.com/traceblock/sdk/middleware"
"git.code.tecnalia.com/blockchain/hypercog/controller/bid"
"git.code.tecnalia.com/blockchain/hypercog/controller/stats"
m2 "git.code.tecnalia.com/blockchain/hypercog/middleware"
)
......@@ -79,7 +80,9 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
middleware.MarkAssetAsCreated,
middleware.InjectAssetOwnerData,
},
nil,
[]shared.MiddlewareInterface{
m2.UpdateStats,
},
assetController.SaveAbstractAsset,
).
AddOperation(
......@@ -192,6 +195,15 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
AddBasicReadOperation("random-uuid", testController.DistributedPrngUuid).
AddBasicReadOperation("random-string", testController.DistributedPrngString).
// HyperCOG operations
AddOperation(
"hypercog-stats",
shared.READ_OP,
[]shared.MiddlewareInterface{
m2.RejectIfNotPublicAdmin,
},
nil,
stats.GetStatsOperation,
).
AddOperation(
"hypercog-list-bid-assets",
shared.READ_OP,
......@@ -206,7 +218,7 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
AddOperationWithoutDefaults(
"hypercog-bid-asset",
shared.WRITE_OP,
&assetController,
&assetController, // Not used, just because it is required
bidController.StubReader,
bidController.LedgerReader,
[]shared.MiddlewareInterface{
......@@ -218,7 +230,7 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
AddOperationWithoutDefaults(
"hypercog-reject-asset",
shared.WRITE_OP,
&assetController,
&assetController, // Not used, just because it is required
bidDecisionController.StubReader,
bidDecisionController.LedgerReader,
[]shared.MiddlewareInterface{
......@@ -230,7 +242,7 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
AddOperationWithoutDefaults(
"hypercog-accept-asset",
shared.WRITE_OP,
&assetController,
&assetController, // Not used, just because it is required
bidDecisionController.StubReader,
bidDecisionController.LedgerReader,
[]shared.MiddlewareInterface{
......
/**
* stats_controller.go
*
* COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2022.
*/
package stats
import (
"git.code.tecnalia.com/blockchain/hypercog/model"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/api"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/fabric/protos"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
)
type StatsResult struct {
GlobalStats model.Stats `json:"global"` // in tons
PerCompany map[string]model.Stats `json:"perCompany,omitempty"`
}
func GetStatsOperation(stub shared.LedgerBuildrStubInterface, request shared.LedgerBuildrAsset) protos.Response {
fnName := "GetStats"
ret := new(StatsResult)
orgs, err := getOrgList(stub)
if err != nil {
return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
}
globalStat, err := GetStats(stub, GLOBAL_KEY)
if err != nil {
return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
}
ret.GlobalStats = *globalStat
if len(*orgs) > 0 {
ret.PerCompany = make(map[string]model.Stats)
}
for _, org := range *orgs {
orgStat, err := GetStats(stub, org)
if err != nil {
return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
}
ret.PerCompany[org] = *orgStat
}
return api.NewAPIGenericResponsePtr(fnName, nil, ret).SendResponse()
}
/**
* stub.go
*
* COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2022.
*/
package stats
import (
"encoding/json"
"git.code.tecnalia.com/blockchain/hypercog/model"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
)
const GLOBAL_KEY = "global"
const ORG_LIST_KEY = "org_list"
type OrgList []string
func GetStats(stub shared.LedgerBuildrStubInterface, key string) (st *model.Stats, err error) {
value, err := stub.GetState(key)
if err != nil || len(value) == 0 {
st = new(model.Stats)
} else {
err = json.Unmarshal(value, &st)
if err != nil {
return nil, err
}
}
return st, nil
}
func PutStats(stub shared.LedgerBuildrStubInterface, key string, stats *model.Stats) (error) {
serialized, err := json.Marshal(stats)
if err != nil {
return err
}
err = stub.PutState(key, serialized)
if err != nil {
return err
}
return nil
}
func getOrgList(stub shared.LedgerBuildrStubInterface) (st *OrgList, err error) {
value, err := stub.GetState(ORG_LIST_KEY)
if err != nil || len(value) == 0 {
st = new(OrgList)
} else {
err = json.Unmarshal(value, &st)
if err != nil {
return nil, err
}
}
return st, nil
}
func (orgs OrgList) contains(org string) (bool) {
for _, o := range orgs {
if o == org {
return true
}
}
return false
}
func AddOrgIfNotExist(stub shared.LedgerBuildrStubInterface, org string) (err error) {
orgs, err := getOrgList(stub)
if err != nil {
return err
}
if !orgs.contains(org) {
newOrgs := append(*orgs, org)
serialized, err := json.Marshal(newOrgs)
if err != nil {
return err
}
err = stub.PutState(ORG_LIST_KEY, serialized)
if err != nil {
return err
}
}
return nil
}
\ No newline at end of file
......@@ -18,7 +18,7 @@ import (
const (
defaultContractConfig = `{
"context_id": 0,
"chaincode_name": "traceblock-cc",
"chaincode_name": "hypercog-cc",
"features": {
"force_lowercase_ids": true,
"generate_abi": false,
......
......@@ -14,6 +14,7 @@ import (
var (
RejectIfNotSidenor = shared.NewMiddlewareFunction("reject-not-sidenor", rejectIfNotSidenor)
RejectIfNotCementCompany = shared.NewMiddlewareFunction("reject-not-cement-company", rejectIfNotCementCompany)
RejectIfNotPublicAdmin = shared.NewMiddlewareFunction("reject-not-public-admin", rejectIfNotPublicAdmin)
errInvalidOrg = errors.New("user belongs to an invalid organization")
)
......@@ -36,3 +37,13 @@ func rejectIfNotCementCompany(stub shared.LedgerBuildrStubInterface, ctl shared.
return nil, errInvalidOrg
}
func rejectIfNotPublicAdmin(stub shared.LedgerBuildrStubInterface, ctl shared.ControllerInterface, req shared.TXRequestInterface, request shared.LedgerBuildrAsset) (shared.LedgerBuildrAsset, error) {
mspId := stub.GetMSPId()
if (mspId == "public-administration-com") {
return request, nil
}
return nil, errInvalidOrg
}
\ No newline at end of file
/**
* type.go
*
* COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2022.
*/
package middleware
import (
"git.code.tecnalia.com/blockchain/hypercog/controller/stats"
"git.code.tecnalia.com/blockchain/hypercog/model"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
"git.code.tecnalia.com/traceblock/sdk/middleware"
)
var (
UpdateStats = shared.NewMiddlewareFunction("update-stats-slag", _updateSlagProduction)
)
func _retrieveExistingStats(stub shared.LedgerBuildrStubInterface) (*model.Stats, *model.Stats, error) {
org, err := stub.GetOrganization()
if err != nil {
return nil, nil, err
}
customStats, err := stats.GetStats(stub, org)
if err != nil {
return nil, nil, err
}
globalStats, err := stats.GetStats(stub , stats.GLOBAL_KEY)
if err != nil {
return nil, nil, err
}
return globalStats, customStats, nil
}
func _upgradeStats(stub shared.LedgerBuildrStubInterface, globalStats *model.Stats, customStats *model.Stats) (error) {
org, err := stub.GetOrganization()
if err != nil {
return err
}
err = stats.PutStats(stub, org, customStats)
if err != nil {
return err
}
err = stats.PutStats(stub, stats.GLOBAL_KEY, globalStats)
if err != nil {
return err
}
err = stats.AddOrgIfNotExist(stub, org)
if err != nil {
return err
}
return nil
}
func _updateSlagProduction(stub shared.LedgerBuildrStubInterface, ctl shared.ControllerInterface, req shared.TXRequestInterface, requestAsset shared.LedgerBuildrAsset) (shared.LedgerBuildrAsset, error) {
asst, err := middleware.ConvertToTraceableAsset(requestAsset)
if err != nil {
return nil, err
}
status, ok := asst.Get("status")
if ok && status == "slag" {
globalStats, customStats, err := _retrieveExistingStats(stub)
if err != nil {
return nil, err
}
amount := float64(asst.Quantity)
if asst.Units == "kg" {
amount /= 1000.0
}
customStats.TotalSlag += amount
globalStats.TotalSlag += amount
err = _upgradeStats(stub, globalStats, customStats)
if err != nil {
return nil, err
}
}
return asst, nil
}
\ No newline at end of file
/**
* stats.go
*
* COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2022.
*/
package model
// Total or per company
type Stats struct {
TotalSlag float64 `json:"total"` // in tons
SlagReused float64 `json:"reused"` // in tons
SlagDiscarded float64 `json:"discarded"` // in tons
TotalPrice float64 `json:"price"` // in €
MinPrice float64 `json:"minPrice"` // in €
MaxPrice float64 `json:"maxPrice"` // in €
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment