Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
hh_ccs
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
贺阳
hh_ccs
Commits
b85c538a
提交
b85c538a
authored
6月 17, 2025
作者:
伍姿英
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'release/2.8.0'
上级
5430de23
88e8f7e3
隐藏空白字符变更
内嵌
并排
正在显示
16 个修改的文件
包含
710 行增加
和
92 行删除
+710
-92
zh_CN.po
ccs_base/i18n/zh_CN.po
+76
-30
cc_exception_info.py
ccs_base/models/cc_exception_info.py
+1
-2
cc_last_mile_provider.py
ccs_base/models/cc_last_mile_provider.py
+54
-7
common_common.py
ccs_base/models/common_common.py
+18
-4
res_config_setting.py
ccs_base/models/res_config_setting.py
+5
-3
cc_last_mile_provider_views.xml
ccs_base/views/cc_last_mile_provider_views.xml
+4
-0
res_config_setting.xml
ccs_base/views/res_config_setting.xml
+5
-0
__init__.py
ccs_connect_tiktok/controllers/__init__.py
+1
-0
binary.py
ccs_connect_tiktok/controllers/binary.py
+118
-0
order_controller.py
ccs_connect_tiktok/controllers/order_controller.py
+281
-22
__init__.py
ccs_connect_tiktok/models/__init__.py
+2
-0
cc_bill_loading.py
ccs_connect_tiktok/models/cc_bill_loading.py
+30
-15
http.py
ccs_connect_tiktok/models/http.py
+53
-0
ir_attachment.py
ccs_connect_tiktok/models/ir_attachment.py
+56
-0
config.py
consumers/config.py
+1
-8
mail_push.py
consumers/mail_push.py
+5
-1
没有找到文件。
ccs_base/i18n/zh_CN.po
浏览文件 @
b85c538a
...
@@ -6,14 +6,16 @@ msgid ""
...
@@ -6,14 +6,16 @@ msgid ""
msgstr ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-0
4-03 02:14
+0000\n"
"POT-Creation-Date: 2025-0
6-09 07:48
+0000\n"
"PO-Revision-Date: 2025-0
4-03 02:14+00
00\n"
"PO-Revision-Date: 2025-0
6-09 15:53+08
00\n"
"Last-Translator: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Language-Team: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.5\n"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
...
@@ -62,26 +64,32 @@ msgid ""
...
@@ -62,26 +64,32 @@ msgid ""
"<div style=\"margin: 0px; padding: 0px;\">\n"
"<div style=\"margin: 0px; padding: 0px;\">\n"
" <p style=\"margin: 0px; padding: 0px;\">\n"
" <p style=\"margin: 0px; padding: 0px;\">\n"
" Dear all\n"
" Dear all\n"
" <br
/
>\n"
" <br>\n"
" <!-- 检查 big_package_ids 是否有值 -->\n"
" <!-- 检查 big_package_ids 是否有值 -->\n"
" <t t-if=\"object.big_package_ids\">\n"
" <t t-if=\"object.big_package_ids\">\n"
" <t t-foreach=\"object.big_package_ids\" t-as=\"big_package_id\">\n"
" <t t-foreach=\"object.big_package_ids\" t-"
"as=\"big_package_id\">\n"
" <div>Package:\n"
" <div>Package:\n"
" <t t-esc=\"big_package_id.big_package_no or ''\"/>\n"
" <t t-esc=\"big_package_id.big_package_no or "
"''\"></t>\n"
" </div>\n"
" </div>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" <!-- 检查 ship_package_ids 是否有值 -->\n"
" <!-- 检查 ship_package_ids 是否有值 -->\n"
" <t t-if=\"object.ship_package_ids\">\n"
" <t t-if=\"object.ship_package_ids\">\n"
" <t t-foreach=\"object.ship_package_ids\" t-as=\"ship_package_id\">\n"
" <t t-foreach=\"object.ship_package_ids\" t-"
"as=\"ship_package_id\">\n"
" <div>Package:\n"
" <div>Package:\n"
" <t t-esc=\"ship_package_id.logistic_order_no or ''\"/>\n"
" <t t-esc=\"ship_package_id."
"logistic_order_no or ''\"></t>\n"
" </div>\n"
" </div>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" <div>Please know that there is an exception and the cause of the exception is\n"
" <div>Please know that there is an exception and the "
"cause of the exception is\n"
" <t t-if=\"object.exception_ids\">\n"
" <t t-if=\"object.exception_ids\">\n"
" <t t-esc=\"'/'.join([ex.reason for ex in object.exception_ids])\"/>\n"
" <t t-esc=\"'/'.join([ex.reason for ex in object."
"exception_ids])\"></t>\n"
" </t>\n"
" </t>\n"
" <t t-if=\"not object.exception_ids\">\n"
" <t t-if=\"not object.exception_ids\">\n"
" No Exception\n"
" No Exception\n"
...
@@ -99,26 +107,31 @@ msgid ""
...
@@ -99,26 +107,31 @@ msgid ""
"<div style=\"margin: 0px; padding: 0px;\">\n"
"<div style=\"margin: 0px; padding: 0px;\">\n"
" <p style=\"margin: 0px; padding: 0px;\">\n"
" <p style=\"margin: 0px; padding: 0px;\">\n"
" 您好\n"
" 您好\n"
" <br
/
>\n"
" <br>\n"
" <!-- 检查 big_package_ids 是否有值 -->\n"
" <!-- 检查 big_package_ids 是否有值 -->\n"
" <t t-if=\"object.big_package_ids\">\n"
" <t t-if=\"object.big_package_ids\">\n"
" <t t-foreach=\"object.big_package_ids\" t-as=\"big_package_id\">\n"
" <t t-foreach=\"object.big_package_ids\" t-"
"as=\"big_package_id\">\n"
" <div>包裹:\n"
" <div>包裹:\n"
" <t t-esc=\"big_package_id.big_package_no or ''\"/>\n"
" <t t-esc=\"big_package_id.big_package_no or "
"''\"></t>\n"
" </div>\n"
" </div>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" <!-- 检查 ship_package_ids 是否有值 -->\n"
" <!-- 检查 ship_package_ids 是否有值 -->\n"
" <t t-if=\"object.ship_package_ids\">\n"
" <t t-if=\"object.ship_package_ids\">\n"
" <t t-foreach=\"object.ship_package_ids\" t-as=\"ship_package_id\">\n"
" <t t-foreach=\"object.ship_package_ids\" t-"
"as=\"ship_package_id\">\n"
" <div>包裹:\n"
" <div>包裹:\n"
" <t t-esc=\"ship_package_id.logistic_order_no or ''\"/>\n"
" <t t-esc=\"ship_package_id."
"logistic_order_no or ''\"></t>\n"
" </div>\n"
" </div>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" </t>\n"
" <div>出现异常,异常原因:\n"
" <div>出现异常,异常原因:\n"
" <t t-if=\"object.exception_ids\">\n"
" <t t-if=\"object.exception_ids\">\n"
" <t t-esc=\"'/'.join([ex.reason for ex in object.exception_ids])\"/>,请知晓。\n"
" <t t-esc=\"'/'.join([ex.reason for ex in object."
"exception_ids])\"></t>,请知晓。\n"
" </t>\n"
" </t>\n"
" <t t-if=\"not object.exception_ids\">\n"
" <t t-if=\"not object.exception_ids\">\n"
" 无异常,请知晓。\n"
" 无异常,请知晓。\n"
...
@@ -380,7 +393,6 @@ msgstr "添加异常信息"
...
@@ -380,7 +393,6 @@ msgstr "添加异常信息"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: model_terms:ir.ui.view,arch_db:ccs_base.form_cc_big_package_view
#: model_terms:ir.ui.view,arch_db:ccs_base.form_cc_big_package_view
#: model_terms:ir.ui.view,arch_db:ccs_base.form_cc_ship_package_view
#: model_terms:ir.ui.view,arch_db:ccs_base.form_cc_ship_package_view
#, python-format
#, python-format
...
@@ -836,7 +848,6 @@ msgstr "已理货"
...
@@ -836,7 +848,6 @@ msgstr "已理货"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
#: code:addons/ccs_base/wizard/add_exception_info_wizard.py:0
#: code:addons/ccs_base/wizard/add_exception_info_wizard.py:0
#: code:addons/ccs_base/wizard/add_exception_info_wizard.py:0
#: model:ir.model.fields.selection,name:ccs_base.selection__add_exception_info_wizard__email_language__zh_cn
#: model:ir.model.fields.selection,name:ccs_base.selection__add_exception_info_wizard__email_language__zh_cn
#, python-format
#, python-format
msgid "Chinese"
msgid "Chinese"
...
@@ -929,6 +940,11 @@ msgstr "对应大包状态"
...
@@ -929,6 +940,11 @@ msgstr "对应大包状态"
msgid "Corresponding to the status of the package"
msgid "Corresponding to the status of the package"
msgstr "对应小包状态"
msgstr "对应小包状态"
#. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_cc_last_mile_provider__logo
msgid "Courier Logo"
msgstr "快递logo"
#. module: ccs_base
#. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_cc_last_mile_provider__name
#: model:ir.model.fields,field_description:ccs_base.field_cc_last_mile_provider__name
msgid "Courier Name"
msgid "Courier Name"
...
@@ -1244,7 +1260,6 @@ msgstr "目的地港口代码"
...
@@ -1244,7 +1260,6 @@ msgstr "目的地港口代码"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
#: code:addons/ccs_base/wizard/add_exception_info_wizard.py:0
#: code:addons/ccs_base/wizard/add_exception_info_wizard.py:0
#: code:addons/ccs_base/wizard/add_exception_info_wizard.py:0
#: model:ir.model.fields.selection,name:ccs_base.selection__add_exception_info_wizard__email_language__en_us
#: model:ir.model.fields.selection,name:ccs_base.selection__add_exception_info_wizard__email_language__en_us
#, python-format
#, python-format
msgid "English"
msgid "English"
...
@@ -1426,8 +1441,6 @@ msgstr "商品税号"
...
@@ -1426,8 +1441,6 @@ msgstr "商品税号"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_history_big_package.py:0
#: code:addons/ccs_base/models/cc_history_big_package.py:0
#: model:ir.model.fields,field_description:ccs_base.field_cc_big_package__goods_ids
#: model:ir.model.fields,field_description:ccs_base.field_cc_big_package__goods_ids
#: model:ir.model.fields,field_description:ccs_base.field_cc_bl__good_ids
#: model:ir.model.fields,field_description:ccs_base.field_cc_bl__good_ids
...
@@ -1950,8 +1963,8 @@ msgid "Link"
...
@@ -1950,8 +1963,8 @@ msgid "Link"
msgstr "链接"
msgstr "链接"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-javascript
#. odoo-javascript
#. odoo-python
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/static/src/views/list.xml:0
#: code:addons/ccs_base/static/src/views/list.xml:0
#, python-format
#, python-format
...
@@ -2233,7 +2246,7 @@ msgstr ""
...
@@ -2233,7 +2246,7 @@ msgstr ""
#: model:ir.model.fields,help:ccs_base.field_cc_history_ship_package__message_needaction_counter
#: model:ir.model.fields,help:ccs_base.field_cc_history_ship_package__message_needaction_counter
#: model:ir.model.fields,help:ccs_base.field_cc_ship_package__message_needaction_counter
#: model:ir.model.fields,help:ccs_base.field_cc_ship_package__message_needaction_counter
#: model:ir.model.fields,help:ccs_base.field_order_state_change_rule__message_needaction_counter
#: model:ir.model.fields,help:ccs_base.field_order_state_change_rule__message_needaction_counter
msgid "Number of messages
which requires an
action"
msgid "Number of messages
requiring
action"
msgstr ""
msgstr ""
#. module: ccs_base
#. module: ccs_base
...
@@ -2389,13 +2402,26 @@ msgstr "托盘号"
...
@@ -2389,13 +2402,26 @@ msgstr "托盘号"
msgid "Pallet Usage Date"
msgid "Pallet Usage Date"
msgstr "托盘使用日期"
msgstr "托盘使用日期"
#. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_cc_last_mile_provider__placement_area
msgid "Placement Area"
msgstr "摆放区域"
#. module: ccs_base
#. odoo-python
#: code:addons/ccs_base/models/cc_last_mile_provider.py:0
#, python-format
msgid ""
"Placement Area must be unique !"
msgstr "摆放区域必须唯一!"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#, python-format
#, python-format
msgid ""
msgid ""
"Please configure the default customs clearance status of the bill of
loading
"
"Please configure the default customs clearance status of the bill of "
" node type first."
"
loading
node type first."
msgstr "请先配置默认的提单节点类型的清关节点"
msgstr "请先配置默认的提单节点类型的清关节点"
#. module: ccs_base
#. module: ccs_base
...
@@ -2910,7 +2936,6 @@ msgstr "节点序号"
...
@@ -2910,7 +2936,6 @@ msgstr "节点序号"
#. module: ccs_base
#. module: ccs_base
#. odoo-python
#. odoo-python
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_bill_loading.py:0
#: code:addons/ccs_base/models/cc_history_big_package.py:0
#: code:addons/ccs_base/models/cc_history_big_package.py:0
#: model:ir.actions.act_window,name:ccs_base.action_cc_ship_package
#: model:ir.actions.act_window,name:ccs_base.action_cc_ship_package
#: model:ir.model,name:ccs_base.model_cc_history_ship_package
#: model:ir.model,name:ccs_base.model_cc_history_ship_package
...
@@ -3556,8 +3581,8 @@ msgstr "【清关公司】还没!点击左上角的创建按钮,沙发就是
...
@@ -3556,8 +3581,8 @@ msgstr "【清关公司】还没!点击左上角的创建按钮,沙发就是
#. module: ccs_base
#. module: ccs_base
#: model_terms:ir.actions.act_window,help:ccs_base.action_cc_clearance_file
#: model_terms:ir.actions.act_window,help:ccs_base.action_cc_clearance_file
msgid ""
msgid ""
"[Clearance File] Not yet! Click the Create button in the top left corner
and
"
"[Clearance File] Not yet! Click the Create button in the top left corner "
" the sofa is yours!"
"
and
the sofa is yours!"
msgstr "【清关文件】 还没有!点击左上角的“创建”按钮,沙发就是你的了!"
msgstr "【清关文件】 还没有!点击左上角的“创建”按钮,沙发就是你的了!"
#. module: ccs_base
#. module: ccs_base
...
@@ -3608,6 +3633,11 @@ msgstr "【小包】 还没有!点击左上角的“创建”按钮,沙发
...
@@ -3608,6 +3633,11 @@ msgstr "【小包】 还没有!点击左上角的“创建”按钮,沙发
msgid "base_info"
msgid "base_info"
msgstr "基本信息"
msgstr "基本信息"
#. module: ccs_base
#: model_terms:ir.ui.view,arch_db:ccs_base.res_config_settings_view_form_auto_push
msgid "pda扫码配置"
msgstr ""
#. module: ccs_base
#. module: ccs_base
#: model:ir.model.fields,help:ccs_base.field_add_exception_info_wizard__action_type
#: model:ir.model.fields,help:ccs_base.field_add_exception_info_wizard__action_type
msgid "ship package/big package"
msgid "ship package/big package"
...
@@ -3627,7 +3657,18 @@ msgstr ""
...
@@ -3627,7 +3657,18 @@ msgstr ""
#. module: ccs_base
#. module: ccs_base
#: model:mail.template,subject:ccs_base.email_template_exception_notification
#: model:mail.template,subject:ccs_base.email_template_exception_notification
msgid "{{ ('大包异常' if object.action_type == 'big package' else '小包异常') }}"
msgid ""
"{{ ('大包异常' if object.action_type == 'big package' else '小包异常') }}"
msgstr ""
#. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_res_config_settings__package_scan_min
msgid "一键全扫完成时间(min)"
msgstr ""
#. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_res_config_settings__is_package_scan
msgid "一键全扫开关"
msgstr ""
msgstr ""
#. module: ccs_base
#. module: ccs_base
...
@@ -3781,6 +3822,11 @@ msgstr ""
...
@@ -3781,6 +3822,11 @@ msgstr ""
msgid "请求id"
msgid "请求id"
msgstr ""
msgstr ""
#. module: ccs_base
#: model:ir.model.fields,help:ccs_base.field_res_config_settings__package_scan_min
msgid "输入示范:10,即表示在10分钟内大包时间随机分配,并不能重复"
msgstr ""
#. module: ccs_base
#. module: ccs_base
#: model_terms:ir.ui.view,arch_db:ccs_base.search_history_tt_api_log_view
#: model_terms:ir.ui.view,arch_db:ccs_base.search_history_tt_api_log_view
msgid "近30日日志"
msgid "近30日日志"
...
...
ccs_base/models/cc_exception_info.py
浏览文件 @
b85c538a
import
random
from
odoo
import
models
,
fields
,
api
from
odoo
import
models
,
fields
,
api
...
@@ -21,7 +20,7 @@ class CCExceptionInfo(models.Model):
...
@@ -21,7 +20,7 @@ class CCExceptionInfo(models.Model):
# 异常编码增加唯一约束
# 异常编码增加唯一约束
_sql_constraints
=
[(
'exception_code_uniq'
,
'unique(exception_code)'
,
'The Exception Code must be unique.'
)]
_sql_constraints
=
[(
'exception_code_uniq'
,
'unique(exception_code)'
,
'The Exception Code must be unique.'
)]
def
search_exception_info
(
self
,
pda_lang
=
False
):
def
search_exception_info
(
self
):
"""
"""
查询包裹异常原因
查询包裹异常原因
:return:
:return:
...
...
ccs_base/models/cc_last_mile_provider.py
浏览文件 @
b85c538a
...
@@ -10,23 +10,70 @@ class CCLastMileProvider(models.Model):
...
@@ -10,23 +10,70 @@ class CCLastMileProvider(models.Model):
def
_check_matching_value
(
self
):
def
_check_matching_value
(
self
):
for
record
in
self
:
for
record
in
self
:
if
record
.
matching_value
:
if
record
.
matching_value
:
values
=
record
.
matching_value
.
split
(
'
\n
'
)
# 将当前记录的值转换为小写
existing_values
=
'
\n
'
.
join
(
self
.
search
([(
'id'
,
'!='
,
record
.
id
)])
.
mapped
(
'matching_value'
))
.
split
(
'
\n
'
)
values
=
[
value
.
lower
()
for
value
in
record
.
matching_value
.
split
(
'
\n
'
)]
# 获取其他记录的所有匹配值并转换为小写
existing_values
=
[
value
.
lower
()
for
value
in
'
\n
'
.
join
(
self
.
search
(
[(
'id'
,
'!='
,
record
.
id
)])
.
mapped
(
'matching_value'
))
.
split
(
'
\n
'
)]
# 检查是否有重复值(不区分大小写)
if
len
(
values
)
!=
len
(
set
(
values
))
or
any
(
value
in
existing_values
for
value
in
values
):
if
len
(
values
)
!=
len
(
set
(
values
))
or
any
(
value
in
existing_values
for
value
in
values
):
raise
ValidationError
(
_
(
"Matching values must be unique!"
))
raise
ValidationError
(
_
(
"Matching values must be unique!"
))
name
=
fields
.
Char
(
string
=
'Courier Name'
,
required
=
True
)
# 快递名称
@api.constrains
(
'placement_area'
)
def
_check_placement_area_unique
(
self
):
for
record
in
self
:
if
record
.
placement_area
:
placement_area
=
self
.
env
[
'common.common'
]
.
process_match_str
(
record
.
placement_area
)
# 检查所有记录的处理后值是否有重复
pro_map
=
self
.
get_all_placement_area
(
[(
'id'
,
'!='
,
record
.
id
),
(
'placement_area'
,
'!='
,
False
)])
pro_id
=
pro_map
.
get
(
placement_area
)
if
pro_id
:
raise
ValidationError
(
_
(
"Placement Area must be unique !"
))
logo
=
fields
.
Binary
(
'Courier Logo'
)
# 快递logo,英文
name
=
fields
.
Char
(
string
=
'Courier Name'
,
required
=
True
,
translate
=
True
)
# 快递名称
abbreviation
=
fields
.
Char
(
string
=
'Abbreviation'
,
required
=
True
)
# 简称
abbreviation
=
fields
.
Char
(
string
=
'Abbreviation'
,
required
=
True
)
# 简称
tape_color_value
=
fields
.
Char
(
string
=
'Tape Color Value'
)
# 胶带色值
tape_color_value
=
fields
.
Char
(
string
=
'Tape Color Value'
)
# 胶带色值
active
=
fields
.
Boolean
(
'Active'
,
default
=
True
)
# 有效☑️
active
=
fields
.
Boolean
(
'Active'
,
default
=
True
)
# 有效☑️
matching_value
=
fields
.
Text
(
string
=
'Matching Value'
)
# 尾程服务商匹配值
matching_value
=
fields
.
Text
(
string
=
'Matching Value'
)
# 尾程服务商匹配值
placement_area
=
fields
.
Char
(
'Placement Area'
)
# 摆放区域,英文
def
match_provider
(
self
,
provider_name
):
def
match_provider
(
self
,
provider_name
):
"""Check if the provider name exists in matching values and return the record."""
"""Check if the provider name exists in matching values and return the record."""
# 将输入的 provider_name 转换为小写
provider_name_lower
=
provider_name
.
lower
()
# 查询所有匹配的记录
# 查询所有匹配的记录
matching_records
=
self
.
search
([])
matching_records
=
self
.
s
udo
()
.
s
earch
([])
# 检查是否有记录的 matching_value 包含 provider_name
# 检查是否有记录的 matching_value 包含 provider_name
(不区分大小写)
for
record
in
matching_records
:
for
record
in
matching_records
:
if
provider_name
in
record
.
matching_value
.
split
(
'
\n
'
):
if
record
.
matching_value
:
return
record
# 返回找到的记录
# 将匹配值转换为小写进行比较
matching_values
=
[
value
.
lower
()
for
value
in
record
.
matching_value
.
split
(
'
\n
'
)]
if
provider_name_lower
in
matching_values
:
return
record
# 返回找到的记录
return
False
# 如果没有找到,返回 None
return
False
# 如果没有找到,返回 None
def
get_all_placement_area
(
self
,
domain
=
[]):
"""
获取所有摆放区域
"""
all_providers
=
self
.
sudo
()
.
search
(
domain
or
[])
provider_map
=
{
self
.
env
[
'common.common'
]
.
process_match_str
(
provider
.
placement_area
):
provider
.
id
for
provider
in
all_providers
}
return
provider_map
def
search_pro_info
(
self
):
base_url
=
self
.
env
[
'ir.config_parameter'
]
.
sudo
()
.
get_param
(
'web.base.url'
)
return
{
'provider_name'
:
self
.
name
,
# 尾程快递名称
"abbreviation"
:
self
.
abbreviation
or
''
,
# 简称
'placement_area'
:
self
.
placement_area
or
''
,
# 摆放区域
'tape_color_value'
:
self
.
tape_color_value
or
''
,
# 胶带色值
'matching_value'
:
self
.
matching_value
or
''
,
# 匹配值
'logo'
:
"
%
s/web/image/
%
s/
%
s/logo"
%
(
base_url
,
self
.
_name
,
self
.
id
)
if
self
.
logo
else
''
,
# 快递logo
}
ccs_base/models/common_common.py
浏览文件 @
b85c538a
...
@@ -16,6 +16,16 @@ class CommonCommon(models.Model):
...
@@ -16,6 +16,16 @@ class CommonCommon(models.Model):
_name
=
'common.common'
_name
=
'common.common'
_description
=
u'公用基础类'
_description
=
u'公用基础类'
# 去杠去空格转大写
def
process_match_str
(
self
,
input_str
):
"""
处理匹配的字符串,去除杠和空格,并转换为大写
"""
if
input_str
:
return
input_str
.
replace
(
'-'
,
''
)
.
replace
(
'/'
,
''
)
.
replace
(
' '
,
''
)
.
upper
()
return
input_str
def
get_local_time
(
self
,
local_time
=
None
,
user_obj
=
False
):
def
get_local_time
(
self
,
local_time
=
None
,
user_obj
=
False
):
"""获取Odoo时区的时间
"""获取Odoo时区的时间
Args:
Args:
...
@@ -30,8 +40,10 @@ class CommonCommon(models.Model):
...
@@ -30,8 +40,10 @@ class CommonCommon(models.Model):
if
not
user_obj
:
if
not
user_obj
:
user_obj
=
self
.
env
.
user
user_obj
=
self
.
env
.
user
user_tz
=
user_obj
.
tz
or
'UTC'
user_tz
=
user_obj
.
tz
or
'UTC'
timezone_offset
=
self
.
env
[
'common.common'
]
.
sudo
()
.
get_time_zone
(
user_tz
)
timezone_offset
=
self
.
env
[
'common.common'
]
.
sudo
(
local_time
=
local_time
+
datetime
.
timedelta
(
hours
=
int
(
timezone_offset
))
)
.
get_time_zone
(
user_tz
)
local_time
=
local_time
+
\
datetime
.
timedelta
(
hours
=
int
(
timezone_offset
))
return
local_time
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
),
timezone_offset
return
local_time
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
),
timezone_offset
except
Exception
as
e
:
except
Exception
as
e
:
# 如果出现任何错误,返回UTC时间
# 如果出现任何错误,返回UTC时间
...
@@ -51,8 +63,10 @@ class CommonCommon(models.Model):
...
@@ -51,8 +63,10 @@ class CommonCommon(models.Model):
if
not
user_obj
:
if
not
user_obj
:
user_obj
=
self
.
env
.
user
user_obj
=
self
.
env
.
user
user_tz
=
user_obj
.
tz
or
'UTC'
user_tz
=
user_obj
.
tz
or
'UTC'
timezone_offset
=
self
.
env
[
'common.common'
]
.
sudo
()
.
get_time_zone
(
user_tz
)
timezone_offset
=
self
.
env
[
'common.common'
]
.
sudo
(
local_time
=
local_time
+
datetime
.
timedelta
(
hours
=
int
(
timezone_offset
))
)
.
get_time_zone
(
user_tz
)
local_time
=
local_time
+
\
datetime
.
timedelta
(
hours
=
int
(
timezone_offset
))
local_tz
=
pytz
.
timezone
(
user_tz
)
local_tz
=
pytz
.
timezone
(
user_tz
)
# 确保时间是本地时区
# 确保时间是本地时区
if
local_time
.
tzinfo
is
None
:
if
local_time
.
tzinfo
is
None
:
...
...
ccs_base/models/res_config_setting.py
浏览文件 @
b85c538a
...
@@ -12,7 +12,10 @@ class ResConfigSettings(models.TransientModel):
...
@@ -12,7 +12,10 @@ class ResConfigSettings(models.TransientModel):
_inherit
=
'res.config.settings'
_inherit
=
'res.config.settings'
before_min
=
fields
.
Integer
(
'清关时间取值(早于清关结束)'
)
before_min
=
fields
.
Integer
(
'清关时间取值(早于清关结束)'
)
package_scan_min
=
fields
.
Integer
(
'一键全扫完成时间(min)'
,
help
=
'输入示范:10,即表示在10分钟内大包时间随机分配,并不能重复'
)
package_scan_min
=
fields
.
Integer
(
'一键全扫完成时间(min)'
,
help
=
'输入示范:10,即表示在10分钟内大包时间随机分配,并不能重复'
)
is_package_scan
=
fields
.
Boolean
(
'一键全扫开关'
,
default
=
False
,
config_parameter
=
'is_package_scan'
)
@api.model
@api.model
def
get_values
(
self
):
def
get_values
(
self
):
...
@@ -24,10 +27,9 @@ class ResConfigSettings(models.TransientModel):
...
@@ -24,10 +27,9 @@ class ResConfigSettings(models.TransientModel):
config
=
self
.
env
[
'ir.config_parameter'
]
.
sudo
()
config
=
self
.
env
[
'ir.config_parameter'
]
.
sudo
()
before_min
=
config
.
get_param
(
'before_min'
,
default
=
10
)
before_min
=
config
.
get_param
(
'before_min'
,
default
=
10
)
package_scan_min
=
config
.
get_param
(
'package_scan_min'
,
default
=
10
)
package_scan_min
=
config
.
get_param
(
'package_scan_min'
,
default
=
10
)
values
.
update
(
values
.
update
(
before_min
=
before_min
,
before_min
=
before_min
,
package_scan_min
=
package_scan_min
,
package_scan_min
=
package_scan_min
)
)
return
values
return
values
...
...
ccs_base/views/cc_last_mile_provider_views.xml
浏览文件 @
b85c538a
...
@@ -7,11 +7,13 @@
...
@@ -7,11 +7,13 @@
<sheet>
<sheet>
<group>
<group>
<group>
<group>
<field
name=
"logo"
widget=
"image"
class=
"oe_avatar"
/>
<field
name=
"name"
/>
<!-- 快递名称 -->
<field
name=
"name"
/>
<!-- 快递名称 -->
<field
name=
"abbreviation"
/>
<!-- 简称 -->
<field
name=
"abbreviation"
/>
<!-- 简称 -->
<field
name=
"tape_color_value"
widget=
"color"
required=
"1"
/>
<!-- 胶带色值 -->
<field
name=
"tape_color_value"
widget=
"color"
required=
"1"
/>
<!-- 胶带色值 -->
<field
name=
"matching_value"
<field
name=
"matching_value"
placeholder=
"Multiple entries can be made, one matching value per line"
/>
<!-- 尾程服务商匹配值 -->
placeholder=
"Multiple entries can be made, one matching value per line"
/>
<!-- 尾程服务商匹配值 -->
<field
name=
"placement_area"
/>
</group>
</group>
<group>
<group>
<field
name=
"active"
/>
<!-- 有效☑️ -->
<field
name=
"active"
/>
<!-- 有效☑️ -->
...
@@ -31,6 +33,7 @@
...
@@ -31,6 +33,7 @@
<field
name=
"abbreviation"
/>
<!-- 简称 -->
<field
name=
"abbreviation"
/>
<!-- 简称 -->
<field
name=
"tape_color_value"
/>
<!-- 胶带色值 -->
<field
name=
"tape_color_value"
/>
<!-- 胶带色值 -->
<field
name=
"matching_value"
/>
<!-- 尾程服务商匹配值 -->
<field
name=
"matching_value"
/>
<!-- 尾程服务商匹配值 -->
<field
name=
"placement_area"
/>
<!-- 摆放区域 -->
<field
name=
"active"
/>
<!-- 有效☑️ -->
<field
name=
"active"
/>
<!-- 有效☑️ -->
</tree>
</tree>
</field>
</field>
...
@@ -43,6 +46,7 @@
...
@@ -43,6 +46,7 @@
<search
string=
"Last Mile Provider"
>
<search
string=
"Last Mile Provider"
>
<field
name=
"name"
/>
<field
name=
"name"
/>
<field
name=
"abbreviation"
/>
<field
name=
"abbreviation"
/>
<field
name=
"placement_area"
/>
</search>
</search>
</field>
</field>
</record>
</record>
...
...
ccs_base/views/res_config_setting.xml
浏览文件 @
b85c538a
...
@@ -27,6 +27,11 @@
...
@@ -27,6 +27,11 @@
<div
class=
"col-12 col-lg-6 o_setting_box"
>
<div
class=
"col-12 col-lg-6 o_setting_box"
>
<div
class=
"o_setting_left_pane"
/>
<div
class=
"o_setting_left_pane"
/>
<div
class=
"o_setting_right_pane"
>
<div
class=
"o_setting_right_pane"
>
<div
class=
"text-muted"
>
<label
for=
"is_package_scan"
/>
<field
name=
"is_package_scan"
/>
</div>
<div
class=
"text-muted"
>
<div
class=
"text-muted"
>
<label
for=
"package_scan_min"
/>
<label
for=
"package_scan_min"
/>
<field
name=
"package_scan_min"
/>
<field
name=
"package_scan_min"
/>
...
...
ccs_connect_tiktok/controllers/__init__.py
浏览文件 @
b85c538a
from
.
import
tt_controllers
from
.
import
tt_controllers
from
.
import
order_controller
from
.
import
order_controller
from
.
import
binary
ccs_connect_tiktok/controllers/binary.py
0 → 100644
浏览文件 @
b85c538a
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import
logging
from
odoo.addons.web.controllers.binary
import
Binary
try
:
from
werkzeug.utils
import
send_file
except
ImportError
:
from
odoo.tools._vendor.send_file
import
send_file
from
odoo
import
http
from
odoo.exceptions
import
UserError
from
odoo.http
import
request
from
odoo.tools
import
replace_exceptions
,
str2bool
from
odoo.tools.image
import
image_guess_size_from_field_name
_logger
=
logging
.
getLogger
(
__name__
)
BAD_X_SENDFILE_ERROR
=
"""
\
Odoo is running with --x-sendfile but is receiving /web/filestore requests.
With --x-sendfile enabled, NGINX should be serving the
/web/filestore route, however Odoo is receiving the
request.
This usually indicates that NGINX is badly configured,
please make sure the /web/filestore location block exists
in your configuration file and that it is similar to:
location /web/filestore {{
internal;
alias {data_dir}/filestore;
}}
"""
def
clean
(
name
):
return
name
.
replace
(
'
\x3c
'
,
''
)
class
AttachmentBinary
(
Binary
):
@http.route
([
'/web/image'
,
'/web/image/<string:xmlid>'
,
'/web/image/<string:xmlid>/<string:filename>'
,
'/web/image/<string:xmlid>/<int:width>x<int:height>'
,
'/web/image/<string:xmlid>/<int:width>x<int:height>/<string:filename>'
,
'/web/image/<string:model>/<int:id>/<string:field>'
,
'/web/image/<string:model>/<int:id>/<string:field>/<string:filename>'
,
'/web/image/<string:model>/<int:id>/<string:field>/<int:width>x<int:height>'
,
'/web/image/<string:model>/<int:id>/<string:field>/<int:width>x<int:height>/<string:filename>'
,
'/web/image/<int:id>'
,
'/web/image/<int:id>/<string:filename>'
,
'/web/image/<int:id>/<int:width>x<int:height>'
,
'/web/image/<int:id>/<int:width>x<int:height>/<string:filename>'
,
'/web/image/<int:id>-<string:unique>'
,
'/web/image/<int:id>-<string:unique>/<string:filename>'
,
'/web/image/<int:id>-<string:unique>/<int:width>x<int:height>'
,
'/web/image/<int:id>-<string:unique>/<int:width>x<int:height>/<string:filename>'
],
type
=
'http'
,
auth
=
"public"
,
cors
=
"*"
)
# pylint: disable=redefined-builtin,invalid-name
def
content_image
(
self
,
xmlid
=
None
,
model
=
'ir.attachment'
,
id
=
None
,
field
=
'raw'
,
filename_field
=
'name'
,
filename
=
None
,
mimetype
=
None
,
unique
=
False
,
download
=
False
,
width
=
0
,
height
=
0
,
crop
=
False
,
access_token
=
None
,
nocache
=
False
):
try
:
record
=
request
.
env
[
'ir.binary'
]
.
sudo
()
.
_find_record
(
xmlid
,
model
,
id
and
int
(
id
),
access_token
)
stream
=
request
.
env
[
'ir.binary'
]
.
sudo
()
.
_get_image_stream_from
(
record
,
field
,
filename
=
filename
,
filename_field
=
filename_field
,
mimetype
=
mimetype
,
width
=
int
(
width
),
height
=
int
(
height
),
crop
=
crop
,
)
except
UserError
as
exc
:
if
download
:
raise
request
.
not_found
()
from
exc
# Use the ratio of the requested field_name instead of "raw"
if
(
int
(
width
),
int
(
height
))
==
(
0
,
0
):
width
,
height
=
image_guess_size_from_field_name
(
field
)
record
=
request
.
env
.
ref
(
'web.image_placeholder'
)
.
sudo
()
stream
=
request
.
env
[
'ir.binary'
]
.
_get_image_stream_from
(
record
,
'raw'
,
width
=
int
(
width
),
height
=
int
(
height
),
crop
=
crop
,
)
send_file_kwargs
=
{
'as_attachment'
:
download
}
if
unique
:
send_file_kwargs
[
'immutable'
]
=
True
send_file_kwargs
[
'max_age'
]
=
http
.
STATIC_CACHE_LONG
if
nocache
:
send_file_kwargs
[
'max_age'
]
=
None
return
stream
.
get_response
(
**
send_file_kwargs
)
@http.route
([
'/web/content'
,
'/web/content/<string:xmlid>'
,
'/web/content/<string:xmlid>/<string:filename>'
,
'/web/content/<int:id>'
,
'/web/content/<int:id>/<string:filename>'
,
'/web/content/<string:model>/<int:id>/<string:field>'
,
'/web/content/<string:model>/<int:id>/<string:field>/<string:filename>'
],
type
=
'http'
,
auth
=
"public"
,
cors
=
"*"
)
# pylint: disable=redefined-builtin,invalid-name
def
content_common
(
self
,
xmlid
=
None
,
model
=
'ir.attachment'
,
id
=
None
,
field
=
'raw'
,
filename
=
None
,
filename_field
=
'name'
,
mimetype
=
None
,
unique
=
False
,
download
=
False
,
access_token
=
None
,
nocache
=
False
):
with
replace_exceptions
(
UserError
,
by
=
request
.
not_found
()):
record
=
request
.
env
[
'ir.binary'
]
.
sudo
()
.
_find_record
(
xmlid
,
model
,
id
and
int
(
id
),
access_token
)
stream
=
request
.
env
[
'ir.binary'
]
.
sudo
()
.
_get_stream_from
(
record
,
field
,
filename
,
filename_field
,
mimetype
)
if
request
.
httprequest
.
args
.
get
(
'access_token'
):
stream
.
public
=
True
send_file_kwargs
=
{
'as_attachment'
:
str2bool
(
download
)}
if
unique
:
send_file_kwargs
[
'immutable'
]
=
True
send_file_kwargs
[
'max_age'
]
=
http
.
STATIC_CACHE_LONG
if
nocache
:
send_file_kwargs
[
'max_age'
]
=
None
return
stream
.
get_response
(
**
send_file_kwargs
)
ccs_connect_tiktok/controllers/order_controller.py
浏览文件 @
b85c538a
...
@@ -49,7 +49,8 @@ class OrderController(http.Controller):
...
@@ -49,7 +49,8 @@ class OrderController(http.Controller):
# system_user = system_user.with_context(lang=lang)
# system_user = system_user.with_context(lang=lang)
try
:
try
:
if
kwargs
.
get
(
'login'
)
and
kwargs
.
get
(
'password'
):
if
kwargs
.
get
(
'login'
)
and
kwargs
.
get
(
'password'
):
uid
=
request
.
session
.
authenticate
(
request
.
session
.
db
,
kwargs
[
'login'
],
kwargs
[
'password'
])
uid
=
request
.
session
.
authenticate
(
request
.
session
.
db
,
kwargs
[
'login'
],
kwargs
[
'password'
])
user
=
request
.
env
[
'res.users'
]
.
sudo
()
.
browse
(
uid
)
user
=
request
.
env
[
'res.users'
]
.
sudo
()
.
browse
(
uid
)
res
[
'user_info'
]
=
{
res
[
'user_info'
]
=
{
'id'
:
uid
,
# 用户id
'id'
:
uid
,
# 用户id
...
@@ -58,21 +59,37 @@ class OrderController(http.Controller):
...
@@ -58,21 +59,37 @@ class OrderController(http.Controller):
res
[
'state'
]
=
200
res
[
'state'
]
=
200
else
:
else
:
res
[
'state'
]
=
202
res
[
'state'
]
=
202
res
[
'message'
]
=
error_msg_dic
[
pda_lang
]
# _('Login name and password cannot be empty') # 登录名、密码不能为空
# _('Login name and password cannot be empty') # 登录名、密码不能为空
res
[
'message'
]
=
error_msg_dic
[
pda_lang
]
except
exceptions
.
AccessDenied
as
e
:
except
exceptions
.
AccessDenied
as
e
:
if
e
.
args
==
exceptions
.
AccessDenied
()
.
args
:
if
e
.
args
==
exceptions
.
AccessDenied
()
.
args
:
res
[
'message'
]
=
exceptions_msg_dic
[
pda_lang
]
# _("Wrong login/password") # 错误的登录名或密码
# _("Wrong login/password") # 错误的登录名或密码
res
[
'message'
]
=
exceptions_msg_dic
[
pda_lang
]
else
:
else
:
res
[
'message'
]
=
e
.
args
[
0
]
res
[
'message'
]
=
e
.
args
[
0
]
logging
.
info
(
'api_cc_login error:
%
s'
%
res
)
logging
.
info
(
'api_cc_login error:
%
s'
%
res
)
return
res
return
res
@http.route
(
'/api/one_key_full_scan/info'
,
type
=
'json'
,
auth
=
'public'
,
csrf
=
False
)
def
one_key_full_scan_info
(
self
):
"""
查询一键全扫信息接口,返回是否一键全扫和完成时间
入参:bl_no
"""
# kwargs = json.loads(request.httprequest.data)
res
=
{
'state'
:
201
,
'message'
:
''
}
res
[
'package_scan_min'
]
=
int
(
request
.
env
[
'res.config.settings'
]
.
sudo
()
.
get_values
()
.
get
(
'package_scan_min'
))
res
[
'is_package_scan'
]
=
bool
(
request
.
env
[
'ir.config_parameter'
]
.
sudo
(
)
.
get_param
(
'is_package_scan'
))
res
[
'state'
]
=
200
return
res
@http.route
(
'/api/bl/info'
,
type
=
'json'
,
auth
=
'public'
,
methods
=
[
'GET'
,
'POST'
],
csrf
=
False
)
@http.route
(
'/api/bl/info'
,
type
=
'json'
,
auth
=
'public'
,
methods
=
[
'GET'
,
'POST'
],
csrf
=
False
)
def
bl_info
(
self
):
def
bl_info
(
self
):
"""
"""
查看提单以及大包,小包和托盘信息
查看提单以及大包,小包和托盘信息
:param kwargs:
:return:
:return:
"""
"""
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
...
@@ -85,17 +102,22 @@ class OrderController(http.Controller):
...
@@ -85,17 +102,22 @@ class OrderController(http.Controller):
bl_no
=
kwargs
[
'bl_no'
]
bl_no
=
kwargs
[
'bl_no'
]
# bl_obj = request.env['cc.bl'].sudo().search([('bl_no', '=', bl_no)]) # 提单
# bl_obj = request.env['cc.bl'].sudo().search([('bl_no', '=', bl_no)]) # 提单
state_arr
=
[
'draft'
,
'ccing'
]
state_arr
=
[
'draft'
,
'ccing'
]
bl_obj
=
request
.
env
[
'cc.bl'
]
.
sudo
()
.
deal_bl_no
(
bl_no
)
# 提单号去掉杠和空格,并转换为小写
bl_obj
=
request
.
env
[
'cc.bl'
]
.
sudo
()
.
deal_bl_no
(
bl_no
)
# 提单号去掉杠和空格,并转换为小写
if
bl_obj
:
if
bl_obj
:
if
bl_obj
.
state
in
state_arr
:
if
bl_obj
.
state
in
state_arr
:
res
[
'bl_info'
]
=
bl_obj
.
search_bl_info
(
pda_lang
=
pda_lang
,
type
=
action_type
)
res
[
'bl_info'
]
=
bl_obj
.
search_bl_info
(
res
[
'package_scan_min'
]
=
int
(
request
.
env
[
'res.config.settings'
]
.
sudo
()
.
get_values
()
.
get
(
'package_scan_min'
))
pda_lang
=
pda_lang
,
type
=
action_type
)
res
[
'package_scan_min'
]
=
int
(
request
.
env
[
'res.config.settings'
]
.
sudo
()
.
get_values
()
.
get
(
'package_scan_min'
))
res
[
'state'
]
=
200
res
[
'state'
]
=
200
else
:
else
:
res
[
'message'
]
=
bill_state_msg_dic
[
pda_lang
]
# 没有在系统中找到未完成清关的该提单信息
# 没有在系统中找到未完成清关的该提单信息
res
[
'message'
]
=
bill_state_msg_dic
[
pda_lang
]
else
:
else
:
res
[
'state'
]
=
404
res
[
'state'
]
=
404
res
[
'message'
]
=
bill_noexist_msg_dic
[
pda_lang
]
# _('Bill of lading does not exist') # 提单不存在
# _('Bill of lading does not exist') # 提单不存在
res
[
'message'
]
=
bill_noexist_msg_dic
[
pda_lang
]
else
:
else
:
res
[
'state'
]
=
202
res
[
'state'
]
=
202
res
[
'message'
]
=
bill_null_msg_dic
[
res
[
'message'
]
=
bill_null_msg_dic
[
...
@@ -115,7 +137,6 @@ class OrderController(http.Controller):
...
@@ -115,7 +137,6 @@ class OrderController(http.Controller):
def
update_big_package_tally_detail
(
self
):
def
update_big_package_tally_detail
(
self
):
"""
"""
修改理货信息
修改理货信息
:param kwargs:
:return:
:return:
"""
"""
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
...
@@ -128,7 +149,8 @@ class OrderController(http.Controller):
...
@@ -128,7 +149,8 @@ class OrderController(http.Controller):
kwargs
.
get
(
'big_package_arr'
)
or
kwargs
.
get
(
'ship_package_arr'
)
or
kwargs
.
get
(
'pallet_arr'
)):
kwargs
.
get
(
'big_package_arr'
)
or
kwargs
.
get
(
'ship_package_arr'
)
or
kwargs
.
get
(
'pallet_arr'
)):
bl_no
=
kwargs
[
'bl_no'
]
bl_no
=
kwargs
[
'bl_no'
]
state_arr
=
[
'draft'
,
'ccing'
]
state_arr
=
[
'draft'
,
'ccing'
]
bl_obj
=
request
.
env
[
'cc.bl'
]
.
sudo
()
.
deal_bl_no
(
bl_no
)
# 提单号去掉杠和空格,并转换为小写
bl_obj
=
request
.
env
[
'cc.bl'
]
.
sudo
()
.
deal_bl_no
(
bl_no
)
# 提单号去掉杠和空格,并转换为小写
if
bl_obj
and
bl_obj
.
state
in
state_arr
:
if
bl_obj
and
bl_obj
.
state
in
state_arr
:
ship_packages
=
[]
ship_packages
=
[]
big_package_exception_arr
=
{}
big_package_exception_arr
=
{}
...
@@ -141,7 +163,8 @@ class OrderController(http.Controller):
...
@@ -141,7 +163,8 @@ class OrderController(http.Controller):
file_str
=
'big_package_no'
if
package_type
==
'big'
else
(
file_str
=
'big_package_no'
if
package_type
==
'big'
else
(
'logistic_order_no'
if
package_type
==
'ship'
else
'pallet_number'
)
# 大包号/物流订单号
'logistic_order_no'
if
package_type
==
'ship'
else
'pallet_number'
)
# 大包号/物流订单号
package_no
=
package_item
.
get
(
file_str
)
# 包裹号
package_no
=
package_item
.
get
(
file_str
)
# 包裹号
exception_cause_ids
=
package_item
.
get
(
'exception_cause_ids'
)
# 异常原因id数组
exception_cause_ids
=
package_item
.
get
(
'exception_cause_ids'
)
# 异常原因id数组
if
package_type
==
'pallet'
:
if
package_type
==
'pallet'
:
package_obj
=
request
.
env
[
'cc.big.package'
]
.
sudo
()
.
search
(
package_obj
=
request
.
env
[
'cc.big.package'
]
.
sudo
()
.
search
(
[(
'pallet_number'
,
'='
,
package_no
),
(
'bl_id'
,
'='
,
bl_obj
.
id
)])
# 多个
[(
'pallet_number'
,
'='
,
package_no
),
(
'bl_id'
,
'='
,
bl_obj
.
id
)])
# 多个
...
@@ -153,13 +176,16 @@ class OrderController(http.Controller):
...
@@ -153,13 +176,16 @@ class OrderController(http.Controller):
for
excep_item
in
exception_cause_ids
:
for
excep_item
in
exception_cause_ids
:
if
package_type
==
'ship'
:
if
package_type
==
'ship'
:
if
excep_item
not
in
ship_package_exception_arr
:
if
excep_item
not
in
ship_package_exception_arr
:
ship_package_exception_arr
[
excep_item
]
=
[]
ship_package_exception_arr
[
excep_item
]
=
[
]
ship_package_exception_arr
[
excep_item
]
+=
package_obj
.
ids
ship_package_exception_arr
[
excep_item
]
+=
package_obj
.
ids
else
:
else
:
if
excep_item
not
in
big_package_exception_arr
:
if
excep_item
not
in
big_package_exception_arr
:
big_package_exception_arr
[
excep_item
]
=
[]
big_package_exception_arr
[
excep_item
]
=
[
]
big_package_exception_arr
[
excep_item
]
+=
package_obj
.
ids
big_package_exception_arr
[
excep_item
]
+=
package_obj
.
ids
package_obj
.
update_exception_info
(
exception_cause_ids
)
# 修改异常信息
package_obj
.
update_exception_info
(
exception_cause_ids
)
# 修改异常信息
tally_time
=
package_item
.
get
(
'tally_time'
)
tally_time
=
package_item
.
get
(
'tally_time'
)
if
(
action_type
==
'tally'
and
package_item
.
get
(
'tally_state'
)
==
'checked_goods'
)
or
(
if
(
action_type
==
'tally'
and
package_item
.
get
(
'tally_state'
)
==
'checked_goods'
)
or
(
action_type
==
'handover'
and
package_item
.
get
(
action_type
==
'handover'
and
package_item
.
get
(
...
@@ -179,7 +205,8 @@ class OrderController(http.Controller):
...
@@ -179,7 +205,8 @@ class OrderController(http.Controller):
'tally_time'
:
tally_time
'tally_time'
:
tally_time
})
# 小包
})
# 小包
package_obj
.
update_big_package_info
(
action_type
=
action_type
,
package_obj
.
update_big_package_info
(
action_type
=
action_type
,
tally_state
=
package_item
.
get
(
'tally_state'
),
tally_state
=
package_item
.
get
(
'tally_state'
),
tally_user_id
=
package_item
.
get
(
tally_user_id
=
package_item
.
get
(
'tally_user_id'
),
'tally_user_id'
),
tally_time
=
tally_time
)
# 修改理货信息
tally_time
=
tally_time
)
# 修改理货信息
...
@@ -189,7 +216,8 @@ class OrderController(http.Controller):
...
@@ -189,7 +216,8 @@ class OrderController(http.Controller):
# 处理小包、大包和托盘
# 处理小包、大包和托盘
if
kwargs
.
get
(
'ship_package_arr'
):
if
kwargs
.
get
(
'ship_package_arr'
):
error_no_arr
=
process_packages
(
kwargs
[
'ship_package_arr'
],
'ship'
,
ship_packages
)
error_no_arr
=
process_packages
(
kwargs
[
'ship_package_arr'
],
'ship'
,
ship_packages
)
if
error_no_arr
:
if
error_no_arr
:
res
[
'message'
]
=
{
res
[
'message'
]
=
{
'en'
:
'Ship package number [
%
s] does not exist'
%
','
.
join
(
error_no_arr
),
'en'
:
'Ship package number [
%
s] does not exist'
%
','
.
join
(
error_no_arr
),
...
@@ -198,7 +226,8 @@ class OrderController(http.Controller):
...
@@ -198,7 +226,8 @@ class OrderController(http.Controller):
return
res
return
res
if
kwargs
.
get
(
'big_package_arr'
):
if
kwargs
.
get
(
'big_package_arr'
):
error_no_arr
=
process_packages
(
kwargs
[
'big_package_arr'
],
'big'
,
ship_packages
)
error_no_arr
=
process_packages
(
kwargs
[
'big_package_arr'
],
'big'
,
ship_packages
)
if
error_no_arr
:
if
error_no_arr
:
res
[
'message'
]
=
{
res
[
'message'
]
=
{
'en'
:
'Big package number [
%
s] does not exist'
%
','
.
join
(
error_no_arr
),
'en'
:
'Big package number [
%
s] does not exist'
%
','
.
join
(
error_no_arr
),
...
@@ -207,7 +236,8 @@ class OrderController(http.Controller):
...
@@ -207,7 +236,8 @@ class OrderController(http.Controller):
return
res
return
res
if
kwargs
.
get
(
'pallet_arr'
):
if
kwargs
.
get
(
'pallet_arr'
):
error_no_arr
=
process_packages
(
kwargs
[
'pallet_arr'
],
'pallet'
,
ship_packages
)
error_no_arr
=
process_packages
(
kwargs
[
'pallet_arr'
],
'pallet'
,
ship_packages
)
if
error_no_arr
:
if
error_no_arr
:
res
[
'message'
]
=
{
res
[
'message'
]
=
{
'en'
:
'Tray number [
%
s] does not have a corresponding big package'
%
','
.
join
(
'en'
:
'Tray number [
%
s] does not have a corresponding big package'
%
','
.
join
(
...
@@ -238,10 +268,12 @@ class OrderController(http.Controller):
...
@@ -238,10 +268,12 @@ class OrderController(http.Controller):
email_language
=
lang
)
email_language
=
lang
)
ship_wizard_obj
.
confirm
()
# 发送邮件
ship_wizard_obj
.
confirm
()
# 发送邮件
res
[
'state'
]
=
200
res
[
'state'
]
=
200
logging
.
info
(
'update_big_package_tally_detail ship_packages:
%
s'
%
len
(
ship_packages
))
logging
.
info
(
'update_big_package_tally_detail ship_packages:
%
s'
%
len
(
ship_packages
))
# 有小包 就更新小包状态和同步
# 有小包 就更新小包状态和同步
if
ship_packages
:
if
ship_packages
:
redis_conn
=
request
.
env
[
'common.common'
]
.
sudo
()
.
get_redis
()
redis_conn
=
request
.
env
[
'common.common'
]
.
sudo
(
)
.
get_redis
()
if
redis_conn
and
redis_conn
!=
'no'
:
if
redis_conn
and
redis_conn
!=
'no'
:
# redis_conn.lpush('push_ship_package_state', json.dumps(
# redis_conn.lpush('push_ship_package_state', json.dumps(
# {'bl_id': bl_obj.id, 'ship_package_ids': ship_package_ids}))
# {'bl_id': bl_obj.id, 'ship_package_ids': ship_package_ids}))
...
@@ -266,6 +298,152 @@ class OrderController(http.Controller):
...
@@ -266,6 +298,152 @@ class OrderController(http.Controller):
logging
.
info
(
'res:
%
s'
%
res
)
logging
.
info
(
'res:
%
s'
%
res
)
return
res
return
res
@http.route
(
'/api/update/pro/big/package/tally/detail'
,
type
=
'json'
,
auth
=
'public'
,
methods
=
[
'GET'
,
'POST'
],
csrf
=
False
)
def
update_pro_big_package_tally_detail
(
self
):
"""
修改尾程快递的理货信息
:return:
"""
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
pda_lang
=
kwargs
.
get
(
'pda_lang'
)
or
'zh'
res
=
{
'state'
:
201
,
'message'
:
''
}
action_type
=
kwargs
.
get
(
'action_type'
)
or
'tally'
# tally / handover
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'
)):
ship_packages
=
[]
big_package_exception_arr
=
{}
ship_package_exception_arr
=
{}
# 处理包裹信息
def
process_packages
(
package_arr
,
package_type
,
ship_packages
):
error_no_set
=
set
()
# 使用集合来存储错误信息
for
package_item
in
package_arr
:
file_str
=
'big_package_no'
if
package_type
==
'big'
else
(
'logistic_order_no'
if
package_type
==
'ship'
else
'pallet_number'
)
# 大包号/物流订单号
package_no
=
package_item
.
get
(
file_str
)
# 包裹号
exception_cause_ids
=
package_item
.
get
(
'exception_cause_ids'
)
# 异常原因id数组
package_obj
=
request
.
env
[
f
'cc.{package_type}.package'
]
.
sudo
()
.
search
(
[(
file_str
,
'='
,
package_no
)])
# 小包/大包 1个
if
package_obj
:
if
exception_cause_ids
:
for
excep_item
in
exception_cause_ids
:
if
package_type
==
'ship'
:
if
excep_item
not
in
ship_package_exception_arr
:
ship_package_exception_arr
[
excep_item
]
=
[
]
ship_package_exception_arr
[
excep_item
]
+=
package_obj
.
ids
else
:
if
excep_item
not
in
big_package_exception_arr
:
big_package_exception_arr
[
excep_item
]
=
[
]
big_package_exception_arr
[
excep_item
]
+=
package_obj
.
ids
package_obj
.
update_exception_info
(
exception_cause_ids
)
# 修改异常信息
tally_time
=
package_item
.
get
(
'tally_time'
)
if
(
action_type
==
'tally'
and
package_item
.
get
(
'tally_state'
)
==
'checked_goods'
)
or
(
action_type
==
'handover'
and
package_item
.
get
(
'tally_state'
)
==
'handover_completed'
):
if
package_type
==
'ship'
:
ship_packages
.
append
({
'id'
:
[
package_obj
.
id
],
'bl_id'
:
package_obj
.
bl_id
.
id
,
'tally_time'
:
tally_time
})
else
:
for
package
in
package_obj
:
if
(
action_type
==
'tally'
and
package
.
tally_state
==
'unprocessed_goods'
)
or
(
action_type
==
'handover'
and
package
.
tally_state
in
(
'unprocessed_goods'
,
'checked_goods'
)):
ship_packages
.
append
({
'id'
:
package
.
ship_package_ids
.
ids
,
'bl_id'
:
package
.
bl_id
.
id
,
'tally_time'
:
tally_time
})
# 小包
package_obj
.
update_big_package_info
(
action_type
=
action_type
,
tally_state
=
package_item
.
get
(
'tally_state'
),
tally_user_id
=
package_item
.
get
(
'tally_user_id'
),
tally_time
=
tally_time
)
# 修改理货信息
else
:
error_no_set
.
add
(
package_no
)
return
error_no_set
# 处理小包、大包
if
kwargs
.
get
(
'ship_package_arr'
):
error_no_arr
=
process_packages
(
kwargs
[
'ship_package_arr'
],
'ship'
,
ship_packages
)
if
error_no_arr
:
res
[
'message'
]
=
{
'en'
:
'Ship package number [
%
s] does not exist'
%
','
.
join
(
error_no_arr
),
'zh'
:
'小包物流订单号[
%
s]不存在'
%
','
.
join
(
error_no_arr
)
}[
pda_lang
]
return
res
if
kwargs
.
get
(
'big_package_arr'
):
error_no_arr
=
process_packages
(
kwargs
[
'big_package_arr'
],
'big'
,
ship_packages
)
if
error_no_arr
:
res
[
'message'
]
=
{
'en'
:
'Big package number [
%
s] does not exist'
%
','
.
join
(
error_no_arr
),
'zh'
:
'大包号[
%
s]不存在'
%
','
.
join
(
error_no_arr
)
}[
pda_lang
]
return
res
# 修改异常原因,发送异常邮件
lang
=
'zh_CN'
if
pda_lang
==
'zh'
else
'en_US'
# 语言
for
exception_id
,
big_package
in
big_package_exception_arr
.
items
():
if
big_package
:
big_wizard_obj
=
request
.
env
[
'add.exception.info.wizard'
]
.
sudo
()
.
with_context
({
'active_id'
:
big_package
,
'active_name'
:
'cc.big.package'
,
'not_update_ex'
:
True
})
.
create_add_exception_wizard
(
'big package'
,
[
exception_id
],
big_package_ids
=
big_package
,
send_email
=
True
,
email_language
=
lang
)
big_wizard_obj
.
confirm
()
# 发送邮件
for
exception_id
,
ship_package
in
ship_package_exception_arr
.
items
():
if
ship_package
:
ship_wizard_obj
=
request
.
env
[
'add.exception.info.wizard'
]
.
sudo
()
.
with_context
({
'active_id'
:
ship_package
,
'active_name'
:
'cc.ship.package'
,
'not_update_ex'
:
True
})
.
create_add_exception_wizard
(
'ship package'
,
[
exception_id
],
ship_package_ids
=
ship_package
,
send_email
=
True
,
email_language
=
lang
)
ship_wizard_obj
.
confirm
()
# 发送邮件
res
[
'state'
]
=
200
logging
.
info
(
'update_big_package_tally_detail ship_packages:
%
s'
%
len
(
ship_packages
))
# 有小包 就更新小包状态和同步
if
ship_packages
:
redis_conn
=
request
.
env
[
'common.common'
]
.
sudo
()
.
get_redis
()
if
redis_conn
and
redis_conn
!=
'no'
:
# redis_conn.lpush('push_ship_package_state', json.dumps(
# {'bl_id': bl_obj.id, 'ship_package_ids': ship_package_ids}))
bl_ids
=
[
ship_package
.
get
(
'bl_id'
)
for
ship_package
in
ship_packages
]
logging
.
info
(
'bl_ids:
%
s'
%
bl_ids
)
redis_conn
.
lpush
(
'mail_push_package_list'
,
json
.
dumps
(
{
'ids'
:
list
(
set
(
bl_ids
)),
'ship_packages'
:
str
(
ship_packages
),
'action_type'
:
action_type
}))
else
:
null_msg_dic
=
{
'en'
:
'The bill of lading number and action type must be provided; at least one of the following is required: big package data or ship package data.'
,
'zh'
:
'类型必须提供;大包数据或小包数据至少需要提供一个。'
}
res
[
'message'
]
=
null_msg_dic
[
pda_lang
]
except
Exception
as
e
:
logging
.
info
(
'update_pro_big_package_tally_detail error:
%
s'
%
e
)
exceptions_msg_dic
=
{
'en'
:
'System parsing error, the reason for the error is
%
s'
%
e
,
'zh'
:
'系统解析错误,错误原因是
%
s'
%
e
}
res
[
'message'
]
=
exceptions_msg_dic
[
pda_lang
]
logging
.
info
(
'res:
%
s'
%
res
)
return
res
@http.route
(
'/api/exceptions/info'
,
type
=
'json'
,
auth
=
'public'
,
methods
=
[
'GET'
,
'POST'
],
csrf
=
False
)
@http.route
(
'/api/exceptions/info'
,
type
=
'json'
,
auth
=
'public'
,
methods
=
[
'GET'
,
'POST'
],
csrf
=
False
)
def
exceptions_info
(
self
):
def
exceptions_info
(
self
):
"""
"""
...
@@ -278,7 +456,7 @@ class OrderController(http.Controller):
...
@@ -278,7 +456,7 @@ class OrderController(http.Controller):
logging
.
info
(
'exceptions_info kwargs:
%
s'
%
kwargs
)
logging
.
info
(
'exceptions_info kwargs:
%
s'
%
kwargs
)
lang
=
'zh_CN'
if
pda_lang
==
'zh'
else
'en_US'
# 语言
lang
=
'zh_CN'
if
pda_lang
==
'zh'
else
'en_US'
# 语言
exception_obj
=
request
.
env
[
'cc.exception.info'
]
.
sudo
()
.
with_context
({
'lang'
:
lang
})
.
search
([])
# 包裹异常原因
exception_obj
=
request
.
env
[
'cc.exception.info'
]
.
sudo
()
.
with_context
({
'lang'
:
lang
})
.
search
([])
# 包裹异常原因
res
[
'exception_arr'
]
=
[
excep
.
search_exception_info
(
pda_lang
=
pda_lang
)
for
excep
in
exception_obj
]
res
[
'exception_arr'
]
=
[
excep
.
search_exception_info
()
for
excep
in
exception_obj
]
res
[
'state'
]
=
200
res
[
'state'
]
=
200
except
Exception
as
e
:
except
Exception
as
e
:
exceptions_msg_dic
=
{
exceptions_msg_dic
=
{
...
@@ -290,3 +468,84 @@ class OrderController(http.Controller):
...
@@ -290,3 +468,84 @@ class OrderController(http.Controller):
pda_lang
]
# _('System parsing error, the reason for the error is %s', e) # 系统解析错误,错误原因是
pda_lang
]
# _('System parsing error, the reason for the error is %s', e) # 系统解析错误,错误原因是
logging
.
info
(
'exceptions_info res:
%
s'
%
res
)
logging
.
info
(
'exceptions_info res:
%
s'
%
res
)
return
res
return
res
@http.route
(
'/api/last_mile/tally'
,
type
=
'json'
,
auth
=
'public'
,
csrf
=
False
)
def
last_mile_tally
(
self
):
"""
按尾程快递理货的接口,查询所有清关中的提单关联的大包,且大包状态为未理货的数量,按下一阶段服务商名称分组,下一个阶段服务商名称匹配尾程快递;传给PDA。
尾程快递名称,摆放区域,快递LOGO,大包件数
大包信息字段:大包号,尾程快递名称,尾程快递色值;
"""
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
pda_lang
=
kwargs
.
get
(
'pda_lang'
)
or
'zh'
res
=
{
'state'
:
201
,
'message'
:
''
}
try
:
logging
.
info
(
'last_mile_tally kwargs:
%
s'
%
kwargs
)
return
self
.
_get_last_mile_grouped
(
'unprocessed_goods'
,
pda_lang
)
except
Exception
as
e
:
exceptions_msg_dic
=
{
'en'
:
'System parsing error, the reason for the error is
%
s'
%
e
,
'zh'
:
'系统解析错误,错误原因是
%
s'
%
e
}
logging
.
info
(
'last_mile_tally error:
%
s'
%
e
)
res
[
'message'
]
=
exceptions_msg_dic
[
pda_lang
]
# _('System parsing error, the reason for the error is %s', e) # 系统解析错误,错误原因是
logging
.
info
(
'last_mile_tally res:
%
s'
%
res
)
return
res
@http.route
(
'/api/last_mile/delivery'
,
type
=
'json'
,
auth
=
'public'
,
csrf
=
False
)
def
last_mile_delivery
(
self
):
"""
按尾程快递交货接口,查询系统所有清关中的提单关联的大包,且大包状态为已理货的数量,按下一阶段服务商名称分组,下一个阶段服务商名称匹配尾程快递传给PDA。传输字段与理货的一致。
"""
kwargs
=
json
.
loads
(
request
.
httprequest
.
data
)
pda_lang
=
kwargs
.
get
(
'pda_lang'
)
or
'zh'
res
=
{
'state'
:
201
,
'message'
:
''
}
try
:
logging
.
info
(
'last_mile_delivery kwargs:
%
s'
%
kwargs
)
return
self
.
_get_last_mile_grouped
(
'checked_goods'
,
pda_lang
)
except
Exception
as
e
:
exceptions_msg_dic
=
{
'en'
:
'System parsing error, the reason for the error is
%
s'
%
e
,
'zh'
:
'系统解析错误,错误原因是
%
s'
%
e
}
logging
.
info
(
'last_mile_delivery error:
%
s'
%
e
)
res
[
'message'
]
=
exceptions_msg_dic
[
pda_lang
]
# _('System parsing error, the reason for the error is %s', e) # 系统解析错误,错误原因是
logging
.
info
(
'last_mile_delivery res:
%
s'
%
res
)
return
res
def
_get_last_mile_grouped
(
self
,
tally_state
,
pda_lang
):
lang
=
'zh_CN'
if
pda_lang
==
'zh'
else
'en_US'
# 语言
# 1. 查所有清关中提单
bls
=
request
.
env
[
'cc.bl'
]
.
sudo
()
.
search
([(
'state'
,
'='
,
'ccing'
)])
# 2. 查所有大包
big_packages
=
request
.
env
[
'cc.big.package'
]
.
sudo
()
.
search
([
(
'bl_id'
,
'in'
,
bls
.
ids
),
(
'tally_state'
,
'='
,
tally_state
)
])
# 3. 按"下一阶段服务商名称"分组
group_dict
=
{}
for
pkg
in
big_packages
:
provider
=
request
.
env
[
'cc.last.mile.provider'
]
.
sudo
()
.
with_context
({
'lang'
:
lang
})
.
match_provider
(
pkg
.
next_provider_name
)
if
not
provider
:
continue
key
=
provider
.
id
if
key
not
in
group_dict
:
group_dict
[
key
]
=
provider
.
search_pro_info
()
# 查询快递信息
group_dict
[
key
][
'count'
]
=
0
group_dict
[
key
][
'big_package_arr'
]
=
[]
group_dict
[
key
][
'ship_package_arr'
]
=
[]
group_dict
[
key
][
'count'
]
+=
1
group_dict
[
key
][
'big_package_arr'
]
.
append
(
pkg
.
search_big_package_info
(
pda_lang
=
pda_lang
,
type
=
tally_state
))
group_dict
[
key
][
'ship_package_arr'
]
.
extend
(
[
ship_package_item
.
search_ship_package_info
(
pda_lang
=
pda_lang
)
for
ship_package_item
in
pkg
.
ship_package_ids
])
# 4. 返回
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
}
ccs_connect_tiktok/models/__init__.py
浏览文件 @
b85c538a
...
@@ -6,6 +6,8 @@ from . import res_config_setting
...
@@ -6,6 +6,8 @@ from . import res_config_setting
from
.
import
ao_tt_api_log
from
.
import
ao_tt_api_log
from
.
import
cc_node
from
.
import
cc_node
from
.
import
cc_bill_loading
from
.
import
cc_bill_loading
from
.
import
ir_attachment
from
.
import
http
ccs_connect_tiktok/models/cc_bill_loading.py
浏览文件 @
b85c538a
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import
asyncio
import
asyncio
import
json
import
logging
import
logging
import
ssl
import
ssl
from
datetime
import
timedelta
,
datetime
from
datetime
import
timedelta
,
datetime
import
json
import
aiohttp
import
aiohttp
import
certifi
import
certifi
import
pytz
import
pytz
...
@@ -280,7 +281,7 @@ class CcBl(models.Model):
...
@@ -280,7 +281,7 @@ class CcBl(models.Model):
bl
=
self
.
env
[
'cc.bl'
]
.
sudo
()
.
search
(
bl
=
self
.
env
[
'cc.bl'
]
.
sudo
()
.
search
(
[(
'bl_no'
,
'='
,
master_waybill_no
),
(
'create_date'
,
'>='
,
date
)],
limit
=
1
)
[(
'bl_no'
,
'='
,
master_waybill_no
),
(
'create_date'
,
'>='
,
date
)],
limit
=
1
)
if
bl
:
if
bl
:
# 根据kws中获取的"img_detail"中的"img_file_code
”
和img_file_type,生成odoo的附件,并关联到cc.bl的bl_attachment_ids字段
# 根据kws中获取的"img_detail"中的"img_file_code
"
和img_file_type,生成odoo的附件,并关联到cc.bl的bl_attachment_ids字段
vals
=
{
'customs_bl_no'
:
kws
.
get
(
'customs_waybill_id'
),
vals
=
{
'customs_bl_no'
:
kws
.
get
(
'customs_waybill_id'
),
'transport_tool_code'
:
kws
.
get
(
'transport_code'
),
'transport_tool_code'
:
kws
.
get
(
'transport_code'
),
'transport_tool_name'
:
kws
.
get
(
'transport_name'
),
'transport_tool_name'
:
kws
.
get
(
'transport_name'
),
...
@@ -367,6 +368,7 @@ class CcBl(models.Model):
...
@@ -367,6 +368,7 @@ class CcBl(models.Model):
"""
"""
根据小包的状态修改提单关务状态以及生成同步日志
根据小包的状态修改提单关务状态以及生成同步日志
:param package_state_obj:小包更新后的状态
:param package_state_obj:小包更新后的状态
:param user_obj:
:return:
:return:
"""
"""
# 根据小包的状态找到对应的提单关务状态
# 根据小包的状态找到对应的提单关务状态
...
@@ -540,7 +542,12 @@ class CcBl(models.Model):
...
@@ -540,7 +542,12 @@ class CcBl(models.Model):
# 根据小包状态更新提单关务状态
# 根据小包状态更新提单关务状态
try
:
try
:
if
is_ok
and
item
.
ship_package_ids
:
if
is_ok
and
item
.
ship_package_ids
:
item
.
change_customs_state_by_ship_package
(
item
.
ship_package_ids
[
0
]
.
state
,
user_obj
=
user_obj
)
# 检查所有小包状态是否一致
states
=
set
(
item
.
ship_package_ids
.
mapped
(
'state.id'
))
if
len
(
states
)
==
1
:
item
.
change_customs_state_by_ship_package
(
item
.
ship_package_ids
[
0
]
.
state
,
user_obj
=
user_obj
)
else
:
logging
.
info
(
'Not all ship package states are the same, skip updating customs state.'
)
except
Exception
as
e
:
except
Exception
as
e
:
logging
.
info
(
'change_customs_state_by_ship_package error:
%
s'
%
e
)
logging
.
info
(
'change_customs_state_by_ship_package error:
%
s'
%
e
)
return
is_ok
return
is_ok
...
@@ -606,19 +613,22 @@ class CcBl(models.Model):
...
@@ -606,19 +613,22 @@ class CcBl(models.Model):
# package_order = self.env['cc.ship.package'].sudo().browse(package_id)
# package_order = self.env['cc.ship.package'].sudo().browse(package_id)
if
response_data
[
'code'
]
!=
0
:
if
response_data
[
'code'
]
!=
0
:
# package_order.is_sync = False
# package_order.is_sync = False
update_false_arr
.
append
(
package_id
)
# 更新 is_sync为 False
update_false_arr
.
append
(
package_id
)
# 更新 is_sync为 False
error_msg
=
response_data
[
'msg'
]
error_msg
=
response_data
[
'msg'
]
request_id
=
response_data
[
'requestID'
]
request_id
=
response_data
[
'requestID'
]
create_api_log_value_arr
.
append
((
tracking_no
,
utc_time
,
'小包状态轨迹回传:'
+
error_msg
,
False
,
data_text
,
request_id
,
'推出'
,
utc_time
))
create_api_log_value_arr
.
append
((
tracking_no
,
utc_time
,
'小包状态轨迹回传:'
+
error_msg
,
False
,
data_text
,
request_id
,
'推出'
,
utc_time
))
is_ok
=
False
is_ok
=
False
else
:
else
:
# 回传成功
# 回传成功
update_true_arr
.
append
(
package_id
)
# 更新 is_sync为 True
update_true_arr
.
append
(
package_id
)
# 更新 is_sync为 True
state_arr
=
package_node_result_dict
.
get
(
state
,
[])
state_arr
=
package_node_result_dict
.
get
(
state
,
[])
tk_code
=
state_arr
[
1
]
if
state_arr
else
''
tk_code
=
state_arr
[
1
]
if
state_arr
else
''
create_sync_log_value_arr
.
append
((
package_id
,
utc_time
,
'Tiktok'
,
tk_code
,
process_time
,
state_explain
,
user_id
))
create_sync_log_value_arr
.
append
(
(
package_id
,
utc_time
,
'Tiktok'
,
tk_code
,
process_time
,
state_explain
,
user_id
))
request_id
=
response_data
[
'requestID'
]
request_id
=
response_data
[
'requestID'
]
create_api_log_value_arr
.
append
((
tracking_no
,
utc_time
,
''
,
True
,
data_text
,
request_id
,
'推出'
,
utc_time
))
create_api_log_value_arr
.
append
(
(
tracking_no
,
utc_time
,
''
,
True
,
data_text
,
request_id
,
'推出'
,
utc_time
))
if
update_false_arr
:
if
update_false_arr
:
update_false_ids
=
'(
%
s)'
%
str
(
update_false_arr
)[
1
:
-
1
]
update_false_ids
=
'(
%
s)'
%
str
(
update_false_arr
)[
1
:
-
1
]
sql
=
"update cc_ship_package set is_sync=False where id in
%
s"
%
update_false_ids
sql
=
"update cc_ship_package set is_sync=False where id in
%
s"
%
update_false_ids
...
@@ -813,13 +823,18 @@ class CcBl(models.Model):
...
@@ -813,13 +823,18 @@ class CcBl(models.Model):
if
is_ok
:
if
is_ok
:
# 根据小包状态更新提单关务状态
# 根据小包状态更新提单关务状态
if
self
.
ship_package_ids
:
if
self
.
ship_package_ids
:
self
.
change_customs_state_by_ship_package
(
self
.
ship_package_ids
[
0
]
.
state
,
user_obj
=
user_obj
)
# 检查所有小包状态是否一致
states
=
set
(
self
.
ship_package_ids
.
mapped
(
'state.id'
))
if
len
(
states
)
==
1
:
self
.
change_customs_state_by_ship_package
(
self
.
ship_package_ids
[
0
]
.
state
,
user_obj
=
user_obj
)
else
:
logging
.
info
(
'Not all ship package states are the same, skip updating customs state.'
)
if
is_ok
:
if
is_ok
:
return
is_ok
return
is_ok
logging
.
warning
(
f
"Attempt {i + 1}/{max_retries} failed. Retrying..."
)
logging
.
warning
(
f
"Attempt {i + 1}/{max_retries} failed. Retrying..."
)
return
False
return
False
def
mail_auto_push
(
self
,
mail_time
=
False
,
ship_packages
=
[],
action_type
=
'tally'
,
mail_db_user
=
'邮件接收'
,
def
mail_auto_push
(
self
,
mail_time
=
False
,
tally_
ship_packages
=
[],
action_type
=
'tally'
,
mail_db_user
=
'邮件接收'
,
pda_db_user
=
'pda'
):
pda_db_user
=
'pda'
):
self
=
self
.
with_context
(
dict
(
self
.
_context
,
is_mail
=
True
))
self
=
self
.
with_context
(
dict
(
self
.
_context
,
is_mail
=
True
))
for
item
in
self
:
for
item
in
self
:
...
@@ -831,14 +846,15 @@ class CcBl(models.Model):
...
@@ -831,14 +846,15 @@ class CcBl(models.Model):
item
.
push_clear_customs_start
(
before_utc_time
)
item
.
push_clear_customs_start
(
before_utc_time
)
user_obj
=
self
.
env
[
'res.users'
]
.
search
([(
'login'
,
'='
,
mail_db_user
)],
limit
=
1
)
user_obj
=
self
.
env
[
'res.users'
]
.
search
([(
'login'
,
'='
,
mail_db_user
)],
limit
=
1
)
# 尝试调用 callback_track
# 尝试调用 callback_track
if
self
.
try_callback_track
(
user_obj
=
user_obj
):
if
item
.
try_callback_track
(
user_obj
=
user_obj
):
item
.
push_clear_customs_end
(
utc_time
)
item
.
push_clear_customs_end
(
utc_time
)
# 再次尝试调用 callback_track
# 再次尝试调用 callback_track
if
not
self
.
try_callback_track
(
user_obj
=
user_obj
):
if
not
item
.
try_callback_track
(
user_obj
=
user_obj
):
logging
.
error
(
f
"Failed to push item after {3} attempts."
)
logging
.
error
(
f
"Failed to push item after {3} attempts."
)
else
:
else
:
logging
.
error
(
f
"Failed to start process for item after {3} attempts."
)
logging
.
error
(
f
"Failed to start process for item after {3} attempts."
)
elif
ship_packages
:
elif
tally_ship_packages
:
ship_packages
=
[
pkg
for
pkg
in
tally_ship_packages
if
pkg
.
get
(
'bl_id'
)
==
item
.
id
]
user_obj
=
self
.
env
[
'res.users'
]
.
search
([(
'login'
,
'='
,
pda_db_user
)],
limit
=
1
)
user_obj
=
self
.
env
[
'res.users'
]
.
search
([(
'login'
,
'='
,
pda_db_user
)],
limit
=
1
)
ship_package_ids
=
[
ship_package_dict
for
sublist
in
[
d
[
'id'
]
for
d
in
ship_packages
]
for
ship_package_ids
=
[
ship_package_dict
for
sublist
in
[
d
[
'id'
]
for
d
in
ship_packages
]
for
ship_package_dict
in
sublist
]
ship_package_dict
in
sublist
]
...
@@ -914,7 +930,7 @@ class CcBl(models.Model):
...
@@ -914,7 +930,7 @@ class CcBl(models.Model):
self
.
env
.
cr
.
execute
(
sql
)
self
.
env
.
cr
.
execute
(
sql
)
self
.
_cr
.
commit
()
# 提交事务
self
.
_cr
.
commit
()
# 提交事务
self
.
try_callback_track
(
max_retries
=
2
,
ship_package_ids
=
ship_package_ids
,
item
.
try_callback_track
(
max_retries
=
2
,
ship_package_ids
=
ship_package_ids
,
user_obj
=
user_obj
)
user_obj
=
user_obj
)
# 理货或尾程交接的节点
# 理货或尾程交接的节点
# 预先获取所有状态节点
# 预先获取所有状态节点
...
@@ -960,9 +976,8 @@ class CcBl(models.Model):
...
@@ -960,9 +976,8 @@ class CcBl(models.Model):
self
.
env
.
cr
.
execute
(
sql
)
self
.
env
.
cr
.
execute
(
sql
)
self
.
_cr
.
commit
()
# 提交事务
self
.
_cr
.
commit
()
# 提交事务
self
.
try_callback_track
(
max_retries
=
2
,
ship_package_ids
=
ship_package_ids
,
item
.
try_callback_track
(
max_retries
=
2
,
ship_package_ids
=
ship_package_ids
,
user_obj
=
user_obj
)
user_obj
=
user_obj
)
return
True
except
Exception
as
err
:
except
Exception
as
err
:
logging
.
error
(
'fetch_mail_dlv--error:
%
s'
%
str
(
err
))
logging
.
error
(
'fetch_mail_dlv--error:
%
s'
%
str
(
err
))
...
...
ccs_connect_tiktok/models/http.py
0 → 100644
浏览文件 @
b85c538a
# -*- coding: utf-8 -*-
import
logging
from
datetime
import
datetime
,
timedelta
import
time
import
hashlib
from
odoo
import
models
from
odoo.http
import
request
__author__
=
'yubo.peng'
_logger
=
logging
.
getLogger
(
__name__
)
class
AuthenticationError
(
Exception
):
pass
class
Http
(
models
.
AbstractModel
):
_inherit
=
'ir.http'
@classmethod
def
_auth_method_erp_token
(
cls
):
# 从headers.environ中获取对方传过来的token,timestamp,加密的校验字符串
datas
=
request
.
httprequest
.
headers
.
environ
if
'HTTP_TOKEN'
in
datas
and
'HTTP_TIMESTAMP'
in
datas
and
'HTTP_CHECKSTR'
in
datas
:
# 从系统参数中获取TOKEt和密钥
factory_secret
=
request
.
env
[
'ir.config_parameter'
]
.
sudo
()
.
get_param
(
'erp_token'
)
erp_secret_key
=
request
.
env
[
'ir.config_parameter'
]
.
sudo
()
.
get_param
(
'erp_secret_key'
)
# 从系统参数获取是否时间校验,-1为不校验,其他为校验
check_timeout
=
int
(
request
.
env
[
'ir.config_parameter'
]
.
sudo
()
.
get_param
(
'check_timeout'
)
or
5
)
if
not
factory_secret
:
raise
AuthenticationError
(
'系统中未设置ERP TOKEN'
)
if
datas
[
'HTTP_TOKEN'
]
!=
factory_secret
:
raise
AuthenticationError
(
'无效的token'
)
if
check_timeout
>
0
:
post_time
=
int
(
datas
[
'HTTP_TIMESTAMP'
])
datetime_post
=
datetime
.
fromtimestamp
(
post_time
)
datetime_now
=
datetime
.
now
()
.
replace
(
microsecond
=
0
)
datetime_del
=
datetime_now
+
timedelta
(
seconds
=
check_timeout
)
if
datetime_post
>
datetime_del
:
raise
AuthenticationError
(
'请求已过期'
)
# 获得sha1_str加密字符串
check_str
=
'
%
s
%
s
%
s'
%
(
datas
[
'HTTP_TOKEN'
],
datas
[
'HTTP_TIMESTAMP'
],
erp_secret_key
)
check_crm_str
=
hashlib
.
sha1
(
check_str
.
encode
(
'utf-8'
))
.
hexdigest
()
if
check_crm_str
.
upper
()
!=
datas
[
'HTTP_CHECKSTR'
]
.
upper
():
raise
AuthenticationError
(
'数据校验不通过'
)
else
:
raise
AuthenticationError
(
'请求参数中无token'
)
ccs_connect_tiktok/models/ir_attachment.py
0 → 100644
浏览文件 @
b85c538a
# -*- coding: utf-8 -*-
from
odoo
import
models
,
api
,
_
from
collections
import
defaultdict
from
odoo.exceptions
import
AccessError
class
IrAttachment
(
models
.
Model
):
_inherit
=
"ir.attachment"
# override
@api.model
def
check
(
self
,
mode
,
values
=
None
):
""" Restricts the access to an ir.attachment, according to referred mode """
if
self
.
env
.
is_superuser
():
return
True
# Always require an internal user (aka, employee) to access to a attachment
if
not
(
self
.
env
.
is_admin
()
or
self
.
env
.
user
.
has_group
(
'base.group_user'
)):
raise
AccessError
(
_
(
"Sorry, you are not allowed to access this document."
))
# collect the records to check (by model)
model_ids
=
defaultdict
(
set
)
# {model_name: set(ids)}
if
self
:
# DLE P173: `test_01_portal_attachment`
self
.
env
[
'ir.attachment'
]
.
flush
([
'res_model'
,
'res_id'
,
'create_uid'
,
'public'
,
'res_field'
])
self
.
_cr
.
execute
(
'SELECT res_model, res_id, create_uid, public, res_field FROM ir_attachment WHERE id IN
%
s'
,
[
tuple
(
self
.
ids
)])
for
res_model
,
res_id
,
create_uid
,
public
,
res_field
in
self
.
_cr
.
fetchall
():
if
public
and
mode
==
'read'
:
continue
if
not
(
res_model
and
res_id
):
continue
model_ids
[
res_model
]
.
add
(
res_id
)
if
values
and
values
.
get
(
'res_model'
)
and
values
.
get
(
'res_id'
):
model_ids
[
values
[
'res_model'
]]
.
add
(
values
[
'res_id'
])
# check access rights on the records
for
res_model
,
res_ids
in
model_ids
.
items
():
# ignore attachments that are not attached to a resource anymore
# when checking access rights (resource was deleted but attachment
# was not)
if
res_model
not
in
self
.
env
:
continue
if
res_model
==
'res.users'
and
len
(
res_ids
)
==
1
and
self
.
env
.
uid
==
list
(
res_ids
)[
0
]:
# by default a user cannot write on itself, despite the list of writeable fields
# e.g. in the case of a user inserting an image into his image signature
# we need to bypass this check which would needlessly throw us away
continue
records
=
self
.
env
[
res_model
]
.
browse
(
res_ids
)
.
exists
()
# For related models, check if we can write to the model, as unlinking
# and creating attachments can be seen as an update to the model
access_mode
=
'write'
if
mode
in
(
'create'
,
'unlink'
)
else
mode
records
.
check_access_rights
(
access_mode
)
records
.
check_access_rule
(
access_mode
)
@api.model
def
read_as_sudo
(
self
,
domain
=
None
,
fields
=
None
):
return
self
.
sudo
()
.
search_read
(
domain
,
fields
)
consumers/config.py
浏览文件 @
b85c538a
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
# 本地
# 本地
db_ip
=
"127.0.0.1"
db_ip
=
"127.0.0.1"
db_port
=
"8069"
db_port
=
"8069"
db_name
=
"hhccs
_test
"
db_name
=
"hhccs
324
"
db_user
=
"admin"
db_user
=
"admin"
db_password
=
"admin"
db_password
=
"admin"
...
@@ -13,13 +13,6 @@ redis_options = dict(
...
@@ -13,13 +13,6 @@ redis_options = dict(
db
=
0
db
=
0
)
)
postgresql_options
=
dict
(
host
=
"127.0.0.1"
,
port
=
5431
,
database
=
"hh_ccs_test"
,
user
=
"odoo14"
,
password
=
"qq166349"
,
)
# 测试
# 测试
# db_ip = "121.199.167.133"
# db_ip = "121.199.167.133"
...
...
consumers/mail_push.py
浏览文件 @
b85c538a
...
@@ -37,7 +37,11 @@ class Order_dispose(object):
...
@@ -37,7 +37,11 @@ class Order_dispose(object):
bl_obj
=
self
.
odoo_db
.
env
[
'cc.bl'
]
bl_obj
=
self
.
odoo_db
.
env
[
'cc.bl'
]
if
action_type
and
not
utc_time
:
if
action_type
and
not
utc_time
:
bl_obj
=
self
.
pda_odoo_db
.
env
[
'cc.bl'
]
bl_obj
=
self
.
pda_odoo_db
.
env
[
'cc.bl'
]
bl_record
=
bl_obj
.
browse
(
data
[
'id'
])
bl_ids
=
data
.
get
(
'ids'
)
if
bl_ids
:
bl_record
=
bl_obj
.
browse
(
bl_ids
)
else
:
bl_record
=
bl_obj
.
browse
(
data
[
'id'
])
# utc_time = datetime.strptime(data['utc_time'], "%Y-%m-%d %H:%M:%S")
# utc_time = datetime.strptime(data['utc_time'], "%Y-%m-%d %H:%M:%S")
utc_time
=
data
.
get
(
'utc_time'
)
utc_time
=
data
.
get
(
'utc_time'
)
user_login
=
data
.
get
(
'user_login'
)
user_login
=
data
.
get
(
'user_login'
)
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论