mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'FEAT/BE/Transfer_stock' into 'development'
[FEAT][BE-transfer_Stock]L Update StockTransferDelivery and TransferDeliveryDTO to allow optional SupplierId See merge request mbugroup/lti-api!265
This commit is contained in:
@@ -6,7 +6,7 @@ import "time"
|
||||
type StockTransferDelivery struct {
|
||||
Id uint64 `gorm:"primaryKey;autoIncrement"`
|
||||
StockTransferId uint64
|
||||
SupplierId uint64
|
||||
SupplierId *uint64
|
||||
VehiclePlate string
|
||||
DriverName string
|
||||
DocumentNumber string
|
||||
|
||||
@@ -60,7 +60,7 @@ type TransferDetailItemDTO struct {
|
||||
|
||||
type TransferDeliveryDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
Supplier SupplierSimpleDTO `json:"supplier"`
|
||||
Supplier *SupplierSimpleDTO `json:"supplier,omitempty"`
|
||||
VehiclePlate string `json:"vehicle_plate"`
|
||||
DriverName string `json:"driver_name"`
|
||||
DocumentNumber string `json:"document_number"`
|
||||
@@ -115,7 +115,6 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
|
||||
Quantity: d.UsageQty + d.PendingQty, // Total actual quantity allocated
|
||||
}
|
||||
|
||||
|
||||
if d.ExpenseNonstock != nil {
|
||||
priceCopy := d.ExpenseNonstock.Price
|
||||
detailDTO.TransportPerItem = &priceCopy
|
||||
@@ -155,12 +154,17 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
|
||||
}
|
||||
}
|
||||
|
||||
deliveries = append(deliveries, TransferDeliveryDTO{
|
||||
Id: del.Id,
|
||||
Supplier: SupplierSimpleDTO{
|
||||
var supplier *SupplierSimpleDTO
|
||||
if del.Supplier != nil {
|
||||
supplier = &SupplierSimpleDTO{
|
||||
Id: del.Supplier.Id,
|
||||
Name: del.Supplier.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
deliveries = append(deliveries, TransferDeliveryDTO{
|
||||
Id: del.Id,
|
||||
Supplier: supplier,
|
||||
VehiclePlate: del.VehiclePlate,
|
||||
DriverName: del.DriverName,
|
||||
DocumentNumber: del.DocumentNumber,
|
||||
@@ -201,7 +205,6 @@ func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO {
|
||||
Quantity: d.UsageQty + d.PendingQty, // Total actual quantity allocated
|
||||
}
|
||||
|
||||
|
||||
if d.ExpenseNonstock != nil {
|
||||
priceCopy := d.ExpenseNonstock.Price
|
||||
detailDTO.TransportPerItem = &priceCopy
|
||||
@@ -241,12 +244,17 @@ func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO {
|
||||
}
|
||||
}
|
||||
|
||||
deliveries = append(deliveries, TransferDeliveryDTO{
|
||||
Id: del.Id,
|
||||
Supplier: SupplierSimpleDTO{
|
||||
var supplier *SupplierSimpleDTO
|
||||
if del.Supplier != nil {
|
||||
supplier = &SupplierSimpleDTO{
|
||||
Id: del.Supplier.Id,
|
||||
Name: del.Supplier.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
deliveries = append(deliveries, TransferDeliveryDTO{
|
||||
Id: del.Id,
|
||||
Supplier: supplier,
|
||||
VehiclePlate: del.VehiclePlate,
|
||||
DriverName: del.DriverName,
|
||||
DocumentNumber: del.DocumentNumber,
|
||||
|
||||
@@ -196,6 +196,11 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
|
||||
}
|
||||
|
||||
for _, delivery := range req.Deliveries {
|
||||
// Skip supplier validation if SupplierID is 0 (optional)
|
||||
if delivery.SupplierID == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
supplier, err := s.SupplierRepo.GetByID(c.Context(), uint(delivery.SupplierID), nil)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -310,9 +315,16 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
|
||||
|
||||
var deliveries []*entity.StockTransferDelivery
|
||||
for _, delivery := range req.Deliveries {
|
||||
supplierId := func() *uint64 {
|
||||
if delivery.SupplierID > 0 {
|
||||
id := uint64(delivery.SupplierID)
|
||||
return &id
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
deliveries = append(deliveries, &entity.StockTransferDelivery{
|
||||
StockTransferId: entityTransfer.Id,
|
||||
SupplierId: uint64(delivery.SupplierID),
|
||||
SupplierId: supplierId,
|
||||
VehiclePlate: delivery.VehiclePlate,
|
||||
DriverName: delivery.DriverName,
|
||||
ShippingCostItem: delivery.DeliveryCostPerItem,
|
||||
@@ -458,6 +470,11 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
|
||||
|
||||
if len(req.Deliveries) > 0 {
|
||||
for _, delivery := range req.Deliveries {
|
||||
// Skip adding to expensePayloads if SupplierID is 0 (optional)
|
||||
if delivery.SupplierID == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, prod := range delivery.Products {
|
||||
detail := detailMap[uint64(prod.ProductID)]
|
||||
if detail == nil {
|
||||
|
||||
@@ -26,7 +26,7 @@ type TransferDelivery struct {
|
||||
DocumentIndex int `json:"document_index" validate:"omitempty,min=-1" default:"-1"`
|
||||
DriverName string `json:"driver_name" validate:"required"`
|
||||
VehiclePlate string `json:"vehicle_plate" validate:"required"`
|
||||
SupplierID uint `json:"supplier_id" validate:"required"`
|
||||
SupplierID uint `json:"supplier_id" `
|
||||
Products []TransferDeliveryProduct `json:"products" validate:"required,dive"`
|
||||
}
|
||||
|
||||
|
||||
@@ -650,9 +650,9 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
repoTx := s.Repository.WithTx(dbTransaction)
|
||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(dbTransaction))
|
||||
|
||||
// Gunakan repo baru untuk transaction scope agar bisa akses method custom
|
||||
sourceRepoTx := repository.NewLayingTransferSourceRepository(dbTransaction)
|
||||
targetRepoTx := repository.NewLayingTransferTargetRepository(dbTransaction)
|
||||
stockLogRepoTx := rStockLogs.NewStockLogRepository(dbTransaction)
|
||||
|
||||
for _, approvableID := range approvableIDs {
|
||||
transfer, err := repoTx.GetByID(c.Context(), approvableID, nil)
|
||||
@@ -687,23 +687,28 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil targets transfer")
|
||||
}
|
||||
|
||||
// Hitung total quantity dari targets untuk di-consume dari sources
|
||||
totalTargetQty := 0.0
|
||||
for _, target := range targets {
|
||||
totalTargetQty += target.TotalQty
|
||||
}
|
||||
|
||||
// Consume dari laying_transfer_sources (Usable) - akan consume dari ProjectFlockPopulation (Stockable)
|
||||
totalSourceRequested := 0.0
|
||||
for _, source := range sources {
|
||||
totalSourceRequested += source.RequestedQty
|
||||
}
|
||||
|
||||
for _, source := range sources {
|
||||
if source.ProductWarehouseId == nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Source product warehouse tidak ditemukan untuk transfer %d", approvableID))
|
||||
}
|
||||
|
||||
sourceShare := (source.RequestedQty / totalSourceRequested) * totalTargetQty
|
||||
|
||||
consumeResult, err := s.FifoSvc.Consume(c.Context(), commonSvc.StockConsumeRequest{
|
||||
UsableKey: fifo.UsableKeyTransferToLayingOut,
|
||||
UsableID: source.Id,
|
||||
ProductWarehouseID: *source.ProductWarehouseId,
|
||||
Quantity: totalTargetQty,
|
||||
Quantity: sourceShare,
|
||||
AllowPending: false,
|
||||
Tx: dbTransaction,
|
||||
})
|
||||
@@ -717,6 +722,19 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
}, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Gagal update source usage qty")
|
||||
}
|
||||
|
||||
stockLogDecrease := &entity.StockLog{
|
||||
ProductWarehouseId: *source.ProductWarehouseId,
|
||||
CreatedBy: actorID,
|
||||
Increase: 0,
|
||||
Decrease: sourceShare,
|
||||
LoggableType: string(utils.StockLogTypeTransferLaying),
|
||||
LoggableId: approvableID,
|
||||
Notes: fmt.Sprintf("TL #%s", transfer.TransferNumber),
|
||||
}
|
||||
if err := stockLogRepoTx.CreateOne(c.Context(), stockLogDecrease, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Gagal membuat log stok keluar")
|
||||
}
|
||||
}
|
||||
|
||||
for _, target := range targets {
|
||||
@@ -725,7 +743,7 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
}
|
||||
|
||||
note := fmt.Sprintf("Transfer to Laying #%s", transfer.TransferNumber)
|
||||
replenishResult, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{
|
||||
_, err := s.FifoSvc.Replenish(c.Context(), commonSvc.StockReplenishRequest{
|
||||
StockableKey: fifo.StockableKeyTransferToLayingIn,
|
||||
StockableID: target.Id,
|
||||
ProductWarehouseID: *target.ProductWarehouseId,
|
||||
@@ -738,10 +756,23 @@ func (s transferLayingService) Approval(c *fiber.Ctx, req *validation.Approve) (
|
||||
}
|
||||
|
||||
if err := targetRepoTx.PatchOne(c.Context(), target.Id, map[string]interface{}{
|
||||
"total_qty": replenishResult.AddedQuantity,
|
||||
"total_qty": target.TotalQty,
|
||||
}, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Gagal update target total qty")
|
||||
}
|
||||
|
||||
stockLogIncrease := &entity.StockLog{
|
||||
ProductWarehouseId: *target.ProductWarehouseId,
|
||||
CreatedBy: actorID,
|
||||
Increase: target.TotalQty,
|
||||
Decrease: 0,
|
||||
LoggableType: string(utils.StockLogTypeTransferLaying),
|
||||
LoggableId: approvableID,
|
||||
Notes: fmt.Sprintf("TL #%s", transfer.TransferNumber),
|
||||
}
|
||||
if err := stockLogRepoTx.CreateOne(c.Context(), stockLogIncrease, nil); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Gagal membuat log stok masuk")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ type Update struct {
|
||||
|
||||
type Query struct {
|
||||
Page int `query:"page" validate:"omitempty,number,min=1,gt=0"`
|
||||
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100,gt=0"`
|
||||
Limit int `query:"limit" validate:"omitempty,number,min=1,gt=0"`
|
||||
Search string `query:"search" validate:"omitempty"`
|
||||
StartDate string `query:"start_date" validate:"omitempty"`
|
||||
EndDate string `query:"end_date" validate:"omitempty"`
|
||||
|
||||
@@ -111,6 +111,7 @@ type StockLogType string
|
||||
const (
|
||||
StockLogTypeAdjustment StockLogType = "ADJUSTMENT"
|
||||
StockLogTypeTransfer StockLogType = "TRANSFER"
|
||||
StockLogTypeTransferLaying StockLogType = "TRANSFER_LAYING"
|
||||
StockLogTypeMarketing StockLogType = "MARKETING"
|
||||
StockLogTypeChikin StockLogType = "CHICKIN"
|
||||
StockLogTypePurchase StockLogType = "PURCHASE"
|
||||
|
||||
Reference in New Issue
Block a user