提交 afef8d8f authored 作者: 贺阳's avatar 贺阳

查询尾程交货数据时,判断时间是否倒序了

上级 882d5dbe
......@@ -106,6 +106,14 @@ class OrderController(http.Controller):
bl_obj = request.env['cc.bl'].sudo().deal_bl_no_and_transfer_bl_no(
bl_no) # 提单号去掉杠和空格,并转换为小写,优先匹配提单号,匹配不到则匹配转单号
if bl_obj:
# 1.按提单交货时,创建批次,填写的提单号传给后台查找对应的提单号,在匹配查找前,先查找是否pda扫码记录,若有类型该提单,类型为理货的,且操作时间-当前时间小于等于配置的参数(交货操作晚于提货操作X分钟),则提示:该提单未到交货时间,有风险产生倒叙,请间隔规定时间后再扫码;
if action_type == 'handover':
# 检查是否存在时间倒序风险
time_check_result = self._check_delivery_time_risk(bl_obj, pda_lang)
if time_check_result['has_risk']:
res['state'] = 400
res['message'] = time_check_result['message']
return res
if bl_obj.state in state_arr:
res['bl_info'] = bl_obj.search_bl_info(
pda_lang=pda_lang, type=action_type)
......@@ -155,17 +163,6 @@ class OrderController(http.Controller):
bl_obj = request.env['cc.bl'].sudo().deal_bl_no_and_transfer_bl_no(
bl_no) # 提单号去掉杠和空格,并转换为小写,优先匹配提单号,匹配不到则匹配转单号
if bl_obj and bl_obj.state in state_arr:
# 1.按提单交货时,创建批次,填写的提单号传给后台查找对应的提单号,在匹配查找前,先查找是否pda扫码记录,若有类型该提单,类型为理货的,且操作时间-当前时间小于等于配置的参数(交货操作晚于提货操作X分钟),则提示:该提单未到交货时间,有风险产生倒叙,请间隔规定时间后再扫码;
if action_type == 'handover':
# 检查是否存在时间倒序风险
time_check_result = self._check_delivery_time_risk(bl_obj, pda_lang)
if time_check_result['has_risk']:
res['state'] = 400
res['message'] = time_check_result['message']
return res
# 继续原有的处理逻辑...
ship_packages = []
big_package_exception_arr = {}
ship_package_exception_arr = {}
......@@ -284,6 +281,8 @@ class OrderController(http.Controller):
email_language=lang)
ship_wizard_obj.confirm() # 发送邮件
res['state'] = 200
# 获取最晚的操作时间
latest_operation_time = self._get_latest_operation_time(ship_packages)
# 创建成功的pda扫码记录
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
......@@ -291,7 +290,8 @@ class OrderController(http.Controller):
bill_number=bl_obj.bl_no,
transfer_number=bl_obj.transfer_bl_no,
state='success',
bl_id=bl_obj.id)
bl_id=bl_obj.id,
operation_time=latest_operation_time)
logging.info(
'update_big_package_tally_detail ship_packages:%s' % len(ship_packages))
# 有小包 就更新小包状态和同步
......@@ -328,10 +328,16 @@ class OrderController(http.Controller):
bill_number=bl_obj.bl_no,
transfer_number=bl_obj.transfer_bl_no,
state='failed',
bl_id=bl_obj.id, failure_reason=error)
bl_id=bl_obj.id,
failure_reason=error)
else:
request.env['pda.scan.record'].sudo().create_scan_record(operation, action_type, '', '', 'failed',
failure_reason=error)
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
record_type=action_type,
bill_number='',
transfer_number='',
state='failed',
failure_reason=error)
logging.info('res:%s' % res)
return res
......@@ -351,31 +357,6 @@ class OrderController(http.Controller):
try:
logging.info('update_pro_big_package_tally_detail kw:%s' % kwargs)
if action_type and (kwargs.get('big_package_arr') or kwargs.get('ship_package_arr')):
# 按尾程交货时,检查时间风险 大包或小包对应的提单是否已存在成功扫码记录
if action_type == 'handover':
all_bl_ids_in_request = set()
if kwargs.get('ship_package_arr'):
for pkg_item in kwargs['ship_package_arr']:
pkg_obj = request.env['cc.ship.package'].sudo().search(
[('logistic_order_no', '=', pkg_item.get('logistic_order_no'))], limit=1)
if pkg_obj and pkg_obj.bl_id:
all_bl_ids_in_request.add(pkg_obj.bl_id.id)
if kwargs.get('big_package_arr'):
for pkg_item in kwargs['big_package_arr']:
pkg_obj = request.env['cc.big.package'].sudo().search(
[('big_package_no', '=', pkg_item.get('big_package_no'))], limit=1)
if pkg_obj and pkg_obj.bl_id:
all_bl_ids_in_request.add(pkg_obj.bl_id.id)
if all_bl_ids_in_request:
for bl_id in all_bl_ids_in_request:
bl_obj = request.env['cc.bl'].sudo().browse(bl_id)
time_check_result = self._check_delivery_time_risk(bl_obj, pda_lang, 'tail_tally')
if time_check_result['has_risk']:
res['state'] = 400
res['message'] = time_check_result['message']
return res
logging.info(f"all_bl_ids_in_request: {all_bl_ids_in_request}")
# return res
big_package_exception_arr = {}
ship_package_exception_arr = {}
......@@ -481,6 +462,8 @@ class OrderController(http.Controller):
logging.info('update_pro_big_package_tally_detail ship_packages:%s' % len(ship_packages))
# 有小包 就更新小包状态和同步
if ship_packages:
# 获取最晚的操作时间
latest_operation_time = self._get_latest_operation_time(ship_packages)
# 在这里创建成功的pda扫码记录
bl_obj = request.env['cc.bl'].sudo().search(
[('id', 'in', [ship_package.get('bl_id') for ship_package in ship_packages])])
......@@ -492,7 +475,8 @@ class OrderController(http.Controller):
bill_number=bl.bl_no,
transfer_number=bl.transfer_bl_no,
state='success',
bl_id=bl.id)
bl_id=bl.id,
operation_time=latest_operation_time)
redis_conn = request.env['common.common'].sudo().get_redis()
if redis_conn and redis_conn != 'no':
bl_ids = [ship_package.get('bl_id') for ship_package in ship_packages]
......@@ -530,8 +514,13 @@ class OrderController(http.Controller):
bl_id=bl.id,
failure_reason=error)
else:
request.env['pda.scan.record'].sudo().create_scan_record(operation, action_type, '', '', 'failed',
failure_reason=error)
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
record_type=action_type,
bill_number='',
transfer_number='',
state='failed',
failure_reason=error)
logging.info('res:%s' % res)
return res
......@@ -595,8 +584,20 @@ class OrderController(http.Controller):
res = {'state': 201, 'message': ''}
try:
logging.info('last_mile_delivery kwargs:%s' % kwargs)
return self._get_last_mile_grouped('checked_goods', pda_lang)
# 按尾程交货时,检查时间风险 大包或小包对应的提单是否已存在成功扫码记录
res= self._get_last_mile_grouped('checked_goods', pda_lang)
all_bl_ids_in_request=res['bl_ids']
logging.info(f"all_bl_ids_in_request: {all_bl_ids_in_request}")
if all_bl_ids_in_request:
bl_objs=request.env['cc.bl'].sudo().search([('id','in',all_bl_ids_in_request)])
for bl_obj in bl_objs:
time_check_result = self._check_delivery_time_risk(bl_obj, pda_lang, 'tail_tally')
if time_check_result['has_risk']:
res['state'] = 400
res['message'] = time_check_result['message']
return res
res['state'] = 200
return res
except Exception as e:
exceptions_msg_dic = {
'en': 'System parsing error, the reason for the error is %s' % e,
......@@ -640,7 +641,7 @@ class OrderController(http.Controller):
provider_info_arr = list(group_dict.values())
# 按服务商名称升序排序
provider_info_arr.sort(key=lambda x: x.get('name', ''))
return {'provider_info_arr': provider_info_arr, 'state': 200}
return {'provider_info_arr': provider_info_arr, 'state': 200,'bl_ids':list(map(lambda x:x.bl_id.id,big_packages))}
def _check_delivery_time_risk(self, bl_obj, pda_lang='zh', operation='bill_tally'):
"""
......@@ -654,22 +655,20 @@ class OrderController(http.Controller):
'delivery_time', '80' # 使用现有的delivery_time参数,默认80分钟
)
allowed_minutes = int(config_param)
logging.info(f"allowed_minutes: {allowed_minutes}")
# 查找该提单的PDA扫码记录,类型为理货的
pda_records = request.env['pda.scan.record'].sudo().search([
('bl_id', '=', bl_obj.id),
('operation', '=', operation), # 理货类型
('state', '=', 'success') # 成功状态
], order='create_date desc', limit=1)
], order='operation_time desc', limit=1)
if pda_records:
latest_tally_record = pda_records[0]
current_time = request.env['common.common'].sudo().get_utc_time(datetime.now())
# Ensure create_date is also timezone-aware (UTC)
create_date = latest_tally_record.create_date
logging.info(f"current_time: {current_time}, latest_tally_record.create_date: {create_date}")
time_diff = (datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S') - create_date).total_seconds() / 60
logging.info(f"time_diff: {time_diff}")
# Ensure operation_time is also timezone-aware (UTC)
operation_time = latest_tally_record.operation_time
time_diff = (datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S') - operation_time).total_seconds() / 60
logging.info(f"current_time: {current_time}, operation_time: {operation_time},time_diff: {time_diff}")
# 如果时间差小于等于配置的参数,则存在风险
if time_diff <= allowed_minutes:
if pda_lang == 'en':
......@@ -690,3 +689,37 @@ class OrderController(http.Controller):
'time_diff': 0,
'allowed_minutes': allowed_minutes
}
def _get_latest_operation_time(self, ship_packages):
"""
获取最晚的操作时间(理货时间或交货时间)
:param ship_packages: 小包列表
:return: 最晚的操作时间字符串
"""
latest_time = None
for ship_package in ship_packages:
tally_time = ship_package.get('tally_time')
if tally_time:
# 如果tally_time是字符串,转换为datetime对象进行比较
if isinstance(tally_time, str):
try:
# 尝试解析时间字符串
from datetime import datetime
parsed_time = datetime.strptime(tally_time, '%Y-%m-%d %H:%M:%S')
if latest_time is None or parsed_time > latest_time:
latest_time = parsed_time
except ValueError:
# 如果解析失败,记录日志但继续处理
logging.warning(f"无法解析时间字符串: {tally_time}")
continue
elif isinstance(tally_time, datetime):
# 如果已经是datetime对象
if latest_time is None or tally_time > latest_time:
latest_time = tally_time
# 返回最晚时间的字符串格式,如果没有找到则返回当前时间
if latest_time:
return latest_time.strftime('%Y-%m-%d %H:%M:%S')
else:
return request.env['common.common'].sudo().get_utc_time(datetime.now())
......@@ -20,7 +20,7 @@ class PDAScanRecord(models.Model):
self.record_type = 'handover'
operator_id = fields.Many2one('res.users', string='操作人', required=True)
# operation_time = fields.Datetime(string='操作时间', required=True, default=fields.Datetime.now)
operation_time = fields.Datetime(string='操作时间', required=True, default=fields.Datetime.now)
operation = fields.Selection([
('bill_tally', _('Bill Tally')), # 按提单理货
('tail_tally', _('Tail Tally')), # 按尾程理货
......@@ -43,7 +43,7 @@ class PDAScanRecord(models.Model):
failure_reason = fields.Char(string=_('Failure Reason')) # 失败原因
@api.model
def create_scan_record(self, operation, record_type, bill_number, transfer_number, state, operator_id=False, bl_id=False,failure_reason=False):
def create_scan_record(self, operation, record_type, bill_number, transfer_number, state, operator_id=False, bl_id=False, failure_reason=False, operation_time=False):
"""
创建扫码记录的方法,供接口调用
Create scan record method for API calls
......@@ -58,7 +58,8 @@ class PDAScanRecord(models.Model):
if bl_obj:
bl_id = bl_obj.id
record = self.create({
# 准备创建记录的数据
record_data = {
'operator_id': operator_id,
'operation': operation,
'record_type': record_type,
......@@ -67,7 +68,13 @@ class PDAScanRecord(models.Model):
'bl_id': bl_id,
'state': state,
'failure_reason': failure_reason
})
}
# 如果传入了自定义操作时间,使用它
if operation_time:
record_data['operation_time'] = operation_time
record = self.create(record_data)
return {
'success': True,
'record_id': record.id,
......
......@@ -7,9 +7,7 @@
<field name="arch" type="xml">
<tree string="PDA Scan Record" decoration-info="state == 'success'" decoration-danger="state == 'failed'">
<field name="operator_id" />
<field name="create_date"/>
<!-- <field name="operator_id"/>
<field name="operation_time"/> -->
<field name="operation_time"/>
<field name="operation"/>
<field name="record_type"/>
<field name="bill_number"/>
......@@ -34,9 +32,7 @@
<group>
<group>
<field name="operator_id" />
<field name="create_date"/>
<!-- <field name="operator_id"/>
<field name="operation_time"/> -->
<field name="operation_time"/>
<field name="operation"/>
</group>
<group>
......@@ -61,7 +57,7 @@
<field name="arch" type="xml">
<search string="PDA Scan Record">
<field name="operator_id"/>
<field name="create_date"/>
<field name="operation_time"/>
<field name="operation"/>
<field name="record_type"/>
<field name="bill_number"/>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论