Files
lti-api/internal/utils/recording/util.recording.go
T
2026-03-30 13:40:29 +07:00

212 lines
5.3 KiB
Go

package recording
import (
"fmt"
"strings"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/validations"
)
func MapStocks(recordingID uint, items []validation.Stock) []entity.RecordingStock {
if len(items) == 0 {
return nil
}
result := make([]entity.RecordingStock, 0, len(items))
for _, item := range items {
usagePtr := new(float64)
*usagePtr = item.Qty
result = append(result, entity.RecordingStock{
RecordingId: recordingID,
ProductWarehouseId: item.ProductWarehouseId,
UsageQty: usagePtr,
})
}
return result
}
func MapDepletions(recordingID uint, items []validation.Depletion) []entity.RecordingDepletion {
if len(items) == 0 {
return nil
}
type depletionKey struct {
ProductWarehouseID uint
SourceProductWarehouseID uint
}
aggregate := make(map[depletionKey]float64, len(items))
for _, item := range items {
if item.ProductWarehouseId == 0 || item.Qty == 0 {
continue
}
key := depletionKey{ProductWarehouseID: item.ProductWarehouseId}
if item.SourceProductWarehouseId != nil {
key.SourceProductWarehouseID = *item.SourceProductWarehouseId
}
aggregate[key] += item.Qty
}
if len(aggregate) == 0 {
return nil
}
result := make([]entity.RecordingDepletion, 0, len(aggregate))
for key, qty := range aggregate {
if qty == 0 {
continue
}
var sourceWarehouseID *uint
if key.SourceProductWarehouseID != 0 {
sourceWarehouseID = new(uint)
*sourceWarehouseID = key.SourceProductWarehouseID
}
result = append(result, entity.RecordingDepletion{
RecordingId: recordingID,
ProductWarehouseId: key.ProductWarehouseID,
SourceProductWarehouseId: sourceWarehouseID,
Qty: qty,
})
}
return result
}
func MapEggs(recordingID uint, projectFlockKandangID uint, createdBy uint, items []validation.Egg) []entity.RecordingEgg {
if len(items) == 0 {
return nil
}
result := make([]entity.RecordingEgg, 0, len(items))
for _, item := range items {
var sourceProjectFlockKandangID *uint
if projectFlockKandangID != 0 {
sourceProjectFlockKandangID = new(uint)
*sourceProjectFlockKandangID = projectFlockKandangID
}
result = append(result, entity.RecordingEgg{
RecordingId: recordingID,
ProductWarehouseId: item.ProductWarehouseId,
ProjectFlockKandangId: sourceProjectFlockKandangID,
Qty: item.Qty,
Weight: item.Weight,
CreatedBy: createdBy,
})
}
return result
}
type EggTotals struct {
Qty int
Weight float64
}
type DepletionRoute struct {
ProductWarehouseId uint
SourceProductWarehouseId uint
}
func StockUsageByWarehouse(items []entity.RecordingStock) map[uint]float64 {
return TotalsByWarehouse(items, func(stock entity.RecordingStock) (uint, float64) {
var usage float64
if stock.UsageQty != nil {
usage = *stock.UsageQty
}
return stock.ProductWarehouseId, usage
})
}
func StockUsageByWarehouseReq(items []validation.Stock) map[uint]float64 {
return TotalsByWarehouse(items, func(item validation.Stock) (uint, float64) {
return item.ProductWarehouseId, item.Qty
})
}
func FloatMapsEqual(a, b map[uint]float64) bool {
if len(a) != len(b) {
return false
}
for key, value := range a {
other, ok := b[key]
if !ok || !floatNearlyEqual(value, other) {
return false
}
}
return true
}
func EggTotalsEqual(a, b map[uint]EggTotals) bool {
if len(a) != len(b) {
return false
}
for key, value := range a {
other, ok := b[key]
if !ok || value.Qty != other.Qty || !floatNearlyEqual(value.Weight, other.Weight) {
return false
}
}
return true
}
func DepletionRouteMapsEqual(a, b map[DepletionRoute]float64) bool {
if len(a) != len(b) {
return false
}
for key, value := range a {
other, ok := b[key]
if !ok || !floatNearlyEqual(value, other) {
return false
}
}
return true
}
func floatNearlyEqual(a, b float64) bool {
return a-b <= 0.000001 && b-a <= 0.000001
}
func TotalsByWarehouse[T any](items []T, get func(T) (uint, float64)) map[uint]float64 {
result := make(map[uint]float64)
for _, item := range items {
warehouseID, qty := get(item)
result[warehouseID] += qty
}
return result
}
func DepletionTotalsByRoute[T any](items []T, get func(T) (uint, *uint, float64)) map[DepletionRoute]float64 {
result := make(map[DepletionRoute]float64)
for _, item := range items {
productWarehouseID, sourceProductWarehouseID, qty := get(item)
key := DepletionRoute{ProductWarehouseId: productWarehouseID}
if sourceProductWarehouseID != nil {
key.SourceProductWarehouseId = *sourceProductWarehouseID
}
result[key] += qty
}
return result
}
func EggTotalsByWarehouse[T any](items []T, get func(T) (uint, int, *float64)) map[uint]EggTotals {
result := make(map[uint]EggTotals)
for _, item := range items {
warehouseID, qty, weightPtr := get(item)
weight := 0.0
if weightPtr != nil {
weight = *weightPtr
}
current := result[warehouseID]
current.Qty += qty
current.Weight += weight
result[warehouseID] = current
}
return result
}
func RecordingNote(action string, id uint) string {
action = strings.TrimSpace(action)
if action == "" {
return fmt.Sprintf("Recording#%d", id)
}
return fmt.Sprintf("Recording-%s#%d", action, id)
}