"""Debug script to trace order status sync in logistics flow.""" import sys, os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.environ['APP_ENV'] = 'test' os.environ['MYSQL_DATABASE'] = ':memory:' os.environ['SECRET_KEY'] = 'test-secret-key-for-testing-only' os.environ['JWT_EXPIRE_MINUTES'] = '60' os.environ['AI_PROVIDER'] = 'mock' os.environ['AUTH_TOKEN_STORE_PATH'] = 'D:/tmp/order-flow-test/revoked_tokens.json' from sqlalchemy import create_engine from sqlalchemy.orm import Session from backend.app.db import Base from backend.app.core.security import create_access_token, hash_password from backend.app.main import app from backend.app.api.deps import get_db_session from backend.tests.conftest import SyncTestClient from backend.app.models.system import Role, User, Menu, RoleMenu from backend.app.models.business import Customer, Product, Supplier, SalesOrder, SalesOrderItem engine = create_engine('sqlite:///:memory:', echo=False, connect_args={'check_same_thread': False}) Base.metadata.create_all(engine) connection = engine.connect() transaction = connection.begin() session = Session(bind=connection) # Seed data roles = [ Role(id=1, role_name='Admin', role_code='admin', status=1), Role(id=2, role_name='Sales', role_code='salesman', status=1), Role(id=3, role_name='Manager', role_code='manager', status=1), Role(id=4, role_name='Driver', role_code='driver', status=1), ] session.add_all(roles) session.flush() users = [ User(id=1, username='admin01', password_hash=hash_password('admin123'), real_name='Admin', mobile='13800000001', role_id=1, status=1), User(id=5, username='driver01', password_hash=hash_password('driver123'), real_name='Driver', mobile='13800000005', role_id=4, status=1), ] session.add_all(users) session.flush() menus = [ Menu(id=1, menu_name='Orders', menu_path='/orders', menu_type='page', permission_code='order:list', sort_no=1, status=1), Menu(id=8, menu_name='Driver', menu_path='/driver', menu_type='page', permission_code='driver:task:list', sort_no=6, status=1), Menu(id=9, menu_name='Accept', menu_path='', menu_type='button', permission_code='driver:task:accept', parent_id=8, sort_no=1, status=1), Menu(id=10, menu_name='Pickup', menu_path='', menu_type='button', permission_code='driver:task:pickup', parent_id=8, sort_no=2, status=1), Menu(id=11, menu_name='Deliver', menu_path='', menu_type='button', permission_code='driver:task:deliver', parent_id=8, sort_no=3, status=1), Menu(id=25, menu_name='TaskList', menu_path='', menu_type='button', permission_code='logistics:task:list', parent_id=8, sort_no=4, status=1), Menu(id=26, menu_name='TaskCreate', menu_path='', menu_type='button', permission_code='logistics:task:create', parent_id=8, sort_no=5, status=1), Menu(id=27, menu_name='TaskCancel', menu_path='', menu_type='button', permission_code='logistics:task:cancel', parent_id=8, sort_no=6, status=1), Menu(id=28, menu_name='TraceList', menu_path='', menu_type='button', permission_code='logistics:trace:list', parent_id=8, sort_no=7, status=1), Menu(id=29, menu_name='TraceCreate', menu_path='', menu_type='button', permission_code='logistics:trace:create', parent_id=8, sort_no=8, status=1), Menu(id=12, menu_name='Submit', menu_path='', menu_type='button', permission_code='order:submit', parent_id=1, sort_no=3, status=1), ] session.add_all(menus) session.flush() role_menus = [ *[RoleMenu(role_id=1, menu_id=m.id) for m in menus], RoleMenu(role_id=4, menu_id=8), RoleMenu(role_id=4, menu_id=9), RoleMenu(role_id=4, menu_id=10), RoleMenu(role_id=4, menu_id=11), RoleMenu(role_id=4, menu_id=28), RoleMenu(role_id=4, menu_id=29), ] session.add_all(role_menus) session.flush() def override_get_db(): try: yield session finally: pass app.dependency_overrides[get_db_session] = override_get_db admin_token = create_access_token({'user_id': 1, 'role_code': 'admin', 'username': 'admin01'}) driver_token = create_access_token({'user_id': 5, 'role_code': 'driver', 'username': 'driver01'}) with SyncTestClient(app, raise_server_exceptions=False) as c: admin_h = {'Authorization': f'Bearer {admin_token}'} driver_h = {'Authorization': f'Bearer {driver_token}'} # Create test data directly in DB customer = Customer(customer_name='Test', mobile='13800001111', settlement_type='immediate', settlement_days=0, salesman_id=2, credit_limit=0, deleted=0) product = Product(product_name='TestProd', specification='100x100', unit='pcs', category='cat', cost_price=60.0, sale_price=100.0, status=1) supplier = Supplier(supplier_name='TestFactory', supplier_type='factory', contact_name='Contact', contact_mobile='13900001111', status=1) session.add_all([customer, product, supplier]) session.flush() order = SalesOrder( order_no='TEST-001', customer_id=customer.id, customer_name=customer.customer_name, customer_mobile=customer.mobile, salesman_id=2, order_status='approved', factory_id=supplier.id, sale_price_total=1000.0, cost_price_total=600.0, profit_total=400.0, profit_rate=40.0, deleted=0, ) session.add(order) session.flush() print(f'1. Order created: id={order.id}, status={order.order_status}') # Create task via API resp = c.post('/api/logistics/tasks', headers=admin_h, json={ 'order_id': order.id, 'driver_id': 5, 'pickup_address': 'Factory', 'delivery_address': 'Warehouse', 'pickup_content': 'Goods', 'quantity': 10, }) print(f'2. Create task: status={resp.status_code}') if resp.status_code == 200: task_id = resp.json()['data']['task_id'] print(f' task_id={task_id}') else: print(f' Error: {resp.text[:200]}') sys.exit(1) # Check order status in DB session.expire_all() order = session.get(SalesOrder, order.id) print(f'3. Order status after create_task: {order.order_status}') # Check task in DB from backend.app.models.business import LogisticsTask task = session.get(LogisticsTask, task_id) print(f'4. Task: id={task.id}, order_id={task.order_id}, status={task.status}') # Accept task resp = c.post(f'/api/driver/tasks/{task_id}/accept', headers=driver_h, json={}) print(f'5. Accept task: status={resp.status_code}') if resp.status_code != 200: print(f' Error: {resp.text[:200]}') # Check order status session.expire_all() order = session.get(SalesOrder, order.id) print(f'6. Order status after accept: {order.order_status}') # Check task status session.expire_all() task = session.get(LogisticsTask, task_id) print(f'7. Task status after accept: {task.status}') app.dependency_overrides.clear() transaction.rollback() session.close() connection.close()