quotation.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. """报价单CRUD"""
  2. from decimal import Decimal
  3. from typing import Optional, List
  4. from sqlalchemy.orm import Session
  5. from sqlalchemy import and_, func
  6. from app.models.models import BizQuotation, BizQuotationItem, BizQuotationHis, BizQuotationItemHis
  7. from app.crud.base import CRUDBase
  8. from app.core.utils import generate_id
  9. class QuotationCRUD(CRUDBase[BizQuotation]):
  10. """报价单CRUD操作"""
  11. def get_by_inquiry(self, db: Session, inquiry_id: str) -> List[BizQuotation]:
  12. """根据询价单获取报价列表"""
  13. return db.query(BizQuotation).filter(
  14. and_(
  15. BizQuotation.inquiry_id == inquiry_id,
  16. BizQuotation.is_del == 0
  17. )
  18. ).all()
  19. def get_by_supplier(self, db: Session, supplier_id: str) -> List[BizQuotation]:
  20. """根据供应商获取报价列表"""
  21. return db.query(BizQuotation).filter(
  22. and_(
  23. BizQuotation.supplier_id == supplier_id,
  24. BizQuotation.is_del == 0
  25. )
  26. ).order_by(BizQuotation.create_at.desc()).all()
  27. def get_by_inquiry_and_supplier(
  28. self,
  29. db: Session,
  30. inquiry_id: str,
  31. supplier_id: str
  32. ) -> Optional[BizQuotation]:
  33. """根据询价单和供应商获取报价"""
  34. return db.query(BizQuotation).filter(
  35. and_(
  36. BizQuotation.inquiry_id == inquiry_id,
  37. BizQuotation.supplier_id == supplier_id,
  38. BizQuotation.is_del == 0
  39. )
  40. ).first()
  41. def get_latest_by_inquiry_and_supplier(
  42. self,
  43. db: Session,
  44. inquiry_id: str,
  45. supplier_id: str
  46. ) -> Optional[BizQuotation]:
  47. """获取某供应商在某询价单下最新一次报价"""
  48. return db.query(BizQuotation).filter(
  49. and_(
  50. BizQuotation.inquiry_id == inquiry_id,
  51. BizQuotation.supplier_id == supplier_id,
  52. BizQuotation.is_del == 0
  53. )
  54. ).order_by(BizQuotation.create_at.desc()).first()
  55. def get_multi_with_filters(
  56. self,
  57. db: Session,
  58. inquiry_id: str = None,
  59. supplier_id: str = None,
  60. region_id: str = None,
  61. status: str = None,
  62. skip: int = 0,
  63. limit: int = 10
  64. ) -> tuple[List[BizQuotation], int]:
  65. """多条件查询报价单"""
  66. query = db.query(BizQuotation).filter(BizQuotation.is_del == 0)
  67. if inquiry_id:
  68. query = query.filter(BizQuotation.inquiry_id == inquiry_id)
  69. if supplier_id:
  70. query = query.filter(BizQuotation.supplier_id == supplier_id)
  71. if region_id:
  72. query = query.filter(BizQuotation.region_id == region_id)
  73. if status:
  74. query = query.filter(BizQuotation.status == status)
  75. total = query.count()
  76. quotations = query.order_by(BizQuotation.create_at.desc()).offset(skip).limit(limit).all()
  77. return quotations, total
  78. def update_with_history(self, db: Session, id: str, obj_in: dict, updater: dict = None) -> Optional[BizQuotation]:
  79. """更新报价单并记录历史"""
  80. original = self.get(db, id)
  81. if not original:
  82. return None
  83. his_data = {
  84. "id": original.id,
  85. "inquiry_id": original.inquiry_id,
  86. "supplier_id": original.supplier_id,
  87. "region_id": original.region_id,
  88. "status": original.status,
  89. "total_amount": original.total_amount,
  90. "submit_time": original.submit_time,
  91. "create_at": original.create_at,
  92. "create_by": original.create_by,
  93. "create_name": original.create_name,
  94. "update_at": original.update_at,
  95. "update_by": original.update_by,
  96. }
  97. his = BizQuotationHis(**his_data)
  98. db.add(his)
  99. return self.update(db, id, obj_in, updater)
  100. def soft_delete_with_history(self, db: Session, id: str) -> bool:
  101. """删除报价单并记录历史"""
  102. original = self.get(db, id)
  103. if not original:
  104. return False
  105. his_data = {
  106. "id": original.id,
  107. "inquiry_id": original.inquiry_id,
  108. "supplier_id": original.supplier_id,
  109. "region_id": original.region_id,
  110. "status": original.status,
  111. "total_amount": original.total_amount,
  112. "submit_time": original.submit_time,
  113. "create_at": original.create_at,
  114. "create_by": original.create_by,
  115. "create_name": original.create_name,
  116. "update_at": original.update_at,
  117. "update_by": original.update_by,
  118. }
  119. his = BizQuotationHis(**his_data)
  120. db.add(his)
  121. return self.delete(db, id)
  122. class QuotationItemCRUD(CRUDBase[BizQuotationItem]):
  123. """报价单项CRUD操作"""
  124. def get_by_quotation(self, db: Session, quotation_id: str) -> List[BizQuotationItem]:
  125. """获取报价单的所有报价项"""
  126. return db.query(BizQuotationItem).filter(
  127. and_(
  128. BizQuotationItem.quotation_id == quotation_id,
  129. BizQuotationItem.is_del == 0
  130. )
  131. ).all()
  132. def get_multi_by_quotations(
  133. self,
  134. db: Session,
  135. quotation_ids: List[str]
  136. ) -> List[BizQuotationItem]:
  137. """根据多个报价单ID获取报价项"""
  138. return db.query(BizQuotationItem).filter(
  139. and_(
  140. BizQuotationItem.quotation_id.in_(quotation_ids),
  141. BizQuotationItem.is_del == 0
  142. )
  143. ).all()
  144. def create_items(
  145. self,
  146. db: Session,
  147. quotation_id: str,
  148. items: List[dict],
  149. creator: dict = None
  150. ) -> List[BizQuotationItem]:
  151. """批量创建报价项"""
  152. result = []
  153. for item in items:
  154. quotation_item = BizQuotationItem(
  155. id=generate_id(),
  156. quotation_id=quotation_id,
  157. product_id=item.get("product_id"),
  158. unit_id=item.get("unit_id"),
  159. price=Decimal(str(item.get("price", 0))),
  160. create_by=creator.get("user_id") if creator else None,
  161. create_name=creator.get("real_name") if creator else None
  162. )
  163. db.add(quotation_item)
  164. result.append(quotation_item)
  165. db.commit()
  166. for item in result:
  167. db.refresh(item)
  168. return result
  169. def delete_by_quotation(self, db: Session, quotation_id: str) -> bool:
  170. """删除报价单的所有报价项"""
  171. items = self.get_by_quotation(db, quotation_id)
  172. for item in items:
  173. item.is_del = 1
  174. db.commit()
  175. return True
  176. quotation_crud = QuotationCRUD(BizQuotation)
  177. quotation_item_crud = QuotationItemCRUD(BizQuotationItem)