Compare commits
2 Commits
00f4e40505
...
2ecd8db79a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ecd8db79a | ||
|
|
3acdbf4b1a |
45
src/main/dao/production-order.dao.ts
Normal file
45
src/main/dao/production-order.dao.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { DatabaseService } from '../services/database.service';
|
||||||
|
import { LoggerService } from '../services/logger.service';
|
||||||
|
|
||||||
|
export class ProductionOrderDAO {
|
||||||
|
constructor(private dbService: DatabaseService) {}
|
||||||
|
|
||||||
|
async queryProductionOrderNumbers(productionIds: string[]): Promise<string[]> {
|
||||||
|
try {
|
||||||
|
LoggerService.info(`Querying production orders for ${productionIds.length} IDs`);
|
||||||
|
|
||||||
|
const idsString = productionIds.map((id) => `'${id}'`).join(',');
|
||||||
|
const query = `
|
||||||
|
SELECT DISTINCT production_order_no
|
||||||
|
FROM production_orders
|
||||||
|
WHERE production_id IN (${idsString})
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = await this.dbService.executeSQLServerQuery(query);
|
||||||
|
const orderNumbers = result.rows.map((row: any) => row.production_order_no);
|
||||||
|
|
||||||
|
LoggerService.info(`Found ${orderNumbers.length} production orders`);
|
||||||
|
return orderNumbers;
|
||||||
|
} catch (error) {
|
||||||
|
LoggerService.error('Failed to query production orders', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async readProductionIds(filePath: string): Promise<string[]> {
|
||||||
|
try {
|
||||||
|
const fs = await import('fs/promises');
|
||||||
|
const content = await fs.readFile(filePath, 'utf-8');
|
||||||
|
const ids = content
|
||||||
|
.split('\n')
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter((line) => line.length > 0);
|
||||||
|
|
||||||
|
LoggerService.info(`Read ${ids.length} production IDs from file`);
|
||||||
|
return ids;
|
||||||
|
} catch (error) {
|
||||||
|
LoggerService.error('Failed to read production IDs file', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
125
src/main/services/excel-converter.service.ts
Normal file
125
src/main/services/excel-converter.service.ts
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import ExcelJS from 'exceljs';
|
||||||
|
import path from 'path';
|
||||||
|
import { LoggerService } from './logger.service';
|
||||||
|
|
||||||
|
export class ExcelConverterService {
|
||||||
|
constructor(private verbose: boolean = true) {}
|
||||||
|
|
||||||
|
async convert(inputPath: string, outputPath?: string): Promise<any[]> {
|
||||||
|
try {
|
||||||
|
// Validate input file
|
||||||
|
const fs = await import('fs/promises');
|
||||||
|
|
||||||
|
// Check file exists
|
||||||
|
try {
|
||||||
|
await fs.access(inputPath, fs.constants.R_OK);
|
||||||
|
} catch {
|
||||||
|
throw new Error(`File not found: ${inputPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check file extension
|
||||||
|
if (!inputPath.match(/\.(xlsx|xls)$/i)) {
|
||||||
|
throw new Error(`Invalid file type. Expected .xlsx or .xls file: ${inputPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerService.info(`Converting Excel file: ${inputPath}`);
|
||||||
|
|
||||||
|
const workbook = new ExcelJS.Workbook();
|
||||||
|
await workbook.xlsx.readFile(inputPath);
|
||||||
|
|
||||||
|
const worksheet = workbook.worksheets[0];
|
||||||
|
if (!worksheet) {
|
||||||
|
throw new Error('No worksheet found in Excel file');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: any[] = [];
|
||||||
|
const headers: string[] = [];
|
||||||
|
|
||||||
|
// Extract headers
|
||||||
|
const headerRow = worksheet.getRow(1);
|
||||||
|
headerRow.eachCell((cell, colNumber) => {
|
||||||
|
headers[colNumber - 1] = cell.text;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Extract data rows
|
||||||
|
worksheet.eachRow((row, rowNumber) => {
|
||||||
|
if (rowNumber === 1) return; // Skip header row
|
||||||
|
|
||||||
|
const rowData: any = {};
|
||||||
|
row.eachCell((cell, colNumber) => {
|
||||||
|
const header = headers[colNumber - 1];
|
||||||
|
if (header) {
|
||||||
|
// Extract actual value from cell (handles formulas, rich text, etc.)
|
||||||
|
const value = cell.value;
|
||||||
|
const extractedValue = typeof value === 'object' && value !== null
|
||||||
|
? (value as any).result || (value as any).text || value
|
||||||
|
: value;
|
||||||
|
rowData[header] = extractedValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
data.push(rowData);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Validate we got data
|
||||||
|
if (data.length === 0) {
|
||||||
|
LoggerService.warn('Excel file contains no data rows');
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerService.info(`Extracted ${data.length} rows from Excel file`);
|
||||||
|
|
||||||
|
// Save to output path if provided
|
||||||
|
if (outputPath) {
|
||||||
|
await this.saveAsJson(data, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
LoggerService.error('Excel conversion failed', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async mergeExcelFiles(filePaths: string[], outputPath: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
LoggerService.info(`Merging ${filePaths.length} Excel files...`);
|
||||||
|
|
||||||
|
const allData: any[] = [];
|
||||||
|
|
||||||
|
for (const filePath of filePaths) {
|
||||||
|
const data = await this.convert(filePath);
|
||||||
|
allData.push(...data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new Excel workbook with merged data
|
||||||
|
const workbook = new ExcelJS.Workbook();
|
||||||
|
const worksheet = workbook.addWorksheet('Merged Data');
|
||||||
|
|
||||||
|
if (allData.length > 0) {
|
||||||
|
const headers = Object.keys(allData[0]);
|
||||||
|
worksheet.addRow(headers);
|
||||||
|
|
||||||
|
allData.forEach((row) => {
|
||||||
|
const values = headers.map((header) => row[header]);
|
||||||
|
worksheet.addRow(values);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await workbook.xlsx.writeFile(outputPath);
|
||||||
|
LoggerService.info(`Merged data saved to: ${outputPath}`);
|
||||||
|
} catch (error) {
|
||||||
|
LoggerService.error('Excel merge failed', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveAsJson(data: any[], outputPath: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
const fs = await import('fs/promises');
|
||||||
|
await fs.writeFile(outputPath, JSON.stringify(data, null, 2), 'utf-8');
|
||||||
|
LoggerService.info(`Data saved to JSON: ${outputPath}`);
|
||||||
|
} catch (error) {
|
||||||
|
LoggerService.error(`Failed to save JSON to ${outputPath}`, error);
|
||||||
|
throw new Error(`Failed to save JSON output: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user