package models import ( "errors" "strings" "time" "github.com/lib/pq" ) type Contract struct { BaseModel Name string `json:"name"` UUID string `json:"uuid" gorm:"type:uuid;"` DeviceIDs pq.Int64Array `json:"deviceIds" gorm:"type:integer[]"` BuyerID uint `json:"buyerId"` SellerID uint `json:"sellerId"` Description string `json:"description"` StartPlaceName string `json:"startPlaceName"` StartLat float64 `json:"startLat"` StartLon float64 `json:"startLon"` EndPlaceName string `json:"endPlaceName"` EndLat float64 `json:"endLat"` EndLon float64 `json:"endLon"` StartTime time.Time `json:"startTime"` EndTime time.Time `json:"endTime"` Status string `json:"status"` BlockchainSecret string `json:"blockchainSecret"` ContractInfos []ContractInfo `json:"contractInfos"` ProductID uint `json:"productId"` TemplateID uint `json:"templateId"` MaxTemp float64 `json:"maxTemp"` MinTemp float64 `json:"minTemp"` ArrivalDate time.Time `json:"arrivalDate"` PenaltyType string `json:"penaltyType"` PenaltyValue int `json:"penaltyValue"` PenaltyRec string `json:"penaltyRec"` BuyerName string `json:"buyerName" gorm:"-"` SellerName string `json:"sellerName" gorm:"-"` ProductName string `json:"productName" gorm:"-"` NumberOfDevices int `json:"numberOfDevices" gorm:"-"` DevicesImeis []string `json:"devicesImeis" gorm:"-"` DevicesImeisScanner PQStringArray `json:"contractDevicesImeis" gorm:"-"` } type PQStringArray []string func (a *PQStringArray) Scan(src interface{}) error { if src == nil { *a = nil return nil } // The database driver will give us a string in the format "{item1,item2,item3}" // We need to convert this to a slice var str string switch src := src.(type) { case []byte: str = string(src) case string: str = src default: return errors.New("incompatible type for PQStringArray") } // Remove the curly braces and split the string str = strings.Trim(str, "{}") if str != "" { *a = strings.Split(str, ",") } else { *a = []string{} } return nil } type DashboardContractResponse struct { BaseModel Name string `json:"name"` DeviceIDs pq.Int64Array `json:"deviceIds" gorm:"type:integer[]"` BuyerID uint `json:"buyerId"` SellerID uint `json:"sellerId"` Description string `json:"description"` StartLat float64 `json:"startLat"` StartLon float64 `json:"startLon"` EndLat float64 `json:"endLat"` EndLon float64 `json:"endLon"` StartTime time.Time `json:"startTime"` EndTime time.Time `json:"endTime"` Status string `json:"status"` BlockchainID string `json:"blockchainId"` ContractInfos []ContractInfo `json:"contractInfos"` ProductID uint `json:"productId"` MaxTemp float64 `json:"maxTemp"` MinTemp float64 `json:"minTemp"` ArrivalDate time.Time `json:"arrivalDate"` PenaltyType string `json:"penaltyType"` PenaltyValue int `json:"penaltyValue"` PenaltyRec string `json:"penaltyRec"` BuyerName string `json:"buyerName" gorm:"-"` NumberOfDevices int `json:"numberOfDevices" gorm:"-"` } type ContractResponse struct { BaseModel Name string `json:"name"` DeviceIDs pq.Int64Array `json:"deviceIds" gorm:"type:integer[]"` Seller struct { ID uint `json:"id"` Name string `json:"name"` } `json:"seller"` Buyer struct { ID uint `json:"id"` Name string `json:"name"` } `json:"buyer"` Start struct { Name string `json:"name"` Lat float64 `json:"lat"` Lon float64 `json:"lon"` Time time.Time `json:"time"` } `json:"start"` End struct { Name string `json:"name"` Lat float64 `json:"lat"` Lon float64 `json:"lon"` Time time.Time `json:"time"` } `json:"end"` Product struct { ID uint `json:"id"` Name string `json:"name"` } `json:"product"` Description string `json:"description"` Status string `json:"status"` BlockchainID string `json:"blockchainId"` ContractInfos []ContractInfo `json:"contractInfos"` MaxTemp float64 `json:"maxTemp"` MinTemp float64 `json:"minTemp"` ArrivalDate time.Time `json:"arrivalDate"` PenaltyType string `json:"penaltyType"` PenaltyValue int `json:"penaltyValue"` PenaltyRec string `json:"penaltyRec"` DeviceImeis []string `json:"devicesImeis"` } func ConvertContractsToContractResponse(contracts []Contract) []ContractResponse { contractResponses := []ContractResponse{} for _, contract := range contracts { contractResponse := ConvertContractToContractResponse(contract) contractResponses = append(contractResponses, contractResponse) } return contractResponses } func ConvertContractToContractResponse(contract Contract) ContractResponse { contractResponse := ContractResponse{ BaseModel: BaseModel{ID: contract.ID, CreatedAt: contract.CreatedAt, UpdatedAt: contract.UpdatedAt}, Name: contract.Name, DeviceIDs: contract.DeviceIDs, Seller: struct { ID uint "json:\"id\"" Name string "json:\"name\"" }{ ID: contract.SellerID, Name: contract.SellerName, }, Buyer: struct { ID uint "json:\"id\"" Name string "json:\"name\"" }{ ID: contract.BuyerID, Name: contract.BuyerName, }, Start: struct { Name string "json:\"name\"" Lat float64 "json:\"lat\"" Lon float64 "json:\"lon\"" Time time.Time "json:\"time\"" }{ Name: contract.StartPlaceName, Lat: contract.StartLat, Lon: contract.StartLon, Time: contract.StartTime, }, End: struct { Name string "json:\"name\"" Lat float64 "json:\"lat\"" Lon float64 "json:\"lon\"" Time time.Time "json:\"time\"" }{ Name: contract.EndPlaceName, Lat: contract.EndLat, Lon: contract.EndLon, Time: contract.EndTime, }, Product: struct { ID uint "json:\"id\"" Name string "json:\"name\"" }{ ID: contract.ProductID, Name: contract.ProductName, }, Description: contract.Description, Status: contract.Status, BlockchainID: contract.BlockchainSecret, ContractInfos: contract.ContractInfos, MaxTemp: contract.MaxTemp, MinTemp: contract.MinTemp, ArrivalDate: contract.ArrivalDate, PenaltyType: contract.PenaltyType, PenaltyValue: contract.PenaltyValue, PenaltyRec: contract.PenaltyRec, DeviceImeis: contract.DevicesImeis, } return contractResponse } func ConvertContractToDashboardResponse(contracts []Contract) []DashboardContractResponse { contractResponses := []DashboardContractResponse{} for _, contract := range contracts { contractResponse := DashboardContractResponse{ BaseModel: BaseModel{ ID: contract.ID, CreatedAt: contract.CreatedAt, UpdatedAt: contract.UpdatedAt, }, Name: contract.Name, DeviceIDs: contract.DeviceIDs, BuyerID: contract.BuyerID, SellerID: contract.SellerID, Description: contract.Description, StartLat: contract.StartLat, StartLon: contract.StartLon, EndLat: contract.EndLat, EndLon: contract.EndLon, StartTime: contract.StartTime, EndTime: contract.EndTime, Status: contract.Status, BlockchainID: contract.BlockchainSecret, ContractInfos: contract.ContractInfos, ProductID: contract.ProductID, MaxTemp: contract.MaxTemp, MinTemp: contract.MinTemp, ArrivalDate: contract.ArrivalDate, PenaltyType: contract.PenaltyType, PenaltyValue: contract.PenaltyValue, PenaltyRec: contract.PenaltyRec, BuyerName: contract.BuyerName, NumberOfDevices: contract.NumberOfDevices, } contractResponses = append(contractResponses, contractResponse) } return contractResponses } func ConvertContractToListResponse(contracts []Contract) []ListContractResponse { listInvoiceResponses := []ListContractResponse{} // Get all statuses statuses := GetContractStatuses() statusMap := make(map[string]Status) for _, s := range statuses { statusMap[s.Key] = s } for _, contract := range contracts { // Get the status based on Value in the DB status, ok := statusMap[contract.Status] if !ok { status = Status{Key: "", Value: ""} } listInvoiceResponse := ListContractResponse{ Status: KeyValue{Key: status.Key, Value: status.Value}, Buyer: CompanyShortResponse{ID: int(contract.BuyerID), Name: contract.BuyerName}, ContractID: int(contract.ID), ContractName: contract.Name, DateCreated: contract.CreatedAt, NumberOfDevices: contract.NumberOfDevices, DeviceImeis: contract.DevicesImeis, } listInvoiceResponses = append(listInvoiceResponses, listInvoiceResponse) } return listInvoiceResponses } const ContractStatusActive = "active" const ContractStatusPending = "pending" const ContractStatusDraft = "draft" const ContractStatusSigned = "signed" const ContractStatusReadyForActivation = "ready_for_activation" const ContractStatusExecuted = "executed" const ContractStatusRevoked = "revoked" const PenaltyTypeAmount = "amount" const PenaltyTypePercentage = "percentage" const PenaltyRecDaily = "daily" const PenaltyRecMonthly = "monthly" type Status struct { Key string `json:"key"` Value string `json:"value"` } type ActiveContractsResponse struct { ActiveCount int64 `json:"active"` ExecutedCount int64 `json:"executed"` MonthlyContracts map[string]map[string]int64 `json:"monthly"` } func GetContractStatuses() []Status { return []Status{ {Value: "Active", Key: "active"}, {Value: "Pending signature", Key: "pending"}, {Value: "Draft", Key: "draft"}, {Value: "Signed", Key: "signed"}, {Value: "Ready for Activation", Key: "ready_for_activation"}, {Value: "Executed", Key: "executed"}, {Value: "Revoked", Key: "revoked"}, } } type ListContractResponse struct { Status KeyValue `json:"status"` Buyer CompanyShortResponse `json:"buyer"` ContractID int `json:"contractID"` ContractName string `json:"contractName"` NumberOfDevices int `json:"numberOfDevices"` DateCreated time.Time `json:"dateCreated"` DeviceImeis []string `json:"deviceImeis"` } type CreateContractRequestPayload struct { SellerID uint `json:"sellerId" binding:"required"` BuyerID uint `json:"buyerId" binding:"required"` Description string `json:"description"` ProductID uint `json:"productId"` MinTemp float64 `json:"minTemp" binding:"required"` MaxTemp float64 `json:"maxTemp" binding:"required"` ArrivalDate int64 `json:"arrivalDate"` PenaltyType string `json:"penaltyType"` PenaltyValue int `json:"penaltyValue"` PenaltyRec string `json:"penaltyRec"` StartPlaceName string `json:"startPlaceName"` StartLat float64 `json:"startLat"` StartLon float64 `json:"startLon"` EndPlaceName string `json:"endPlaceName"` EndLat float64 `json:"endLat"` EndLon float64 `json:"endLon"` Name string `json:"name"` } func (Contract) Update() (bool, error) { return false, nil } func (Contract) Create() (bool, error) { return false, nil } func (Contract) Delete() (bool, error) { return false, nil }