116 lines
4.5 KiB
Python
116 lines
4.5 KiB
Python
from typing import Dict, Any
|
|
from fastapi import APIRouter, Depends, Request, Body
|
|
from sqlalchemy.orm import Session
|
|
|
|
from adapters.db.session import get_db
|
|
from app.core.auth_dependency import get_current_user, AuthContext
|
|
from app.core.permissions import require_business_access
|
|
from app.core.responses import success_response
|
|
from adapters.db.models.document import Document
|
|
from adapters.db.models.warehouse_document import WarehouseDocument
|
|
from adapters.db.models.warehouse_document_line import WarehouseDocumentLine
|
|
from app.services.warehouse_service import create_from_invoice, post_warehouse_document, warehouse_document_to_dict
|
|
|
|
|
|
router = APIRouter(prefix="/warehouse-docs", tags=["warehouse_docs"])
|
|
|
|
|
|
@router.post("/business/{business_id}/from-invoice/{invoice_id}")
|
|
@require_business_access("business_id")
|
|
def create_warehouse_doc_from_invoice(
|
|
request: Request,
|
|
business_id: int,
|
|
invoice_id: int,
|
|
payload: Dict[str, Any] = Body(default={}),
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db),
|
|
) -> Dict[str, Any]:
|
|
inv = db.query(Document).filter(Document.id == invoice_id).first()
|
|
if not inv or inv.business_id != business_id:
|
|
from app.core.responses import ApiError
|
|
raise ApiError("DOCUMENT_NOT_FOUND", "Invoice document not found", http_status=404)
|
|
lines = payload.get("lines") or []
|
|
wh_type = payload.get("doc_type") or ("issue" if inv.document_type in ("invoice_sales", "invoice_purchase_return", "invoice_waste", "invoice_direct_consumption") else "receipt")
|
|
wh = create_from_invoice(db, business_id, inv, lines, wh_type, ctx.get_user_id())
|
|
db.commit()
|
|
return success_response(data={"id": wh.id, "code": wh.code, "status": wh.status}, request=request)
|
|
|
|
|
|
@router.post("/business/{business_id}/{wh_id}/post")
|
|
@require_business_access("business_id")
|
|
def post_warehouse_doc_endpoint(
|
|
request: Request,
|
|
business_id: int,
|
|
wh_id: int,
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db),
|
|
) -> Dict[str, Any]:
|
|
res = post_warehouse_document(db, wh_id)
|
|
db.commit()
|
|
return success_response(data=res, request=request)
|
|
|
|
|
|
@router.get("/business/{business_id}/{wh_id}")
|
|
@require_business_access("business_id")
|
|
def get_warehouse_doc(
|
|
request: Request,
|
|
business_id: int,
|
|
wh_id: int,
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db),
|
|
) -> Dict[str, Any]:
|
|
wh = db.query(WarehouseDocument).filter(WarehouseDocument.id == wh_id).first()
|
|
if not wh or wh.business_id != business_id:
|
|
from app.core.responses import ApiError
|
|
raise ApiError("NOT_FOUND", "Warehouse document not found", http_status=404)
|
|
return success_response(data={"item": warehouse_document_to_dict(db, wh)}, request=request)
|
|
|
|
|
|
@router.post("/business/{business_id}/search")
|
|
@require_business_access("business_id")
|
|
def search_warehouse_docs(
|
|
request: Request,
|
|
business_id: int,
|
|
body: Dict[str, Any] = Body(default={}),
|
|
ctx: AuthContext = Depends(get_current_user),
|
|
db: Session = Depends(get_db),
|
|
) -> Dict[str, Any]:
|
|
q = db.query(WarehouseDocument).filter(WarehouseDocument.business_id == business_id)
|
|
# فیلتر ساده بر اساس نوع/وضعیت/تاریخ
|
|
doc_type = body.get("doc_type")
|
|
status = body.get("status")
|
|
source_document_id = body.get("source_document_id")
|
|
source_type = body.get("source_type")
|
|
from_date = body.get("from_date")
|
|
to_date = body.get("to_date")
|
|
try:
|
|
if isinstance(doc_type, str) and doc_type:
|
|
q = q.filter(WarehouseDocument.doc_type == doc_type)
|
|
if isinstance(status, str) and status:
|
|
q = q.filter(WarehouseDocument.status == status)
|
|
if isinstance(source_document_id, int):
|
|
q = q.filter(WarehouseDocument.source_document_id == source_document_id)
|
|
if isinstance(source_type, str) and source_type:
|
|
q = q.filter(WarehouseDocument.source_type == source_type)
|
|
if isinstance(from_date, str) and from_date:
|
|
from app.services.transfer_service import _parse_iso_date as _p
|
|
q = q.filter(WarehouseDocument.document_date >= _p(from_date))
|
|
if isinstance(to_date, str) and to_date:
|
|
from app.services.transfer_service import _parse_iso_date as _p
|
|
q = q.filter(WarehouseDocument.document_date <= _p(to_date))
|
|
except Exception:
|
|
pass
|
|
q = q.order_by(WarehouseDocument.document_date.desc(), WarehouseDocument.id.desc())
|
|
take = int(body.get("take") or 20)
|
|
skip = int(body.get("skip") or 0)
|
|
total = q.count()
|
|
items = q.offset(skip).limit(take).all()
|
|
return success_response(data={
|
|
"items": [warehouse_document_to_dict(db, wh) for wh in items],
|
|
"total": total,
|
|
"page": (skip // max(1, take)) + 1,
|
|
"limit": take,
|
|
}, request=request)
|
|
|
|
|