提交 2d49a026 authored 作者: 伍姿英's avatar 伍姿英

Merge branch 'release/V2.5.0'

...@@ -19,10 +19,16 @@ ...@@ -19,10 +19,16 @@
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'wizard/batch_input_ship_package_statu_wizard.xml', 'wizard/batch_input_ship_package_statu_wizard.xml',
'wizard/export_bl_big_package_xlsx_wizard.xml', 'wizard/export_bl_big_package_xlsx_wizard.xml',
'wizard/associate_pallet_wizard_views.xml',
'wizard/add_exception_info_wizard_views.xml',
'wizard/email_template.xml',
'data/data.xml', 'data/data.xml',
'data/sequence.xml',
'views/menu_view.xml', 'views/menu_view.xml',
'views/cc_clearance_file_view.xml', 'views/cc_clearance_file_view.xml',
'views/cc_node_view.xml', 'views/cc_node_view.xml',
'views/cc_last_mile_provider_views.xml',
'views/cc_exception_info_views.xml',
'views/cc_process_view.xml', 'views/cc_process_view.xml',
'views/cc_package_good_view.xml', 'views/cc_package_good_view.xml',
'views/cc_ship_package_view.xml', 'views/cc_ship_package_view.xml',
...@@ -43,6 +49,11 @@ ...@@ -43,6 +49,11 @@
'web.assets_frontend': [ 'web.assets_frontend': [
'ccs_base/static/css/base.scss', 'ccs_base/static/css/base.scss',
], ],
'web.assets_backend': [
'ccs_base/static/src/mixins/*.js',
'ccs_base/static/src/views/*.js',
'ccs_base/static/src/views/*.xml',
],
}, },
'license': 'AGPL-3', 'license': 'AGPL-3',
} }
...@@ -14,5 +14,18 @@ ...@@ -14,5 +14,18 @@
<field name="key">parcel_export_num</field> <field name="key">parcel_export_num</field>
<field name="value">50000</field> <field name="value">50000</field>
</record> </record>
<!-- 默认发件邮箱-->
<record id="default_email_from" model="ir.config_parameter">
<field name="key">default_email_from</field>
<field name="value">847896395@qq.com</field>
</record>
<record id="next_minutes" model="ir.config_parameter">
<field name="key">next_minutes</field>
<field name="value">20</field>
</record>
</data> </data>
</odoo> </odoo>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="sequence_cc_exception_info" model="ir.sequence">
<field name="name">异常信息编码规则</field>
<field name="code">cc.exception.info</field>
<field name="padding">2</field>
<field name="number_next_actual">10</field>
<field name="company_id" eval="False"/>
</record>
</data>
</odoo>
\ No newline at end of file
差异被折叠。
from . import res_partner from . import res_partner
from . import cc_node
from . import cc_bill_loading from . import cc_bill_loading
from . import cc_customs_declaration_order from . import cc_customs_declaration_order
from . import cc_exception_info
from . import cc_last_mile_provider
from . import cc_node
from . import cc_node_exception_reason from . import cc_node_exception_reason
from . import mail_thread
from . import common_common from . import common_common
from . import fetch_mail from . import fetch_mail
from . import mail_thread
from . import order_state_change_rule from . import order_state_change_rule
from . import res_config_setting from . import res_config_setting
import random
from odoo import models, fields, api
class CCExceptionInfo(models.Model):
_name = 'cc.exception.info'
_description = 'Package Exception Information'
_rec_name = 'reason'
@api.model
def create(self, vals):
if 'exception_code' not in vals or vals['exception_code'] == '/':
vals['exception_code'] = self.env['ir.sequence'].next_by_code('cc.exception.info') or '/'
obj = super(CCExceptionInfo, self).create(vals)
return obj
exception_code = fields.Char(string='Exception Code', default='/', required=True) # 异常编码*
reason = fields.Text(string='Exception Reason', required=True, translate=True) # 异常原因
responsible_email = fields.Text(string='Exception Responsible Email') # 异常接收负责人邮箱(可输入多个)
# 异常编码增加唯一约束
_sql_constraints = [('exception_code_uniq', 'unique(exception_code)', 'The Exception Code must be unique.')]
def search_exception_info(self, pda_lang=False):
"""
查询包裹异常原因
:return:
"""
return {
'exception_code': self.exception_code or '',
'reason': self.reason or '',
'responsible_email': self.responsible_email or '',
'id': self.id
}
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class CCLastMileProvider(models.Model):
_name = 'cc.last.mile.provider'
_description = 'Last Mile Provider'
@api.constrains('matching_value')
def _check_matching_value(self):
for record in self:
if record.matching_value:
values = record.matching_value.split('\n')
existing_values = '\n'.join(self.search([('id', '!=', record.id)]).mapped('matching_value')).split('\n')
if len(values) != len(set(values)) or any(value in existing_values for value in values):
raise ValidationError(_("Matching values must be unique!"))
name = fields.Char(string='Courier Name', required=True) # 快递名称
abbreviation = fields.Char(string='Abbreviation', required=True) # 简称
tape_color_value = fields.Char(string='Tape Color Value') # 胶带色值
active = fields.Boolean('Active', default=True) # 有效☑️
matching_value = fields.Text(string='Matching Value') # 尾程服务商匹配值
def match_provider(self, provider_name):
"""Check if the provider name exists in matching values and return the record."""
# 查询所有匹配的记录
matching_records = self.search([])
# 检查是否有记录的 matching_value 包含 provider_name
for record in matching_records:
if provider_name in record.matching_value.split('\n'):
return record # 返回找到的记录
return False # 如果没有找到,返回 None
# 导入odoo # 导入odoo
import base64 import base64
import xlrd
from odoo import models, fields, api, _
# 导入日志 # 导入日志
import logging import logging
import xlrd
from odoo import models, fields, api, _
from odoo.exceptions import UserError from odoo.exceptions import UserError
# 获取日志 # 获取日志
...@@ -45,3 +42,9 @@ class CcNode(models.Model): ...@@ -45,3 +42,9 @@ class CcNode(models.Model):
], string='Node Type', default='bl') ], string='Node Type', default='bl')
next_code_ids = fields.Many2many('cc.node', 'node_next_node_rel', 'node_id', 'next_node_id', 'Next Node', next_code_ids = fields.Many2many('cc.node', 'node_next_node_rel', 'node_id', 'next_node_id', 'Next Node',
domain="[('node_type','=',node_type)]") domain="[('node_type','=',node_type)]")
tally_state = fields.Selection([
('unprocessed_goods', 'Unprocessed goods'),
('checked_goods', 'Checked goods'),
('handover_completed', 'Handover Completed')
], default='', string='Corresponding to the status of the big package', index=True) # 对应大包状态 未理货/已理货/尾程交接
...@@ -9,7 +9,6 @@ import json ...@@ -9,7 +9,6 @@ import json
import xlrd import xlrd
import base64 import base64
import pdfplumber import pdfplumber
import demjson
from io import BytesIO from io import BytesIO
from datetime import datetime, timedelta from datetime import datetime, timedelta
import re import re
......
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
batch_input_ship_package_status_wizard_group_user,batch_input_ship_package_status_wizard_group_user,ccs_base.model_batch_input_ship_package_status_wizard,base.group_user,1,1,1,1 batch_input_ship_package_status_wizard_group_user,batch_input_ship_package_status_wizard_group_user,ccs_base.model_batch_input_ship_package_status_wizard,base.group_user,1,1,1,1
export_bl_big_package_xlsx_wizard_group_user,export_bl_big_package_xlsx_wizard_group_user,ccs_base.model_export_bl_big_package_xlsx_wizard,base.group_user,1,1,1,1 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
access_group_user_common_common,access_group_user_common_common,model_common_common,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
...@@ -11,6 +16,12 @@ access_cc_node_exception_reason_base.group_user,cc_node_exception_reason base.gr ...@@ -11,6 +16,12 @@ access_cc_node_exception_reason_base.group_user,cc_node_exception_reason base.gr
access_cc_node_exception_reason_base.group_erp_manager,cc_node_exception_reason base.group_erp_manager,ccs_base.model_cc_node_exception_reason,base.group_erp_manager,1,1,1,1 access_cc_node_exception_reason_base.group_erp_manager,cc_node_exception_reason base.group_erp_manager,ccs_base.model_cc_node_exception_reason,base.group_erp_manager,1,1,1,1
cc_exception_info_group_user,cc_exception_info_group_user,ccs_base.model_cc_exception_info,base.group_user,1,0,0,0
cc_exception_info_group_erp_manager,cc_exception_info_group_erp_manager,ccs_base.model_cc_exception_info,base.group_erp_manager,1,1,1,1
cc_last_mile_provider_group_user,cc_last_mile_provider_group_user,ccs_base.model_cc_last_mile_provider,base.group_user,1,0,0,0
cc_last_mile_provider_group_erp_manager,cc_last_mile_provider_group_erp_manager,ccs_base.model_cc_last_mile_provider,base.group_erp_manager,1,1,1,1
......
/** @odoo-module */
import {useService} from '@web/core/utils/hooks';
const {useRef, useEffect, useState} = owl;
export const BigPackageLinkPallet = {
setup() {
this._super();
this.actionService = useService('action');
this.notification = useService('notification');
this.orm = useService('orm');
this.http = useService('http');
this.fileInput = useRef('fileInput');
this.root = useRef("root");
// this.isBigPackage = this.model.rootParams.resModel === "cc.big.package";
// this.is_link = this.user.hasGroup("ccs_base.group_clearance_of_customs_manager");
// console.log('ccs isBigPackage:' + this.isBigPackage)
// console.log('ccs is_link:' + this.is_link)
},
// displayLink() {
// console.log('ccs flag:' + this.isBigPackage && this.is_link)
// // 是大包的对象以及有清关清理的权限才显示按钮
// return this.isBigPackage && this.is_link;
// },
async onLinkPalletClick() {
// 点击按钮弹出关联托盘的向导
const records = this.model.root.selection;
const recordIds = records.map((a) => a.resId);
const action = await this.orm.call('cc.big.package', 'action_link_pallet', [recordIds]);
this.actionService.doAction(action);
},
};
/** @odoo-module */
import {BigPackageLinkPallet} from '../mixins/link_pallet';
import {registry} from '@web/core/registry';
import {patch} from '@web/core/utils/patch';
import {useService} from '@web/core/utils/hooks';
import {listView} from "@web/views/list/list_view";
import {ListController} from "@web/views/list/list_controller";
const {onWillStart} = owl;
export class BigPackageListController extends ListController {
setup() {
super.setup();
console.log('----------引用成功')
this.orm = useService('orm');
this.actionService = useService('action');
this.rpc = useService("rpc");
this.user = useService("user");
this.isBigPackage = this.model.rootParams.resModel === "cc.big.package";
console.log('ccs isBigPackage:' + this.isBigPackage)
onWillStart(async () => {
this.is_link = await this.user.hasGroup("ccs_base.group_clearance_of_customs_manager");
console.log('ccs is_link:' + this.is_link)
});
}
displayLink() {
console.log('ccs flag:' + this.isBigPackage && this.is_link)
// 是大包的对象以及有清关清理的权限才显示按钮
return this.isBigPackage && this.is_link;
}
}
patch(BigPackageListController.prototype, 'big_package_list_controller_link_pallet', BigPackageLinkPallet);
registry.category('views').add('cc_big_package_tree', {
...listView,
buttonTemplate: 'ccs_base.ListButtons',
Controller: BigPackageListController
});
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="ccs_base.ListButtons" t-inherit="web.ListView.Buttons" t-inherit-mode="primary" owl="1">
<xpath expr="//button[hasclass('o_list_button_add')]" position="after">
<button t-if="displayLink()" type="button" class="d-none d-md-inline o_button_link_pallet btn btn-primary mx-1" t-on-click.prevent="onLinkPalletClick">
Link Pallet
</button>
</xpath>
</t>
</templates>
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
<field name="model">cc.bl</field> <field name="model">cc.bl</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Bill of Loading" decoration-warning="is_cancel==True"> <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="state" string="Status" widget="badge" decoration-info="state=='draft'"
decoration-primary="state=='ccing'" decoration-success="state=='done'"/>
<field optional="show" name="bl_no" string="Bill of Loading No."/> <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="bl_date" string="B/L Date"/>
<field optional="show" name="customer_id" string="Customer"/> <field optional="show" name="customer_id" string="Customer"/>
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
<field optional="show" name="etd" string="ETD"/> <field optional="show" name="etd" string="ETD"/>
<field optional="show" name="is_cancel" string="Is Cancel"/> <field optional="show" name="is_cancel" string="Is Cancel"/>
<field optional="hide" name="cancel_reason" string="Cancel Reason"/> <field optional="hide" name="cancel_reason" string="Cancel Reason"/>
<field optional="show" name="create_date"/>
</tree> </tree>
</field> </field>
</record> </record>
...@@ -47,7 +49,8 @@ ...@@ -47,7 +49,8 @@
<header> <header>
<!-- # 为action_batch_input_ship_package_wizard添加一个按钮, 上下文中添加bl_id--> <!-- # 为action_batch_input_ship_package_wizard添加一个按钮, 上下文中添加bl_id-->
<button name="%(action_batch_input_ship_package_wizard)d" type="action" class="oe_highlight" <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}"/> string="Update Ship Package Status"
context="{'default_bl_id': active_id, 'active_id': id}"/>
<field name="state" widget="statusbar" options="{'clickable': '1'}"/> <field name="state" widget="statusbar" options="{'clickable': '1'}"/>
</header> </header>
...@@ -68,6 +71,15 @@ ...@@ -68,6 +71,15 @@
<span class="o_stat_text">Tally Big Packages</span> <span class="o_stat_text">Tally Big Packages</span>
</div> </div>
</button> </button>
<button name="action_show_big_package_delivered" type="object"
class="oe_stat_button" icon="fa-cube">
<div class="o_stat_info">
<field name="delivered_big_package_qty" class="o_stat_value"/>
<span class="o_stat_text">Delivered Big Packages</span>
</div>
</button>
<button name="action_show_ship_package" type="object" <button name="action_show_ship_package" type="object"
class="oe_stat_button" icon="fa-cubes"> class="oe_stat_button" icon="fa-cubes">
<div class="o_stat_info"> <div class="o_stat_info">
...@@ -183,7 +195,42 @@ ...@@ -183,7 +195,42 @@
<field name="bl_no" string="Search" <field name="bl_no" string="Search"
filter_domain="['|', ('bl_no', 'ilike', self), ('customs_bl_no', 'ilike', self)]"/> filter_domain="['|', ('bl_no', 'ilike', self), ('customs_bl_no', 'ilike', self)]"/>
<separator/> <separator/>
<filter string="Draft" name="filter_state_draft" domain="[('state','=','draft')]"/>
<filter string="CCing" name="filter_state_ccing" domain="[('state','=','ccing')]"/>
<filter string="Done" name="filter_state_done" domain="[('state','=','done')]"/>
<filter string="Not Finished Bill of Loading" name="filter_state_not_finished"
domain="[('state','in',('ccing','draft'))]"/>
<separator/>
<filter string="Today's bill of loading"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))
, ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="today_ship"/>
<filter string="Yesterday's bill of loading"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=1), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')), ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"
name="yesterday_ship"/>
<filter string="Last 7 days bill of loading"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=7), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_7d"/>
<filter string="Last 10 days bill of loading"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=10), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_10d"/>
<filter string="This week bill of loading" name="this_week_ship"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today() + relativedelta(weeks=-1,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),
('create_date', '&lt;', (datetime.datetime.combine(context_today() + relativedelta(days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<filter string="Last week bill of loading" name="last_week_ship"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today() + relativedelta(weeks=-2,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),
('create_date', '&lt;', (datetime.datetime.combine(context_today() + relativedelta(weeks=-1,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<!-- <filter string="This month ship package"-->
<!-- domain="[('create_date', '>=', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-01 00:00:00'))]"-->
<!-- name="this_month_ship"/>-->
<!-- <filter string=" Last month ship package"-->
<!-- domain="[('create_date','&lt;', (context_today().replace(day=1)).strftime('%Y-%m-%d 00:00:00')),('create_date','&gt;=',(context_today() -relativedelta(months=1)).replace(day=1).strftime('%Y-%m-%d 00:00:00'))]"-->
<!-- name="last_month_ship"/>-->
<filter string="Last 30 days bill of loading"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=30), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_30d"/>
<separator/>
<field name="bl_no" string="Bill of Loading No."/> <field name="bl_no" string="Bill of Loading No."/>
<field name="bl_date" string="B/L Date"/> <field name="bl_date" string="B/L Date"/>
<field name="customer_id" string="Customer"/> <field name="customer_id" string="Customer"/>
...@@ -248,14 +295,14 @@ ...@@ -248,14 +295,14 @@
<field name="res_model">cc.bl</field> <field name="res_model">cc.bl</field>
<field name="view_mode">tree,form,pivot,graph,calendar</field> <field name="view_mode">tree,form,pivot,graph,calendar</field>
<field name="domain">[]</field> <field name="domain">[]</field>
<field name="context">{}</field> <field name="context">{'search_default_filter_state_not_finished':1}</field>
<field name="help" type="html"> <field name="help" type="html">
<p> <p>
</p> </p>
</field> </field>
</record> </record>
<menuitem parent="" sequence="15" name="Bill of Loading" id="menu_cc_bl" action="action_cc_bl"/> <menuitem parent="" sequence="10" name="Bill of Loading" id="menu_cc_bl" action="action_cc_bl"/>
<!--&lt;!&ndash; <record model="ir.ui.view" id="search_cc_bl_view">&ndash;&gt;--> <!--&lt;!&ndash; <record model="ir.ui.view" id="search_cc_bl_view">&ndash;&gt;-->
...@@ -335,7 +382,7 @@ ...@@ -335,7 +382,7 @@
</field> </field>
</record> </record>
<record id="export_flight_png_server" model="ir.actions.server"> <record id="export_flight_png_server" model="ir.actions.server">
<field name="name">Export customs clearance bill of lading file</field> <field name="name">Export customs clearance bill of lading file</field>
<field name="model_id" ref="model_cc_bl"/> <field name="model_id" ref="model_cc_bl"/>
<field name="binding_model_id" ref="model_cc_bl"/> <field name="binding_model_id" ref="model_cc_bl"/>
...@@ -346,7 +393,7 @@ ...@@ -346,7 +393,7 @@
</field> </field>
</record> </record>
<record id="batch_input_ship_package_status_server" model="ir.actions.server"> <record id="batch_input_ship_package_status_server" model="ir.actions.server">
<field name="name">Update the status of the small package</field> <field name="name">Update the status of the small package</field>
<field name="model_id" ref="model_cc_bl"/> <field name="model_id" ref="model_cc_bl"/>
<field name="binding_model_id" ref="model_cc_bl"/> <field name="binding_model_id" ref="model_cc_bl"/>
......
<odoo>
<record id="view_exception_info_form" model="ir.ui.view">
<field name="name">exception.info.form</field>
<field name="model">cc.exception.info</field>
<field name="arch" type="xml">
<form string="Package Exception Information">
<sheet>
<group>
<field name="exception_code" readonly="1"/> <!-- 异常编码 -->
<field name="reason"/> <!-- 异常原因 -->
<field name="responsible_email"
placeholder="Multiple entries can be made, one email per line"/>
<!-- 异常接收负责人邮箱 可输入多个,一行一个邮箱 -->
</group>
</sheet>
</form>
</field>
</record>
<record id="view_exception_info_tree" model="ir.ui.view">
<field name="name">exception.info.tree</field>
<field name="model">cc.exception.info</field>
<field name="arch" type="xml">
<tree string="Package Exception Information">
<field name="exception_code"/> <!-- 异常编码 -->
<field name="reason"/> <!-- 异常原因 -->
<field name="responsible_email"/> <!-- 异常接收负责人邮箱 -->
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_exception_info_search">
<field name="name">exception.info.search</field>
<field name="model">cc.exception.info</field>
<field name="arch" type="xml">
<search string="Package Exception Information">
<field name="exception_code"/>
<field name="reason"/>
</search>
</field>
</record>
<record id="action_exception_info" model="ir.actions.act_window">
<field name="name">Package Exception Information</field>
<field name="res_model">cc.exception.info</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_exception_info" name="Package Exception Information" parent="menu_ccs_base_main" sequence="98"
action="action_exception_info"/>
</odoo>
\ No newline at end of file
<odoo>
<record id="view_last_mile_provider_form" model="ir.ui.view">
<field name="name">last.mile.provider.form</field>
<field name="model">cc.last.mile.provider</field>
<field name="arch" type="xml">
<form string="Last Mile Provider">
<sheet>
<group>
<group>
<field name="name"/> <!-- 快递名称 -->
<field name="abbreviation"/> <!-- 简称 -->
<field name="tape_color_value" widget="color" required="1"/> <!-- 胶带色值 -->
<field name="matching_value"
placeholder="Multiple entries can be made, one matching value per line"/> <!-- 尾程服务商匹配值 -->
</group>
<group>
<field name="active"/> <!-- 有效☑️ -->
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_last_mile_provider_tree" model="ir.ui.view">
<field name="name">last.mile.provider.tree</field>
<field name="model">cc.last.mile.provider</field>
<field name="arch" type="xml">
<tree string="Last Mile Provider">
<field name="name"/> <!-- 快递名称 -->
<field name="abbreviation"/> <!-- 简称 -->
<field name="tape_color_value"/> <!-- 胶带色值 -->
<field name="matching_value"/> <!-- 尾程服务商匹配值 -->
<field name="active"/> <!-- 有效☑️ -->
</tree>
</field>
</record>
<record model="ir.ui.view" id="view_last_mile_provider_search">
<field name="name">last.mile.provider.search</field>
<field name="model">cc.last.mile.provider</field>
<field name="arch" type="xml">
<search string="Last Mile Provider">
<field name="name"/>
<field name="abbreviation"/>
</search>
</field>
</record>
<record id="action_last_mile_provider" model="ir.actions.act_window">
<field name="name">Last Mile Providers</field>
<field name="res_model">cc.last.mile.provider</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_last_mile_provider" name="Last Mile Providers" parent="menu_ccs_base_main" sequence="95"
action="action_last_mile_provider"/>
</odoo>
\ No newline at end of file
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
<field optional="show" name="name" string="Node Name"/> <field optional="show" name="name" string="Node Name"/>
<field optional="show" name="desc" string="Node Description"/> <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="next_code_ids" widget="many2many_tags" options="{'no_create':True}"/>
<field optional="show" name="tally_state"/>
<field optional="show" name="is_must" string="Is Must Node"/> <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_done" string="Is Done Node"/>
<field optional="show" name="is_default" string="Is Current Node"/> <field optional="show" name="is_default" string="Is Current Node"/>
......
...@@ -184,6 +184,6 @@ ...@@ -184,6 +184,6 @@
</field> </field>
</record> </record>
<menuitem parent="" sequence="12" name="Package Goods" id="menu_cc_package_good" action="action_cc_package_good"/> <menuitem parent="" sequence="16" name="Package Goods" id="menu_cc_package_good" action="action_cc_package_good"/>
</odoo> </odoo>
\ No newline at end of file
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<field optional="hide" name="customer_ref" string="Customer Ref"/> <field optional="hide" name="customer_ref" string="Customer Ref"/>
<field optional="hide" name="company_code" string="Company Code"/> <field optional="hide" name="company_code" string="Company Code"/>
<field optional="hide" name="internal_account_number" string="Internal Account Number"/> <field optional="hide" name="internal_account_number" string="Internal Account Number"/>
<field optional="hide" name="create_date"/>
<field optional="show" name="logistic_order_no" string="Logistic Order No"/> <field optional="show" name="logistic_order_no" string="Logistic Order No"/>
<field optional="hide" name="buyer_region" string="Package Sell Country Code"/> <field optional="hide" name="buyer_region" string="Package Sell Country Code"/>
<field optional="show" name="big_package_no" string="Big Package No"/> <field optional="show" name="big_package_no" string="Big Package No"/>
...@@ -79,6 +80,10 @@ ...@@ -79,6 +80,10 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Ship Package"> <form string="Ship Package">
<header> <header>
<button name="action_package_exception_info" type="object"
string="Add Package Exception Information"
groups="ccs_base.group_clearance_of_customs_manager"/><!-- 添加包裹异常信息 -->
<field name="state" string="Progress Status" widget="statusbar"/> <field name="state" string="Progress Status" widget="statusbar"/>
</header> </header>
<sheet> <sheet>
...@@ -94,6 +99,7 @@ ...@@ -94,6 +99,7 @@
<field name="big_package_id" string="Big Package"/> <field name="big_package_id" string="Big Package"/>
<field name="bl_id" string="Bill of Loading"/> <field name="bl_id" string="Bill of Loading"/>
<field name="next_provider_name" string="Next Provider Name"/> <field name="next_provider_name" string="Next Provider Name"/>
<field name="exception_info_ids" readonly="1" widget="many2many_tags"/>
<field name="process_time" readonly="1"/> <field name="process_time" readonly="1"/>
</group> </group>
...@@ -201,7 +207,33 @@ ...@@ -201,7 +207,33 @@
<field name="tracking_no" string="Search" <field name="tracking_no" string="Search"
filter_domain="['|', ('tracking_no', 'ilike', self), ('trade_no', 'ilike', self)]"/> filter_domain="['|', ('tracking_no', 'ilike', self), ('trade_no', 'ilike', self)]"/>
<separator/> <separator/>
<filter string="Today's ship package"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))
, ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="today_ship"/>
<filter string="Yesterday's ship package"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=1), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')), ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"
name="yesterday_ship"/>
<filter string="Last 7 days ship package"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=7), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_7d"/>
<filter string="This week ship package" name="this_week_ship"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today() + relativedelta(weeks=-1,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),
('create_date', '&lt;', (datetime.datetime.combine(context_today() + relativedelta(days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<filter string="Last week ship package" name="last_week_ship"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today() + relativedelta(weeks=-2,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),
('create_date', '&lt;', (datetime.datetime.combine(context_today() + relativedelta(weeks=-1,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<!-- <filter string="This month ship package"-->
<!-- domain="[('create_date', '>=', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-01 00:00:00'))]"-->
<!-- name="this_month_ship"/>-->
<!-- <filter string=" Last month ship package"-->
<!-- domain="[('create_date','&lt;', (context_today().replace(day=1)).strftime('%Y-%m-%d 00:00:00')),('create_date','&gt;=',(context_today() -relativedelta(months=1)).replace(day=1).strftime('%Y-%m-%d 00:00:00'))]"-->
<!-- name="last_month_ship"/>-->
<filter string="Last 30 days Ship Package"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=30), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_30d"/>
<separator/>
<field name="tracking_no" string="Tracking No."/> <field name="tracking_no" string="Tracking No."/>
<field name="trade_no" string="Trade No"/> <field name="trade_no" string="Trade No"/>
<field name="user_track_note" string="User Tracking Note"/> <field name="user_track_note" string="User Tracking Note"/>
...@@ -290,9 +322,9 @@ ...@@ -290,9 +322,9 @@
<record model="ir.actions.act_window" id="action_cc_ship_package"> <record model="ir.actions.act_window" id="action_cc_ship_package">
<field name="name">Ship Package</field> <field name="name">Ship Package</field>
<field name="res_model">cc.ship.package</field> <field name="res_model">cc.ship.package</field>
<field name="view_mode">tree,form,pivot,graph</field> <field name="view_mode">tree,form,search,pivot,graph</field>
<field name="domain">[]</field> <field name="domain">[]</field>
<field name="context">{}</field> <field name="context">{'search_default_last_30d':1}</field>
<field name="help" type="html"> <field name="help" type="html">
<p class="o_view_nocontent_smiling_face"> <p class="o_view_nocontent_smiling_face">
[Ship Package] Not yet! Click the Create button in the top left corner and the sofa is yours! [Ship Package] Not yet! Click the Create button in the top left corner and the sofa is yours!
...@@ -302,18 +334,20 @@ ...@@ -302,18 +334,20 @@
</field> </field>
</record> </record>
<menuitem parent="" sequence="10" name="Ship Package" id="menu_cc_ship_package" action="action_cc_ship_package"/> <menuitem parent="" sequence="15" name="Ship Package" id="menu_cc_ship_package" action="action_cc_ship_package"/>
<!-- <record id="bl_line_translate_server_action" model="ir.actions.server">--> <record id="ship_package_add_exception_info_server_action" model="ir.actions.server">
<!-- <field name="name">Translate</field>--> <field name="name">Batch Add Package Exception Information</field>
<!-- <field name="model_id" ref="model_cc.ship.package"/>--> <field name="model_id" ref="model_cc_ship_package"/>
<!-- <field name="binding_model_id" ref="model_cc.ship.package"/>--> <field name="binding_model_id" ref="model_cc_ship_package"/>
<!-- <field name="state">code</field>--> <field name="state">code</field>
<!-- <field name="code">--> <field name="binding_view_types">list</field>
<!-- if records:--> <field name="groups_id" eval="[(4, ref('ccs_base.group_clearance_of_customs_manager'))]"/>
<!-- action = records.action_bl_line_translate()--> <field name="code">
<!-- </field>--> if records:
<!-- </record>--> action = records.action_package_exception_info()
</field>
</record>
</odoo> </odoo>
\ No newline at end of file
...@@ -2,14 +2,16 @@ ...@@ -2,14 +2,16 @@
<odoo> <odoo>
<data> <data>
<!-- 隐藏讨论菜单-->
<menuitem id="mail.menu_root_discuss" active="False"/>
<!-- # 增加名称为主数据的,排序99--> <!-- # 增加名称为主数据的,排序99-->
<record id="menu_ccs_base_main" model="ir.ui.menu"> <record id="menu_ccs_base_main" model="ir.ui.menu">
<field name="name">Master Data</field> <field name="name">Master Data</field>
<field name="sequence" eval="99"/> <field name="sequence" eval="20"/>
<field name="web_icon">ccs_base,static/description/icon5.png</field> <field name="web_icon">ccs_base,static/description/icon5.png</field>
</record> </record>
<!-- # 增加一个"客户"action, 仅显示为客户的partner,显示模式为树,表单--> <!-- # 增加一个"客户"action, 仅显示为客户的partner,显示模式为树,表单-->
<record model="ir.actions.act_window" id="action_cc_partner"> <record model="ir.actions.act_window" id="action_cc_partner">
<field name="name">Customers</field> <field name="name">Customers</field>
<field name="res_model">res.partner</field> <field name="res_model">res.partner</field>
...@@ -27,7 +29,7 @@ ...@@ -27,7 +29,7 @@
<!-- # 增加一个"客户"菜单, 与action_cc_partner关联--> <!-- # 增加一个"客户"菜单, 与action_cc_partner关联-->
<menuitem sequence="10" name="Customers" id="menu_cc_partner" action="action_cc_partner" <menuitem sequence="10" name="Customers" id="menu_cc_partner" action="action_cc_partner"
parent="menu_ccs_base_main" /> parent="menu_ccs_base_main"/>
<!-- # 增加一个"供应商"action, 仅显示为供应商的partner,显示模式为树,表单--> <!-- # 增加一个"供应商"action, 仅显示为供应商的partner,显示模式为树,表单-->
<record model="ir.actions.act_window" id="action_cc_is_clearance_company"> <record model="ir.actions.act_window" id="action_cc_is_clearance_company">
...@@ -46,7 +48,8 @@ ...@@ -46,7 +48,8 @@
</record> </record>
<!-- # 增加一个"供应商"菜单, 与action_cc_supplier关联--> <!-- # 增加一个"供应商"菜单, 与action_cc_supplier关联-->
<menuitem sequence="20" name="Clearance Company" id="menu_cc_clearance_company" action="action_cc_is_clearance_company" <menuitem sequence="20" name="Clearance Company" id="menu_cc_clearance_company"
action="action_cc_is_clearance_company"
parent="menu_ccs_base_main"/> parent="menu_ccs_base_main"/>
</data> </data>
</odoo> </odoo>
\ No newline at end of file
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
from . import batch_input_ship_package_statu_wizard from . import batch_input_ship_package_statu_wizard
from . import export_bl_big_package_xlsx_wizard from . import export_bl_big_package_xlsx_wizard
# from . import again_push_wizard from . import associate_pallet_wizard
# from . import parcel_exception_wizard from . import add_exception_info_wizard
# from . import big_bag_pickup_wizard
# from . import batch_push_tiktok
# from . import big_bag_check_wizard
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import models, fields, api, _
from odoo.exceptions import UserError
class AddExceptionInfoWizard(models.TransientModel):
_name = 'add.exception.info.wizard'
_description = 'Add Package Exception Information Wizard'
def get_order(self):
order_id = self._context.get('active_id')
if type(order_id) != list:
order_id = [self._context.get('active_id')]
return self.env[self._context.get('active_name')].browse(order_id)
def get_language(self):
"""
当前用户语言进行默认
:return:
"""
lang = self.env.user.lang
logging.info('lang:%s' % lang)
return lang
action_type = fields.Char(string='Action Type', help='ship package/big package')
big_package_ids = fields.Many2many('cc.big.package', 'exception_wizard_big_package_rel', string='Big Packages')
ship_package_ids = fields.Many2many('cc.ship.package', 'exception_wizard_ship_package_rel', string='Ship Packages')
exception_ids = fields.Many2many('cc.exception.info', 'big_package_add_exception_info_rel',
string='Exception Information',
required=True) # 异常信息(多选)
send_email = fields.Boolean(string='Send Email Notification', default=False) # 发送邮件通知
email_language = fields.Selection([
('zh_CN', 'Chinese'),
('en_US', 'English')
], string='Email Language', default=get_language) # 邮件语言
def create_add_exception_wizard(self, action_type, exception_ids, big_package_ids=[], ship_package_ids=[],
send_email=False, email_language='zh_CN'):
vals = {
'action_type': action_type,
'big_package_ids': [(6, 0, big_package_ids)],
'ship_package_ids': [(6, 0, ship_package_ids)],
'exception_ids': [(6, 0, exception_ids)],
'send_email': send_email,
'email_language': email_language,
}
return self.create(vals)
def confirm(self):
for record in self:
# 更新小包的异常信息
exception_objs = record.exception_ids
package_objs = self.get_order()
if not self._context.get('not_update_ex'):
for package in package_objs:
package.update_exception_info(exception_objs.ids) # 回写小包的异常信息
# 发送邮件通知
if record.send_email:
self.send_email_notification(record, package_objs, exception_objs)
else:
body = _(
'%s at %s manipulated abnormal information, the reason for the abnormality is: %s, not sent %s email') % (
self.env.user.name, fields.Datetime.now(),
'/'.join([exception.reason for exception in exception_objs]),
_('Chinese') if record.email_language == 'zh_CN' else _('English'))
package.message_post(body=body)
def send_email_notification(self, wizard_obj, package_objs, exception_objs):
"""
发送对应语言的邮件
"""
if self.email_language == 'zh_CN':
template_id = self.env.ref('ccs_base.email_template_exception_notification')
else:
template_id = self.env.ref(
'ccs_base.email_template_exception_notification_en') # Assuming you have an English template
if template_id:
email_arr = []
for r in exception_objs:
if r.responsible_email:
email_arr += r.responsible_email.split('\n')
email_to = ','.join(set(email_arr)) # 取 异常信息里的邮箱
logging.info('email_to:%s' % email_to)
default_email_from = self.env["ir.config_parameter"].sudo().get_param("default_email_from")
local_context = {'lang': self.email_language}
mail_id = template_id.with_context(local_context).send_mail(wizard_obj.id, force_send=True,
email_values={
'email_from': default_email_from,
'email_to': email_to
})
mail = self.env['mail.mail'].sudo().browse(mail_id)
for package in package_objs:
# 回写sns %s %s 操作了异常信息,异常原因:%s,%s发送%s邮件
body = _(
'%s at %s manipulated abnormal information, the reason for the abnormality is: %s, %s %s email') % (
self.env.user.name, fields.Datetime.now(),
'/'.join([exception.reason for exception in exception_objs]),
_('Sent Fail') if mail.exists() and mail.state == 'exception' else _('Sent'),
(_('Chinese') if wizard_obj.email_language == 'zh_CN' else _(
'English')) if wizard_obj.send_email else '')
package.message_post(body=body)
else:
raise UserError(_("Email template not found."))
<odoo>
<record id="view_add_exception_info_wizard" model="ir.ui.view">
<field name="name">add.exception.info.wizard.form</field>
<field name="model">add.exception.info.wizard</field>
<field name="arch" type="xml">
<form string="Add Exception Information">
<sheet>
<group>
<field name="big_package_ids" widget="many2many_tags" readonly="1" invisible="1"/>
<field name="ship_package_ids" widget="many2many_tags" readonly="1" invisible="1"/>
<field name="exception_ids" widget="many2many_tags" required="1"/> <!-- 异常信息 -->
<field name="send_email"/> <!-- 发送邮件通知 -->
<field name="email_language"
attrs="{'required':[('send_email','=',True)]}"/> <!-- 邮件语言 -->
</group>
<footer>
<button string="Confirm" type="object" name="confirm" class="btn-primary"/>
<button string="Close" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
</odoo>
\ No newline at end of file
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from odoo import models, fields, api, _
from odoo.exceptions import Warning, ValidationError
class AssociatePalletWizard(models.TransientModel):
_name = 'associate.pallet.wizard'
_description = 'Associate Pallet Wizard'
@api.onchange('usage_date')
def change_usage_date(self):
for item in self:
if item.usage_date:
item.pallet_number = item.get_pallet_number(item.usage_date)
def get_pallet_number(self, usage_date):
"""
生成托盘号 从001开始,如果
:return: 新的托盘号
"""
try:
# 查找大包中最新的托盘号
latest_pallet = self.env['cc.big.package'].search([('pallet_usage_date', '=', str(usage_date))],
order='pallet_number desc', limit=1)
# 生成新的托盘号
if latest_pallet:
new_pallet_number = int(latest_pallet.pallet_number) + 1
else:
new_pallet_number = 1 # 如果没有找到,默认从1开始
return str(new_pallet_number).zfill(3) # 返回格式化的托盘号
except Exception as e:
raise ValidationError(str(e))
usage_date = fields.Date(string='Usage Date', default=fields.Date.today) # 使用日期
pallet_number = fields.Char(string='Pallet Number', required=True) # 托盘号
big_package_numbers = fields.Text(string='Big Package Numbers') # 大包号(可输入多个)
def confirm(self):
for record in self:
if not record.pallet_number.isdigit():
raise ValidationError(_('The pallet number can only be entered as a number!')) # 托盘号只能输入数字!
if record.usage_date > fields.Date.today():
raise ValidationError(_('The usage date cannot be later than the current date!')) # 使用日期不能大于当前日期!
# 处理大包号
big_package_ids = record.big_package_numbers.splitlines()
success_package = []
fail_package = []
for package_number in big_package_ids:
package = self.env['cc.big.package'].search([('big_package_no', '=', package_number)], limit=1)
if package:
success_package.append(package)
else:
fail_package.append(package_number)
if fail_package:
raise ValidationError(_('%s The package does not exist, please check the input information!') % (
'\n'.join(fail_package))) # 不存在该大包,请检查输入信息
if success_package:
for package in success_package:
# 回写大包的托盘号和使用日期
old_pallet_number = package.pallet_number
new_pallet_number = record.pallet_number # 修改的托盘号
old_usage_date = package.pallet_usage_date
# 同一提单,同一托盘号,使用日期必须一致
related_packages = package.bl_id.big_package_ids.filtered(
lambda p: p.pallet_number == new_pallet_number) # 查找对应提单下相同托盘号的所有大包
warning_package_arr = [related_package.big_package_no for related_package in related_packages if
related_package.pallet_usage_date != record.usage_date]
if warning_package_arr:
raise ValidationError(
_('Big Package No :%s ,The same bill of lading, same pallet number, and usage date must be consistent!') % (
'\n'.join(warning_package_arr))) # 大包号关联的同一提单,同一托盘号,使用日期必须一致
package.update_pallet_info(new_pallet_number, record.usage_date)
if old_pallet_number:
# %s %s更改了托盘号,由%s变更为%s,托盘使用日期%s变更为%s
body = _(
'%s at %s changed the pallet number from %s to %s, and the pallet usage date from %s to %s') % (
self.env.user.name, fields.Datetime.now(), old_pallet_number, new_pallet_number,
old_usage_date,
record.usage_date)
else:
# 某人某时关联了托盘xxx,托盘使用日期xxxx
body = _('%s at %s associated tray %s, with a tray usage date of %s') % (
self.env.user.name, fields.Datetime.now(), new_pallet_number, record.usage_date)
package.message_post(body=body)
<odoo>
<record id="view_associate_pallet_wizard" model="ir.ui.view">
<field name="name">associate.pallet.wizard.form</field>
<field name="model">associate.pallet.wizard</field>
<field name="arch" type="xml">
<form string="Associate Pallet">
<sheet>
<group>
<field name="usage_date" required="1"/> <!-- 使用日期 -->
<field name="pallet_number" required="1"/> <!-- 托盘号 -->
<field name="big_package_numbers" required="1"
placeholder="Multiple can be entered, one large package number per line"/> <!-- 大包号 可输入多个,一行一个大包号 -->
</group>
<footer>
<button string="Confirm" type="object" name="confirm" class="btn-primary"/>
<button string="Close" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="action_associate_pallet" model="ir.actions.act_window">
<field name="name">Associate Pallet</field>
<field name="res_model">associate.pallet.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>
\ No newline at end of file
<odoo>
<record id="email_template_exception_notification" model="mail.template">
<field name="name">异常信息邮件</field>
<field name="model_id" ref="model_add_exception_info_wizard"/>
<field name="subject">{{ ('大包异常' if object.action_type == 'big package' else '小包异常') }}</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px;">
您好
<br/>
<!-- 检查 big_package_ids 是否有值 -->
<t t-if="object.big_package_ids">
<t t-foreach="object.big_package_ids" t-as="big_package_id">
<div>包裹:
<t t-esc="big_package_id.big_package_no or ''"/>
</div>
</t>
</t>
<!-- 检查 ship_package_ids 是否有值 -->
<t t-if="object.ship_package_ids">
<t t-foreach="object.ship_package_ids" t-as="ship_package_id">
<div>包裹:
<t t-esc="ship_package_id.logistic_order_no or ''"/>
</div>
</t>
</t>
<div>出现异常,异常原因:
<t t-if="object.exception_ids">
<t t-esc="'/'.join([ex.reason for ex in object.exception_ids])"/>,请知晓。
</t>
<t t-if="not object.exception_ids">
无异常,请知晓。
</t>
</div>
</p>
</div>
</field>
</record>
<record id="email_template_exception_notification_en" model="mail.template">
<field name="name">Exception Notification</field>
<field name="model_id" ref="model_add_exception_info_wizard"/>
<field name="subject">{{ ('Big Package Exception' if object.action_type == 'big package' else 'Ship Package Exception') }}</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px;">
Dear all
<br/>
<!-- 检查 big_package_ids 是否有值 -->
<t t-if="object.big_package_ids">
<t t-foreach="object.big_package_ids" t-as="big_package_id">
<div>Package:
<t t-esc="big_package_id.big_package_no or ''"/>
</div>
</t>
</t>
<!-- 检查 ship_package_ids 是否有值 -->
<t t-if="object.ship_package_ids">
<t t-foreach="object.ship_package_ids" t-as="ship_package_id">
<div>Package:
<t t-esc="ship_package_id.logistic_order_no or ''"/>
</div>
</t>
</t>
<div>Please know that there is an exception and the cause of the exception is
<t t-if="object.exception_ids">
<t t-esc="'/'.join([ex.reason for ex in object.exception_ids])"/>
</t>
<t t-if="not object.exception_ids">
No Exception
</t>
</div>
</p>
</div>
</field>
</record>
</odoo>
\ No newline at end of file
...@@ -293,7 +293,6 @@ class TTApi(http.Controller): ...@@ -293,7 +293,6 @@ class TTApi(http.Controller):
kws.get('master_waybill_no'), kws.get('big_bag_quantity')) kws.get('master_waybill_no'), kws.get('big_bag_quantity'))
request._cr.execute(select_bl_sql) request._cr.execute(select_bl_sql)
exit_bl_obj = request._cr.fetchall() exit_bl_obj = request._cr.fetchall()
logging.info('select_bl_sql:%s,exit_bl_obj:%s' % (select_bl_sql, exit_bl_obj))
if not bl: if not bl:
if declare_type == 'create': if declare_type == 'create':
bl = request.env['cc.bl'].sudo().create(bl_vals) bl = request.env['cc.bl'].sudo().create(bl_vals)
...@@ -307,7 +306,6 @@ class TTApi(http.Controller): ...@@ -307,7 +306,6 @@ class TTApi(http.Controller):
bl.write(bl_vals) bl.write(bl_vals)
if bl and ((declare_type == 'create' and len(exit_bl_obj) <= 0) or ( if bl and ((declare_type == 'create' and len(exit_bl_obj) <= 0) or (
declare_type == 'update' and bl.state == 'draft')): declare_type == 'update' and bl.state == 'draft')):
logging.info('-----update big')
# 生成cc.big.package # 生成cc.big.package
big_bag_list = kws.get('big_bag_list') big_bag_list = kws.get('big_bag_list')
if big_bag_list and len(big_bag_list) > 0: if big_bag_list and len(big_bag_list) > 0:
......
...@@ -6,8 +6,8 @@ msgid "" ...@@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 16.0\n" "Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-16 08:24+0000\n" "POT-Creation-Date: 2025-02-18 02:36+0000\n"
"PO-Revision-Date: 2024-10-16 16:25+0800\n" "PO-Revision-Date: 2025-02-18 10:37+0800\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: zh\n" "Language: zh\n"
...@@ -112,6 +112,11 @@ msgstr "" ...@@ -112,6 +112,11 @@ msgstr ""
msgid "Created on" msgid "Created on"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model:ir.model.fields,help:ccs_connect_tiktok.field_cc_node__interval_minutes
msgid "Default interval time between predecessor nodes in minutes."
msgstr "前置节点之间的默认间隔时间(分钟)。"
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api__display_name #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api__display_name
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__display_name #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__display_name
...@@ -196,6 +201,11 @@ msgstr "操作时间" ...@@ -196,6 +201,11 @@ msgstr "操作时间"
msgid "Operate User" msgid "Operate User"
msgstr "操作人" msgstr "操作人"
#. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_cc_node__interval_minutes
msgid "Predecessor Node Interval (Minutes)"
msgstr "前置节点间隔(分钟)"
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.tree_cc_ship_package_view #: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.tree_cc_ship_package_view
msgid "Progress" msgid "Progress"
...@@ -252,6 +262,7 @@ msgstr "" ...@@ -252,6 +262,7 @@ msgstr ""
#: model:ir.actions.act_window,name:ccs_connect_tiktok.action_ao_tt_api_log #: model:ir.actions.act_window,name:ccs_connect_tiktok.action_ao_tt_api_log
#: model:ir.ui.menu,name:ccs_connect_tiktok.menu_ao_flight_tt_api_log #: model:ir.ui.menu,name:ccs_connect_tiktok.menu_ao_flight_tt_api_log
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.form_ao_tt_api_log_view #: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.form_ao_tt_api_log_view
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.tree_ao_tt_api_log_view #: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.tree_ao_tt_api_log_view
msgid "TIKTOK推送日志" msgid "TIKTOK推送日志"
msgstr "" msgstr ""
...@@ -338,8 +349,14 @@ msgstr "" ...@@ -338,8 +349,14 @@ msgstr ""
msgid "tt推送日志" msgid "tt推送日志"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "上周日志"
msgstr ""
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__big_bag_no #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__big_bag_no
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "业务信息" msgid "业务信息"
msgstr "" msgstr ""
...@@ -348,11 +365,26 @@ msgstr "" ...@@ -348,11 +365,26 @@ msgstr ""
msgid "产生时间" msgid "产生时间"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "今日日志"
msgstr ""
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__data_text #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__data_text
msgid "传输数据" msgid "传输数据"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "分组"
msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "失败"
msgstr ""
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__error_msg #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__error_msg
msgid "失败原因" msgid "失败原因"
...@@ -363,6 +395,11 @@ msgstr "" ...@@ -363,6 +395,11 @@ msgstr ""
msgid "客户" msgid "客户"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "成功"
msgstr ""
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.actions.server,name:ccs_connect_tiktok.action_batch_update_package_status #: model:ir.actions.server,name:ccs_connect_tiktok.action_batch_update_package_status
msgid "批量手动处理小包异常数据" msgid "批量手动处理小包异常数据"
...@@ -388,13 +425,25 @@ msgstr "" ...@@ -388,13 +425,25 @@ msgstr ""
msgid "推出" msgid "推出"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "昨日日志"
msgstr ""
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__success_bl #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__success_bl
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "是否成功" msgid "是否成功"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "本周日志"
msgstr ""
#. module: ccs_connect_tiktok #. module: ccs_connect_tiktok
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__source #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__source
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "类型" msgid "类型"
msgstr "" msgstr ""
...@@ -402,3 +451,13 @@ msgstr "" ...@@ -402,3 +451,13 @@ msgstr ""
#: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__request_id #: model:ir.model.fields,field_description:ccs_connect_tiktok.field_ao_tt_api_log__request_id
msgid "请求id" msgid "请求id"
msgstr "" msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "近30日日志"
msgstr ""
#. module: ccs_connect_tiktok
#: model_terms:ir.ui.view,arch_db:ccs_connect_tiktok.search_ao_tt_api_log_view
msgid "近7日日志"
msgstr ""
import base64
import json
import logging import logging
from datetime import datetime from datetime import datetime
from lxml import etree
import pytz
from odoo import models, fields, api, tools from odoo import models, fields, api, tools
from odoo.exceptions import ValidationError, Warning
# 继承节点对象.增加TK编码 # 继承节点对象.增加TK编码
class CCNode(models.Model): class CCNode(models.Model):
...@@ -14,3 +10,18 @@ class CCNode(models.Model): ...@@ -14,3 +10,18 @@ class CCNode(models.Model):
_inherit = 'cc.node' _inherit = 'cc.node'
tk_code = fields.Char('TK Code', help='TK Code') tk_code = fields.Char('TK Code', help='TK Code')
interval_minutes = fields.Integer('Predecessor Node Interval (Minutes)', default=20,
help='Default interval time between predecessor nodes in minutes.') # 前序节点间隔时间,默认20分钟
def calculate_total_interval(self, next_node):
"""
计算该节点到某个节点直接的间隔时间和
"""
total_interval = 0
predecessor_nodes = self.env['cc.node'].search(
[('node_type', '=', 'package'), ('is_must', '=', True), ('seq', '<=', next_node.seq),
('seq', '>', self.seq)])
for node in predecessor_nodes:
total_interval += node.interval_minutes
logging.info('node:%s,last_node:%s,total_interval:%s' % (self.desc, next_node.desc, total_interval))
return total_interval
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<field name="error_msg"/> <field name="error_msg"/>
<field name="success_bl"/> <field name="success_bl"/>
<field name="request_id"/> <field name="request_id"/>
<field name="create_date" optional="hide"/>
</tree> </tree>
</field> </field>
</record> </record>
...@@ -41,19 +42,66 @@ ...@@ -41,19 +42,66 @@
</field> </field>
</record> </record>
<record model="ir.ui.view" id="search_ao_tt_api_log_view">
<field name="name">search.ao.tt.api.log</field>
<field name="model">ao.tt.api.log</field>
<field name="arch" type="xml">
<search string="TIKTOK推送日志">
<filter string="今日日志"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')), ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="create_date"/>
<filter string="昨日日志"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=1), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')), ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_24h"/>
<filter string="近7日日志"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=7), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"
name="last_7d"/>
<filter string="本周日志" name="this_week_log"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today() + relativedelta(weeks=-1,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),
('create_date', '&lt;', (datetime.datetime.combine(context_today() + relativedelta(days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<filter string="上周日志" name="last_week_log"
domain="[('create_date', '&gt;=', (datetime.datetime.combine(context_today() + relativedelta(weeks=-2,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')),
('create_date', '&lt;', (datetime.datetime.combine(context_today() + relativedelta(weeks=-1,days=1,weekday=0), datetime.time(0,0,0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<!-- <filter string="本月日志" name="this_month_log"-->
<!-- domain="[('create_date','&gt;=', time.strftime('%Y-%m-1 00:00:00')),('create_date','&lt;',(context_today() + relativedelta(months=1)).strftime('%Y-%m-1 00:00:00'))]"/>-->
<!-- <filter string="上月日志" name="last_month_log"-->
<!-- domain="[('create_date','&lt;', time.strftime('%Y-%m-1 00:00:00')),('create_date','&gt;=',(context_today() - relativedelta(months=1)).strftime('%Y-%m-1 00:00:00'))]"/>-->
<filter string="近30日日志" name="last_30d"
domain="[('create_date', '>=', (datetime.datetime.combine(context_today() - datetime.timedelta(days=30), datetime.time(0, 0, 0)).to_utc()).strftime('%Y-%m-%d %H:%M:%S')), ('create_date', '&lt;', (datetime.datetime.combine(context_today(), datetime.time(0, 0, 0)).to_utc() + datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"/>
<separator/>
<field name="big_bag_no"/>
<field name="data_text"/>
<separator/>
<filter name="filter_success_bl" string="成功" domain="[('success_bl','=',True)]"/>
<filter name="filter_not_success_bl" string="失败" domain="[('success_bl','=',False)]"/>
<separator/>
<group expand="0" string="分组">
<filter domain="[]" name="groupby_success_bl" string="是否成功"
context="{'group_by': 'success_bl'}"/>
<filter domain="[]" name="groupby_big_bag_no" string="业务信息"
context="{'group_by': 'big_bag_no'}"/>
<filter domain="[]" name="groupby_source" string="类型"
context="{'group_by': 'source'}"/>
</group>
<searchpanel>
<field icon="fa-users" select="multi" name="source"/>
</searchpanel>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_ao_tt_api_log"> <record model="ir.actions.act_window" id="action_ao_tt_api_log">
<field name="name">TIKTOK推送日志</field> <field name="name">TIKTOK推送日志</field>
<field name="res_model">ao.tt.api.log</field> <field name="res_model">ao.tt.api.log</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form,search</field>
<field name="domain">[]</field> <field name="domain">[]</field>
<field name="context">{}</field> <field name="context">{'search_default_last_30d':1}</field>
</record> </record>
<menuitem <menuitem
id="menu_ao_flight_tt_api_log" id="menu_ao_flight_tt_api_log"
name="TIKTOK推送日志" name="TIKTOK推送日志"
sequence="9" action="action_ao_tt_api_log"/> sequence="21" action="action_ao_tt_api_log"/>
</data> </data>
</odoo> </odoo>
\ No newline at end of file
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
<field name="desc" position="after"> <field name="desc" position="after">
<field name="tk_code"/> <field name="tk_code"/>
</field> </field>
<field name="next_code_ids" position="after">
<field name="interval_minutes"/>
</field>
</field> </field>
</record> </record>
......
...@@ -2,30 +2,27 @@ ...@@ -2,30 +2,27 @@
# 本地 # 本地
db_ip = "127.0.0.1" db_ip = "127.0.0.1"
db_port = "8888" db_port = "8069"
db_name = "hh_ccs_test" db_name = "hhccs_test"
db_user = "admin" db_user = "admin"
db_password = "admin" db_password = "admin"
redis_options = dict( redis_options = dict(
host='127.0.0.1', host='127.0.0.1',
port=6379, port=6379,
# password='topodoo1314',
decode_responses=True,
db=0 db=0
) )
# 测试 # 测试
# db_ip = "121.199.167.133" # db_ip = "121.199.167.133"
# db_port = "8369" # db_port = "8369"
# db_name = "airorder0309" # db_name = "hh_ccs"
# db_user = "admin" # db_user = "admin"
# db_password = "123123" # db_password = "admin"
# #
# redis_options = dict( # redis_options = dict(
# host='172.18.0.6', # host='172.18.0.6',
# port=6379, # port=6379,
# # password='top123',
# decode_responses=True, # decode_responses=True,
# db=3 # db=3
# ) # )
...@@ -44,5 +41,3 @@ redis_options = dict( ...@@ -44,5 +41,3 @@ redis_options = dict(
# decode_responses=True, # decode_responses=True,
# db=3 # db=3
# ) # )
# coding=utf-8 # coding=utf-8
import json import json
import logging import logging
import odoorpc
import redis import redis
import time
import requests import requests
import odoorpc import time
from requests.adapters import HTTPAdapter
from datetime import datetime from datetime import datetime
import config from requests.adapters import HTTPAdapter
import config
# 默认字符gbk # 默认字符gbk
# logging.basicConfig(filename='./push_data_logger.log', level=logging.INFO) logging.basicConfig(filename='./push_data_logger.log', level=logging.INFO)
# 设置文件字符为utf-8 # 设置文件字符为utf-8
logging.basicConfig(handlers=[logging.FileHandler('logs/mail_push.log', 'a', 'utf-8')], # logging.basicConfig(handlers=[logging.FileHandler('logs/mail_push.log', 'a', 'utf-8')],
format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO) # format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
class Order_dispose(object): class Order_dispose(object):
...@@ -29,11 +31,13 @@ class Order_dispose(object): ...@@ -29,11 +31,13 @@ class Order_dispose(object):
try: try:
data = json.loads(data) data = json.loads(data)
logging.info('mail_push_data: %s', data) logging.info('mail_push_data: %s', data)
ship_packages = eval(data['ship_packages']) if data.get('ship_packages') else [] # 小包
action_type = data.get('action_type') # 类型
bl_obj = self.odoo_db.env['cc.bl'] bl_obj = self.odoo_db.env['cc.bl']
bl_record = bl_obj.browse(data['id']) bl_record = bl_obj.browse(data['id'])
# utc_time = datetime.strptime(data['utc_time'], "%Y-%m-%d %H:%M:%S") # utc_time = datetime.strptime(data['utc_time'], "%Y-%m-%d %H:%M:%S")
utc_time = data['utc_time'] utc_time = data.get('utc_time')
bl_record.mail_auto_push(utc_time) bl_record.mail_auto_push(utc_time, ship_packages, action_type)
except Exception as ex: except Exception as ex:
logging.error('mail_auto_push error:%s' % str(ex)) logging.error('mail_auto_push error:%s' % str(ex))
return res_data return res_data
......
# coding=utf-8
import json
import logging
import odoorpc
import redis
import requests
import time
from requests.adapters import HTTPAdapter
import config
# 本地
# 默认字符gbk
# logging.basicConfig(filename='./push_ship_package_state.log', level=logging.INFO)
# 环境?
# 设置文件字符为utf-8
logging.basicConfig(handlers=[logging.FileHandler('logs/push_ship_package_state.log', 'a', 'utf-8')],
format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)
class Order_dispose(object):
def __init__(self):
# rpc连接
self.odoo_db = odoorpc.ODOO(config.db_ip, port=config.db_port)
self.odoo_db.login(config.db_name, config.db_user, config.db_password)
def order_data(self, record_ids):
res_data = []
try:
result = json.loads(record_ids)
ship_package_ids = result['ship_package_ids'] # 小包
bl_id = result['bl_id']
logging.info('push_ship_package_state kw: %s', result)
bl_obj = self.odoo_db.env['cc.bl'].browse(bl_id) # 提单
logging.info('bl_obj:%s' % bl_obj)
logging.info('ship_package_ids:%s' % len(ship_package_ids))
is_ok = bl_obj.package_callback_func(ship_package_ids) # 调用同步包裹状态
logging.info('is_ok:%s' % is_ok)
# 失败的重复推送 重复推2次
for i in range(2):
if not is_ok:
is_ok = bl_obj.package_callback_func(ship_package_ids)
logging.info('push_ship_package_state 重试推送: %d次' % (i + 1))
else:
break
except Exception as ex:
logging.error('push_ship_package_state error:%s' % str(ex))
return res_data
try:
pool = redis.ConnectionPool(**config.redis_options)
r = redis.Redis(connection_pool=pool)
logging.info(u'redis连接成功')
Order_dispose = Order_dispose()
while 1:
try:
result = r.brpop('push_ship_package_state', 0)
data1 = result[1]
response_data = Order_dispose.order_data(data1)
except Exception as e:
logging.error(e)
continue
except Exception as e:
logging.error("登录失败")
logging.error(e)
[program:push_ship_package_state_consumer_1]
process_name=%(program_name)s_%(process_num)02d ; 进程名称
directory = /mnt/extra-addons ; 程序的启动目录
command = /usr/bin/python3 /mnt/extra-addons/push_ship_package_state.py ; 启动命令
autostart = true ; 在 supervisord 启动的时候也自动启动
startsecs = 5 ; 启动 5 秒后没有异常退出,就当作已经正常启动了
autorestart = true ; 程序异常退出后自动重启
startretries = 2 ; 启动失败自动重试次数,默认是 3
user = root ; 用哪个用户启动
numprocs=1 ; 进程数
redirect_stderr = true ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /var/log/supervisor/push_ship_package_state.log
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论