attribution_repositories.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. from sqlalchemy import select
  2. from app.domains.attribution.models import (
  3. LeadAttribution,
  4. OrderAttribution,
  5. PromotionCode,
  6. Salesperson,
  7. )
  8. from app.domains.attribution.repository import AttributionRepository
  9. from app.infrastructure.mysql.core_models import (
  10. LeadAttributionRecord,
  11. OrderAttributionRecord,
  12. PromotionCodeRecord,
  13. SalespersonRecord,
  14. )
  15. from app.infrastructure.mysql.repositories import SessionFactory
  16. class SqlAlchemyAttributionRepository(AttributionRepository):
  17. def __init__(self, session_factory: SessionFactory) -> None:
  18. self._session_factory = session_factory
  19. def save_salesperson(self, salesperson: Salesperson) -> None:
  20. with self._session_factory() as session:
  21. session.merge(
  22. SalespersonRecord(
  23. id=salesperson.id,
  24. admin_user_id=salesperson.admin_user_id,
  25. salesperson_code=salesperson.code,
  26. name=salesperson.name,
  27. status=salesperson.status,
  28. created_at=salesperson.created_at,
  29. )
  30. )
  31. session.commit()
  32. def list_salespersons(self) -> list[Salesperson]:
  33. with self._session_factory() as session:
  34. records = session.scalars(
  35. select(SalespersonRecord).order_by(SalespersonRecord.salesperson_code)
  36. ).all()
  37. return [
  38. Salesperson(
  39. id=item.id,
  40. admin_user_id=item.admin_user_id,
  41. code=item.salesperson_code,
  42. name=item.name,
  43. status=item.status,
  44. created_at=item.created_at,
  45. )
  46. for item in records
  47. ]
  48. def save_promotion_code(self, promotion_code: PromotionCode) -> None:
  49. with self._session_factory() as session:
  50. session.merge(
  51. PromotionCodeRecord(
  52. id=promotion_code.id,
  53. code=promotion_code.code,
  54. salesperson_id=promotion_code.salesperson_id,
  55. channel=promotion_code.channel,
  56. status=promotion_code.status,
  57. created_at=promotion_code.created_at,
  58. )
  59. )
  60. session.commit()
  61. def get_promotion_code(self, code: str) -> PromotionCode | None:
  62. with self._session_factory() as session:
  63. record = session.scalar(
  64. select(PromotionCodeRecord).where(PromotionCodeRecord.code == code.upper())
  65. )
  66. return self._code(record) if record else None
  67. def list_promotion_codes(self) -> list[PromotionCode]:
  68. with self._session_factory() as session:
  69. records = session.scalars(
  70. select(PromotionCodeRecord).order_by(PromotionCodeRecord.code)
  71. ).all()
  72. return [self._code(item) for item in records]
  73. def save_lead(self, lead: LeadAttribution) -> None:
  74. with self._session_factory() as session:
  75. session.merge(
  76. LeadAttributionRecord(
  77. id=lead.id,
  78. h5_user_id=lead.h5_user_id,
  79. salesperson_id=lead.salesperson_id,
  80. promotion_code_id=lead.promotion_code_id,
  81. source_code=lead.source_code,
  82. visit_count=lead.visit_count,
  83. first_touch_at=lead.first_touch_at,
  84. last_touch_at=lead.last_touch_at,
  85. )
  86. )
  87. session.commit()
  88. def get_lead_by_user(self, h5_user_id: str) -> LeadAttribution | None:
  89. with self._session_factory() as session:
  90. record = session.scalar(
  91. select(LeadAttributionRecord).where(LeadAttributionRecord.h5_user_id == h5_user_id)
  92. )
  93. return self._lead(record) if record else None
  94. def list_leads(self) -> list[LeadAttribution]:
  95. with self._session_factory() as session:
  96. records = session.scalars(select(LeadAttributionRecord)).all()
  97. return [self._lead(item) for item in records]
  98. def save_order_attribution(self, attribution: OrderAttribution) -> None:
  99. with self._session_factory() as session:
  100. session.merge(
  101. OrderAttributionRecord(
  102. id=attribution.id,
  103. order_id=attribution.order_id,
  104. h5_user_id=attribution.h5_user_id,
  105. salesperson_id=attribution.salesperson_id,
  106. promotion_code_id=attribution.promotion_code_id,
  107. source_code=attribution.source_code,
  108. amount_cents=attribution.amount_cents,
  109. attributed_at=attribution.attributed_at,
  110. )
  111. )
  112. session.commit()
  113. def get_order_attribution(self, order_id: str) -> OrderAttribution | None:
  114. with self._session_factory() as session:
  115. record = session.scalar(
  116. select(OrderAttributionRecord).where(OrderAttributionRecord.order_id == order_id)
  117. )
  118. return self._order(record) if record else None
  119. def list_order_attributions(self) -> list[OrderAttribution]:
  120. with self._session_factory() as session:
  121. records = session.scalars(select(OrderAttributionRecord)).all()
  122. return [self._order(item) for item in records]
  123. @staticmethod
  124. def _code(record: PromotionCodeRecord) -> PromotionCode:
  125. return PromotionCode(
  126. id=record.id,
  127. code=record.code,
  128. salesperson_id=record.salesperson_id,
  129. channel=record.channel,
  130. status=record.status,
  131. created_at=record.created_at,
  132. )
  133. @staticmethod
  134. def _lead(record: LeadAttributionRecord) -> LeadAttribution:
  135. return LeadAttribution(
  136. id=record.id,
  137. h5_user_id=record.h5_user_id,
  138. salesperson_id=record.salesperson_id,
  139. promotion_code_id=record.promotion_code_id,
  140. source_code=record.source_code,
  141. visit_count=record.visit_count,
  142. first_touch_at=record.first_touch_at,
  143. last_touch_at=record.last_touch_at,
  144. )
  145. @staticmethod
  146. def _order(record: OrderAttributionRecord) -> OrderAttribution:
  147. return OrderAttribution(
  148. id=record.id,
  149. order_id=record.order_id,
  150. h5_user_id=record.h5_user_id,
  151. salesperson_id=record.salesperson_id,
  152. promotion_code_id=record.promotion_code_id,
  153. source_code=record.source_code,
  154. amount_cents=record.amount_cents,
  155. attributed_at=record.attributed_at,
  156. )