1、优化工单扫描绑定托盘的验证条件,只有在工单已完成时不能再扫描绑定托盘;2、优化中控的刀具组接口,改为传输功能刀具清单的刀具组数据;3、优化功能刀具组装单模型的刀柄信息,删除刀柄货位字段,添加刀柄Rfid字段,根据货位带出刀柄信息改为根据序列号带出;5、优化功能刀具组装单弹窗,删除刀柄货位字段添加刀柄Rfid字段,删除刀柄的扫货位录入信息的代码;夹头货位改为非必填;添加组装后刀具组字段,添加根据所选的功能刀具名称,自动带出功能刀具的类型、刀具组、直径、刀尖R角、最大寿命值、总长度、伸出长、避空长信息,且可修改;6、优化调整功能刀具组装单弹窗的布局;

This commit is contained in:
yuxianghui
2024-04-11 15:11:50 +08:00
parent 7f6444cc89
commit 010fbb23b0
6 changed files with 106 additions and 102 deletions

View File

@@ -830,9 +830,9 @@ class SfWorkOrderBarcodes(models.Model):
# raise UserError('该托盘已绑定工件,请先解除绑定!!!') # raise UserError('该托盘已绑定工件,请先解除绑定!!!')
if workorder: if workorder:
if workorder.routing_type == '装夹预调': if workorder.routing_type == '装夹预调':
if workorder.state in ['progress', 'done']: if workorder.state in ['done']:
work_state = {'progress': '进行中', 'done': '已完工'} work_state = {'done': '已完工'}
raise UserError('该工单%s不能重新绑定托盘' % work_state.get(workorder.state)) raise UserError('装夹%s请勿重复扫码' % work_state.get(workorder.state))
lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)]) lots = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
if lots: if lots:
for lot in lots: for lot in lots:

View File

@@ -22,14 +22,14 @@ class Manufacturing_Connect(http.Controller):
ret = json.loads(datas) ret = json.loads(datas)
# ret = json.loads(ret['result']) # ret = json.loads(ret['result'])
logging.info('DeviceId:%s' % ret) logging.info('DeviceId:%s' % ret)
functional_tools = request.env['sf.functional.cutting.tool.entity'].sudo().search([]) functional_tools = request.env['sf.tool.inventory'].sudo().search([])
res = {'Succeed': True, 'Datas': []} res = {'Succeed': True, 'Datas': []}
if functional_tools: if functional_tools:
for item in functional_tools: for item in functional_tools:
res['Datas'].append({ res['Datas'].append({
'GroupName': item.tool_groups_id.name, 'GroupName': item.tool_groups_id.name,
'ToolId': item.code, 'ToolId': item.functional_cutting_tool_model_id.name,
'ToolName': item.name 'ToolName': item.name
}) })
except Exception as e: except Exception as e:

View File

@@ -473,26 +473,25 @@ class FunctionalToolAssembly(models.Model):
item.pad_product_id = False item.pad_product_id = False
# ==============刀柄型号============== # ==============刀柄型号==============
handle_freight_barcode = fields.Char('刀柄货位') handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_handle_product_id', store=True)
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', compute='_compute_handle_product_id', store=True) handle_code_id = fields.Many2one('stock.lot', '刀柄序列号')
handle_product_id = fields.Many2one('product.product', string='刀柄名称', compute='_compute_handle_product_id', handle_product_id = fields.Many2one('product.product', string='刀柄名称', compute='_compute_handle_product_id',
store=True) store=True)
cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号', cutting_tool_cutterhandle_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀柄型号',
related='handle_code_id.product_id.cutting_tool_model_id') related='handle_product_id.cutting_tool_model_id')
handle_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀柄规格', handle_specification_id = fields.Many2one('sf.tool.materials.basic.parameters', string='刀柄规格',
related='handle_code_id.product_id.specification_id') related='handle_product_id.specification_id')
sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', related='handle_code_id.product_id.brand_id') sf_tool_brand_id_5 = fields.Many2one('sf.machine.brand', '刀柄品牌', related='handle_product_id.brand_id')
@api.depends('handle_freight_barcode') @api.depends('handle_code_id')
def _compute_handle_product_id(self): def _compute_handle_product_id(self):
for item in self: for item in self:
location = self.env['sf.shelf.location'].sudo().search([('barcode', '=', item.handle_freight_barcode)]) if item.handle_code_id:
if location: item.handle_product_id = item.handle_code_id.product_id.id
item.handle_code_id = location.product_sn_id.id item.handle_freight_rfid = item.handle_code_id.rfid
item.handle_product_id = location.product_id.id
else: else:
item.handle_code_id = False
item.handle_product_id = False item.handle_product_id = False
item.handle_freight_rfid = False
# ==============夹头型号============== # ==============夹头型号==============
chuck_freight_barcode = fields.Char('夹头货位') chuck_freight_barcode = fields.Char('夹头货位')

View File

@@ -589,14 +589,14 @@
</group> </group>
</group> </group>
<group> <group>
<group col="1" attrs="{'invisible': [('handle_freight_barcode', '=', False)]}"> <group col="1" attrs="{'invisible': [('handle_code_id', '=', False)]}">
<div> <div>
<separator string="刀柄:" style="font-size: 13px;"/> <separator string="刀柄:" style="font-size: 13px;"/>
</div> </div>
<group> <group>
<field name="handle_freight_barcode" string="货位"/>
<field name="handle_code_id" string="序列号" placeholder="请选择" <field name="handle_code_id" string="序列号" placeholder="请选择"
options="{'no_create': True, 'no_quick_create': True}"/> options="{'no_create': True, 'no_quick_create': True}"/>
<field name="handle_freight_rfid" string="Rfid"/>
<field name="handle_product_id" string="名称"/> <field name="handle_product_id" string="名称"/>
<field name="cutting_tool_cutterhandle_model_id" string="型号"/> <field name="cutting_tool_cutterhandle_model_id" string="型号"/>
<field name="handle_specification_id" string="规格"/> <field name="handle_specification_id" string="规格"/>

View File

@@ -296,7 +296,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
self.pad_product_id = False self.pad_product_id = False
# ================刀柄型号=============== # ================刀柄型号===============
handle_freight_barcode = fields.Char('刀柄货位', required=True) handle_freight_rfid = fields.Char('刀柄Rfid', compute='_compute_rfid')
handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True, handle_code_id = fields.Many2one('stock.lot', '刀柄序列号', required=True,
domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'), domain=[('product_id.cutting_tool_material_id.name', '=', '刀柄'),
('tool_material_status', '=', '可用')]) ('tool_material_status', '=', '可用')])
@@ -316,7 +316,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
self.pad_product_id = False self.pad_product_id = False
# =================夹头型号============== # =================夹头型号==============
chuck_freight_barcode = fields.Char('夹头货位', required=True) chuck_freight_barcode = fields.Char('夹头货位')
chuck_product_id = fields.Many2one('product.product', string='夹头名称', compute='_compute_chuck_product_id', chuck_product_id = fields.Many2one('product.product', string='夹头名称', compute='_compute_chuck_product_id',
store=True) store=True)
cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号', cutting_tool_cutterhead_model_id = fields.Many2one('sf.cutting_tool.standard.library', string='夹头型号',
@@ -345,11 +345,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
for lot_id in lot_ids: for lot_id in lot_ids:
if lot_id.quant_ids[-1].location_id.name in '刀具房': if lot_id.quant_ids[-1].location_id.name in '刀具房':
record.handle_code_id = lot_id.id record.handle_code_id = lot_id.id
location = self.env['sf.shelf.location'].sudo().search(
[('product_sn_id', '=', lot_id.id)])
if not location:
raise ValidationError('该刀柄未入库到库位,请先入库!!!')
record.handle_freight_barcode = location.barcode
elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置': elif lot_id.quant_ids[-1].location_id.name == '刀具组装位置':
raise ValidationError('该刀柄已使用,请重新扫描!!!') raise ValidationError('该刀柄已使用,请重新扫描!!!')
else: else:
@@ -360,11 +355,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
material_name = location.product_id.cutting_tool_material_id.name material_name = location.product_id.cutting_tool_material_id.name
if material_name == '夹头': if material_name == '夹头':
record.chuck_freight_barcode = barcode record.chuck_freight_barcode = barcode
elif material_name == '刀柄':
record.handle_freight_barcode = barcode
location = self.env['sf.shelf.location'].sudo().search(
[('barcode', '=', barcode)])
record.handle_code_id = location.product_sn_id.id
elif material_name == '整体式刀具': elif material_name == '整体式刀具':
record.integral_freight_barcode = barcode record.integral_freight_barcode = barcode
record.blade_freight_barcode = '' record.blade_freight_barcode = ''
@@ -391,8 +381,10 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
for item in self: for item in self:
if item: if item:
item.rfid = item.handle_code_id.rfid item.rfid = item.handle_code_id.rfid
item.handle_freight_rfid = item.handle_code_id.rfid
else: else:
item.rfid = None item.rfid = None
item.handle_freight_rfid = None
# 组装功能刀具参数信息 # 组装功能刀具参数信息
after_name_id = fields.Many2one('sf.tool.inventory', string='功能刀具名称', required=True) after_name_id = fields.Many2one('sf.tool.inventory', string='功能刀具名称', required=True)
@@ -401,8 +393,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
tool_code = fields.Char(string='功能刀具编码', compute='_compute_tool_code') tool_code = fields.Char(string='功能刀具编码', compute='_compute_tool_code')
after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name', store=True) after_assembly_functional_tool_name = fields.Char(string='组装后功能刀具名称', compute='_compute_name', store=True)
after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model', after_assembly_functional_tool_type_id = fields.Many2one('sf.functional.cutting.tool.model',
string='组装后功能刀具类型', string='组装后功能刀具类型')
compute='_compute_after_assembly_functional_tool_type_id')
after_assembly_functional_tool_diameter = fields.Integer(string='组装后功能刀具直径(mm)') after_assembly_functional_tool_diameter = fields.Integer(string='组装后功能刀具直径(mm)')
after_assembly_knife_tip_r_angle = fields.Float(string='组装后刀尖R角(mm)') after_assembly_knife_tip_r_angle = fields.Float(string='组装后刀尖R角(mm)')
after_assembly_new_former = fields.Selection([('0', ''), ('1', '')], string='组装后新/旧', default='0') after_assembly_new_former = fields.Selection([('0', ''), ('1', '')], string='组装后新/旧', default='0')
@@ -421,6 +412,23 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
after_assembly_effective_length = fields.Float(string='组装后有效长(mm)') after_assembly_effective_length = fields.Float(string='组装后有效长(mm)')
L_D_number = fields.Float(string='L/D值(mm)', compute='_compute_l_d_number') L_D_number = fields.Float(string='L/D值(mm)', compute='_compute_l_d_number')
hiding_length = fields.Float(string='避空长(mm)') hiding_length = fields.Float(string='避空长(mm)')
after_tool_groups_id = fields.Many2one('sf.tool.groups', string='组装后刀具组')
@api.onchange('after_name_id')
def _onchange_number(self):
for item in self:
if item.after_name_id:
item.after_assembly_functional_tool_diameter = item.after_name_id.diameter
item.after_assembly_knife_tip_r_angle = item.after_name_id.angle
item.after_assembly_max_lifetime_value = item.after_name_id.life_span
item.after_assembly_tool_loading_length = item.after_name_id.tool_length
item.after_assembly_functional_tool_length = item.after_name_id.extension
item.hiding_length = item.after_name_id.blade_length
item.after_assembly_functional_tool_type_id = item.after_name_id.functional_cutting_tool_model_id.id
item.after_tool_groups_id = item.after_name_id.tool_groups_id.id
else:
item.after_assembly_functional_tool_type_id = item.functional_tool_type_id
item.after_tool_groups_id = item.tool_groups_id.id
# functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=False) # functional_tool_cutting_type = fields.Char(string='功能刀具切削类型', readonly=False)
# res_partner_id = fields.Many2one('res.partner', '智能工厂', domain="[('is_factory', '=', True)]") # res_partner_id = fields.Many2one('res.partner', '智能工厂', domain="[('is_factory', '=', True)]")
@@ -489,14 +497,6 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
else: else:
obj.after_assembly_knife_tip_r_angle = 0 obj.after_assembly_knife_tip_r_angle = 0
@api.depends('functional_tool_type_id')
def _compute_after_assembly_functional_tool_type_id(self):
for obj in self:
if obj.functional_tool_type_id:
obj.after_assembly_functional_tool_type_id = obj.functional_tool_type_id
else:
obj.after_assembly_functional_tool_type_id = None
@api.depends('hiding_length', 'after_assembly_functional_tool_diameter') @api.depends('hiding_length', 'after_assembly_functional_tool_diameter')
def _compute_l_d_number(self): def _compute_l_d_number(self):
for record in self: for record in self:
@@ -567,7 +567,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
self.env['sf.real.time.distribution.of.functional.tools'].create_or_edit_safety_stock({ self.env['sf.real.time.distribution.of.functional.tools'].create_or_edit_safety_stock({
'functional_name_id': self.after_name_id.id, 'functional_name_id': self.after_name_id.id,
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id, 'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,
'tool_groups_id': self.tool_groups_id.id, 'tool_groups_id': self.after_tool_groups_id.id,
'diameter': self.after_assembly_functional_tool_diameter, 'diameter': self.after_assembly_functional_tool_diameter,
'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle, 'knife_tip_r_angle': self.after_assembly_knife_tip_r_angle,
'coarse_middle_thin': self.after_assembly_coarse_middle_thin, 'coarse_middle_thin': self.after_assembly_coarse_middle_thin,
@@ -607,12 +607,12 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'barcode_id': stock_lot.id, 'barcode_id': stock_lot.id,
'code': self.tool_code, 'code': self.tool_code,
'rfid': self.rfid, 'rfid': self.rfid,
'tool_groups_id': self.tool_groups_id.id, 'tool_groups_id': self.after_tool_groups_id.id,
'integral_freight_barcode': self.integral_freight_barcode, 'integral_freight_barcode': self.integral_freight_barcode,
'blade_freight_barcode': self.blade_freight_barcode, 'blade_freight_barcode': self.blade_freight_barcode,
'bar_freight_barcode': self.bar_freight_barcode, 'bar_freight_barcode': self.bar_freight_barcode,
'pad_freight_barcode': self.pad_freight_barcode, 'pad_freight_barcode': self.pad_freight_barcode,
'handle_freight_barcode': self.handle_freight_barcode, 'handle_code_id': self.handle_code_id.id,
'chuck_freight_barcode': self.chuck_freight_barcode, 'chuck_freight_barcode': self.chuck_freight_barcode,
'after_assembly_functional_tool_name': self.after_assembly_functional_tool_name, 'after_assembly_functional_tool_name': self.after_assembly_functional_tool_name,
@@ -645,7 +645,7 @@ class FunctionalToolAssemblyOrder(models.TransientModel):
'code': self.tool_code, 'code': self.tool_code,
'name': self.after_assembly_functional_tool_name, 'name': self.after_assembly_functional_tool_name,
'rfid': self.rfid, 'rfid': self.rfid,
'tool_groups_id': self.tool_groups_id.id, 'tool_groups_id': self.after_tool_groups_id.id,
'functional_tool_name_id': functional_tool_assembly_id.id, 'functional_tool_name_id': functional_tool_assembly_id.id,
'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id, 'sf_cutting_tool_type_id': self.after_assembly_functional_tool_type_id.id,
'cutting_tool_integral_model_id': self.integral_product_id.id, 'cutting_tool_integral_model_id': self.integral_product_id.id,
@@ -707,7 +707,7 @@ class StockPicking(models.Model):
'code': obj.tool_code, 'code': obj.tool_code,
'rfid': obj.rfid, 'rfid': obj.rfid,
'functional_tool_name': obj.after_assembly_functional_tool_name, 'functional_tool_name': obj.after_assembly_functional_tool_name,
'tool_groups_id': obj.tool_groups_id.id 'tool_groups_id': obj.after_tool_groups_id.id
}) })
# 将刀具组装入库单的状态更改为就绪 # 将刀具组装入库单的状态更改为就绪
picking_id.action_confirm() picking_id.action_confirm()
@@ -840,7 +840,7 @@ class StockLot(models.Model):
'code': '' if not obj else obj.tool_code, 'code': '' if not obj else obj.tool_code,
'rfid': '' if not obj else obj.rfid, 'rfid': '' if not obj else obj.rfid,
'functional_tool_name': '' if not obj else obj.after_assembly_functional_tool_name, 'functional_tool_name': '' if not obj else obj.after_assembly_functional_tool_name,
'tool_groups_id': False if not obj else obj.tool_groups_id.id 'tool_groups_id': False if not obj else obj.after_tool_groups_id.id
}) })
return stock_move_id, stock_move_line_id return stock_move_id, stock_move_line_id

View File

@@ -200,6 +200,31 @@
</group> </group>
<group string="组装物料信息" col="1"> <group string="组装物料信息" col="1">
<field name="_barcode_scanned" widget="barcode_handler"/> <field name="_barcode_scanned" widget="barcode_handler"/>
<group col="1">
<div>
<separator string="刀柄:" style="font-size: 13px;"/>
</div>
<group>
<group>
<field name="handle_code_id" string="序列号" placeholder="请选择"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
<group>
<field name="handle_freight_rfid" string="Rfid"/>
</group>
</group>
<group col="2">
<group>
<field name="handle_product_id" string="名称"/>
<field name="handle_specification_id" string="规格"/>
</group>
<group>
<field name="cutting_tool_cutterhandle_model_id" string="型号"/>
<field name="sf_tool_brand_id_5" string="品牌"/>
</group>
</group>
</group>
<group col="1" <group col="1"
attrs="{'invisible': ['|','|',('blade_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}"> attrs="{'invisible': ['|','|',('blade_freight_barcode', '!=', False),('bar_freight_barcode', '!=', False),('pad_freight_barcode', '!=', False)]}">
<div> <div>
@@ -283,33 +308,6 @@
</group> </group>
</group> </group>
</group> </group>
<group col="1">
<div>
<separator string="刀柄:" style="font-size: 13px;"/>
</div>
<group>
<group>
<group>
<field name="handle_freight_barcode" string="货位"/>
</group>
<group>
<field name="handle_code_id" string="序列号" placeholder="请选择"
class="custom_required"
options="{'no_create': True, 'no_quick_create': True}"/>
</group>
</group>
</group>
<group col="2">
<group>
<field name="handle_product_id" string="名称"/>
<field name="handle_specification_id" string="规格"/>
</group>
<group>
<field name="cutting_tool_cutterhandle_model_id" string="型号"/>
<field name="sf_tool_brand_id_5" string="品牌"/>
</group>
</group>
</group>
<group col="1"> <group col="1">
<div> <div>
<separator string="夹头:" style="font-size: 13px;"/> <separator string="夹头:" style="font-size: 13px;"/>
@@ -334,37 +332,44 @@
<group string="组装参数信息"> <group string="组装参数信息">
<group> <group>
<field name="barcode_id" invisible="True"/> <group>
<field name="tool_code" readonly="True"/> <field name="barcode_id" invisible="True"/>
<field name="rfid" placeholder="请输入rfid码" class="custom_required"/> <field name="tool_code" readonly="True"/>
<field name="after_name_id" string="功能刀具名称"/> <field name="rfid" class="custom_required"/>
<field name="after_assembly_functional_tool_name" string="功能刀具名称" invisible="1"/> <field name="after_name_id" string="功能刀具名称" placeholder="请选择功能刀具名称"/>
<field name="after_assembly_functional_tool_type_id" string="功能刀具类型" <field name="after_assembly_functional_tool_name" string="功能刀具名称" invisible="1"/>
options="{'no_create': True, 'no_quick_create': True}"/> <field name="after_assembly_functional_tool_type_id" string="功能刀具类型"
<field name="tool_groups_id"/> options="{'no_create': True, 'no_quick_create': True}"/>
<field name="after_assembly_functional_tool_diameter" string="刀具直径(mm)" <field name="after_tool_groups_id"/>
class="custom_required"/> <field name="after_assembly_functional_tool_diameter" string="刀具直径(mm)"
<field name="after_assembly_knife_tip_r_angle" string="刀尖R角(mm)" class="custom_required"/>
class="custom_required"/> <field name="after_assembly_knife_tip_r_angle" string="刀尖R角(mm)"
<field name="after_assembly_new_former" string="新/旧"/> class="custom_required"/>
<field name="cut_time" attrs="{'invisible': [('after_assembly_new_former','=','0')]}"/> <field name="after_assembly_new_former" string="新/旧"/>
<field name="cut_length" attrs="{'invisible': [('after_assembly_new_former','=','0')]}"/> <field name="cut_time" attrs="{'invisible': [('after_assembly_new_former','=','0')]}"/>
<field name="cut_number" attrs="{'invisible': [('after_assembly_new_former','=','0')]}"/> <field name="cut_length"
attrs="{'invisible': [('after_assembly_new_former','=','0')]}"/>
<field name="cut_number"
attrs="{'invisible': [('after_assembly_new_former','=','0')]}"/>
</group>
</group> </group>
<group> <group>
<field name="after_assembly_whether_standard_knife" string="是否标准刀"/> <group>
<field name="after_assembly_coarse_middle_thin" string="粗/中/精"/> <field name="after_assembly_whether_standard_knife" string="是否标准刀"/>
<field name="after_assembly_max_lifetime_value" string="最大寿命值(min)" <field name="after_assembly_coarse_middle_thin" string="粗/中/精"/>
class="custom_required"/> <field name="after_assembly_max_lifetime_value" string="最大寿命值(min)"
<field name="after_assembly_alarm_value" string="报警值(min)" class="custom_required"/> class="custom_required"/>
<field name="after_assembly_used_value" string="已使用值(min)"/> <field name="after_assembly_alarm_value" string="报警值(min)" class="custom_required"/>
<field name="after_assembly_tool_loading_length" string="总长度(mm)" <field name="after_assembly_used_value" string="已使用值(min)"/>
class="custom_required"/> <field name="after_assembly_tool_loading_length" string="总长度(mm)"
<field name="after_assembly_functional_tool_length" string="伸出长(mm)" class="custom_required"/>
class="custom_required"/> <field name="after_assembly_functional_tool_length" string="伸出长(mm)"
<field name="after_assembly_effective_length" string="有效长(mm)" class="custom_required"/> class="custom_required"/>
<field name="hiding_length" class="custom_required"/> <field name="after_assembly_effective_length" string="有效长(mm)"
<field name="L_D_number"/> class="custom_required"/>
<field name="hiding_length" class="custom_required"/>
<field name="L_D_number"/>
</group>
</group> </group>
</group> </group>
</sheet> </sheet>