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:
Misaka_Company
2026-02-06 13:08:31 +08:00
parent 53a1e33e45
commit 2096a51f55
9 changed files with 976 additions and 57 deletions

View File

@@ -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",
),
)

View File

@@ -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

View File

@@ -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("批次大小不应超过 2000SQL 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,
},
}