Загадочная логическая ошибка в Java-программе многоячеечного комбинированного анализа файлов CSVJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Загадочная логическая ошибка в Java-программе многоячеечного комбинированного анализа файлов CSV

Сообщение Anonymous »

Короче, у меня есть ошибка в Java-программе, которую компания надеялась использовать для отслеживания бонусных (бесплатных) продуктов, которые она предоставляет клиентам (компания является дистрибьютором детских товаров, и они продают в аптеки через склады). Проблема в том, что склады иногда продают товары с дополнительными бонусами, которых нет в официальном списке кампаний за этот месяц, и поэтому, когда они отправляют нам обратно данные о своих продажах, компания должна это отслеживать и информировать их о сокращениях.
Проблема в коде, который функционирует как часть более широкой программы, которая стандартизирует и анализирует рассматриваемые данные, возникает, когда кампания, которая имеет минимальные требования к количеству, и определенная аптека (обозначенная как «АПТЕКА» Уникальный тег GLN NUMBER) соответствует минимальному объему заказа для первого продукта, но не для второго. Эта кампания, о которой идет речь, которая представлена ​​одной строкой в ​​файле Bones.csv, также не должна быть действительна для первой продажи продукта. в строке 10 входного файла примера/теста ниже это единственная ситуация, в которой код дает сбой — он должен сократить 3 из 6 бонусов, но этого не происходит.
Это код на данный момент (Я сильно подозреваю, что виноват либо метод CompareSalesWithCampaigns(), либо метод getCampaignBonus() для минимально воспроизводимых примеров, но остальная часть программы предоставлена и здесь для справки):

Код: Выделить всё

package mf_app.BonusCalculate_3;

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;

import tocsv.UniversalConverter;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;

public class BonusTracker {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
private static final String[] dateFormats = {
"dd/MM/yyyy", "d/M/yyyy", "dd/M/yyyy", "d/MM/yyyy", // Original formats with slash as separator
"dd.MM.yyyy", "d.M.yyyy", "dd.M.yyyy", "d.MM.yyyy", "dd.MM.yy", // Formats with dot as separator
"MM/dd/yyyy", "M/d/yyyy", "MM/d/yyyy", "M/dd/yyyy", // Additional US-style formats with slash as separator
"MM/dd/yy"
};
private static final NumberFormat US_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat EU_FORMAT = NumberFormat.getInstance(Locale.GERMANY);
private static List campaignData; // Added campaignData as class-level variable

public static void main(String[] args) {
String bonusesDirectoryPath = "./data/0_UTILITIES/BONUSES";
String salesFilePath = "./data/5_1_CALCULATIONS_1/CALCULATED_1.csv";
String reportFilePath = "./data/5_2_MF_CHECKED/MF_CHECKED.csv";

try {
String campaignsFilePath = findAndConvertBonusesFile(bonusesDirectoryPath);
if (campaignsFilePath == null) {
System.err.println("No bonuses CSV or Excel file found in the directory: " + bonusesDirectoryPath);
System.exit(1);
}

ParsedCSV salesParsedCSV = parseCSV(salesFilePath);
ParsedCSV campaignsParsedCSV = parseCSV(campaignsFilePath);
campaignData = campaignsParsedCSV.data;

List discrepancies = compareSalesWithCampaigns(salesParsedCSV.data, campaignData);
System.out.println("Total Discrepancies Found: " + discrepancies.size());
generateReport(discrepancies, reportFilePath, salesParsedCSV.headers);
System.out.println("Discrepancies reported: " + discrepancies.size());
System.out.println("Report generated successfully: " + reportFilePath);
} catch (IOException | ParseException e) {
e.printStackTrace();
System.exit(1); // Exit with error status
} catch (Error err) {
// This block catches OutOfMemoryError and other serious errors
System.err.println("A severe error occurred: " + err.getMessage());
if (err instanceof OutOfMemoryError) {
System.err.println("The application ran out of memory.  Consider increasing the heap size or optimizing memory usage.");
} else {
System.err.println("Please check the application's environment and configuration.");
}
System.exit(2); // Exit with a specific error status for this type of failure
}
}

private static String findAndConvertBonusesFile(String directoryPath) throws IOException {
File directory = new File(directoryPath);
if (directory.isDirectory()) {
// Check for Excel file first
File[] excelFiles = directory.listFiles((dir, name) -> name.toLowerCase().endsWith(".xlsx"));
if (excelFiles != null && excelFiles.length > 0) {
System.out.println("excel not found!");
// Convert the first Excel file found to CSV
String excelFilePath = excelFiles[0].getPath();
String csvFilePath = directoryPath + "/" + excelFiles[0].getName().replace(".xlsx", ".csv");
UniversalConverter.convertFiles(directoryPath, directoryPath);
return csvFilePath;
}
// If no Excel file, check for CSV file
File[] csvFiles = directory.listFiles((dir, name) -> name.toLowerCase().endsWith(".csv"));
if (csvFiles != null && csvFiles.length > 0) {
System.out.println("csv not found!");
return csvFiles[0].getPath();
}
}
return null;
}

// static ParsedCSV class:
static class ParsedCSV {
List headers;
List data;

public ParsedCSV(List headers, List data) {
this.headers = headers;
this.data = data;
}
}

private static ParsedCSV parseCSV(String filePath) throws IOException {
List data = new ArrayList();
List headersList = new ArrayList();
try (CSVReader reader = new CSVReader(new FileReader(filePath))) {
String[] headers = reader.readNext();
if (headers != null) {
for (int i = 0; i < headers.length; i++) {
headers[i] = headers[i].replaceAll("[^\\x20-\\x7E]", "").trim();
headersList.add(headers[i]);
}
}
String[] line;
while ((line = reader.readNext()) != null) {
Map row = new HashMap();
for (int i = 0; i < headers.length; i++) {
row.put(headers[i], line[i]);
}
data.add(row);
}
}
return new ParsedCSV(headersList, data);
}

private static List compareSalesWithCampaigns(List salesData, List campaignData) throws ParseException {
List discrepancies = new ArrayList();

for (Map sale : salesData) {
boolean noSale = false;
boolean saleNoBonus = false;

String productBarcode = sale.get("BARCODE"); // Use the barcode instead of the product name

int saleQuantity = 0;
int saleBonus = 0;
try {
saleQuantity = parseEuropeanInteger(sale.get("QUANTITY"));
} catch (NumberFormatException e) {
noSale = true;
saleQuantity = 0;
}
if(!noSale) {
try {
saleBonus = parseEuropeanInteger(sale.get("BONUS"));
} catch (NumberFormatException e) {
noSale = true;
saleBonus = 0;

}
if (saleBonus == 0) {
saleNoBonus = true;
}
}
//int saleQuantity = parseEuropeanInteger(sale.get("QUANTITY"));
System.out.println("the bonus is: "  + sale.get("BONUS"));
//int saleBonus = parseEuropeanInteger(sale.get("BONUS"));
double salePrice = parsePrice(sale.get("PRICE"));
Date saleDate = parseDate(sale.get("DATE"), false);

Map bestCampaign = null;
int bestCampaignBonus = 0;
boolean priceMismatch = false;

//System.out.println("Processing sale: " + sale); // Debug statement

for (Map campaign : campaignData) {
boolean[] eligibilityAndMismatch = isProductEligibleForCampaign(campaign, productBarcode, saleQuantity, salePrice); // Pass product barcode
boolean isEligible = eligibilityAndMismatch[0];
boolean currentPriceMismatch = eligibilityAndMismatch[1];

if (isCampaignDateValid(campaign, saleDate) && isEligible) {
int campaignBonus = getCampaignBonus(campaign, saleQuantity);
//System.out.println("Campaign: " + campaign + " Bonus: " + campaignBonus); // Debug statement

if (campaignBonus > bestCampaignBonus && campaignBonus  0 || autoApproved > 0) {
autoCut = saleBonus - autoApproved;
}
//System.out.println("Sale: " + sale.get("PRODUCT NAME") + ", Auto Approved: " + autoApproved + ", Auto Cut: " + autoCut); // Debug statement

Map discrepancyRecord = new HashMap(sale);
discrepancyRecord.put("AUTO APPROVED", String.valueOf(autoApproved));
discrepancyRecord.put("AUTO CUT", String.valueOf(autoCut));
if (noSale) {
discrepancyRecord.put("NOTE", "NO SALE");
}
else if (saleNoBonus) {
discrepancyRecord.put("NOTE", "NO BONUS");
}
else if (priceMismatch) {
discrepancyRecord.put("PRICE HIGHLIGHT", "!!");
//discrepancyRecord.put("NOTE", "Campaign found but price mismatch");
discrepancyRecord.put("NOTE", ("Price mismatch, but: " + calculateNote(bestCampaign, saleQuantity, autoApproved)));
} else {
discrepancyRecord.put("HIGHLIGHT", autoCut > 0 ? "!" : "");
discrepancyRecord.put("NOTE", calculateNote(bestCampaign, saleQuantity, autoApproved));
}

discrepancies.add(discrepancyRecord);
}

return discrepancies;
}

private static String calculateNote(Map bestCampaign, int saleQuantity, int autoApprovedBonus) throws ParseException {
if (bestCampaign == null) {
// Handle the case where no eligible campaign is found
return "Rejected: No matching campaign found";
}

// Get the date of the sale from the bestCampaign
String saleDateString = bestCampaign.get("ValidFrom");
String saleDateStrings = bestCampaign.get("ValidUntil");
if (saleDateString == null || saleDateString.isEmpty()) {
// Handle the case where the sale date is missing
//  System.out.println("DEBUG: Sale date is missing for the sale.  Best Campaign: " + bestCampaign);
return "Note: Sale date is missing.";
}

//    System.out.println("DEBUG: Sale date string: " + saleDateString);

// Parse the sale date
Date saleDate;
try {
saleDate = dateFormat.parse(saleDateString);
saleDate = dateFormat.parse(saleDateStrings);

//    System.out.println("DEBUG: Parsed sale date: " + saleDate);
} catch (ParseException e) {
// Handle parsing exception
e.printStackTrace();
return "oups; this is not parseable as a date..."; // Return empty note in case of error
}

// Calculate the maximum campaign bonus for the given date
int maxCampaignBonus = getMaxCampaignBonusForDate(saleDate);

// System.out.println("DEBUG: Maximum campaign bonus for sale date: " + maxCampaignBonus);

// Calculate auto cut and auto approve amounts
int autoCut = Math.max(0, autoApprovedBonus - maxCampaignBonus);
int autoApproved = autoApprovedBonus - autoCut;
/*
System.out.println("DEBUG: Auto Approved: " + autoApproved);
System.out.println("DEBUG: Auto Cut: " + autoCut);*/

// Construct the note with auto cut and auto approve amounts
StringBuilder note = new StringBuilder();
note.append("Auto Approved: ").append(autoApproved).append(". ");
if (autoCut > 0) {
note.append("Auto Cut: ").append(autoCut).append(".  ");
}

return note.toString();
}

private static int getMaxCampaignBonusForDate(Date saleDate) throws ParseException {
int maxCampaignBonus = 0;
// Iterate through all campaigns and calculate the maximum campaign bonus for the given date
for (Map campaign : campaignData) {
if (isCampaignDateValid(campaign, saleDate)) {
int campaignBonus = getCampaignBonusForDate(campaign);
maxCampaignBonus = Math.max(maxCampaignBonus, campaignBonus);
}
}
return maxCampaignBonus;
}

private static boolean[] isProductEligibleForCampaign(Map campaign, String productBarcode, int saleQuantity, double salePrice) {
boolean[] result = new boolean[2]; // [eligible, priceMismatch]
for (int i = 1; i = minOrderQuantity) {
result[0] = true; // Eligible based on quantity
result[1] = (salePrice != campaignPrice); // Price mismatch check
return result;
}
}
}
result[0] = false; // Not eligible
return result;
}

private static int getCampaignBonus(Map campaign, int totalSaleQuantity) {
int maxCampaignBonus = 0;

// Check if the combined campaign for all products meets the minimum order quantity
String campaignQtyStr1 = campaign.getOrDefault("PRODUCT_1_MINIMUM_QUANTITY", "0");
int campaignQty1 = campaignQtyStr1.isEmpty() ? 0 : Integer.parseInt(campaignQtyStr1);
String campaignQtyStr2 = campaign.getOrDefault("PRODUCT_2_MINIMUM_QUANTITY", "0");
int campaignQty2 = campaignQtyStr2.isEmpty() ? 0 : Integer.parseInt(campaignQtyStr2);
String campaignQtyStr3 = campaign.getOrDefault("PRODUCT_3_MINIMUM_QUANTITY", "0");
int campaignQty3 = campaignQtyStr3.isEmpty() ? 0 : Integer.parseInt(campaignQtyStr3);

// Check if all products involved in the campaign meet their criteria
boolean isValidCampaign1 = totalSaleQuantity >= campaignQty1;
boolean isValidCampaign2 = totalSaleQuantity >= campaignQty2;
boolean isValidCampaign3 = totalSaleQuantity >= campaignQty3;

// Set the maximum campaign bonus based on valid combinations
if (isValidCampaign1 && isValidCampaign2 && isValidCampaign3) {
String campaignBonusStr1 = campaign.getOrDefault("PRODUCT_1_MF", "0");
int campaignBonus1 = campaignBonusStr1.isEmpty() ? 0 : Integer.parseInt(campaignBonusStr1);
String campaignBonusStr2 = campaign.getOrDefault("PRODUCT_2_MF", "0");
int campaignBonus2 = campaignBonusStr2.isEmpty() ? 0 : Integer.parseInt(campaignBonusStr2);
String campaignBonusStr3 = campaign.getOrDefault("PRODUCT_3_MF", "0");
int campaignBonus3 = campaignBonusStr3.isEmpty() ? 0 : Integer.parseInt(campaignBonusStr3);

maxCampaignBonus = Math.max(Math.max(campaignBonus1, campaignBonus2), campaignBonus3);
} else if (isValidCampaign1 && isValidCampaign2) {
maxCampaignBonus = Math.max(campaign.getOrDefault("PRODUCT_1_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_1_MF", "0")), campaign.getOrDefault("PRODUCT_2_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_2_MF", "0")));
} else if (isValidCampaign1 &&  isValidCampaign3) {
maxCampaignBonus = Math.max(campaign.getOrDefault("PRODUCT_1_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_1_MF", "0")), campaign.getOrDefault("PRODUCT_3_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_3_MF", "0")));
} else if (isValidCampaign2 && isValidCampaign3) {
maxCampaignBonus = Math.max(campaign.getOrDefault("PRODUCT_2_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_2_MF", "0")), campaign.getOrDefault("PRODUCT_3_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_3_MF", "0")));
} else if (isValidCampaign1) {
maxCampaignBonus = campaign.getOrDefault("PRODUCT_1_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_1_MF", "0"));
} else if (isValidCampaign2) {
maxCampaignBonus = campaign.getOrDefault("PRODUCT_2_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_2_MF", "0"));
} else if (isValidCampaign3) {
maxCampaignBonus = campaign.getOrDefault("PRODUCT_3_MF", "0").isEmpty() ? 0 : Integer.parseInt(campaign.getOrDefault("PRODUCT_3_MF", "0"));
}

return maxCampaignBonus;
}

private static int getCampaignBonusForDate(Map campaign) {
// Extract the campaign bonus for the given date from the campaign map
String campaignBonusStr = campaign.get("PRODUCT_1_MF"); // Assuming bonus for product 1 is used to represent campaign bonus
int campaignBonus = Integer.parseInt(campaignBonusStr.isEmpty() ? "0" : campaignBonusStr);

// You can add additional logic here if the campaign bonus depends on specific conditions or criteria

return campaignBonus;
}

private static boolean isCampaignDateValid(Map campaign, Date saleDate) throws ParseException {
// If saleDate is null, set it to the default value of 01/01/2000
if (saleDate == null) {
saleDate = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
}
String validFromStr = campaign.getOrDefault("ValidFrom", "");
String validUntilStr = campaign.getOrDefault("ValidUntil", "");
Date validFrom = validFromStr.isEmpty() ? new Date(Long.MIN_VALUE) : parseDate(validFromStr, true);
Date validUntil = validUntilStr.isEmpty() ? new Date(Long.MAX_VALUE) : parseDate(validUntilStr, true);
return !saleDate.before(validFrom) && !saleDate.after(validUntil);
}

// Refactor parseDate to minimize unnecessary parsing attempts
private static Date parseDate(String dateString, Boolean isQuiet) throws ParseException {
if (dateString == null || dateString.trim().isEmpty()) {
return null; // Or a more appropriate default date
}
ParseException lastException = null;
for (String format : dateFormats) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
dateFormat.setLenient(false); // Ensure strict parsing
return dateFormat.parse(dateString);
} catch (ParseException e) {
lastException = e;
}
}
if (lastException != null) {
throw lastException;
}
return null; // This should never happen if dateFormats is comprehensive
}

private static double parsePrice(String priceString) throws ParseException {
if (priceString == null || priceString.trim().isEmpty()) {
return 0.0; // Return zero or another appropriate default value
}

// Try parsing in US format
try {
Number number = US_FORMAT.parse(priceString);
return number.doubleValue();
} catch (ParseException e) {
// Try parsing in EU format
try {
Number number = EU_FORMAT.parse(priceString);
return number.doubleValue();
} catch (ParseException euException) {
throw euException;  // Throw the exception from the EU format attempt
}
}
}

public static int parseEuropeanInteger(String value) {
try {
// Remove commas before parsing
return Integer.parseInt(value.replaceAll(",", ""));
} catch (NumberFormatException e) {
throw new NumberFormatException("Unable to parse the integer: " + value);
}
}

private static void generateReport(List discrepancies, String filePath, List additionalHeaders) throws IOException {
try (CSVWriter writer = new CSVWriter(new FileWriter(filePath))) {
// Predefined headers
List predefinedHeaders = Arrays.asList(
"PRODUCT NAME", "BARCODE", "PHARMACY GLN NUMBER", "PHARMACY NAME", "DATE", "ORDER NO",
"TOWN", "PROVINCE", "QUANTITY", "BONUS", "PRICE", "WAREHOUSE",
"AUTO APPROVED", "AUTO CUT", "MANUAL APPROVED", "HIGHLIGHT", "PRICE HIGHLIGHT", "NOTE"
);

// Combine predefined headers with additional headers, avoiding duplicates
Set combinedHeadersSet = new LinkedHashSet(predefinedHeaders);
combinedHeadersSet.addAll(additionalHeaders);
List combinedHeaders = new ArrayList(combinedHeadersSet);

// Write headers to CSV
writer.writeNext(combinedHeaders.toArray(new String[0]));

// Write data records to CSV
for (Map discrepancy : discrepancies) {
List record = new ArrayList();
for (String header : combinedHeaders) {
record.add(discrepancy.getOrDefault(header, ""));
}
writer.writeNext(record.toArray(new String[0]));
}
}
}

}
это образец CSV-файла бонусных кампаний («MF» — ​​это сокращение компании для определенного типа бонусов, а не что-то вульгарное):
образец CSV-файла бонусных кампаний

Код: Выделить всё

PRODUCT_1_NAME,PRODUCT_1_BARCODE,PRODUCT_1_MINIMUM_QUANTITY,PRODUCT_1_MF,PRODUCT_1_PRICE,PRODUCT_2_NAME,PRODUCT_2_BARCODE,PRODUCT_2_MINIMUM_QUANTITY,PRODUCT_2_MF,PRODUCT_2_PRICE,PRODUCT_3_NAME,PRODUCT_3_BARCODE,PRODUCT_3_MINIMUM_QUANTITY,PRODUCT_3_MF,PRODUCT_3_PRICE,ValidFrom,ValidUntil
A,1,10,2,1000,,,,,,,,,,,01/01/2024,01/02/2024
A,1,10,3,1000,,,,,,,,,,,01/01/2024,01/02/2024
A,1,10,5,1000,,,,,,,,,,,10/01/2024,15/02/2024
A,1,10,6,1000,B,2,3,1,1500,,,,,,01/01/2024,01/02/2024
B,2,100,50,1500,,,,,,,,,,,01/01/2024,01/02/2024
B,2,10,3,1500,,,,,,,,,,,01/01/2024,01/02/2024
это образец CSV-файла с данными о продажах, который необходимо проверить:
пример CSV-файла с данными о продажах

Код: Выделить всё

    PRODUCT NAME,BARCODE,PHARMACY GLN NUMBER,PHARMACY NAME,DATE,ORDER NO,TOWN,PROVINCE,QUANTITY,BONUS,PRICE
A,1,100,Pharma 1,02/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,2,1000
A,1,200,Pharma 2,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,3,1000
A,1,300,Pharma 3,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,11,3,1000
A,1,400,Pharma 4,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,20,6,1000
A,1,500,Pharma 5,04/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,5,1000
A,1,600,Pharma 6,10/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,5,1000
A,1,700,Pharma 7,04/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,6,1000
B,2,700,Pharma 7,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,3,1,1500
A,1,800,Pharma 8,04/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,6,1000
B,2,800,Pharma 8,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,2,0,1500
B,2,900,Pharma 9,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,105,50,1500
B,2,1000,Pharma 10,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,20,10,1500
A,1,1100,Pharma 11,02/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,2,800
C,3,1200,Pharma 12,02/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,5,1,35
это вывод, который должна получить программа:
вывод, который должна получить программа

Код: Выделить всё

    PRODUCT NAME,BARCODE,PHARMACY GLN NUMBER,PHARMACY NAME,DATE,ORDER NO,TOWN,PROVINCE,QUANTITY,BONUS,PRICE,WAREHOUSE,AUTO APPROVED,AUTO CUT,MANUAL APPROVE,HIGHLIGHT,NOTE
A,1,100,Pharma 1,02/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,2,1000,xxxxxxx,2,,,,Auto Approved: 2.
A,1,200,Pharma 2,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,3,1000,xxxxxxx,3,,,,Auto Approved: 3.
A,1,300,Pharma 3,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,11,3,1000,xxxxxxx,3,,,,Auto Approved: 3.
A,1,400,Pharma 4,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,20,6,1000,xxxxxxx,6,,,,Auto Approved: 6.
A,1,500,Pharma 5,04/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,5,1000,xxxxxxx,3,2,,!,Auto Approved: 3.
A,1,600,Pharma 6,10/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,5,1000,xxxxxxx,5,,,,Auto Approved: 5.
A,1,700,Pharma 7,04/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,6,1000,xxxxxxx,6,,,,Auto Approved: 6.
B,2,700,Pharma 7,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,3,1,1500,xxxxxxx,1,,,,Auto Approved: 1.
A,1,800,Pharma 8,04/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,6,1000,xxxxxxx,3,3,,!,Auto Approved: 3.
B,2,800,Pharma 8,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,2,0,1500,xxxxxxx,0,,,,NO BONUS
B,2,900,Pharma 9,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,105,50,1500,xxxxxxx,50,,,,Auto Approved: 50.
B,2,1000,Pharma 10,03/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,20,10,1500,xxxxxxx,6,4,,!,Auto Approved: 6.
A,1,1100,Pharma 11,02/01/2024,xxxxxxx,xxxxxxx,xxxxxxx,10,2,800,xxxxxxx,2,,,!!,"Price mismatch, but: Auto Approved: 2. "
это вывод, который он генерирует в данный момент (обратите внимание на строку 10!!!):
вывод, который он генерирует в данный момент

Код: Выделить всё

PRODUCT NAME,BARCODE,PHARMACY GLN NUMBER,PHARMACY NAME,DATE,ORDER NO,TOWN,PROVINCE,QUANTITY,BONUS,PRICE,WAREHOUSE,AUTO APPROVED,AUTO CUT,MANUAL APPROVED,HIGHLIGHT,PRICE HIGHLIGHT,NOTE
A,1,100,Pharma 1,02.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,2,1000,TO_CHECK_EXAMPLE,2,0,,,,Auto Approved: 2.
A,1,200,Pharma 2,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,3,1000,TO_CHECK_EXAMPLE,3,0,,,,Auto Approved: 3.
A,1,300,Pharma 3,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,11,3,1000,TO_CHECK_EXAMPLE,3,0,,,,Auto Approved: 3.
A,1,400,Pharma 4,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,20,6,1000,TO_CHECK_EXAMPLE,6,0,,,,Auto Approved: 6.
A,1,500,Pharma 5,04.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,5,1000,TO_CHECK_EXAMPLE,3,2,,!,,Auto Approved: 3.
A,1,600,Pharma 6,10.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,5,1000,TO_CHECK_EXAMPLE,5,0,,,,Auto Approved: 5.
A,1,700,Pharma 7,04.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,6,1000,TO_CHECK_EXAMPLE,6,0,,,,Auto Approved: 6.
B,2,700,Pharma 7,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,3,1,1500,TO_CHECK_EXAMPLE,1,0,,,,Auto Approved: 1.
A,1,800,Pharma 8,04.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,6,1000,TO_CHECK_EXAMPLE,6,0,,,,Auto Approved: 6.
B,2,800,Pharma 8,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,2,0,1500,TO_CHECK_EXAMPLE,0,0,,,,NO BONUS
B,2,900,Pharma 9,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,105,50,1500,TO_CHECK_EXAMPLE,50,0,,,,Auto Approved: 50.
B,2,1000,Pharma 10,03.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,20,10,1500,TO_CHECK_EXAMPLE,6,4,,!,,Auto Approved: 6.
A,1,1100,Pharma 11,02.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,10,2,800,TO_CHECK_EXAMPLE,2,0,,,!!,"Price mismatch, but: Auto Approved: 2. "
C,3,1200,Pharma 12,02.01.2024,xxxxxxx,xxxxxxx,xxxxxxx,5,1,35,TO_CHECK_EXAMPLE,0,1,,!,,Rejected: No matching campaign found
а это пояснения сокращений и утверждений:
пояснения сокращений и согласований

Подробнее здесь: https://stackoverflow.com/questions/785 ... s-java-pro
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»