mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
176 lines
5.6 KiB
Go
176 lines
5.6 KiB
Go
package dto
|
|
|
|
import (
|
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
|
)
|
|
|
|
// === DTO Structs ===
|
|
|
|
type OverheadDTO struct {
|
|
ItemName string `json:"item_name"`
|
|
UOMName string `json:"uom_name"`
|
|
BudgetQuantity float64 `json:"budget_quantity"`
|
|
BudgetUnitPrice float64 `json:"budget_unit_price"`
|
|
BudgetTotalAmount float64 `json:"budget_total_amount"`
|
|
ActualDate string `json:"actual_date"`
|
|
ActualQuantity float64 `json:"actual_quantity"`
|
|
ActualUnitPrice float64 `json:"actual_unit_price"`
|
|
ActualTotalAmount float64 `json:"actual_total_amount"`
|
|
CostPerBird float64 `json:"cost_per_bird"`
|
|
}
|
|
|
|
type TotalDTO struct {
|
|
BudgetQuantity float64 `json:"budget_quantity"`
|
|
BudgetTotalAmount float64 `json:"budget_total_amount"`
|
|
ActualQuantity float64 `json:"actual_quantity"`
|
|
ActualTotalAmount float64 `json:"actual_total_amount"`
|
|
CostPerBird float64 `json:"cost_per_bird"`
|
|
}
|
|
|
|
type OverheadListDTO struct {
|
|
Total TotalDTO `json:"total"`
|
|
Overheads []OverheadDTO `json:"overheads"`
|
|
}
|
|
|
|
// === Mapper Functions ===
|
|
|
|
func ToOverheadDTO(budget *entity.ProjectBudget, realization *entity.ExpenseRealization) OverheadDTO {
|
|
if budget == nil && realization == nil {
|
|
return OverheadDTO{}
|
|
}
|
|
|
|
var itemName, itemUOM string
|
|
if budget != nil {
|
|
itemName, itemUOM = getItemInfo(budget.Nonstock)
|
|
}
|
|
|
|
if itemName == "" && realization != nil && realization.ExpenseNonstock != nil {
|
|
itemName, itemUOM = getItemInfo(realization.ExpenseNonstock.Nonstock)
|
|
}
|
|
|
|
dto := OverheadDTO{
|
|
ItemName: itemName,
|
|
UOMName: itemUOM,
|
|
}
|
|
|
|
if budget != nil {
|
|
dto.BudgetQuantity = budget.Qty
|
|
dto.BudgetUnitPrice = budget.Price
|
|
dto.BudgetTotalAmount = calculateTotal(budget.Qty, budget.Price)
|
|
}
|
|
|
|
if realization != nil {
|
|
dto.ActualQuantity = realization.Qty
|
|
dto.ActualUnitPrice = realization.Price
|
|
dto.ActualTotalAmount = calculateTotal(realization.Qty, realization.Price)
|
|
dto.ActualDate = formatRealizationDate(realization)
|
|
}
|
|
|
|
return dto
|
|
}
|
|
|
|
func ToOverheadListDTOs(budgets []entity.ProjectBudget, realizations []entity.ExpenseRealization, totalChickinQty float64) OverheadListDTO {
|
|
overheadsByNonstockID := make(map[uint]*OverheadDTO)
|
|
latestDateByNonstockID := make(map[uint]string)
|
|
|
|
for i := range budgets {
|
|
nonstockID := budgets[i].NonstockId
|
|
if overheadsByNonstockID[nonstockID] == nil {
|
|
overheadsByNonstockID[nonstockID] = &OverheadDTO{}
|
|
}
|
|
|
|
itemName, itemUOM := getItemInfo(budgets[i].Nonstock)
|
|
overheadsByNonstockID[nonstockID].ItemName = itemName
|
|
overheadsByNonstockID[nonstockID].UOMName = itemUOM
|
|
overheadsByNonstockID[nonstockID].BudgetQuantity = budgets[i].Qty
|
|
overheadsByNonstockID[nonstockID].BudgetUnitPrice = budgets[i].Price
|
|
overheadsByNonstockID[nonstockID].BudgetTotalAmount = calculateTotal(budgets[i].Qty, budgets[i].Price)
|
|
}
|
|
|
|
for i := range realizations {
|
|
if realizations[i].ExpenseNonstock == nil || realizations[i].ExpenseNonstock.NonstockId == nil {
|
|
continue
|
|
}
|
|
|
|
nonstockID := uint(*realizations[i].ExpenseNonstock.NonstockId)
|
|
if overheadsByNonstockID[nonstockID] == nil {
|
|
overheadsByNonstockID[nonstockID] = &OverheadDTO{}
|
|
}
|
|
|
|
overheadsByNonstockID[nonstockID].ActualQuantity += realizations[i].Qty
|
|
overheadsByNonstockID[nonstockID].ActualTotalAmount += calculateTotal(realizations[i].Qty, realizations[i].Price)
|
|
|
|
if overheadsByNonstockID[nonstockID].ItemName == "" {
|
|
itemName, itemUOM := getItemInfo(realizations[i].ExpenseNonstock.Nonstock)
|
|
overheadsByNonstockID[nonstockID].ItemName = itemName
|
|
overheadsByNonstockID[nonstockID].UOMName = itemUOM
|
|
}
|
|
|
|
realizationDateStr := formatRealizationDate(&realizations[i])
|
|
if realizationDateStr != "" {
|
|
if latestDateByNonstockID[nonstockID] == "" || realizationDateStr > latestDateByNonstockID[nonstockID] {
|
|
latestDateByNonstockID[nonstockID] = realizationDateStr
|
|
}
|
|
}
|
|
}
|
|
|
|
var totalBudgetQuantity, totalBudgetAmount, totalActualQuantity, totalActualAmount float64
|
|
overheadItems := make([]OverheadDTO, 0, len(overheadsByNonstockID))
|
|
|
|
for nonstockID, overhead := range overheadsByNonstockID {
|
|
overhead.ActualDate = latestDateByNonstockID[nonstockID]
|
|
overhead.CostPerBird = calculateCostPerBird(overhead.ActualTotalAmount, totalChickinQty)
|
|
|
|
if overhead.ActualQuantity > 0 {
|
|
overhead.ActualUnitPrice = overhead.ActualTotalAmount / overhead.ActualQuantity
|
|
}
|
|
|
|
totalBudgetQuantity += overhead.BudgetQuantity
|
|
totalBudgetAmount += overhead.BudgetTotalAmount
|
|
totalActualQuantity += overhead.ActualQuantity
|
|
totalActualAmount += overhead.ActualTotalAmount
|
|
|
|
overheadItems = append(overheadItems, *overhead)
|
|
}
|
|
|
|
return OverheadListDTO{
|
|
Total: TotalDTO{
|
|
BudgetQuantity: totalBudgetQuantity,
|
|
BudgetTotalAmount: totalBudgetAmount,
|
|
ActualQuantity: totalActualQuantity,
|
|
ActualTotalAmount: totalActualAmount,
|
|
CostPerBird: calculateCostPerBird(totalActualAmount, totalChickinQty),
|
|
},
|
|
Overheads: overheadItems,
|
|
}
|
|
}
|
|
|
|
// === Helper Functions ===
|
|
|
|
func getItemInfo(nonstock *entity.Nonstock) (string, string) {
|
|
if nonstock != nil && nonstock.Id != 0 {
|
|
return nonstock.Name, nonstock.Uom.Name
|
|
}
|
|
return "", ""
|
|
}
|
|
|
|
func calculateTotal(qty, price float64) float64 {
|
|
return qty * price
|
|
}
|
|
|
|
func calculateCostPerBird(totalPrice, totalChickinQty float64) float64 {
|
|
if totalChickinQty > 0 {
|
|
return totalPrice / totalChickinQty
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func formatRealizationDate(realization *entity.ExpenseRealization) string {
|
|
if realization != nil && realization.ExpenseNonstock != nil && realization.ExpenseNonstock.Expense != nil {
|
|
if !realization.ExpenseNonstock.Expense.RealizationDate.IsZero() {
|
|
return realization.ExpenseNonstock.Expense.RealizationDate.Format("2006-01-02T15:04:05Z07:00")
|
|
}
|
|
}
|
|
return ""
|
|
}
|