Merge branch 'create-contract' into 'main'
Added create contact ednpoint See merge request ukacorp/mesari/backend!16
This commit was merged in pull request #16.
This commit is contained in:
792
NOVA.postman_collection.json
Normal file
792
NOVA.postman_collection.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,20 +1,23 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gitlab.com/pactual1/backend/database/contract"
|
"gitlab.com/pactual1/backend/database/contract"
|
||||||
"gitlab.com/pactual1/backend/models"
|
"gitlab.com/pactual1/backend/models"
|
||||||
|
"gitlab.com/pactual1/backend/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetLatestContracts(c *gin.Context) {
|
func GetLatestContracts(c *gin.Context) {
|
||||||
// Existing parameters
|
// Existing parameters
|
||||||
limitStr := c.DefaultQuery("limit", "50")
|
limitStr := c.DefaultQuery("limit", "50")
|
||||||
offsetStr := c.DefaultQuery("offset", "0")
|
offsetStr := c.DefaultQuery("offset", "0")
|
||||||
status := c.DefaultQuery("status", models.ContractStatusActive)
|
status := strings.Split(c.DefaultQuery("status", models.ContractStatusActive), ",")
|
||||||
|
|
||||||
// New/Updated optional parameters
|
// New/Updated optional parameters
|
||||||
companyName := c.Query("company_name")
|
companyName := c.Query("company_name")
|
||||||
@@ -81,7 +84,7 @@ func GetLatestContracts(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Respond with the contracts and the total count
|
// Respond with the contracts and the total count
|
||||||
c.JSON(http.StatusOK, gin.H{"total": total, "data": contracts})
|
c.JSON(http.StatusOK, gin.H{"total": total, "data": models.ConvertContractToResponse(contracts)})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +92,7 @@ func GetBuyerContracts(c *gin.Context) {
|
|||||||
// Existing parameters
|
// Existing parameters
|
||||||
limitStr := c.DefaultQuery("limit", "50")
|
limitStr := c.DefaultQuery("limit", "50")
|
||||||
offsetStr := c.DefaultQuery("offset", "0")
|
offsetStr := c.DefaultQuery("offset", "0")
|
||||||
status := c.Query("status")
|
status := strings.Split(c.DefaultQuery("status", models.ContractStatusActive), ",")
|
||||||
|
|
||||||
contractIDStr := c.DefaultQuery("contract_id","0")
|
contractIDStr := c.DefaultQuery("contract_id","0")
|
||||||
dateCreatedStr := c.Query("date_created")
|
dateCreatedStr := c.Query("date_created")
|
||||||
@@ -137,44 +140,51 @@ func GetBuyerContracts(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Respond with the contracts and the total count
|
// Respond with the contracts and the total count
|
||||||
c.JSON(http.StatusOK, gin.H{"total": total, "data": convertContractToResponseModel(contracts)})
|
c.JSON(http.StatusOK, gin.H{"total": total, "data": models.ConvertContractToResponseModel(contracts)})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetContractStatuses(c *gin.Context) {
|
func GetContractStatuses(c *gin.Context) {
|
||||||
|
|
||||||
// Respond with the contract statuses
|
// Respond with the contract statuses
|
||||||
c.JSON(http.StatusOK, gin.H{"statuses": models.GetContractStatuses()})
|
c.JSON(http.StatusOK, gin.H{"data": models.GetContractStatuses()})
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func convertContractToResponseModel(contracts []models.Contract) []models.ListContractResponse {
|
|
||||||
var listInvoiceResponses []models.ListContractResponse
|
|
||||||
|
|
||||||
// Get all statuses
|
|
||||||
statuses := models.GetContractStatuses()
|
|
||||||
statusMap := make(map[string]models.Status)
|
|
||||||
for _, s := range statuses {
|
|
||||||
statusMap[s.Value] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, contract := range contracts {
|
|
||||||
// Get the status based on Value in the DB
|
|
||||||
status, ok := statusMap[contract.Status]
|
|
||||||
if !ok {
|
|
||||||
status = models.Status{Key: "Unknown", Value: "unknown"}
|
|
||||||
}
|
|
||||||
|
|
||||||
listInvoiceResponse := models.ListContractResponse{
|
|
||||||
Status: models.KeyValue{Key: status.Key, Value: status.Value},
|
|
||||||
Buyer: models.CompanyShortResponse{ID: int(contract.BuyerID), Name: contract.BuyerName},
|
|
||||||
ContractID: int(contract.ID),
|
|
||||||
DateCreated: contract.CreatedAt,
|
|
||||||
NumberOfDevices: contract.NumberOfDevices,
|
|
||||||
}
|
|
||||||
listInvoiceResponses = append(listInvoiceResponses, listInvoiceResponse)
|
|
||||||
}
|
|
||||||
return listInvoiceResponses
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func CreateContract(c *gin.Context) {
|
||||||
|
|
||||||
|
var payload models.CreateContractRequestPayload
|
||||||
|
|
||||||
|
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON payload"})
|
||||||
|
log.Printf("Invalid JSON payload: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
db := shared.GetDb()
|
||||||
|
|
||||||
|
newContract := models.Contract{
|
||||||
|
BuyerID: payload.BuyerID,
|
||||||
|
SellerID: payload.SellerID,
|
||||||
|
Description: payload.Description,
|
||||||
|
ProductID: payload.ProductID,
|
||||||
|
MinTemp: payload.MinTemp,
|
||||||
|
MaxTemp: payload.MaxTemp,
|
||||||
|
ArrivalDate: time.Unix(payload.ArrivalDate, 0),
|
||||||
|
PenaltyType: payload.PenaltyRec,
|
||||||
|
PenaltyValue : payload.PenaltyValue,
|
||||||
|
PenaltyRec : payload.PenaltyRec,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Create(&newContract).Error; err != nil {
|
||||||
|
log.Printf("SaveContractInfo CREATE - Contract DB Error: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create new contract"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Successfully received and saved contract: %v", newContract)
|
||||||
|
c.JSON(http.StatusOK, gin.H{"message": "Successfully received and saved contract", "id": newContract.ID})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -161,5 +161,5 @@ func GetDevicesByContract(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Respond with the devices
|
// Respond with the devices
|
||||||
c.JSON(http.StatusOK,gin.H{"data" : devices})
|
c.JSON(http.StatusOK,gin.H{"data" : models.ConvertDeviceToResponse(devices)})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,10 @@ func GetInvoiceByID(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invoiceResponses := models.ConvertInvoiceToResponse(invoices)
|
||||||
|
|
||||||
if len(invoices) > 0 {
|
if len(invoices) > 0 {
|
||||||
c.JSON(http.StatusOK, gin.H{"data": invoices[0]})
|
c.JSON(http.StatusOK, gin.H{"data": invoiceResponses[0]})
|
||||||
} else {
|
} else {
|
||||||
c.JSON(http.StatusNotFound, gin.H{"error": "Invoice not found"})
|
c.JSON(http.StatusNotFound, gin.H{"error": "Invoice not found"})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func GetContracts(status string, companyName string, companyAddress string,
|
func GetContracts(status []string, companyName string, companyAddress string,
|
||||||
companyEmail string, companyPhone string, startTime *time.Time, endTime *time.Time,
|
companyEmail string, companyPhone string, startTime *time.Time, endTime *time.Time,
|
||||||
contractName string, deviceIDs []int64, contractID int, dateCreated *time.Time, limit, offset int) ([]models.Contract, int64, int, error) {
|
contractName string, deviceIDs []int64, contractID int, dateCreated *time.Time, limit, offset int) ([]models.Contract, int64, int, error) {
|
||||||
|
|
||||||
@@ -24,10 +24,10 @@ func GetContracts(status string, companyName string, companyAddress string,
|
|||||||
// Define custom fields to be selected, varies based on joined tables
|
// Define custom fields to be selected, varies based on joined tables
|
||||||
customFields := "contracts.*, array_length(contracts.device_ids, 1) as number_of_devices"
|
customFields := "contracts.*, array_length(contracts.device_ids, 1) as number_of_devices"
|
||||||
|
|
||||||
// Search by Status
|
// Search by Statuses
|
||||||
if status != "" {
|
if len(status) > 0 {
|
||||||
db = db.Where("contracts.status = ?", status)
|
db = db.Where("contracts.status IN (?)", status)
|
||||||
countDb = countDb.Where("contracts.status = ?", status)
|
countDb = countDb.Where("contracts.status IN (?)", status)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search by Company Fields
|
// Search by Company Fields
|
||||||
|
|||||||
@@ -79,13 +79,14 @@ func GetDeviceInfoForContract (deviceID uint64, contract models.Contract) (model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceInfosResponse := models.ConvertDeviceInfoToResponse(deviceInfos)
|
||||||
|
|
||||||
// Loop through each deviceInfo to create GeoJSON features
|
// Loop through each deviceInfo to create GeoJSON features
|
||||||
for _, info := range deviceInfos {
|
for _, info := range deviceInfosResponse {
|
||||||
info.RawJSON = ""
|
info.RawJSON = ""
|
||||||
feature := models.GeoJSONFeature{
|
feature := models.GeoJSONFeature{
|
||||||
Type: "Feature",
|
Type: "Feature",
|
||||||
DeviceInfo: &info,
|
DeviceInfoResponse: &info,
|
||||||
Geometry: models.GeoJSONGeometry{
|
Geometry: models.GeoJSONGeometry{
|
||||||
Type: "Point",
|
Type: "Point",
|
||||||
Coordinates: []float64{info.Lon, info.Lat},
|
Coordinates: []float64{info.Lon, info.Lat},
|
||||||
|
|||||||
@@ -47,13 +47,15 @@ func GetInvoices(buyerName string, sortBy string, limit int, offset int, id uint
|
|||||||
Find(&invoices).Error; err != nil {
|
Find(&invoices).Error; err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range invoices {
|
for i := range invoices {
|
||||||
var sum int64
|
var sum int64
|
||||||
for _, item := range invoices[i].InvoiceItem {
|
if invoices[i].InvoiceItem != nil {
|
||||||
|
for _, item := range *invoices[i].InvoiceItem {
|
||||||
sum += item.PriceCents * item.Quantity
|
sum += item.PriceCents * item.Quantity
|
||||||
}
|
}
|
||||||
invoices[i].PriceCents = sum
|
invoices[i].PriceCents = sum
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return invoices, total, nil
|
return invoices, total, nil
|
||||||
|
|||||||
@@ -1,20 +1,29 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "github.com/jinzhu/gorm"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseModel struct {
|
||||||
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
|
CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"`
|
||||||
|
}
|
||||||
type Company struct {
|
type Company struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
Address string
|
Address string `json:"address"`
|
||||||
Email string
|
Email string `json:"email"`
|
||||||
Phone string
|
Phone string `json:"phone"`
|
||||||
Users []User
|
Users []User `json:"users"`
|
||||||
Devices []Device
|
Devices []Device `json:"devices"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompanyShortResponse struct {
|
type CompanyShortResponse struct {
|
||||||
ID int
|
ID int `json:"id"`
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,22 +9,127 @@ import (
|
|||||||
|
|
||||||
type Contract struct {
|
type Contract struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
DeviceIDs pq.Int64Array `gorm:"type:integer[]"`
|
DeviceIDs pq.Int64Array `json:"deviceIds" gorm:"type:integer[]"`
|
||||||
BuyerID uint
|
BuyerID uint `json:"buyerId"`
|
||||||
StartLat float64
|
SellerID uint `json:"sellerId"`
|
||||||
StartLon float64
|
Description string `json:"description"`
|
||||||
EndLat float64
|
StartLat float64 `json:"startLat"`
|
||||||
EndLon float64
|
StartLon float64 `json:"startLon"`
|
||||||
StartTime time.Time
|
EndLat float64 `json:"endLat"`
|
||||||
EndTime time.Time
|
EndLon float64 `json:"endLon"`
|
||||||
Status string
|
StartTime time.Time `json:"startTime"`
|
||||||
BlockchainID string
|
EndTime time.Time `json:"endTime"`
|
||||||
ContractInfos []ContractInfo
|
Status string `json:"status"`
|
||||||
BuyerName string `gorm:"-"`
|
BlockchainID string `json:"blockchainId"`
|
||||||
NumberOfDevices int `gorm:"-"`
|
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[]"`
|
||||||
|
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:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func ConvertContractToResponse(contracts []Contract) []ContractResponse {
|
||||||
|
var contractResponses []ContractResponse
|
||||||
|
for _, contract := range contracts {
|
||||||
|
contractResponse := ContractResponse{
|
||||||
|
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.BlockchainID,
|
||||||
|
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 ConvertContractToResponseModel(contracts []Contract) []ListContractResponse {
|
||||||
|
var listInvoiceResponses []ListContractResponse
|
||||||
|
|
||||||
|
// Get all statuses
|
||||||
|
statuses := GetContractStatuses()
|
||||||
|
statusMap := make(map[string]Status)
|
||||||
|
for _, s := range statuses {
|
||||||
|
statusMap[s.Value] = 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),
|
||||||
|
DateCreated: contract.CreatedAt,
|
||||||
|
NumberOfDevices: contract.NumberOfDevices,
|
||||||
|
}
|
||||||
|
listInvoiceResponses = append(listInvoiceResponses, listInvoiceResponse)
|
||||||
|
}
|
||||||
|
return listInvoiceResponses
|
||||||
|
|
||||||
|
}
|
||||||
const ContractStatusActive = "active"
|
const ContractStatusActive = "active"
|
||||||
const ContractStatusPending = "pending"
|
const ContractStatusPending = "pending"
|
||||||
const ContractStatusDraft = "draft"
|
const ContractStatusDraft = "draft"
|
||||||
@@ -34,6 +139,13 @@ const ContractStatusExecuted = "executed"
|
|||||||
const ContractStatusRevoked = "revoked"
|
const ContractStatusRevoked = "revoked"
|
||||||
|
|
||||||
|
|
||||||
|
const PenaltyTypeAmount = "amount"
|
||||||
|
const PenaltyTypePercentage = "percentage"
|
||||||
|
|
||||||
|
const PenaltyRecDaily = "daily"
|
||||||
|
const PenaltyRecMonthly = "monthly"
|
||||||
|
|
||||||
|
|
||||||
type Status struct {
|
type Status struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
@@ -41,25 +153,38 @@ type Status struct {
|
|||||||
|
|
||||||
func GetContractStatuses() []Status {
|
func GetContractStatuses() []Status {
|
||||||
return []Status{
|
return []Status{
|
||||||
{Key: "Active", Value: "active"},
|
{Value: "Active", Key: "active"},
|
||||||
{Key: "Pending signature", Value: "pending"},
|
{Value: "Pending signature", Key: "pending"},
|
||||||
{Key: "Draft", Value: "draft"},
|
{Value: "Draft", Key: "draft"},
|
||||||
{Key: "Signed", Value: "signed"},
|
{Value: "Signed", Key: "signed"},
|
||||||
{Key: "Ready for Activation", Value: "ready_for_activation"},
|
{Value: "Ready for Activation", Key: "ready_for_activation"},
|
||||||
{Key: "Executed", Value: "executed"},
|
{Value: "Executed", Key: "executed"},
|
||||||
{Key: "Revoked", Value: "revoked"},
|
{Value: "Revoked", Key: "revoked"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListContractResponse struct {
|
type ListContractResponse struct {
|
||||||
Status KeyValue `json:"Status"`
|
Status KeyValue `json:"status"`
|
||||||
Buyer CompanyShortResponse `json:"Buyer"`
|
Buyer CompanyShortResponse `json:"buyer"`
|
||||||
ContractID int
|
ContractID int `json:"contractID"`
|
||||||
NumberOfDevices int
|
NumberOfDevices int `json:"numberOfDevices"`
|
||||||
DateCreated time.Time
|
DateCreated time.Time `json:"dateCreated"`
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
func (Contract) Update() (bool, error) {
|
func (Contract) Update() (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
@@ -69,3 +194,5 @@ func (Contract) Create() (bool, error) {
|
|||||||
func (Contract) Delete() (bool, error) {
|
func (Contract) Delete() (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,54 @@ import (
|
|||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
DeviceID string `json:"deviceId"`
|
DeviceID string `json:"deviceId"`
|
||||||
DeviceName string
|
DeviceName string `json:"deviceName"`
|
||||||
IMEI string `json:"imei"`
|
IMEI string `json:"imei"`
|
||||||
IMSI string `json:"imsi"`
|
IMSI string `json:"imsi"`
|
||||||
DeviceConfiguration string `gorm:"type:json"`
|
DeviceConfiguration string `json:"deviceConfiguration" gorm:"type:json"`
|
||||||
CompanyID uint
|
CompanyID uint `json:"companyId"`
|
||||||
DeviceInfos []DeviceInfo
|
DeviceInfos *[]DeviceInfo `json:"deviceInfos"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeviceResponse struct {
|
||||||
|
BaseModel
|
||||||
|
DeviceID string `json:"deviceId"`
|
||||||
|
DeviceName string `json:"deviceName"`
|
||||||
|
IMEI string `json:"imei"`
|
||||||
|
IMSI string `json:"imsi"`
|
||||||
|
DeviceConfiguration string `json:"deviceConfiguration" gorm:"type:json"`
|
||||||
|
CompanyID uint `json:"companyId"`
|
||||||
|
DeviceInfos *[]DeviceInfo `json:"deviceInfos"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertDeviceToResponse(devices []Device) []DeviceResponse {
|
||||||
|
var deviceResponses []DeviceResponse
|
||||||
|
for _, device := range devices {
|
||||||
|
if device.DeviceInfos == nil {
|
||||||
|
emptySlice := make([]DeviceInfo, 0)
|
||||||
|
device.DeviceInfos = &emptySlice
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceResponse := DeviceResponse{
|
||||||
|
BaseModel: BaseModel{
|
||||||
|
ID: device.ID,
|
||||||
|
CreatedAt: device.CreatedAt,
|
||||||
|
UpdatedAt: device.UpdatedAt,
|
||||||
|
},
|
||||||
|
DeviceID: device.DeviceID,
|
||||||
|
DeviceName: device.DeviceName,
|
||||||
|
IMEI: device.IMEI,
|
||||||
|
IMSI: device.IMSI,
|
||||||
|
DeviceConfiguration: device.DeviceConfiguration,
|
||||||
|
CompanyID: device.CompanyID,
|
||||||
|
DeviceInfos: device.DeviceInfos,
|
||||||
|
}
|
||||||
|
deviceResponses = append(deviceResponses, deviceResponse)
|
||||||
|
}
|
||||||
|
return deviceResponses
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Device) Update() (bool, error) {
|
func (Device) Update() (bool, error) {
|
||||||
@@ -30,3 +69,4 @@ func (d *Device) Delete(db *gorm.DB) (bool, error) {
|
|||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "github.com/jinzhu/gorm"
|
import (
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
// Location holds latitude and longitude.
|
// Location holds latitude and longitude.
|
||||||
type Location struct {
|
type Location struct {
|
||||||
@@ -10,17 +12,15 @@ type Location struct {
|
|||||||
|
|
||||||
// ImportantInfo holds fields that are important for quick access.
|
// ImportantInfo holds fields that are important for quick access.
|
||||||
type SensorData struct {
|
type SensorData struct {
|
||||||
IMEI string `json:"imei"`
|
IMEI string `json:"imei"`
|
||||||
IMSI string `json:"imsi"`
|
IMSI string `json:"imsi"`
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
Lat float64 `json:"lat"`
|
Lat float64 `json:"lat"`
|
||||||
Lon float64 `json:"lon"`
|
Lon float64 `json:"lon"`
|
||||||
WifiLoc Location `json:"wifi_location"`
|
WifiLoc Location `json:"wifiLocation"`
|
||||||
CellLoc Location `json:"cell_location"`
|
CellLoc Location `json:"cellLocation"`
|
||||||
Temperature float64 `json:"temperature"`
|
Temperature float64 `json:"temperature"`
|
||||||
// Used to parse incoming json data
|
AccInfo AccelerometerInfo `json:"accelerometerInfo"`
|
||||||
AccInfo AccelerometerInfo `json:"accelerometerInfo"`
|
|
||||||
// Used to store coordinates of accelerometer to DB
|
|
||||||
AccelerometerInfo
|
AccelerometerInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,12 +33,38 @@ type DeviceInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type AccelerometerInfo struct {
|
type DeviceInfoResponse struct {
|
||||||
X int64
|
BaseModel
|
||||||
Y int64
|
RawJSON string `json:"rawJson" gorm:"type:json"`
|
||||||
Z int64
|
SensorData
|
||||||
|
DeviceID uint `json:"deviceId"`
|
||||||
|
ExternalDeviceID string `json:"externalDeviceId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConvertDeviceInfoToResponse(deviceInfos []DeviceInfo) []DeviceInfoResponse {
|
||||||
|
var deviceInfoResponses []DeviceInfoResponse
|
||||||
|
for _, deviceInfo := range deviceInfos {
|
||||||
|
deviceInfoResponse := DeviceInfoResponse{
|
||||||
|
BaseModel: BaseModel{
|
||||||
|
ID: deviceInfo.ID,
|
||||||
|
CreatedAt: deviceInfo.CreatedAt,
|
||||||
|
UpdatedAt: deviceInfo.UpdatedAt,
|
||||||
|
},
|
||||||
|
RawJSON: deviceInfo.RawJSON,
|
||||||
|
SensorData: deviceInfo.SensorData,
|
||||||
|
DeviceID: deviceInfo.DeviceID,
|
||||||
|
ExternalDeviceID: deviceInfo.ExternalDeviceID,
|
||||||
|
}
|
||||||
|
deviceInfoResponses = append(deviceInfoResponses, deviceInfoResponse)
|
||||||
|
}
|
||||||
|
return deviceInfoResponses
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccelerometerInfo struct {
|
||||||
|
X int64 `json:"x"`
|
||||||
|
Y int64 `json:"y"`
|
||||||
|
Z int64 `json:"z"`
|
||||||
|
}
|
||||||
type GeoJSONFeatureCollection struct {
|
type GeoJSONFeatureCollection struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Features []GeoJSONFeature `json:"features"`
|
Features []GeoJSONFeature `json:"features"`
|
||||||
@@ -47,7 +73,7 @@ type GeoJSONFeatureCollection struct {
|
|||||||
type GeoJSONFeature struct {
|
type GeoJSONFeature struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Geometry GeoJSONGeometry `json:"geometry"`
|
Geometry GeoJSONGeometry `json:"geometry"`
|
||||||
DeviceInfo *DeviceInfo `json:",omitempty"`
|
DeviceInfoResponse *DeviceInfoResponse `json:"deviceInfo,omitempty"`
|
||||||
Properties map[string]interface{} `json:"properties"`
|
Properties map[string]interface{} `json:"properties"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +82,6 @@ type GeoJSONGeometry struct {
|
|||||||
Coordinates []float64 `json:"coordinates"`
|
Coordinates []float64 `json:"coordinates"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (DeviceInfo) Update() (bool, error) {
|
func (DeviceInfo) Update() (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
@@ -8,42 +9,113 @@ import (
|
|||||||
|
|
||||||
type Invoice struct {
|
type Invoice struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
BuyerID uint
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
BuyerName string
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
BuyerAddress string
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
BuyerEmail string
|
DeletedAt sql.NullTime `json:"deletedAt" gorm:"index"`
|
||||||
BuyerPhone string
|
BuyerID uint `json:"buyerId"`
|
||||||
SellerID uint
|
BuyerName string `json:"buyerName"`
|
||||||
SellerName string
|
BuyerAddress string `json:"buyerAddress"`
|
||||||
SellerAddress string
|
BuyerEmail string `json:"buyerEmail"`
|
||||||
SellerEmail string
|
BuyerPhone string `json:"buyerPhone"`
|
||||||
SellerPhone string
|
SellerID uint `json:"sellerId"`
|
||||||
PriceCents int64 `gorm:"column:price_cents"`
|
SellerName string `json:"sellerName"`
|
||||||
Discount int64
|
SellerAddress string `json:"sellerAddress"`
|
||||||
Tax int64
|
SellerEmail string `json:"sellerEmail"`
|
||||||
TermsAndConditions string
|
SellerPhone string `json:"sellerPhone"`
|
||||||
InvoiceName string
|
PriceCents int64 `json:"priceCents" gorm:"column:price_cents"`
|
||||||
InvoiceDate time.Time
|
Discount int64 `json:"discount"`
|
||||||
InvoiceDueDate time.Time
|
Tax int64 `json:"tax"`
|
||||||
ContractID uint
|
TermsAndConditions string `json:"termsAndConditions"`
|
||||||
InvoiceItem [] InvoiceItem
|
InvoiceName string `json:"invoiceName"`
|
||||||
Status string
|
InvoiceDate time.Time `json:"invoiceDate"`
|
||||||
|
InvoiceDueDate time.Time `json:"invoiceDueDate"`
|
||||||
|
ContractID uint `json:"contractId"`
|
||||||
|
InvoiceItem *[]InvoiceItem `json:"invoiceItem"`
|
||||||
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InvoiceResponse struct {
|
||||||
|
BaseModel
|
||||||
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
DeletedAt sql.NullTime `json:"deletedAt" gorm:"index"`
|
||||||
|
BuyerID uint `json:"buyerId"`
|
||||||
|
BuyerName string `json:"buyerName"`
|
||||||
|
BuyerAddress string `json:"buyerAddress"`
|
||||||
|
BuyerEmail string `json:"buyerEmail"`
|
||||||
|
BuyerPhone string `json:"buyerPhone"`
|
||||||
|
SellerID uint `json:"sellerId"`
|
||||||
|
SellerName string `json:"sellerName"`
|
||||||
|
SellerAddress string `json:"sellerAddress"`
|
||||||
|
SellerEmail string `json:"sellerEmail"`
|
||||||
|
SellerPhone string `json:"sellerPhone"`
|
||||||
|
PriceCents int64 `json:"priceCents" gorm:"column:price_cents"`
|
||||||
|
Discount int64 `json:"discount"`
|
||||||
|
Tax int64 `json:"tax"`
|
||||||
|
TermsAndConditions string `json:"termsAndConditions"`
|
||||||
|
InvoiceName string `json:"invoiceName"`
|
||||||
|
InvoiceDate time.Time `json:"invoiceDate"`
|
||||||
|
InvoiceDueDate time.Time `json:"invoiceDueDate"`
|
||||||
|
ContractID uint `json:"contractId"`
|
||||||
|
InvoiceItem *[]InvoiceItem `json:"invoiceItem"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertInvoiceToResponse(invoices []Invoice) []InvoiceResponse {
|
||||||
|
var invoiceResponses []InvoiceResponse
|
||||||
|
for _, invoice := range invoices {
|
||||||
|
if invoice.InvoiceItem == nil {
|
||||||
|
emptySlice := make([]InvoiceItem, 0)
|
||||||
|
invoice.InvoiceItem = &emptySlice
|
||||||
|
}
|
||||||
|
|
||||||
|
invoiceResponse := InvoiceResponse{
|
||||||
|
BaseModel: BaseModel{
|
||||||
|
ID: invoice.ID,
|
||||||
|
CreatedAt: invoice.CreatedAt,
|
||||||
|
UpdatedAt: invoice.UpdatedAt,
|
||||||
|
},
|
||||||
|
BuyerID: invoice.BuyerID,
|
||||||
|
BuyerName: invoice.BuyerName,
|
||||||
|
BuyerAddress: invoice.BuyerAddress,
|
||||||
|
BuyerEmail: invoice.BuyerEmail,
|
||||||
|
BuyerPhone: invoice.BuyerPhone,
|
||||||
|
SellerID: invoice.SellerID,
|
||||||
|
SellerName: invoice.SellerName,
|
||||||
|
SellerAddress: invoice.SellerAddress,
|
||||||
|
SellerEmail: invoice.SellerEmail,
|
||||||
|
SellerPhone: invoice.SellerPhone,
|
||||||
|
PriceCents: invoice.PriceCents,
|
||||||
|
Discount: invoice.Discount,
|
||||||
|
Tax: invoice.Tax,
|
||||||
|
TermsAndConditions: invoice.TermsAndConditions,
|
||||||
|
InvoiceName: invoice.InvoiceName,
|
||||||
|
InvoiceDate: invoice.InvoiceDate,
|
||||||
|
InvoiceDueDate: invoice.InvoiceDueDate,
|
||||||
|
ContractID: invoice.ContractID,
|
||||||
|
InvoiceItem: invoice.InvoiceItem,
|
||||||
|
Status: invoice.Status,
|
||||||
|
}
|
||||||
|
invoiceResponses = append(invoiceResponses, invoiceResponse)
|
||||||
|
}
|
||||||
|
return invoiceResponses
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type ListInvoiceResponse struct {
|
type ListInvoiceResponse struct {
|
||||||
Status KeyValue `json:"Status"`
|
Status KeyValue `json:"status"`
|
||||||
Buyer CompanyShortResponse `json:"Buyer"`
|
Buyer CompanyShortResponse `json:"buyer"`
|
||||||
ContractID int
|
ContractID int `json:"contractId"`
|
||||||
DateCreated time.Time
|
DateCreated time.Time `json:"dateCreated"`
|
||||||
DueDate time.Time
|
DueDate time.Time `json:"dueDate"`
|
||||||
Amount string
|
Amount string `json:"amount"`
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyValue struct {
|
type KeyValue struct {
|
||||||
Key string
|
Key string `json:"key"`
|
||||||
Value string
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,60 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InvoiceItem struct {
|
type InvoiceItem struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Description string
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
Quantity int64
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
Unit string
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
PriceCents int64 `gorm:"column:price_cents"`
|
DeletedAt sql.NullTime `json:"deletedAt" gorm:"index"`
|
||||||
InvoiceID uint
|
Description string `json:"description"`
|
||||||
|
Quantity int64 `json:"quantity"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
PriceCents int64 `json:"priceCents" gorm:"column:price_cents"`
|
||||||
|
InvoiceID uint `json:"invoiceId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InvoiceItemResponse struct {
|
||||||
|
BaseModel
|
||||||
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
DeletedAt sql.NullTime `json:"deletedAt" gorm:"index"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Quantity int64 `json:"quantity"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
PriceCents int64 `json:"priceCents" gorm:"column:price_cents"`
|
||||||
|
InvoiceID uint `json:"invoiceId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertSliceOfInvoiceItemToResponse converts a slice of InvoiceItem models to a slice of InvoiceItemResponse models
|
||||||
|
func ConvertInvoiceItemToResponse(items []InvoiceItem) []InvoiceItemResponse {
|
||||||
|
var itemResponses []InvoiceItemResponse
|
||||||
|
for _, item := range items {
|
||||||
|
itemResponse := InvoiceItemResponse{
|
||||||
|
BaseModel: BaseModel{
|
||||||
|
ID: item.ID,
|
||||||
|
CreatedAt: item.CreatedAt,
|
||||||
|
UpdatedAt: item.UpdatedAt,
|
||||||
|
},
|
||||||
|
Description: item.Description,
|
||||||
|
Quantity: item.Quantity,
|
||||||
|
Unit: item.Unit,
|
||||||
|
PriceCents: item.PriceCents,
|
||||||
|
InvoiceID: item.InvoiceID,
|
||||||
|
}
|
||||||
|
itemResponses = append(itemResponses, itemResponse)
|
||||||
|
}
|
||||||
|
return itemResponses
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func (InvoiceItem) Update() (bool, error) {
|
func (InvoiceItem) Update() (bool, error) {
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "github.com/jinzhu/gorm"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Username string
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
Password string
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
Email string
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
Avatar string
|
DeletedAt sql.NullTime `json:"deletedAt" gorm:"index"`
|
||||||
CompanyID uint
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
CompanyID uint `json:"companyId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (User) Update() (bool, error) {
|
func (User) Update() (bool, error) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ func RegisterPublicRoutes(r *gin.Engine) {
|
|||||||
|
|
||||||
// Contracts
|
// Contracts
|
||||||
r.GET("/contracts/statuses", controllers.GetContractStatuses)
|
r.GET("/contracts/statuses", controllers.GetContractStatuses)
|
||||||
r.GET("/contracts/list", controllers.GetBuyerContracts)
|
r.GET("/contracts", controllers.GetBuyerContracts)
|
||||||
|
r.POST("/contracts/create", controllers.CreateContract)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user