Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
H
hh_ccs
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
贺阳
hh_ccs
Commits
1b8d84e6
提交
1b8d84e6
authored
9月 09, 2025
作者:
贺阳
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
托盘功能开发和关联托盘的修改
上级
727366d3
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
35 个修改的文件
包含
440 行增加
和
465 行删除
+440
-465
__manifest__.py
ccs_base/__manifest__.py
+0
-3
cc_bill_loading.py
ccs_base/models/cc_bill_loading.py
+0
-20
ir.model.access.csv
ccs_base/security/ir.model.access.csv
+0
-1
bl_list_controller.js
ccs_base/static/src/views/bl_list_controller.js
+4
-4
list.xml
ccs_base/static/src/views/list.xml
+0
-5
cc_big_package_view.xml
ccs_base/views/cc_big_package_view.xml
+1
-4
__init__.py
ccs_base/wizard/__init__.py
+0
-1
__init__.py
ccs_pallet/__init__.py
+1
-2
__manifest__.py
ccs_pallet/__manifest__.py
+15
-8
__init__.py
ccs_pallet/controllers/__init__.py
+0
-1
data.xml
ccs_pallet/data/data.xml
+0
-7
sequence.xml
ccs_pallet/data/sequence.xml
+0
-13
timer.xml
ccs_pallet/data/timer.xml
+0
-6
zh_CN.po
ccs_pallet/i18n/zh_CN.po
+0
-0
__init__.py
ccs_pallet/models/__init__.py
+1
-0
cc_big_package.py
ccs_pallet/models/cc_big_package.py
+41
-0
cc_pallet.py
ccs_pallet/models/cc_pallet.py
+90
-123
pallet_label_report.xml
ccs_pallet/reports/pallet_label_report.xml
+8
-5
ir.model.access.csv
ccs_pallet/security/ir.model.access.csv
+14
-5
pallet_security.xml
ccs_pallet/security/pallet_security.xml
+2
-2
batch_create_pallet.js
ccs_pallet/static/src/mixins/batch_create_pallet.js
+26
-0
link_pallet.js
ccs_pallet/static/src/mixins/link_pallet.js
+0
-0
big_package_list_controller.js
ccs_pallet/static/src/views/big_package_list_controller.js
+5
-4
bl_list_pallet_controller.js
ccs_pallet/static/src/views/bl_list_pallet_controller.js
+50
-0
list.xml
ccs_pallet/static/src/views/list.xml
+17
-0
cc_big_package_view.xml
ccs_pallet/views/cc_big_package_view.xml
+17
-0
cc_pallet_view.xml
ccs_pallet/views/cc_pallet_view.xml
+51
-83
menu_view.xml
ccs_pallet/views/menu_view.xml
+11
-1
__init__.py
ccs_pallet/wizard/__init__.py
+1
-0
associate_pallet_wizard.py
ccs_pallet/wizard/associate_pallet_wizard.py
+23
-30
associate_pallet_wizard_views.xml
ccs_pallet/wizard/associate_pallet_wizard_views.xml
+1
-1
pallet_batch_wizard.py
ccs_pallet/wizard/pallet_batch_wizard.py
+39
-82
pallet_batch_wizard_view.xml
ccs_pallet/wizard/pallet_batch_wizard_view.xml
+10
-23
pallet_print_wizard.py
ccs_pallet/wizard/pallet_print_wizard.py
+7
-17
pallet_print_wizard_view.xml
ccs_pallet/wizard/pallet_print_wizard_view.xml
+5
-14
没有找到文件。
ccs_base/__manifest__.py
浏览文件 @
1b8d84e6
...
...
@@ -21,7 +21,6 @@
'wizard/update_bl_status_wizard.xml'
,
'wizard/export_bl_big_package_xlsx_wizard.xml'
,
'wizard/batch_update_transfer_bl_no_wizard_view.xml'
,
'wizard/associate_pallet_wizard_views.xml'
,
'wizard/add_exception_info_wizard_views.xml'
,
'wizard/email_template.xml'
,
'data/data.xml'
,
...
...
@@ -58,9 +57,7 @@
'ccs_base/static/css/base.scss'
,
],
'web.assets_backend'
:
[
'ccs_base/static/src/mixins/link_pallet.js'
,
'ccs_base/static/src/mixins/link_transfer_bl_no.js'
,
'ccs_base/static/src/views/big_package_list_controller.js'
,
'ccs_base/static/src/views/bl_list_controller.js'
,
'ccs_base/static/src/views/list.xml'
,
],
...
...
ccs_base/models/cc_bill_loading.py
浏览文件 @
1b8d84e6
...
...
@@ -67,16 +67,6 @@ class CcBigPackage(models.Model):
exception_info_ids
=
fields
.
Many2many
(
'cc.exception.info'
,
'bigpackage_exception_info_rel'
,
string
=
'Exception Information'
)
def
update_pallet_info
(
self
,
pallet_number
,
pallet_usage_date
):
"""
修改托盘信息
:param pallet_number:
:param pallet_usage_date:
:return:
"""
self
.
pallet_usage_date
=
pallet_usage_date
self
.
pallet_number
=
pallet_number
def
update_exception_info
(
self
,
exception_info_ids
,
is_send
=
False
,
email_language
=
'zh_CN'
):
"""
大包回写异常原因,发送邮件
...
...
@@ -110,16 +100,6 @@ class CcBigPackage(models.Model):
'domain'
:
[(
'bl_line_id'
,
'in'
,
self
.
ship_package_ids
.
ids
),
(
'is_cancel'
,
'='
,
False
)],
}
def
action_link_pallet
(
self
):
return
{
'name'
:
_
(
'Link Pallet'
),
'type'
:
'ir.actions.act_window'
,
'views'
:
[[
False
,
"form"
]],
'res_model'
:
'associate.pallet.wizard'
,
'target'
:
'new'
,
'context'
:
{},
}
def
action_cc_big_package
(
self
):
"""
菜单 大包
...
...
ccs_base/security/ir.model.access.csv
浏览文件 @
1b8d84e6
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
batch_input_ship_package_status_wizard_group_user,batch_input_ship_package_status_wizard_group_user,ccs_base.model_batch_input_ship_package_status_wizard,base.group_user,1,1,1,1
export_bl_big_package_xlsx_wizard_group_user,export_bl_big_package_xlsx_wizard_group_user,ccs_base.model_export_bl_big_package_xlsx_wizard,base.group_user,1,1,1,1
associate_pallet_wizard_group_user,associate_pallet_wizard_group_user,ccs_base.model_associate_pallet_wizard,base.group_user,1,1,1,1
add_exception_info_wizard_group_user,add_exception_info_wizard_group_user,ccs_base.model_add_exception_info_wizard,base.group_user,1,1,1,1
update_bl_status_wizard_group_user,update_bl_status_wizard_group_user,ccs_base.model_update_bl_status_wizard,base.group_user,1,1,1,1
batch_update_transfer_bl_no_wizard_group_user,batch_update_transfer_bl_no_wizard_group_user,ccs_base.model_batch_update_transfer_bl_no_wizard,base.group_user,1,1,1,1
...
...
ccs_base/static/src/views/bl_list_controller.js
浏览文件 @
1b8d84e6
...
...
@@ -26,10 +26,10 @@ export class BlListController extends ListController {
});
}
displayLink
()
{
// 提单页面永远不显示“关联托盘”按钮
return
false
;
}
//
displayLink() {
//
// 提单页面永远不显示“关联托盘”按钮
//
return false;
//
}
displayTransferBlNo
()
{
console
.
log
(
'ccs flag:'
+
this
.
isBl
&&
this
.
can_link_transfer_bl_no
)
...
...
ccs_base/static/src/views/list.xml
浏览文件 @
1b8d84e6
...
...
@@ -2,11 +2,6 @@
<templates
xml:space=
"preserve"
>
<t
t-name=
"ccs_base.ListButtons"
t-inherit=
"web.ListView.Buttons"
t-inherit-mode=
"primary"
owl=
"1"
>
<xpath
expr=
"//button[hasclass('o_list_button_add')]"
position=
"after"
>
<button
t-if=
"displayLink()"
type=
"button"
class=
"d-none d-md-inline o_button_link_pallet btn btn-primary mx-1"
t-on-click.prevent=
"onLinkPalletClick"
>
Link Pallet
</button>
</xpath>
<xpath
expr=
"//button[hasclass('o_list_button_add')]"
position=
"after"
>
<button
t-if=
"displayTransferBlNo()"
type=
"button"
class=
"d-none d-md-inline o_button_transfer_bl_no btn btn-primary mx-1"
t-on-click.prevent=
"onTransferBlNoClick"
>
Link Transfer B/L No
...
...
ccs_base/views/cc_big_package_view.xml
浏览文件 @
1b8d84e6
...
...
@@ -6,7 +6,7 @@
<field
name=
"name"
>
tree.cc.big.package
</field>
<field
name=
"model"
>
cc.big.package
</field>
<field
name=
"arch"
type=
"xml"
>
<tree
string=
"Big Package"
js_class=
"cc_big_package_tree"
decoration-warning=
"is_cancel==True"
>
<tree
string=
"Big Package"
decoration-warning=
"is_cancel==True"
>
<field
optional=
"show"
name=
"big_package_no"
string=
"Big Package No."
/>
<field
optional=
"show"
name=
"bl_id"
string=
"Bill of Loading"
/>
<field
name=
"ship_package_qty"
string=
"Packages Qty"
/>
...
...
@@ -30,9 +30,6 @@
<field
name=
"arch"
type=
"xml"
>
<form
string=
"Big Package"
>
<header>
<!-- <button name="action_link_pallet" type="object"-->
<!-- string="Link Pallet"-->
<!-- groups="ccs_base.group_clearance_of_customs_manager"/><!– 关联托盘 –>-->
<button
name=
"action_package_exception_info"
type=
"object"
string=
"Add Package Exception Information"
groups=
"ccs_base.group_clearance_of_customs_manager"
/>
<!-- 添加包裹异常信息 -->
...
...
ccs_base/wizard/__init__.py
浏览文件 @
1b8d84e6
...
...
@@ -2,7 +2,6 @@
from
.
import
batch_input_ship_package_statu_wizard
from
.
import
export_bl_big_package_xlsx_wizard
from
.
import
associate_pallet_wizard
from
.
import
add_exception_info_wizard
from
.
import
update_bl_status_wizard
from
.
import
batch_update_transfer_bl_no_wizard
...
...
ccs_pallet/__init__.py
浏览文件 @
1b8d84e6
from
.
import
wizard
from
.
import
models
from
.
import
controllers
from
.
import
wizard
ccs_pallet/__manifest__.py
浏览文件 @
1b8d84e6
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name'
:
'清关托盘
管理
模块'
,
'name'
:
'清关托盘模块'
,
'version'
:
'1.2'
,
'summary'
:
'
托盘管理
模块'
,
'summary'
:
'
清关托盘
模块'
,
'sequence'
:
10
,
'description'
:
"""
托盘管理模块
1) 定义托盘对象,并完成托盘的导入功能
2) 定义托盘生成报关单的功能
3) 定义清关节点,并在托盘上更新清关节点.
清关托盘模块
1) 创建托盘和打印
"""
,
'category'
:
'Pallet Management'
,
'website'
:
'https://www.yizuo.ltd'
,
...
...
@@ -17,15 +15,24 @@
'data'
:
[
'security/pallet_security.xml'
,
'security/ir.model.access.csv'
,
'views/cc_pallet_view.xml'
,
'views/menu_view.xml'
,
'wizard/pallet_batch_wizard_view.xml'
,
'wizard/pallet_print_wizard_view.xml'
,
'wizard/associate_pallet_wizard_views.xml'
,
'reports/pallet_label_report.xml'
,
'views/cc_pallet_view.xml'
,
'views/cc_big_package_view.xml'
,
'views/menu_view.xml'
,
],
'installable'
:
True
,
'application'
:
True
,
'assets'
:
{
'web.assets_backend'
:
[
'ccs_pallet/static/src/mixins/link_pallet.js'
,
'ccs_pallet/static/src/mixins/batch_create_pallet.js'
,
'ccs_pallet/static/src/views/bl_list_pallet_controller.js'
,
'ccs_pallet/static/src/views/big_package_list_controller.js'
,
'ccs_pallet/static/src/views/list.xml'
,
],
},
'license'
:
'AGPL-3'
,
}
ccs_pallet/controllers/__init__.py
deleted
100644 → 0
浏览文件 @
727366d3
ccs_pallet/data/data.xml
deleted
100644 → 0
浏览文件 @
727366d3
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data
noupdate=
"1"
>
</data>
</odoo>
\ No newline at end of file
ccs_pallet/data/sequence.xml
deleted
100644 → 0
浏览文件 @
727366d3
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- <record id="sequence_cc_pallet" model="ir.sequence">
<field name="name">托盘编码规则</field>
<field name="code">cc.pallet</field>
<field name="padding">2</field>
<field name="number_next_actual">1</field>
<field name="company_id" eval="False"/>
</record> -->
</data>
</odoo>
\ No newline at end of file
ccs_pallet/data/timer.xml
deleted
100644 → 0
浏览文件 @
727366d3
<odoo>
<data>
</data>
</odoo>
\ No newline at end of file
ccs_pallet/i18n/zh_CN.po
0 → 100644
浏览文件 @
1b8d84e6
差异被折叠。
点击展开。
ccs_pallet/models/__init__.py
浏览文件 @
1b8d84e6
from
.
import
cc_pallet
from
.
import
cc_big_package
ccs_pallet/models/cc_big_package.py
0 → 100644
浏览文件 @
1b8d84e6
# -*- coding: utf-8 -*-
# 导入日志
import
logging
from
odoo
import
models
,
fields
,
api
,
_
# 获取日志
_logger
=
logging
.
getLogger
(
__name__
)
class
CCBigPackage
(
models
.
Model
):
# 模型名称
_inherit
=
'cc.big.package'
# 模型描述
_description
=
'Big Package'
pallet_id
=
fields
.
Many2one
(
'cc.pallet'
,
string
=
'Pallet'
,
index
=
True
)
def
action_link_pallet
(
self
):
return
{
'name'
:
_
(
'Link Pallet'
),
'type'
:
'ir.actions.act_window'
,
'views'
:
[[
False
,
"form"
]],
'res_model'
:
'associate.pallet.wizard'
,
'target'
:
'new'
,
'context'
:
{},
}
def
update_pallet_info
(
self
,
pallet_number
,
pallet_usage_date
,
pallet_id
):
"""
修改托盘信息
:param pallet_number:
:param pallet_usage_date:
:param pallet_id:
:return:
"""
self
.
pallet_usage_date
=
pallet_usage_date
self
.
pallet_number
=
pallet_number
self
.
pallet_id
=
pallet_id
\ No newline at end of file
ccs_pallet/models/cc_pallet.py
浏览文件 @
1b8d84e6
# -*- coding: utf-8 -*-
# 导入日志
import
json
import
logging
from
datetime
import
timedelta
import
pytz
from
odoo
import
models
,
fields
,
api
,
_
from
odoo.exceptions
import
UserError
,
ValidationError
# 获取日志
_logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -19,125 +15,95 @@ class CcPallet(models.Model):
_inherit
=
[
'mail.thread'
,
'mail.activity.mixin'
]
# 模型描述
_description
=
'Pallet'
@api.model
def
create
(
self
,
vals
):
# 托盘号(年月+4位数,不能重复生成)
if
not
vals
.
get
(
'name'
):
vals
[
'name'
]
=
self
.
get_start_number
()
return
super
(
CcPallet
,
self
)
.
create
(
vals
)
def
get_start_number
(
self
):
"""
获取当前年月+4位数,不能重复生成
"""
now
=
fields
.
Datetime
.
now
()
year_month
=
now
.
strftime
(
'
%
Y
%
m'
)
last_pallet
=
self
.
search
([(
'name'
,
'like'
,
year_month
+
'
%
'
)],
order
=
'name desc'
,
limit
=
1
)
if
last_pallet
and
last_pallet
.
name
:
last_number
=
int
(
last_pallet
.
name
[
-
4
:])
new_number
=
last_number
+
1
else
:
new_number
=
1
return
f
"{year_month}{new_number:04d}"
@api.model
def
get_partner_id
(
self
):
"""
默认给值,随机选一个未存档的客户
"""
return
self
.
env
[
'res.partner'
]
.
search
([(
'is_customer'
,
'='
,
True
),
(
'active'
,
'='
,
True
)],
limit
=
1
)
.
id
# 计算字段:大包数量
@api.depends
(
'package_ids'
)
def
_compute_package_count
(
self
):
for
record
in
self
:
record
.
package_count
=
len
(
record
.
package_ids
)
# 计算字段:托盘理货时间和交货时间
@api.depends
(
'package_ids'
,
'package_ids.tally_time'
,
'package_ids.delivery_time'
)
def
_compute_pallet_times
(
self
):
for
pallet
in
self
:
if
pallet
.
package_ids
:
# 获取所有关联大包的理货时间,取最晚的时间
sorting_times
=
pallet
.
package_ids
.
filtered
(
'tally_time'
)
.
mapped
(
'tally_time'
)
if
sorting_times
:
pallet
.
sorting_time
=
max
(
sorting_times
)
else
:
pallet
.
sorting_time
=
False
# 获取所有关联大包的尾程交货时间,取最晚的时间
delivery_times
=
pallet
.
package_ids
.
filtered
(
'delivery_time'
)
.
mapped
(
'delivery_time'
)
if
delivery_times
:
pallet
.
delivery_time
=
max
(
delivery_times
)
else
:
pallet
.
delivery_time
=
False
else
:
pallet
.
sorting_time
=
False
pallet
.
delivery_time
=
False
# 托盘号(年月+4位数,不能重复生成)
name
=
fields
.
Char
(
string
=
'托盘号'
,
required
=
True
,
readonly
=
True
,
copy
=
False
,
default
=
lambda
self
:
_
(
'New'
),
help
=
'托盘号格式:年月+4位数'
)
name
=
fields
.
Char
(
string
=
_
(
'Pallet Number'
),
required
=
True
,
readonly
=
True
,
copy
=
False
,
help
=
_
(
'Pallet number format: YYYYMM + 4 digits'
))
# 托盘归属快递
express_company_id
=
fields
.
Many2one
(
'res.partner'
,
string
=
'托盘归属快递'
,
required
=
True
,
domain
=
[(
'is_express_company'
,
'='
,
True
)],
help
=
'选择尾程快递公司'
)
# 创建时间
create_date
=
fields
.
Datetime
(
string
=
'创建时间'
,
readonly
=
True
,
default
=
fields
.
Datetime
.
now
)
# 创建人
create_uid
=
fields
.
Many2one
(
'res.users'
,
string
=
'创建人'
,
readonly
=
True
,
default
=
lambda
self
:
self
.
env
.
user
)
express_company_id
=
fields
.
Many2one
(
'cc.last.mile.provider'
,
string
=
_
(
'Express Company'
),
index
=
True
)
# 使用状态
usage_state
=
fields
.
Selection
([
(
'unused'
,
'未使用'
),
(
'used'
,
'已使用'
)
],
string
=
'使用状态'
,
default
=
'unused'
,
required
=
True
,
tracking
=
True
)
usage_state
=
fields
.
Selection
([(
'unused'
,
_
(
'Unused'
)),
(
'used'
,
_
(
'Used'
))],
string
=
_
(
'Usage State'
),
default
=
'unused'
,
index
=
True
,
tracking
=
True
)
# 打印状态
print_state
=
fields
.
Selection
([
(
'unprinted'
,
'未打印'
),
(
'printed'
,
'已打印'
)
],
string
=
'打印状态'
,
default
=
'unprinted'
,
required
=
True
,
tracking
=
True
)
# 托盘理货时间
sorting_time
=
fields
.
Datetime
(
string
=
'托盘理货时间'
,
help
=
'托盘理货完成的时间'
)
# 托盘交货时间
delivery_time
=
fields
.
Datetime
(
string
=
'托盘交货时间'
,
help
=
'托盘交付给客户的时间'
)
print_state
=
fields
.
Selection
([(
'unprinted'
,
_
(
'Unprinted'
)),
(
'printed'
,
_
(
'Printed'
))],
string
=
_
(
'Print State'
),
default
=
'unprinted'
,
index
=
True
,
tracking
=
True
)
# 托盘理货时间(计算字段)
sorting_time
=
fields
.
Datetime
(
string
=
_
(
'Sorting Time'
),
compute
=
'_compute_pallet_times'
,
store
=
True
)
# 托盘交货时间(计算字段)
delivery_time
=
fields
.
Datetime
(
string
=
_
(
'Delivery Time'
),
compute
=
'_compute_pallet_times'
,
store
=
True
)
# 托盘装载大包
package_ids
=
fields
.
One2many
(
'stock.picking'
,
'pallet_id'
,
string
=
'托盘装载大包'
,
help
=
'装载在此托盘上的大包'
)
package_ids
=
fields
.
Many2many
(
'cc.big.package'
,
'pallet_package_rel'
,
string
=
_
(
'Packages'
))
# 大包数量
package_count
=
fields
.
Integer
(
string
=
'托盘装载大包数'
,
compute
=
'_compute_package_count'
,
store
=
True
)
package_count
=
fields
.
Integer
(
string
=
_
(
'Package Count'
),
compute
=
'_compute_package_count'
,
store
=
True
)
# 使用客户
customer_id
=
fields
.
Many2one
(
'res.partner'
,
string
=
'使用客户'
,
domain
=
[(
'is_company'
,
'='
,
True
)],
help
=
'使用此托盘的客户'
)
partner_id
=
fields
.
Many2one
(
'res.partner'
,
string
=
_
(
'Customer'
),
default
=
get_partner_id
,
domain
=
[(
'is_customer'
,
'='
,
True
)])
# 托盘交付车牌号
delivery_plate_number
=
fields
.
Char
(
string
=
'托盘交付车牌号'
,
help
=
'交付托盘时的车牌号'
)
# 计算字段:大包数量
@api.depends
(
'package_ids'
)
def
_compute_package_count
(
self
):
for
record
in
self
:
record
.
package_count
=
len
(
record
.
package_ids
)
# 重写create方法,自动生成托盘号
@api.model
def
create
(
self
,
vals
):
if
vals
.
get
(
'name'
,
_
(
'New'
))
==
_
(
'New'
):
# 生成托盘号:年月+4位数
now
=
fields
.
Datetime
.
now
()
year_month
=
now
.
strftime
(
'
%
Y
%
m'
)
# 查找当月最大的编号
last_pallet
=
self
.
search
([
(
'name'
,
'like'
,
year_month
+
'
%
'
)
],
order
=
'name desc'
,
limit
=
1
)
if
last_pallet
and
last_pallet
.
name
:
# 提取最后4位数字
last_number
=
int
(
last_pallet
.
name
[
-
4
:])
new_number
=
last_number
+
1
else
:
new_number
=
1
# 生成新的托盘号
vals
[
'name'
]
=
f
"{year_month}{new_number:04d}"
return
super
(
CcPallet
,
self
)
.
create
(
vals
)
delivery_plate_number
=
fields
.
Char
(
string
=
_
(
'Delivery Plate Number'
))
# 当大包关联到托盘时,自动更新使用状态
@api.model
def
update_usage_state
(
self
):
...
...
@@ -147,12 +113,13 @@ class CcPallet(models.Model):
pallet
.
usage_state
=
'used'
else
:
pallet
.
usage_state
=
'unused'
def
action_print_labels
(
self
):
"""打印标签动作"""
return
{
'type'
:
'ir.actions.act_window'
,
'name'
:
_
(
'
打印托盘标签
'
),
'name'
:
_
(
'
Print Pallet Labels
'
),
'res_model'
:
'pallet.print.wizard'
,
'view_mode'
:
'form'
,
'target'
:
'new'
,
...
...
@@ -160,24 +127,25 @@ class CcPallet(models.Model):
'default_pallet_ids'
:
[(
6
,
0
,
self
.
ids
)],
},
}
def
action_view_packages
(
self
):
"""查看大包动作"""
return
{
'type'
:
'ir.actions.act_window'
,
'name'
:
_
(
'
托盘大包
'
),
'name'
:
_
(
'
Pallet Packages
'
),
'res_model'
:
'stock.picking'
,
'view_mode'
:
'list,form'
,
'domain'
:
[(
'pallet_id'
,
'='
,
self
.
id
)],
'context'
:
{
'default_pallet_id'
:
self
.
id
},
}
def
action_batch_create
(
self
):
"""批量创建托盘动作"""
return
{
'name'
:
_
(
'Batch Create Pallets'
),
'type'
:
'ir.actions.act_window'
,
'
name'
:
_
(
'批量创建托盘'
)
,
'
views'
:
[[
False
,
"form"
]]
,
'res_model'
:
'pallet.batch.wizard'
,
'view_mode'
:
'form'
,
'target'
:
'new'
,
}
\ No newline at end of file
'context'
:
{},
}
ccs_pallet/reports/pallet_label_report.xml
浏览文件 @
1b8d84e6
...
...
@@ -26,11 +26,14 @@
<!-- 条形码区域 -->
<div
style=
"text-align: center; margin: 2cm 0; padding: 1cm; border: 2px dashed #999; background-color: #f9f9f9;"
>
<div
style=
"font-size: 18px; color: #666; margin-bottom: 0.5cm;"
>
条形二维码
</div>
<!-- 这里可以集成条形码生成库 -->
<div
style=
"font-size: 14px; color: #999;"
>
<t
t-esc=
"pallet.name"
/>
<!-- 托盘号作为二维码 -->
<t
t-if=
"pallet.name"
>
<!-- `quiet=0` to remove the left and right margins on the barcode -->
<div
t-out=
"pallet.name"
style=
"padding:0"
t-options=
"{'widget': 'barcode', 'quiet': 0, 'symbology': 'auto', 'img_style': barcode_size}"
/>
<div
class=
"o_label_name"
style=
"height:1.7em;background-color: transparent;"
>
<span
t-out=
"pallet.name"
/>
</div>
</t>
</div>
</div>
...
...
ccs_pallet/security/ir.model.access.csv
浏览文件 @
1b8d84e6
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_cc_pallet_user,cc.pallet.user,model_cc_pallet,base.group_user,1,1,1,0
access_cc_pallet_manager,cc.pallet.manager,model_cc_pallet,base.group_system,1,1,1,1
access_pallet_batch_wizard_user,pallet.batch.wizard.user,model_pallet_batch_wizard,base.group_user,1,1,1,0
access_pallet_print_wizard_user,pallet.print.wizard.user,model_pallet_print_wizard,base.group_user,1,1,1,0
\ No newline at end of file
pallet_batch_wizard_group_user,pallet_batch_wizard_group_user,model_pallet_batch_wizard,base.group_user,1,1,1,1
pallet_print_wizard_group_user,pallet_print_wizard_group_user,model_pallet_print_wizard,base.group_user,1,1,1,1
associate_pallet_wizard_group_user,associate_pallet_wizard_group_user,model_associate_pallet_wizard,base.group_user,1,1,1,1
cc_pallet_group_user,cc_pallet_group_user,model_cc_pallet,base.group_user,1,1,1,0
cc_pallet_group_system,cc_pallet_group_system,model_cc_pallet,base.group_system,1,1,1,1
cc_pallet_group_pallet_manager,cc_pallet_group_pallet_manager,model_cc_pallet,ccs_pallet.group_pallet_manager,1,1,1,1
cc_big_package_group_pallet_manager,cc_big_package_group_pallet_manager,model_cc_big_package,ccs_pallet.group_pallet_manager,1,1,0,0
ccs_pallet/security/pallet_security.xml
浏览文件 @
1b8d84e6
...
...
@@ -2,7 +2,7 @@
<odoo>
<data
noupdate=
"0"
>
<record
model=
"ir.module.category"
id=
"ccs_
base
.module_category_pallet"
>
<record
model=
"ir.module.category"
id=
"ccs_
pallet
.module_category_pallet"
>
<field
name=
"name"
>
Pallet Information
</field>
<field
name=
"description"
>
Pallet Information
</field>
<field
name=
"sequence"
>
7
</field>
...
...
@@ -10,7 +10,7 @@
<record
id=
"group_pallet_manager"
model=
"res.groups"
>
<field
name=
"name"
>
Pallet Manager
</field>
<field
name=
"category_id"
ref=
"ccs_
base
.module_category_pallet"
/>
<field
name=
"category_id"
ref=
"ccs_
pallet
.module_category_pallet"
/>
<field
name=
"implied_ids"
eval=
"[(4, ref('base.group_user'))]"
/>
</record>
</data>
...
...
ccs_pallet/static/src/mixins/batch_create_pallet.js
0 → 100644
浏览文件 @
1b8d84e6
/** @odoo-module */
import
{
useService
}
from
'@web/core/utils/hooks'
;
const
{
useRef
,
useEffect
,
useState
}
=
owl
;
export
const
BatchCreatePallet
=
{
setup
()
{
this
.
_super
();
this
.
actionService
=
useService
(
'action'
);
this
.
notification
=
useService
(
'notification'
);
this
.
orm
=
useService
(
'orm'
);
this
.
http
=
useService
(
'http'
);
this
.
fileInput
=
useRef
(
'fileInput'
);
this
.
root
=
useRef
(
"root"
);
},
async
onBatchCreatePalletClick
()
{
// 点击按钮弹出批量创建托盘的向导
const
records
=
this
.
model
.
root
.
selection
;
const
recordIds
=
records
.
map
((
a
)
=>
a
.
resId
);
const
action
=
await
this
.
orm
.
call
(
'cc.pallet'
,
'action_batch_create'
,
[
recordIds
]);
this
.
actionService
.
doAction
(
action
);
},
};
ccs_
base
/static/src/mixins/link_pallet.js
→
ccs_
pallet
/static/src/mixins/link_pallet.js
浏览文件 @
1b8d84e6
File moved
ccs_
base
/static/src/views/big_package_list_controller.js
→
ccs_
pallet
/static/src/views/big_package_list_controller.js
浏览文件 @
1b8d84e6
...
...
@@ -21,7 +21,7 @@ export class BigPackageListController extends ListController {
this
.
isBigPackage
=
this
.
model
.
rootParams
.
resModel
===
"cc.big.package"
;
console
.
log
(
'ccs isBigPackage:'
+
this
.
isBigPackage
)
onWillStart
(
async
()
=>
{
this
.
is_link
=
await
this
.
user
.
hasGroup
(
"ccs_base.group_clearance_of_customs_manager"
);
this
.
is_link
=
await
this
.
user
.
hasGroup
(
"ccs_base.group_clearance_of_customs_manager"
)
||
await
this
.
user
.
hasGroup
(
"ccs_pallet.group_pallet_manager"
)
;
console
.
log
(
'ccs is_link:'
+
this
.
is_link
)
});
}
...
...
@@ -32,8 +32,8 @@ export class BigPackageListController extends ListController {
return
this
.
isBigPackage
&&
this
.
is_link
;
}
display
TransferBlNo
()
{
// 大包页面永远不显示“
关联转单号
”按钮
display
BatchCreatePallet
()
{
// 大包页面永远不显示“
批量创建托盘
”按钮
return
false
;
}
...
...
@@ -43,6 +43,6 @@ patch(BigPackageListController.prototype, 'big_package_list_controller_link_pall
registry
.
category
(
'views'
).
add
(
'cc_big_package_tree'
,
{
...
listView
,
buttonTemplate
:
'ccs_
base
.ListButtons'
,
buttonTemplate
:
'ccs_
pallet
.ListButtons'
,
Controller
:
BigPackageListController
});
\ No newline at end of file
ccs_pallet/static/src/views/bl_list_pallet_controller.js
0 → 100644
浏览文件 @
1b8d84e6
/** @odoo-module */
import
{
BatchCreatePallet
}
from
'../mixins/batch_create_pallet'
;
import
{
registry
}
from
'@web/core/registry'
;
import
{
patch
}
from
'@web/core/utils/patch'
;
import
{
useService
}
from
'@web/core/utils/hooks'
;
import
{
listView
}
from
"@web/views/list/list_view"
;
import
{
ListController
}
from
"@web/views/list/list_controller"
;
const
{
onWillStart
}
=
owl
;
export
class
BlListPalletController
extends
ListController
{
setup
()
{
super
.
setup
();
console
.
log
(
'----------引用成功'
)
this
.
orm
=
useService
(
'orm'
);
this
.
actionService
=
useService
(
'action'
);
this
.
rpc
=
useService
(
"rpc"
);
this
.
user
=
useService
(
"user"
);
this
.
isPallet
=
this
.
model
.
rootParams
.
resModel
===
"cc.pallet"
;
console
.
log
(
'ccs isPallet:'
+
this
.
isPallet
)
onWillStart
(
async
()
=>
{
this
.
can_batch_create_pallet
=
await
this
.
user
.
hasGroup
(
"ccs_pallet.group_pallet_manager"
);
console
.
log
(
'ccs can_batch_create_pallet:'
+
this
.
can_batch_create_pallet
)
});
}
displayLink
()
{
// 提单页面永远不显示“关联托盘”按钮
return
false
;
}
displayBatchCreatePallet
()
{
console
.
log
(
'ccs flag:'
+
this
.
isPallet
&&
this
.
can_batch_create_pallet
)
// 是提单的对象以及有清关用户的权限才显示按钮
return
this
.
isPallet
&&
this
.
can_batch_create_pallet
;
}
}
patch
(
BlListPalletController
.
prototype
,
'batch_create_pallet'
,
BatchCreatePallet
);
registry
.
category
(
'views'
).
add
(
'cc_pallet_tree'
,
{
...
listView
,
buttonTemplate
:
'ccs_pallet.ListButtons'
,
Controller
:
BlListPalletController
});
\ No newline at end of file
ccs_pallet/static/src/views/list.xml
0 → 100644
浏览文件 @
1b8d84e6
<?xml version="1.0" encoding="UTF-8"?>
<templates
xml:space=
"preserve"
>
<t
t-name=
"ccs_pallet.ListButtons"
t-inherit=
"web.ListView.Buttons"
t-inherit-mode=
"primary"
owl=
"1"
>
<xpath
expr=
"//button[hasclass('o_list_button_add')]"
position=
"after"
>
<button
t-if=
"displayLink()"
type=
"button"
class=
"d-none d-md-inline o_button_link_pallet btn btn-primary mx-1"
t-on-click.prevent=
"onLinkPalletClick"
>
Link Pallet
</button>
</xpath>
<xpath
expr=
"//button[hasclass('o_list_button_add')]"
position=
"after"
>
<button
t-if=
"displayBatchCreatePallet()"
type=
"button"
class=
"d-none d-md-inline o_button_batch_create_pallet btn btn-primary mx-1"
t-on-click.prevent=
"onBatchCreatePalletClick"
>
Batch Create Pallet
</button>
</xpath>
</t>
</templates>
ccs_pallet/views/cc_big_package_view.xml
0 → 100644
浏览文件 @
1b8d84e6
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record
model=
"ir.ui.view"
id=
"tree_cc_big_package_view"
>
<field
name=
"name"
>
tree.cc.big.package
</field>
<field
name=
"model"
>
cc.big.package
</field>
<field
name=
"inherit_id"
ref=
"ccs_base.tree_cc_big_package_view"
/>
<field
name=
"arch"
type=
"xml"
>
<tree
position=
"attributes"
>
<attribute
name=
"js_class"
>
cc_big_package_tree
</attribute>
</tree>
</field>
</record>
</odoo>
\ No newline at end of file
ccs_pallet/views/cc_pallet_view.xml
浏览文件 @
1b8d84e6
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- 托盘管理列表视图 -->
<record
id=
"view_cc_pallet_list"
model=
"ir.ui.view"
>
<field
name=
"name"
>
cc.pallet.list
</field>
<field
name=
"model"
>
cc.pallet
</field>
<field
name=
"arch"
type=
"xml"
>
<list
string=
"托盘管理"
multi_edit=
"1"
>
<field
name=
"name"
string=
"托盘号"
/>
<field
name=
"express_company_id"
string=
"托盘归属快递"
/>
<field
name=
"usage_state"
string=
"使用状态"
decoration-success=
"usage_state == 'unused'"
decoration-warning=
"usage_state == 'used'"
/>
<field
name=
"print_state"
string=
"打印状态"
decoration-info=
"print_state == 'unprinted'"
decoration-success=
"print_state == 'printed'"
/>
<field
name=
"sorting_time"
string=
"托盘理货时间"
/>
<field
name=
"delivery_time"
string=
"托盘交货时间"
/>
<field
name=
"package_count"
string=
"托盘装载大包数"
/>
<field
name=
"delivery_plate_number"
string=
"托盘交付车牌号"
/>
</list>
</field>
</record>
<!-- 托盘管理表单视图 -->
<record
id=
"view_cc_pallet_form"
model=
"ir.ui.view"
>
<field
name=
"name"
>
cc.pallet.form
</field>
<field
name=
"model"
>
cc.pallet
</field>
<field
name=
"arch"
type=
"xml"
>
<form
string=
"
托盘管理
"
>
<form
string=
"
Pallet Management
"
>
<header>
<button
name=
"action_print_labels"
string=
"打印标签"
type=
"object"
class=
"btn-primary"
icon=
"fa-print"
/>
<field
name=
"usage_state"
widget=
"statusbar"
statusbar_visible=
"unused,used"
/>
<button
name=
"action_print_labels"
string=
"Print Labels"
type=
"object"
class=
"btn-primary"
icon=
"fa-print"
/>
<field
name=
"usage_state"
widget=
"statusbar"
/>
</header>
<sheet>
<div
class=
"oe_button_box"
name=
"button_box"
>
<button
name=
"action_view_packages"
type=
"object"
class=
"oe_stat_button"
icon=
"fa-cubes"
>
<field
name=
"package_count"
widget=
"statinfo"
string=
"
大包
"
/>
<field
name=
"package_count"
widget=
"statinfo"
string=
"
Packages
"
/>
</button>
</div>
<div
class=
"oe_title"
>
<h1>
<field
name=
"name"
readonly=
"1"
/>
</h1>
</div>
<group>
<group
string=
"
基本信息
"
>
<group
string=
"
Basic Information
"
>
<field
name=
"express_company_id"
required=
"1"
/>
<field
name=
"
custom
er_id"
/>
<field
name=
"
partn
er_id"
/>
<field
name=
"delivery_plate_number"
/>
</group>
<group
string=
"
状态信息
"
>
<group
string=
"
Status Information
"
>
<field
name=
"print_state"
/>
<field
name=
"sorting_time"
/>
<field
name=
"delivery_time"
/>
</group>
</group>
<notebook>
<page
string=
"大包信息"
name=
"packages"
>
<field
name=
"package_ids"
>
<list>
<field
name=
"name"
/>
<field
name=
"partner_id"
/>
<field
name=
"state"
/>
</list>
</field>
<page
string=
"Package Information"
name=
"packages"
>
<field
name=
"package_ids"
/>
</page>
</notebook>
</sheet>
...
...
@@ -71,28 +45,49 @@
</field>
</record>
<!-- 托盘管理列表视图 -->
<record
id=
"view_cc_pallet_list"
model=
"ir.ui.view"
>
<field
name=
"name"
>
cc.pallet.list
</field>
<field
name=
"model"
>
cc.pallet
</field>
<field
name=
"arch"
type=
"xml"
>
<tree
string=
"Pallet Management"
js_class=
"cc_pallet_tree"
>
<field
name=
"name"
string=
"Pallet Number"
/>
<field
name=
"express_company_id"
string=
"Express Company"
/>
<field
name=
"usage_state"
string=
"Usage State"
decoration-success=
"usage_state == 'unused'"
decoration-warning=
"usage_state == 'used'"
/>
<field
name=
"print_state"
string=
"Print State"
decoration-info=
"print_state == 'unprinted'"
decoration-success=
"print_state == 'printed'"
/>
<field
name=
"sorting_time"
string=
"Sorting Time"
/>
<field
name=
"delivery_time"
string=
"Delivery Time"
/>
<field
name=
"package_count"
string=
"Package Count"
/>
<field
name=
"delivery_plate_number"
string=
"Delivery Plate Number"
/>
</tree>
</field>
</record>
<!-- 托盘管理搜索视图 -->
<record
id=
"view_cc_pallet_search"
model=
"ir.ui.view"
>
<field
name=
"name"
>
cc.pallet.search
</field>
<field
name=
"model"
>
cc.pallet
</field>
<field
name=
"arch"
type=
"xml"
>
<search
string=
"
托盘搜索
"
>
<field
name=
"name"
string=
"
托盘号
"
filter_domain=
"[('name', 'ilike', self)]"
/>
<field
name=
"express_company_id"
string=
"
快递公司
"
/>
<field
name=
"
customer_id"
string=
"使用客户
"
/>
<field
name=
"delivery_plate_number"
string=
"
车牌号
"
/>
<search
string=
"
Pallet Search
"
>
<field
name=
"name"
string=
"
Pallet Number
"
filter_domain=
"[('name', 'ilike', self)]"
/>
<field
name=
"express_company_id"
string=
"
Express Company
"
/>
<field
name=
"
partner_id"
string=
"Customer
"
/>
<field
name=
"delivery_plate_number"
string=
"
Plate Number
"
/>
<separator/>
<filter
name=
"filter_unused"
string=
"
未使用
"
domain=
"[('usage_state', '=', 'unused')]"
/>
<filter
name=
"filter_used"
string=
"
已使用
"
domain=
"[('usage_state', '=', 'used')]"
/>
<filter
name=
"filter_unprinted"
string=
"
未打印
"
domain=
"[('print_state', '=', 'unprinted')]"
/>
<filter
name=
"filter_printed"
string=
"
已打印
"
domain=
"[('print_state', '=', 'printed')]"
/>
<filter
name=
"filter_unused"
string=
"
Unused
"
domain=
"[('usage_state', '=', 'unused')]"
/>
<filter
name=
"filter_used"
string=
"
Used
"
domain=
"[('usage_state', '=', 'used')]"
/>
<filter
name=
"filter_unprinted"
string=
"
Unprinted
"
domain=
"[('print_state', '=', 'unprinted')]"
/>
<filter
name=
"filter_printed"
string=
"
Printed
"
domain=
"[('print_state', '=', 'printed')]"
/>
<separator/>
<group
expand=
"0"
string=
"分组"
>
<filter
name=
"group_by_express"
string=
"尾程快递"
context=
"{'group_by': 'express_company_id'}"
/>
<filter
name=
"group_by_print_state"
string=
"打印状态"
context=
"{'group_by': 'print_state'}"
/>
<filter
name=
"group_by_usage_state"
string=
"使用状态"
context=
"{'group_by': 'usage_state'}"
/>
<group
expand=
"0"
string=
"Group By"
>
<filter
name=
"group_by_express"
string=
"Express Company"
context=
"{'group_by': 'express_company_id'}"
/>
<filter
name=
"group_by_print_state"
string=
"Print State"
context=
"{'group_by': 'print_state'}"
/>
<filter
name=
"group_by_usage_state"
string=
"Usage State"
context=
"{'group_by': 'usage_state'}"
/>
</group>
</search>
</field>
...
...
@@ -100,44 +95,18 @@
<!-- 托盘管理动作 -->
<record
id=
"action_cc_pallet"
model=
"ir.actions.act_window"
>
<field
name=
"name"
>
托盘管理
</field>
<field
name=
"name"
>
Pallet Management
</field>
<field
name=
"res_model"
>
cc.pallet
</field>
<field
name=
"view_mode"
>
list
,form
</field>
<field
name=
"view_mode"
>
tree
,form
</field>
<field
name=
"context"
>
{}
</field>
<field
name=
"help"
type=
"html"
>
<p
class=
"o_view_nocontent_smiling_face"
>
创建托盘
Create Pallet
</p>
<p>
托盘管理系统用于管理仓库中的托盘,包括托盘号生成、状态跟踪和标签打印。
Pallet management system for managing pallets in the warehouse, including pallet number generation,
status tracking and label printing.
</p>
</field>
</record>
<!-- 批量创建托盘动作 -->
<record
id=
"action_cc_pallet_batch_create"
model=
"ir.actions.act_window"
>
<field
name=
"name"
>
批量创建托盘
</field>
<field
name=
"res_model"
>
pallet.batch.wizard
</field>
<field
name=
"view_mode"
>
form
</field>
<field
name=
"target"
>
new
</field>
<field
name=
"context"
>
{}
</field>
</record>
<!-- 菜单项 -->
<menuitem
id=
"menu_cc_pallet_root"
name=
"托盘管理"
sequence=
"10"
/>
<menuitem
id=
"menu_cc_pallet"
name=
"托盘管理"
parent=
"menu_cc_pallet_root"
action=
"action_cc_pallet"
sequence=
"10"
/>
<menuitem
id=
"menu_cc_pallet_batch_create"
name=
"批量创建托盘"
parent=
"menu_cc_pallet_root"
action=
"action_cc_pallet_batch_create"
sequence=
"20"
/>
</odoo>
\ No newline at end of file
ccs_pallet/views/menu_view.xml
浏览文件 @
1b8d84e6
...
...
@@ -2,6 +2,15 @@
<odoo>
<data>
<!-- 菜单项 -->
<menuitem
id=
"menu_cc_pallet_root"
name=
"Pallet Management"
sequence=
"18"
groups=
"ccs_pallet.group_pallet_manager"
/>
<menuitem
id=
"menu_cc_pallet"
name=
"Pallet"
parent=
"menu_cc_pallet_root"
action=
"action_cc_pallet"
sequence=
"10"
/>
</data>
</odoo>
\ No newline at end of file
ccs_pallet/wizard/__init__.py
浏览文件 @
1b8d84e6
...
...
@@ -2,3 +2,4 @@
from
.
import
pallet_batch_wizard
from
.
import
pallet_print_wizard
from
.
import
associate_pallet_wizard
ccs_
base
/wizard/associate_pallet_wizard.py
→
ccs_
pallet
/wizard/associate_pallet_wizard.py
浏览文件 @
1b8d84e6
...
...
@@ -10,40 +10,17 @@ class AssociatePalletWizard(models.TransientModel):
_name
=
'associate.pallet.wizard'
_description
=
'Associate Pallet Wizard'
@api.onchange
(
'usage_date'
)
def
change_usage_date
(
self
):
for
item
in
self
:
if
item
.
usage_date
:
item
.
pallet_number
=
item
.
get_pallet_number
(
item
.
usage_date
)
def
get_pallet_number
(
self
,
usage_date
):
"""
生成托盘号 从001开始,如果
:return: 新的托盘号
"""
try
:
# 查找大包中最新的托盘号
latest_pallet
=
self
.
env
[
'cc.big.package'
]
.
search
([(
'pallet_usage_date'
,
'='
,
str
(
usage_date
))],
order
=
'pallet_number desc'
,
limit
=
1
)
# 生成新的托盘号
if
latest_pallet
:
new_pallet_number
=
int
(
latest_pallet
.
pallet_number
)
+
1
else
:
new_pallet_number
=
1
# 如果没有找到,默认从1开始
return
str
(
new_pallet_number
)
.
zfill
(
3
)
# 返回格式化的托盘号
except
Exception
as
e
:
raise
ValidationError
(
str
(
e
))
usage_date
=
fields
.
Date
(
string
=
'Usage Date'
,
default
=
fields
.
Date
.
today
)
# 使用日期
pallet_
number
=
fields
.
Char
(
string
=
'Pallet Number'
,
required
=
True
)
# 托盘号
pallet_
id
=
fields
.
Many2one
(
'cc.pallet'
,
string
=
'Pallet'
)
# 托盘选择
big_package_numbers
=
fields
.
Text
(
string
=
'Big Package Numbers'
)
# 大包号(可输入多个)
def
confirm
(
self
):
for
record
in
self
:
if
not
record
.
pallet_
number
.
isdigit
()
:
raise
ValidationError
(
_
(
'
The pallet number can only be entered as a number!'
))
# 托盘号只能输入数字
!
if
not
record
.
pallet_
id
:
raise
ValidationError
(
_
(
'
Please select a pallet!'
))
# 请选择托盘
!
if
record
.
usage_date
>
fields
.
Date
.
today
():
raise
ValidationError
(
_
(
'The usage date cannot be later than the current date!'
))
# 使用日期不能大于当前日期!
# 处理大包号
big_package_ids
=
record
.
big_package_numbers
.
splitlines
()
success_package
=
[]
...
...
@@ -54,15 +31,21 @@ class AssociatePalletWizard(models.TransientModel):
success_package
.
append
(
package
)
else
:
fail_package
.
append
(
package_number
)
if
fail_package
:
raise
ValidationError
(
_
(
'
%
s The package does not exist, please check the input information!'
)
%
(
'
\n
'
.
join
(
fail_package
)))
# 不存在该大包,请检查输入信息
if
success_package
:
# 关联大包到托盘
record
.
pallet_id
.
package_ids
=
[(
6
,
0
,
[
p
.
id
for
p
in
success_package
])]
# 更新大包的托盘信息
for
package
in
success_package
:
# 回写大包的托盘号和使用日期
old_pallet_number
=
package
.
pallet_number
new_pallet_number
=
record
.
pallet_
number
# 修改的托盘
号
new_pallet_number
=
record
.
pallet_
id
.
name
# 使用托盘的编
号
old_usage_date
=
package
.
pallet_usage_date
# 同一提单,同一托盘号,使用日期必须一致
related_packages
=
package
.
bl_id
.
big_package_ids
.
filtered
(
lambda
p
:
p
.
pallet_number
==
new_pallet_number
)
# 查找对应提单下相同托盘号的所有大包
...
...
@@ -72,7 +55,9 @@ class AssociatePalletWizard(models.TransientModel):
raise
ValidationError
(
_
(
'Big Package No :
%
s ,The same bill of lading, same pallet number, and usage date must be consistent!'
)
%
(
'
\n
'
.
join
(
warning_package_arr
)))
# 大包号关联的同一提单,同一托盘号,使用日期必须一致
package
.
update_pallet_info
(
new_pallet_number
,
record
.
usage_date
)
package
.
update_pallet_info
(
new_pallet_number
,
record
.
usage_date
,
record
.
pallet_id
.
id
)
if
old_pallet_number
:
# %s %s更改了托盘号,由%s变更为%s,托盘使用日期%s变更为%s
body
=
_
(
...
...
@@ -85,3 +70,11 @@ class AssociatePalletWizard(models.TransientModel):
body
=
_
(
'
%
s at
%
s associated tray
%
s, with a tray usage date of
%
s'
)
%
(
self
.
env
.
user
.
name
,
fields
.
Datetime
.
now
(),
new_pallet_number
,
record
.
usage_date
)
package
.
message_post
(
body
=
body
)
# 更新托盘的使用状态(理货时间和交货时间会自动通过计算字段更新)
record
.
pallet_id
.
update_usage_state
()
# 记录托盘关联日志
body
=
_
(
'
%
s at
%
s associated
%
d packages to pallet
%
s'
)
%
(
self
.
env
.
user
.
name
,
fields
.
Datetime
.
now
(),
len
(
success_package
),
record
.
pallet_id
.
name
)
record
.
pallet_id
.
message_post
(
body
=
body
)
ccs_
base
/wizard/associate_pallet_wizard_views.xml
→
ccs_
pallet
/wizard/associate_pallet_wizard_views.xml
浏览文件 @
1b8d84e6
...
...
@@ -7,7 +7,7 @@
<sheet>
<group>
<field
name=
"usage_date"
required=
"1"
/>
<!-- 使用日期 -->
<field
name=
"pallet_
number"
required=
"1"
/>
<!-- 托盘号
-->
<field
name=
"pallet_
id"
required=
"1"
options=
"{'no_create': True, 'no_quick_create': True}"
/>
<!-- 托盘选择
-->
<field
name=
"big_package_numbers"
required=
"1"
placeholder=
"Multiple can be entered, one large package number per line"
/>
<!-- 大包号 可输入多个,一行一个大包号 -->
</group>
...
...
ccs_pallet/wizard/pallet_batch_wizard.py
浏览文件 @
1b8d84e6
...
...
@@ -6,130 +6,87 @@ from odoo.exceptions import UserError, ValidationError
class
PalletBatchWizard
(
models
.
TransientModel
):
_name
=
'pallet.batch.wizard'
_description
=
'
批量创建托盘向导
'
_description
=
'
Batch Create Pallet Wizard
'
express_company_id
=
fields
.
Many2one
(
'res.partner'
,
string
=
'托盘归属快递'
,
required
=
True
,
domain
=
[(
'is_express_company'
,
'='
,
True
)],
help
=
'选择尾程快递公司'
)
quantity
=
fields
.
Integer
(
string
=
'创建数量'
,
required
=
True
,
default
=
1
,
help
=
'要创建的托盘数量'
)
start_number
=
fields
.
Char
(
string
=
'托盘创建开始编号'
,
readonly
=
True
,
help
=
'本次创建托盘的起始编号'
)
customer_id
=
fields
.
Many2one
(
'res.partner'
,
string
=
'使用客户'
,
domain
=
[(
'is_company'
,
'='
,
True
)],
help
=
'使用此托盘的客户(可选)'
)
@api.onchange
(
'express_company_id'
,
'quantity'
)
def
_onchange_express_company
(
self
):
"""当选择快递公司或数量时,计算开始编号"""
if
self
.
express_company_id
and
self
.
quantity
:
# 获取当前年月
now
=
fields
.
Datetime
.
now
()
year_month
=
now
.
strftime
(
'
%
Y
%
m'
)
# 查找当月最大的编号
last_pallet
=
self
.
env
[
'cc.pallet'
]
.
search
([
(
'name'
,
'like'
,
year_month
+
'
%
'
)
],
order
=
'name desc'
,
limit
=
1
)
if
last_pallet
and
last_pallet
.
name
:
# 提取最后4位数字
last_number
=
int
(
last_pallet
.
name
[
-
4
:])
start_number
=
last_number
+
1
else
:
start_number
=
1
self
.
start_number
=
f
"{year_month}{start_number:04d}"
# 创建数量必须大于0,且不能超过1000
@api.constrains
(
'quantity'
)
def
_check_quantity
(
self
):
"""
验证创建数量
"""
"""
Validate create quantity
"""
if
self
.
quantity
<=
0
:
raise
ValidationError
(
_
(
'
创建数量必须大于
0'
))
raise
ValidationError
(
_
(
'
Create quantity must be greater than
0'
))
if
self
.
quantity
>
1000
:
raise
ValidationError
(
_
(
'单次创建数量不能超过1000个'
))
raise
ValidationError
(
_
(
'Cannot create more than 1000 pallets at once'
))
# 托盘归属快递
express_company_id
=
fields
.
Many2one
(
'cc.last.mile.provider'
,
string
=
_
(
'Express Company'
),
index
=
True
)
# 创建数量
quantity
=
fields
.
Integer
(
string
=
_
(
'Create Quantity'
),
default
=
1
)
# 起始托盘号
start_number
=
fields
.
Char
(
string
=
_
(
'Pallet Start Number'
),
default
=
lambda
self
:
self
.
env
[
'cc.pallet'
]
.
get_start_number
())
# 使用客户
partner_id
=
fields
.
Many2one
(
'res.partner'
,
string
=
_
(
'Customer'
),
domain
=
[(
'is_customer'
,
'='
,
True
)],
default
=
lambda
self
:
self
.
env
[
'cc.pallet'
]
.
get_partner_id
())
# 确认创建托盘
def
action_confirm
(
self
):
"""确认创建托盘"""
self
.
ensure_one
()
# 检查起始托盘号是否被占用
if
self
.
start_number
:
existing_pallet
=
self
.
env
[
'cc.pallet'
]
.
search
([(
'name'
,
'='
,
self
.
start_number
)])
if
existing_pallet
:
raise
UserError
(
_
(
'Start number has been occupied, please close the window and recreate'
))
# 创建托盘记录
pallets
=
[]
now
=
fields
.
Datetime
.
now
()
year_month
=
now
.
strftime
(
'
%
Y
%
m'
)
# 获取起始编号
# 获取起始托盘号
if
self
.
start_number
:
start_num
=
int
(
self
.
start_number
[
-
4
:])
else
:
start_num
=
1
for
i
in
range
(
self
.
quantity
):
pallet_name
=
f
"{year_month}{start_num + i:04d}"
# 检查托盘号是否已存在
existing_pallet
=
self
.
env
[
'cc.pallet'
]
.
search
([
(
'name'
,
'='
,
pallet_name
)
])
# 检查每个托盘号是否已存在
existing_pallet
=
self
.
env
[
'cc.pallet'
]
.
search
([(
'name'
,
'='
,
pallet_name
)])
if
existing_pallet
:
raise
UserError
(
_
(
'托盘号
%
s 已存在,请检查系统数据'
)
%
pallet_name
)
raise
UserError
(
_
(
'Pallet number
%
s already exists, please check system data'
)
%
pallet_name
)
pallet_vals
=
{
'name'
:
pallet_name
,
'express_company_id'
:
self
.
express_company_id
.
id
,
'
customer_id'
:
self
.
customer_id
.
id
if
self
.
custom
er_id
else
False
,
'
partner_id'
:
self
.
partner_id
.
id
if
self
.
partn
er_id
else
False
,
}
pallet
=
self
.
env
[
'cc.pallet'
]
.
create
(
pallet_vals
)
pallets
.
append
(
pallet
)
# 返回创建结果
return
{
'type'
:
'ir.actions.act_window'
,
'name'
:
_
(
'
批量创建托盘结果
'
),
'name'
:
_
(
'
Batch Create Pallet Result
'
),
'res_model'
:
'cc.pallet'
,
'view_mode'
:
'list,form'
,
'domain'
:
[(
'id'
,
'in'
,
[
p
.
id
for
p
in
pallets
])],
'context'
:
{
'create'
:
False
},
}
# 确认创建托盘并打印
def
action_confirm_and_print
(
self
):
"""确认创建托盘并打印"""
self
.
ensure_one
()
"""Confirm create pallets and print"""
# 先创建托盘
result
=
self
.
action_confirm
()
# 获取创建的托盘
pallets
=
self
.
env
[
'cc.pallet'
]
.
search
([
(
'id'
,
'in'
,
result
[
'domain'
][
0
][
2
])
])
# 生成打印文件
return
self
.
_generate_print_report
(
pallets
)
# 生成打印报告
def
_generate_print_report
(
self
,
pallets
):
"""
生成打印报告
"""
#
这里需要实现PDF生成逻辑
#
暂时
返回一个简单的动作
"""
Generate print report
"""
#
PDF生成逻辑需要在这里实现
#
现在
返回一个简单的动作
return
{
'type'
:
'ir.actions.report'
,
'report_name'
:
'ccs_pallet.pallet_label_report'
,
...
...
ccs_pallet/wizard/pallet_batch_wizard_view.xml
浏览文件 @
1b8d84e6
...
...
@@ -5,45 +5,32 @@
<field
name=
"name"
>
pallet.batch.wizard.form
</field>
<field
name=
"model"
>
pallet.batch.wizard
</field>
<field
name=
"arch"
type=
"xml"
>
<form
string=
"
批量创建托盘
"
>
<form
string=
"
Batch Create Pallets
"
>
<sheet>
<div
class=
"oe_title"
>
<h1>
批量创建托盘
</h1>
</div>
<group>
<group
string=
"
创建信息
"
>
<group
string=
"
Create Information
"
>
<field
name=
"express_company_id"
required=
"1"
/>
<field
name=
"quantity"
required=
"1"
/>
<field
name=
"
custom
er_id"
/>
<field
name=
"
partn
er_id"
/>
</group>
<group
string=
"
编号信息
"
>
<group
string=
"
Number Information
"
>
<field
name=
"start_number"
readonly=
"1"
/>
</group>
</group>
<div
class=
"alert alert-info"
role=
"alert"
>
<strong>
提示:
</strong>
<ul>
<li>
托盘号将按升序自动生成
</li>
<li>
格式:年月+4位数(如:2025010001)
</li>
<li>
单次最多可创建1000个托盘
</li>
</ul>
</div>
</sheet>
<footer>
<button
name=
"action_confirm"
string=
"
确认
"
type=
"object"
class=
"btn-primary"
/>
<button
name=
"action_confirm_and_print"
string=
"
确认并打印
"
type=
"object"
class=
"btn-success"
/>
<button
string=
"
取消
"
class=
"btn-secondary"
special=
"cancel"
/>
<button
name=
"action_confirm"
string=
"
Confirm
"
type=
"object"
class=
"btn-primary"
/>
<button
name=
"action_confirm_and_print"
string=
"
Confirm and Print
"
type=
"object"
class=
"btn-success"
/>
<button
string=
"
Cancel
"
class=
"btn-secondary"
special=
"cancel"
/>
</footer>
</form>
</field>
</record>
<!-- 批量创建托盘
向导
动作 -->
<record
id=
"action_
pallet_batch_wizard
"
model=
"ir.actions.act_window"
>
<field
name=
"name"
>
批量创建托盘
</field>
<!-- 批量创建托盘动作 -->
<record
id=
"action_
cc_pallet_batch_create
"
model=
"ir.actions.act_window"
>
<field
name=
"name"
>
Batch Create Pallets
</field>
<field
name=
"res_model"
>
pallet.batch.wizard
</field>
<field
name=
"view_mode"
>
form
</field>
<field
name=
"target"
>
new
</field>
...
...
ccs_pallet/wizard/pallet_print_wizard.py
浏览文件 @
1b8d84e6
...
...
@@ -6,32 +6,22 @@ from odoo.exceptions import UserError
class
PalletPrintWizard
(
models
.
TransientModel
):
_name
=
'pallet.print.wizard'
_description
=
'
托盘打印向导
'
_description
=
'
Pallet Print Wizard
'
pallet_ids
=
fields
.
Many2many
(
'cc.pallet'
,
string
=
'托盘'
,
required
=
True
,
help
=
'选择要打印的托盘'
)
pallet_count
=
fields
.
Integer
(
string
=
'托盘数量'
,
compute
=
'_compute_pallet_count'
,
store
=
True
)
@api.depends
(
'pallet_ids'
)
def
_compute_pallet_count
(
self
):
"""计算托盘数量"""
for
record
in
self
:
record
.
pallet_count
=
len
(
record
.
pallet_ids
)
pallet_ids
=
fields
.
Many2many
(
'cc.pallet'
,
string
=
_
(
'Pallets'
))
pallet_count
=
fields
.
Integer
(
string
=
_
(
'Pallet Count'
),
compute
=
'_compute_pallet_count'
,
store
=
True
)
def
action_print
(
self
):
"""执行打印"""
self
.
ensure_one
()
if
not
self
.
pallet_ids
:
raise
UserError
(
_
(
'
请选择要打印的托盘
'
))
raise
UserError
(
_
(
'
Please select pallets to print
'
))
# 更新打印状态为已打印
self
.
pallet_ids
.
write
({
'print_state'
:
'printed'
})
...
...
ccs_pallet/wizard/pallet_print_wizard_view.xml
浏览文件 @
1b8d84e6
...
...
@@ -5,10 +5,10 @@
<field
name=
"name"
>
pallet.print.wizard.form
</field>
<field
name=
"model"
>
pallet.print.wizard
</field>
<field
name=
"arch"
type=
"xml"
>
<form
string=
"
托盘打印
"
>
<form
string=
"
Pallet Print
"
>
<sheet>
<div
class=
"oe_title"
>
<h1>
托盘标签打印
</h1>
<h1>
Pallet Label Print
</h1>
</div>
<group>
...
...
@@ -16,20 +16,11 @@
</group>
<field
name=
"pallet_ids"
widget=
"many2many_tags"
readonly=
"1"
/>
<div
class=
"alert alert-info"
role=
"alert"
>
<strong>
打印说明:
</strong>
<ul>
<li>
标签尺寸:10cm × 15cm
</li>
<li>
标签内容:客户名称、尾程快递简称、托盘号条形码
</li>
<li>
打印后托盘状态将自动更新为"已打印"
</li>
</ul>
</div>
</sheet>
<footer>
<button
name=
"action_print"
string=
"
确定打印
"
type=
"object"
class=
"btn-primary"
/>
<button
string=
"
取消
"
class=
"btn-secondary"
special=
"cancel"
/>
<button
name=
"action_print"
string=
"
Confirm Print
"
type=
"object"
class=
"btn-primary"
/>
<button
string=
"
Cancel
"
class=
"btn-secondary"
special=
"cancel"
/>
</footer>
</form>
</field>
...
...
@@ -37,7 +28,7 @@
<!-- 托盘打印向导动作 -->
<record
id=
"action_pallet_print_wizard"
model=
"ir.actions.act_window"
>
<field
name=
"name"
>
托盘打印
</field>
<field
name=
"name"
>
Pallet Print
</field>
<field
name=
"res_model"
>
pallet.print.wizard
</field>
<field
name=
"view_mode"
>
form
</field>
<field
name=
"target"
>
new
</field>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论