adjust edit delivery order; add migration for delivery order; adjust response get marketing

This commit is contained in:
giovanni
2026-04-14 14:48:56 +07:00
parent 7ca7d0841b
commit cd549de578
7 changed files with 111 additions and 53 deletions
@@ -49,26 +49,30 @@ type MarketingDetailDTO struct {
}
type MarketingDeliveryProductDTO struct {
Id uint `json:"id"`
MarketingProductId uint `json:"marketing_product_id"`
Qty float64 `json:"qty"`
UnitPrice float64 `json:"unit_price"`
TotalWeight float64 `json:"total_weight"`
AvgWeight float64 `json:"avg_weight"`
TotalPrice float64 `json:"total_price"`
DeliveryDate *time.Time `json:"delivery_date"`
VehicleNumber string `json:"vehicle_number"`
ProductWarehouse *productwarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse,omitempty"`
Id uint `json:"id"`
MarketingProductId uint `json:"marketing_product_id"`
Qty float64 `json:"qty"`
UnitPrice float64 `json:"unit_price"`
TotalWeight float64 `json:"total_weight"`
AvgWeight float64 `json:"avg_weight"`
TotalPrice float64 `json:"total_price"`
DeliveryDate *time.Time `json:"delivery_date"`
VehicleNumber string `json:"vehicle_number"`
ConvertionUnit *string `json:"-"`
WeightPerConvertion *float64 `json:"-"`
ProductWarehouse *productwarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse,omitempty"`
}
type DeliveryItemDTO struct {
ProductWarehouse *productwarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse"`
Qty float64 `json:"qty"`
UnitPrice float64 `json:"unit_price"`
TotalWeight float64 `json:"total_weight"`
AvgWeight float64 `json:"avg_weight"`
TotalPrice float64 `json:"total_price"`
VehicleNumber string `json:"vehicle_number"`
ProductWarehouse *productwarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse"`
Qty float64 `json:"qty"`
UnitPrice float64 `json:"unit_price"`
TotalWeight float64 `json:"total_weight"`
AvgWeight float64 `json:"avg_weight"`
WeightPerConvertion *float64 `json:"weight_per_convertion"`
TotalPeti *float64 `json:"total_peti"`
TotalPrice float64 `json:"total_price"`
VehicleNumber string `json:"vehicle_number"`
}
type DeliveryGroupDTO struct {
@@ -147,15 +151,16 @@ func ToDeliveryMarketingProductDTO(e entity.MarketingProduct, marketingType stri
func ToMarketingDeliveryProductDTO(e entity.MarketingDeliveryProduct) MarketingDeliveryProductDTO {
return MarketingDeliveryProductDTO{
Id: e.Id,
MarketingProductId: e.MarketingProductId,
Qty: e.UsageQty,
UnitPrice: e.UnitPrice,
TotalWeight: e.TotalWeight,
AvgWeight: e.AvgWeight,
TotalPrice: e.TotalPrice,
DeliveryDate: e.DeliveryDate,
VehicleNumber: e.VehicleNumber,
Id: e.Id,
MarketingProductId: e.MarketingProductId,
Qty: e.UsageQty,
UnitPrice: e.UnitPrice,
TotalWeight: e.TotalWeight,
AvgWeight: e.AvgWeight,
TotalPrice: e.TotalPrice,
DeliveryDate: e.DeliveryDate,
VehicleNumber: e.VehicleNumber,
WeightPerConvertion: e.WeightPerConvertion,
}
}
@@ -285,6 +290,7 @@ func enrichDeliveryProductDTOsWithWarehouse(deliveryProductDTOs []MarketingDeliv
mapped := productwarehouseDTO.ToProductWarehouseNestedDTO(product.ProductWarehouse)
deliveryProductDTOs[i].ProductWarehouse = &mapped
}
deliveryProductDTOs[i].ConvertionUnit = product.ConvertionUnit
}
}
@@ -322,13 +328,21 @@ func groupDeliveryProducts(products []MarketingDeliveryProductDTO, soNumber stri
}
deliveryItem := DeliveryItemDTO{
ProductWarehouse: product.ProductWarehouse,
Qty: product.Qty,
UnitPrice: product.UnitPrice,
TotalWeight: product.TotalWeight,
AvgWeight: product.AvgWeight,
TotalPrice: product.TotalPrice,
VehicleNumber: product.VehicleNumber,
ProductWarehouse: product.ProductWarehouse,
Qty: product.Qty,
UnitPrice: product.UnitPrice,
TotalWeight: product.TotalWeight,
AvgWeight: product.AvgWeight,
WeightPerConvertion: product.WeightPerConvertion,
TotalPrice: product.TotalPrice,
VehicleNumber: product.VehicleNumber,
}
if product.ConvertionUnit != nil &&
strings.EqualFold(*product.ConvertionUnit, "PETI") &&
product.WeightPerConvertion != nil &&
*product.WeightPerConvertion > 0 {
totalPeti := product.TotalWeight / *product.WeightPerConvertion
deliveryItem.TotalPeti = &totalPeti
}
group.Deliveries = append(group.Deliveries, deliveryItem)
}
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"math"
"strings"
"time"
@@ -375,11 +376,12 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Delivery
itemDeliveryDate = &parsedDate
}
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, requestedProduct.Qty, requestedProduct.AvgWeight, requestedProduct.UnitPrice, foundMarketingProduct.Week)
totalWeight, totalPrice := s.resolveDeliveryTotals(marketing.MarketingType, requestedProduct, foundMarketingProduct)
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
deliveryProduct.AvgWeight = requestedProduct.AvgWeight
deliveryProduct.WeightPerConvertion = requestedProduct.WeightPerConvertion
deliveryProduct.TotalWeight = totalWeight
deliveryProduct.TotalPrice = totalPrice
deliveryProduct.DeliveryDate = itemDeliveryDate
@@ -498,11 +500,12 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
itemDeliveryDate = deliveryProduct.DeliveryDate
}
totalWeight, totalPrice := s.calculatePriceByMarketingType(marketing.MarketingType, requestedProduct.Qty, requestedProduct.AvgWeight, requestedProduct.UnitPrice, foundMarketingProduct.Week)
totalWeight, totalPrice := s.resolveDeliveryTotals(marketing.MarketingType, requestedProduct, foundMarketingProduct)
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
deliveryProduct.AvgWeight = requestedProduct.AvgWeight
deliveryProduct.WeightPerConvertion = requestedProduct.WeightPerConvertion
deliveryProduct.TotalWeight = totalWeight
deliveryProduct.TotalPrice = totalPrice
deliveryProduct.DeliveryDate = itemDeliveryDate
@@ -541,20 +544,53 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
return s.getMarketingWithDeliveries(c, id)
}
func (s *deliveryOrdersService) calculatePriceByMarketingType(marketingType string, qty, avgWeight, unitPrice float64, week *int) (totalWeight, totalPrice float64) {
func (s *deliveryOrdersService) calculatePriceByMarketingType(marketingType string, qty, avgWeight, unitPrice float64, week *int, convertionUnit *string, _ *float64) (totalWeight, totalPrice float64) {
if marketingType == string(utils.MarketingTypeTrading) {
totalWeight = 0
totalPrice = qty * unitPrice
totalPrice = math.Round(qty*unitPrice*100) / 100
} else if marketingType == string(utils.MarketingTypeAyamPullet) && week != nil && *week > 0 {
totalWeight = qty * avgWeight
totalPrice = unitPrice * float64(*week) * qty
totalWeight = math.Round(qty*avgWeight*100) / 100
totalPrice = math.Round(unitPrice*float64(*week)*qty*100) / 100
} else {
totalWeight = qty * avgWeight
totalPrice = totalWeight * unitPrice
totalWeight = math.Round(qty*avgWeight*100) / 100
if marketingType == string(utils.MarketingTypeTelur) && convertionUnit != nil {
switch *convertionUnit {
case string(utils.ConvertionUnitQty):
totalPrice = math.Round(qty*unitPrice*100) / 100
return totalWeight, totalPrice
case string(utils.ConvertionUnitPeti):
totalPrice = math.Round(totalWeight*unitPrice*100) / 100
return totalWeight, totalPrice
}
}
totalPrice = math.Round(totalWeight*unitPrice*100) / 100
}
return totalWeight, totalPrice
}
func (s *deliveryOrdersService) resolveDeliveryTotals(marketingType string, requestedProduct validation.DeliveryProduct, marketingProduct *entity.MarketingProduct) (totalWeight, totalPrice float64) {
totalWeight, totalPrice = s.calculatePriceByMarketingType(
marketingType,
requestedProduct.Qty,
requestedProduct.AvgWeight,
requestedProduct.UnitPrice,
marketingProduct.Week,
marketingProduct.ConvertionUnit,
marketingProduct.WeightPerConvertion,
)
if requestedProduct.TotalWeight != nil {
totalWeight = *requestedProduct.TotalWeight
}
if requestedProduct.TotalPrice != nil {
totalPrice = *requestedProduct.TotalPrice
}
return totalWeight, totalPrice
}
func (s deliveryOrdersService) consumeDeliveryStock(ctx context.Context, tx *gorm.DB, deliveryProduct *entity.MarketingDeliveryProduct, marketingProduct *entity.MarketingProduct, requestedQty float64, actorID uint) error {
if marketingProduct == nil || marketingProduct.ProductWarehouseId == 0 {
return fiber.NewError(fiber.StatusInternalServerError, "Product warehouse not found")
@@ -815,7 +815,7 @@ func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Cont
return nil
}
func (s *salesOrdersService) calculatePriceByMarketingType(marketingType string, qty, avgWeight, unitPrice float64, week *int, convertionUnit *string, weightPerConvertion *float64) (totalWeight, totalPrice float64) {
func (s *salesOrdersService) calculatePriceByMarketingType(marketingType string, qty, avgWeight, unitPrice float64, week *int, convertionUnit *string, _ *float64) (totalWeight, totalPrice float64) {
if marketingType == string(utils.MarketingTypeTrading) {
totalWeight = 0
totalPrice = math.Round(qty*unitPrice*100) / 100
@@ -831,11 +831,8 @@ func (s *salesOrdersService) calculatePriceByMarketingType(marketingType string,
totalPrice = math.Round(qty*unitPrice*100) / 100
return totalWeight, totalPrice
case string(utils.ConvertionUnitPeti):
if weightPerConvertion != nil && *weightPerConvertion > 0 {
totalPeti := totalWeight / *weightPerConvertion
totalPrice = math.Round(totalPeti*unitPrice*100) / 100
return totalWeight, totalPrice
}
totalPrice = math.Round(totalWeight*unitPrice*100) / 100
return totalWeight, totalPrice
}
}
@@ -1,12 +1,15 @@
package validation
type DeliveryProduct struct {
MarketingProductId uint `json:"marketing_product_id" validate:"required,gt=0"`
Qty float64 `json:"qty" validate:"omitempty,gte=0"`
UnitPrice float64 `json:"unit_price" validate:"omitempty,gte=0"`
AvgWeight float64 `json:"avg_weight" validate:"omitempty,gte=0"`
DeliveryDate string `json:"delivery_date" validate:"omitempty,datetime=2006-01-02"`
VehicleNumber string `json:"vehicle_number" validate:"omitempty,max=50"`
MarketingProductId uint `json:"marketing_product_id" validate:"required,gt=0"`
Qty float64 `json:"qty" validate:"omitempty,gte=0"`
UnitPrice float64 `json:"unit_price" validate:"omitempty,gte=0"`
AvgWeight float64 `json:"avg_weight" validate:"omitempty,gte=0"`
WeightPerConvertion *float64 `json:"weight_per_convertion" validate:"omitempty,gt=0"`
TotalWeight *float64 `json:"total_weight" validate:"omitempty,gte=0"`
TotalPrice *float64 `json:"total_price" validate:"omitempty,gte=0"`
DeliveryDate string `json:"delivery_date" validate:"omitempty,datetime=2006-01-02"`
VehicleNumber string `json:"vehicle_number" validate:"omitempty,max=50"`
}
type DeliveryOrderCreate struct {