feat: add database-driven material validation with multi-mode support
This commit enhances the material validation functionality to support database-driven workflows alongside the existing Excel-based approach. ## New Features ### DAO Layer - Add ProductionContractDataDAO for querying production contract data - Add MaterialsToBeDeletedDAO with full CRUD operations - Enhance DiscreteMaterialPlanDAO with query_all(), query_by_source_numbers(), and get_unique_material_names() methods ### Validation Modes Support for 4 validation modes in MaterialValidationTab: 1. Database Full - Query all materials from DiscreteMaterialPlanData 2. Database Filtered - Query by ProductionID.txt file 3. Excel Existing - Validate from existing Excel file 4. Excel Full - Complete workflow with ERP extraction ### Configuration - Add ValidationConfig dataclass with data_source, batch_size, match_mode, enable_crud_operations, and default_manager fields - Update ConfigLoader to support validation configuration - Add validation settings section in SettingsTab GUI ### Query Chain Implementation of full query chain: ProductionID.txt (总排号) → productionContractData (生产订单号) → DiscreteMaterialPlanData (SourceNumber) → MaterialName → MaterialsToBeDeleted comparison ## Backward Compatibility All existing Excel-based validation methods remain unchanged, ensuring no breaking changes for existing workflows. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ from config.schema import (
|
||||
DatabaseConfig,
|
||||
PathConfig,
|
||||
ExtractionConfig,
|
||||
ValidationConfig,
|
||||
AppConfig,
|
||||
)
|
||||
|
||||
@@ -45,6 +46,14 @@ DEFAULT_APP_CONFIG = AppConfig(
|
||||
merge_batches=True,
|
||||
enable_db_persistence=False, # Disabled by default
|
||||
),
|
||||
validation=ValidationConfig(
|
||||
data_source="database_full",
|
||||
use_database=True,
|
||||
batch_size=2000,
|
||||
enable_crud_operations=False,
|
||||
default_manager="",
|
||||
match_mode="substring",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ class ConfigLoader:
|
||||
database_dict = settings.get("database", {})
|
||||
paths_dict = settings.get("paths", {})
|
||||
extraction_dict = settings.get("extraction", {})
|
||||
validation_dict = settings.get("validation", {})
|
||||
|
||||
return AppConfig(
|
||||
erp=ERPConfig(
|
||||
@@ -142,9 +143,18 @@ class ConfigLoader:
|
||||
verbose=extraction_dict.get("verbose", True),
|
||||
auto_convert=extraction_dict.get("auto_convert", True),
|
||||
merge_batches=extraction_dict.get("merge_batches", True),
|
||||
enable_db_persistence=extraction_dict.get("enable_db_persistence", False),
|
||||
),
|
||||
validation=ValidationConfig(
|
||||
data_source=validation_dict.get("data_source", "database_full"),
|
||||
use_database=validation_dict.get("use_database", True),
|
||||
batch_size=validation_dict.get("batch_size", 2000),
|
||||
enable_crud_operations=validation_dict.get("enable_crud_operations", False),
|
||||
default_manager=validation_dict.get("default_manager", ""),
|
||||
match_mode=validation_dict.get("match_mode", "substring"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# 为了兼容旧代码,导入必要的类型
|
||||
from config.schema import ERPConfig, DatabaseConfig, PathConfig, ExtractionConfig
|
||||
from config.schema import ERPConfig, DatabaseConfig, PathConfig, ExtractionConfig, ValidationConfig
|
||||
|
||||
@@ -97,6 +97,48 @@ class ExtractionConfig:
|
||||
return errors
|
||||
|
||||
|
||||
@dataclass
|
||||
class ValidationConfig:
|
||||
"""物料校验配置"""
|
||||
|
||||
data_source: str = "database_full"
|
||||
use_database: bool = True
|
||||
batch_size: int = 2000
|
||||
enable_crud_operations: bool = False
|
||||
default_manager: str = ""
|
||||
match_mode: str = "substring"
|
||||
|
||||
def validate(self) -> list[str]:
|
||||
"""验证配置,返回错误列表"""
|
||||
errors = []
|
||||
|
||||
valid_sources = [
|
||||
"database_full",
|
||||
"database_filtered",
|
||||
"excel_existing",
|
||||
"excel_full"
|
||||
]
|
||||
if self.data_source not in valid_sources:
|
||||
errors.append(
|
||||
f"无效的数据源: {self.data_source}。"
|
||||
f"有效选项: {', '.join(valid_sources)}"
|
||||
)
|
||||
|
||||
if self.batch_size <= 0:
|
||||
errors.append("批次大小必须大于 0")
|
||||
if self.batch_size > 2000:
|
||||
errors.append("批次大小不应超过 2000(SQL Server 参数限制)")
|
||||
|
||||
valid_match_modes = ["substring", "exact"]
|
||||
if self.match_mode not in valid_match_modes:
|
||||
errors.append(
|
||||
f"无效的匹配模式: {self.match_mode}。"
|
||||
f"有效选项: {', '.join(valid_match_modes)}"
|
||||
)
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
@dataclass
|
||||
class AppConfig:
|
||||
"""应用总配置"""
|
||||
@@ -105,6 +147,7 @@ class AppConfig:
|
||||
database: DatabaseConfig
|
||||
paths: PathConfig
|
||||
extraction: ExtractionConfig
|
||||
validation: ValidationConfig
|
||||
|
||||
def validate(self) -> list[str]:
|
||||
"""验证所有配置,返回错误列表"""
|
||||
@@ -113,6 +156,7 @@ class AppConfig:
|
||||
errors.extend(self.database.validate())
|
||||
errors.extend(self.paths.validate())
|
||||
errors.extend(self.extraction.validate())
|
||||
errors.extend(self.validation.validate())
|
||||
return errors
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
@@ -147,4 +191,12 @@ class AppConfig:
|
||||
"merge_batches": self.extraction.merge_batches,
|
||||
"enable_db_persistence": self.extraction.enable_db_persistence,
|
||||
},
|
||||
"validation": {
|
||||
"data_source": self.validation.data_source,
|
||||
"use_database": self.validation.use_database,
|
||||
"batch_size": self.validation.batch_size,
|
||||
"enable_crud_operations": self.validation.enable_crud_operations,
|
||||
"default_manager": self.validation.default_manager,
|
||||
"match_mode": self.validation.match_mode,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user