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