[FEAT/BE] wiring recording,transfer_stock,transfer_laying,marketing for consumer chick in project flock population

This commit is contained in:
ragilap
2026-03-04 12:41:26 +07:00
parent 80135466df
commit d334f46829
17 changed files with 513 additions and 11 deletions
@@ -787,6 +787,7 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
req.Items[idx].TravelDocumentPath = &uploadedURL
}
}
lockedIDs := map[uint]struct{}{}
if action == entity.ApprovalActionApproved {
itemByID := make(map[uint]entity.PurchaseItem, len(purchase.Items))
for i := range purchase.Items {
@@ -795,11 +796,14 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
}
itemByID[purchase.Items[i].Id] = purchase.Items[i]
}
lockedIDs, err := s.resolveChickinLockedItemIDs(ctx, s.PurchaseRepo.DB(), purchase.Items)
locked, err := s.resolveChickinLockedItemIDs(ctx, s.PurchaseRepo.DB(), purchase.Items)
if err != nil {
return nil, err
}
if len(lockedIDs) > 0 {
if len(locked) > 0 {
for id := range locked {
lockedIDs[id] = struct{}{}
}
for _, payload := range req.Items {
if _, used := lockedIDs[payload.PurchaseItemID]; !used {
continue
@@ -880,7 +884,7 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
if receivedQty > item.SubQty {
return nil, utils.BadRequest(fmt.Sprintf("Received quantity for item %d cannot exceed ordered quantity (%.3f)", payload.PurchaseItemID, item.SubQty))
}
if receivedQty < item.TotalUsed {
if receivedQty < item.TotalUsed && isReceivingBelowUsedBlocked(item, lockedIDs) {
return nil, utils.BadRequest(fmt.Sprintf("Received quantity for item %d cannot be lower than used amount (%.3f)", payload.PurchaseItemID, item.TotalUsed))
}
@@ -1659,7 +1663,7 @@ func (s *purchaseService) buildStaffAdjustmentPayload(
if *data.Qty <= 0 {
return nil, utils.BadRequest(fmt.Sprintf("Quantity for item %d must be greater than 0", item.Id))
}
if item.TotalUsed > 0 && *data.Qty < item.TotalUsed {
if item.TotalUsed > 0 && *data.Qty < item.TotalUsed && isReceivingBelowUsedBlocked(&item, nil) {
return nil, utils.BadRequest(fmt.Sprintf("Quantity for item %d cannot be lower than used amount (%.3f)", item.Id, item.TotalUsed))
}
if (item.TotalQty > 0 || item.TotalUsed > 0) && !syncReceiving {
@@ -1778,6 +1782,51 @@ func calculateTotalPrice(quantity float64, price float64, provided *float64, ref
return *provided, nil
}
func purchaseItemHasFlag(item *entity.PurchaseItem, flag utils.FlagType) bool {
if item == nil || item.Product == nil {
return false
}
target := utils.NormalizeFlag(string(flag))
for _, f := range item.Product.Flags {
if utils.NormalizeFlag(f.Name) == target {
return true
}
}
return false
}
func isReceivingBelowUsedBlocked(item *entity.PurchaseItem, lockedIDs map[uint]struct{}) bool {
if item == nil {
return false
}
if !purchaseItemHasAnyFlag(item, []utils.FlagType{
utils.FlagPullet,
utils.FlagLayer,
utils.FlagAyamAfkir,
utils.FlagAyamCulling,
utils.FlagAyamMati,
}) {
return false
}
if lockedIDs == nil {
return true
}
_, locked := lockedIDs[item.Id]
return locked
}
func purchaseItemHasAnyFlag(item *entity.PurchaseItem, flags []utils.FlagType) bool {
if item == nil || item.Product == nil || len(flags) == 0 {
return false
}
for _, flag := range flags {
if purchaseItemHasFlag(item, flag) {
return true
}
}
return false
}
func (s *purchaseService) attachLatestApproval(ctx context.Context, item *entity.Purchase) error {
if item == nil || item.Id == 0 || s.ApprovalSvc == nil {
return nil