提交 8279ed7a authored 作者: 刘擎阳's avatar 刘擎阳

1.优化

上级 53af0a0d
...@@ -2710,15 +2710,20 @@ msgid "Package Goods" ...@@ -2710,15 +2710,20 @@ msgid "Package Goods"
msgstr "小包商品" msgstr "小包商品"
#. module: ccs_base #. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_cc_big_package__goods_qty
#: model:ir.model.fields,field_description:ccs_base.field_cc_big_package__ship_package_qty #: model:ir.model.fields,field_description:ccs_base.field_cc_big_package__ship_package_qty
#: model:ir.model.fields,field_description:ccs_base.field_cc_history_big_package__goods_qty #: model:ir.model.fields,field_description:ccs_base.field_cc_history_big_package__goods_qty
#: model:ir.model.fields,field_description:ccs_base.field_cc_history_big_package__ship_package_qty #: model:ir.model.fields,field_description:ccs_base.field_cc_history_big_package__ship_package_qty
#: 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_history_big_package_view #: model_terms:ir.ui.view,arch_db:ccs_base.form_cc_history_big_package_view
msgid "Package Qty" msgid "Package Qty"
msgstr "小包数" msgstr "小包数"
#. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_cc_big_package__goods_qty
#: model_terms:ir.ui.view,arch_db:ccs_base.form_cc_big_package_view
msgid "Goods Qty"
msgstr "商品数"
#. module: ccs_base #. module: ccs_base
#: model:ir.model.fields,field_description:ccs_base.field_cc_history_ship_package__buyer_region #: model:ir.model.fields,field_description:ccs_base.field_cc_history_ship_package__buyer_region
#: model:ir.model.fields,field_description:ccs_base.field_cc_ship_package__buyer_region #: model:ir.model.fields,field_description:ccs_base.field_cc_ship_package__buyer_region
...@@ -4463,3 +4468,13 @@ msgstr "" ...@@ -4463,3 +4468,13 @@ msgstr ""
#, python-format #, python-format
msgid "预览操作失败: %s" msgid "预览操作失败: %s"
msgstr "" msgstr ""
#. module: ccs_base
#: model_terms:ir.ui.view,arch_db:ccs_base.search_cc_bl_view
msgid "Customs Clearance Status"
msgstr "关务提单状态"
#. module: ccs_base
#: model_terms:ir.ui.view,arch_db:ccs_base.search_cc_bl_view
msgid "Last Mile Provider"
msgstr "尾程服务商"
\ No newline at end of file
...@@ -40,7 +40,7 @@ class CcBigPackage(models.Model): ...@@ -40,7 +40,7 @@ class CcBigPackage(models.Model):
# 增加包裹数量字段, 用于显示包裹数量, 根据big_package_line_ids计算 # 增加包裹数量字段, 用于显示包裹数量, 根据big_package_line_ids计算
ship_package_qty = fields.Integer(string='Package Qty', compute='_compute_big_package_qty', store=True) ship_package_qty = fields.Integer(string='Package Qty', compute='_compute_big_package_qty', store=True)
# 商品纪录数 # 商品纪录数
goods_qty = fields.Integer(string='Package Qty', compute='_compute_big_package_qty', store=True) goods_qty = fields.Integer(string='Goods Qty', compute='_compute_big_package_qty', store=True)
# New fields: pallet_number (char type), pallet_usage_date # New fields: pallet_number (char type), pallet_usage_date
# 托盘号(char型),托盘使用日期 # 托盘号(char型),托盘使用日期
......
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
<field name="implied_ids" eval="[(4, ref('group_clearance_of_customs_user'))]"/> <field name="implied_ids" eval="[(4, ref('group_clearance_of_customs_user'))]"/>
</record> </record>
<record id="group_import_package" model="res.groups">
<field name="name">包裹数据导入</field>
<field name="category_id" ref="ccs_base.module_category_clearance_of_customs"/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
</data> </data>
......
...@@ -313,6 +313,10 @@ ...@@ -313,6 +313,10 @@
context="{'group_by': 'cc_country_id'}"/> context="{'group_by': 'cc_country_id'}"/>
<filter domain="[]" name="groupby_state" string="Status" <filter domain="[]" name="groupby_state" string="Status"
context="{'group_by': 'state'}"/> context="{'group_by': 'state'}"/>
<filter domain="[]" name="groupby_customs_clearance_status" string="Customs Clearance Status"
context="{'group_by': 'customs_clearance_status'}"/>
<filter domain="[]" name="groupby_last_mile_provider_ids" string="Last Mile Provider"
context="{'group_by': 'last_mile_provider_ids'}"/>
</group> </group>
<searchpanel> <searchpanel>
<field icon="fa-users" select="multi" name="cc_company_id"/> <field icon="fa-users" select="multi" name="cc_company_id"/>
......
...@@ -992,3 +992,14 @@ msgstr "" ...@@ -992,3 +992,14 @@ msgstr ""
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_bl_patrol__email_sent #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_bl_patrol__email_sent
msgid "邮件已发送" msgid "邮件已发送"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_cc_ship_package_view_inherit
msgid "Is Sync"
msgstr "是否同步"
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_cc_ship_package_view_inherit
msgid "Next Provider"
msgstr "下阶段服务商"
...@@ -34,6 +34,12 @@ ...@@ -34,6 +34,12 @@
<search position="inside"> <search position="inside">
<filter string="Not Sync" name="filter_is_sync" domain="[('is_sync','=',False)]"/> <filter string="Not Sync" name="filter_is_sync" domain="[('is_sync','=',False)]"/>
</search> </search>
<xpath expr="//search//group" position="inside">
<filter domain="[]" name="groupby_is_sync" string="Is Sync"
context="{'group_by': 'is_sync'}"/>
<filter domain="[]" name="groupby_next_provider_name" string="Next Provider"
context="{'group_by': 'next_provider_name'}"/>
</xpath>
</field> </field>
</record> </record>
......
# 文件:wizards/collection_receive_wizard.py
import xlrd
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from datetime import date, datetime
import logging
import pytz
_logger = logging.getLogger(__name__)
class PackageDataWizard(models.TransientModel):
_name = 'package.data.wizard'
_description = '包裹数据处理'
attachment_ids = fields.Many2many('ir.attachment', 'ref_package_data_attachment', string='附件')
node_id = fields.Many2one('cc.node', string='变更状态')
# 新增时区字段
timezone = fields.Selection(
selection=lambda self: [(tz, tz) for tz in pytz.all_timezones],
string='时区',
default=lambda self: self.env.user.tz or self.env.context.get('tz') or 'UTC'
)
def get_file_path(self, report_file_ids):
"""
得到excel表格的内容
:return:
"""
report_path = report_file_ids._full_path(report_file_ids.store_fname)
if report_file_ids.name[-3:] == 'xls':
data = xlrd.open_workbook(report_path, formatting_info=True)
else:
data = xlrd.open_workbook(report_path)
return data
def submit(self):
for attachment_obj in self.attachment_ids:
data = self.get_file_path(attachment_obj)
first_table = data.sheets()[0]
try:
if self.node_id.name == '待尾程提货':
select_node_obj = self.env['cc.node'].sudo().search([('node_type', '=', 'package'),
('name', '=', '已提货')],
limit=1)
else:
select_node_obj = self.env['cc.node'].sudo().search([('node_type', '=', 'package'),
('name', '=', '待尾程提货')],
limit=1)
# 新增:定义一个累加器,记录整个 Excel 总共更新了多少个小包
total_updated_count = 0
for i in range(1, first_table.nrows):
line = first_table.row_values(i)
big_no = str(line[1]).strip()
if not big_no:
continue
lh_time = line[10]
wj_time = line[5] # 尾程交货时间
# 大包数据
wj_user_name = line[4] # 尾程交货人
lh_user_name = line[8] # 理货人
pallet_date = line[6] # 托盘日期
pallet_no = str(line[7]).replace('.0', '').replace(' ', '') # 托盘号
wj_user_obj = self.env['res.users'].sudo().search([('login', '=', wj_user_name)], limit=1)
lh_user_obj = self.env['res.users'].sudo().search([('login', '=', lh_user_name)], limit=1)
update_time = lh_time if self.node_id.name == '待尾程提货' else wj_time
ship_package_objs = self.env['cc.ship.package'].sudo().search([
('big_package_id.big_package_no', '=', big_no),
('state', '=', select_node_obj.id)
]) # 已提货
if ship_package_objs:
# 核心修改:计算当前大包查到的小包数量
current_count = len(ship_package_objs)
total_updated_count += current_count # 累加到总数
# 日志记录:每个大包具体查到了多少个小包
_logger.info(f"处理第 {i} 行: 大包号 [{big_no}] 查到 {current_count} 个小包准备更新。")
sql = """
UPDATE cc_ship_package
SET state = %s, process_time = %s , is_sync=False
WHERE id IN %s
"""
self.env.cr.execute(sql, (self.node_id.id, update_time, tuple(ship_package_objs.ids)))
# 更新大包
big_package_obj = self.env['cc.big.package'].sudo().search([('big_package_no', '=', big_no)], limit=1)
sql = """
UPDATE cc_big_package
SET pallet_number = %s, pallet_usage_date = %s , tally_user_id= %s,
tally_time = %s, delivery_user_id = %s , delivery_time= %s
WHERE id = %s
"""
self.env.cr.execute(sql, (pallet_no, pallet_date, lh_user_obj.id if lh_user_obj else None,
lh_time, wj_user_obj.id if wj_user_obj else None, wj_time, big_package_obj.id))
pallet_obj = self.env['cc.pallet'].sudo().search([('name', '=', pallet_no)], limit=1)
pallet_obj.usage_state = 'used'
else:
# 选做:把没查到数据的大包也用 warning 级别记录下来,方便后期排查漏刷的数据
_logger.warning(f"处理第 {i} 行: 大包号 [{big_no}] 未查到状态为'已提货'的小包,跳过更新。")
# 循环结束后,记录该文件的最终战果
_logger.info(f"==== 附件处理完毕 ==== 整个表格共查到并更新了 {total_updated_count} 个小包!")
except Exception as err:
_logger.error(f'package_data_xls error : {str(err)}')
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data> <data>
<record id="view_package_data_wizard_form" model="ir.ui.view"> <record id="view_package_data_wizard_form" model="ir.ui.view">
<field name="name">package.data.wizard.form</field> <field name="name">package.data.wizard.form</field>
<field name="model">package.data.wizard</field> <field name="model">package.data.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="包裹数据处理向导"> <form string="包裹数据处理向导">
<div class="alert alert-info" role="alert" style="margin-bottom: 16px;">
<strong><i class="fa fa-info-circle"/> 操作指引:</strong>
<ul class="mb-0 mt-1">
<li>请先 <a href="/ccs_connect_tiktok/static/xlsx/template.xlsx?v=20250715001" class="alert-link fw-bold" target="_blank"><i class="fa fa-download"/> 下载数据模板</a></li>
<li class="text-danger fw-bold">请务必严格按照模板填写信息,切勿修改表头,否则系统无法识别!</li>
</ul>
</div>
<group> <group>
<group> <group>
<field name="attachment_ids" widget="many2many_binary" string="上传Excel附件" required="1"/> <field name="attachment_ids" widget="many2many_binary" string="上传Excel附件" required="True"/>
<field name="node_id" required="1" domain="[('node_type', '=', 'package'), ('name', 'in', ['待尾程提货', '尾程交接'])]" options="{'no_edit': True, 'no_create': True}"/> <field name="node_id" required="True"
domain="[('node_type', '=', 'package'), ('name', 'in', ['待尾程提货', '尾程交接'])]"
options="{'no_edit': True, 'no_create': True}"/>
<field name="timezone"/>
</group>
<group>
<field name="file_name" invisible="1"/>
<field name="report_file" filename="file_name" widget="binary"
attrs="{'invisible': [('report_file', '=', False)]}"/>
</group> </group>
</group> </group>
<div attrs="{'invisible': [('report_file', '=', False)]}" class="alert alert-warning mt-2" role="alert">
<strong><i class="fa fa-exclamation-triangle"/> 检测到异常数据!</strong>
<br/>
请点击上方下载 <b>异常数据文件</b>,根据文件最后一列的错误提示修改原表,然后再重新上传导入。
</div>
<footer> <footer>
<button name="submit" string="确认处理" type="object" class="btn-primary"/> <button name="submit" string="确认处理" type="object" class="btn-primary" data-hotkey="q"/>
<button string="取消" class="btn-secondary" special="cancel"/> <button string="取消" class="btn-secondary" special="cancel" data-hotkey="z"/>
</footer> </footer>
</form> </form>
</field> </field>
</record> </record>
<record id="action_package_data_wizard" model="ir.actions.act_window"> <record id="action_package_data_wizard" model="ir.actions.act_window">
<field name="name">包裹数据导入处理</field> <field name="name">包裹数据导入</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">package.data.wizard</field> <field name="res_model">package.data.wizard</field>
<field name="view_mode">form</field> <field name="view_mode">form</field>
...@@ -32,8 +56,8 @@ ...@@ -32,8 +56,8 @@
<menuitem id="menu_package_data_wizard" <menuitem id="menu_package_data_wizard"
name="导入包裹数据" name="导入包裹数据"
action="action_package_data_wizard" groups="base.group_system" action="action_package_data_wizard"
groups="base.group_system"
sequence="50"/> sequence="50"/>
</data> </data>
</odoo> </odoo>
\ No newline at end of file
...@@ -157,3 +157,23 @@ class BaseModel(models.AbstractModel): ...@@ -157,3 +157,23 @@ class BaseModel(models.AbstractModel):
return super(BaseModel, self).name_search( return super(BaseModel, self).name_search(
name=name, args=args, operator=operator, limit=limit name=name, args=args, operator=operator, limit=limit
) )
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
"""Override read_group for all models to support multi-search domains"""
try:
# 1. 拦截前端传来的 domain,使用你已经写好的转换器进行解析
new_domain = self._process_multi_search_args(domain)
# 2. 将解析后正确的 domain 传给原生的 read_group 去做聚合查询
return super(BaseModel, self).read_group(
new_domain, fields, groupby, offset=offset, limit=limit,
orderby=orderby, lazy=lazy
)
except Exception as e:
_logger.warning("Multi-search processing failed in read_group, falling back to normal: %s", str(e))
# 降级处理:如果转换出错,用原始 domain 继续执行,防止系统崩溃
return super(BaseModel, self).read_group(
domain, fields, groupby, offset=offset, limit=limit,
orderby=orderby, lazy=lazy
)
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论