Merge branch 'jsooi/imported-files-validation' into tmtan/simplify-ui

This commit is contained in:
ThaiMing3 2024-01-11 09:59:56 +08:00
commit dcaf8a9ec7
2 changed files with 78 additions and 0 deletions

View file

@ -41,6 +41,12 @@ func (s *IOSheet) indexHeaders() {
} }
} }
// Ooi J Sen
// function to return headers from excel sheet
func (s *IOSheet) GetHeaders() []string {
return s.headers
}
func (s *IOSheet) GetColumn(str string) (col int, ok bool) { func (s *IOSheet) GetColumn(str string) (col int, ok bool) {
if s.index == nil { if s.index == nil {
s.indexHeaders() s.indexHeaders()

View file

@ -89,6 +89,36 @@ func serializeLocation[T ~[]string](location T) string {
return strings.Join(location, "/") return strings.Join(location, "/")
} }
// Ooi J Sen
// Function to validate headers
func validateHeaders(expected, actual []string) bool {
actualHeaderCount := make(map[string]int)
// Count occurrences of headers in the actual slice
for _, header := range actual {
actualHeaderCount[header]++
}
// Check if all actual headers are within the expected headers
for header, count := range actualHeaderCount {
if count > 0 && !contains(expected, header) {
return false
}
}
return true
}
// Function to check if a string slice contains a specific string
func contains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
// CsvImport imports items from a CSV file. using the standard defined format. // CsvImport imports items from a CSV file. using the standard defined format.
// //
// CsvImport applies the following rules/operations // CsvImport applies the following rules/operations
@ -103,6 +133,16 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
if err != nil { if err != nil {
return 0, err return 0, err
} }
// Ooi J Sen
// Access excel sheet headers
headers := sheet.GetHeaders()
// Validate column headers
expectedHeaders := []string{"HB.import_ref", "HB.location", "HB.labels", "HB.asset_id", "HB.archived", "HB.name", "HB.quantity", "HB.description", "HB.insured", "HB.notes", "HB.purchase_price", "HB.purchase_from", "HB.purchase_time", "HB.manufacturer", "HB.model_number", "HB.serial_number", "HB.lifetime_warranty", "HB.warranty_expires", "HB.warranty_details", "HB.sold_to", "HB.sold_price", "HB.sold_time", "HB.sold_notes",}
if !validateHeaders(expectedHeaders, headers) {
return 0, fmt.Errorf("CSV columns do not match the expected format")
}
// ======================================== // ========================================
// Labels // Labels
@ -161,8 +201,12 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
finished := 0 finished := 0
var errorMessage string
for i := range sheet.Rows { for i := range sheet.Rows {
row := sheet.Rows[i] row := sheet.Rows[i]
var hasNegativeValues bool
createRequired := true createRequired := true
@ -178,6 +222,25 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
createRequired = false createRequired = false
} }
} }
// Ooi J Sen
// Check integer fields for negative values
if row.Quantity < 0 {
errorMessage += fmt.Sprintf("Negative quantity at row %d\n", i+1)
hasNegativeValues = true
}
if row.PurchasePrice < 0 {
errorMessage += fmt.Sprintf("Negative purchase price at row %d\n", i+1)
hasNegativeValues = true
}
if row.SoldPrice < 0 {
errorMessage += fmt.Sprintf("Negative sold price at row %d\n", i+1)
hasNegativeValues = true
}
if (hasNegativeValues) {
continue
}
// ======================================== // ========================================
// Pre-Create Labels as necessary // Pre-Create Labels as necessary
@ -326,6 +389,15 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
finished++ finished++
} }
// Ooi J Sen
// Display error messages in console
if errorMessage != "" {
// Log or handle the error message here
fmt.Println("Error Messages:")
fmt.Println(errorMessage)
return 0, fmt.Errorf("Errors detected in CSV:\n%s", errorMessage)
}
return finished, nil return finished, nil
} }