def calculate_fun(bean, productList, groupnum=1, oldpro_list=[]):
    """
    换购促销的计算方法 hexiaoxia
    :param bean: 一个换购促销对象
    :param productList: 录入所有商品列表对象
    :param groupnum: 当前是哪个倍数进来的倍数，从1开始（例如：某促销可以翻3倍，那么第一次进来传入1，第二次进来传入2，第三进来传入3，……
    :return:
    """
    from pro.utils.linq import linq
    import pro.utils.util as util
    import copy
    n_productList = copy.deepcopy(productList)
    operation_set = bean.operation_set
    three_id = str(bean.prom_type_three).lower()
    target_item = bean.target_item
    purchase_way = 'T'
    if three_id == 'ga1505' or three_id == 'ga1506':
        purchase_way = 'J'
        operation_set = sorted(operation_set, key=lambda x: x.
            purchase_condition)
    else:
        if three_id == 'ga1503' or three_id == 'ga1504':
            purchase_way = 'D'
        operation_set = sorted(operation_set, key=lambda x: x.
            purchase_condition, reverse=True)
    calculate_list = []
    swap_products = []
    operation_set_list = []
    pronum = 0
    give_value = operation_set[0].give_value
    one_item = {}
    one_item['one_multiple'] = False
    for row in operation_set:
        old_pronum = 0
        if pronum >= int(give_value):
            break
        isnew = True
        oneprice = 0
        tamt_receivable = 0
        t_qtty = 0
        rownum = 0
        pro_list = []
        r_item = {}
        r_item['pcond_id'] = row.pcond_id
        if oldpro_list:
            for index, row3 in enumerate(oldpro_list):
                if row3['pcond_id'] == row.pcond_id and len(row3['pro_list']
                    ) < give_value:
                    old_pronum = len(row3['pro_list'])
                    pro_list = row3['pro_list']
                    isnew = False
                    break
        for row1_index, row1 in enumerate(n_productList):
            if pronum >= int(give_value):
                break
            row1pro = linq(row.product_list).where(lambda x: x['ECODE'] ==
                row1.ecode).tolist().copy()
            if not row1pro:
                continue
            row1pro1 = linq(row1.productSeatList).where(lambda x: x.seat ==
                False and x.is_run_other_pro == True).tolist().copy()
            if not row1pro1:
                continue
            for row2_index, row2 in enumerate(row1.productSeatList):
                if pronum < int(give_value):
                    if row2.seat == True or row2.is_run_other_pro == False:
                        continue
                    if target_item == 'amt_retail':
                        tamt_receivable = tamt_receivable + row2.amt_retail
                        new_amtreceivable = row2.amt_retail
                    elif target_item == 'amt_list':
                        tamt_receivable = tamt_receivable + row2.amt_list
                        new_amtreceivable = row2.amt_list
                    else:
                        tamt_receivable = tamt_receivable + row2.amt_receivable
                        new_amtreceivable = row2.amt_receivable
                    t_qtty = t_qtty + row2.qtty
                    row2.amt_receivable = new_amtreceivable
                    if old_pronum >= int(give_value):
                        isnew = True
                        pro_list = []
                        old_pronum = 0
                    pro_list.append(row2)
                    row2.seat = True
                    productList[row1_index].productSeatList[row2_index
                        ].seat = True
                    productList[row1_index].productSeatList[row2_index
                        ].is_run_other_pro = False
                    productList[row1_index].productSeatList[row2_index
                        ].is_run_store_act = False
                    pronum += 1
                    old_pronum += 1
                else:
                    break
        if not pro_list:
            continue
        r_item['pro_list'] = pro_list
        if oldpro_list:
            if isnew:
                oldpro_list.append(r_item)
        else:
            operation_set_list.append(r_item)
    if pronum == int(give_value):
        one_item['one_multiple'] = True
    else:
        one_item['one_multiple'] = False
    one_item['pro_list'
        ] = operation_set_list if not oldpro_list else oldpro_list
    calculate_list.append(one_item)
    if not calculate_list:
        return None
    else:
        return calculate_list
