diff --git a/jituan/services/club_member_admin.py b/jituan/services/club_member_admin.py index c3764ea..62bac72 100644 --- a/jituan/services/club_member_admin.py +++ b/jituan/services/club_member_admin.py @@ -71,6 +71,20 @@ def _format_member(m, price_row=None): return item +def count_club_member_sales(club_id, huiyuan_id, formal_only=True): + """本俱乐部已支付会员单数(用于后台展示,非全局 goumai_cishu)。""" + from products.models import Czjilu + qs = Czjilu.query.filter( + club_id=club_id, + huiyuan_id=huiyuan_id, + leixing=1, + zhuangtai=3, + ) + if formal_only: + qs = qs.filter(is_trial=False) + return qs.count() + + def build_member_list_payload(request): scope = resolve_club_scope(request) club_id = resolve_club_id_from_request(request) @@ -94,7 +108,9 @@ def build_member_list_payload(request): continue if row is not None and not row.is_enabled: continue - member_list.append(_format_member(m, row)) + item = _format_member(m, row) + item['goumai_cishu'] = count_club_member_sales(club_id, m.huiyuan_id) + member_list.append(item) return { 'list': member_list, diff --git a/jituan/services/member_recharge.py b/jituan/services/member_recharge.py index b7ab539..71ec00c 100644 --- a/jituan/services/member_recharge.py +++ b/jituan/services/member_recharge.py @@ -156,6 +156,56 @@ def resolve_member_purchase_cishu(yonghuid, huiyuan_id, current_dingdan_id, club return resolve_formal_purchase_cishu(yonghuid, huiyuan_id, current_dingdan_id, club_id) +def fulfill_member_balance_purchase(czjilu, huiyuan, club_id=None): + """余额抵扣购买会员:按俱乐部配置天数履约,并计入购买次数/分红。""" + club_id = club_id or getattr(czjilu, 'club_id', None) or CLUB_ID_DEFAULT + is_trial = bool(getattr(czjilu, 'is_trial', False)) + purchase_days = int(getattr(czjilu, 'purchase_days', None) or 0) + if purchase_days <= 0: + _, _, purchase_days = club_huiyuan_sellable(club_id, czjilu.huiyuan_id, is_trial=is_trial) + + formal_cishu = None + trial_guanshi_fc = Decimal('0') + trial_zuzhangfc = Decimal('0') + if is_trial: + row = get_club_huiyuan_row(club_id, czjilu.huiyuan_id) + if row: + trial_guanshi_fc = Decimal(str(row.trial_guanshifc or 0)) + trial_zuzhangfc = Decimal(str(row.trial_zuzhangfc or 0)) + else: + formal_cishu = resolve_formal_purchase_cishu( + czjilu.yonghuid, czjilu.huiyuan_id, czjilu.dingdan_id, club_id, + ) + + goumai_record, is_first_buy_any = _apply_huiyuan_entitlement( + czjilu.yonghuid, czjilu.huiyuan_id, huiyuan, club_id, is_trial, purchase_days, + ) + if is_first_buy_any: + _add_first_buy_jifen(czjilu.yonghuid) + + czjilu.zhuangtai = MEMBER_PAID_STATUS + if not czjilu.purchase_days: + czjilu.purchase_days = purchase_days + czjilu.save(update_fields=['zhuangtai', 'purchase_days']) + + huiyuan.goumai_cishu = (huiyuan.goumai_cishu or 0) + 1 + huiyuan.save(update_fields=['goumai_cishu']) + + try: + _apply_member_fenhong( + czjilu, huiyuan, + formal_cishu=formal_cishu, + trial_guanshi_fc=trial_guanshi_fc, + trial_zuzhangfc=trial_zuzhangfc, + ) + except Exception as exc: + logger.error( + '余额购会员分红失败 dingdan=%s: %s', czjilu.dingdan_id, exc, exc_info=True, + ) + + return goumai_record, is_first_buy_any + + def _lookup_duoci_fenhong(club_id, huiyuan_id, beneficiary_id, cishu, field): try: row = DuociFenhong.query.get( diff --git a/products/views.py b/products/views.py index 058693c..68ebdd3 100644 --- a/products/views.py +++ b/products/views.py @@ -5992,34 +5992,36 @@ class DsqrgmdhView(APIView): shuoming = f"{identity['name']}抵扣 {action_desc},抵扣金额{required}元" - czjilu = Czjilu.query.create( - dingdan_id=dingdan_id, - huiyuan_id=huiyuan_id if leixing == 1 else None, - zhuangtai=1, - yonghuid=yonghuid, - jine=required, - leixing=leixing, - shuoming=shuoming, - club_id=club_id, - ) + member_purchase_days = 0 + czjilu_kwargs = { + 'dingdan_id': dingdan_id, + 'zhuangtai': 1, + 'yonghuid': yonghuid, + 'jine': required, + 'leixing': leixing, + 'shuoming': shuoming, + 'club_id': club_id, + } + if leixing == 1: + from jituan.services.member_recharge import club_huiyuan_sellable + _, _, member_purchase_days = club_huiyuan_sellable( + club_id, huiyuan_id, is_trial=False, + ) + czjilu_kwargs.update({ + 'huiyuan_id': huiyuan_id, + 'is_trial': False, + 'purchase_days': member_purchase_days, + }) + + czjilu = Czjilu.query.create(**czjilu_kwargs) response_data = {} if leixing == 1: - huiyuan_record, is_first_buy = self._process_member_purchase( - yonghuid, huiyuan_id, huiyuan, club_id=club_id, + from jituan.services.member_recharge import fulfill_member_balance_purchase + huiyuan_record, is_first_buy = fulfill_member_balance_purchase( + czjilu, huiyuan, club_id=club_id, ) - try: - from jituan.services.member_recharge import ( - resolve_member_purchase_cishu, - _apply_member_fenhong, - ) - purchase_cishu = resolve_member_purchase_cishu( - yonghuid, huiyuan_id, dingdan_id, club_id, - ) - _apply_member_fenhong(czjilu, huiyuan, purchase_cishu) - except Exception as exc: - logger.error('余额购会员分红失败 dingdan=%s: %s', dingdan_id, exc, exc_info=True) response_data['huiyuan'] = { 'huiyuanid': huiyuan_id, 'huiyuanming': huiyuan.jieshao, @@ -6083,36 +6085,4 @@ class DsqrgmdhView(APIView): except Exception as e: logger.error(f"接口顶层异常: {str(e)}", exc_info=True) - return Response({'code': 500, 'msg': f'系统错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - - def _process_member_purchase(self, yonghuid, huiyuan_id, huiyuan_obj, club_id=None): - is_first_buy_any = False - try: - record = Huiyuangoumai.query.filter( - yonghu_id=yonghuid, - huiyuan_id=huiyuan_id - ).first() - - if record: - record.daoqi_time += timedelta(days=30) - record.huiyuan_zhuangtai = 1 - record.save(update_fields=['daoqi_time', 'huiyuan_zhuangtai']) - else: - other_count = Huiyuangoumai.query.filter(yonghu_id=yonghuid).exclude(huiyuan_id=huiyuan_id).count() - if other_count == 0: - is_first_buy_any = True - resolved_club = club_id or get_user_club_id(User.query.filter(UserUID=yonghuid).first()) - record = Huiyuangoumai.query.create( - yonghu_id=yonghuid, - huiyuan_id=huiyuan_id, - jieshao=huiyuan_obj.jieshao, - huiyuan_zhuangtai=1, - daoqi_time=timezone.now() + timedelta(days=30), - club_id=resolved_club, - ) - return record, is_first_buy_any - except Exception as e: - if 'unique' in str(e).lower() or 'duplicate' in str(e).lower(): - record = Huiyuangoumai.query.get(yonghu_id=yonghuid, huiyuan_id=huiyuan_id) - return record, False - raise \ No newline at end of file + return Response({'code': 500, 'msg': f'系统错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) \ No newline at end of file