mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-06-09 15:07:49 +00:00
fix: use soDate instead of deliveryDate for Delivery Order rows in marketing export
In the Excel export, Delivery Order rows were writing `group.DeliveryDate`
(the actual delivery date) to column B ("Tanggal"), while the web UI always
shows `so_date` for every row. This caused a visible mismatch — e.g. DO-01954
displayed "31 Mei 2026" on the web but "01-06-2026" in the exported file.
Changes:
- Remove the `doDate` variable from the DO branch; both the empty-deliveries
fallback row and each per-delivery row now write `soDate` to column B,
consistent with what the web shows
- Fix a pre-existing nil pointer dereference: `prod.ProductWarehouse.Warehouse`
was accessed without a nil guard in the SO branch
- Update the export test to match the current 17-column layout (headers and
row assertions were stale), and add a regression case that explicitly
asserts a DO row with soDate=2026-05-31 / deliveryDate=2026-06-01 produces
"31-05-2026" in column B
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -201,11 +201,6 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
|
|||||||
for _, group := range item.DeliveryOrder {
|
for _, group := range item.DeliveryOrder {
|
||||||
doNumber := safeMarketingExportText(group.DoNumber)
|
doNumber := safeMarketingExportText(group.DoNumber)
|
||||||
|
|
||||||
doDate := "-"
|
|
||||||
if group.DeliveryDate != nil {
|
|
||||||
doDate = formatMarketingExportDate(*group.DeliveryDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
gudang := "-"
|
gudang := "-"
|
||||||
if group.Warehouse != nil {
|
if group.Warehouse != nil {
|
||||||
gudang = safeMarketingExportText(group.Warehouse.Name)
|
gudang = safeMarketingExportText(group.Warehouse.Name)
|
||||||
@@ -215,7 +210,7 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
|
|||||||
row++
|
row++
|
||||||
r := strconv.Itoa(row)
|
r := strconv.Itoa(row)
|
||||||
vals := map[string]interface{}{
|
vals := map[string]interface{}{
|
||||||
"A": doNumber, "B": doDate, "C": status, "D": customer, "E": salesPerson,
|
"A": doNumber, "B": soDate, "C": status, "D": customer, "E": salesPerson,
|
||||||
"F": "-", "G": "-", "H": gudang, "I": "-", "J": "-", "K": "-",
|
"F": "-", "G": "-", "H": gudang, "I": "-", "J": "-", "K": "-",
|
||||||
"L": "-", "M": "-", "N": "-", "O": "-",
|
"L": "-", "M": "-", "N": "-", "O": "-",
|
||||||
"P": grandTotal, "Q": notes,
|
"P": grandTotal, "Q": notes,
|
||||||
@@ -251,7 +246,7 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
|
|||||||
if err := file.SetCellValue(sheet, "A"+r, doNumber); err != nil {
|
if err := file.SetCellValue(sheet, "A"+r, doNumber); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := file.SetCellValue(sheet, "B"+r, doDate); err != nil {
|
if err := file.SetCellValue(sheet, "B"+r, soDate); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := file.SetCellValue(sheet, "C"+r, status); err != nil {
|
if err := file.SetCellValue(sheet, "C"+r, status); err != nil {
|
||||||
@@ -347,7 +342,7 @@ func setMarketingExportRows(file *excelize.File, sheet string, items []dto.Marke
|
|||||||
}
|
}
|
||||||
|
|
||||||
gudang := "-"
|
gudang := "-"
|
||||||
if prod.ProductWarehouse != nil {
|
if prod.ProductWarehouse != nil && prod.ProductWarehouse.Warehouse != nil {
|
||||||
gudang = safeMarketingExportText(prod.ProductWarehouse.Warehouse.Name)
|
gudang = safeMarketingExportText(prod.ProductWarehouse.Warehouse.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestBuildMarketingExportWorkbookHeadersAndRows(t *testing.T) {
|
func TestBuildMarketingExportWorkbookHeadersAndRows(t *testing.T) {
|
||||||
|
// DO item has soDate=2026-05-31 and deliveryDate=2026-06-01 to verify
|
||||||
|
// the export uses soDate (not deliveryDate) in column B.
|
||||||
|
deliveryDate := time.Date(2026, time.June, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
|
||||||
items := []dto.MarketingListDTO{
|
items := []dto.MarketingListDTO{
|
||||||
{
|
{
|
||||||
MarketingRelationDTO: dto.MarketingRelationDTO{
|
MarketingRelationDTO: dto.MarketingRelationDTO{
|
||||||
@@ -51,6 +55,22 @@ func TestBuildMarketingExportWorkbookHeadersAndRows(t *testing.T) {
|
|||||||
Action: strPtr("REJECTED"),
|
Action: strPtr("REJECTED"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MarketingRelationDTO: dto.MarketingRelationDTO{
|
||||||
|
SoNumber: "SO-00760",
|
||||||
|
SoDate: time.Date(2026, time.May, 31, 0, 0, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
Customer: customerDTO.CustomerRelationDTO{Name: "CORDELA"},
|
||||||
|
DeliveryOrder: []dto.DeliveryGroupDTO{
|
||||||
|
{
|
||||||
|
DoNumber: "DO-01954",
|
||||||
|
DeliveryDate: &deliveryDate,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
LatestApproval: approvalDTO.ApprovalRelationDTO{
|
||||||
|
StepName: "Delivery Order",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := buildMarketingExportWorkbook(items)
|
content, err := buildMarketingExportWorkbook(items)
|
||||||
@@ -69,9 +89,10 @@ func TestBuildMarketingExportWorkbookHeadersAndRows(t *testing.T) {
|
|||||||
"B1": "Tanggal",
|
"B1": "Tanggal",
|
||||||
"C1": "Status",
|
"C1": "Status",
|
||||||
"D1": "Customer",
|
"D1": "Customer",
|
||||||
"E1": "Grand Total",
|
"E1": "Sales",
|
||||||
"F1": "Products",
|
"G1": "Nama Produk",
|
||||||
"G1": "Notes",
|
"P1": "Grand Total",
|
||||||
|
"Q1": "Catatan",
|
||||||
}
|
}
|
||||||
for cell, expected := range expectedHeaders {
|
for cell, expected := range expectedHeaders {
|
||||||
got, err := file.GetCellValue(marketingExportSheetName, cell)
|
got, err := file.GetCellValue(marketingExportSheetName, cell)
|
||||||
@@ -83,19 +104,25 @@ func TestBuildMarketingExportWorkbookHeadersAndRows(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SO-00762: 3 products → rows 2, 3, 4
|
||||||
assertCellEquals(t, file, "A2", "SO-00762")
|
assertCellEquals(t, file, "A2", "SO-00762")
|
||||||
assertCellEquals(t, file, "B2", "22-04-2026")
|
assertCellEquals(t, file, "B2", "22-04-2026")
|
||||||
assertCellEquals(t, file, "C2", "Pengajuan")
|
assertCellEquals(t, file, "C2", "Pengajuan")
|
||||||
assertCellEquals(t, file, "D2", "AJAT")
|
assertCellEquals(t, file, "D2", "AJAT")
|
||||||
assertCellEquals(t, file, "E2", "Rp 5.206.200.000")
|
assertCellEquals(t, file, "G2", "PAKAN GROWING CRUMBLE 8603 MALINDO")
|
||||||
assertCellEquals(t, file, "F2", "PAKAN GROWING CRUMBLE 8603 MALINDO, 295 GOLD PELLET")
|
assertCellEquals(t, file, "Q2", "tes")
|
||||||
assertCellEquals(t, file, "G2", "tes")
|
|
||||||
|
|
||||||
assertCellEquals(t, file, "A3", "SO-00761")
|
// SO-00761 (rejected): 1 product → row 5
|
||||||
assertCellEquals(t, file, "C3", "Ditolak")
|
assertCellEquals(t, file, "A5", "SO-00761")
|
||||||
assertCellEquals(t, file, "E3", "Rp 75.000")
|
assertCellEquals(t, file, "C5", "Ditolak")
|
||||||
assertCellEquals(t, file, "F3", "HS30 FOAM @20 LITER")
|
assertCellEquals(t, file, "G5", "HS30 FOAM @20 LITER")
|
||||||
assertCellEquals(t, file, "G3", "-")
|
assertCellEquals(t, file, "Q5", "-")
|
||||||
|
|
||||||
|
// DO-01954: column B must use soDate (31-05-2026), not deliveryDate (01-06-2026)
|
||||||
|
assertCellEquals(t, file, "A6", "DO-01954")
|
||||||
|
assertCellEquals(t, file, "B6", "31-05-2026")
|
||||||
|
assertCellEquals(t, file, "C6", "Delivery Order")
|
||||||
|
assertCellEquals(t, file, "D6", "CORDELA")
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertCellEquals(t *testing.T, file *excelize.File, cell, expected string) {
|
func assertCellEquals(t *testing.T, file *excelize.File, cell, expected string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user