feat(pl): 运输计划模块接入数据权限过滤
新增 pl_data_scope 辅助,PL 列表/统计 apply_pl_scope,详情与改删 assert_pl_row_in_scope;运费结算待办审批 skip_scope。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
bf73b6b2d8
commit
eff99edeea
8 files changed
+526
-53
No files matched your search
@@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.db_auth import DbUserContext, get_db_current_user
|
||||
from app.services.pl_data_scope import apply_pl_scope, assert_pl_row_in_scope
|
||||
from app.core.tenant_context import get_tenant_no
|
||||
from app.core.utils import generate_uuid
|
||||
from app.models.pl_models import (
|
||||
@@ -77,6 +78,8 @@ def list_carriers(
|
||||
)
|
||||
)
|
||||
|
||||
query = apply_pl_scope(query, PlCarrier, user, db, tenant_no)
|
||||
|
||||
query = query.order_by(
|
||||
case((PlCarrier.order_num.is_(None), 1), else_=0).asc(),
|
||||
PlCarrier.create_time.desc(),
|
||||
@@ -116,7 +119,7 @@ def get_carrier(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> CarrierRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
carrier = _get_carrier(db, tenant_no, id)
|
||||
carrier = _get_carrier(db, tenant_no, id, user)
|
||||
return carrier
|
||||
|
||||
|
||||
@@ -128,7 +131,7 @@ def update_carrier(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> CarrierRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
carrier = _get_carrier(db, tenant_no, id)
|
||||
carrier = _get_carrier(db, tenant_no, id, user)
|
||||
|
||||
for key, value in payload.model_dump(exclude_unset=True).items():
|
||||
setattr(carrier, key, value)
|
||||
@@ -146,13 +149,13 @@ def delete_carrier(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> None:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
carrier = _get_carrier(db, tenant_no, id)
|
||||
carrier = _get_carrier(db, tenant_no, id, user)
|
||||
carrier.del_flag = 1
|
||||
carrier.update_by = user.id
|
||||
db.commit()
|
||||
|
||||
|
||||
def _get_carrier(db: Session, tenant_no: str, carrier_id: str) -> PlCarrier:
|
||||
def _get_carrier(db: Session, tenant_no: str, carrier_id: str, user: DbUserContext) -> PlCarrier:
|
||||
carrier = (
|
||||
db.query(PlCarrier)
|
||||
.filter(
|
||||
@@ -164,6 +167,7 @@ def _get_carrier(db: Session, tenant_no: str, carrier_id: str) -> PlCarrier:
|
||||
)
|
||||
if not carrier:
|
||||
raise HTTPException(status_code=404, detail="承运商不存在")
|
||||
assert_pl_row_in_scope(db, carrier, PlCarrier, user, tenant_no)
|
||||
return carrier
|
||||
|
||||
|
||||
@@ -229,6 +233,8 @@ def list_vehicles(
|
||||
if q:
|
||||
query = query.filter(PlVehicle.license_plate.contains(q))
|
||||
|
||||
query = apply_pl_scope(query, PlVehicle, user, db, tenant_no)
|
||||
|
||||
query = query.order_by(
|
||||
case((PlVehicle.order_num.is_(None), 1), else_=0).asc(),
|
||||
PlVehicle.create_time.desc(),
|
||||
@@ -269,6 +275,7 @@ def create_vehicle(
|
||||
carrier_id=payload.carrier_id,
|
||||
carrier_name=payload.carrier_name,
|
||||
license_plate=payload.license_plate,
|
||||
trailer_no=payload.trailer_no,
|
||||
load_capacity=payload.load_capacity,
|
||||
vehicle_status=payload.vehicle_status,
|
||||
remark=payload.remark,
|
||||
@@ -315,7 +322,7 @@ def get_vehicle(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> VehicleDetailRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
vehicle = _get_vehicle(db, tenant_no, id)
|
||||
vehicle = _get_vehicle(db, tenant_no, id, user)
|
||||
return _vehicle_to_detail(db, tenant_no, vehicle)
|
||||
|
||||
|
||||
@@ -327,7 +334,7 @@ def update_vehicle(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> VehicleDetailRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
vehicle = _get_vehicle(db, tenant_no, id)
|
||||
vehicle = _get_vehicle(db, tenant_no, id, user)
|
||||
|
||||
personnel_list = payload.personnel_list
|
||||
cert_list = payload.cert_list
|
||||
@@ -379,13 +386,13 @@ def delete_vehicle(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> None:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
vehicle = _get_vehicle(db, tenant_no, id)
|
||||
vehicle = _get_vehicle(db, tenant_no, id, user)
|
||||
vehicle.del_flag = 1
|
||||
vehicle.update_by = user.id
|
||||
db.commit()
|
||||
|
||||
|
||||
def _get_vehicle(db: Session, tenant_no: str, vehicle_id: str) -> PlVehicle:
|
||||
def _get_vehicle(db: Session, tenant_no: str, vehicle_id: str, user: DbUserContext) -> PlVehicle:
|
||||
vehicle = (
|
||||
db.query(PlVehicle)
|
||||
.filter(
|
||||
@@ -397,6 +404,7 @@ def _get_vehicle(db: Session, tenant_no: str, vehicle_id: str) -> PlVehicle:
|
||||
)
|
||||
if not vehicle:
|
||||
raise HTTPException(status_code=404, detail="车辆不存在")
|
||||
assert_pl_row_in_scope(db, vehicle, PlVehicle, user, tenant_no)
|
||||
return vehicle
|
||||
|
||||
|
||||
@@ -451,6 +459,8 @@ def list_personnel(
|
||||
)
|
||||
)
|
||||
|
||||
query = apply_pl_scope(query, PlPersonnel, user, db, tenant_no)
|
||||
|
||||
query = query.order_by(
|
||||
case((PlPersonnel.order_num.is_(None), 1), else_=0).asc(),
|
||||
PlPersonnel.create_time.desc(),
|
||||
@@ -508,7 +518,7 @@ def get_personnel(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> PersonnelDetailRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
personnel = _get_personnel(db, tenant_no, id)
|
||||
personnel = _get_personnel(db, tenant_no, id, user)
|
||||
return _personnel_to_detail(db, tenant_no, personnel)
|
||||
|
||||
|
||||
@@ -520,7 +530,7 @@ def update_personnel(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> PersonnelDetailRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
personnel = _get_personnel(db, tenant_no, id)
|
||||
personnel = _get_personnel(db, tenant_no, id, user)
|
||||
|
||||
cert_list = payload.cert_list
|
||||
data = payload.model_dump(exclude_unset=True, exclude={"cert_list"})
|
||||
@@ -557,13 +567,13 @@ def delete_personnel(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> None:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
personnel = _get_personnel(db, tenant_no, id)
|
||||
personnel = _get_personnel(db, tenant_no, id, user)
|
||||
personnel.del_flag = 1
|
||||
personnel.update_by = user.id
|
||||
db.commit()
|
||||
|
||||
|
||||
def _get_personnel(db: Session, tenant_no: str, personnel_id: str) -> PlPersonnel:
|
||||
def _get_personnel(db: Session, tenant_no: str, personnel_id: str, user: DbUserContext) -> PlPersonnel:
|
||||
personnel = (
|
||||
db.query(PlPersonnel)
|
||||
.filter(
|
||||
@@ -575,6 +585,7 @@ def _get_personnel(db: Session, tenant_no: str, personnel_id: str) -> PlPersonne
|
||||
)
|
||||
if not personnel:
|
||||
raise HTTPException(status_code=404, detail="人员不存在")
|
||||
assert_pl_row_in_scope(db, personnel, PlPersonnel, user, tenant_no)
|
||||
return personnel
|
||||
|
||||
|
||||
@@ -621,6 +632,8 @@ def list_drivers(
|
||||
)
|
||||
)
|
||||
|
||||
query = apply_pl_scope(query, PlPersonnel, user, db, tenant_no)
|
||||
|
||||
query = query.order_by(
|
||||
case((PlPersonnel.order_num.is_(None), 1), else_=0).asc(),
|
||||
PlPersonnel.create_time.desc(),
|
||||
@@ -660,7 +673,7 @@ def get_driver(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> DriverRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
personnel = _get_personnel(db, tenant_no, id)
|
||||
personnel = _get_personnel(db, tenant_no, id, user)
|
||||
return _personnel_to_driver_read(personnel)
|
||||
|
||||
|
||||
@@ -672,7 +685,7 @@ def update_driver(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> DriverRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
personnel = _get_personnel(db, tenant_no, id)
|
||||
personnel = _get_personnel(db, tenant_no, id, user)
|
||||
|
||||
if payload.driver_name is not None:
|
||||
personnel.personnel_name = payload.driver_name
|
||||
@@ -696,7 +709,7 @@ def delete_driver(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> None:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
personnel = _get_personnel(db, tenant_no, id)
|
||||
personnel = _get_personnel(db, tenant_no, id, user)
|
||||
personnel.del_flag = 1
|
||||
personnel.update_by = user.id
|
||||
db.commit()
|
||||
@@ -714,6 +727,8 @@ def bind_vehicle_driver(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> dict:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
_get_vehicle(db, tenant_no, payload.vehicle_id, user)
|
||||
_get_personnel(db, tenant_no, payload.driver_id, user)
|
||||
|
||||
if payload.is_default == 1:
|
||||
db.query(PlVehiclePersonnel).filter(
|
||||
@@ -764,5 +779,9 @@ def unbind_vehicle_driver(
|
||||
.first()
|
||||
)
|
||||
if vd:
|
||||
if isinstance(vd, PlVehiclePersonnel):
|
||||
assert_pl_row_in_scope(db, vd, PlVehiclePersonnel, user, tenant_no)
|
||||
else:
|
||||
assert_pl_row_in_scope(db, vd, PlVehicleDriver, user, tenant_no)
|
||||
vd.del_flag = 1
|
||||
db.commit()
|
||||
@@ -47,6 +47,7 @@ def _generate_settlement_no(db: Session) -> str:
|
||||
@router.get("/unsettled-plans", response_model=UnsettledPlanListResponse)
|
||||
def list_unsettled_plans(
|
||||
q: Optional[str] = Query(default=None),
|
||||
carrier_id: Optional[str] = Query(default=None, alias="carrierId"),
|
||||
plan_type: Optional[str] = Query(default=None, alias="planType"),
|
||||
license_plate: Optional[str] = Query(default=None, alias="licensePlate"),
|
||||
page: int = Query(default=1, ge=1),
|
||||
@@ -58,7 +59,9 @@ def list_unsettled_plans(
|
||||
total, items = freight_svc.list_unsettled_plans(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
user=user,
|
||||
q=q,
|
||||
carrier_id=carrier_id,
|
||||
plan_type=plan_type,
|
||||
license_plate=license_plate,
|
||||
page=page,
|
||||
@@ -70,8 +73,12 @@ def list_unsettled_plans(
|
||||
@router.get("/", response_model=FreightSettlementListResponse)
|
||||
def list_settlements(
|
||||
q: Optional[str] = Query(default=None),
|
||||
carrier_id: Optional[str] = Query(default=None, alias="carrierId"),
|
||||
settlement_status: Optional[str] = Query(default=None, alias="settlementStatus"),
|
||||
tab: Optional[str] = Query(default=None, description="bills|disburse|settled"),
|
||||
tab: Optional[str] = Query(
|
||||
default=None,
|
||||
description="bills|approval_pending|approval_done|disburse|settled",
|
||||
),
|
||||
page: int = Query(default=1, ge=1),
|
||||
page_size: int = Query(default=20, ge=1, le=100, alias="pageSize"),
|
||||
db: Session = Depends(get_db),
|
||||
@@ -82,7 +89,9 @@ def list_settlements(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
user_id=user.id,
|
||||
user=user,
|
||||
q=q,
|
||||
carrier_id=carrier_id,
|
||||
settlement_status=settlement_status,
|
||||
tab=tab,
|
||||
page=page,
|
||||
@@ -118,7 +127,7 @@ def get_settlement(
|
||||
) -> FreightSettlementWithTransports:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
detail = freight_svc.get_settlement_detail(
|
||||
db, tenant_no=tenant_no, settlement_id=id, user_id=user.id
|
||||
db, tenant_no=tenant_no, settlement_id=id, user_id=user.id, user=user
|
||||
)
|
||||
return FreightSettlementWithTransports.model_validate(detail)
|
||||
|
||||
@@ -132,7 +141,12 @@ def update_settlement(
|
||||
) -> FreightSettlementRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
return freight_svc.update_settlement_draft(
|
||||
db, tenant_no=tenant_no, settlement_id=id, payload=payload, user_id=user.id
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
settlement_id=id,
|
||||
payload=payload,
|
||||
user_id=user.id,
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@@ -144,7 +158,7 @@ def delete_settlement(
|
||||
) -> None:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
freight_svc.delete_draft_settlement(
|
||||
db, tenant_no=tenant_no, settlement_id=id, user_id=user.id
|
||||
db, tenant_no=tenant_no, settlement_id=id, user_id=user.id, user=user
|
||||
)
|
||||
|
||||
|
||||
@@ -163,6 +177,7 @@ def submit_settlement_approval(
|
||||
body=payload,
|
||||
user_id=user.id,
|
||||
dept_id=user.dept_id,
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@@ -194,7 +209,7 @@ def withdraw_settlement_approval(
|
||||
) -> FreightSettlementRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
return freight_svc.withdraw_settlement_approval(
|
||||
db, tenant_no=tenant_no, settlement_id=id, user_id=user.id
|
||||
db, tenant_no=tenant_no, settlement_id=id, user_id=user.id, user=user
|
||||
)
|
||||
|
||||
|
||||
@@ -205,7 +220,7 @@ def get_settlement_approval_flow(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
):
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
freight_svc.get_settlement_row(db, tenant_no, id)
|
||||
freight_svc.get_settlement_row(db, tenant_no, id, user=user)
|
||||
return freight_svc.get_approval_flow(db, id)
|
||||
|
||||
|
||||
@@ -224,6 +239,7 @@ def disburse_settlement(
|
||||
body=payload,
|
||||
user_id=user.id,
|
||||
dept_id=user.dept_id,
|
||||
user=user,
|
||||
)
|
||||
|
||||
|
||||
@@ -253,8 +269,8 @@ def list_vouchers(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> list[RemittanceVoucherRead]:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
freight_svc.get_settlement_row(db, tenant_no, settlement_id)
|
||||
freight_svc.get_settlement_row(db, tenant_no, settlement_id, user=user)
|
||||
detail = freight_svc.get_settlement_detail(
|
||||
db, tenant_no=tenant_no, settlement_id=settlement_id, user_id=user.id
|
||||
db, tenant_no=tenant_no, settlement_id=settlement_id, user_id=user.id, user=user
|
||||
)
|
||||
return detail.get("vouchers") or []
|
||||
@@ -9,6 +9,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.db_auth import DbUserContext, get_db_current_user
|
||||
from app.services.pl_data_scope import apply_pl_scope, assert_pl_row_in_scope
|
||||
from app.core.tenant_context import get_tenant_no
|
||||
from app.core.utils import generate_uuid
|
||||
from app.models.pl_models import (
|
||||
@@ -61,6 +62,8 @@ def get_inventory_ledger(
|
||||
if product_name:
|
||||
query = query.filter(PlInventory.product_name.contains(product_name))
|
||||
|
||||
query = apply_pl_scope(query, PlInventory, user, db, tenant_no)
|
||||
|
||||
total = query.count()
|
||||
offset = (page - 1) * page_size
|
||||
items = query.order_by(PlInventory.product_name).offset(offset).limit(page_size).all()
|
||||
@@ -92,6 +95,7 @@ def set_warning_threshold(
|
||||
)
|
||||
|
||||
if inventory:
|
||||
assert_pl_row_in_scope(db, inventory, PlInventory, user, tenant_no)
|
||||
inventory.low_stock_warning = payload.low_stock_warning
|
||||
inventory.high_stock_warning = payload.high_stock_warning
|
||||
else:
|
||||
@@ -136,6 +140,7 @@ def list_warnings(
|
||||
if status:
|
||||
query = query.filter(PlInventoryWarning.status == status)
|
||||
|
||||
query = apply_pl_scope(query, PlInventoryWarning, user, db, tenant_no)
|
||||
return query.order_by(PlInventoryWarning.create_time.desc()).all()
|
||||
|
||||
|
||||
@@ -160,6 +165,7 @@ def update_warning(
|
||||
|
||||
if not warning:
|
||||
raise HTTPException(status_code=404, detail="预警不存在")
|
||||
assert_pl_row_in_scope(db, warning, PlInventoryWarning, user, tenant_no)
|
||||
|
||||
if payload.status == "resolved":
|
||||
warning.status = "resolved"
|
||||
@@ -207,6 +213,8 @@ def list_transactions(
|
||||
if date_to:
|
||||
query = query.filter(PlInventoryTransaction.create_time <= date_to)
|
||||
|
||||
query = apply_pl_scope(query, PlInventoryTransaction, user, db, tenant_no)
|
||||
|
||||
total = query.count()
|
||||
offset = (page - 1) * page_size
|
||||
items = query.order_by(PlInventoryTransaction.create_time.desc()).offset(offset).limit(page_size).all()
|
||||
@@ -236,6 +244,7 @@ def get_summary(
|
||||
PlInventoryTransaction.create_time >= date_from,
|
||||
PlInventoryTransaction.create_time <= date_to,
|
||||
)
|
||||
query = apply_pl_scope(query, PlInventoryTransaction, user, db, tenant_no)
|
||||
|
||||
if product_id:
|
||||
query = query.filter(PlInventoryTransaction.product_id == product_id)
|
||||
@@ -295,6 +304,7 @@ def list_document_reminders(
|
||||
if status:
|
||||
query = query.filter(PlDocumentReminder.status == status)
|
||||
|
||||
query = apply_pl_scope(query, PlDocumentReminder, user, db, tenant_no)
|
||||
return query.order_by(PlDocumentReminder.expire_date.asc()).all()
|
||||
|
||||
|
||||
@@ -319,6 +329,7 @@ def update_document_reminder(
|
||||
|
||||
if not reminder:
|
||||
raise HTTPException(status_code=404, detail="提醒不存在")
|
||||
assert_pl_row_in_scope(db, reminder, PlDocumentReminder, user, tenant_no)
|
||||
|
||||
reminder.status = payload.status
|
||||
if payload.remark:
|
||||
|
||||
+14
-10
@@ -9,6 +9,7 @@ from sqlalchemy.orm import Session
|
||||
from app.core.config import settings
|
||||
from app.core.database import get_db
|
||||
from app.core.db_auth import DbUserContext, get_db_current_user
|
||||
from app.services.pl_data_scope import apply_pl_scope, assert_pl_row_in_scope
|
||||
from app.core.tenant_context import get_tenant_no
|
||||
from app.core.utils import generate_uuid
|
||||
from app.models.crm_models import CrmContract, CrmContractProduct, CrmProduct
|
||||
@@ -171,6 +172,8 @@ def list_plans(
|
||||
if plan_date_to:
|
||||
query = query.filter(PlPlan.plan_date <= plan_date_to)
|
||||
|
||||
query = apply_pl_scope(query, PlPlan, user, db, tenant_no)
|
||||
|
||||
# 统计总数
|
||||
total = query.count()
|
||||
|
||||
@@ -234,9 +237,8 @@ def count_plans_by_contract(
|
||||
PlPlan.del_flag == 0,
|
||||
PlPlan.contract_id.in_(ids),
|
||||
)
|
||||
.group_by(PlPlan.contract_id)
|
||||
.all()
|
||||
)
|
||||
rows = apply_pl_scope(rows, PlPlan, user, db, tenant_no).group_by(PlPlan.contract_id).all()
|
||||
return {"counts": {contract_id: count for contract_id, count in rows}}
|
||||
|
||||
|
||||
@@ -544,7 +546,7 @@ def get_plan(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> PlanWithProducts:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
|
||||
products = (
|
||||
db.query(PlPlanProduct)
|
||||
@@ -588,7 +590,7 @@ def update_plan(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> PlanRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
|
||||
# 更新主表字段
|
||||
update_data = payload.model_dump(exclude_unset=True, exclude={"products", "transport"})
|
||||
@@ -698,6 +700,7 @@ def patch_plan_product_certs(
|
||||
) -> PlanWithProducts:
|
||||
"""更新计划危化品产品购买证/运输证(不触发安排运输)"""
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
_get_plan(db, tenant_no, id, user)
|
||||
update_plan_product_certs(
|
||||
db,
|
||||
tenant_no=tenant_no,
|
||||
@@ -705,7 +708,7 @@ def patch_plan_product_certs(
|
||||
items=payload.products,
|
||||
user_id=user.id,
|
||||
)
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
products = (
|
||||
db.query(PlPlanProduct)
|
||||
.filter(
|
||||
@@ -733,7 +736,7 @@ def get_plan_arrange_info(
|
||||
) -> PlanArrangeInfoRead:
|
||||
"""获取计划已安排运输后的司机链接与地磅出入库关联(供查看弹窗复制简述/二维码)。"""
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
|
||||
empty = PlanArrangeInfoRead(driver_url=None, license_plate=None, site_records=[], inventory_records=[])
|
||||
if plan.follow_status == "cancelled" or plan.transport_status != "arranged" or not plan.transport_id:
|
||||
@@ -847,7 +850,7 @@ def cancel_plan(
|
||||
) -> PlanRead:
|
||||
"""作废运输计划:取消跟进状态、作废关联地磅出入库单、取消运输单。"""
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
|
||||
if plan.follow_status == "cancelled":
|
||||
raise HTTPException(status_code=400, detail="计划已作废")
|
||||
@@ -905,7 +908,7 @@ def archive_plan(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> PlanWithProducts:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
|
||||
if plan.follow_status == "cancelled":
|
||||
raise HTTPException(status_code=400, detail="已作废的计划不能归档")
|
||||
@@ -965,7 +968,7 @@ def delete_plan(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> None:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
plan = _get_plan(db, tenant_no, id)
|
||||
plan = _get_plan(db, tenant_no, id, user)
|
||||
|
||||
plan.del_flag = 1
|
||||
plan.update_by = user.id
|
||||
@@ -990,7 +993,7 @@ def delete_plan(
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def _get_plan(db: Session, tenant_no: str, plan_id: str) -> PlPlan:
|
||||
def _get_plan(db: Session, tenant_no: str, plan_id: str, user: DbUserContext) -> PlPlan:
|
||||
plan = (
|
||||
db.query(PlPlan)
|
||||
.filter(
|
||||
@@ -1002,4 +1005,5 @@ def _get_plan(db: Session, tenant_no: str, plan_id: str) -> PlPlan:
|
||||
)
|
||||
if not plan:
|
||||
raise HTTPException(status_code=404, detail="计划不存在")
|
||||
assert_pl_row_in_scope(db, plan, PlPlan, user, tenant_no)
|
||||
return plan
|
||||
@@ -11,6 +11,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.db_auth import DbUserContext, get_db_current_user
|
||||
from app.services.pl_data_scope import apply_pl_scope, assert_pl_row_in_scope
|
||||
from app.core.tenant_context import get_tenant_no
|
||||
from app.core.utils import generate_uuid
|
||||
from app.core.config import settings
|
||||
@@ -334,6 +335,8 @@ def list_transports(
|
||||
if driver_id:
|
||||
query = query.filter(PlTransport.driver_id == driver_id)
|
||||
|
||||
query = apply_pl_scope(query, PlTransport, user, db, tenant_no)
|
||||
|
||||
total = query.count()
|
||||
offset = (page - 1) * page_size
|
||||
transports = query.order_by(PlTransport.create_time.desc()).offset(offset).limit(page_size).all()
|
||||
@@ -401,6 +404,7 @@ def create_transport(
|
||||
# 更新计划关联的运输信息
|
||||
plan = db.query(PlPlan).filter(PlPlan.id == pid, PlPlan.del_flag == 0).first()
|
||||
if plan:
|
||||
assert_pl_row_in_scope(db, plan, PlPlan, user, tenant_no)
|
||||
plan.transport_id = transport.id
|
||||
plan.transport_no = transport_no
|
||||
plan.vehicle_id = transport.vehicle_id
|
||||
@@ -435,6 +439,7 @@ def arrange_transport(
|
||||
).first()
|
||||
if not plan:
|
||||
raise HTTPException(status_code=404, detail="计划不存在")
|
||||
assert_pl_row_in_scope(db, plan, PlPlan, user, tenant_no)
|
||||
|
||||
# 获取车辆信息
|
||||
vehicle_info = _get_vehicle_info(db, payload.vehicle_id, tenant_no)
|
||||
@@ -655,7 +660,7 @@ def get_transport(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> TransportRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
transport = _get_transport(db, tenant_no, id)
|
||||
transport = _get_transport(db, tenant_no, id, user)
|
||||
return transport
|
||||
|
||||
|
||||
@@ -681,7 +686,7 @@ def generate_qrcode(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> QrCodeResponse:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
transport = _get_transport(db, tenant_no, id)
|
||||
transport = _get_transport(db, tenant_no, id, user)
|
||||
|
||||
from datetime import timedelta
|
||||
expire_date = date.today() + timedelta(days=expire_days)
|
||||
@@ -755,7 +760,7 @@ def submit_approval(
|
||||
user: DbUserContext = Depends(get_db_current_user),
|
||||
) -> TransportRead:
|
||||
tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
|
||||
transport = _get_transport(db, tenant_no, id)
|
||||
transport = _get_transport(db, tenant_no, id, user)
|
||||
|
||||
if transport.approval_status not in ("none", "rejected"):
|
||||
raise HTTPException(status_code=400, detail="当前状态不允许提交审批")
|
||||
@@ -880,7 +885,7 @@ def get_transport_approvals(
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def _get_transport(db: Session, tenant_no: str, transport_id: str) -> PlTransport:
|
||||
def _get_transport(db: Session, tenant_no: str, transport_id: str, user: DbUserContext) -> PlTransport:
|
||||
transport = (
|
||||
db.query(PlTransport)
|
||||
.filter(
|
||||
@@ -892,4 +897,5 @@ def _get_transport(db: Session, tenant_no: str, transport_id: str) -> PlTranspor
|
||||
)
|
||||
if not transport:
|
||||
raise HTTPException(status_code=404, detail="运输不存在")
|
||||
assert_pl_row_in_scope(db, transport, PlTransport, user, tenant_no)
|
||||
return transport
|
||||
Reference in new issue
Block a user