add filter warehouse to marketing;add detail export recording egg; adjust format export marketing

This commit is contained in:
giovanni
2026-05-31 16:23:22 +07:00
parent 09b1f19d19
commit bfef144668
9 changed files with 478 additions and 98 deletions
@@ -70,23 +70,26 @@ func buildMarketingExportWorkbook(items []dto.MarketingListDTO) ([]byte, error)
}
func setMarketingExportColumns(file *excelize.File, sheet string) error {
// AQ = 17 columns
// E = Sales (new), H = Gudang (new), Satuan (old I) removed
columnWidths := map[string]float64{
"A": 16,
"B": 14,
"C": 18,
"D": 20,
"E": 14,
"F": 40,
"G": 10,
"H": 12,
"I": 12,
"J": 12,
"K": 16,
"L": 16,
"M": 18,
"N": 18,
"O": 18,
"P": 24,
"A": 16, // No. Order
"B": 14, // Tanggal
"C": 18, // Status
"D": 20, // Customer
"E": 20, // Sales (new)
"F": 14, // Tipe
"G": 40, // Nama Produk
"H": 20, // Gudang (new)
"I": 10, // Week
"J": 12, // Jumlah
"K": 12, // Qty Peti
"L": 16, // Berat Rata-rata (kg)
"M": 16, // Total Berat (kg)
"N": 18, // Harga Satuan
"O": 18, // Total Harga
"P": 18, // Grand Total
"Q": 24, // Catatan
}
for col, width := range columnWidths {
@@ -104,22 +107,23 @@ func setMarketingExportColumns(file *excelize.File, sheet string) error {
func setMarketingExportHeaders(file *excelize.File, sheet string) error {
headers := []string{
"No. Order", // A
"Tanggal", // B
"Status", // C
"Customer", // D
"Tipe", // E
"Nama Produk", // F
"Week", // G
"Jumlah", // H
"Satuan", // I
"Qty Peti", // J
"Berat Rata-rata (kg)", // K
"Total Berat (kg)", // L
"Harga Satuan", // M
"Total Harga", // N
"Grand Total", // O
"Catatan", // P
"No. Order", // A
"Tanggal", // B
"Status", // C
"Customer", // D
"Sales", // E (new)
"Tipe", // F
"Nama Produk", // G
"Gudang", // H (new)
"Week", // I
"Jumlah Butir", // J
"Qty Peti", // K
"Berat Rata-rata (kg)", // L
"Total Berat (kg)", // M
"Harga Satuan", // N
"Total Harga", // O
"Grand Total", // P
"Catatan", // Q
}
for i, header := range headers {
@@ -148,7 +152,7 @@ func setMarketingExportHeaders(file *excelize.File, sheet string) error {
return err
}
return file.SetCellStyle(sheet, "A1", "P1", headerStyle)
return file.SetCellStyle(sheet, "A1", "Q1", headerStyle)
}
func setMarketingExportRows(file *excelize.File, sheet string, items []dto.MarketingListDTO) error {
@@ -162,17 +166,161 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
soDate := formatMarketingExportDate(item.SoDate)
status := formatMarketingExportStatus(item)
customer := safeMarketingExportText(item.Customer.Name)
grandTotal := sumMarketingGrandTotal(item.SalesOrder)
notes := safeMarketingExportText(item.Notes)
salesPerson := safeMarketingExportText(item.SalesPerson.Name)
isDeliveryOrder := strings.EqualFold(strings.TrimSpace(status), "delivery order")
// ── Delivery Order branch ──────────────────────────────────────────────
if isDeliveryOrder {
grandTotal := sumDeliveryGrandTotal(item.DeliveryOrder)
if len(item.DeliveryOrder) == 0 {
row++
r := strconv.Itoa(row)
vals := map[string]interface{}{
"A": soNumber, "B": soDate, "C": status, "D": customer, "E": salesPerson,
"F": "-", "G": "-", "H": "-", "I": "-", "J": "-", "K": "-",
"L": "-", "M": "-", "N": "-", "O": "-",
"P": grandTotal, "Q": notes,
}
for col, val := range vals {
if err := file.SetCellValue(sheet, col+r, val); err != nil {
return err
}
}
continue
}
// Build lookup map: MarketingProductId → SO product (for Week & MarketingType)
soProductMap := make(map[uint]*dto.DeliveryMarketingProductDTO, len(item.SalesOrder))
for i := range item.SalesOrder {
soProductMap[item.SalesOrder[i].Id] = &item.SalesOrder[i]
}
for _, group := range item.DeliveryOrder {
doNumber := safeMarketingExportText(group.DoNumber)
doDate := "-"
if group.DeliveryDate != nil {
doDate = formatMarketingExportDate(*group.DeliveryDate)
}
gudang := "-"
if group.Warehouse != nil {
gudang = safeMarketingExportText(group.Warehouse.Name)
}
if len(group.Deliveries) == 0 {
row++
r := strconv.Itoa(row)
vals := map[string]interface{}{
"A": doNumber, "B": doDate, "C": status, "D": customer, "E": salesPerson,
"F": "-", "G": "-", "H": gudang, "I": "-", "J": "-", "K": "-",
"L": "-", "M": "-", "N": "-", "O": "-",
"P": grandTotal, "Q": notes,
}
for col, val := range vals {
if err := file.SetCellValue(sheet, col+r, val); err != nil {
return err
}
}
continue
}
for _, delivery := range group.Deliveries {
row++
r := strconv.Itoa(row)
productName := "-"
if delivery.ProductWarehouse != nil && delivery.ProductWarehouse.Product != nil {
if n := strings.TrimSpace(delivery.ProductWarehouse.Product.Name); n != "" {
productName = n
}
}
week := "-"
marketingType := "-"
if soProduct, ok := soProductMap[delivery.MarketingProductId]; ok {
if soProduct.Week != nil {
week = strconv.Itoa(*soProduct.Week)
}
marketingType = safeMarketingExportText(soProduct.MarketingType)
}
if err := file.SetCellValue(sheet, "A"+r, doNumber); err != nil {
return err
}
if err := file.SetCellValue(sheet, "B"+r, doDate); err != nil {
return err
}
if err := file.SetCellValue(sheet, "C"+r, status); err != nil {
return err
}
if err := file.SetCellValue(sheet, "D"+r, customer); err != nil {
return err
}
if err := file.SetCellValue(sheet, "E"+r, salesPerson); err != nil {
return err
}
if err := file.SetCellValue(sheet, "F"+r, marketingType); err != nil {
return err
}
if err := file.SetCellValue(sheet, "G"+r, productName); err != nil {
return err
}
if err := file.SetCellValue(sheet, "H"+r, gudang); err != nil {
return err
}
if err := file.SetCellValue(sheet, "I"+r, week); err != nil {
return err
}
if err := file.SetCellValue(sheet, "J"+r, delivery.Qty); err != nil {
return err
}
if delivery.TotalPeti != nil {
if err := file.SetCellValue(sheet, "K"+r, *delivery.TotalPeti); err != nil {
return err
}
} else {
if err := file.SetCellValue(sheet, "K"+r, "-"); err != nil {
return err
}
}
if err := file.SetCellValue(sheet, "L"+r, delivery.AvgWeight); err != nil {
return err
}
if err := file.SetCellValue(sheet, "M"+r, delivery.TotalWeight); err != nil {
return err
}
if err := file.SetCellValue(sheet, "N"+r, delivery.UnitPrice); err != nil {
return err
}
if err := file.SetCellValue(sheet, "O"+r, delivery.TotalPrice); err != nil {
return err
}
if err := file.SetCellValue(sheet, "P"+r, grandTotal); err != nil {
return err
}
if err := file.SetCellValue(sheet, "Q"+r, notes); err != nil {
return err
}
}
}
continue
}
// ── Sales Order branch (all other statuses) ───────────────────────────
grandTotal := sumMarketingGrandTotal(item.SalesOrder)
if len(item.SalesOrder) == 0 {
row++
r := strconv.Itoa(row)
vals := map[string]interface{}{
"A": soNumber, "B": soDate, "C": status, "D": customer,
"E": "-", "F": "-", "G": "-", "H": "-", "I": "-", "J": "-",
"K": "-", "L": "-", "M": "-", "N": "-",
"O": grandTotal, "P": notes,
"A": soNumber, "B": soDate, "C": status, "D": customer, "E": salesPerson,
"F": "-", "G": "-", "H": "-", "I": "-", "J": "-", "K": "-",
"L": "-", "M": "-", "N": "-", "O": "-",
"P": grandTotal, "Q": notes,
}
for col, val := range vals {
if err := file.SetCellValue(sheet, col+r, val); err != nil {
@@ -198,9 +346,9 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
week = strconv.Itoa(*prod.Week)
}
satuan := "-"
if prod.ConvertionUnit != nil && strings.TrimSpace(*prod.ConvertionUnit) != "" {
satuan = *prod.ConvertionUnit
gudang := "-"
if prod.ProductWarehouse != nil {
gudang = safeMarketingExportText(prod.ProductWarehouse.Warehouse.Name)
}
if err := file.SetCellValue(sheet, "A"+r, soNumber); err != nil {
@@ -215,46 +363,49 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
if err := file.SetCellValue(sheet, "D"+r, customer); err != nil {
return err
}
if err := file.SetCellValue(sheet, "E"+r, safeMarketingExportText(prod.MarketingType)); err != nil {
if err := file.SetCellValue(sheet, "E"+r, salesPerson); err != nil {
return err
}
if err := file.SetCellValue(sheet, "F"+r, productName); err != nil {
if err := file.SetCellValue(sheet, "F"+r, safeMarketingExportText(prod.MarketingType)); err != nil {
return err
}
if err := file.SetCellValue(sheet, "G"+r, week); err != nil {
if err := file.SetCellValue(sheet, "G"+r, productName); err != nil {
return err
}
if err := file.SetCellValue(sheet, "H"+r, prod.Qty); err != nil {
if err := file.SetCellValue(sheet, "H"+r, gudang); err != nil {
return err
}
if err := file.SetCellValue(sheet, "I"+r, satuan); err != nil {
if err := file.SetCellValue(sheet, "I"+r, week); err != nil {
return err
}
if err := file.SetCellValue(sheet, "J"+r, prod.Qty); err != nil {
return err
}
if prod.TotalPeti != nil {
if err := file.SetCellValue(sheet, "J"+r, *prod.TotalPeti); err != nil {
if err := file.SetCellValue(sheet, "K"+r, *prod.TotalPeti); err != nil {
return err
}
} else {
if err := file.SetCellValue(sheet, "J"+r, "-"); err != nil {
if err := file.SetCellValue(sheet, "K"+r, "-"); err != nil {
return err
}
}
if err := file.SetCellValue(sheet, "K"+r, prod.AvgWeight); err != nil {
if err := file.SetCellValue(sheet, "L"+r, prod.AvgWeight); err != nil {
return err
}
if err := file.SetCellValue(sheet, "L"+r, prod.TotalWeight); err != nil {
if err := file.SetCellValue(sheet, "M"+r, prod.TotalWeight); err != nil {
return err
}
if err := file.SetCellValue(sheet, "M"+r, prod.UnitPrice); err != nil {
if err := file.SetCellValue(sheet, "N"+r, prod.UnitPrice); err != nil {
return err
}
if err := file.SetCellValue(sheet, "N"+r, prod.TotalPrice); err != nil {
if err := file.SetCellValue(sheet, "O"+r, prod.TotalPrice); err != nil {
return err
}
if err := file.SetCellValue(sheet, "O"+r, grandTotal); err != nil {
if err := file.SetCellValue(sheet, "P"+r, grandTotal); err != nil {
return err
}
if err := file.SetCellValue(sheet, "P"+r, notes); err != nil {
if err := file.SetCellValue(sheet, "Q"+r, notes); err != nil {
return err
}
}
@@ -276,7 +427,7 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
if err != nil {
return err
}
if err := file.SetCellStyle(sheet, "A2", "P"+lastRowStr, dataStyle); err != nil {
if err := file.SetCellStyle(sheet, "A2", "Q"+lastRowStr, dataStyle); err != nil {
return err
}
@@ -287,7 +438,7 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
if err != nil {
return err
}
if err := file.SetCellStyle(sheet, "K2", "O"+lastRowStr, numberStyle); err != nil {
if err := file.SetCellStyle(sheet, "L2", "P"+lastRowStr, numberStyle); err != nil {
return err
}
@@ -298,7 +449,7 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
if err != nil {
return err
}
for _, col := range []string{"G", "H", "J"} {
for _, col := range []string{"I", "J", "K"} {
if err := file.SetCellStyle(sheet, col+"2", col+lastRowStr, centerStyle); err != nil {
return err
}
@@ -327,16 +478,23 @@ func formatMarketingExportStatus(item dto.MarketingListDTO) string {
return safeMarketingExportText(item.LatestApproval.StepName)
}
func sumMarketingGrandTotal(items []dto.DeliveryMarketingProductDTO) float64 {
total := 0.0
for _, item := range items {
total += item.TotalPrice
}
return total
}
func sumDeliveryGrandTotal(groups []dto.DeliveryGroupDTO) float64 {
total := 0.0
for _, g := range groups {
for _, d := range g.Deliveries {
total += d.TotalPrice
}
}
return total
}
func safeMarketingExportText(value string) string {
trimmed := strings.TrimSpace(value)