"""Service Order Blueprint: workshop Kanban management. Prefix: /pos/api/service-orders """ from flask import Blueprint, request, jsonify, g from middleware import require_auth from tenant_db import get_tenant_conn from services.service_order_engine import ( create_service_order, get_service_order, list_service_orders, update_status, add_item, update_item, remove_item, add_labor, update_labor, remove_labor, update_service_order, get_kanban_summary, ) service_order_bp = Blueprint('service_orders', __name__, url_prefix='/pos/api/service-orders') @service_order_bp.route('', methods=['GET']) @require_auth() def list_orders(): status = request.args.get('status') priority = request.args.get('priority') customer_id = request.args.get('customer_id', type=int) employee_id = request.args.get('employee_id', type=int) page = int(request.args.get('page', 1)) per_page = min(int(request.args.get('per_page', 50)), 200) conn = get_tenant_conn(g.tenant_id) try: result = list_service_orders( conn, status=status, branch_id=g.branch_id, customer_id=customer_id, priority=priority, employee_id=employee_id, page=page, per_page=per_page ) return jsonify(result) finally: conn.close() @service_order_bp.route('', methods=['POST']) @require_auth() def create_order(): data = request.get_json() or {} conn = get_tenant_conn(g.tenant_id) try: result = create_service_order(conn, { 'tenant_id': g.tenant_id, 'branch_id': data.get('branch_id', g.branch_id), 'customer_id': data.get('customer_id'), 'vehicle_id': data.get('vehicle_id'), 'priority': data.get('priority', 'normal'), 'reception_notes': data.get('reception_notes'), 'estimated_cost': data.get('estimated_cost'), 'estimated_completion': data.get('estimated_completion'), 'employee_id': data.get('employee_id'), 'mileage_in': data.get('mileage_in'), 'fuel_level': data.get('fuel_level'), 'created_by': getattr(g, 'employee_id', None), }) return jsonify(result), 201 finally: conn.close() @service_order_bp.route('/', methods=['GET']) @require_auth() def get_order(so_id): conn = get_tenant_conn(g.tenant_id) try: order = get_service_order(conn, so_id) if not order: return jsonify({'error': 'Service order not found'}), 404 return jsonify(order) finally: conn.close() @service_order_bp.route('/', methods=['PUT']) @require_auth() def update_order(so_id): data = request.get_json() or {} conn = get_tenant_conn(g.tenant_id) try: ok = update_service_order(conn, so_id, data) if not ok: return jsonify({'error': 'No fields to update'}), 400 return jsonify({'message': 'Service order updated'}) finally: conn.close() @service_order_bp.route('//status', methods=['PUT']) @require_auth() def change_status(so_id): data = request.get_json() or {} new_status = data.get('status') if not new_status: return jsonify({'error': 'status is required'}), 400 conn = get_tenant_conn(g.tenant_id) try: result = update_status( conn, so_id, new_status, changed_by=getattr(g, 'employee_id', None), notes=data.get('notes'), ) return jsonify(result) except ValueError as e: return jsonify({'error': str(e)}), 400 finally: conn.close() # ─── Items (Parts) ───────────────────────────── @service_order_bp.route('//items', methods=['POST']) @require_auth() def add_order_item(so_id): data = request.get_json() or {} conn = get_tenant_conn(g.tenant_id) try: item_id = add_item(conn, so_id, data) return jsonify({'id': item_id, 'message': 'Item added'}), 201 finally: conn.close() @service_order_bp.route('/items/', methods=['PUT']) @require_auth() def update_order_item(item_id): data = request.get_json() or {} conn = get_tenant_conn(g.tenant_id) try: ok = update_item(conn, item_id, data) if not ok: return jsonify({'error': 'No fields to update'}), 400 return jsonify({'message': 'Item updated'}) finally: conn.close() @service_order_bp.route('/items/', methods=['DELETE']) @require_auth() def delete_order_item(item_id): conn = get_tenant_conn(g.tenant_id) try: remove_item(conn, item_id) return jsonify({'message': 'Item removed'}) finally: conn.close() # ─── Labor ───────────────────────────── @service_order_bp.route('//labor', methods=['POST']) @require_auth() def add_order_labor(so_id): data = request.get_json() or {} if not data.get('description'): return jsonify({'error': 'description is required'}), 400 conn = get_tenant_conn(g.tenant_id) try: labor_id = add_labor(conn, so_id, data) return jsonify({'id': labor_id, 'message': 'Labor added'}), 201 finally: conn.close() @service_order_bp.route('/labor/', methods=['PUT']) @require_auth() def update_order_labor(labor_id): data = request.get_json() or {} conn = get_tenant_conn(g.tenant_id) try: ok = update_labor(conn, labor_id, data) if not ok: return jsonify({'error': 'No fields to update'}), 400 return jsonify({'message': 'Labor updated'}) finally: conn.close() @service_order_bp.route('/labor/', methods=['DELETE']) @require_auth() def delete_order_labor(labor_id): conn = get_tenant_conn(g.tenant_id) try: remove_labor(conn, labor_id) return jsonify({'message': 'Labor removed'}) finally: conn.close() # ─── Kanban Summary ───────────────────────────── @service_order_bp.route('/kanban/summary', methods=['GET']) @require_auth() def kanban_summary(): conn = get_tenant_conn(g.tenant_id) try: summary = get_kanban_summary(conn, branch_id=g.branch_id) return jsonify(summary) finally: conn.close()