...
This commit is contained in:
100
pkg/heroservices/billing/models/transaction.go
Normal file
100
pkg/heroservices/billing/models/transaction.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
// Transaction represents a financial transaction in the billing system
|
||||
type Transaction struct {
|
||||
TxID uint32 // Transaction ID, auto-incremented
|
||||
From uint32 // Source account ID
|
||||
To uint32 // Destination account ID
|
||||
Comment string // Transaction comment
|
||||
Amount float64 // Transaction amount
|
||||
}
|
||||
|
||||
// Serialize converts a Transaction to a binary representation
|
||||
func (t *Transaction) Serialize() []byte {
|
||||
// Calculate the size of the serialized data
|
||||
// 4 bytes for TxID + 4 bytes for From + 4 bytes for To +
|
||||
// 2 bytes for comment length + len(comment) bytes + 8 bytes for amount
|
||||
size := 4 + 4 + 4 + 2 + len(t.Comment) + 8
|
||||
data := make([]byte, size)
|
||||
|
||||
// Write TxID (4 bytes)
|
||||
binary.LittleEndian.PutUint32(data[0:4], t.TxID)
|
||||
|
||||
// Write From (4 bytes)
|
||||
binary.LittleEndian.PutUint32(data[4:8], t.From)
|
||||
|
||||
// Write To (4 bytes)
|
||||
binary.LittleEndian.PutUint32(data[8:12], t.To)
|
||||
|
||||
// Write comment length (2 bytes) and comment
|
||||
commentLen := uint16(len(t.Comment))
|
||||
binary.LittleEndian.PutUint16(data[12:14], commentLen)
|
||||
copy(data[14:14+commentLen], t.Comment)
|
||||
|
||||
// Write amount (8 bytes)
|
||||
amountOffset := 14 + int(commentLen)
|
||||
binary.LittleEndian.PutUint64(data[amountOffset:amountOffset+8], math.Float64bits(t.Amount))
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
// DeserializeTransaction converts a binary representation back to a Transaction
|
||||
func DeserializeTransaction(data []byte) (*Transaction, error) {
|
||||
if len(data) < 22 { // Minimum size: 4 (TxID) + 4 (From) + 4 (To) + 2 (comment length) + 8 (amount)
|
||||
return nil, errors.New("data too short to deserialize Transaction")
|
||||
}
|
||||
|
||||
transaction := &Transaction{}
|
||||
|
||||
// Read TxID
|
||||
transaction.TxID = binary.LittleEndian.Uint32(data[0:4])
|
||||
|
||||
// Read From
|
||||
transaction.From = binary.LittleEndian.Uint32(data[4:8])
|
||||
|
||||
// Read To
|
||||
transaction.To = binary.LittleEndian.Uint32(data[8:12])
|
||||
|
||||
// Read comment length and comment
|
||||
commentLen := binary.LittleEndian.Uint16(data[12:14])
|
||||
if 14+commentLen > uint16(len(data)) {
|
||||
return nil, errors.New("data too short to read comment")
|
||||
}
|
||||
transaction.Comment = string(data[14 : 14+commentLen])
|
||||
|
||||
// Read amount
|
||||
amountOffset := 14 + commentLen
|
||||
if int(amountOffset)+8 > len(data) {
|
||||
return nil, errors.New("data too short to read amount")
|
||||
}
|
||||
transaction.Amount = math.Float64frombits(binary.LittleEndian.Uint64(data[amountOffset : amountOffset+8]))
|
||||
|
||||
return transaction, nil
|
||||
}
|
||||
|
||||
// Validate checks if the transaction data is valid
|
||||
func (t *Transaction) Validate() error {
|
||||
if t.From == 0 {
|
||||
return errors.New("source account ID cannot be zero")
|
||||
}
|
||||
|
||||
if t.To == 0 {
|
||||
return errors.New("destination account ID cannot be zero")
|
||||
}
|
||||
|
||||
if t.From == t.To {
|
||||
return errors.New("source and destination accounts cannot be the same")
|
||||
}
|
||||
|
||||
if t.Amount <= 0 {
|
||||
return errors.New("amount must be positive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user