fix(query-tool): finalize raw-material tab/export and resolve ORA-00918
This commit is contained in:
@@ -89,3 +89,26 @@ def test_fetch_events_history_branch_replaces_container_filter(
|
||||
assert "h.CONTAINERID = :container_id" not in sql
|
||||
assert "{{ WORKCENTER_FILTER }}" not in sql
|
||||
assert params == {"p0": "CID-1"}
|
||||
|
||||
|
||||
@patch("mes_dashboard.services.event_fetcher.cache_set")
|
||||
@patch("mes_dashboard.services.event_fetcher.cache_get", return_value=None)
|
||||
@patch("mes_dashboard.services.event_fetcher.read_sql_df")
|
||||
@patch("mes_dashboard.services.event_fetcher.SQLLoader.load")
|
||||
def test_fetch_events_materials_branch_replaces_aliased_container_filter(
|
||||
mock_sql_load,
|
||||
mock_read_sql_df,
|
||||
_mock_cache_get,
|
||||
_mock_cache_set,
|
||||
):
|
||||
mock_sql_load.return_value = (
|
||||
"SELECT * FROM t m WHERE m.CONTAINERID = :container_id ORDER BY TXNDATE"
|
||||
)
|
||||
mock_read_sql_df.return_value = pd.DataFrame([])
|
||||
|
||||
EventFetcher.fetch_events(["CID-1", "CID-2"], "materials")
|
||||
|
||||
sql, params = mock_read_sql_df.call_args.args
|
||||
assert "m.CONTAINERID = :container_id" not in sql
|
||||
assert "IN" in sql.upper()
|
||||
assert params == {"p0": "CID-1", "p1": "CID-2"}
|
||||
|
||||
@@ -123,5 +123,5 @@ def test_resource_history_export_uses_contract_headers(
|
||||
chunks = list(export_resource_history_csv('2024-01-01', '2024-01-10'))
|
||||
|
||||
assert chunks
|
||||
header_row = next(csv.reader(io.StringIO(chunks[0])))
|
||||
header_row = next(csv.reader(io.StringIO(chunks[0].lstrip('\ufeff'))))
|
||||
assert header_row == export_headers
|
||||
|
||||
@@ -690,10 +690,10 @@ class TestExportCsvEndpoint:
|
||||
assert '不支援' in data['error'] or 'type' in data['error'].lower()
|
||||
|
||||
@patch('mes_dashboard.routes.query_tool_routes.get_lot_history')
|
||||
def test_export_lot_history_success(self, mock_get_history, client):
|
||||
"""Should return CSV for lot history."""
|
||||
mock_get_history.return_value = {
|
||||
'data': [
|
||||
def test_export_lot_history_success(self, mock_get_history, client):
|
||||
"""Should return CSV for lot history."""
|
||||
mock_get_history.return_value = {
|
||||
'data': [
|
||||
{
|
||||
'EQUIPMENTNAME': 'ASSY-01',
|
||||
'SPECNAME': 'SPEC-001',
|
||||
@@ -709,9 +709,46 @@ class TestExportCsvEndpoint:
|
||||
'export_type': 'lot_history',
|
||||
'params': {'container_id': '488103800029578b'}
|
||||
}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert 'text/csv' in response.content_type
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert 'text/csv' in response.content_type
|
||||
|
||||
@patch('mes_dashboard.routes.query_tool_routes.get_lot_materials')
|
||||
def test_export_lot_materials_uses_container_name_as_lot_id(
|
||||
self,
|
||||
mock_get_materials,
|
||||
client,
|
||||
):
|
||||
mock_get_materials.return_value = {
|
||||
'data': [
|
||||
{
|
||||
'CONTAINERID': '488103800029578b',
|
||||
'CONTAINERNAME': 'GA25010001-A01',
|
||||
'MATERIALPARTNAME': 'M-001',
|
||||
'MATERIALLOTNAME': 'LOT-MAT-01',
|
||||
'QTYCONSUMED': 10,
|
||||
'WORKCENTERNAME': 'DB',
|
||||
'SPECNAME': 'SPEC-DB',
|
||||
'EQUIPMENTNAME': 'EQ-01',
|
||||
'TXNDATE': '2026-02-22 10:00:00',
|
||||
}
|
||||
],
|
||||
'total': 1,
|
||||
}
|
||||
|
||||
response = client.post(
|
||||
'/api/query-tool/export-csv',
|
||||
json={
|
||||
'export_type': 'lot_materials',
|
||||
'params': {'container_id': '488103800029578b'}
|
||||
}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert 'lot_raw_materials_488103800029578b.csv' in response.headers.get('Content-Disposition', '')
|
||||
decoded = response.data.decode('utf-8-sig')
|
||||
assert 'LOT ID' in decoded
|
||||
assert 'GA25010001-A01' in decoded
|
||||
|
||||
|
||||
class TestEquipmentListEndpoint:
|
||||
|
||||
Reference in New Issue
Block a user