mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'fix/delivery-order' into 'development'
[FIX][BE]: adjust edit delivery order; add migration for delivery order; adjust response get marketing See merge request mbugroup/lti-api!417
This commit is contained in:
@@ -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)"`
|
||||
TotalWeight 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)"`
|
||||
DeliveryDate *time.Time `gorm:"type:timestamptz"`
|
||||
VehicleNumber string `gorm:"type:varchar(50)"`
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user