提交 6bb5c09a authored 作者: 刘擎阳's avatar 刘擎阳

Merge branch 'develop' of https://e.coding.net/yizuo/hh_ccs/hh_ccs into develop

......@@ -18,6 +18,7 @@
'security/account_security.xml',
'security/ir.model.access.csv',
'wizard/batch_input_ship_package_statu_wizard.xml',
'wizard/update_bl_status_wizard.xml',
'wizard/export_bl_big_package_xlsx_wizard.xml',
'wizard/associate_pallet_wizard_views.xml',
'wizard/add_exception_info_wizard_views.xml',
......
差异被折叠。
......@@ -5,7 +5,7 @@ from datetime import timedelta
import pytz
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from odoo.exceptions import UserError, ValidationError
# 获取日志
_logger = logging.getLogger(__name__)
......@@ -590,6 +590,30 @@ class CcBL(models.Model):
'context': {'active_id': self.ids, 'default_is_batch': True, 'default_bl_id': self.ids}
}
def batch_update_bl_status_wizard(self):
"""批量更新提单状态"""
# 检查关务提单状态必须是同一个
customs_clearance_status_list = self.filtered(lambda x: x.customs_clearance_status.id).mapped(
'customs_clearance_status.id')
if len(customs_clearance_status_list) == 0:
# 请先配置默认的提单节点类型的清关节点
raise ValidationError(
_('Please configure the default customs clearance status of the bill of loading node type first.'))
if len(customs_clearance_status_list) > 1:
raise ValidationError(_('The customs clearance status of the selected bill of loading must be the same.'))
# 最近操作时间取最晚的一条提单状态操作时间。
last_process_time = \
self.filtered(lambda x: x.customs_clearance_status.id).mapped('process_time').sorted(reverse=True)[0]
return {
'name': _('Update the status of the bill of loading'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'update.bl.status.wizard',
'target': 'new',
'context': {'active_id': self.ids, 'default_is_batch': True, 'default_last_process_time': last_process_time,
'default_current_status': customs_clearance_status_list[0]}
}
@api.depends('big_package_ids', 'big_package_ids.tally_state', 'big_package_ids.is_cancel')
def cal_tally_big_package_qty(self):
"""
......@@ -670,6 +694,16 @@ class CcBL(models.Model):
# 通关文件, 关联附件对象(类型限定为image和PDF)
cc_attachment_ids = fields.One2many('cc.clearance.file', 'bl_id', string='Clearance Files')
# 提单上新增字段:关务提单状态,用英文:关联节点的配置(cc.node),节点类型过滤提单的节点名称。
customs_clearance_status = fields.Many2one('cc.node', string='Customs Clearance Status', tracking=True,
default=lambda self: self.env['cc.node'].search(
[('node_type', '=', 'bl'), ('is_default', '=', True)], limit=1),
domain=[('node_type', '=', 'bl')])
# 增加关务提单状态操作时间
process_time = fields.Datetime(string='Customs Clearance Status Process Time')
# 添加状态说明字段
state_explain = fields.Text('State Explain', help='State Explain')
# 增加一个can_cancel的方法,用于检查提单当前是否可以取消,返回True表示可以取消, False表示不可以取消,同时返回取消的原因
def check_cancel(self):
if self.is_cancel:
......@@ -683,6 +717,8 @@ class CcBL(models.Model):
is_cancel = fields.Boolean(string='Is Cancel', default=False)
# 取消原因
cancel_reason = fields.Char(string='Cancel Reason')
# 是否同步
is_bl_sync = fields.Boolean('Is Bill Of Loading Synchronized', default=False)
# 增加提单取消的方法,用于取消提单,取消提单时,需要检查提单是否可以取消,如果可以取消,则将提单的状态设置为取消,并记录取消原因, 同时取消提单下的所有包裹
def action_cancel(self, cancel_reason=''):
......
......@@ -48,3 +48,8 @@ class CcNode(models.Model):
('checked_goods', 'Checked goods'),
('handover_completed', 'Handover Completed')
], default='', string='Corresponding to the status of the big package', index=True) # 对应大包状态 未理货/已理货/尾程交接
# 新增字段:对应小包状态。只有类型为提单上才可填写。可选已配置节点类型为小包的节点。单选;
package_state = fields.Many2one('cc.node', string='Corresponding to the status of the package',domain="[('node_type','=','package')]", index=True) # 对应小包状态
......@@ -3,7 +3,7 @@ batch_input_ship_package_status_wizard_group_user,batch_input_ship_package_statu
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
access_group_user_common_common,access_group_user_common_common,model_common_common,base.group_user,1,1,1,1
......
......@@ -10,6 +10,7 @@
<tree string="Bill of Loading" decoration-warning="is_cancel==True">
<field optional="show" name="state" string="Status" widget="badge" decoration-info="state=='draft'"
decoration-primary="state=='ccing'" decoration-success="state=='done'"/>
<field optional="show" name="customs_clearance_status" string="Customs Clearance Status"/>
<field optional="show" name="bl_no" string="Bill of Loading No."/>
<field optional="show" name="bl_date" string="B/L Date"/>
<field optional="show" name="customer_id" string="Customer"/>
......@@ -50,10 +51,18 @@
<!-- # 为action_batch_input_ship_package_wizard添加一个按钮, 上下文中添加bl_id-->
<button name="%(action_batch_input_ship_package_wizard)d" type="action" class="oe_highlight"
string="Update Ship Package Status"
context="{'default_bl_id': active_id, 'active_id': id}"/>
context="{'default_bl_id': active_id, 'active_id': id,}"/>
<button name="%(action_batch_input_bl_status_wizard)d" type="action" class="oe_highlight"
string="Update Bill Of Loading Status"
context="{'active_id': id,'default_bl_id': active_id,
'default_last_process_time':process_time,'default_current_status':customs_clearance_status}"/>
<field name="state" widget="statusbar" options="{'clickable': '1'}"/>
</header>
<header>
<field name="customs_clearance_status" widget="statusbar"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
......@@ -117,6 +126,7 @@
<field name="eta" string="ETA"/>
<field name="end_port_code" string="End Port"/>
<field name="etd" string="ETD"/>
<field name="process_time" string="Customs Clearance Status Process Time"/>
</group>
<group>
<field name="billing_weight" string="Billing Weight"/>
......@@ -404,4 +414,16 @@
</field>
</record>
<record id="batch_update_bl_status_server" model="ir.actions.server">
<field name="name">Update the status of the bl of loading</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.batch_update_bl_status_wizard()
</field>
</record>
</odoo>
\ No newline at end of file
......@@ -13,6 +13,7 @@
<field optional="show" name="desc" string="Node Description"/>
<field optional="show" name="next_code_ids" widget="many2many_tags" options="{'no_create':True}"/>
<field optional="show" name="tally_state"/>
<field optional="show" name="package_state"/>
<field optional="show" name="is_must" string="Is Must Node"/>
<field optional="show" name="is_done" string="Is Done Node"/>
<field optional="show" name="is_default" string="Is Current Node"/>
......
......@@ -4,4 +4,5 @@ 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
......@@ -50,7 +50,7 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
# print(self.get_order())
return len(self.get_order())
bl_count = fields.Integer('Bl count', default=get_bl_count)
bl_count = fields.Integer('Bill Of Loading Count', default=get_bl_count)
current_status = fields.Many2one('cc.node', 'Select Node')
next_code_ids = fields.Many2many('cc.node', 'node_next_node_wizard_rel', 'node_id', 'next_node_id', 'Next Node',
related='current_status.next_code_ids')
......@@ -82,12 +82,12 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
state_explain = fields.Text('State Explain', help='State Explain')
node_exception_reason_id = fields.Many2one('cc.node.exception.reason', 'Exception Reason',
domain="[('code_id', '=', update_status)]")
# 批量更新小包状态
def submit(self):
# 确认数据
if not self.is_ok:
raise ValidationError('Please confirm that the above data is correct.') # 请确认以上数据正确
parcels = self.get_process_package()
if not parcels:
......@@ -108,7 +108,7 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
# 更新状态
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': is_sync})
'process_time': self.process_time, 'state_explain': self.state_explain, 'is_sync': is_sync})
# if parcels:
# where_sql = " where id={0}".format(parcels[0].id) if len(
# parcels) == 1 else " where id in {0}".format(tuple(parcels.ids))
......
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api, fields
from odoo.exceptions import ValidationError
# 定义一个批量更新提单状态的向导, 用于批量更新提单状态
# 包括以下字段,提单, 当前节点, 更新节点, 排除面单号, 排除状态
class UpdateBlStatusWizard(models.TransientModel):
_name = 'update.bl.status.wizard'
_description = 'Update the status of the bill of loading' # 更新提单状态向导
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'].browse(order_id)
bl_id = fields.Many2one('cc.bl', 'Bill of Loading')
def get_bl_count(self):
# print(self.get_order())
return len(self.get_order())
bl_count = fields.Integer('Bill Of Loading Count', default=get_bl_count)
current_status = fields.Many2one('cc.node', 'Current Status')
update_status = fields.Many2one('cc.node', 'Update Node')
is_ok = fields.Boolean('Confirm Date is ok.', default=False)
process_time = fields.Datetime('Process Time')
last_process_time = fields.Datetime('Last Process Time', readonly=True, help='Bill Of Loading Last Process Time')
# 添加状态说明字段
state_explain = fields.Text('State Explain', help='State Explain')
is_batch = fields.Boolean('Is Batch', default=False)
# 批量更新小包状态
def submit(self):
bl_obj=self.get_order()
# 确认数据
if not self.is_ok:
raise ValidationError('Please confirm that the above data is correct.') # 请确认以上数据正确
# 1.若选择的更新节点为是当前节点【清关节点设置,是当前节点字段名称改为初始节点】,当更新节点为初始节点时,无需填写操作时间;
# if self.update_status and not self.update_status.is_default:
# 2.若选择的更新节点为“选择节点”的后续节点(根据节点设置排序),则按照操作时间不能大于当前时间,且不能早于最近的操作时间。
# 3.若选择的“更新节点”为“选择节点”的前序节点(根据节点设置排序),则查找“选择节点”是否已有同步日志,若有,则操作时间不允许早于前序节点同步日志里的操作时间,且不能大于当前时间。若有多条,以同步时间最晚的一条为准。
# 4.若选择的“更新节点”和“选择节点”一致时,需检查该节点的前序节点是否有同步日志,若有,则操作时间不允许早于前序节点同步日志里的操作时间,且不能大于当前时间。同一节点若有多条同步日志,以同步时间最晚的一条为准。
# 如果更新节点是 默认节点 同步的标志变为True
is_sync = False
if self.update_status.is_default:
is_sync = True
# 更新状态
bl_obj.write(
{'customs_clearance_status': self.update_status.id, 'process_time': self.process_time, 'state_explain': self.state_explain,
'is_bl_sync': is_sync})
<?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_update_bl_status_wizard" model="ir.ui.view">
<field name="name">view_update_bl_status_wizard</field>
<field name="model">update.bl.status.wizard</field>
<field name="arch" type="xml">
<form string="Update Bill Of Loading Status">
<sheet>
<group>
<field name="bl_count" attrs="{'invisible': [('is_batch', '=', False)]}" readonly="1"/>
<field name="bl_id" invisible="1"/>
<field name="current_status" readonly="1"/>
<field name="last_process_time"/>
<field name="update_status" required="1" domain="[('node_type','=','bl')]"/>
<field name="process_time" required="1" string="Customs Clearance Status Process Time"/>
<field name="state_explain" invisible="1"/>
<field name="is_batch" invisible="1"/>
</group>
<group>
<field name="is_ok"/>
</group>
<footer>
<button name="submit" type="object" string="Submit" class="oe_highlight"
attrs="{'invisible':[('is_ok','=',False)]}"/>
<button string="Close" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<!--定义视图动作-->
<record model="ir.actions.act_window" id="action_batch_input_bl_status_wizard">
<field name="name">Update Bill Of Loading Status</field>
<field name="res_model">update.bl.status.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</odoo>
\ No newline at end of file
......@@ -18,12 +18,14 @@
# 'data/data.xml',
# wizard
'wizard/batch_input_ship_package_statu_wizard.xml',
'wizard/update_bl_status_wizard.xml',
# 'wizard/again_push_wizard.xml',
# 'wizard/batch_push_tiktok.xml',
# view
'views/config_settings_views.xml',
# 'views/flight_order_view.xml',
'views/cc_ship_package_sync_log_view.xml',
'views/cc_bl_sync_log_view.xml',
'views/ao_tt_api_log_view.xml',
'views/cc_node_view.xml',
'views/cc_ship_package_view.xml',
......
import logging
from datetime import datetime
from odoo import models, fields, api, tools
from odoo import models, fields
# 继承节点对象.增加TK编码
......@@ -13,6 +12,60 @@ class CCNode(models.Model):
interval_minutes = fields.Integer('Predecessor Node Interval (Minutes)', default=20,
help='Default interval time between predecessor nodes in minutes.') # 前序节点间隔时间,默认20分钟
def get_before_node(self, node_type='package'):
"""
获取当前状态的前序节点
"""
# 前序节点 该节点之前没有生成的节点
before_node_obj = self.env['cc.node'].sudo().search([
('node_type', '=', node_type), ('is_must', '=', True), ('seq', '<', self.seq)],
order='seq asc')
return before_node_obj
def is_before_node(self, target_state):
"""
判断当前状态是否在目标状态之前
Args:
target_state: 目标状态代码
Returns:
bool: 如果当前状态在目标状态之前返回True,否则返回False
"""
if not target_state:
return False
# 获取所有状态的顺序映射
states_seq = dict(
self.search([]).sorted('seq').mapped(lambda r: (r.tk_code, r.seq))
)
# 获取当前状态的序号
current_code = self.tk_code
current_seq = states_seq.get(current_code)
# 获取目标状态的序号
target_code = target_state.tk_code if isinstance(target_state, models.Model) else target_state
target_seq = states_seq.get(target_code)
# 如果任一状态不存在,返回False
if current_seq is None or target_seq is None:
return False
# 比较序号判断先后顺序
return current_seq < target_seq
def is_next_code(self, current_state_obj, next_state_id):
"""
判断更新的节点是否是 小包状态的下级节点
:param next_state_id:
:return:
"""
if current_state_obj:
if next_state_id in current_state_obj.next_code_ids.ids:
return True
return False
def calculate_total_interval(self, next_node):
"""
计算该节点到某个节点直接的间隔时间和
......
......@@ -44,14 +44,14 @@ class TT(models.Model):
def callback_track(self, push_data):
"""包裹轨迹回传"""
url = '/logistics/provider/cross_border/callback_track?country=GB'
"""包裹轨迹/提单状态回传"""
url = '/logistics/provider/cross_border/callback_track?country=GB'
# cb_excustoms_finished 出口清关完毕
# cb_transport_assigned 干线揽收
timestamp = int(time.time())
sign = self.generate_sign(timestamp, push_data)
response = self.get_response(url, sign, timestamp, push_data)
logging.info('callback_track response:%s' % response)
# logging.info('callback_track response:%s' % response)
return response
def package_invoice_query(self, push_data):
......@@ -66,7 +66,7 @@ class TT(models.Model):
def mwb_status_update(self, push_data):
"""清关提单状态回传"""
url = 'logistics/provider/customs/mwb_status_update'
url = 'logistics/provider/customs/mwb_status_update?country=GB'
timestamp = int(time.time())
sign = self.generate_sign(timestamp, push_data)
response = self.get_response(url, sign, timestamp, push_data)
......@@ -126,20 +126,20 @@ class TT(models.Model):
'app_key': app_key
}
request_url = tt_url + url
logging.info('request_url: %s' % request_url)
logging.info('request_data: %s' % parameter)
# logging.info('request_url: %s' % request_url)
# logging.info('request_data: %s' % parameter)
for i in range(3): # 尝试最多3次
try:
async with session.post(request_url, headers=headers, data=parameter) as response:
response_data = await response.json()
logging.info('response: %s', response_data)
# logging.info('response: %s', response_data)
# print(response.json())
return response_data
except Exception as e:
if i < 2: # 如果不是最后一次尝试,等待后重试
await asyncio.sleep(2 ** i) # 指数退避策略
else:
logging.warning('request error:%s' % str(e))
# logging.warning('request error:%s' % str(e))
return {'code': 500, 'requestID': 'request error timeout', 'msg': '超时,请重试'} # 如果重试次数用尽,抛出异常
async def async_callback_track_callback(self, session, push_data, package_id):
......@@ -150,10 +150,24 @@ class TT(models.Model):
timestamp = int(time.time())
sign = self.generate_sign(timestamp, push_data)
response = await self.async_get_response(session, url, sign, timestamp, push_data)
logging.info('callback_track response:%s' % response)
# logging.info('callback_track response:%s' % response)
return response, push_data, package_id
async def async_callback_track(self, session, data, package_id):
"""异步调用推送接口"""
# async with semaphore:
return await self.async_callback_track_callback(session, data, package_id)
async def async_bl_callback_track_callback(self, session, push_data, package_id):
"""提单状态回传"""
url = '/logistics/provider/customs/mwb_status_update?country=GB'
timestamp = int(time.time())
sign = self.generate_sign(timestamp, push_data)
response = await self.async_get_response(session, url, sign, timestamp, push_data)
# logging.info('bl_callback_track response:%s' % response)
return response, push_data, package_id
async def async_bl_callback_track(self, session, data, bl_id):
"""异步调用提单推送接口"""
# async with semaphore:
return await self.async_bl_callback_track_callback(session, data, bl_id)
......@@ -7,3 +7,8 @@ access_cc_ship_package_sync_log_base.group_erp_manager,cc_ship_package_sync_log
access_cc_ship_package_sync_log_ccs_base.group_clearance_of_customs_manager,cc_ship_package_sync_log ccs_base.group_clearance_of_customs_manager,ccs_connect_tiktok.model_cc_ship_package_sync_log,ccs_base.group_clearance_of_customs_manager,1,0,0,0
access_cc_ship_package_sync_log_ccs_base.group_clearance_of_customs_user,cc_ship_package_sync_log ccs_base.group_clearance_of_customs_user,ccs_connect_tiktok.model_cc_ship_package_sync_log,ccs_base.group_clearance_of_customs_user,1,0,0,0
access_cc_bl_sync_log_base.group_user,cc_bl_sync_log base.group_user,ccs_connect_tiktok.model_cc_bl_sync_log,base.group_user,1,0,0,0
access_cc_bl_sync_log_base.group_erp_manager,cc_bl_sync_log base.group_erp_manager,ccs_connect_tiktok.model_cc_bl_sync_log,base.group_erp_manager,1,1,1,1
access_cc_bl_sync_log_ccs_base.group_clearance_of_customs_manager,cc_bl_sync_log ccs_base.group_clearance_of_customs_manager,ccs_connect_tiktok.model_cc_bl_sync_log,ccs_base.group_clearance_of_customs_manager,1,0,0,0
access_cc_bl_sync_log_ccs_base.group_clearance_of_customs_user,cc_bl_sync_log ccs_base.group_clearance_of_customs_user,ccs_connect_tiktok.model_cc_bl_sync_log,ccs_base.group_clearance_of_customs_user,1,0,0,0
<?xml version="1.0" encoding="utf-8"?>
<odoo>
# ---------- CC Bill Of Loading Sync Log ------------
<record model="ir.ui.view" id="tree_cc_bl_sync_log_view">
<field name="name">tree.cc.bl.sync.log</field>
<field name="model">cc.bl.sync.log</field>
<field name="arch" type="xml">
<tree string="CC Bill Of Loading Sync Log">
<field optional="hide" name="bl_id" string="Bill of Loading"/>
<field optional="show" name="api_customer" string="Api Customer"/>
<field optional="show" name="process_code" string="TK Process Code"/>
<field optional="show" name="progress_name" string="Progress Name"/>
<field optional="show" name="operate_time" string="Operate Time"/>
<field optional="show" name="operate_user" string="Operate User"/>
<field optional="show" name="sync_time" string="Sync Time"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="form_cc_bl_sync_log_view">
<field name="name">form.cc.bl.sync.log</field>
<field name="model">cc.bl.sync.log</field>
<field name="arch" type="xml">
<form string="CC Bill Of Loading Sync Log">
<sheet>
<group>
<group>
<field name="bl_id" string="Bill of Loading"/>
<field name="api_customer" string="Api Customer"/>
<field name="process_code" string="TK Process Code"/>
<field name="progress_name" string="Progress Name"/>
<field name="operate_time" string="Operate Time"/>
<field name="operate_user" string="Operate User"/>
<field name="sync_time" string="Sync Time"/>
</group>
<group>
</group>
</group>
<notebook>
<page string="Operate Remark">
<field name="operate_remark" string="Operate Remark"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="search_cc_bl_sync_log_view">
<field name="name">search.cc.bl.sync.log</field>
<field name="model">cc.bl.sync.log</field>
<field name="arch" type="xml">
<search string="CC Bill Of Loading Sync Log">
<field name="bl_id" string="Bill of Loading"/>
<field name="api_customer" string="Api Customer"/>
<field name="process_code" string="TK Process Code"/>
<field name="operate_time" string="Operate Time"/>
<field name="operate_user" string="Operate User"/>
<field name="sync_time" string="Sync Time"/>
<separator/>
<filter name="filter_operate_time" string="Operate Time" date="operate_time"/>
<filter name="filter_sync_time" string="Sync Time" date="sync_time"/>
<separator/>
<group expand="0" string="Group By">
<filter domain="[]" name="groupby_bl_id" string="Bill of Loading"
context="{'group_by': 'bl_id'}"/>
<filter domain="[]" name="groupby_operate_user" string="Operate User"
context="{'group_by': 'operate_user'}"/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_cc_bl_sync_log">
<field name="name">CC Bill Of Loading Sync Log</field>
<field name="res_model">cc.bl.sync.log</field>
<field name="view_mode">tree</field>
<field name="domain">[]</field>
<field name="context">{}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
[CC Bill Of Loading Sync Log] Not yet! Click the Create button in the top left corner and the sofa is yours!
</p>
<p>
</p>
</field>
</record>
</odoo>
\ No newline at end of file
......@@ -9,7 +9,11 @@
<field name="inherit_id" ref="ccs_base.tree_cc_bl_view"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="unsync_package_count" string="UnSync" widget="badge" decoration-danger="1 == 1"/>
<field name="unsync_package_count" string="UnSync Package Count" widget="badge"
decoration-danger="1 == 1"/>
</field>
<field name="customs_clearance_status" position="after">
<field name="is_bl_sync" string="Is Bill Of Loading Sync"/>
</field>
</field>
</record>
......@@ -20,12 +24,16 @@
<field name="model">cc.bl</field>
<field name="inherit_id" ref="ccs_base.form_cc_bl_view"/>
<field name="arch" type="xml">
<!-- # header之间增加一个按钮,调用自定义的方法-->
<header position="inside">
<button name="%(ccs_base.action_batch_input_ship_package_wizard)d" position="after">
<button name="callback_track" string="Sync Package Status" type="object"/>
</button>
<button name="%(ccs_base.action_batch_input_bl_status_wizard)d" position="before">
<button name="batch_action_sync" string="Sync CC Attachment" type="object"/>
</header>
</button>
<button name="%(ccs_base.action_batch_input_bl_status_wizard)d" position="after">
<!--增加同步提单状态的按钮-->
<button name="callback_track_bl" string="Sync Bill Of Loading Status" type="object"/>
</button>
<button name="action_show_ship_package" position="replace">
<button name="action_show_ship_package" type="object"
......@@ -45,48 +53,13 @@
</div>
</button>
</button>
</field>
</record>
<!-- # 继承ccs_base模块的cc_ship_package_view.xml视图,增加is_sync字段在列表中-->
<record model="ir.ui.view" id="tree_cc_ship_package_view_inherit">
<field name="name">tree_cc_ship_package_view_inherit</field>
<field name="model">cc.ship.package</field>
<field name="inherit_id" ref="ccs_base.tree_cc_ship_package_view"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="is_sync"/>
</field>
<tree position="attributes">
<attribute name="decoration-danger">is_sync == False</attribute>
</tree>
</field>
</record>
<!-- # 继承ccs_base模块的search_cc_ship_package_view视图,装置加未同步的筛选条件-->
<record model="ir.ui.view" id="search_cc_ship_package_view_inherit">
<field name="name">search_cc_ship_package_view_inherit</field>
<field name="model">cc.ship.package</field>
<field name="inherit_id" ref="ccs_base.search_cc_ship_package_view"/>
<field name="arch" type="xml">
<search position="inside">
<filter string="Not Sync" name="filter_is_sync" domain="[('is_sync','=',False)]"/>
</search>
</field>
</record>
# 继承ccs_base模块的form_cc_ship_package_view视图,增加同步日志列表在notebook中
<record model="ir.ui.view" id="form_cc_ship_package_view_inherit">
<field name="name">form_cc_ship_package_view_inherit</field>
<field name="model">cc.ship.package</field>
<field name="inherit_id" ref="ccs_base.form_cc_ship_package_view"/>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Sync Log">
<field name="sync_log_ids" widget="one2many_list"/>
<field name="bl_sync_log_ids" widget="one2many_list"/>
<group invisible="1">
<field name="is_bl_sync" string="Is Sync" readonly="1"/>
<field name="state_explain" string="State Explain"/>
</group>
</page>
</notebook>
</field>
......@@ -100,7 +73,19 @@
<field name="state">code</field>
<field name="code">
if records:
records.callback_track()
records.callback_track()
</field>
</record>
<record id="action_batch_sync_bl_status" model="ir.actions.server">
<field name="name">Batch Sync Bill Of Loading Status</field>
<field name="model_id" ref="model_cc_bl"/>
<field name="binding_model_id" ref="model_cc_bl"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">
if records:
records.callback_track_bl()
</field>
</record>
......@@ -110,11 +95,11 @@
<field name="model_id" ref="model_cc_bl"/>
<field name="binding_model_id" ref="model_cc_bl"/>
<field name="binding_view_types">list</field>
<field name="groups_id" eval="[(4, ref('base.group_system'))]"/>
<field name="groups_id" eval="[(4, ref('base.group_system'))]"/>
<field name="state">code</field>
<field name="code">
if records:
records.deal_ship_package_state()
records.deal_ship_package_state()
</field>
</record>
</data>
......
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record model="ir.ui.view" id="tree_cc_ship_package_view">
<field name="name">tree.cc.ship.package</field>
<!-- # 继承ccs_base模块的cc_ship_package_view.xml视图,增加is_sync字段在列表中-->
<record model="ir.ui.view" id="tree_cc_ship_package_view_inherit">
<field name="name">tree_cc_ship_package_view_inherit</field>
<field name="model">cc.ship.package</field>
<field name="inherit_id" ref="ccs_base.tree_cc_ship_package_view"/>
<field name="arch" type="xml">
<field name="state" position="after">
<field name="is_sync"/>
</field>
<field name="state" position="replace">
<field name="tk_code" invisible="1"/>
<field optional="show" name="state" string="Progress" widget="badge"
......@@ -13,7 +19,35 @@
decoration-warning="tk_code in ('cb_imcustoms_inspection','cb_imcustoms_exception')"
decoration-muted="tk_code=='cb_import_customs_failure'"/>
</field>
<tree position="attributes">
<attribute name="decoration-danger">is_sync == False</attribute>
</tree>
</field>
</record>
<!-- # 继承ccs_base模块的search_cc_ship_package_view视图,装置加未同步的筛选条件-->
<record model="ir.ui.view" id="search_cc_ship_package_view_inherit">
<field name="name">search_cc_ship_package_view_inherit</field>
<field name="model">cc.ship.package</field>
<field name="inherit_id" ref="ccs_base.search_cc_ship_package_view"/>
<field name="arch" type="xml">
<search position="inside">
<filter string="Not Sync" name="filter_is_sync" domain="[('is_sync','=',False)]"/>
</search>
</field>
</record>
# 继承ccs_base模块的form_cc_ship_package_view视图,增加同步日志列表在notebook中
<record model="ir.ui.view" id="form_cc_ship_package_view_inherit">
<field name="name">form_cc_ship_package_view_inherit</field>
<field name="model">cc.ship.package</field>
<field name="inherit_id" ref="ccs_base.form_cc_ship_package_view"/>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Sync Log">
<field name="sync_log_ids" widget="one2many_list"/>
</page>
</notebook>
</field>
</record>
......
......@@ -2,4 +2,5 @@
from . import batch_input_ship_package_statu_wizard
from . import update_bl_status_wizard
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import models, api, fields, _
from odoo.exceptions import Warning, ValidationError
from odoo.exceptions import ValidationError
class BatchInputShipPackageStatusWizard(models.TransientModel):
......@@ -129,7 +128,7 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
if parcels:
error_package_arr = []
for package_item in parcels:
result = package_item.is_next_code(self.update_status.id)
result = self.env['cc.node'].is_next_code(package_item.state, self.update_status.id)
if not result:
error_package_arr.append(package_item.tracking_no)
if len(error_package_arr) > 0:
......@@ -164,4 +163,5 @@ class BatchInputShipPackageStatusWizard(models.TransientModel):
self.update_status.name or ''))
# 如果提单有小包变成了清关开始,提单状态变为清关中;如果提单所有小包的清关节点变成“是完成节点”,则该提单状态变成已完成
bl_obj.change_state_by_ship_package()
bl_obj.change_customs_state_by_ship_package(self.update_status)#根据小包状态更新提单关务状态
return obj
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, _
from odoo.exceptions import ValidationError
# 定义一个批量更新提单状态的向导, 用于批量更新提单状态
# 包括以下字段,提单, 当前节点, 更新节点, 排除面单号, 排除状态
class UpdateBlStatusWizard(models.TransientModel):
_inherit = 'update.bl.status.wizard'
_description = 'Update the status of the bill of loading' # 更新提单状态向导
is_skip_check = fields.Boolean('Skip Check', default=False)
def submit(self):
bl_objs = self.get_order()
if not self.is_skip_check:
# 1检查操作时间不能大于当前时间,不能小于 最晚操作时间
current_time = fields.Datetime.now()
if self.process_time and (self.process_time > current_time or (
self.last_process_time and self.process_time < self.last_process_time)):
raise ValidationError(
_('The operation time cannot be greater than the current time and cannot be less than the latest operation time!')) # 操作时间不能大于当前时间且不能小于最晚操作时间
# 2检查更新节点是否是 提单的状态的下一节点
if bl_objs:
error_bl_arr = []
for bl in bl_objs:
result = self.env['cc.node'].is_next_code(bl.customs_clearance_status, self.update_status.id)
if not result:
error_bl_arr.append(bl.bl_no)
if len(error_bl_arr) > 0:
raise ValidationError(
_('[%s] The update node is not the next node in the state of the bill of loading!') % ','.join(
error_bl_arr)) # 更新节点不是提单的状态的下一节点!
# 3检查提单%s是否存在还未推送或 提单已经推送过将更变更的状态
bl_id_arr = self.get_exception_bl() # 异常的提单
if len(bl_id_arr) > 0:
raise ValidationError(
_('Check if the bill of loading [%s] has a status that has not been pushed yet or if the bill of loading has already been pushed and will be updated!') % '\n'.join(
[bl.bl_no for bl in
self.env['cc.bl'].search([('id', 'in', bl_id_arr)])])) # # 提单%s是否存在还未推送或 提单已经推送过将更变更的状态
obj = super(UpdateBlStatusWizard, self).submit()
for bl_obj in bl_objs:
bl_obj.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
def get_exception_bl(self):
"""
比如 已提货 --- 清关开始,选择了清关开始之后 把已提货状态的提单且更新日志明细包含了 清关开始 的编码的 提单显示出来
已提货的判断是否推送过
"""
item = self
bl_ids = []
bl_objs = self.get_order()
if bl_objs and not item.is_skip_check:
where_sql = " and bl_id={0}".format(bl_objs[0].id) if len(
bl_objs) == 1 else " and bl_id in {0}".format(tuple(bl_objs.ids))
current_status = item.current_status
if current_status and not current_status.is_default:
# 更新日志里没有 当前节点(不包括默认节点) 【已提货】的提单
select_sql = "select id from cc_bl_sync_log where process_code='{0}' {1}".format(
current_status.tk_code, where_sql)
self._cr.execute(select_sql)
sync_log_obj = self._cr.fetchall()
if len(sync_log_obj) <= 0:
bl_ids += bl_objs.ids
if item.update_status:
# 更新日志明细包含了 更新节点 【清关开始】 的 提单
select_sql = "select bl_id from cc_bl_sync_log where process_code='{0}' {1}".format(
item.update_status.tk_code, where_sql)
self._cr.execute(select_sql)
bl_ids += [r[0] for r in self._cr.fetchall()]
return bl_ids
<?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_update_bl_status_wizard" model="ir.ui.view">
<field name="name">view_update_bl_status_wizard</field>
<field name="model">update.bl.status.wizard</field>
<field name="inherit_id" ref="ccs_base.view_update_bl_status_wizard"/>
<field name="arch" type="xml">
<field name="bl_id" position="after">
<field name="is_skip_check"/>
</field>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论