工作中心概述看板视图

This commit is contained in:
gqh
2022-11-16 09:41:34 +08:00
parent ba92f616a0
commit ec9f82f09c
9 changed files with 452 additions and 36 deletions

View File

@@ -220,18 +220,26 @@ class StockRule(models.Model):
for company_id, productions_values in productions_values_by_company.items(): for company_id, productions_values in productions_values_by_company.items():
# create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
'''创建制造订单'''
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create( productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
productions_values) productions_values)
self.env['stock.move'].sudo().create(productions._get_moves_raw_values()) self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
self.env['stock.move'].sudo().create(productions._get_moves_finished_values()) self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
'''
创建工单
'''
productions._create_workorder() productions._create_workorder()
productions.lot_producing_id._get_next_serial(productions.company_id,productions.product_id)
productions.action_generate_serial()
productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \ productions.filtered(lambda p: (not p.orderpoint_id and p.move_raw_ids) or \
( (
p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm() p.move_dest_ids.procure_method != 'make_to_order' and not p.move_raw_ids and not p.workorder_ids)).action_confirm()
for production in productions: for production in productions:
'''
创建制造订单时生成序列号
'''
production.lot_producing_id._get_next_serial(production.company_id, production.product_id)
production.action_generate_serial()
origin_production = production.move_dest_ids and production.move_dest_ids[ origin_production = production.move_dest_ids and production.move_dest_ids[
0].raw_material_production_id or False 0].raw_material_production_id or False
orderpoint = production.orderpoint_id orderpoint = production.orderpoint_id

View File

@@ -10,10 +10,13 @@
""", """,
'category': 'YZ', 'category': 'YZ',
'website': 'https://www.sf.cs.jikimo.com', 'website': 'https://www.sf.cs.jikimo.com',
'depends': ['mrp', 'sf_base', 'hr_holidays'], 'depends': ['mrp', 'sf_base', 'hr_holidays', 'maintenance'],
'data': [ 'data': [
'views/sf_tray_view.xml', 'views/sf_tray_view.xml',
'views/sf_workorder.xml', 'views/sf_workorder.xml',
'views/maintenance_views.xml',
'views/mrp_views.xml',
'views/mrp_workcenter_views.xml',
'report/sf_tray_report.xml' 'report/sf_tray_report.xml'
], ],
'demo': [ 'demo': [

View File

@@ -1,3 +1,3 @@
# -*-coding:utf-8-*- # -*-coding:utf-8-*-
from . import workcenter from . import workcenter
from . import mrp_maintenance

View File

@@ -0,0 +1,184 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from dateutil.relativedelta import relativedelta
from datetime import timedelta, datetime
from collections import defaultdict
from odoo import api, fields, models, _
from odoo.addons.resource.models.resource import Intervals
class MrpWorkcenter(models.Model):
_inherit = "mrp.workcenter"
equipment_ids = fields.One2many(
'maintenance.equipment', 'workcenter_id', string="Maintenance Equipment",
check_company=True)
def action_work_order(self):
if not self.env.context.get('desktop_list_view', False):
action = self.env["ir.actions.actions"]._for_xml_id("sf_route_workcenter.mrp_workorder_action_tablet")
return action
else:
return super(MrpWorkcenter, self).action_work_order()
def _get_unavailability_intervals(self, start_datetime, end_datetime):
res = super(MrpWorkcenter, self)._get_unavailability_intervals(start_datetime, end_datetime)
if not self:
return res
sql = """
SELECT workcenter_id, ARRAY_AGG((schedule_date || '|' || schedule_date + INTERVAL '1h' * duration)) as date_intervals
FROM maintenance_request
LEFT JOIN maintenance_equipment
ON maintenance_request.equipment_id = maintenance_equipment.id
WHERE
schedule_date IS NOT NULL
AND duration IS NOT NULL
AND equipment_id IS NOT NULL
AND maintenance_equipment.workcenter_id IS NOT NULL
AND maintenance_equipment.workcenter_id IN %s
AND (schedule_date, schedule_date + INTERVAL '1h' * duration) OVERLAPS (%s, %s)
GROUP BY maintenance_equipment.workcenter_id;
"""
self.env.cr.execute(sql, [tuple(self.ids), fields.Datetime.to_string(start_datetime.astimezone()), fields.Datetime.to_string(end_datetime.astimezone())])
res_maintenance = defaultdict(list)
for wc_row in self.env.cr.dictfetchall():
res_maintenance[wc_row.get('workcenter_id')] = [
[fields.Datetime.to_datetime(i) for i in intervals.split('|')]
for intervals in wc_row.get('date_intervals')
]
for wc_id in self.ids:
intervals_previous_list = [(s.timestamp(), e.timestamp(), self.env['maintenance.request']) for s, e in res[wc_id]]
intervals_maintenances_list = [(m[0].timestamp(), m[1].timestamp(), self.env['maintenance.request']) for m in res_maintenance[wc_id]]
final_intervals_wc = Intervals(intervals_previous_list + intervals_maintenances_list)
res[wc_id] = [(datetime.fromtimestamp(s), datetime.fromtimestamp(e)) for s, e, _ in final_intervals_wc]
return res
class MaintenanceEquipment(models.Model):
_inherit = "maintenance.equipment"
_check_company_auto = True
expected_mtbf = fields.Integer(string='Expected MTBF', help='Expected Mean Time Between Failure')
mtbf = fields.Integer(compute='_compute_maintenance_request', string='MTBF', help='Mean Time Between Failure, computed based on done corrective maintenances.')
mttr = fields.Integer(compute='_compute_maintenance_request', string='MTTR', help='Mean Time To Repair')
estimated_next_failure = fields.Date(compute='_compute_maintenance_request', string='Estimated time before next failure (in days)', help='Computed as Latest Failure Date + MTBF')
latest_failure_date = fields.Date(compute='_compute_maintenance_request', string='Latest Failure Date')
workcenter_id = fields.Many2one(
'mrp.workcenter', string='Work Center', check_company=True)
@api.depends('effective_date', 'maintenance_ids.stage_id', 'maintenance_ids.close_date', 'maintenance_ids.request_date')
def _compute_maintenance_request(self):
for equipment in self:
maintenance_requests = equipment.maintenance_ids.filtered(lambda x: x.maintenance_type == 'corrective' and x.stage_id.done)
mttr_days = 0
for maintenance in maintenance_requests:
if maintenance.stage_id.done and maintenance.close_date:
mttr_days += (maintenance.close_date - maintenance.request_date).days
equipment.mttr = len(maintenance_requests) and (mttr_days / len(maintenance_requests)) or 0
maintenance = maintenance_requests.sorted(lambda x: x.request_date)
if len(maintenance) >= 1:
equipment.mtbf = (maintenance[-1].request_date - equipment.effective_date).days / len(maintenance)
equipment.latest_failure_date = maintenance and maintenance[-1].request_date or False
if equipment.mtbf:
equipment.estimated_next_failure = equipment.latest_failure_date + relativedelta(days=equipment.mtbf)
else:
equipment.estimated_next_failure = False
def button_mrp_workcenter(self):
self.ensure_one()
return {
'name': _('work centers'),
'view_mode': 'form',
'res_model': 'mrp.workcenter',
'view_id': self.env.ref('mrp.mrp_workcenter_view').id,
'type': 'ir.actions.act_window',
'res_id': self.workcenter_id.id,
'context': {
'default_company_id': self.company_id.id
}
}
class MaintenanceRequest(models.Model):
_inherit = "maintenance.request"
_check_company_auto = True
production_id = fields.Many2one(
'mrp.production', string='Manufacturing Order', check_company=True)
workorder_id = fields.Many2one(
'mrp.workorder', string='Work Order', check_company=True)
production_company_id = fields.Many2one(string='Production Company', related='production_id.company_id')
company_id = fields.Many2one(domain="[('id', '=?', production_company_id)]")
class MrpProduction(models.Model):
_inherit = "mrp.production"
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
request_ids = fields.One2many('maintenance.request', 'production_id')
@api.depends('request_ids')
def _compute_maintenance_count(self):
for production in self:
production.maintenance_count = len(production.request_ids)
def button_maintenance_req(self):
self.ensure_one()
return {
'name': _('New Maintenance Request'),
'view_mode': 'form',
'res_model': 'maintenance.request',
'type': 'ir.actions.act_window',
'context': {
'default_company_id': self.company_id.id,
'default_production_id': self.id,
},
'domain': [('production_id', '=', self.id)],
}
def open_maintenance_request_mo(self):
self.ensure_one()
action = {
'name': _('Maintenance Requests'),
'view_mode': 'kanban,tree,form,pivot,graph,calendar',
'res_model': 'maintenance.request',
'type': 'ir.actions.act_window',
'context': {
'default_company_id': self.company_id.id,
'default_production_id': self.id,
},
'domain': [('production_id', '=', self.id)],
}
if self.maintenance_count == 1:
production = self.env['maintenance.request'].search([('production_id', '=', self.id)])
action['view_mode'] = 'form'
action['res_id'] = production.id
return action
class MrpProductionWorkcenterLine(models.Model):
_inherit = "mrp.workorder"
def button_maintenance_req(self):
self.ensure_one()
return {
'name': _('New Maintenance Request'),
'view_mode': 'form',
'views': [(self.env.ref('mrp_maintenance.maintenance_request_view_form_inherit_mrp').id, 'form')],
'res_model': 'maintenance.request',
'type': 'ir.actions.act_window',
'context': {
'default_company_id': self.company_id.id,
'default_workorder_id': self.id,
'default_production_id': self.production_id.id,
'discard_on_footer_button': True,
},
'target': 'new',
'domain': [('workorder_id', '=', self.id)]
}

View File

@@ -320,7 +320,10 @@ class MrpProduction(models.Model):
i += 1 i += 1
for route in routingworkcenter: for route in routingworkcenter:
if route.is_repeat == True: if route.routing_type == 'CNC加工':
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(k, production, route))
if route.routing_type == '后置三元质量检测':
workorders_values.append( workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(k, production, route)) self.env['mrp.workorder'].json_workorder_str(k, production, route))

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="maintenance_equipment_view_form_inherit_mrp" model="ir.ui.view">
<field name="name">maintenance.equipment.view.form.inherit.mrp</field>
<field name="model">maintenance.equipment</field>
<field name="inherit_id" ref="maintenance.hr_equipment_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="button_mrp_workcenter" type="object" class="oe_stat_button"
icon="fa-cogs" string="Work Center" attrs="{'invisible': [('workcenter_id', '=', False)]}" groups="mrp.group_mrp_routings">
</button>
</xpath>
<xpath expr="//field[@name='location']" position="after">
<field name="workcenter_id" context="{'default_company_id':company_id}" groups="mrp.group_mrp_routings"/>
</xpath>
<xpath expr="//group[@name='maintenance']" position="after">
<group name="statistics">
<label for="expected_mtbf" string="Expected Mean Time Between Failure"/>
<div class="o_row">
<field name="expected_mtbf"/> days
</div>
<label for="mtbf" string="Mean Time Between Failure"/>
<div class="o_row">
<field name="mtbf" /> days
</div>
<label for="estimated_next_failure" string="Estimated Next Failure"/>
<div class="o_row">
<field name="estimated_next_failure" />
</div>
<field name="latest_failure_date" string="Latest Failure" />
<label for="mttr" string="Mean Time To Repair"/>
<div class="o_row">
<field name="mttr" /> days
</div>
</group>
</xpath>
</field>
</record>
<record id="maintenance_request_view_form_inherit_mrp" model="ir.ui.view">
<field name="name">maintenance.request.view.form.inherit.mrp</field>
<field name="model">maintenance.request</field>
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='maintenance_type']" position="after">
<field name="production_company_id" invisible="1"/>
<field name="workorder_id" invisible="1"/>
<field name="production_id" options="{'no_create': True, 'no_open': True}"/>
<field name="workorder_id" attrs="{'invisible': [('production_id', '=', False)]}" options="{'no_create': True, 'no_open': True}" domain="[('production_id', '=', production_id)]" groups="mrp.group_mrp_routings"/>
<!-- <field name="repair_id"/> -->
</xpath>
<xpath expr="//div[hasclass('oe_chatter')]" position="after">
<div invisible="not context.get('discard_on_footer_button', False)">
<footer class="oe_edit_only">
<button special="save" data-hotkey="v" string="Save" class="oe_highlight"/>
<button string="Discard" special="cancel" data-hotkey="z"/>
</footer>
</div>
</xpath>
<field name="equipment_id" position="attributes">
<attribute name="domain">['|', (not workorder_id and 1 or 0, '=', 1), '|', ('workcenter_id', '=', False), ('workcenter_id.order_ids', 'in', workorder_id)]</attribute>
</field>
</field>
</record>
<record id="maintenance_request_view_search_inherit_mrp" model="ir.ui.view">
<field name="name">maintenence.request.view.search.inherit.mrp</field>
<field name="model">maintenance.request</field>
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_search"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='maintenance_team_id']" position="after">
<field name="production_id" string="Operation" filter_domain="['|', ('production_id', 'ilike', self), ('workorder_id', 'ilike', self)]"/>
</xpath>
</field>
</record>
<menuitem
id="maintenance.menu_equipment_form"
name="Equipments"
parent="maintenance.menu_maintenance_title"
groups="maintenance.group_equipment_manager,base.group_user"
sequence="2"/>
<menuitem id="menu_workcenter_tree"
action="mrp.mrp_workcenter_action"
groups="mrp.group_mrp_routings"
parent="maintenance.menu_equipment_form"
sequence="1"/>
<menuitem
id="menu_equipment_dashboard"
name="Machines &amp; Tools"
parent="maintenance.menu_equipment_form"
action="maintenance.hr_equipment_action"
sequence="2"/>
</odoo>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- MRP.WORKCENTER -->
<record id="mrp_workcenter_view_form_inherit_maintenance" model="ir.ui.view">
<field name="name">mrp.workcenter.form.inherit.maintenance</field>
<field name="model">mrp.workcenter</field>
<field name="inherit_id" ref="mrp.mrp_workcenter_view"/>
<field name="arch" type="xml">
<xpath expr="//notebook" position="inside">
<page string="Equipment" name="equipment">
<field name="equipment_ids" widget="many2many">
<tree string="Equipments">
<field name="name"/>
<field name="technician_user_id"/>
<field name="category_id"/>
<field name="mtbf"/>
<field name="mttr"/>
<field name="estimated_next_failure" string="Est. Next Failure"/>
</tree>
</field>
</page>
</xpath>
</field>
</record>
<record id="mrp_workcenter_view_kanban_inherit_maintenance" model="ir.ui.view">
<field name="name">mrp.workcenter.view.kanban.inherit.maintenance</field>
<field name="model">mrp.workcenter</field>
<field name="inherit_id" ref="mrp.mrp_workcenter_kanban"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='plan_order']" position="after">
<div>
<a name="%(maintenance.hr_equipment_request_action)d" type="action">Maintenance</a>
</div>
</xpath>
</field>
</record>
<!-- MRP.PRODUCTION -->
<record id="mrp_production_view_form_inherit_maintenance" model="ir.ui.view">
<field name="name">mrp.production.view.form.inherit.maintenance</field>
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
<field name="arch" type="xml">
<button name="action_cancel" position="before">
<button name="button_maintenance_req" type="object" string="Maintenance Request"/>
</button>
<div name="button_box" position="inside">
<button name="open_maintenance_request_mo" type="object" class="oe_stat_button" icon="fa-wrench" attrs="{'invisible': [('maintenance_count', '=', 0)]}" context="{'search_default_production_id': active_id}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value"><field name="maintenance_count"/></span>
<span class="o_stat_text">Maintenance</span>
</div>
</button>
</div>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,37 @@
<odoo>
<record id="mrp_workcenter_view_kanban_inherit_workorder" model="ir.ui.view">
<field name="name">mrp.workcenter.view.kanban.inherit.mrp.workorder</field>
<field name="model">mrp.workcenter</field>
<field name="inherit_id" ref="mrp.mrp_workcenter_kanban"/>
<field name="arch" type="xml">
<!-- Desktop view -->
<xpath expr="//div[@name='o_wo']" position="inside">
<button class="btn btn-secondary fa fa-desktop" name="action_work_order" type="object" context="{'search_default_ready': 1, 'search_default_progress': 1, 'search_default_pending': 1, 'desktop_list_view': 1, 'search_default_workcenter_id': active_id}" title="Work orders" aria-label="Work orders"/>
</xpath>
</field>
</record>
<!-- override to change the no content image -->
<record id="mrp.action_work_orders" model="ir.actions.act_window">
<field name="help" type="html">
<p class="o_view_nocontent_workorder">
No work orders to do!
</p><p>
Work orders are operations to do as part of a manufacturing order.
Operations are defined in the bill of materials or added in the manufacturing order directly.
</p><p>
Use the table work center control panel to register operations in the shop floor directly.
The tablet provides worksheets for your workers and allow them to scrap products, track time,
launch a maintenance request, perform quality tests, etc.
</p>
</field>
</record>
<menuitem id="menu_mrp_dashboard"
name="工作中心概述"
action="mrp.mrp_workcenter_kanban_action"
groups="mrp.group_mrp_routings"
parent="mrp.menu_mrp_root"
sequence="5"/>
</odoo>

View File

@@ -1,6 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data> <data>
<record model="ir.actions.act_window" id="mrp_workorder_action_tablet">
<field name="name">Work Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.workorder</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')}),
(0, 0, {'view_mode': 'tree', 'view_id': ref('mrp.mrp_production_workorder_tree_editable_view')}) ]"/>
<field name="target">fullscreen</field>
<field name="domain">[('state', 'not in', ['done', 'cancel'])]</field>
<field name="context">{'search_default_workcenter_id': active_id}</field>
<field name="help" type="html">
<p class="o_view_nocontent_workorder">
No work orders to do!
</p><p>
Work orders are operations to do as part of a manufacturing order.
Operations are defined in the bill of materials or added in the manufacturing order directly.
</p><p>
Use the table work center control panel to register operations in the shop floor directly.
The tablet provides worksheets for your workers and allow them to scrap products, track time,
launch a maintenance request, perform quality tests, etc.
</p>
</field>
</record>
<record id="sf_install_the_tray_workorder_form_view" model="ir.ui.view"> <record id="sf_install_the_tray_workorder_form_view" model="ir.ui.view">
<field name="name">装夹工序工单</field> <field name="name">装夹工序工单</field>
<field name="model">mrp.workorder</field> <field name="model">mrp.workorder</field>
@@ -47,97 +73,97 @@
<div>左面:</div> <div>左面:</div>
<div></div> <div></div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X1_axis" string="Lx1"/> <label for="X1_axis" string="x1"/>
<field name='X1_axis' class="o_address_city"/> <field name='X1_axis' class="o_address_city"/>
<label for="Y1_axis" string="Ly1"/> <label for="Y1_axis" string="y1"/>
<field name='Y1_axis' class="o_address_city"/> <field name='Y1_axis' class="o_address_city"/>
<label for="Z1_axis" string="Lz1"/> <label for="Z1_axis" string="z1"/>
<field name='Z1_axis' class="o_address_city"/> <field name='Z1_axis' class="o_address_city"/>
</div> </div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X2_axis" string="Lx2"/> <label for="X2_axis" string="x2"/>
<field name='X2_axis' class="o_address_city"/> <field name='X2_axis' class="o_address_city"/>
<label for="Y2_axis" string="Ly2"/> <label for="Y2_axis" string="y2"/>
<field name='Y2_axis' class="o_address_city"/> <field name='Y2_axis' class="o_address_city"/>
<label for="Z2_axis" string="Lz2"/> <label for="Z2_axis" string="z2"/>
<field name='Z2_axis' class="o_address_city"/> <field name='Z2_axis' class="o_address_city"/>
</div> </div>
<div>前面:</div> <div>前面:</div>
<div></div> <div></div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X3_axis" string="Fx1"/> <label for="X3_axis" string="x1"/>
<field name='X3_axis' class="o_address_city"/> <field name='X3_axis' class="o_address_city"/>
<label for="Y3_axis" string="Fy1"/> <label for="Y3_axis" string="y1"/>
<field name='Y3_axis' class="o_address_city"/> <field name='Y3_axis' class="o_address_city"/>
<label for="Z3_axis" string="Fz1"/> <label for="Z3_axis" string="z1"/>
<field name='Z3_axis' class="o_address_city"/> <field name='Z3_axis' class="o_address_city"/>
</div> </div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X4_axis" string="Fx2"/> <label for="X4_axis" string="x2"/>
<field name='X4_axis' class="o_address_city"/> <field name='X4_axis' class="o_address_city"/>
<label for="Y4_axis" string="Fy2"/> <label for="Y4_axis" string="y2"/>
<field name='Y4_axis' class="o_address_city"/> <field name='Y4_axis' class="o_address_city"/>
<label for="Z4_axis" string="Fz2"/> <label for="Z4_axis" string="z2"/>
<field name='Z4_axis' class="o_address_city"/> <field name='Z4_axis' class="o_address_city"/>
</div> </div>
<div>右面:</div> <div>右面:</div>
<div></div> <div></div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X5_axis" string="Rx1"/> <label for="X5_axis" string="x1"/>
<field name='X5_axis' class="o_address_city"/> <field name='X5_axis' class="o_address_city"/>
<label for="Y5_axis" string="Ry1"/> <label for="Y5_axis" string="y1"/>
<field name='Y5_axis' class="o_address_city"/> <field name='Y5_axis' class="o_address_city"/>
<label for="Z5_axis" string="Rz1"/> <label for="Z5_axis" string="z1"/>
<field name='Z5_axis' class="o_address_city"/> <field name='Z5_axis' class="o_address_city"/>
</div> </div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X6_axis" string="Rx2"/> <label for="X6_axis" string="x2"/>
<field name='X6_axis' class="o_address_city"/> <field name='X6_axis' class="o_address_city"/>
<label for="Y6_axis" string="Ry2"/> <label for="Y6_axis" string="y2"/>
<field name='Y6_axis' class="o_address_city"/> <field name='Y6_axis' class="o_address_city"/>
<label for="Z6_axis" string="Rz2"/> <label for="Z6_axis" string="z2"/>
<field name='Z6_axis' class="o_address_city"/> <field name='Z6_axis' class="o_address_city"/>
</div> </div>
<div>下面:</div> <div>下面:</div>
<div></div> <div></div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X7_axis" string="Bx1"/> <label for="X7_axis" string="x1"/>
<field name='X7_axis' class="o_address_city"/> <field name='X7_axis' class="o_address_city"/>
<label for="Y7_axis" string="By1"/> <label for="Y7_axis" string="y1"/>
<field name='Y7_axis' class="o_address_city"/> <field name='Y7_axis' class="o_address_city"/>
<label for="Z7_axis" string="Bz1"/> <label for="Z7_axis" string="z1"/>
<field name='Z7_axis' class="o_address_city"/> <field name='Z7_axis' class="o_address_city"/>
</div> </div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X8_axis" string="Bx2"/> <label for="X8_axis" string="x2"/>
<field name='X8_axis' class="o_address_city"/> <field name='X8_axis' class="o_address_city"/>
<label for="Y8_axis" string="By2"/> <label for="Y8_axis" string="y2"/>
<field name='Y8_axis' class="o_address_city"/> <field name='Y8_axis' class="o_address_city"/>
<label for="Z8_axis" string="Bz2"/> <label for="Z8_axis" string="z2"/>
<field name='Z8_axis' class="o_address_city"/> <field name='Z8_axis' class="o_address_city"/>
</div> </div>
<div>上面:</div> <div>上面:</div>
<div></div> <div></div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X9_axis" string="Ux1"/> <label for="X9_axis" string="x1"/>
<field name='X9_axis' class="o_address_city"/> <field name='X9_axis' class="o_address_city"/>
<label for="Y9_axis" string="Uy1"/> <label for="Y9_axis" string="y1"/>
<field name='Y9_axis' class="o_address_city"/> <field name='Y9_axis' class="o_address_city"/>
<label for="Z9_axis" string="Uz1"/> <label for="Z9_axis" string="z1"/>
<field name='Z9_axis' class="o_address_city"/> <field name='Z9_axis' class="o_address_city"/>
</div> </div>
<div class="o_address_city"> <div class="o_address_city">
<label for="X10_axis" string="Ux2"/> <label for="X10_axis" string="x2"/>
<field name='X10_axis' class="o_address_city"/> <field name='X10_axis' class="o_address_city"/>
<label for="Y10_axis" string="Uy2"/> <label for="Y10_axis" string="y2"/>
<field name='Y10_axis' class="o_address_city"/> <field name='Y10_axis' class="o_address_city"/>
<label for="Z10_axis" string="Uz2"/> <label for="Z10_axis" string="z2"/>
<field name='Z10_axis' class="o_address_city"/> <field name='Z10_axis' class="o_address_city"/>
</div> </div>
<div class="col-12 col-lg-6 o_setting_box"> <div class="col-12 col-lg-6 o_setting_box">
<button type="object" class="oe_highlight" name="getcenter" string="中心定位" <button type="object" class="oe_highlight" name="getcenter" string="计算定位"
/> />
</div> </div>