提交 2d04ffe8 authored 作者: 贺阳's avatar 贺阳

1、PDA扫码记录的操作增加 按托盘理货或按托盘交货

2、按托盘理货接口
上级 9344661e
......@@ -10,7 +10,7 @@
""",
'category': 'Clearance of customs',
'website': 'https://www.yizuo.ltd',
'depends': ['base_setup', 'ccs_base'],
'depends': ['base_setup', 'ccs_base', 'ccs_pallet'],
'data': [
'security/security.xml',
'security/ir.model.access.csv',
......
......@@ -642,17 +642,17 @@ class OrderController(http.Controller):
logging.info('last_mile_delivery_time_check res:%s' % res)
return res
def _get_last_mile_grouped(self, tally_state, pda_lang):
def _get_last_mile_grouped(self, tally_state, pda_lang, is_pallet=False):
lang = 'zh_CN' if pda_lang == 'zh' else 'en_US' # 语言
# 1. 查所有清关中提单
bls = request.env['cc.bl'].sudo().search([('state', '=', 'ccing')])
# if is_pallet:
# domain=[('state', '!=', 'done')]# 1. 按托盘理货时,查非已完成状态的提单
# else:
#先都查清关中的,如果以后要查非已完成状态的提单,再修改domain。而且查尾程快递和对应的大包或托盘信息得分两个接口
domain=[('state', '=', 'ccing')]# 1. 按尾程理货时,查所有清关中提单
bls = request.env['cc.bl'].sudo().search(domain)
# 2. 查所有大包
big_packages = request.env['cc.big.package'].sudo().search([
('bl_id', 'in', bls.ids),
('tally_state', '=', tally_state)
])
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(
......@@ -663,13 +663,21 @@ class OrderController(http.Controller):
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]['big_package_arr'] = []#大包信息
group_dict[key]['ship_package_arr'] = []#小包信息
group_dict[key]['pallet_info_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])
#按托盘理货时返回未使用的托盘信息,按尾程时返回小包信息
if is_pallet:
unused_pallets = request.env['cc.pallet'].sudo().search([('usage_state', '=', 'unused'),('express_company_id', '=', key)])
pallet_info_arr=[pallet.search_pallet_info() for pallet in unused_pallets]
group_dict[key]['pallet_info_arr'] = pallet_info_arr
group_dict[key]['pallet_info_arr'].sort(key=lambda x: x.get('name', ''))#根据托盘号升序排序
else:
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())
# 按服务商名称升序排序
......@@ -758,3 +766,229 @@ class OrderController(http.Controller):
return latest_time.strftime('%Y-%m-%d %H:%M:%S')
else:
return request.env['common.common'].sudo().get_utc_time(datetime.now())
@http.route('/api/pallet/tally', type='json', auth='public', csrf=False)
def pallet_tally(self):
"""
按托盘理货接口
返回尾程服务商信息供前端选择
"""
kwargs = json.loads(request.httprequest.data)
pda_lang = kwargs.get('pda_lang') or 'zh'
res = {'state': 201, 'message': ''}
try:
logging.info('pallet_tally kwargs:%s' % kwargs)
return self._get_last_mile_grouped('unprocessed_goods', pda_lang, is_pallet=True)
except Exception as e:
exceptions_msg_dic = {
'en': 'System parsing error, the reason for the error is %s' % e,
'zh': '系统解析错误,错误原因是%s' % e
}
logging.info('pallet_tally error:%s' % e)
res['message'] = exceptions_msg_dic[pda_lang] # _('System parsing error, the reason for the error is %s', e) # 系统解析错误,错误原因是
logging.info('pallet_tally res:%s' % res)
return res
@http.route('/api/pallet/tally/complete', type='json', auth='public', csrf=False)
def pallet_tally_complete(self):
"""
按托盘理货完成接口
处理理货完成后的数据
"""
kwargs = json.loads(request.httprequest.data)
pda_lang = kwargs.get('pda_lang') or 'zh'
res = {'state': 201, 'message': ''}
operation = 'pallet_tally'
tally_user_id = kwargs.get('tally_user_id')
try:
logging.info('pallet_tally_complete kwargs:%s' % kwargs)
pallet_data = kwargs.get('pallet_data', [])
if not pallet_data:
res['message'] = {
'en': 'Pallet data is required',
'zh': '托盘数据必须提供'
}[pda_lang]
return res
for pallet_item in pallet_data:
pallet_id = pallet_item.get('pallet_id')
usage_time = pallet_item.get('usage_time')
big_package_nos = pallet_item.get('big_package_nos', [])
if not pallet_id or not usage_time or not big_package_nos:
continue
# 获取托盘对象
pallet = request.env['cc.pallet'].sudo().browse(pallet_id)
if not pallet.exists():
continue
# 获取大包对象
big_packages = request.env['cc.big.package'].sudo().search([
('big_package_no', 'in', big_package_nos)
])
if big_packages:
# 更新托盘状态为已使用
pallet.usage_state = 'used'
# 关联大包到托盘
pallet.package_ids = [(4, pkg.id) for pkg in big_packages]
# 更新大包的托盘信息
for pkg in big_packages:
pkg.update_pallet_info(
pallet_number=pallet.name,
pallet_usage_date=usage_time,
pallet_id=pallet.id
)
# 更新大包理货状态
pkg.update_big_package_info(
action_type='tally',
tally_state='checked_goods',
tally_user_id=tally_user_id,
tally_time=usage_time
)
# 创建成功的PDA扫码记录
bl_obj = big_packages[0].bl_id if big_packages else None
if bl_obj:
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
record_type='tally',
bill_number=bl_obj.bl_no,
transfer_number=bl_obj.transfer_bl_no,
state='success',
bl_id=bl_obj.id,
operation_time=usage_time,
operator_id=tally_user_id
)
res['state'] = 200
except Exception as e:
error = str(e)
logging.info('pallet_tally_complete error:%s' % error)
exceptions_msg_dic = {
'en': 'System parsing error, the reason for the error is %s' % error,
'zh': '系统解析错误,错误原因是%s' % error
}
res['message'] = exceptions_msg_dic[pda_lang]
# 创建失败的PDA扫码记录
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
record_type='tally',
bill_number='',
transfer_number='',
state='failed',
failure_reason=error,
operator_id=tally_user_id
)
logging.info('pallet_tally_complete res:%s' % res)
return res
@http.route('/api/pallet/handover', type='json', auth='public', csrf=False)
def pallet_handover(self):
"""
按托盘交货接口
返回尾程服务商信息供前端选择
"""
kwargs = json.loads(request.httprequest.data)
pda_lang = kwargs.get('pda_lang') or 'zh'
res = {'state': 201, 'message': ''}
try:
logging.info('pallet_handover kwargs:%s' % kwargs)
res = self._get_last_mile_grouped('checked_goods', pda_lang, is_pallet=True)
except Exception as e:
exceptions_msg_dic = {
'en': 'System parsing error, the reason for the error is %s' % e,
'zh': '系统解析错误,错误原因是%s' % e
}
logging.info('pallet_handover error:%s' % e)
res['message'] = exceptions_msg_dic[pda_lang] # _('System parsing error, the reason for the error is %s', e) # 系统解析错误,错误原因是
logging.info('pallet_handover res:%s' % res)
return res
@http.route('/api/pallet/handover/complete', type='json', auth='public', csrf=False)
def pallet_handover_complete(self):
"""
按托盘交货完成接口
处理交货完成后的数据
"""
kwargs = json.loads(request.httprequest.data)
pda_lang = kwargs.get('pda_lang') or 'zh'
res = {'state': 201, 'message': ''}
operation = 'pallet_handover'
tally_user_id = kwargs.get('tally_user_id')
try:
logging.info('pallet_handover_complete kwargs:%s' % kwargs)
pallet_data = kwargs.get('pallet_data', [])
if not pallet_data:
res['message'] = {
'en': 'Pallet data is required',
'zh': '托盘数据必须提供'
}[pda_lang]
return res
for pallet_item in pallet_data:
pallet_id = pallet_item.get('pallet_id')
handover_time = pallet_item.get('handover_time')
plate_number = pallet_item.get('plate_number', '')
if not pallet_id or not handover_time:
continue
# 获取托盘对象
pallet = request.env['cc.pallet'].sudo().browse(pallet_id)
if not pallet.exists():
continue
# 更新托盘交货时间和车牌号
pallet.delivery_plate_number = plate_number
# 更新托盘关联的大包交货信息
for pkg in pallet.package_ids:
pkg.update_big_package_info(
action_type='handover',
tally_state='handover_completed',
tally_user_id=tally_user_id,
tally_time=handover_time
)
# 创建成功的PDA扫码记录
if pallet.package_ids:
bl_obj = pallet.package_ids[0].bl_id
if bl_obj:
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
record_type='handover',
bill_number=bl_obj.bl_no,
transfer_number=bl_obj.transfer_bl_no,
state='success',
bl_id=bl_obj.id,
operation_time=handover_time,
operator_id=tally_user_id
)
res['state'] = 200
except Exception as e:
error = str(e)
logging.info('pallet_handover_complete error:%s' % error)
exceptions_msg_dic = {
'en': 'System parsing error, the reason for the error is %s' % error,
'zh': '系统解析错误,错误原因是%s' % error
}
res['message'] = exceptions_msg_dic[pda_lang]
# 创建失败的PDA扫码记录
request.env['pda.scan.record'].sudo().create_scan_record(
operation=operation,
record_type='handover',
bill_number='',
transfer_number='',
state='failed',
failure_reason=error,
operator_id=tally_user_id
)
logging.info('pallet_handover_complete res:%s' % res)
return res
\ No newline at end of file
......@@ -10,6 +10,7 @@ from . import ir_attachment
from . import http
from . import pda_scan_record
from . import bl_patrol
from . import cc_pallet
# -*- coding: utf-8 -*-
# 导入日志
import logging
from odoo import models, fields, api, _
# 获取日志
_logger = logging.getLogger(__name__)
class CcPallet(models.Model):
# 模型名称
_inherit = 'cc.pallet'
# 模型描述
_description = 'Pallet'
def search_pallet_info(self):
"""搜索托盘信息"""
return {
'id': self.id,#托盘id
'name': self.name,#托盘号
'express_company_id': self.express_company_id.id,#快递公司id
'express_company_name': self.express_company_id.name,#快递公司名称
'usage_state': self.usage_state,#使用状态 unused未使用 used已使用
'print_state': self.print_state,#打印状态 unprinted未打印 printed已打印
'sorting_time': self.sorting_time,#托盘理货时间
'delivery_time': self.delivery_time,#托盘交货时间
'package_count': self.package_count,#大包数量
'partner_id': self.partner_id.id,#使用客户id
'partner_name': self.partner_id.name,#使用客户名称
'delivery_plate_number': self.delivery_plate_number,#托盘交付车牌号
}
\ No newline at end of file
......@@ -24,8 +24,10 @@ class PDAScanRecord(models.Model):
operation = fields.Selection([
('bill_tally', _('Bill Tally')), # 按提单理货
('tail_tally', _('Tail Tally')), # 按尾程理货
('pallet_tally', _('Pallet Tally')), # 按托盘理货
('bill_handover', _('Bill Handover')), # 按提单交货
('tail_handover', _('Tail Handover')) # 按尾程交货
('tail_handover', _('Tail Handover')), # 按尾程交货
('pallet_handover', _('Pallet Handover')) # 按托盘交货
], string=_('Operation'), required=True) # 操作
record_type = fields.Selection([
('tally', _('Tally')), # 理货
......
......@@ -124,6 +124,7 @@ class CcPallet(models.Model):
'target': 'new',
'context': {
'default_pallet_ids': [(6, 0, self.ids)],
'active_ids': self.ids,
},
}
......
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- 托盘标签纸张格式 -->
<record id="paperformat_pallet_label" model="report.paperformat">
<field name="name">托盘标签 (10x15cm)</field>
<field name="default" eval="True"/>
<field name="format">custom</field>
<field name="orientation">Portrait</field>
<field name="margin_top">0</field>
<field name="margin_bottom">0</field>
<field name="margin_left">0</field>
<field name="margin_right">0</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">0</field>
<field name="dpi">90</field>
<field name="page_width">10</field>
<field name="page_height">15</field>
</record>
<!-- 托盘标签打印报告 -->
<record id="action_pallet_label_report" model="ir.actions.report">
<field name="name">托盘标签</field>
......@@ -7,6 +24,7 @@
<field name="report_type">qweb-pdf</field>
<field name="report_name">ccs_pallet.pallet_label_report</field>
<field name="report_file">ccs_pallet.pallet_label_report</field>
<field name="paperformat_id" ref="paperformat_pallet_label"/>
<field name="binding_model_id" ref="model_cc_pallet"/>
<field name="binding_type">report</field>
</record>
......@@ -15,22 +33,21 @@
<template id="pallet_label_report">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="pallet">
<div class="page" style="width: 10cm; height: 15cm; margin: 0; padding: 0.5cm; border: 1px solid #ccc; page-break-after: always;">
<div class="page" style="width: 100%; height: 100%; margin: 0; padding: 0.3cm; page-break-after: always; font-family: 'DejaVu Sans', Arial, sans-serif; box-sizing: border-box; position: relative;">
<!-- 客户名称和快递简称 -->
<div style="text-align: center; margin-bottom: 1cm;">
<h2 style="margin: 0; font-size: 24px; font-weight: bold;">
<t t-esc="pallet.customer_id.name or 'TIKTOK'"/> / <t t-esc="pallet.express_company_id.name or 'RM'"/>
<div style="text-align: center; height: 2cm; display: flex; align-items: center; justify-content: center; margin-bottom: 0.2cm;">
<h2 style="margin: 0; font-size: 18px; font-weight: bold; line-height: 1.2;">
<t t-esc="pallet.partner_id.name or 'TIKTOK'"/> / <t t-esc="pallet.express_company_id.name or 'RM'"/>
</h2>
</div>
<!-- 条形码区域 -->
<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 style="text-align: center; height: 8cm; border: 2px dashed #999; background-color: #f9f9f9; display: flex; flex-direction: column; justify-content: center; margin-bottom: 0.2cm;">
<div style="font-size: 14px; color: #666; margin-bottom: 0.5cm;">
<!-- 托盘号作为条形码 -->
<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;">
<div t-out="pallet.name" style="padding:0; margin-bottom: 0.3cm;" t-options="{'widget': 'barcode', 'quiet': 0, 'symbology': 'auto', 'width': 2, 'height': 60}"/>
<div class="o_label_name" style="height:1.2em;background-color: transparent; font-size: 12px;">
<span t-out="pallet.name"/>
</div>
</t>
......@@ -38,8 +55,8 @@
</div>
<!-- 托盘号 -->
<div style="text-align: center; margin-top: 1cm;">
<h1 style="margin: 0; font-size: 28px; font-weight: bold;">
<div style="text-align: center; height: 3cm; display: flex; align-items: center; justify-content: center;">
<h1 style="margin: 0; font-size: 22px; font-weight: bold; line-height: 1.2;">
<t t-esc="pallet.name"/>
</h1>
</div>
......
......@@ -31,13 +31,4 @@ class PalletPrintWizard(models.TransientModel):
def _generate_print_report(self):
"""生成打印报告"""
return {
'type': 'ir.actions.report',
'report_name': 'ccs_pallet.pallet_label_report',
'report_type': 'qweb-pdf',
'data': {
'ids': self.pallet_ids.ids,
'model': 'cc.pallet',
},
'context': self.env.context,
}
return self.env.ref('ccs_pallet.action_pallet_label_report').report_action(self.pallet_ids)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论