mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 05:21:57 +00:00
add gudang tujuan to po
This commit is contained in:
@@ -3,13 +3,11 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/dto"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/xuri/excelize/v2"
|
"github.com/xuri/excelize/v2"
|
||||||
@@ -45,7 +43,6 @@ func buildPurchaseExportWorkbook(purchases []entity.Purchase) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listItems := dto.ToPurchaseListDTOs(purchases)
|
|
||||||
grandTotals := buildPurchaseGrandTotalMap(purchases)
|
grandTotals := buildPurchaseGrandTotalMap(purchases)
|
||||||
|
|
||||||
if err := setPurchaseExportColumns(file, purchaseExportSheetName); err != nil {
|
if err := setPurchaseExportColumns(file, purchaseExportSheetName); err != nil {
|
||||||
@@ -54,7 +51,7 @@ func buildPurchaseExportWorkbook(purchases []entity.Purchase) ([]byte, error) {
|
|||||||
if err := setPurchaseExportHeaders(file, purchaseExportSheetName); err != nil {
|
if err := setPurchaseExportHeaders(file, purchaseExportSheetName); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := setPurchaseExportRows(file, purchaseExportSheetName, listItems, grandTotals); err != nil {
|
if err := setPurchaseExportRows(file, purchaseExportSheetName, purchases, grandTotals); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := file.SetPanes(purchaseExportSheetName, &excelize.Panes{
|
if err := file.SetPanes(purchaseExportSheetName, &excelize.Panes{
|
||||||
@@ -81,10 +78,11 @@ func setPurchaseExportColumns(file *excelize.File, sheet string) error {
|
|||||||
"D": 14,
|
"D": 14,
|
||||||
"E": 22,
|
"E": 22,
|
||||||
"F": 22,
|
"F": 22,
|
||||||
"G": 18,
|
"G": 22,
|
||||||
"H": 18,
|
"H": 32,
|
||||||
"I": 52,
|
"I": 18,
|
||||||
"J": 24,
|
"J": 18,
|
||||||
|
"K": 24,
|
||||||
}
|
}
|
||||||
|
|
||||||
for col, width := range columnWidths {
|
for col, width := range columnWidths {
|
||||||
@@ -107,9 +105,10 @@ func setPurchaseExportHeaders(file *excelize.File, sheet string) error {
|
|||||||
"Tanggal Terima",
|
"Tanggal Terima",
|
||||||
"Supplier",
|
"Supplier",
|
||||||
"Lokasi",
|
"Lokasi",
|
||||||
|
"Gudang",
|
||||||
|
"Product",
|
||||||
"Status",
|
"Status",
|
||||||
"Grand Total",
|
"Grand Total",
|
||||||
"Products",
|
|
||||||
"Notes",
|
"Notes",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,49 +137,34 @@ func setPurchaseExportHeaders(file *excelize.File, sheet string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.SetCellStyle(sheet, "A1", "J1", headerStyle)
|
return file.SetCellStyle(sheet, "A1", "K1", headerStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPurchaseExportRows(file *excelize.File, sheet string, items []dto.PurchaseListDTO, grandTotals map[uint]float64) error {
|
func setPurchaseExportRows(file *excelize.File, sheet string, purchases []entity.Purchase, grandTotals map[uint]float64) error {
|
||||||
if len(items) == 0 {
|
if len(purchases) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, item := range items {
|
rowIdx := 2
|
||||||
row := strconv.Itoa(i + 2)
|
for p := range purchases {
|
||||||
if err := file.SetCellValue(sheet, "A"+row, safePurchaseExportText(item.PrNumber)); err != nil {
|
purchase := &purchases[p]
|
||||||
return err
|
total := grandTotals[purchase.Id]
|
||||||
|
if len(purchase.Items) == 0 {
|
||||||
|
if err := writePurchaseExportRow(file, sheet, rowIdx, purchase, nil, total); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rowIdx++
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if err := file.SetCellValue(sheet, "B"+row, safePurchaseExportPointerText(item.PoNumber)); err != nil {
|
for it := range purchase.Items {
|
||||||
return err
|
if err := writePurchaseExportRow(file, sheet, rowIdx, purchase, &purchase.Items[it], total); err != nil {
|
||||||
}
|
return err
|
||||||
if err := file.SetCellValue(sheet, "C"+row, formatPurchaseExportDate(item.PoDate)); err != nil {
|
}
|
||||||
return err
|
rowIdx++
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "D"+row, formatPurchaseExportDate(item.ReceivedDate)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "E"+row, safePurchaseSupplierName(item)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "F"+row, safePurchaseLocationName(item)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "G"+row, formatPurchaseExportStatus(item)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "H"+row, formatPurchaseRupiah(grandTotals[item.Id])); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "I"+row, formatPurchaseProducts(item)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := file.SetCellValue(sheet, "J"+row, safePurchaseExportPointerText(item.Notes)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastRow := len(items) + 1
|
lastRow := rowIdx - 1
|
||||||
dataStyle, err := file.NewStyle(&excelize.Style{
|
dataStyle, err := file.NewStyle(&excelize.Style{
|
||||||
Alignment: &excelize.Alignment{
|
Alignment: &excelize.Alignment{
|
||||||
Horizontal: "left",
|
Horizontal: "left",
|
||||||
@@ -197,7 +181,7 @@ func setPurchaseExportRows(file *excelize.File, sheet string, items []dto.Purcha
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := file.SetCellStyle(sheet, "A2", "J"+strconv.Itoa(lastRow), dataStyle); err != nil {
|
if err := file.SetCellStyle(sheet, "A2", "K"+strconv.Itoa(lastRow), dataStyle); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +201,59 @@ func setPurchaseExportRows(file *excelize.File, sheet string, items []dto.Purcha
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.SetCellStyle(sheet, "H2", "H"+strconv.Itoa(lastRow), moneyStyle)
|
return file.SetCellStyle(sheet, "J2", "J"+strconv.Itoa(lastRow), moneyStyle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writePurchaseExportRow(file *excelize.File, sheet string, rowIdx int, purchase *entity.Purchase, item *entity.PurchaseItem, grandTotal float64) error {
|
||||||
|
row := strconv.Itoa(rowIdx)
|
||||||
|
|
||||||
|
// Purchase-level columns (repeat across rows of the same purchase)
|
||||||
|
if err := file.SetCellValue(sheet, "A"+row, safePurchaseExportText(purchase.PrNumber)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "B"+row, safePurchaseExportPointerText(purchase.PoNumber)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "C"+row, formatPurchaseExportDate(purchase.PoDate)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "E"+row, safePurchaseExportEntitySupplierName(purchase)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "I"+row, formatPurchaseExportEntityStatus(purchase)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "J"+row, formatPurchaseRupiah(grandTotal)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "K"+row, safePurchaseExportPointerText(purchase.Notes)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item-level columns
|
||||||
|
if item == nil {
|
||||||
|
for _, col := range []string{"D", "F", "G", "H"} {
|
||||||
|
if err := file.SetCellValue(sheet, col+row, "-"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := file.SetCellValue(sheet, "D"+row, formatPurchaseExportDate(item.ReceivedDate)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "F"+row, safePurchaseItemLocationName(item)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "G"+row, safePurchaseWarehouseName(item)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := file.SetCellValue(sheet, "H"+row, safePurchaseItemProductName(item)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildPurchaseGrandTotalMap(items []entity.Purchase) map[uint]float64 {
|
func buildPurchaseGrandTotalMap(items []entity.Purchase) map[uint]float64 {
|
||||||
@@ -232,31 +268,45 @@ func buildPurchaseGrandTotalMap(items []entity.Purchase) map[uint]float64 {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func safePurchaseSupplierName(item dto.PurchaseListDTO) string {
|
func safePurchaseExportEntitySupplierName(purchase *entity.Purchase) string {
|
||||||
if item.Supplier == nil {
|
if purchase.Supplier.Id == 0 {
|
||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
return safePurchaseExportText(item.Supplier.Name)
|
return safePurchaseExportText(purchase.Supplier.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func safePurchaseLocationName(item dto.PurchaseListDTO) string {
|
func safePurchaseWarehouseName(item *entity.PurchaseItem) string {
|
||||||
if item.Location == nil {
|
if item.Warehouse == nil {
|
||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
return safePurchaseExportText(item.Location.Name)
|
return safePurchaseExportText(item.Warehouse.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatPurchaseExportStatus(item dto.PurchaseListDTO) string {
|
func safePurchaseItemLocationName(item *entity.PurchaseItem) string {
|
||||||
if item.LatestApproval == nil {
|
if item.Warehouse == nil || item.Warehouse.Location == nil {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
return safePurchaseExportText(item.Warehouse.Location.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func safePurchaseItemProductName(item *entity.PurchaseItem) string {
|
||||||
|
if item.Product == nil {
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
|
return safePurchaseExportText(item.Product.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatPurchaseExportEntityStatus(purchase *entity.Purchase) string {
|
||||||
|
if purchase.LatestApproval == nil {
|
||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.LatestApproval.Action != nil &&
|
if purchase.LatestApproval.Action != nil &&
|
||||||
strings.EqualFold(strings.TrimSpace(*item.LatestApproval.Action), string(entity.ApprovalActionRejected)) {
|
strings.EqualFold(strings.TrimSpace(string(*purchase.LatestApproval.Action)), string(entity.ApprovalActionRejected)) {
|
||||||
return "Ditolak"
|
return "Ditolak"
|
||||||
}
|
}
|
||||||
|
|
||||||
return safePurchaseExportText(item.LatestApproval.StepName)
|
return safePurchaseExportText(purchase.LatestApproval.StepName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatPurchaseExportDate(value *time.Time) string {
|
func formatPurchaseExportDate(value *time.Time) string {
|
||||||
@@ -273,33 +323,6 @@ func formatPurchaseExportDate(value *time.Time) string {
|
|||||||
return t.Format("02-01-2006")
|
return t.Format("02-01-2006")
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatPurchaseProducts(item dto.PurchaseListDTO) string {
|
|
||||||
if len(item.Products) == 0 {
|
|
||||||
return "-"
|
|
||||||
}
|
|
||||||
|
|
||||||
seen := make(map[string]struct{})
|
|
||||||
names := make([]string, 0, len(item.Products))
|
|
||||||
for i := range item.Products {
|
|
||||||
name := strings.TrimSpace(item.Products[i].Name)
|
|
||||||
if name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, exists := seen[name]; exists {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seen[name] = struct{}{}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(names) == 0 {
|
|
||||||
return "-"
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(names)
|
|
||||||
return strings.Join(names, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func safePurchaseExportPointerText(value *string) string {
|
func safePurchaseExportPointerText(value *string) string {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return "-"
|
return "-"
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type PurchaseListDTO struct {
|
|||||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user"`
|
CreatedUser *userDTO.UserRelationDTO `json:"created_user"`
|
||||||
RequesterName string `json:"requester_name"`
|
RequesterName string `json:"requester_name"`
|
||||||
PoExpedition []PoExpeditionDTO `json:"po_expedition"`
|
PoExpedition []PoExpeditionDTO `json:"po_expedition"`
|
||||||
|
Items []PurchaseItemDTO `json:"items"`
|
||||||
Products []productDTO.ProductRelationDTO `json:"products"`
|
Products []productDTO.ProductRelationDTO `json:"products"`
|
||||||
Location *locationDTO.LocationRelationDTO `json:"location"`
|
Location *locationDTO.LocationRelationDTO `json:"location"`
|
||||||
Area *areaDTO.AreaRelationDTO `json:"area"`
|
Area *areaDTO.AreaRelationDTO `json:"area"`
|
||||||
@@ -227,6 +228,7 @@ func ToPurchaseListDTO(p entity.Purchase) PurchaseListDTO {
|
|||||||
CreatedUser: createdUser,
|
CreatedUser: createdUser,
|
||||||
RequesterName: requesterName,
|
RequesterName: requesterName,
|
||||||
PoExpedition: poExpedition,
|
PoExpedition: poExpedition,
|
||||||
|
Items: ToPurchaseItemDTOs(p.Items),
|
||||||
Products: products,
|
Products: products,
|
||||||
Location: location,
|
Location: location,
|
||||||
Area: area,
|
Area: area,
|
||||||
|
|||||||
Reference in New Issue
Block a user