Return imeis for contract

This commit is contained in:
Nedim
2023-11-08 22:49:52 +01:00
parent 5296edc4a7
commit 3248359726
4 changed files with 168 additions and 197 deletions

View File

@@ -27,8 +27,8 @@ func GetContracts(status []string, companyName string, companyAddress string,
db := shared.GetDb()
countDb := db
// Define custom fields to be selected, varies based on joined tables
customFields := "distinct contracts.*, array_length(contracts.device_ids, 1) as number_of_devices"
customFields := "distinct contracts.*, array_length(contracts.device_ids, 1) as number_of_devices, " +
"(SELECT array_agg(devices.imei) FROM devices WHERE devices.id = ANY(contracts.device_ids)) as devices_imeis_scanner"
// Search by Statuses
if len(status) > 0 {
@@ -87,8 +87,8 @@ func GetContracts(status []string, companyName string, companyAddress string,
// Search by Device IDs
if len(deviceIDs) > 0 {
db = db.Where("device_ids && ?", pq.Array(deviceIDs))
countDb = countDb.Where("device_ids && ?", pq.Array(deviceIDs))
db = db.Where("contracts.device_ids && ?", pq.Array(deviceIDs))
countDb = countDb.Where("contracts.device_ids && ?", pq.Array(deviceIDs))
}
// Fetch total count of filtered records
@@ -112,6 +112,10 @@ func GetContracts(status []string, companyName string, companyAddress string,
return contracts, total, http.StatusInternalServerError, err
}
}
for i := range contracts {
contracts[i].DevicesImeis = []string(contracts[i].DevicesImeisScanner)
// Now DevicesImeis contains the IMEIs, and you can use them as needed
}
return contracts, total, http.StatusOK, nil
}
@@ -262,6 +266,32 @@ func GetContractByID(contractID uint) (models.Contract, int, error) {
}
contract.BuyerName = buyer.Name
// Fetch the devices
// Convert DeviceIDs from pq.Int64Array to []int64 for the query
deviceIDs := make([]int64, 0, len(contract.DeviceIDs))
for _, id := range contract.DeviceIDs {
deviceIDs = append(deviceIDs, int64(id))
}
// Fetch the devices using the slice of device IDs
var devicesInfo []models.ContractDeviceInfo
if err := shared.GetDb().
Table("devices"). // Specify the actual table name for devices
Where("id IN (?)", deviceIDs).
Select("id, imei").
Find(&devicesInfo).Error; err != nil {
log.Printf("GetContractByID Error: Could not fetch devices: %v", err)
return contract, http.StatusInternalServerError, err
}
// Prepare a slice of IMEIs to add to the contract
deviceImeis := make([]string, len(devicesInfo))
for i, device := range devicesInfo {
deviceImeis[i] = device.IMEI
}
contract.DevicesImeis = deviceImeis
return contract, http.StatusOK, nil
}

View File

@@ -1,6 +1,8 @@
package models
import (
"errors"
"strings"
"time"
"github.com/lib/pq"
@@ -8,35 +10,66 @@ import (
type Contract 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"`
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:"-"`
Name string `json:"name"`
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 {
@@ -104,6 +137,7 @@ type ContractResponse struct {
PenaltyType string `json:"penaltyType"`
PenaltyValue int `json:"penaltyValue"`
PenaltyRec string `json:"penaltyRec"`
DeviceImeis []string `json:"devicesImeis"`
}
func ConvertContractsToContractResponse(contracts []Contract) []ContractResponse {
@@ -173,6 +207,7 @@ func ConvertContractToContractResponse(contract Contract) ContractResponse {
PenaltyType: contract.PenaltyType,
PenaltyValue: contract.PenaltyValue,
PenaltyRec: contract.PenaltyRec,
DeviceImeis: contract.DevicesImeis,
}
return contractResponse
@@ -240,6 +275,7 @@ func ConvertContractToListResponse(contracts []Contract) []ListContractResponse
ContractName: contract.Name,
DateCreated: contract.CreatedAt,
NumberOfDevices: contract.NumberOfDevices,
DeviceImeis: contract.DevicesImeis,
}
listInvoiceResponses = append(listInvoiceResponses, listInvoiceResponse)
}
@@ -291,6 +327,7 @@ type ListContractResponse struct {
ContractName string `json:"contractName"`
NumberOfDevices int `json:"numberOfDevices"`
DateCreated time.Time `json:"dateCreated"`
DeviceImeis []string `json:"deviceImeis"`
}
type CreateContractRequestPayload struct {

View File

@@ -27,6 +27,11 @@ type DeviceResponse struct {
DeviceInfos *[]DeviceInfo `json:"deviceInfos"`
}
type ContractDeviceInfo struct {
ID uint `json:"id"`
IMEI string `json:"imei"`
}
func ConvertDeviceToResponse(devices []Device) []DeviceResponse {
var deviceResponses []DeviceResponse
for _, device := range devices {

View File

@@ -250,15 +250,15 @@
},
{
"key": "Date",
"value": "Fri, 06 Oct 2023 08:27:52 GMT"
"value": "Thu, 09 Nov 2023 09:14:11 GMT"
},
{
"key": "Content-Length",
"value": "1056"
"value": "1819"
}
],
"cookie": [],
"body": "{\n \"data\": [\n {\n \"status\": {\n \"key\": \"Unknown\",\n \"value\": \"unknown\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 7,\n \"numberOfDevices\": 0,\n \"dateCreated\": \"2023-10-06T08:36:23.752245+02:00\"\n },\n {\n \"status\": {\n \"key\": \"Unknown\",\n \"value\": \"unknown\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 6,\n \"numberOfDevices\": 0,\n \"dateCreated\": \"2023-10-06T08:25:40.488392+02:00\"\n },\n {\n \"status\": {\n \"key\": \"Active\",\n \"value\": \"active\"\n },\n \"buyer\": {\n \"id\": 1,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 1,\n \"numberOfDevices\": 3,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n {\n \"status\": {\n \"key\": \"Pending signature\",\n \"value\": \"pending\"\n },\n \"buyer\": {\n \"id\": 1,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 2,\n \"numberOfDevices\": 1,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n {\n \"status\": {\n \"key\": \"Active\",\n \"value\": \"active\"\n },\n \"buyer\": {\n \"id\": 1,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 3,\n \"numberOfDevices\": 4,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n {\n \"status\": {\n \"key\": \"Active\",\n \"value\": \"active\"\n },\n \"buyer\": {\n \"id\": 1,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 4,\n \"numberOfDevices\": 4,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\"\n }\n ],\n \"total\": 6\n}"
"body": "{\n \"data\": [\n {\n \"status\": {\n \"key\": \"\",\n \"value\": \"\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 9,\n \"contractName\": \"\",\n \"numberOfDevices\": 0,\n \"dateCreated\": \"2023-10-06T10:40:15.342985+02:00\",\n \"deviceImeis\": null\n },\n {\n \"status\": {\n \"key\": \"\",\n \"value\": \"\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 8,\n \"contractName\": \"\",\n \"numberOfDevices\": 0,\n \"dateCreated\": \"2023-10-06T10:40:13.150385+02:00\",\n \"deviceImeis\": null\n },\n {\n \"status\": {\n \"key\": \"\",\n \"value\": \"\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 7,\n \"contractName\": \"\",\n \"numberOfDevices\": 0,\n \"dateCreated\": \"2023-10-06T08:36:23.752245+02:00\",\n \"deviceImeis\": null\n },\n {\n \"status\": {\n \"key\": \"\",\n \"value\": \"\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 6,\n \"contractName\": \"\",\n \"numberOfDevices\": 0,\n \"dateCreated\": \"2023-10-06T08:25:40.488392+02:00\",\n \"deviceImeis\": null\n },\n {\n \"status\": {\n \"key\": \"active\",\n \"value\": \"Active\"\n },\n \"buyer\": {\n \"id\": 1,\n \"name\": \"Nova kompanija\"\n },\n \"contractID\": 1,\n \"contractName\": \"Contract1\",\n \"numberOfDevices\": 3,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\",\n \"deviceImeis\": [\n \"352656107000002\",\n \"352656107000000\",\n \"352656107000001\"\n ]\n },\n {\n \"status\": {\n \"key\": \"executed\",\n \"value\": \"Executed\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 2,\n \"contractName\": \"Cont 1\",\n \"numberOfDevices\": 1,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\",\n \"deviceImeis\": [\n \"352656107000002\"\n ]\n },\n {\n \"status\": {\n \"key\": \"active\",\n \"value\": \"Active\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 3,\n \"contractName\": \"Contract2\",\n \"numberOfDevices\": 4,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\",\n \"deviceImeis\": [\n \"SOME_VALID_IMEI\",\n \"UNKNOWN\",\n \"123456789\"\n ]\n },\n {\n \"status\": {\n \"key\": \"active\",\n \"value\": \"Active\"\n },\n \"buyer\": {\n \"id\": 2,\n \"name\": \"Nova kompanija 2\"\n },\n \"contractID\": 4,\n \"contractName\": \"Contract2\",\n \"numberOfDevices\": 4,\n \"dateCreated\": \"2023-09-13T08:36:41.742294+02:00\",\n \"deviceImeis\": [\n \"SOME_VALID_IMEI\",\n \"UNKNOWN\",\n \"123456789\"\n ]\n }\n ],\n \"total\": 8\n}"
}
]
},
@@ -1467,7 +1467,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"email\": \"someemail@gmail.com\"\n}",
"raw": "{\n \"email\": \"email@mail.com\"\n}",
"options": {
"raw": {
"language": "json"
@@ -1557,7 +1557,7 @@
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"someemail@gmail.com\",\n \"token\": \"sb6qxahXINNsg52dH0Q7u7iR6yaPLRRQ4OnbUWlxEo0=\"\n}",
"raw": "{\n \"password\": \"address@gmail.com\",\n \"token\": \"oR4wIlYRsUgkzpK07KTIhwIZhB-HYCGKNYFDeNqpY0M=\"\n}",
"options": {
"raw": {
"language": "json"
@@ -1576,69 +1576,7 @@
]
}
},
"response": [
{
"name": "Create Contracts",
"originalRequest": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"sellerId\": 1,\n \"buyerId\": 2,\n \"description\": \"This is a sample contract.\",\n \"productId\": 3,\n \"minTemp\": -20.0,\n \"maxTemp\": 40.0,\n \"arrivalDate\": 1674019200,\n \"penaltyType\": \"AMOUNT\",\n \"penaltyValue\": 100,\n \"penaltyRec\": \"DAILY\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/contracts/create",
"host": [
"{{URL}}"
],
"path": [
"contracts",
"create"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Access-Control-Allow-Credentials",
"value": "true"
},
{
"key": "Access-Control-Allow-Headers",
"value": "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With"
},
{
"key": "Access-Control-Allow-Methods",
"value": "POST, OPTIONS, GET, PUT"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
},
{
"key": "Content-Type",
"value": "application/json; charset=utf-8"
},
{
"key": "Date",
"value": "Fri, 06 Oct 2023 08:40:15 GMT"
},
{
"key": "Content-Length",
"value": "61"
}
],
"cookie": [],
"body": "{\n \"id\": 9,\n \"message\": \"Successfully received and saved contract\"\n}"
}
]
"response": []
},
{
"name": "Login",
@@ -1655,6 +1593,43 @@
},
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"email\": \"someemail@gmail.com\",\n \"password\": \"pass\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/user/login",
"host": [
"{{URL}}"
],
"path": [
"user",
"login"
]
}
},
"response": []
},
{
"name": "Logout",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{AuthToken}}",
"type": "string"
}
]
},
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "",
@@ -1665,129 +1640,47 @@
}
},
"url": {
"raw": "{{URL}}/user/logout",
"raw": "{{URL}}/logout",
"host": [
"{{URL}}"
],
"path": [
"user",
"logout"
]
}
},
"response": [
{
"name": "Create Contracts",
"originalRequest": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"sellerId\": 1,\n \"buyerId\": 2,\n \"description\": \"This is a sample contract.\",\n \"productId\": 3,\n \"minTemp\": -20.0,\n \"maxTemp\": 40.0,\n \"arrivalDate\": 1674019200,\n \"penaltyType\": \"AMOUNT\",\n \"penaltyValue\": 100,\n \"penaltyRec\": \"DAILY\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/contracts/create",
"host": [
"{{URL}}"
],
"path": [
"contracts",
"create"
]
}
},
"status": "OK",
"code": 200,
"_postman_previewlanguage": "json",
"header": [
{
"key": "Access-Control-Allow-Credentials",
"value": "true"
},
{
"key": "Access-Control-Allow-Headers",
"value": "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With"
},
{
"key": "Access-Control-Allow-Methods",
"value": "POST, OPTIONS, GET, PUT"
},
{
"key": "Access-Control-Allow-Origin",
"value": "*"
},
{
"key": "Content-Type",
"value": "application/json; charset=utf-8"
},
{
"key": "Date",
"value": "Fri, 06 Oct 2023 08:40:15 GMT"
},
{
"key": "Content-Length",
"value": "61"
}
],
"cookie": [],
"body": "{\n \"id\": 9,\n \"message\": \"Successfully received and saved contract\"\n}"
}
]
"response": []
},
{
"name": "Logout",
"name": "Contract by ID",
"request": {
"method": "POST",
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"password\": \"someemail@gmail.com\",\n \"token\": \"sb6qxahXINNsg52dH0Q7u7iR6yaPLRRQ4OnbUWlxEo0=\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/user/set/password",
"raw": "{{URL}}/contracts/1",
"host": [
"{{URL}}"
],
"path": [
"user",
"set",
"password"
"contracts",
"1"
]
}
},
"response": [
{
"name": "Create Contracts",
"name": "Contract by ID",
"originalRequest": {
"method": "POST",
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"sellerId\": 1,\n \"buyerId\": 2,\n \"description\": \"This is a sample contract.\",\n \"productId\": 3,\n \"minTemp\": -20.0,\n \"maxTemp\": 40.0,\n \"arrivalDate\": 1674019200,\n \"penaltyType\": \"AMOUNT\",\n \"penaltyValue\": 100,\n \"penaltyRec\": \"DAILY\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "{{URL}}/contracts/create",
"raw": "{{URL}}/contracts/1",
"host": [
"{{URL}}"
],
"path": [
"contracts",
"create"
"1"
]
}
},
@@ -1817,17 +1710,23 @@
},
{
"key": "Date",
"value": "Fri, 06 Oct 2023 08:40:15 GMT"
"value": "Thu, 09 Nov 2023 09:18:14 GMT"
},
{
"key": "Content-Length",
"value": "61"
"value": "703"
}
],
"cookie": [],
"body": "{\n \"id\": 9,\n \"message\": \"Successfully received and saved contract\"\n}"
"body": "{\n \"data\": {\n \"id\": 1,\n \"createdAt\": \"2023-09-13T08:36:41.742294+02:00\",\n \"updatedAt\": \"2023-09-13T08:36:41.742294+02:00\",\n \"deletedAt\": {\n \"Time\": \"0001-01-01T00:00:00Z\",\n \"Valid\": false\n },\n \"name\": \"Contract1\",\n \"deviceIds\": [\n 5,\n 6,\n 7\n ],\n \"seller\": {\n \"id\": 2,\n \"name\": \"\"\n },\n \"buyer\": {\n \"id\": 1,\n \"name\": \"\"\n },\n \"start\": {\n \"name\": \"\",\n \"lat\": 1,\n \"lon\": 1,\n \"time\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n \"end\": {\n \"name\": \"\",\n \"lat\": 1,\n \"lon\": 1,\n \"time\": \"2023-09-20T08:36:41.742294+02:00\"\n },\n \"product\": {\n \"id\": 0,\n \"name\": \"\"\n },\n \"description\": \"\",\n \"status\": \"active\",\n \"blockchainId\": \"\",\n \"contractInfos\": null,\n \"maxTemp\": 10,\n \"minTemp\": 1,\n \"arrivalDate\": \"0001-01-01T00:00:00Z\",\n \"penaltyType\": \"\",\n \"penaltyValue\": 0,\n \"penaltyRec\": \"\",\n \"devicesImeis\": [\n \"352656107000002\",\n \"352656107000000\",\n \"352656107000001\"\n ]\n }\n}"
}
]
}
],
"variable": [
{
"key": "AuthToken",
"value": "JBYYy0cb5FOzc_VxWg1tDOF8tKu2Dl5NhR"
}
]
}