mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 21:41:55 +00:00
213 lines
5.4 KiB
Go
213 lines
5.4 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, ownerProjectFlockKandangID *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,
|
|
ProjectFlockKandangId: ownerProjectFlockKandangID,
|
|
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)
|
|
}
|