async def price_guanli_jia(ns={}): """ 修改售价管理 :return: """ db = DBPools() async with db.sqlorContext('kboss') as sor: if ns.get('sor'): sor = ns.get('sor') try: # 按产品倒查who is provider who_is_provider_sql = """SELECT offer_orgid FROM saleprotocol WHERE bid_orgid = '%s' AND salemode = '2' and del_flg = '0' and id in (SELECT protocolid FROM product_salemode WHERE providerid = '%s' and productid = '%s');""" % (ns.get('bid_orgid'), ns.get('providerid'), ns.get('productid')) who_is_provider = (await sor.sqlExe(who_is_provider_sql, {}))[0]['offer_orgid'] # 查找供应商协议id ns_provider_price = { 'offer_orgid': who_is_provider, 'bid_orgid': ns.get('bid_orgid'), 'salemode': '2', 'del_flg': '0' } provider_protocol_id = (await sor.R('saleprotocol', ns_provider_price))[0]['id'] # 查找供应商给的底价 if provider_protocol_id: provider_price_find = { 'protocolid': provider_protocol_id, 'providerid': ns.get('providerid'), 'productid': ns.get('productid'), 'del_flg': '0' } provider_price = (await sor.R('product_salemode', provider_price_find))[0]['price'] if not provider_price: return { 'status': False, 'msg': '获取不到供应商的底价' } if float(provider_price) >= float(ns.get('price')): return { 'status': False, 'msg': '客户售价不能低于供应商底价' } # 首先查找协议是否已经存在 ns_shoujia = { 'offer_orgid': ns.get('bid_orgid'), 'bid_orgid': '*', 'salemode': '2', 'del_flg': '0' } shoujia_res_li = await sor.R('saleprotocol', ns_shoujia) if shoujia_res_li: protocolid = shoujia_res_li[0]['id'] else: # 协议表不存在 就创建 ns_zhubiao = { 'id': uuid(), 'offer_orgid': ns.get('bid_orgid'), 'bid_orgid': '*', 'salemode': '2', 'start_date': '2010-10-01', 'end_date': '2099-10-01' } await sor.C('saleprotocol', ns_zhubiao) protocolid = ns_zhubiao['id'] # 判断该协议下这个产品是否已经存在 ns_zibiao_exist = { 'protocolid': protocolid, 'providerid': ns.get('providerid'), 'productid': ns.get('productid'), 'del_flg': '0' } exists_res_li = await sor.R('product_salemode', ns_zibiao_exist) # 如果已经存在就更新 if exists_res_li: zi_biao_id = exists_res_li[0]['id'] ns_zibiao_update = { 'id': zi_biao_id, 'protocolid': protocolid, 'providerid': ns.get('providerid'), 'productid': ns.get('productid'), 'price': ns.get('price') } await sor.U('product_salemode', ns_zibiao_update) else: # 根据protocolid创建售价 ns_zibiao_shoujia = { 'id': uuid(), 'protocolid': protocolid, 'providerid': ns.get('providerid'), 'productid': ns.get('productid'), 'price': ns.get('price') } await sor.C('product_salemode', ns_zibiao_shoujia) return { 'status': True, 'msg': '创建售价成功' } except Exception as e: raise e return { 'status': False, 'msg': '创建售价失败' } async def discount_guanli_jia(ns={}): """ 折扣管理加 :return: """ # 折扣不能为空 discount_ = ns.get('discount') # if (not discount_) or (float(discount_) == 0): # return { # 'status': False, # 'msg': '折扣不能为空' # } user_orgid = ns.get('customerid') db = DBPools() async with db.sqlorContext('kboss') as sor: try: if ns.get('sor'): sor = ns.get('sor') # 首先查找协议是否已经存在 ns_discount = { 'offer_orgid': ns.get('bid_orgid'), 'bid_orgid': '*', 'salemode': '0', 'del_flg': '0' } if user_orgid: ns_discount['bid_orgid'] = user_orgid discount_res_li = await sor.R('saleprotocol', ns_discount) if discount_res_li: protocolid = discount_res_li[0]['id'] else: # 协议表不存在 就创建 # 获取这个供应商给机构签的协议起始时间 qishi_time_li = await sor.R('saleprotocol', {'offer_orgid': ns.get('providerid'), 'bid_orgid': ns.get('bid_orgid')}) if qishi_time_li: start_time, end_time = qishi_time_li[0]['start_date'], qishi_time_li[0]['end_date'] else: start_time, end_time = '2010-10-01', '2099-10-01' ns_zhubiao = { 'id': uuid(), 'offer_orgid': ns.get('bid_orgid'), 'bid_orgid': '*', 'salemode': '0', 'start_date': '2010-10-01', 'end_date': '2099-10-01' } if user_orgid: ns_zhubiao['bid_orgid'] = user_orgid await sor.C('saleprotocol', ns_zhubiao) protocolid = ns_zhubiao['id'] # 如果productid是列表 循环 productidss = ns.get('productid') if '[' in productidss: productidss = json.loads(productidss) else: productidss = [ns.get('productid')] # 如果是中金 额外添加产品id * # 获取中金id jncs_li = await sor.R('organization', {'orgname': '中金超算', 'del_flg': '0'}) jscs_id = jncs_li[0].get('id') if jncs_li else None if ns.get('providerid') == jscs_id: productidss.append('*') # 给某个供应商设置统一折扣 没有传productid if not ns.get('productid'): provider_id_prd_li = await sor.R('product', {'providerid': ns.get('providerid'), 'del_flg': '0'}) productidss = [item_id.get('id') for item_id in provider_id_prd_li] # 按产品倒查who is provider who_is_provider_sql = """SELECT offer_orgid FROM saleprotocol WHERE bid_orgid = '%s' AND salemode in ('0', '1') and del_flg = '0' and id in (SELECT protocolid FROM product_salemode WHERE providerid = '%s' and productid = '%s');""" % (ns.get('bid_orgid'), ns.get('providerid'), productidss[0]) who_is_provider = (await sor.sqlExe(who_is_provider_sql, {}))[0]['offer_orgid'] # 查找供应商协议id ns_provider_discount = { 'offer_orgid': who_is_provider, 'bid_orgid': ns.get('bid_orgid'), 'salemode': '0', 'del_flg': '0' } provider_protocol_id_li = (await sor.R('saleprotocol', ns_provider_discount)) # 可能是回佣设置折扣 if provider_protocol_id_li: provider_protocol_id = provider_protocol_id_li[0]['id'] else: provider_protocol_id = 0 for productid in productidss: # 判断是否已经存在 ns_zibiao_exist = { 'protocolid': protocolid, 'providerid': ns.get('providerid'), 'productid': productid, 'del_flg': '0' } # 查找供应商给的折扣 # if provider_protocol_id: # provider_discount_find = { # 'protocolid': provider_protocol_id, # 'providerid': ns.get('providerid'), # 'productid': productid, # 'del_flg': '0' # } # provider_discount_li = await sor.R('product_salemode', provider_discount_find) # if provider_discount_li: # provider_discount = provider_discount_li[0]['discount'] # if float(provider_discount) > float(ns.get('discount')): # return { # 'status': False, # 'msg': '客户折扣不能低于供应商折扣' # } res_exist_li = await sor.R('product_salemode', ns_zibiao_exist) if res_exist_li: zi_biao_id = res_exist_li[0]['id'] ns_zibiao_zhekou = { 'id': zi_biao_id, 'protocolid': protocolid, 'providerid': ns.get('providerid'), 'productid': productid, 'discount': ns.get('discount') } await sor.U('product_salemode', ns_zibiao_zhekou) else: # 根据protocolid创建折扣 ns_zibiao_zhekou = { 'id': uuid(), 'protocolid': protocolid, 'providerid': ns.get('providerid'), 'productid': productid, 'discount': ns.get('discount') } await sor.C('product_salemode', ns_zibiao_zhekou) return { 'status': True, 'msg': '创建折扣成功' } except Exception as e: raise e return { 'status': False, 'msg': '创建折扣失败' } async def productAdd(ns={}): """ add new product :param ns: :return: """ db = DBPools() async with db.sqlorContext('kboss') as sor: if ns.get('sor'): sor = ns.get('sor') nss = { 'id': uuid(), 'providerid': ns.get('providerid') or '', 'providerpid': ns.get('providerpid') or '', 'name': ns.get('name') or '', # 'description': ns.get('description') or '', 'ptype': ns.get('ptype') or '', 'state': ns.get('state') or '', # 'effect_date': ns.get('start_date') or '', # 'expire_date': ns.get('end_date') or '', 'salemode': ns.get('salemode') or '', 'product_code': ns.get('product_code') or '', 'spec_note': ns.get('spec_note') or '', 'product_area': ns.get('product_area') or '', 'specific_pattern': ns.get('specific_pattern') or '', 'reseller_orgid': ns.get('reseller_orgid') or '', 'classify': ns.get('classify'), 'productgroup': ns.get('productgroup'), 'label': ns.get('label'), 'description': ns.get('description'), } nss_product_salemode = { 'id': uuid(), 'protocolid': ns.get('protocolid'), 'providerid': ns.get('providerid'), 'productid': nss['id'], 'discount': ns.get('discount'), 'price': ns.get('floorprice') } nss_product_salemode_copy = { 'id': uuid(), 'protocolid': ns.get('protocolid'), 'providerid': ns.get('providerid'), 'productid': '*', 'discount': ns.get('discount'), 'price': ns.get('floorprice') } # if not ns.get('effect_date'): # return { # "status": False, # "message": "product effect date is empty" # } # # if not ns.get('expire_date'): # nss['expire_date'] = "9999-12-31" try: # 添加产品 如果有底价 触发插入底价表, 同时插入两条数据 # 1. 买方售方都设置则为底价 2.售方为本机构 买方为空则为售价 if ns.get('selling') and ns.get('floorprice'): if int(ns.get('selling')) <= int(ns.get('floorprice')): return { 'status': False, 'msg': '售价不能低于底价' } ns_floor = { 'id': uuid(), 'offer_orgid': ns.get('providerid'), 'bid_orgid': ns.get('reseller_orgid'), 'productid': nss.get('id'), 'price': ns.get('floorprice'), 'begin_date': ns.get('effect_date'), 'end_date': '9999-12-31' } ns_selling = { 'id': uuid(), 'offer_orgid': ns.get('reseller_orgid'), 'bid_orgid': '', 'productid': nss.get('id'), 'price': ns.get('selling'), 'begin_date': ns.get('effect_date'), 'end_date': '9999-12-31' } await sor.C('floorprice', ns_floor) await sor.C('floorprice', ns_selling) if ns.get('protocolid'): # 获取供应商名称 用于筛选中金设置映射产品 provider_name_li = await sor.R('organization', {'id': ns.get('providerid')}) provider_name = provider_name_li[0]['orgname'] # 获取协议起始时间 time_line_li = await sor.R('saleprotocol', {'id': ns.get('protocolid'), 'del_flg': '0'}) start_time = time_line_li[0]['start_date'] end_time = time_line_li[0]['end_date'] nss['effect_date'] = start_time nss['expire_date'] = end_time nss['salemode'] = time_line_li[0]['salemode'] # 检查产品表是否已经存在 ns_exist = { 'providerid': ns.get('providerid'), 'name': ns.get('name'), 'del_flg': '0' } product_exist_li = await sor.R('product', ns_exist) # 如果已经存在就更新 if product_exist_li: product_table_exits_id = product_exist_li[0]['id'] nss['id'] = product_table_exits_id await sor.U('product', nss) # 此时默认协议子表已经存在并更新 # 查找协议子表id 用于更新 exists_zibiao = { 'protocolid': ns.get('protocolid'), 'providerid': ns.get('providerid'), 'productid': nss['id'] } exists_zibiao_li = await sor.R('product_salemode', exists_zibiao) if exists_zibiao_li: zibiao_id = exists_zibiao_li[0]['id'] nss_product_salemode['id'] = zibiao_id nss_product_salemode['productid'] = nss['id'] if provider_name == '中金超算': await sor.U('product_salemode', nss_product_salemode_copy) await sor.U('product_salemode', nss_product_salemode) else: await sor.C('product', nss) # 如果时中金协议子表创建两个 一个productid正常用于展示 一个productid为* if provider_name == '中金超算': zj_offer_yezhu_bind_exist = { 'protocolid': ns.get('protocolid'), 'providerid': ns.get('providerid'), 'productid': '*', 'del_flg': '0' } # 如果中金offer bind业主机构 已经配置过* 更新 zj_exist_li = await sor.R('product_salemode', zj_offer_yezhu_bind_exist) if zj_exist_li: nss_product_salemode_copy['id'] = zj_exist_li[0]['id'] await sor.U('product_salemode', nss_product_salemode_copy) else: await sor.C('product_salemode', nss_product_salemode_copy) await sor.C('product_salemode', nss_product_salemode) # 如果是批量添加 salemode=1就是添加产品 不添加统一客户配置 if ns.get('batch'): ns_batch_dic = { 'bid_orgid': nss['reseller_orgid'], 'providerid': nss['providerid'], 'productid': nss['id'], 'sor': sor } if ns.get('salemode') == '0': ns_batch_dic['discount'] = ns.get('kehu_discount') await discount_guanli_jia(ns_batch_dic) elif ns.get('salemode') == '2': ns_batch_dic['price'] = ns.get('kehu_price') await price_guanli_jia(ns_batch_dic) else: await sor.C('product',nss) return { "status": True, "msg": "product add success", } except Exception as e: raise ValueError('产品添加失败: %s' % e) return { "status": False, "msg": "product add failed" } async def batch_add_product(ns={}): """ 批量添加产品 引用文件 productAdd.dspy discount_guanli_jia.dspy price_guanli_jia.dspy :param ns: :return: """ salemode = ns.get('salemode') # file_path_detail = '/d/kboss_dev/www/files/' + ns.get('filepath') file_path_detail = file_realpath(ns.get('filepath')) workbook = openpyxl.load_workbook(filename=file_path_detail) sheet = workbook.active count_ject = 0 flag = None key_list = [] name_list = [] id_list = [] for index, row in enumerate(sheet.rows): res = [item.value for item in row] if index == 0: if len(res) < 5: return { 'status': False, 'msg': '提交的数据格式错误, 产品名称/产品ID/结算(折扣或底价)/客户(折扣或底价)/专属分类 为表头必须字段' } if res[0] != '产品名称' and res[1] != '产品ID': return { 'status': False, 'msg': '检测到第一行标题 第一个字段不是 产品名称 第二个字段不是 产品ID' } if res[4] != '专属分类': return { 'status': False, 'msg': '检测到第五列名称不是 "专属分类"' } if res[5] != '产品组': return { 'status': False, 'msg': '检测到第六列名称不是 "产品组"' } if res[6] != '产品标签': return { 'status': False, 'msg': '检测到第七列名称不是 "产品标签"' } if res[7] != '产品描述': return { 'status': False, 'msg': '检测到第八列名称不是 "产品描述"' } if res.count(None) == len(res): continue if index == 0: if len(res) < 5: return { 'status': False, 'msg': '提交的数据格式错误, 产品名称/产品ID/结算(折扣或底价)/客户(折扣或底价)/专属分类 为表头必须字段' } key_list = res[5:] if ns.get('salemode') != '1': for i in res: if type(i) != str: return { 'status': False, 'msg': '表头中不能包含纯数字或纯特殊字符, 请参照规范格式' } flag_judge = ''.join(res) if '折扣' in flag_judge: if salemode != '0': return { 'status': False, 'msg': '检测到数据中是折扣模式, 上传关键字使用的是底价模式,无法上传' } elif '底价' in flag_judge: if salemode != '2': return { 'status': False, 'msg': '检测到数据中是底价模式, 上传关键字使用的是折扣模式,无法上传' } continue count_ject += 1 # 判断折扣或底价是否是小数 if not (type(res[2]) in [int, float] and type(res[3]) in [int, float]): return { 'status': False, 'msg': '配置出现错误, 产品名称: %s, 折扣或底价内容: %s, 销售折扣或底价内容: %s' % (res[0], res[2], res[3]) } name = res[0] providerpid = res[1] # 筛选重复产品名称 重复产品ID if name in name_list: return { 'status': False, 'msg': '产品名称重复, 产品名称: %s' % name } name_list.append(name) if providerpid in id_list: return { 'status': False, 'msg': '产品ID重复, 产品ID: %s' % providerpid } id_list.append(providerpid) # 添加超算产品的时候 providerpid可能为空 if not name: continue spec_note = [] for i in range(len(key_list)): spec_note.append({'configName': key_list[i], 'value': res[5+i]}) ns_product_add_dic = { "reseller_orgid": ns.get('orgid'), "providerpid": providerpid, "name": name, "ptype": ns.get('ptype'), "salemode": salemode, 'protocolid': ns.get('protocolid'), 'providerid': ns.get('providerid'), 'spec_note': str(spec_note).replace("'", '"') if spec_note else None, 'classify': res[4], 'productgroup': res[5], 'label': res[6], 'description': res[7], 'batch': 1 } if salemode == '0': ns_product_add_dic['discount'] = res[2] ns_product_add_dic['kehu_discount'] = res[3] elif salemode == '2': ns_product_add_dic['floorprice'] = res[2] ns_product_add_dic['kehu_price'] = res[3] # TODO 删除后的产品重新添加 是否成功 try: await productAdd(ns_product_add_dic) except Exception as e: raise e if not flag: return { 'status': True, 'msg': '成功添加 %s 条产品' % count_ject } else: return { 'status': False, '.msg': '添加产品失败' } ret = await batch_add_product(params_kw) return ret