Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
hh_ccs
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
贺阳
hh_ccs
Commits
afef8d8f
提交
afef8d8f
authored
8月 06, 2025
作者:
贺阳
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
查询尾程交货数据时,判断时间是否倒序了
上级
882d5dbe
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
100 行增加
和
64 行删除
+100
-64
order_controller.py
ccs_connect_tiktok/controllers/order_controller.py
+86
-53
pda_scan_record.py
ccs_connect_tiktok/models/pda_scan_record.py
+11
-4
pda_scan_record_views.xml
ccs_connect_tiktok/views/pda_scan_record_views.xml
+3
-7
没有找到文件。
ccs_connect_tiktok/controllers/order_controller.py
浏览文件 @
afef8d8f
...
...
@@ -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_dat
e desc'
,
limit
=
1
)
],
order
=
'
operation_tim
e 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
())
ccs_connect_tiktok/models/pda_scan_record.py
浏览文件 @
afef8d8f
...
...
@@ -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
,
...
...
ccs_connect_tiktok/views/pda_scan_record_views.xml
浏览文件 @
afef8d8f
...
...
@@ -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_dat
e"
/>
<field
name=
"
operation_tim
e"
/>
<field
name=
"operation"
/>
<field
name=
"record_type"
/>
<field
name=
"bill_number"
/>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论