提交 68d4f3d5 authored 作者: 贺阳's avatar 贺阳

1、托盘理货的倒序优化

2、查询托盘理货的性能优化
上级 7e4eac80
...@@ -695,22 +695,71 @@ class OrderController(http.Controller): ...@@ -695,22 +695,71 @@ class OrderController(http.Controller):
def _get_last_mile_grouped(self, tally_state_arr, pda_lang, is_pallet=False): def _get_last_mile_grouped(self, tally_state_arr, pda_lang, is_pallet=False):
lang = 'zh_CN' if pda_lang == 'zh' else 'en_US' # 语言 lang = 'zh_CN' if pda_lang == 'zh' else 'en_US' # 语言
# if is_pallet:
# domain=[('state', '!=', 'done')]# 1. 按托盘理货时,查非已完成状态的提单 # 1. 查询大包数据,使用更高效的查询
# else: domain = [('bl_id.state', '=', 'ccing')] # 查所有清关中提单
# 先都查清关中的,如果以后要查非已完成状态的提单,再修改domain。而且查尾程快递和对应的大包或托盘信息得分两个接口
domain = [('bl_id.state', '=', 'ccing')] # 1. 按尾程理货时,查所有清关中提单
# 2. 查所有大包 如果是托盘的交货,不需要过滤理货状态
if not is_pallet or (is_pallet and 'unprocessed_goods' in tally_state_arr): if not is_pallet or (is_pallet and 'unprocessed_goods' in tally_state_arr):
domain += [('tally_state', 'in', tally_state_arr)] domain += [('tally_state', 'in', tally_state_arr)]
# 预加载关联数据,避免N+1查询
big_packages = request.env['cc.big.package'].sudo().search(domain) big_packages = request.env['cc.big.package'].sudo().search(domain)
# 3. 按"下一阶段服务商名称"分组 if not big_packages:
return {'provider_info_arr': [], 'state': 200, 'bl_ids': []}
# 2. 预加载所有服务商数据,避免重复查询
all_providers = request.env['cc.last.mile.provider'].sudo().with_context({'lang': lang}).search([])
provider_map = {} # 缓存服务商匹配结果
# 创建服务商匹配索引,提高匹配效率
provider_index = {}
for provider in all_providers:
if provider.matching_value:
matching_values = [value.lower().strip() for value in provider.matching_value.split('\n') if value.strip()]
for value in matching_values:
provider_index[value] = provider
# 3. 预加载托盘数据(如果需要)
pallet_data = {}
if is_pallet:
# 先匹配所有服务商,获取ID列表
provider_ids = set()
for pkg in big_packages:
if not pkg.next_provider_name:
continue
for provider in all_providers:
if provider.match_provider(pkg.next_provider_name, all_providers):
provider_ids.add(provider.id)
break
# 批量查询托盘数据
if provider_ids:
pallet_domain = [('express_company_id', 'in', list(provider_ids))]
if 'unprocessed_goods' in tally_state_arr:
pallet_domain.append(('usage_state', '=', 'unused'))
else:
pallet_domain.append(('usage_state', '=', 'used'))
pallets = request.env['cc.pallet'].sudo().search(pallet_domain)
for pallet in pallets:
if pallet.express_company_id.id not in pallet_data:
pallet_data[pallet.express_company_id.id] = []
pallet_data[pallet.express_company_id.id].append(pallet.search_pallet_info())
# 4. 按"下一阶段服务商名称"分组
group_dict = {} group_dict = {}
for pkg in big_packages: for pkg in big_packages:
provider = request.env['cc.last.mile.provider'].sudo().with_context({'lang': lang}).match_provider( if not pkg.next_provider_name:
pkg.next_provider_name) continue
# 使用缓存的匹配结果
if pkg.next_provider_name not in provider_map:
provider = provider_index.get(pkg.next_provider_name.lower().strip())
provider_map[pkg.next_provider_name] = provider
provider = provider_map[pkg.next_provider_name]
if not provider: if not provider:
continue continue
key = provider.id key = provider.id
if key not in group_dict: if key not in group_dict:
group_dict[key] = provider.search_pro_info() # 查询快递信息 group_dict[key] = provider.search_pro_info() # 查询快递信息
...@@ -718,32 +767,34 @@ class OrderController(http.Controller): ...@@ -718,32 +767,34 @@ class OrderController(http.Controller):
group_dict[key]['big_package_arr'] = [] # 大包信息 group_dict[key]['big_package_arr'] = [] # 大包信息
group_dict[key]['ship_package_arr'] = [] # 小包信息 group_dict[key]['ship_package_arr'] = [] # 小包信息
group_dict[key]['pallet_info_arr'] = [] # 托盘信息 group_dict[key]['pallet_info_arr'] = [] # 托盘信息
# 添加预加载的托盘数据
if is_pallet and key in pallet_data:
group_dict[key]['pallet_info_arr'] = sorted(pallet_data[key], key=lambda x: x.get('name', ''))
group_dict[key]['count'] += 1 group_dict[key]['count'] += 1
# 添加大包信息
if 'unprocessed_goods' in tally_state_arr or ('checked_goods' in tally_state_arr and not is_pallet): if 'unprocessed_goods' in tally_state_arr or ('checked_goods' in tally_state_arr and not is_pallet):
for tally_state in tally_state_arr: for tally_state in tally_state_arr:
group_dict[key]['big_package_arr'].append( group_dict[key]['big_package_arr'].append(
pkg.search_big_package_info(pda_lang=pda_lang, type=tally_state)) pkg.search_big_package_info(pda_lang=pda_lang, type=tally_state))
# 按托盘理货时返回未使用的托盘信息,按尾程时返回小包信息
if is_pallet: # 添加小包信息(非托盘模式)
# 如果是未理货,查未使用托盘;如果是已理货,查已使用托盘 if not is_pallet:
if 'unprocessed_goods' in tally_state_arr:
domain = [('usage_state', '=', 'unused')]
else:
domain = [('usage_state', '=', 'used')]
unused_pallets = request.env['cc.pallet'].sudo().search([('express_company_id', '=', key)] + domain)
pallet_info_arr = [pallet.search_pallet_info() for pallet in unused_pallets]
group_dict[key]['pallet_info_arr'] = pallet_info_arr
group_dict[key]['pallet_info_arr'].sort(key=lambda x: x.get('name', '')) # 根据托盘号升序排序
else:
group_dict[key]['ship_package_arr'].extend( group_dict[key]['ship_package_arr'].extend(
[ship_package_item.search_ship_package_info(pda_lang=pda_lang) for ship_package_item in [ship_package_item.search_ship_package_info(pda_lang=pda_lang) for ship_package_item in
pkg.ship_package_ids]) pkg.ship_package_ids])
# 4. 返回
# 5. 返回结果
provider_info_arr = list(group_dict.values()) provider_info_arr = list(group_dict.values())
# 按服务商名称升序排序 provider_info_arr.sort(key=lambda x: x.get('name', '')) # 按服务商名称升序排序
provider_info_arr.sort(key=lambda x: x.get('name', ''))
return {'provider_info_arr': provider_info_arr, 'state': 200, return {
'bl_ids': list(set(list(map(lambda x: x.bl_id.id, big_packages))))} 'provider_info_arr': provider_info_arr,
'state': 200,
'bl_ids': list(set(pkg.bl_id.id for pkg in big_packages))
}
def _check_tally_time_risk(self, bl_obj, pda_lang='zh', pallet_name=None): def _check_tally_time_risk(self, bl_obj, pda_lang='zh', pallet_name=None):
""" """
...@@ -976,16 +1027,6 @@ class OrderController(http.Controller): ...@@ -976,16 +1027,6 @@ class OrderController(http.Controller):
'zh': '托盘号[%s]不存在' % ','.join(pallet_nos) 'zh': '托盘号[%s]不存在' % ','.join(pallet_nos)
}[pda_lang] }[pda_lang]
return res return res
#检查托盘关联的大包的提单时间是否倒序
for pallet in pallet_obj:
bl_objs = pallet.package_ids.mapped('bl_id')
logging.info(f"bl_objs: {','.join([bl_obj.bl_no for bl_obj in bl_objs])}")
for bl_obj in bl_objs:
time_check_result = self._check_tally_time_risk(bl_obj, pda_lang, pallet.name)
if time_check_result['has_risk']:
res['state'] = 400
res['message'] = time_check_result['message']
return res
# 将托盘状态更新为已使用 # 将托盘状态更新为已使用
all_big_package_arr = [] all_big_package_arr = []
for pallet_item in kwargs.get('pallet_arr'): for pallet_item in kwargs.get('pallet_arr'):
...@@ -1001,6 +1042,16 @@ class OrderController(http.Controller): ...@@ -1001,6 +1042,16 @@ class OrderController(http.Controller):
('big_package_no', 'in', [pkg.get('big_package_no') for pkg in big_package_arr]) ('big_package_no', 'in', [pkg.get('big_package_no') for pkg in big_package_arr])
]) ])
if big_package_objs: if big_package_objs:
#检查托盘关联的大包的提单时间是否倒序
# 获取所有大包对应的提单(去重)
bl_objs = big_package_objs.mapped('bl_id')
# 检查每个提单的时间风险
for bl_obj in bl_objs:
time_check_result = self._check_tally_time_risk(bl_obj, pda_lang, pallet.name)
if time_check_result['has_risk']:
res['state'] = 400
res['message'] = time_check_result['message']
return res
# 调用托盘的update_usage_state方法 # 调用托盘的update_usage_state方法
pallet.update_usage_state(big_package_objs, pallet_use_date) pallet.update_usage_state(big_package_objs, pallet_use_date)
tally_user_id = kwargs['pallet_arr'][0]['big_package_arr'][0].get('tally_user_id') if kwargs.get( tally_user_id = kwargs['pallet_arr'][0]['big_package_arr'][0].get('tally_user_id') if kwargs.get(
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论