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
@@ -0,0 +1,3 @@
-- Remove convertion fields from marketing_delivery_products table
ALTER TABLE marketing_delivery_products
DROP COLUMN IF EXISTS weight_per_convertion;
@@ -0,0 +1,4 @@
-- Add convertion fields to marketing_delivery_products table
ALTER TABLE marketing_delivery_products
ADD COLUMN IF NOT EXISTS weight_per_convertion NUMERIC(15, 3);
@@ -12,6 +12,7 @@ type MarketingDeliveryProduct struct {
UnitPrice float64 `gorm:"type:numeric(15,3)"` UnitPrice float64 `gorm:"type:numeric(15,3)"`
TotalWeight float64 `gorm:"type:numeric(15,3)"` TotalWeight float64 `gorm:"type:numeric(15,3)"`
AvgWeight float64 `gorm:"type:numeric(15,3)"` AvgWeight float64 `gorm:"type:numeric(15,3)"`
WeightPerConvertion *float64 `gorm:"type:numeric(15,3)"`
TotalPrice float64 `gorm:"type:numeric(15,3)"` TotalPrice float64 `gorm:"type:numeric(15,3)"`
DeliveryDate *time.Time `gorm:"type:timestamptz"` DeliveryDate *time.Time `gorm:"type:timestamptz"`
VehicleNumber string `gorm:"type:varchar(50)"` VehicleNumber string `gorm:"type:varchar(50)"`
@@ -58,6 +58,8 @@ type MarketingDeliveryProductDTO struct {
TotalPrice float64 `json:"total_price"` TotalPrice float64 `json:"total_price"`
DeliveryDate *time.Time `json:"delivery_date"` DeliveryDate *time.Time `json:"delivery_date"`
VehicleNumber string `json:"vehicle_number"` VehicleNumber string `json:"vehicle_number"`
ConvertionUnit *string `json:"-"`
WeightPerConvertion *float64 `json:"-"`
ProductWarehouse *productwarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse,omitempty"` ProductWarehouse *productwarehouseDTO.ProductWarehousNestedDTO `json:"product_warehouse,omitempty"`
} }
@@ -67,6 +69,8 @@ type DeliveryItemDTO struct {
UnitPrice float64 `json:"unit_price"` UnitPrice float64 `json:"unit_price"`
TotalWeight float64 `json:"total_weight"` TotalWeight float64 `json:"total_weight"`
AvgWeight float64 `json:"avg_weight"` AvgWeight float64 `json:"avg_weight"`
WeightPerConvertion *float64 `json:"weight_per_convertion"`
TotalPeti *float64 `json:"total_peti"`
TotalPrice float64 `json:"total_price"` TotalPrice float64 `json:"total_price"`
VehicleNumber string `json:"vehicle_number"` VehicleNumber string `json:"vehicle_number"`
} }
@@ -156,6 +160,7 @@ func ToMarketingDeliveryProductDTO(e entity.MarketingDeliveryProduct) MarketingD
TotalPrice: e.TotalPrice, TotalPrice: e.TotalPrice,
DeliveryDate: e.DeliveryDate, DeliveryDate: e.DeliveryDate,
VehicleNumber: e.VehicleNumber, VehicleNumber: e.VehicleNumber,
WeightPerConvertion: e.WeightPerConvertion,
} }
} }
@@ -285,6 +290,7 @@ func enrichDeliveryProductDTOsWithWarehouse(deliveryProductDTOs []MarketingDeliv
mapped := productwarehouseDTO.ToProductWarehouseNestedDTO(product.ProductWarehouse) mapped := productwarehouseDTO.ToProductWarehouseNestedDTO(product.ProductWarehouse)
deliveryProductDTOs[i].ProductWarehouse = &mapped deliveryProductDTOs[i].ProductWarehouse = &mapped
} }
deliveryProductDTOs[i].ConvertionUnit = product.ConvertionUnit
} }
} }
@@ -327,9 +333,17 @@ func groupDeliveryProducts(products []MarketingDeliveryProductDTO, soNumber stri
UnitPrice: product.UnitPrice, UnitPrice: product.UnitPrice,
TotalWeight: product.TotalWeight, TotalWeight: product.TotalWeight,
AvgWeight: product.AvgWeight, AvgWeight: product.AvgWeight,
WeightPerConvertion: product.WeightPerConvertion,
TotalPrice: product.TotalPrice, TotalPrice: product.TotalPrice,
VehicleNumber: product.VehicleNumber, 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) group.Deliveries = append(group.Deliveries, deliveryItem)
} }
@@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"math"
"strings" "strings"
"time" "time"
@@ -375,11 +376,12 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Delivery
itemDeliveryDate = &parsedDate 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.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
deliveryProduct.UnitPrice = requestedProduct.UnitPrice deliveryProduct.UnitPrice = requestedProduct.UnitPrice
deliveryProduct.AvgWeight = requestedProduct.AvgWeight deliveryProduct.AvgWeight = requestedProduct.AvgWeight
deliveryProduct.WeightPerConvertion = requestedProduct.WeightPerConvertion
deliveryProduct.TotalWeight = totalWeight deliveryProduct.TotalWeight = totalWeight
deliveryProduct.TotalPrice = totalPrice deliveryProduct.TotalPrice = totalPrice
deliveryProduct.DeliveryDate = itemDeliveryDate deliveryProduct.DeliveryDate = itemDeliveryDate
@@ -498,11 +500,12 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
itemDeliveryDate = deliveryProduct.DeliveryDate 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.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
deliveryProduct.UnitPrice = requestedProduct.UnitPrice deliveryProduct.UnitPrice = requestedProduct.UnitPrice
deliveryProduct.AvgWeight = requestedProduct.AvgWeight deliveryProduct.AvgWeight = requestedProduct.AvgWeight
deliveryProduct.WeightPerConvertion = requestedProduct.WeightPerConvertion
deliveryProduct.TotalWeight = totalWeight deliveryProduct.TotalWeight = totalWeight
deliveryProduct.TotalPrice = totalPrice deliveryProduct.TotalPrice = totalPrice
deliveryProduct.DeliveryDate = itemDeliveryDate deliveryProduct.DeliveryDate = itemDeliveryDate
@@ -541,17 +544,50 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
return s.getMarketingWithDeliveries(c, id) 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) { if marketingType == string(utils.MarketingTypeTrading) {
totalWeight = 0 totalWeight = 0
totalPrice = qty * unitPrice totalPrice = math.Round(qty*unitPrice*100) / 100
} else if marketingType == string(utils.MarketingTypeAyamPullet) && week != nil && *week > 0 { } else if marketingType == string(utils.MarketingTypeAyamPullet) && week != nil && *week > 0 {
totalWeight = qty * avgWeight totalWeight = math.Round(qty*avgWeight*100) / 100
totalPrice = unitPrice * float64(*week) * qty totalPrice = math.Round(unitPrice*float64(*week)*qty*100) / 100
} else { } else {
totalWeight = qty * avgWeight totalWeight = math.Round(qty*avgWeight*100) / 100
totalPrice = totalWeight * unitPrice
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 return totalWeight, totalPrice
} }
@@ -815,7 +815,7 @@ func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Cont
return nil 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) { if marketingType == string(utils.MarketingTypeTrading) {
totalWeight = 0 totalWeight = 0
totalPrice = math.Round(qty*unitPrice*100) / 100 totalPrice = math.Round(qty*unitPrice*100) / 100
@@ -831,13 +831,10 @@ func (s *salesOrdersService) calculatePriceByMarketingType(marketingType string,
totalPrice = math.Round(qty*unitPrice*100) / 100 totalPrice = math.Round(qty*unitPrice*100) / 100
return totalWeight, totalPrice return totalWeight, totalPrice
case string(utils.ConvertionUnitPeti): case string(utils.ConvertionUnitPeti):
if weightPerConvertion != nil && *weightPerConvertion > 0 { totalPrice = math.Round(totalWeight*unitPrice*100) / 100
totalPeti := totalWeight / *weightPerConvertion
totalPrice = math.Round(totalPeti*unitPrice*100) / 100
return totalWeight, totalPrice return totalWeight, totalPrice
} }
} }
}
totalPrice = math.Round(totalWeight*unitPrice*100) / 100 totalPrice = math.Round(totalWeight*unitPrice*100) / 100
} }
@@ -5,6 +5,9 @@ type DeliveryProduct struct {
Qty float64 `json:"qty" validate:"omitempty,gte=0"` Qty float64 `json:"qty" validate:"omitempty,gte=0"`
UnitPrice float64 `json:"unit_price" validate:"omitempty,gte=0"` UnitPrice float64 `json:"unit_price" validate:"omitempty,gte=0"`
AvgWeight float64 `json:"avg_weight" 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"` DeliveryDate string `json:"delivery_date" validate:"omitempty,datetime=2006-01-02"`
VehicleNumber string `json:"vehicle_number" validate:"omitempty,max=50"` VehicleNumber string `json:"vehicle_number" validate:"omitempty,max=50"`
} }