提交 276c59df authored 作者: 贺阳's avatar 贺阳

导出报关数据

上级 847e9d52
from . import wizard
from . import models
from . import controllers
......@@ -18,6 +18,7 @@
'security/account_security.xml',
'security/ir.model.access.csv',
'wizard/batch_input_ship_package_statu_wizard.xml',
'wizard/export_bl_big_package_xlsx_wizard.xml',
'data/data.xml',
'views/menu_view.xml',
'views/cc_clearance_file_view.xml',
......
......@@ -7,25 +7,79 @@ import zipfile
import xlwt
import xlsxwriter
from .util import check_pdd_code
from odoo import http
from odoo.http import request
import logging
from datetime import timedelta
_logger = logging.getLogger(__name__)
class ExportBlAndPackageXlsx(http.Controller):
# 公共导出包裹信息方法
def common_package_data(self, big_bag_objs):
def common_package_data(self, big_bag_obj):
worksheet = xlwt.Workbook(encoding='utf-8')
sheet1 = worksheet.add_sheet('包裹数据', cell_overwrite_ok=True)
font_style = xlwt.easyxf('font: height 220,name Arial,bold on; align: wrap on, vert centre, horiz center;')
font_style = xlwt.easyxf('font: height 220,name 宋体,bold on; align: wrap on, vert centre, horiz center;')
num = 1
sheet1 = self.get_package_title(worksheet, font_style, num)
ship_package_obj = big_bag_obj.mapped('ship_package_ids') # 小包
good_index = 0
parcel_export_num = request.env["ir.config_parameter"].sudo().get_param('parcel_export_num') or 50000
for parcel_idx, package_item in enumerate(ship_package_obj):
if package_item.good_ids:
for good_item in package_item.good_ids:
good_index += 1
sheet1.write(good_index, 0, package_item.logistic_order_no or '') # 物流订单号 TRACKING NO.
sheet1.write(good_index, 1, package_item.customer_ref or '') # CUSTOMER REF
sheet1.write(good_index, 2, package_item.internal_account_number or '') # Internal Account Number
sheet1.write(good_index, 3, package_item.sender_name or '') # SENDER NAME
sheet1.write(good_index, 4, package_item.sender_add_1 or '') # SHIPPER ADD 1
sheet1.write(good_index, 5, package_item.sender_add_2 or '') # SHIPPER ADD 2
sheet1.write(good_index, 6, package_item.sender_add_3 or '') # SHIPPER ADD 3
sheet1.write(good_index, 7, package_item.sender_city or '') # SENDER CITY
sheet1.write(good_index, 8, package_item.sender_state or '') # Ship State
sheet1.write(good_index, 9, package_item.sender_postcode or '') # SENDER POSTCODE
sheet1.write(good_index, 10, package_item.sender_country or '') # SENDER COUNTRY
sheet1.write(good_index, 11, package_item.receiver_name or '') # RECEIPIENT NAME
sheet1.write(good_index, 12, package_item.receiver_add_1 or '') # RECEIPIENT ADD 1
sheet1.write(good_index, 13, package_item.receiver_add_2 or '') # RECEIPIENT ADD 2
sheet1.write(good_index, 14, package_item.receiver_add_3 or '') # RECEIPIENT ADD 3
sheet1.write(good_index, 15, package_item.receiver_city or '') # RECEIPIENT CITY
sheet1.write(good_index, 16, package_item.receiver_county or '') # RECEIPIENT COUNTY
sheet1.write(good_index, 17, package_item.receiver_postcode or '') # RECEIPIENT POSTCODE
sheet1.write(good_index, 18, package_item.receiver_email or '') # RECEPIENT EMAIL
sheet1.write(good_index, 19, package_item.receiver_phone or '') # PHONE NUMBER
sheet1.write(good_index, 20, package_item.gross_weight or 0) # GROSS WEIGHT (KG)
sheet1.write(good_index, 21, package_item.weight_unit or 0) # NET WEIGHT (KG)
sheet1.write(good_index, 22, package_item.currency or '') # Currency
sheet1.write(good_index, 23, good_item.sku_id or '') # SKU NUMBER
sheet1.write(good_index, 24, good_item.item_name_en or '') # ITEM DESCRIPTION
sheet1.write(good_index, 25, good_item.export_hs_code or '') # ITEM HS CODE
sheet1.write(good_index, 26, good_item.quantity) # ITEM QUANTITY
sheet1.write(good_index, 27, good_item.quantity_unit or '') # UNIT VALUE
sheet1.write(good_index, 28, good_item.item_total_price) # TOTAL VALUE
sheet1.write(good_index, 29, good_item.item_vat or '') # VAT
sheet1.write(good_index, 30, '') # SKU NUMBER
sheet1.write(good_index, 31, good_item.item_link or '') # PRODUCT LINK
sheet1.write(good_index, 32, '') # LENGTH
sheet1.write(good_index, 33, '') # WIDTH
sheet1.write(good_index, 34, '') # HEIGHT
if good_index == int(parcel_export_num):
num += 1
sheet1 = self.get_package_title(worksheet, font_style, num)
good_index = 0
return worksheet
def get_package_title(self, worksheet, font_style, num=0):
"""
导出报关文件的标题
"""
sheet1 = worksheet.add_sheet('Sheet(%s)' % num, cell_overwrite_ok=True)
index = 0
for i in range(13):
sheet1.col(i).width = 400 * 11
sheet1.col(12).width = 600 * 11
for i in range(35):
sheet1.col(i).width = 500 * 11
sheet1.col(6).width = 600 * 11
sheet1.write(index, 0, u'TRACKING NO.', font_style)
sheet1.write(index, 1, u'CUSTOMER REF', font_style)
sheet1.write(index, 2, u'Internal Account Number', font_style)
......@@ -61,113 +115,38 @@ class ExportBlAndPackageXlsx(http.Controller):
sheet1.write(index, 32, u'LENGTH', font_style)
sheet1.write(index, 33, u'WIDTH', font_style)
sheet1.write(index, 34, u'HEIGHT', font_style)
ship_package_obj = big_bag_objs.mapped('ship_package_ids')
good_index = 0
num = 0
parcel_export_num = request.env["ir.config_parameter"].sudo().get_param('parcel_export_num') or 50000
for parcel_idx, parcel_item in enumerate(ship_package_obj):
# 收件人名称
receive_name = ''
# 收货人地址街道
receive_address_street = ''
# 收货人地址市
receive_address_market = ''
# 收货人地址州
receive_address_state = ''
# 收货人国家
receive_address_country = ''
# 收货人电话
receive_address_phone = ''
# 主单号
order_no = parcel_item.big_bag_id.order_id.master_business_no or ''
# 大包裹号
big_bag_no = parcel_item.big_bag_id.big_bag_no or ''
# 大包重量
big_bag_weight = parcel_item.big_bag_id.big_bag_weight or ''
# 订单号
provider_order_no = parcel_item.provider_order_no or ''
# 运单号
tracking_no = parcel_item.tracking_no or ''
if parcel_item.shipping_info:
shipping_info_data = json.loads(parcel_item.shipping_info)
receive_name = shipping_info_data['first_name'] if shipping_info_data.get('first_name') else ''
receive_address_street = shipping_info_data['address']['address_l3'] if shipping_info_data.get(
'address', {}).get('address_l3') else ''
receive_address_market = shipping_info_data['address']['address_l2'] if shipping_info_data.get(
'address', {}).get('address_l2') else ''
receive_address_state = shipping_info_data['address']['address_l1'] if shipping_info_data.get('address',
{}).get(
'address_l1') else ''
receive_address_country = shipping_info_data['address']['address_l0'] if shipping_info_data.get(
'address', {}).get('address_l0') else ''
receive_address_phone = shipping_info_data['phone'] if shipping_info_data.get('phone') else ''
if parcel_item.goods_ids:
for good_item in parcel_item.goods_ids:
good_index += 1
# 商品中文名称
product_name_cn = good_item['product_name_cn'] if good_item.get('product_name_cn') else ''
# hs编码
hscode = good_item['hscode'] if good_item.get('hscode') else ''
# 商品数量
qty = good_item['qty'] if good_item.get('qty') else ''
# 总价
unit_price = good_item['unit_price'] if good_item.get('unit_price') else ''
# 币制
unit_code = good_item['unit_code'] if good_item.get('unit_code') else ''
# 总毛重
unit_weight = good_item['unit_weight'] if good_item.get('unit_weight') else ''
sheet1.write(good_index, 0, order_no)
sheet1.write(good_index, 1, big_bag_no)
sheet1.write(good_index, 2, big_bag_weight)
sheet1.write(good_index, 3, provider_order_no)
sheet1.write(good_index, 4, tracking_no)
sheet1.write(good_index, 5, receive_address_country)
sheet1.write(good_index, 6, product_name_cn)
sheet1.write(good_index, 7, hscode)
sheet1.write(good_index, 8, qty)
sheet1.write(good_index, 9, unit_price)
sheet1.write(good_index, 10, unit_code)
sheet1.write(good_index, 11, unit_weight)
sheet1.write(good_index, 12, 'TikTok')
if good_index == int(parcel_export_num):
num += 1
sheet1 = worksheet.add_sheet('包裹数据(%s)' % num, cell_overwrite_ok=True)
for i in range(13):
sheet1.col(i).width = 400 * 11
sheet1.col(12).width = 600 * 11
sheet1.write(index, 0, u'主单号', font_style)
sheet1.write(index, 1, u'大包裹号', font_style)
sheet1.write(index, 2, u'大包重量', font_style)
sheet1.write(index, 3, u'订单号', font_style)
sheet1.write(index, 4, u'运单号', font_style)
sheet1.write(index, 5, u'收货人国家', font_style)
sheet1.write(index, 6, u'商品中文名称', font_style)
sheet1.write(index, 7, u'hs编码', font_style)
sheet1.write(index, 8, u'商品数量', font_style)
sheet1.write(index, 9, u'总价', font_style)
sheet1.write(index, 10, u'币制', font_style)
sheet1.write(index, 11, u'总毛重', font_style)
sheet1.write(index, 12, u'电商平台/海外仓地址', font_style)
good_index = 0
return worksheet
return sheet1
# 运单导出包裹清关数据 每个运单导出一个文件 生成压缩包
@http.route(['/export/flight_package/xls/<string:arr>/<string:select_type>'], type='http', auth="public")
def export_flight_package_xls(self, arr,select_type):
@http.route(['/export/bl/package/xls/<string:arr>/<string:select_type>'], type='http', auth="public")
def export_bl_package_xls(self, arr, select_type):
"""
是否分大包,如果不分,就是提单一个文件,命名 提单号;如果分,一个提单一个大包一个文件,命名 提单号➕大包号
"""
arr = json.loads(arr)
flight_objs = http.request.env['ao.flight.order'].sudo().search([('id', 'in', arr)], order='id')
bl_obj = http.request.env['cc.bl'].sudo().search([('id', 'in', arr)], order='id')
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
for flight in flight_objs:
big_bag_objs = flight.big_package_ids
worksheet = self.common_package_data(big_bag_objs)
if select_type == 'yes':
for bl_item in bl_obj:
for bag_item in bl_item.big_package_ids:
if len(bag_item.mapped('ship_package_ids').mapped('good_ids')) > 0:
worksheet = self.common_package_data(bag_item)
# 将Excel保存到内存中的文件对象
excel_file = io.BytesIO()
worksheet.save(excel_file)
excel_file.seek(0)
zip_file.writestr(f"{flight.master_business_no}.xls", excel_file.read()) # 压缩
zip_file.writestr(f"{bl_item.bl_no}-{bag_item.big_package_no}.xls", excel_file.read()) # 压缩
else:
for bl_item in bl_obj:
big_bag_obj = bl_item.big_package_ids
if len(big_bag_obj.mapped('ship_package_ids').mapped('good_ids')) > 0:
worksheet = self.common_package_data(big_bag_obj)
# 将Excel保存到内存中的文件对象
excel_file = io.BytesIO()
worksheet.save(excel_file)
excel_file.seek(0)
zip_file.writestr(f"{bl_item.bl_no}.xls", excel_file.read()) # 压缩
zip_buffer.seek(0)
headers = [
('Content-Type', 'application/x-zip-compressed'),
......@@ -176,519 +155,17 @@ class ExportBlAndPackageXlsx(http.Controller):
response = http.request.make_response(zip_buffer.getvalue(), headers=headers)
return response
# 导出包裹清关数据
@http.route(['/export/big_package/xls/<string:arr>/<string:model_name>'], type='http', auth="public")
# 导出包裹清关数据 暂时没用的
@http.route(['/export/big/package/xls/<string:arr>/<string:model_name>'], type='http', auth="public")
def export_big_package_xls(self, arr, model_name):
arr = json.loads(arr)
if model_name == 'ao.big.package':
big_bag_objs = http.request.env['ao.big.package'].sudo().search([('id', 'in', arr)], order='order_id')
big_bag_obj = http.request.env['ao.big.package'].sudo().search([('id', 'in', arr)], order='order_id')
else:
big_bag_objs = http.request.env['ao.big.package'].sudo().search([('order_id', 'in', arr)], order='order_id')
# print(model_name, len(big_bag_objs), big_bag_objs)
worksheet = self.common_package_data(big_bag_objs)
big_bag_obj = http.request.env['ao.big.package'].sudo().search([('order_id', 'in', arr)], order='order_id')
worksheet = self.common_package_data(big_bag_obj)
response = http.request.make_response(None, headers=[('Content-Type', 'application/vnd.ms-excel'),
('Content-Disposition',
u'attachment; filename=parcel_data.xls;')])
worksheet.save(response.stream)
return response
# 客户中心我的订舱导出订舱数据
@http.route(['/export/customer_order/xls/<string:arr>'], type='http', auth="public")
def export_customer_order_xls(self, arr):
arr = json.loads(arr)
order_objs = http.request.env['ao.flight.order'].sudo().search([('id', 'in', arr)])
worksheet = xlwt.Workbook(encoding='utf-8')
sheet1 = worksheet.add_sheet('订舱数据', cell_overwrite_ok=True)
font_style = xlwt.easyxf('font: height 220,name 微软雅黑,bold on; align: wrap on, vert centre, horiz center;')
index = 0
sheet1.col(0).width = 400 * 11
sheet1.col(8).width = 300 * 11
sheet1.col(10).width = 350 * 11
sheet1.col(11).width = 350 * 11
sheet1.write(index, 0, u'运单号', font_style)
sheet1.write(index, 1, u'订舱数量', font_style)
sheet1.write(index, 2, u'订舱重量', font_style)
sheet1.write(index, 3, u'订舱体积', font_style)
sheet1.write(index, 4, u'航班', font_style)
sheet1.write(index, 5, u'航次', font_style)
sheet1.write(index, 6, u'始发港', font_style)
sheet1.write(index, 7, u'目的港', font_style)
sheet1.write(index, 8, u'最终目的地', font_style)
sheet1.write(index, 9, u'是否包板', font_style)
# sheet1.write(index, 10, u'空运单价', font_style)
# sheet1.write(index, 10, u'BSA价格', font_style)
sheet1.write(index, 10, u'订舱日期', font_style)
sheet1.write(index, 11, u'当前运单状态', font_style)
for order_idx, order_item in enumerate(order_objs):
order_idx += 1
sheet1.write(order_idx, 0, order_item.master_business_no)
sheet1.write(order_idx, 1, order_item.order_number)
sheet1.write(order_idx, 2, order_item.order_weight)
sheet1.write(order_idx, 3, order_item.order_volume)
sheet1.write(order_idx, 4, order_item.voyage_id.voyage_name or '')
sheet1.write(order_idx, 5, order_item.voyage_name or '')
sheet1.write(order_idx, 6, order_item.depart_port_id.three_no)
sheet1.write(order_idx, 7, order_item.arrive_port_id.three_no)
sheet1.write(order_idx, 8, order_item.final_port)
sheet1.write(order_idx, 9, '是' if order_item.is_all else '否')
# sheet1.write(order_idx, 10, order_item.plane_price)
# sheet1.write(order_idx, 10, order_item.plane_all_amount)
order_date = ''
if order_item.track_ids:
for track in order_item.track_ids:
if track.description == '[已订舱]预报运单' and track.happend_time:
dt = http.request.env['ao.common'].sudo().get_add_time(track.happend_time.strftime("%Y-%m-%d %H:%M:%S"))
order_date = dt[0:10]
sheet1.write(order_idx, 10, order_date)
sheet1.write(order_idx, 11, order_item.state)
response = http.request.make_response(None, headers=[('Content-Type', 'application/vnd.ms-excel'),
('Content-Disposition',
u'attachment; filename=customer_order.xls;')])
worksheet.save(response.stream)
return response
# 客户中心订舱单导出
@http.route(['/export/customer_book/xls/<string:arr>'], type='http', auth="public")
def export_customer_book_order_xls(self, arr):
arr = json.loads(arr)
order_objs = http.request.env['ao.book.reservation'].sudo().search([('id', 'in', arr)])
worksheet = xlwt.Workbook(encoding='utf-8')
sheet1 = worksheet.add_sheet('订舱数据', cell_overwrite_ok=True)
font_style = xlwt.easyxf('font: height 220,name 微软雅黑,bold on; align: wrap on, vert centre, horiz center;')
index = 0
sheet1.col(0).width = 400 * 11
sheet1.col(8).width = 300 * 11
sheet1.col(10).width = 350 * 11
sheet1.col(11).width = 350 * 11
sheet1.write(index, 0, '运单号', font_style)
sheet1.write(index, 1, '订舱数量', font_style)
sheet1.write(index, 2, '订舱重量', font_style)
sheet1.write(index, 3, '订舱体积', font_style)
sheet1.write(index, 4, '航班', font_style)
sheet1.write(index, 5, '航次', font_style)
sheet1.write(index, 6, '始发港', font_style)
sheet1.write(index, 7, '目的港', font_style)
sheet1.write(index, 8, '最终目的地', font_style)
sheet1.write(index, 9, '是否包板', font_style)
sheet1.write(index, 10, '订舱日期', font_style)
sheet1.write(index, 11, '当前运单状态', font_style)
for order_idx, order_item in enumerate(order_objs):
order_idx += 1
sheet1.write(order_idx, 0, order_item.master_business_no)
sheet1.write(order_idx, 1, order_item.order_number)
sheet1.write(order_idx, 2, order_item.order_weight)
sheet1.write(order_idx, 3, order_item.order_volume)
sheet1.write(order_idx, 4, order_item.voyage_id.voyage_name or '')
sheet1.write(order_idx, 5, order_item.voyage_id.name or '')
sheet1.write(order_idx, 6, order_item.voyage_id.depart_port_id.three_no)
sheet1.write(order_idx, 7, order_item.voyage_id.arrive_port_id.three_no)
sheet1.write(order_idx, 8, order_item.final_port)
sheet1.write(order_idx, 9, '是' if order_item.is_all else '否')
order_date = ''
if order_item.waybill_id.track_ids:
for track in order_item.track_ids:
if track.description == '[已订舱]预报运单' and track.happend_time:
dt = http.request.env['ao.common'].sudo().get_add_time(
track.happend_time.strftime("%Y-%m-%d %H:%M:%S"))
order_date = dt[0:10]
sheet1.write(order_idx, 10, order_date)
sheet1.write(order_idx, 11, order_item.master_waybill_id.state or '')
response = http.request.make_response(None, headers=[('Content-Type', 'application/vnd.ms-excel'),
('Content-Disposition',
u'attachment; filename=customer_order.xls;')])
worksheet.save(response.stream)
return response
# 运单轨迹导出
@http.route(['/export/order_track/xls/<string:arr>'], type='http', auth="public")
def export_order_track_xls(self, arr):
arr = json.loads(arr)
order_objs = http.request.env['ao.book.reservation'].sudo().search([('id', 'in', arr)])
worksheet = xlwt.Workbook(encoding='utf-8')
sheet1 = worksheet.add_sheet('运单轨迹数据', cell_overwrite_ok=True)
font_style = xlwt.easyxf('font: height 220,name 微软雅黑,bold on; align: wrap on, vert centre, horiz center;')
index = 0
for i in range(4):
sheet1.col(i).width = 400 * 11
for i in range(4, 8):
sheet1.col(i).width = 500 * 11
sheet1.col(2).width = 700 * 11
sheet1.col(4).width = 650 * 11
sheet1.write(index, 0, '状态', font_style)
sheet1.write(index, 1, '主单号', font_style)
sheet1.write(index, 2, '订舱航班', font_style)
sheet1.write(index, 3, '订舱航次号', font_style)
sheet1.write(index, 4, '执飞航班/实际起飞时间', font_style)
sheet1.write(index, 5, '运单轨迹/业务描述', font_style)
sheet1.write(index, 6, '运单轨迹/地点', font_style)
sheet1.write(index, 7, '运单轨迹/时间', font_style)
index += 1
for order_idx, order_item in enumerate(order_objs):
master_waybill_obj = order_item.master_waybill_id
if master_waybill_obj:
track_objs = master_waybill_obj.track_ids
sheet1.write(index, 0, master_waybill_obj.state)
sheet1.write(index, 1, master_waybill_obj.master_business_no)
sheet1.write(index, 2, master_waybill_obj.voyage_id.name_get()[0][1])
sheet1.write(index, 3, master_waybill_obj.voyage_id.name)
sheet1.write(index, 4, (master_waybill_obj.actual_voyage_id.actual_depart_time + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S') if master_waybill_obj.actual_voyage_id.actual_depart_time else '')
for i, track_obj in enumerate(track_objs):
sheet1.write(index, 5, track_obj.description)
sheet1.write(index, 6, track_obj.address)
sheet1.write(index, 7, track_obj.local_time)
index += 1
# order_date = ''
# if order_item.waybill_id.track_ids:
# for track in order_item.track_ids:
# if track.description == '[已订舱]预报运单' and track.happend_time:
# dt = http.request.env['ao.common'].sudo().get_add_time(
# track.happend_time.strftime("%Y-%m-%d %H:%M:%S"))
# order_date = dt[0:10]
# sheet1.write(order_idx, 10, order_date)
# sheet1.write(order_idx, 11, order_item.master_waybill_id.state or '')
response = http.request.make_response(None, headers=[('Content-Type', 'application/vnd.ms-excel'),
('Content-Disposition',
u'attachment; filename=order_track.xls;')])
worksheet.save(response.stream)
return response
class PddTrack(http.Controller):
@http.route('/get/track', type='http', auth='public', method=["POST", "GET"], csrf=False, cors="*")
@check_pdd_code
def get_pdd_track(self, **kw):
res = {'status': '1', 'msg': ''}
try:
request.env.context = {'lang': 'zh_CN'}
redis_conn = request.env['ao.common'].sudo().get_redis()
if kw.get('parcel_no'):
parcel_no = kw.get('parcel_no')
parcel_no_rep = parcel_no.replace(' ', '').replace('-', '').replace('/', '').upper()
if res['status'] == '1':
sql = "select id,parcel_name from ao_parcel where UPPER(REPLACE(REPLACE(REPLACE(parcel_name, ' ', ''), '-', ''), '/', '')) = '{0}';".format(
parcel_no_rep)
request._cr.execute(sql)
result = request._cr.fetchall()
if result:
select_parcel_no = result[0][1]
if kw.get('order_no'):
order_no_rep = kw.get('order_no').replace(' ', '').replace('-', '').replace('/', '')
redis_parcel_arr = redis_conn.get('parcel' + order_no_rep) if redis_conn != 'no' else []
# for order_parcel_a in order_parcel_arr:
if redis_parcel_arr:
if select_parcel_no not in redis_parcel_arr:
res['data'] = ''
res['status'] = '0'
res['msg'] = '包裹号%s不在提单%s内' % (parcel_no, kw.get('order_no'))
else:
exist_parcel_name = request.env['ao.flight.order'].sudo().get_pdd_redis_order(
kw.get('order_no'))
if select_parcel_no not in exist_parcel_name:
res['data'] = ''
res['status'] = '0'
res['msg'] = '包裹号%s不在提单%s内' % (parcel_no, kw.get('order_no'))
flag = request.env['ao.flight.order'].sudo().order_exist(
kw.get('order_no'))
if not flag:
res['msg'] = '找不到%s提单号' % kw.get('order_no')
res['data'] = ''
res['status'] = '0'
# 获取id
if res['status'] == '1':
parcel_obj = request.env['ao.parcel'].sudo().browse(result[0][0])
redis_data = redis_conn.get(
parcel_obj.order_id.master_business_no.replace(' ', '').replace('-', '').replace('/', '')) if redis_conn != 'no' else []
if redis_data:
data = json.loads(redis_data)
else:
data = request.env['ao.flight.order'].sudo().get_pdd_track(parcel_obj.order_id.id)
if data['track_arr']:
data['parcel_arr'] = list(filter(lambda x: x in [select_parcel_no], data['parcel_arr']))
res['data'] = data
else:
res['msg'] = '该包裹号%s,暂未产生包裹轨迹' % parcel_no
res['data'] = ''
res['status'] = '0'
else:
res['msg'] = '找不到%s包裹号' % parcel_no
res['data'] = ''
res['status'] = '0'
elif kw.get('order_no'):
order_no = kw.get('order_no')
order_no_rep = order_no.replace(' ', '').replace('-', '').replace('/', '')
redis_data = redis_conn.get(order_no_rep) if redis_conn != 'no' else []
if redis_data:
data = json.loads(redis_data)
if data['track_arr']:
res['data'] = data
else:
res['msg'] = '该提单号%s,暂未产生包裹轨迹' % order_no
res['data'] = ''
res['status'] = '0'
else:
sql = "select id from ao_flight_order where REPLACE(REPLACE(REPLACE(master_business_no, ' ', ''), '-', ''), '/', '') = '{0}';".format(
order_no_rep)
request._cr.execute(sql)
result = request._cr.fetchall()
if result:
# 获取id
data = request.env['ao.flight.order'].sudo().get_pdd_track(result[0][0])
if data['track_arr']:
res['data'] = data
else:
res['msg'] = '该提单号%s,暂未产生包裹轨迹' % order_no
res['data'] = ''
res['status'] = '0'
else:
res['msg'] = '找不到%s提单号' % order_no
res['data'] = ''
res['status'] = '0'
else:
res['msg'] = '提单号和包裹号必传其一'
res['data'] = ''
res['status'] = '0'
except Exception as err:
logging.error('get_pdd_track: error %s' % str(err))
res['msg'] = '系统错误,请联系开发人员!'
res['data'] = ''
res['status'] = '0'
if kw.get('order_no') and kw.get('parcel_no'):
select_obj = '提单号/包裹号'
elif kw.get('order_no'):
select_obj = '提单号'
elif kw.get('parcel_no'):
select_obj = '包裹号'
else:
select_obj = ''
request.env['ao.pdd.log'].create_pdd_log(select_obj, kw.get('order_no') if kw.get('order_no') else '',
kw.get('parcel_no') if kw.get('parcel_no') else '',
'/'.join(res['data']['parcel_arr']) if res['data'] else '',
False if res['status'] == "0" else True, res['msg'])
return json.JSONEncoder().encode(res)
@http.route('/batch/get/track', type='http', auth='public', method=["POST", "GET"], csrf=False, cors="*")
@check_pdd_code
def batch_get_pdd_track(self, **kw):
res = {'status': '1', 'msg': ''}
error_msg = []
error_msg_parcel = []
error_msg_order = []
error_msg_no_track = []
error_msg_no_parcel = []
data = []
correct_order_no = []
correct_parcel_no = []
parcel_no_dict = {}
for_correct_parcel_no = []
try:
request.env.context = {'lang': 'zh_CN'}
redis_conn = request.env['ao.common'].sudo().get_redis()
if kw.get('order_no_arr') and kw.get('parcel_no_arr'):
select_obj = '提单号/包裹号'
elif kw.get('order_no_arr'):
select_obj = '提单号'
elif kw.get('parcel_no_arr'):
select_obj = '包裹号'
else:
select_obj = ''
if kw.get('parcel_no_arr'):
parcel_no_arr = json.loads(kw.get('parcel_no_arr'))
# 检查包裹是否存在
for parcel_no in parcel_no_arr:
flag = request.env['ao.flight.order'].sudo().parcel_exist(parcel_no)
if not flag:
if parcel_no not in error_msg:
error_msg.append(parcel_no)
else:
correct_parcel_no.append(flag)
parcel_no_dict[flag] = parcel_no
if error_msg:
res['data'] = ''
res['status'] = '0'
res['msg'] = '%s找不到以上包裹号' % ','.join(error_msg)
# request.env['ao.pdd.log'].create_pdd_log(select_obj,
# kw.get('order_no_arr') if kw.get('order_no_arr') else '',
# kw.get('parcel_no_arr') if kw.get('parcel_no_arr') else '',
# '',
# False if res['status'] == "0" else True,
# res['msg'])
# return json.JSONEncoder().encode(res)
if kw.get('order_no_arr'):
# 检查提单是否存在
order_no_arr = json.loads(kw.get('order_no_arr'))
for order_no in order_no_arr:
flag = request.env['ao.flight.order'].sudo().order_exist(order_no)
if not flag:
if order_no not in error_msg_order:
error_msg_order.append(order_no)
else:
correct_order_no.append(order_no)
if error_msg_order:
res['data'] = ''
res['status'] = '0'
if not error_msg:
res['msg'] += ',%s找不到以上提单号' % ','.join(error_msg_order)
# return json.JSONEncoder().encode(res)
redis_order_data = []
for order_no in order_no_arr:
redis_order_data += request.env['ao.flight.order'].sudo().get_pdd_redis_order(order_no)
for parcel_no in correct_parcel_no:
if parcel_no not in redis_order_data:
if parcel_no_dict.get(parcel_no) not in error_msg_parcel:
error_msg_parcel.append(parcel_no_dict.get(parcel_no))
else:
for_correct_parcel_no.append(parcel_no)
correct_parcel_no = for_correct_parcel_no
if error_msg_parcel:
res['data'] = ''
res['status'] = '0'
# if not res['msg']:
res['msg'] += ',%s以上包裹号不在提单内' % ','.join(error_msg_parcel)
# request.env['ao.pdd.log'].create_pdd_log(select_obj,
# kw.get('order_no_arr') if kw.get(
# 'order_no_arr') else '',
# kw.get('parcel_no_arr') if kw.get(
# 'parcel_no_arr') else '',
# '',
# False if res['status'] == "0" else True,
# res['msg'])
# return json.JSONEncoder().encode(res)
# for order_no in order_no_arr:
# track_data = request.env['ao.flight.order'].sudo().get_order_pdd_track(order_no)
# if track_data.get('parcel_arr'):
# # parcel_line_arr = []
# track_data['parcel_arr'] = list(filter(lambda x: x in parcel_no_arr, track_data['parcel_arr']))
# data.append(track_data)
# for order_no in for_correct_parcel_no:
# track_data = request.env['ao.flight.order'].sudo().get_order_pdd_track(order_no)
# if track_data.get('parcel_arr'):
# # parcel_line_arr = []
# track_data['parcel_arr'] = list(filter(lambda x: x in correct_parcel_no, track_data['parcel_arr']))
# data.append(track_data)
# res['data'] = data
# if res['data']:
# res['status'] = '1'
# write_parcel_arr = []
# for write_data in data:
# if write_data.get('parcel_arr'):
# write_parcel_arr += write_data['parcel_arr']
# request.env['ao.pdd.log'].create_pdd_log(select_obj,
# kw.get('order_no_arr') if kw.get('order_no_arr') else '',
# kw.get('parcel_no_arr') if kw.get('parcel_no_arr') else '',
# '/'.join(write_parcel_arr) if write_parcel_arr else '',
# False if res['status'] == "0" else True,
# res['msg'])
# return json.JSONEncoder().encode(res)
select_parcel_arr = []
for parcel_no in correct_parcel_no:
select_parcel_arr.append(parcel_no.replace(' ', '').replace('-', '').replace('/', '').upper())
select_parcel_str = '(%s)' % str(select_parcel_arr)[1:-1]
if select_parcel_arr:
sql = "select distinct(order_id),parcel_name from ao_parcel where UPPER(REPLACE(REPLACE(REPLACE(parcel_name, ' ', ''), '-', ''), '/', '')) in {0};".format(
select_parcel_str)
request._cr.execute(sql)
result = request._cr.fetchall()
else:
result = []
# print(result)
exist_rest_arr = []
if result:
for rest in result:
if rest[0] not in exist_rest_arr:
order_obj = request.env['ao.flight.order'].sudo().browse(rest[0])
exist_rest_arr.append(rest[0])
track_data = order_obj.get_order_pdd_track(order_obj.master_business_no)
if track_data.get('parcel_arr'):
# parcel_line_arr = []
track_data['parcel_arr'] = list(filter(lambda x: x in correct_parcel_no, track_data['parcel_arr']))
if track_data.get('track_arr'):
data.append(track_data)
else:
error_msg_no_track.append(order_obj.master_business_no)
res['msg'] += '提单号%s,包裹号%s,暂未产生包裹轨迹,' % (order_obj.master_business_no, parcel_no_dict[rest[1]])
# if error_msg_no_track:
# res['data'] = ''
# res['status'] = '0'
# res['msg'] += '%s以上提单暂未产生轨迹' % ','.join(error_msg_no_track)
res['data'] = data
if res['data']:
res['status'] = '1'
write_parcel_arr = []
for write_data in data:
if write_data.get('parcel_arr'):
write_parcel_arr += write_data['parcel_arr']
request.env['ao.pdd.log'].create_pdd_log(select_obj,
kw.get('order_no_arr') if kw.get('order_no_arr') else '',
kw.get('parcel_no_arr') if kw.get('parcel_no_arr') else '',
'/'.join(write_parcel_arr) if write_parcel_arr else '',
False if res['status'] == "0" else True,
res['msg'])
return json.JSONEncoder().encode(res)
else:
res['data'] = []
elif kw.get('order_no_arr'):
order_no_arr = json.loads(kw.get('order_no_arr'))
for order_no in order_no_arr:
flag = request.env['ao.flight.order'].sudo().order_exist(order_no)
if not flag:
error_msg.append(order_no)
else:
correct_order_no.append(order_no)
if error_msg:
res['data'] = ''
res['status'] = '0'
res['msg'] = '%s找不到以上提单号' % ','.join(error_msg)
# request.env['ao.pdd.log'].create_pdd_log(select_obj,
# kw.get('order_no_arr') if kw.get('order_no_arr') else '',
# kw.get('parcel_no_arr') if kw.get('parcel_no_arr') else '',
# '',
# False if res['status'] == "0" else True,
# res['msg'])
# return json.JSONEncoder().encode(res)
for order_no in correct_order_no:
track_data = request.env['ao.flight.order'].sudo().get_order_pdd_track(order_no)
if not track_data.get('parcel_arr'):
error_msg_no_parcel.append(order_no)
else:
if track_data.get('track_arr'):
data.append(track_data)
else:
error_msg_no_track.append(order_no)
if error_msg_no_parcel:
res['data'] = ''
res['status'] = '0'
res['msg'] += '%s以上提单没有包裹信息' % ','.join(error_msg_no_parcel)
if error_msg_no_track:
res['data'] = ''
res['status'] = '0'
res['msg'] += '%s以上提单暂未产生轨迹' % ','.join(error_msg_no_track)
res['data'] = data
if res['data']:
res['status'] = '1'
write_parcel_arr = []
for write_data in data:
if write_data.get('parcel_arr'):
write_parcel_arr += write_data['parcel_arr']
request.env['ao.pdd.log'].create_pdd_log(select_obj, kw.get('order_no_arr') if kw.get('order_no_arr') else '',
kw.get('parcel_no_arr') if kw.get('parcel_no_arr') else '',
'/'.join(write_parcel_arr) if write_parcel_arr else '',
False if res['status'] == "0" else True,
res['msg'])
return json.JSONEncoder().encode(res)
else:
res['msg'] = '提单号和包裹号必传其一'
res['data'] = ''
res['status'] = '0'
except Exception as err:
logging.error('batch_get_pdd_track: error %s' % str(err))
res['msg'] = '系统错误,请联系开发人员!'
res['data'] = ''
res['status'] = '0'
request.env['ao.pdd.log'].create_pdd_log(select_obj, kw.get('order_no_arr') if kw.get('order_no_arr') else '',
kw.get('parcel_no_arr') if kw.get('parcel_no_arr') else '',
res['data'], False if res['status'] == "0" else True, res['msg'])
return json.JSONEncoder().encode(res)
......@@ -10,5 +10,9 @@
<field name="value">{'https': 'socks5://192.168.0.254:1080'}</field>
</record>
<record id="parcel_export_num" model="ir.config_parameter">
<field name="key">parcel_export_num</field>
<field name="value">50000</field>
</record>
</data>
</odoo>
\ No newline at end of file
......@@ -373,7 +373,7 @@ class CcShipPackage(models.Model):
def action_show_package_good(self):
# 返回一个action,显示商品
return {
'name': 'Goods',
'name': _('Goods'),
'type': 'ir.actions.act_window',
'res_model': 'cc.package.good',
'view_mode': 'tree,form',
......@@ -523,6 +523,31 @@ class CcBL(models.Model):
else:
raise UserError(reason)
def action_batch_export_package(self):
"""
导出报关文件
"""
# error_order = []
# for item in order_obj:
# # item.ship_package_ids
# parcel_ids = item.big_package_ids.mapped('ship_package_ids')
# if not parcel_ids:
# error_order.append(item.bl_no)
# continue
# good_parcels = parcel_ids.mapped('good_ids')
# if len(good_parcels) == 0:
# error_order.append(item.bl_no)
# if error_order:
# raise ValidationError(f"{','.join(error_order)},没有任何商品信息可导出报关数据")
return {
'name': _('导出报关文件'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'export.bl.big.package.xlsx.wizard',
'target': 'new',
'context': {'active_id': self.ids, },
}
# # 添加报关单字段
# cdo_ids = fields.One2many('cc.customers.declaration.order', 'bl_id', string='Customers Declaration Order')
#
......
......@@ -173,7 +173,7 @@
<field name="model">cc.bl</field>
<field name="arch" type="xml">
<search string="Bill of Loading">
<field name="bl_no" string="模糊搜索"
<field name="bl_no" string="Search"
filter_domain="['|', ('bl_no', 'ilike', self), ('customs_bl_no', 'ilike', self)]"/>
<separator/>
......@@ -243,9 +243,6 @@
<field name="domain">[]</field>
<field name="context">{}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
[Bill of Loading] 还没有哦!点左上角的[创建]按钮,沙发归你了!
</p>
<p>
</p>
</field>
......@@ -319,15 +316,15 @@
<!-- </field>-->
<!-- </record>-->
<!-- <menuitem sequence="10" name="Bill of Loading" id="menu_cc_bl" action="action_cc_bl" web_icon="ccs_base,static/description/icon3.png"/>-->
<!-- 导出报关数据 <menuitem sequence="10" name="Bill of Loading" id="menu_cc_bl" action="action_cc_bl" web_icon="ccs_base,static/description/icon3.png"/>-->
<record id="export_order_big_package_xls_server" model="ir.actions.server">
<field name="name">导出报关数据</field>
<field name="name">Export customs declaration data</field>
<field name="model_id" ref="model_cc_bl"/>
<field name="binding_model_id" ref="model_cc_bl"/>
<field name="state">code</field>
<field name="code">
if records:
action = records.export_order_big_package_xls_action()
action = records.action_batch_export_package()
</field>
</record>
......
......@@ -21,7 +21,7 @@ PUSH_TYPE = [
# 包括以下字段,提单, 当前节点, 更新节点, 排除面单号, 排除状态
class BatchInputShipPackageStatusWizard(models.TransientModel):
_name = 'batch.input.ship.package.status.wizard'
_description = '批量更新小包状态向导'
_description = 'Batch Update the status of the small package'#批量更新小包状态向导
@api.onchange('select_type', 'current_status')
def onchange_select_type(self):
......@@ -68,25 +68,25 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
def submit(self):
# 确认数据
if not self.is_ok:
raise ValidationError('请确认以上数据正确.')
raise ValidationError('Please confirm that the above data is correct.') # 请确认以上数据正确
parcels = self.get_process_package()
if not parcels:
raise ValidationError('没有找到要更新的小包.')
raise ValidationError('No package to update found.') # 没有找到要更新的小包
# 判断异常状态是否选择了异常原因
reason_obj = self.env['cc.node.exception.reason'].search([('code_id', '=', self.update_status.id)])
if reason_obj and not self.node_exception_reason_id:
raise ValidationError('请选择异常原因!')
raise ValidationError('Please select the reason for the exception!') # 请选择异常原因
# 更新状态
parcels.write(
{'state': self.update_status.id, 'node_exception_reason_id': self.node_exception_reason_id.id,
'process_time': self.process_time, 'state_explain': self.state_explain, 'is_sync': False})
# 生成sns日志
# self.bl_id.message_post(body='%s更新为%s' % (self.current_status.name or '', self.update_status.name or ''))
# 跳转显示本次更新状态的小包
# 跳转显示本次更新状态的小包 更新小包状态
return {
'name': '更新小包状态',
'name': _('Update the status of the small package'),
'type': 'ir.actions.act_window',
'res_model': 'cc.ship.package',
'view_mode': 'tree,form',
......
......@@ -4,62 +4,32 @@
from odoo import models, api, fields
from odoo.exceptions import Warning, ValidationError
class ExportBlBigPackageXlsxWizard(models.TransientModel):
_name = 'export.bl.big.package.xlsx.wizard'
_description = '导出报关文件'
def get_order(self):
"""
得到单据
:return:
"""
order_id = self._context.get('active_id')
if type(order_id) != list:
order_id = [self._context.get('active_id')]
return self.env['cc.bl'].sudo().browse(order_id)
# 增加选择类型字段, 按节点和按面单号(多条)
select_type = fields.Selection([
('yes', 'YES'),
('no', 'NO')
], string='Whether to export in Big packages')
# 增加选择类型字段, 是否分大包导出
select_type = fields.Selection([('yes', 'YES'), ('no', 'NO')], string='Whether to export in Big packages')
# 批量更新小包状态
def submit(self):
# 确认数据
if not self.is_ok:
raise ValidationError('请确认以上数据正确.')
parcels = self.get_process_package()
if not parcels:
raise ValidationError('没有找到要更新的小包.')
# 判断异常状态是否选择了异常原因
reason_obj = self.env['cc.node.exception.reason'].search([('code_id', '=', self.update_status.id)])
if reason_obj and not self.node_exception_reason_id:
raise ValidationError('请选择异常原因!')
# 更新状态
parcels.write(
{'state': self.update_status.id, 'node_exception_reason_id': self.node_exception_reason_id.id,
'process_time': self.process_time, 'state_explain': self.state_explain, 'is_sync': False})
# 生成sns日志
# self.bl_id.message_post(body='%s更新为%s' % (self.current_status.name or '', self.update_status.name or ''))
# 跳转显示本次更新状态的小包
return {
'name': '更新小包状态',
'type': 'ir.actions.act_window',
'res_model': 'cc.ship.package',
'view_mode': 'tree,form',
'domain': [('id', 'in', parcels.ids)],
}
def export_order_big_package_xls_action(self):
error_order = []
for item in self:
item.ship_package_ids
parcel_ids = item.big_package_ids.mapped('ship_package_ids')
if not parcel_ids:
error_order.append(item.master_business_no)
continue
good_parcels = parcel_ids.filtered(lambda x: x.item_text)
if len(good_parcels) == 0:
error_order.append(item.master_business_no)
if error_order:
raise ValidationError(f"{','.join(error_order)},没有任何商品信息可导出报关数据")
arr = [item.id for item in self]
"""
是否分大包,如果不分,就是提单一个文件,命名 提单号;如果分,一个提单一个大包一个文件,命名 提单号➕大包号
"""
order_obj = self.get_order()
arr = [item.id for item in order_obj]
return {
'type': 'ir.actions.act_url',
'url': '/export/flight_package/xls/%s/%s' % (arr,self.select_type),
'url': '/export/bl/package/xls/%s/%s' % (arr, self.select_type),
'target': 'new',
}
<?xml version="1.0" encoding="utf-8"?>
<!-- © <2016> <heyang>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>
<data>
<record id="view_export_bl_big_package_xlsx_wizard" model="ir.ui.view">
<field name="name">导出报关文件</field>
<field name="model">export.bl.big.package.xlsx.wizard</field>
<field name="arch" type="xml">
<form string="导出报关文件">
<sheet>
<group>
<field name="select_type" required="1"/>
</group>
<footer>
<button name="submit" type="object" string="Submit" class="oe_highlight"/>
<button string="Close" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<!--定义视图动作-->
<record model="ir.actions.act_window" id="action_export_bl_big_package_xlsx_wizard">
<field name="name">导出报关文件</field>
<field name="res_model">export.bl.big.package.xlsx.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</odoo>
\ No newline at end of file
......@@ -5,11 +5,8 @@ from odoo import models, api, fields
from odoo.exceptions import Warning, ValidationError
# 定义一个批量更新小包状态的向导, 用于批量更新小包状态
# 包括以下字段,提单, 当前节点, 更新节点, 排除面单号, 排除状态
class BatchInputShipPackageStatusWizard(models.TransientModel):
_inherit = 'batch.input.ship.package.status.wizard'
_description = '批量更新小包状态向导'
is_skip_check = fields.Boolean('Skip Check', default=False)
......@@ -61,7 +58,8 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
if len(state_arr) > 0:
state_arr = set(state_arr)
if len(state_arr) > 1:
raise ValidationError('填写的小包单号状态必须一致!')
# 填写的小包单号状态必须一致
raise ValidationError(_('The status of the small package number filled in must be consistent!'))
else:
# 获取所有的小包
if item.current_status:
......@@ -90,15 +88,19 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
exclude_waybill_no_list = [i.strip() for i in exclude_waybill_no_list if i.strip()]
package_obj = self.ship_package_ids.filtered(lambda r: r.tracking_no not in exclude_waybill_no_list)
if len(package_obj) > 0:
# 单号[%s]需填写在排除单号中
raise ValidationError(
'单号[%s]需填写在排除单号中' % '\n'.join([package.tracking_no for package in package_obj]))
_('The tracking number [%s] needs to be filled in the exclusion tracking number!') % '\n'.join(
[package.tracking_no for package in package_obj]))
else:
if len(self.ship_package_ids) > 0:
# 检查小包%s是否存在还未推送或 小包已经推送过将更变更的状态
raise ValidationError(
'单号[%s]不能更新' % '\n'.join([package.tracking_no for package in self.ship_package_ids]))
_('Check if the package [%s] has a status that has not been pushed yet or if the package has already been pushed and will be updated!') % '\n'.join(
[package.tracking_no for package in self.ship_package_ids]))
obj = super(BatchInputShipPackageStatusWizard, self).submit()
# 生成sns日志
self.bl_id.message_post(body='[%s]%s更新为[%s]%s' % (
self.bl_id.message_post(body=_('[%s]%sUpdate to[%s]%s') % (
self.current_status.tk_code or '', self.current_status.name or '', self.update_status.tk_code or '',
self.update_status.name or ''))
return obj
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论