mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'feat/export-recording-a' into 'development'
[FEAT][BE]: add feed use at export excel recording See merge request mbugroup/lti-api!511
This commit is contained in:
@@ -77,6 +77,10 @@ func setRecordingExportColumns(file *excelize.File, sheet string) error {
|
|||||||
"Z": 22,
|
"Z": 22,
|
||||||
"AA": 16,
|
"AA": 16,
|
||||||
"AB": 18,
|
"AB": 18,
|
||||||
|
"AC": 24,
|
||||||
|
"AD": 18,
|
||||||
|
"AE": 18,
|
||||||
|
"AF": 18,
|
||||||
}
|
}
|
||||||
|
|
||||||
for col, width := range columnWidths {
|
for col, width := range columnWidths {
|
||||||
@@ -96,7 +100,7 @@ func setRecordingExportColumns(file *excelize.File, sheet string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setRecordingExportHeaders(file *excelize.File, sheet string) error {
|
func setRecordingExportHeaders(file *excelize.File, sheet string) error {
|
||||||
verticalHeaderCols := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "Y", "Z", "AA", "AB"}
|
verticalHeaderCols := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF"}
|
||||||
for _, col := range verticalHeaderCols {
|
for _, col := range verticalHeaderCols {
|
||||||
if err := file.MergeCell(sheet, col+"1", col+"2"); err != nil {
|
if err := file.MergeCell(sheet, col+"1", col+"2"); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -117,6 +121,10 @@ func setRecordingExportHeaders(file *excelize.File, sheet string) error {
|
|||||||
"Z1": "Catatan Approval",
|
"Z1": "Catatan Approval",
|
||||||
"AA1": "Dibuat Oleh",
|
"AA1": "Dibuat Oleh",
|
||||||
"AB1": "Tanggal Submit",
|
"AB1": "Tanggal Submit",
|
||||||
|
"AC1": "Nama Pakan",
|
||||||
|
"AD1": "Jumlah Input Pakan",
|
||||||
|
"AE1": "Jumlah Penggunaan",
|
||||||
|
"AF1": "Pending Qty",
|
||||||
}
|
}
|
||||||
for cell, value := range headerValues {
|
for cell, value := range headerValues {
|
||||||
if err := file.SetCellValue(sheet, cell, value); err != nil {
|
if err := file.SetCellValue(sheet, cell, value); err != nil {
|
||||||
@@ -230,7 +238,7 @@ func setRecordingExportHeaders(file *excelize.File, sheet string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.SetCellStyle(sheet, "A1", "AB2", headerStyle)
|
return file.SetCellStyle(sheet, "A1", "AF2", headerStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setRecordingExportRows(file *excelize.File, sheet string, items []dto.RecordingListDTO) error {
|
func setRecordingExportRows(file *excelize.File, sheet string, items []dto.RecordingListDTO) error {
|
||||||
@@ -241,6 +249,7 @@ func setRecordingExportRows(file *excelize.File, sheet string, items []dto.Recor
|
|||||||
columns := []string{
|
columns := []string{
|
||||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
|
||||||
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB",
|
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB",
|
||||||
|
"AC", "AD", "AE", "AF",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, item := range items {
|
for i, item := range items {
|
||||||
@@ -283,6 +292,29 @@ func setRecordingExportRows(file *excelize.File, sheet string, items []dto.Recor
|
|||||||
createdBy = safeExportText(item.Approval.ActionBy.Name)
|
createdBy = safeExportText(item.Approval.ActionBy.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build feed usage columns — concatenate multiple feeds with newline
|
||||||
|
feedNames := make([]string, 0, len(item.FeedUsage))
|
||||||
|
usageAmounts := make([]string, 0, len(item.FeedUsage))
|
||||||
|
pendingQtys := make([]string, 0, len(item.FeedUsage))
|
||||||
|
inputQtys := make([]string, 0, len(item.FeedUsage))
|
||||||
|
for _, fu := range item.FeedUsage {
|
||||||
|
feedNames = append(feedNames, safeExportText(fu.ProductName))
|
||||||
|
usageAmounts = append(usageAmounts, formatNumberID(fu.UsageAmount, 2, true))
|
||||||
|
pendingQtys = append(pendingQtys, formatNumberID(fu.PendingQty, 2, true))
|
||||||
|
inputQtys = append(inputQtys, formatNumberID(fu.UsageAmount+fu.PendingQty, 2, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
feedNameCol := "-"
|
||||||
|
usageCol := "-"
|
||||||
|
pendingCol := "-"
|
||||||
|
inputCol := "-"
|
||||||
|
if len(feedNames) > 0 {
|
||||||
|
feedNameCol = strings.Join(feedNames, "\n")
|
||||||
|
usageCol = strings.Join(usageAmounts, "\n")
|
||||||
|
pendingCol = strings.Join(pendingQtys, "\n")
|
||||||
|
inputCol = strings.Join(inputQtys, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
rowValues := []interface{}{
|
rowValues := []interface{}{
|
||||||
i + 1,
|
i + 1,
|
||||||
locationName,
|
locationName,
|
||||||
@@ -312,6 +344,10 @@ func setRecordingExportRows(file *excelize.File, sheet string, items []dto.Recor
|
|||||||
safeExportText(pointerString(item.Approval.Notes)),
|
safeExportText(pointerString(item.Approval.Notes)),
|
||||||
createdBy,
|
createdBy,
|
||||||
formatDateIndonesian(item.CreatedAt),
|
formatDateIndonesian(item.CreatedAt),
|
||||||
|
feedNameCol, // AC
|
||||||
|
inputCol, // AD - Jumlah Input Pakan
|
||||||
|
usageCol, // AE - Jumlah Penggunaan
|
||||||
|
pendingCol, // AF - Pending Qty
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx, col := range columns {
|
for idx, col := range columns {
|
||||||
@@ -339,7 +375,7 @@ func setRecordingExportRows(file *excelize.File, sheet string, items []dto.Recor
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := file.SetCellStyle(sheet, "A3", fmt.Sprintf("AB%d", lastRow), dataCenterStyle); err != nil {
|
if err := file.SetCellStyle(sheet, "A3", fmt.Sprintf("AF%d", lastRow), dataCenterStyle); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +396,7 @@ func setRecordingExportRows(file *excelize.File, sheet string, items []dto.Recor
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
leftColumns := []string{"B", "C", "D", "F", "G", "H", "Y", "Z", "AA", "AB"}
|
leftColumns := []string{"B", "C", "D", "F", "G", "H", "Y", "Z", "AA", "AB", "AC"}
|
||||||
for _, col := range leftColumns {
|
for _, col := range leftColumns {
|
||||||
if err := file.SetCellStyle(sheet, col+"3", fmt.Sprintf("%s%d", col, lastRow), dataLeftStyle); err != nil {
|
if err := file.SetCellStyle(sheet, col+"3", fmt.Sprintf("%s%d", col, lastRow), dataLeftStyle); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -92,6 +92,12 @@ type RecordingRelationDTO struct {
|
|||||||
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RecordingFeedUsageDTO struct {
|
||||||
|
ProductName string `json:"product_name"`
|
||||||
|
UsageAmount float64 `json:"usage_amount"`
|
||||||
|
PendingQty float64 `json:"pending_qty"`
|
||||||
|
}
|
||||||
|
|
||||||
type RecordingListDTO struct {
|
type RecordingListDTO struct {
|
||||||
RecordingRelationDTO
|
RecordingRelationDTO
|
||||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||||
@@ -99,6 +105,7 @@ type RecordingListDTO struct {
|
|||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
Kandang *RecordingKandangDTO `json:"kandang,omitempty"`
|
Kandang *RecordingKandangDTO `json:"kandang,omitempty"`
|
||||||
Location *RecordingLocationDTO `json:"location,omitempty"`
|
Location *RecordingLocationDTO `json:"location,omitempty"`
|
||||||
|
FeedUsage []RecordingFeedUsageDTO `json:"feed_usage,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordingDetailDTO struct {
|
type RecordingDetailDTO struct {
|
||||||
@@ -192,6 +199,36 @@ func ToRecordingStockDTOs(stocks []entity.RecordingStock) []RecordingStockDTO {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToRecordingFeedUsageDTOs(stocks []entity.RecordingStock) []RecordingFeedUsageDTO {
|
||||||
|
return toRecordingFeedUsageDTOs(stocks)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toRecordingFeedUsageDTOs(stocks []entity.RecordingStock) []RecordingFeedUsageDTO {
|
||||||
|
result := make([]RecordingFeedUsageDTO, 0, len(stocks))
|
||||||
|
for _, s := range stocks {
|
||||||
|
productName := ""
|
||||||
|
if s.ProductWarehouse.Product.Id != 0 {
|
||||||
|
productName = s.ProductWarehouse.Product.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
var usageAmount float64
|
||||||
|
if s.UsageQty != nil {
|
||||||
|
usageAmount = *s.UsageQty
|
||||||
|
}
|
||||||
|
var pendingQty float64
|
||||||
|
if s.PendingQty != nil {
|
||||||
|
pendingQty = *s.PendingQty
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, RecordingFeedUsageDTO{
|
||||||
|
ProductName: productName,
|
||||||
|
UsageAmount: usageAmount,
|
||||||
|
PendingQty: pendingQty,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func ToRecordingEggDTOs(eggs []entity.RecordingEgg) []RecordingEggDTO {
|
func ToRecordingEggDTOs(eggs []entity.RecordingEgg) []RecordingEggDTO {
|
||||||
result := make([]RecordingEggDTO, len(eggs))
|
result := make([]RecordingEggDTO, len(eggs))
|
||||||
for i, egg := range eggs {
|
for i, egg := range eggs {
|
||||||
@@ -222,6 +259,7 @@ func toRecordingListDTO(e entity.Recording) RecordingListDTO {
|
|||||||
CreatedUser: createdUser,
|
CreatedUser: createdUser,
|
||||||
Kandang: recordingKandangDTO(e),
|
Kandang: recordingKandangDTO(e),
|
||||||
Location: recordingKandangLocationDTO(e),
|
Location: recordingKandangLocationDTO(e),
|
||||||
|
FeedUsage: toRecordingFeedUsageDTOs(e.Stocks),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,10 @@ func (r *RecordingRepositoryImpl) WithRelationsList(db *gorm.DB) *gorm.DB {
|
|||||||
Preload("ProjectFlockKandang.Kandang").
|
Preload("ProjectFlockKandang.Kandang").
|
||||||
Preload("ProjectFlockKandang.Kandang.Location").
|
Preload("ProjectFlockKandang.Kandang.Location").
|
||||||
Preload("ProjectFlockKandang.ProjectFlock").
|
Preload("ProjectFlockKandang.ProjectFlock").
|
||||||
Preload("ProjectFlockKandang.ProjectFlock.ProductionStandard")
|
Preload("ProjectFlockKandang.ProjectFlock.ProductionStandard").
|
||||||
|
Preload("Stocks").
|
||||||
|
Preload("Stocks.ProductWarehouse").
|
||||||
|
Preload("Stocks.ProductWarehouse.Product")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RecordingRepositoryImpl) latestApprovalSubQuery(db *gorm.DB) *gorm.DB {
|
func (r *RecordingRepositoryImpl) latestApprovalSubQuery(db *gorm.DB) *gorm.DB {
|
||||||
|
|||||||
Reference in New Issue
Block a user