提交 132ed07a authored 作者: 伍姿英's avatar 伍姿英

Merge branch 'release/3.7.0'

from . import wizard
from . import models
from . import wizard
from . import controllers
......@@ -45,6 +45,7 @@
'views/cc_history_ship_package_view.xml',
'views/cc_history_package_sync_log_view.xml',
'views/history_tt_api_log.xml',
'views/res_partner_view.xml',
'views/menu_view.xml',
# 'views/cc_customers_declaration_order_view.xml',
'templates/login.xml',
......@@ -62,8 +63,10 @@
'web.assets_backend': [
'ccs_base/static/src/mixins/link_pallet.js',
'ccs_base/static/src/mixins/link_transfer_bl_no.js',
# 'ccs_base/static/src/mixins/create_temu_bl.js',
'ccs_base/static/src/views/big_package_list_controller.js',
'ccs_base/static/src/views/bl_list_controller.js',
# 'ccs_base/static/src/views/temu_bl_list_controller.js',
'ccs_base/static/src/views/list.xml',
],
},
......
差异被折叠。
# 导入odoo
# 导入日志
import base64
import io
import json
import logging
import zipfile
from datetime import timedelta
import pytz
......@@ -636,6 +639,10 @@ class CcBL(models.Model):
}
redis_conn.lpush('history_data_list', json.dumps(vals))
# 新增类型 TK提单/TEMU提单
bl_type = fields.Selection([('tk', 'TK Bill of Loading'), ('temu', 'TEMU Bill of Loading')], string='B/L Type',
default='tk')
is_history = fields.Boolean('历史单据', default=False)
# 提单号
bl_no = fields.Char(string='B/L No', index=True)
......@@ -721,7 +728,8 @@ class CcBL(models.Model):
bl_objs = self.env['cc.bl'].search(
[('state', '=', 'ccing'), ('cc_attachment_ids.file_name', '=', fix_name)])
if len(bl_objs) > 0:
line_objs = bl_objs.cc_attachment_ids.filtered(lambda attach: not attach.file and attach.file_name == fix_name)
line_objs = bl_objs.cc_attachment_ids.filtered(
lambda attach: not attach.file and attach.file_name == fix_name)
if len(line_objs) > 0:
bl_objs = line_objs.mapped('bl_id')
logging.info('cron_get_pod bl_objs:%s,%s' % (len(bl_objs), ','.join([bl.bl_no for bl in bl_objs])))
......@@ -733,6 +741,52 @@ class CcBL(models.Model):
})
wizard_obj.confirm()
def _get_pod_files(self):
fix_name = '尾程交接POD(待大包数量和箱号)'
res = []
for bl in self:
files = self.env['cc.clearance.file'].sudo().search(
[('bl_id', '=', bl.id), ('file_name', '=', fix_name), ('file', '!=', False)])
files = files.filtered(lambda f: f.file not in (False, b'', ''))
if not files:
continue
total = len(files)
idx = 0
for f in files:
idx += 1
base = bl.bl_no or str(bl.id)
ext = 'pdf'
if f.attachment_name and '.' in f.attachment_name:
ext = f.attachment_name.split('.')[-1]
name = f"{base}.{ext}" if total == 1 else f"{base}-{idx}.{ext}"
res.append((name, f.file))
return res
def action_download_pod(self):
files = self._get_pod_files()
if not files:
return {'type': 'ir.actions.act_window_close'}
if len(self) == 1 and len(files) == 1:
name, data_b64 = files[0]
att = self.env['ir.attachment'].sudo().create(
{'name': name, 'datas': data_b64, 'res_model': 'cc.bl', 'res_id': self.id,
'mimetype': 'application/pdf'})
url = f"/web/content/ir.attachment/{att.id}/datas/{att.name}?download=true"
return {'type': 'ir.actions.act_url', 'url': url, 'target': 'self'}
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w', compression=zipfile.ZIP_DEFLATED) as zf:
for name, data_b64 in files:
zf.writestr(name, base64.b64decode(data_b64))
datas = base64.b64encode(buf.getvalue())
zip_name = 'POD.zip'
if len(self) == 1:
zip_name = f"{self.bl_no or self.id}.zip"
att = self.env['ir.attachment'].sudo().create(
{'name': zip_name, 'datas': datas, 'res_model': 'cc.bl', 'res_id': (self.id if len(self) == 1 else self[0].id),
'mimetype': 'application/zip'})
url = f"/web/content/ir.attachment/{att.id}/datas/{att.name}?download=true"
return {'type': 'ir.actions.act_url', 'url': url, 'target': 'self'}
# 增加一个can_cancel的方法,用于检查提单当前是否可以取消,返回True表示可以取消, False表示不可以取消,同时返回取消的原因
def check_cancel(self):
if self.is_cancel:
......@@ -774,8 +828,25 @@ class CcBL(models.Model):
bl.bl_ship_package_qty = len(ship_package_ids)
bl.bl_total_qty = len(bl.good_ids.filtered(lambda good: not good.is_cancel))
def get_default_partner(self):
"""
获取默认的客户
:return:
"""
print(self._context)
type = self._context.get('default_bl_type', 'tk')
partner_ids = self.env['res.partner'].get_type_partner(type)
if partner_ids:
return partner_ids[0]
return False
def get_customer_domain(self):
type = self._context.get('default_bl_type', 'tk')
return [('platform_type', '=', type)]
# 所属客户
customer_id = fields.Many2one('res.partner', string='Customer')
customer_id = fields.Many2one('res.partner', string='Customer', index=True, default=get_default_partner,
domain=lambda self: self.get_customer_domain())
# 大包明细
big_package_ids = fields.One2many('cc.big.package', 'bl_id', string='Big Packages')
......@@ -1173,10 +1244,40 @@ class CcBL(models.Model):
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'batch.get.pod.info.wizard',
'context': {'active_id': self.ids},
'context': {'active_id': self.ids, 'default_action_type': '获取尾程POD信息'},
'views': [[self.env.ref('ccs_base.view_batch_get_pod_info_wizard_form').id, "form"]],
'target': 'new',
}
def action_create_temu_bl(self):
"""
创建temu提单
"""
return {
'name': _('Create TEMU Bill of Loading'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'batch.get.pod.info.wizard',
'views': [[self.env.ref('ccs_base.view_batch_create_and_get_pod_info_wizard_form').id, "form"]],
'context': {'active_id': self.ids, 'default_action_type': '创建temu提单'},
'target': 'new'
}
def action_batch_download_pod(self):
"""
将选中的提单以提单号命名下载尾程交接POD文件,若文件有多个则以提单-1/-2进行命名下载,若选择多个提单,则将所有文件打包成zip,zip命名则以POD进行命名
"""
# 检查是否有选中的提单
if not self:
raise UserError(_('Please select at least one bill of loading.'))
# 检查是否有尾程交接POD文件
fix_name = '尾程交接POD(待大包数量和箱号)'
has_files = self.env['cc.clearance.file'].search_count(
[('bl_id', 'in', self.ids), ('file_name', '=', fix_name), ('file', '!=', False)])
if not has_files:
raise UserError(_('Please configure the tail-end handover POD file of the bill of loading first.'))
return self.action_download_pod()
# 增加一个清关进度的业务对象,继承自models.Model, 用于管理业务数据.业务数据包括提单号、清关节点(业务对象)、进度日期、进度描述、更新人
class CcProgress(models.Model):
......
from odoo import models, fields, api, _
# 导入日志
import logging
from odoo.exceptions import UserError
from odoo import models, fields
# 获取日志
_logger = logging.getLogger(__name__)
......@@ -17,3 +15,18 @@ class ResPartner(models.Model):
is_customer = fields.Boolean(string='Is Customer', default=False)
# 是否是清关公司
is_clearance_company = fields.Boolean(string='Is Clearance Company', default=False)
# 新增类型:TK平台/TEMU平台。用英文表示
platform_type = fields.Selection([
('tk', 'TK Platform'),
('temu', 'TEMU Platform'),
], string='Platform Type', default='tk')
def get_type_partner(self, type='tk'):
"""
获取默认的TEMU平台客户
:return:
"""
partner_ids = self.env['res.partner'].search([('platform_type', '=', type)])
if partner_ids:
return partner_ids[0]
return False
......@@ -67,7 +67,7 @@ access_cc_big_package_ccs_base.group_clearance_of_customs_manager,cc_big_package
access_cc_clearance_file_base.group_user,cc_clearance_file base.group_user,ccs_base.model_cc_clearance_file,base.group_user,1,0,0,0
access_cc_clearance_file_base.group_erp_manager,cc_clearance_file base.group_erp_manager,ccs_base.model_cc_clearance_file,base.group_erp_manager,1,1,1,1
access_cc_clearance_file_ccs_base.group_clearance_of_customs_manager,cc_clearance_file ccs_base.group_clearance_of_customs_manager,ccs_base.model_cc_clearance_file,ccs_base.group_clearance_of_customs_manager,1,1,1,1
access_cc_clearance_file_ccs_base.group_clearance_of_customs_user,cc_clearance_file ccs_base.group_clearance_of_customs_user,ccs_base.model_cc_clearance_file,ccs_base.group_clearance_of_customs_user,1,0,0,0
access_cc_clearance_file_ccs_base.group_clearance_of_customs_user,cc_clearance_file ccs_base.group_clearance_of_customs_user,ccs_base.model_cc_clearance_file,ccs_base.group_clearance_of_customs_user,1,1,1,1
order_state_change_rule_group_user,order_state_change_rule_group_user,ccs_base.model_order_state_change_rule,base.group_user,1,1,1,1
......
/** @odoo-module */
import {useService} from '@web/core/utils/hooks';
const {useRef, useEffect, useState} = owl;
export const TemuBlCreateMixin = {
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");
},
async onCreateTemuBlClick() {
// 点击按钮弹出创建temu提单的向导
const records = this.model.root.selection;
const recordIds = records.map((a) => a.resId);
const action = await this.orm.call('cc.bl', 'action_create_temu_bl', [recordIds]);
this.actionService.doAction(action);
},
};
......@@ -23,4 +23,12 @@ export const LinkTransferBlNo = {
this.actionService.doAction(action);
},
async onCreateTemuBlClick() {
// 点击按钮弹出创建temu提单的向导
const records = this.model.root.selection;
const recordIds = records.map((a) => a.resId);
const action = await this.orm.call('cc.bl', 'action_create_temu_bl', [recordIds]);
this.actionService.doAction(action);
},
};
......@@ -13,7 +13,7 @@ const {onWillStart} = owl;
export class BigPackageListController extends ListController {
setup() {
super.setup();
console.log('----------引用成功')
console.log('----------big_package_list_controller引用成功')
this.orm = useService('orm');
this.actionService = useService('action');
this.rpc = useService("rpc");
......@@ -26,12 +26,17 @@ export class BigPackageListController extends ListController {
});
}
displayLink() {
console.log('ccs flag:' + this.isBigPackage && this.is_link)
// 是大包的对象以及有清关清理的权限才显示按钮
return this.isBigPackage && this.is_link;
}
displayCreateTemuBl (){
return false;
}
displayTransferBlNo() {
// 大包页面永远不显示“关联转单号”按钮
return false;
......
......@@ -13,16 +13,49 @@ const {onWillStart} = owl;
export class BlListController extends ListController {
setup() {
super.setup();
console.log('----------引用成功')
console.log('----------bl_list_controller引用成功')
this.orm = useService('orm');
this.actionService = useService('action');
this.rpc = useService("rpc");
this.user = useService("user");
this.isBl = this.model.rootParams.resModel === "cc.bl";
this.isTemuBl=false;
if (this.isBl) {
const d = this.props.domain;
// #输出d类型
console.log('d类型:' + typeof d)
console.log('d:' + d)
const containsTk = (x) => {
if (x === 'temu') {
return true;
}
if (Array.isArray(x)) {
for (const el of x) {
if (containsTk(el)) {
return true;
}
}
return false;
}
if (x && typeof x === 'object') {
for (const k in x) {
if (containsTk(x[k])) {
return true;
}
}
return false;
}
return false;
};
this.isTemuBl = !!containsTk(d);
}
console.log('ccs isBl:' + this.isBl)
console.log('ccs isTemuBl:' + this.isTemuBl)
onWillStart(async () => {
this.can_link_transfer_bl_no = await this.user.hasGroup("ccs_base.group_clearance_of_customs_user");
console.log('ccs can_link_transfer_bl_no:' + this.can_link_transfer_bl_no)
this.is_user = await this.user.hasGroup("ccs_base.group_clearance_of_customs_user");
console.log('ccs is_user:' + this.is_user)
});
}
......@@ -31,6 +64,12 @@ export class BlListController extends ListController {
return false;
}
displayCreateTemuBl() {
console.log('ccs flag:' + this.isTemuBl && this.is_user)
// 是temu提单的对象以及有清关用户的权限才显示按钮
return this.isTemuBl && this.is_user;
}
displayTransferBlNo() {
console.log('ccs flag:' + this.isBl && this.can_link_transfer_bl_no)
// 是提单的对象以及有清关用户的权限才显示按钮
......
......@@ -12,5 +12,10 @@
Link Transfer B/L No
</button>
</xpath>
<xpath expr="//button[hasclass('o_list_button_add')]" position="after">
<button t-if="displayCreateTemuBl()" type="button" class="d-none d-md-inline o_button_create_temu_bl btn btn-primary mx-1" t-on-click.prevent="onCreateTemuBlClick">
Batch Create B/L
</button>
</xpath>
</t>
</templates>
/** @odoo-module */
import {TemuBlCreateMixin} from '../mixins/create_temu_bl';
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 TemuBlListController extends ListController {
setup() {
super.setup();
console.log('----------temu_bl_list_controller引用成功')
this.orm = useService('orm');
this.actionService = useService('action');
this.rpc = useService("rpc");
this.user = useService("user");
this.isTemuBl = this.model.rootParams.resModel === "cc.bl";
console.log('ccs isTemuBl:' + this.isTemuBl)
onWillStart(async () => {
this.is_user = await this.user.hasGroup("ccs_base.group_clearance_of_customs_user");
console.log('ccs is_user:' + this.is_user)
});
}
displayCreateTemuBl() {
console.log('ccs flag:' + this.isTemuBl && this.is_user)
// 是temu提单的对象以及有清关用户的权限才显示按钮
return this.isTemuBl && this.is_user;
}
displayLink() {
return false;
}
displayTransferBlNo() {
// 大包页面永远不显示“关联转单号”按钮
return false;
}
}
patch(TemuBlListController.prototype, 'temu_bl_list_controller_create', TemuBlCreateMixin);
registry.category('views').add('cc_temu_bl_tree', {
...listView,
buttonTemplate: 'ccs_base.ListButtons',
Controller: TemuBlListController
});
\ No newline at end of file
......@@ -14,22 +14,6 @@
<field name="web_icon">ccs_base,static/description/icon5.png</field>
</record>
<!-- # 增加一个"客户"action, 仅显示为客户的partner,显示模式为树,表单-->
<record model="ir.actions.act_window" id="action_cc_partner">
<field name="name">Customers</field>
<field name="res_model">res.partner</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('is_customer', '=', True)]</field>
<field name="context">{'default_is_customer': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
[Customers] Not yet! Click the Create button in the top left corner and the sofa is yours!
</p>
<p>
</p>
</field>
</record>
<!-- # 增加一个"客户"菜单, 与action_cc_partner关联-->
<menuitem sequence="10" name="Customers" id="menu_cc_partner" action="action_cc_partner"
parent="menu_ccs_base_main"/>
......@@ -47,23 +31,6 @@
<menuitem parent="menu_ccs_base_main" sequence="99" name="CC Node" id="menu_cc_node" action="action_cc_node"/>
<!-- # 增加一个"供应商"action, 仅显示为供应商的partner,显示模式为树,表单-->
<record model="ir.actions.act_window" id="action_cc_is_clearance_company">
<field name="name">Clearance Company</field>
<field name="res_model">res.partner</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('is_clearance_company', '=', True)]</field>
<field name="context">{'default_is_clearance_company': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
[Clearance Company] Not yet! Click the Create button in the top left corner and the sofa is yours!
</p>
<p>
</p>
</field>
</record>
<!-- # 增加一个"供应商"菜单, 与action_cc_supplier关联-->
<menuitem sequence="20" name="Clearance Company" id="menu_cc_clearance_company"
action="action_cc_is_clearance_company"
......@@ -86,7 +53,11 @@
action="action_history_tt_api_log"
groups="ccs_base.group_clearance_of_customs_user,ccs_base.group_clearance_of_customs_manager"/>
<menuitem parent="" sequence="10" name="Bill of Loading" id="menu_cc_bl" action="action_cc_bl"
<menuitem parent="" sequence="10" name="TK Bill of Loading" id="menu_cc_bl" action="action_cc_bl"
groups="ccs_base.group_clearance_of_customs_user,ccs_base.group_clearance_of_customs_manager"/>
<!-- TEMU提单 -->
<menuitem parent="" sequence="11" name="TEMU Bill of Loading" id="menu_temu_cc_bl" action="action_temu_bl"
groups="ccs_base.group_clearance_of_customs_user,ccs_base.group_clearance_of_customs_manager"/>
<menuitem parent="" sequence="13" name="Big Package" id="menu_cc_big_package" action="action_cc_big_package"
......
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="view_partner_form" model="ir.ui.view">
<field name="name">view_partner_form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='vat']" position="after">
<field name="platform_type" />
</xpath>
</field>
</record>
<record id="view_partner_tree" model="ir.ui.view">
<field name="name">view_partner_tree</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='email']" position="after">
<field name="platform_type" />
</xpath>
</field>
</record>
<record id="view_res_partner_filter" model="ir.ui.view">
<field name="name">view_res_partner_filter</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='group_country']" position="after">
<filter name="group_platform_type" context="{'group_by': 'platform_type'}"/>
</xpath>
</field>
</record>
<!-- # 增加一个"客户"action, 仅显示为客户的partner,显示模式为树,表单-->
<record model="ir.actions.act_window" id="action_cc_partner">
<field name="name">Customers</field>
<field name="res_model">res.partner</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('is_customer', '=', True)]</field>
<field name="context">{'default_is_customer': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
[Customers] Not yet! Click the Create button in the top left corner and the sofa is yours!
</p>
<p>
</p>
</field>
</record>
<!-- # 增加一个"供应商"action, 仅显示为供应商的partner,显示模式为树,表单-->
<record model="ir.actions.act_window" id="action_cc_is_clearance_company">
<field name="name">Clearance Company</field>
<field name="res_model">res.partner</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('is_clearance_company', '=', True)]</field>
<field name="context">{'default_is_clearance_company': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
[Clearance Company] Not yet! Click the Create button in the top left corner and the sofa is yours!
</p>
<p>
</p>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
......@@ -13,8 +13,8 @@
<group>
<!-- attrs="{'invisible': [('pdf_file', '!=', False)]}" -->
<field name="remove_specified_text" readonly="1" widget="boolean_toggle"/>
<field name="skip_ocr_direct_ai" readonly="0" widget="boolean_toggle"
attrs="{'invisible': [('pdf_file', '!=', False)]}"/>
<field name="skip_ocr_direct_ai" invisible="1" widget="boolean_toggle"/>
<field name="action_type" invisible="1"/>
</group>
<group attrs="{'invisible': ['|', ('pdf_file', '=', False), ('show_error_message', '=', False)]}">
<field name="sync_successful_processed" widget="boolean_toggle"/>
......@@ -71,6 +71,77 @@
</field>
</record>
<!-- Batch Create and Get POD Info Wizard Form View 批量创建并获取POD信息向导表单视图 -->
<record id="view_batch_create_and_get_pod_info_wizard_form" model="ir.ui.view">
<field name="name">batch.create.and.get.pod.info.wizard.form</field>
<field name="model">batch.get.pod.info.wizard</field>
<field name="arch" type="xml">
<form string="Batch Create and Get POD Info"> <!-- 批量创建并获取POD信息 -->
<sheet>
<group>
<group>
<field name="partner_id" options="{'no_create':True}"
domain="[('is_customer', '=', True), ('platform_type', '=', 'temu')]"
attrs="{'invisible': [('action_type', '!=', '创建temu提单')]}"/>
<!-- 请输入提单号,可输入多个,一行一个 -->
<field name="bl_numbers"
placeholder="Please enter the bill of lading numbers. Multiple entries are allowed, one per line"
attrs="{'required': [('action_type', '=', '创建temu提单')],'invisible': [('action_type', '!=', '创建temu提单')]}"/>
</group>
<group>
<field name="get_last_mile_pod"
attrs="{'invisible': [('action_type', '!=', '创建temu提单')]}"/>
<field name="remove_specified_text" readonly="1"
attrs="{'invisible': [('get_last_mile_pod', '=', False)]}"
widget="boolean_toggle"/>
<field name="skip_ocr_direct_ai" invisible="1" widget="boolean_toggle"/>
<field name="action_type" invisible="1"/>
</group>
</group>
<group attrs="{'invisible': ['|', ('pdf_file', '=', False), ('show_error_message', '=', False)]}">
<field name="generate_successful_processed" widget="boolean_toggle"/>
</group>
<div class="alert alert-info" role="alert">
<strong>Description:</strong> <!-- 说明: -->
<ul>
<li>
<strong>Get Last Mile POD:</strong>
Generate a last mile POD (Proof of Delivery) attachment information, including
big package quantities and container numbers
</li> <!-- 获取尾程POD:生成一条尾程交接POD(待大包数量和箱号)的附件信息 -->
<li attrs="{'invisible': [('get_last_mile_pod', '=', False)]}">
<strong>Remove Specified Text:</strong>
Remove specified text (AGN, UCLINK LOGISITICS LTD) from PDF files
</li> <!-- 涂抹指定文字:对PDF文件中的指定文字进行涂抹处理 -->
</ul>
</div>
<div class="alert alert-danger" role="alert"
attrs="{'invisible': [('show_error_message', '=', False)]}">
<field name="show_error_message"/>
</div>
<div>
<field name="pdf_file" filename="pdf_filename" widget="pdf_viewer" readonly="1"
attrs="{'invisible': [('pdf_file', '=', False)]}"/>
</div>
<footer>
<!-- 预览按钮:处理PDF并显示合并后的文件 -->
<button string="Preview" type="object" name="action_preview" class="btn-primary"
attrs="{'invisible': ['|',('pdf_file', '!=', False),('get_last_mile_pod','=',False)]}"/>
<!-- 确认按钮:使用已处理的文件数据进行回写 -->
<!-- 如果有失败的文件(show_error_message不为空),需要勾选generate_successful_processed才显示;如果全部成功,直接显示 -->
<button string="Confirm" type="object" name="confirm" class="btn-primary"
attrs="{'invisible': [('get_last_mile_pod','=',True)]}"/>
<button string="Confirm" type="object" name="confirm" class="btn-primary"
attrs="{'invisible': ['|', ('pdf_file', '=', False), '&amp;', ('show_error_message', '!=', False), ('generate_successful_processed', '=', False)]}"/>
<button string="Close" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<!-- Batch Get POD Info Wizard Action 批量获取POD信息向导动作 -->
<record id="action_batch_get_pod_info_wizard" model="ir.actions.act_window">
<field name="name">Batch Get POD Info</field> <!-- 批量获取POD信息 -->
......
......@@ -30,8 +30,8 @@
'company': 'Cybrosys Techno Solutions',
'maintainer': 'Cybrosys Techno Solutions',
'website': "http://www.cybrosys.com",
'depends': ['base', 'sale_management'],
'data': ['views/sale_order_views.xml'],
'depends': ['base'],
'data': [],
'assets': {
'web.assets_backend': [
'many2many_attachment_preview/static/src/js/attachment_preview.js',
......
......@@ -19,4 +19,4 @@
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from . import sale_order
# from . import sale_order
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论