shipment equipments
This commit is contained in:
parent
c4151da4f2
commit
9e73d4ec09
@ -1,6 +1,6 @@
|
|||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
from . import (address, diary, party, product, purchase, sale,
|
from . import (address, diary, party, product, purchase, sale,
|
||||||
equipment, configuration_equipment, maintenance, subscription, exceptions)
|
equipment, configuration_equipment, maintenance, move, subscription, exceptions)
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
Pool.register(
|
Pool.register(
|
||||||
@ -12,6 +12,7 @@ def register():
|
|||||||
purchase.Purchase,
|
purchase.Purchase,
|
||||||
purchase.Line,
|
purchase.Line,
|
||||||
sale.Sale,
|
sale.Sale,
|
||||||
|
sale.SaleLine,
|
||||||
sale.CreateSubscriptionStart,
|
sale.CreateSubscriptionStart,
|
||||||
equipment.OpticalEquipment,
|
equipment.OpticalEquipment,
|
||||||
equipment.EquipmentMaintenance,
|
equipment.EquipmentMaintenance,
|
||||||
@ -19,11 +20,11 @@ def register():
|
|||||||
maintenance.Maintenance,
|
maintenance.Maintenance,
|
||||||
maintenance.MaintenanceActivity,
|
maintenance.MaintenanceActivity,
|
||||||
maintenance.MaintenanceLine,
|
maintenance.MaintenanceLine,
|
||||||
|
move.Move,
|
||||||
|
move.ShipmentOut,
|
||||||
subscription.Subscription,
|
subscription.Subscription,
|
||||||
subscription.SubscriptionEquipment,
|
subscription.SubscriptionEquipment,
|
||||||
#subscription.CreateContractInvoiceStart,
|
|
||||||
module='optical_equipment', type_='model')
|
module='optical_equipment', type_='model')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
sale.CreateSubscription,
|
sale.CreateSubscription,
|
||||||
#subscription.CreateContractInvoice,
|
|
||||||
module='optical_equipment', type_='wizard')
|
module='optical_equipment', type_='wizard')
|
||||||
|
24
equipment.py
24
equipment.py
@ -104,6 +104,10 @@ class OpticalEquipment(DeactivableMixin, Workflow, ModelSQL, ModelView):
|
|||||||
purchase_origin = fields.Reference("Purchase Origin", selection='get_origin',select=True,
|
purchase_origin = fields.Reference("Purchase Origin", selection='get_origin',select=True,
|
||||||
states={'readonly': True})
|
states={'readonly': True})
|
||||||
|
|
||||||
|
sale_destination = fields.Reference("Sale Destination", selection='get_destination',select=True,
|
||||||
|
states={'readonly': True})
|
||||||
|
|
||||||
|
|
||||||
del _states_serial, _states, _depends
|
del _states_serial, _states, _depends
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -129,6 +133,24 @@ class OpticalEquipment(DeactivableMixin, Workflow, ModelSQL, ModelView):
|
|||||||
|
|
||||||
return [(None, '')] + [(m, get_name(m)) for m in models]
|
return [(None, '')] + [(m, get_name(m)) for m in models]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_destination(cls):
|
||||||
|
'Return list of Model names for origin Reference'
|
||||||
|
pool = Pool()
|
||||||
|
Sale = pool.get('sale.line')
|
||||||
|
|
||||||
|
return [Sale.__name__]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_destination(cls):
|
||||||
|
Model = Pool().get('ir.model')
|
||||||
|
get_name = Model.get_name
|
||||||
|
models = cls._get_destination()
|
||||||
|
|
||||||
|
return [(None, '')] + [(m, get_name(m)) for m in models]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
@ -142,7 +164,7 @@ class OpticalEquipment(DeactivableMixin, Workflow, ModelSQL, ModelView):
|
|||||||
# 'draft': {
|
# 'draft': {
|
||||||
# 'invisible': Eval('state') == 'draft'},
|
# 'invisible': Eval('state') == 'draft'},
|
||||||
'registred': {
|
'registred': {
|
||||||
'invisible': Eval('state').in_(['registred', 'contrated'])}}
|
'invisible': Eval('state').in_(['registred', 'uncontrated', 'contrated'])}}
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
53
move.py
Normal file
53
move.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
from trytond.model import fields
|
||||||
|
from trytond.pool import Pool, PoolMeta
|
||||||
|
|
||||||
|
class Move(metaclass=PoolMeta):
|
||||||
|
"Stock Move"
|
||||||
|
__name__ = "stock.move"
|
||||||
|
|
||||||
|
serial = fields.Char('Serial')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ShipmentOut(metaclass=PoolMeta):
|
||||||
|
"Customer Shipment"
|
||||||
|
__name__ = 'stock.shipment.out'
|
||||||
|
|
||||||
|
def _get_inventory_move(self, move):
|
||||||
|
'Return inventory move for the outgoing move if necessary'
|
||||||
|
pool = Pool()
|
||||||
|
Move = pool.get('stock.move')
|
||||||
|
Uom = pool.get('product.uom')
|
||||||
|
quantity = move.quantity
|
||||||
|
|
||||||
|
for inventory_move in self.inventory_moves:
|
||||||
|
if (inventory_move.origin == move
|
||||||
|
and inventory_move.state != 'cancelled'):
|
||||||
|
quantity -= Uom.compute_qty(
|
||||||
|
inventory_move.uom, inventory_move.quantity, move.uom)
|
||||||
|
quantity = move.uom.round(quantity)
|
||||||
|
|
||||||
|
if quantity <= 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
inventory_move = Move(
|
||||||
|
from_location=self.warehouse_storage,
|
||||||
|
to_location=move.from_location,
|
||||||
|
product=move.product,
|
||||||
|
serial=move.serial,
|
||||||
|
uom=move.uom,
|
||||||
|
quantity=quantity,
|
||||||
|
shipment=self,
|
||||||
|
planned_date=move.planned_date,
|
||||||
|
company=move.company,
|
||||||
|
origin=move,
|
||||||
|
state='staging' if move.state == 'staging' else 'draft',
|
||||||
|
)
|
||||||
|
|
||||||
|
if inventory_move.on_change_with_unit_price_required():
|
||||||
|
|
||||||
|
inventory_move.unit_price = move.unit_price
|
||||||
|
|
||||||
|
inventory_move.currency = move.currency
|
||||||
|
|
||||||
|
return inventory_move
|
14
move.xml
Normal file
14
move.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tryton>
|
||||||
|
<record model="ir.ui.view" id="move_view_list_shipment">
|
||||||
|
<field name="model">stock.move</field>
|
||||||
|
<field name="inherit" ref="stock.move_view_list_shipment"/>
|
||||||
|
<field name="name">move_list_shipment</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="move_view_form">
|
||||||
|
<field name="model">stock.move</field>
|
||||||
|
<field name="inherit" ref="stock.move_view_form"/>
|
||||||
|
<field name="name">move_form</field>
|
||||||
|
</record>
|
||||||
|
</tryton>
|
146
sale.py
146
sale.py
@ -1,7 +1,7 @@
|
|||||||
from trytond.pool import Pool, PoolMeta
|
from trytond.pool import Pool, PoolMeta
|
||||||
from trytond.model import ModelView, ModelSQL, fields
|
from trytond.model import ModelView, ModelSQL, fields
|
||||||
from trytond.modules.currency.fields import Monetary
|
from trytond.modules.currency.fields import Monetary
|
||||||
from trytond.pyson import Eval, Bool, If
|
from trytond.pyson import Eval, Bool, If, Get
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from trytond.modules.product import price_digits
|
from trytond.modules.product import price_digits
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
@ -18,6 +18,7 @@ class Sale(metaclass=PoolMeta):
|
|||||||
'Sale'
|
'Sale'
|
||||||
__name__ = 'sale.sale'
|
__name__ = 'sale.sale'
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ModelView.button
|
@ModelView.button
|
||||||
@Workflow.transition('confirmed')
|
@Workflow.transition('confirmed')
|
||||||
@ -39,6 +40,8 @@ class Sale(metaclass=PoolMeta):
|
|||||||
equipment.propietary=sale.party.id
|
equipment.propietary=sale.party.id
|
||||||
equipment.propietary_address=sale.shipment_address.id
|
equipment.propietary_address=sale.shipment_address.id
|
||||||
equipment.state="uncontrated"
|
equipment.state="uncontrated"
|
||||||
|
equipment.sale_destination = line
|
||||||
|
equipment.maintenance_frequency = "6" if sale.party.client_type == "ips" else "12"
|
||||||
equipment.save()
|
equipment.save()
|
||||||
|
|
||||||
with Transaction().set_context(
|
with Transaction().set_context(
|
||||||
@ -46,6 +49,15 @@ class Sale(metaclass=PoolMeta):
|
|||||||
queue_scheduled_at=config.sale_process_after):
|
queue_scheduled_at=config.sale_process_after):
|
||||||
cls.__queue__.process(sales)
|
cls.__queue__.process(sales)
|
||||||
|
|
||||||
|
# @classmethod
|
||||||
|
# def get_equipments_in_lines(self, sales, equipments):
|
||||||
|
# #raise UserError(str(equipments))
|
||||||
|
# equipments = []
|
||||||
|
# for line in sales[0].lines:
|
||||||
|
# if line.product_equipment:
|
||||||
|
# equipments.append(line.equipment.id)
|
||||||
|
|
||||||
|
# return equipments
|
||||||
|
|
||||||
class SaleLine(metaclass=PoolMeta):
|
class SaleLine(metaclass=PoolMeta):
|
||||||
'SaleLine'
|
'SaleLine'
|
||||||
@ -56,10 +68,22 @@ class SaleLine(metaclass=PoolMeta):
|
|||||||
domain=[('state', '=', 'registred'),
|
domain=[('state', '=', 'registred'),
|
||||||
('product','=', Eval('product'))],
|
('product','=', Eval('product'))],
|
||||||
states={'invisible': If(~Eval('product_equipment'), True)},)
|
states={'invisible': If(~Eval('product_equipment'), True)},)
|
||||||
|
equipment_serial = fields.Char('Serial',states={'readonly': True,
|
||||||
|
'invisible': If(~Eval('product_equipment'), True)},
|
||||||
|
depends=['product_equipment'])
|
||||||
address_equipment = fields.Many2One('party.address', "Direccion")
|
address_equipment = fields.Many2One('party.address', "Direccion")
|
||||||
unit_digits = fields.Function(fields.Integer('Unit Digits'),
|
unit_digits = fields.Function(fields.Integer('Unit Digits'),
|
||||||
'on_change_with_unit_digits')
|
'on_change_with_unit_digits')
|
||||||
|
|
||||||
|
@fields.depends('product_equipment','equipment')
|
||||||
|
def get_serial_equipment(self):
|
||||||
|
if self.product_equipment:
|
||||||
|
raise UserError(str(self.equipment.serial))
|
||||||
|
return self.equipment.serial
|
||||||
|
else:
|
||||||
|
raise UserError(str(self.equipment.serial))
|
||||||
|
return None
|
||||||
|
|
||||||
def on_change_with_unit_digits(self, name=None):
|
def on_change_with_unit_digits(self, name=None):
|
||||||
if self.unit:
|
if self.unit:
|
||||||
return self.unit.digits
|
return self.unit.digits
|
||||||
@ -70,6 +94,7 @@ class SaleLine(metaclass=PoolMeta):
|
|||||||
if self.equipment:
|
if self.equipment:
|
||||||
self.product = self.equipment.product.id
|
self.product = self.equipment.product.id
|
||||||
self.address_equipment = self.sale.shipment_address.id
|
self.address_equipment = self.sale.shipment_address.id
|
||||||
|
self.equipment_serial = self.equipment.serial
|
||||||
self.on_change_product()
|
self.on_change_product()
|
||||||
else:
|
else:
|
||||||
self.address_equipment = None
|
self.address_equipment = None
|
||||||
@ -78,6 +103,7 @@ class SaleLine(metaclass=PoolMeta):
|
|||||||
self.quantity = None
|
self.quantity = None
|
||||||
self.unit_price = None
|
self.unit_price = None
|
||||||
self.amount = None
|
self.amount = None
|
||||||
|
self.equipment_serial = None
|
||||||
self.on_change_product()
|
self.on_change_product()
|
||||||
|
|
||||||
@fields.depends('product_equipment', methods=['on_change_equipment'])
|
@fields.depends('product_equipment', methods=['on_change_equipment'])
|
||||||
@ -98,45 +124,105 @@ class SaleLine(metaclass=PoolMeta):
|
|||||||
self.unit = None
|
self.unit = None
|
||||||
return
|
return
|
||||||
|
|
||||||
party = None
|
else:
|
||||||
|
party = None
|
||||||
|
|
||||||
if self.sale and self.sale.party:
|
if self.sale and self.sale.party:
|
||||||
self.product_equipment = False
|
self.product_equipment = False
|
||||||
party = self.sale.party
|
party = self.sale.party
|
||||||
|
|
||||||
|
# Set taxes before unit_price to have taxes in context of sale price
|
||||||
|
taxes = []
|
||||||
|
pattern = self._get_tax_rule_pattern()
|
||||||
|
for tax in self.product.customer_taxes_used:
|
||||||
|
if party and party.customer_tax_rule:
|
||||||
|
tax_ids = party.customer_tax_rule.apply(tax, pattern)
|
||||||
|
if tax_ids:
|
||||||
|
taxes.extend(tax_ids)
|
||||||
|
continue
|
||||||
|
taxes.append(tax.id)
|
||||||
|
|
||||||
# Set taxes before unit_price to have taxes in context of sale price
|
|
||||||
taxes = []
|
|
||||||
pattern = self._get_tax_rule_pattern()
|
|
||||||
for tax in self.product.customer_taxes_used:
|
|
||||||
if party and party.customer_tax_rule:
|
if party and party.customer_tax_rule:
|
||||||
tax_ids = party.customer_tax_rule.apply(tax, pattern)
|
tax_ids = party.customer_tax_rule.apply(None, pattern)
|
||||||
if tax_ids:
|
if tax_ids:
|
||||||
taxes.extend(tax_ids)
|
taxes.extend(tax_ids)
|
||||||
continue
|
self.taxes = taxes
|
||||||
taxes.append(tax.id)
|
|
||||||
|
|
||||||
if party and party.customer_tax_rule:
|
category = self.product.sale_uom.category
|
||||||
tax_ids = party.customer_tax_rule.apply(None, pattern)
|
if not self.unit or self.unit.category != category:
|
||||||
if tax_ids:
|
self.unit = self.product.sale_uom
|
||||||
taxes.extend(tax_ids)
|
self.unit_digits = self.product.sale_uom.digits
|
||||||
self.taxes = taxes
|
|
||||||
|
|
||||||
category = self.product.sale_uom.category
|
with Transaction().set_context(self._get_context_sale_price()):
|
||||||
if not self.unit or self.unit.category != category:
|
self.unit_price = Product.get_sale_price([self.product],
|
||||||
self.unit = self.product.sale_uom
|
self.quantity or 0)[self.product.id]
|
||||||
self.unit_digits = self.product.sale_uom.digits
|
|
||||||
|
|
||||||
with Transaction().set_context(self._get_context_sale_price()):
|
if self.unit_price:
|
||||||
self.unit_price = Product.get_sale_price([self.product],
|
self.unit_price = self.unit_price.quantize(
|
||||||
self.quantity or 0)[self.product.id]
|
Decimal(1) / 10 ** self.__class__.unit_price.digits[1])
|
||||||
|
|
||||||
if self.unit_price:
|
self.type = 'line'
|
||||||
self.unit_price = self.unit_price.quantize(
|
self.amount = self.on_change_with_amount()
|
||||||
Decimal(1) / 10 ** self.__class__.unit_price.digits[1])
|
|
||||||
|
|
||||||
self.type = 'line'
|
if self.product.equipment:
|
||||||
self.amount = self.on_change_with_amount()
|
self.product_equipment = True
|
||||||
self.product_equipment = True
|
|
||||||
|
|
||||||
|
def get_move(self, shipment_type):
|
||||||
|
|
||||||
|
'''
|
||||||
|
Return moves for the sale line according to shipment_type
|
||||||
|
'''
|
||||||
|
|
||||||
|
pool = Pool()
|
||||||
|
Move = pool.get('stock.move')
|
||||||
|
|
||||||
|
if self.type != 'line':
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.product:
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.product.type not in Move.get_product_types():
|
||||||
|
return
|
||||||
|
|
||||||
|
if (shipment_type == 'out') != (self.quantity >= 0):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
quantity = (self._get_move_quantity(shipment_type)
|
||||||
|
- self._get_shipped_quantity(shipment_type))
|
||||||
|
|
||||||
|
quantity = self.unit.round(quantity)
|
||||||
|
|
||||||
|
if quantity <= 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.sale.party.customer_location:
|
||||||
|
raise PartyLocationError(
|
||||||
|
gettext('sale.msg_sale_customer_location_required',
|
||||||
|
sale=self.sale.rec_name,
|
||||||
|
party=self.sale.party.rec_name))
|
||||||
|
|
||||||
|
move = Move()
|
||||||
|
move.quantity = quantity
|
||||||
|
move.uom = self.unit
|
||||||
|
move.product = self.product
|
||||||
|
move.from_location = self.from_location
|
||||||
|
move.to_location = self.to_location
|
||||||
|
move.state = 'draft'
|
||||||
|
move.company = self.sale.company
|
||||||
|
move.serial = self.equipment_serial
|
||||||
|
|
||||||
|
if move.on_change_with_unit_price_required():
|
||||||
|
move.unit_price = self.unit_price
|
||||||
|
move.currency = self.sale.currency
|
||||||
|
|
||||||
|
move.planned_date = self.planned_shipping_date
|
||||||
|
move.invoice_lines = self._get_move_invoice_lines(shipment_type)
|
||||||
|
move.origin = self
|
||||||
|
|
||||||
|
return move
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ModelView.button
|
@ModelView.button
|
||||||
|
10
sale.xml
10
sale.xml
@ -6,6 +6,16 @@
|
|||||||
<field name="inherit" ref="sale.sale_line_view_form"/>
|
<field name="inherit" ref="sale.sale_line_view_form"/>
|
||||||
<field name="name">sale_line_form</field>
|
<field name="name">sale_line_form</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record model="ir.ui.view" id="sale_line_view_tree">
|
||||||
|
<field name="model">sale.line</field>
|
||||||
|
<field name="inherit" ref="sale.sale_line_view_tree"/>
|
||||||
|
<field name="name">sale_line_tree</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="sale_line_view_tree_sequence">
|
||||||
|
<field name="model">sale.line</field>
|
||||||
|
<field name="inherit" ref="sale.sale_line_view_tree_sequence"/>
|
||||||
|
<field name="name">sale_line_tree_sequence</field>
|
||||||
|
</record>
|
||||||
<record model="ir.ui.view" id="create_subscription_view_form">
|
<record model="ir.ui.view" id="create_subscription_view_form">
|
||||||
<field name="model">sale.create.subscription.start</field>
|
<field name="model">sale.create.subscription.start</field>
|
||||||
<field name="type">form</field>
|
<field name="type">form</field>
|
||||||
|
@ -23,6 +23,7 @@ xml:
|
|||||||
purchase.xml
|
purchase.xml
|
||||||
uom.xml
|
uom.xml
|
||||||
maintenance.xml
|
maintenance.xml
|
||||||
|
move.xml
|
||||||
subscription.xml
|
subscription.xml
|
||||||
message.xml
|
message.xml
|
||||||
|
|
10
view/move_form.xml
Normal file
10
view/move_form.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<data>
|
||||||
|
<xpath expr="/form/field[@name='product']" position="after">
|
||||||
|
<newline/>
|
||||||
|
<label name="serial"/>
|
||||||
|
<field name="serial"/>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
8
view/move_list_shipment.xml
Normal file
8
view/move_list_shipment.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--This file file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
|
||||||
|
<data>
|
||||||
|
<xpath
|
||||||
|
expr="//field[@name='product']" position="after">
|
||||||
|
<field name="serial"/>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
@ -59,7 +59,11 @@
|
|||||||
<field name="maintenance_history"/>
|
<field name="maintenance_history"/>
|
||||||
</page>
|
</page>
|
||||||
<page string="Origins" id="origins_equipment">
|
<page string="Origins" id="origins_equipment">
|
||||||
|
<separator id="purchase_origin" string="Purchase Origin" colspan="4"/>
|
||||||
<field name="purchase_origin"/>
|
<field name="purchase_origin"/>
|
||||||
|
<newline/>
|
||||||
|
<separator id="sale_destination" string="Sale Destination" colspan="4"/>
|
||||||
|
<field name="sale_destination"/>
|
||||||
</page>
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
<group col="2" colspan="2" id="button">
|
<group col="2" colspan="2" id="button">
|
||||||
|
@ -10,7 +10,12 @@
|
|||||||
expr="/form/notebook/page[@id='general']/label[@name='product']" position="before">
|
expr="/form/notebook/page[@id='general']/label[@name='product']" position="before">
|
||||||
<label name="product_equipment"/>
|
<label name="product_equipment"/>
|
||||||
<field name="product_equipment"/>
|
<field name="product_equipment"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath
|
||||||
|
expr="/form/notebook/page[@id='general']/field[@name='product']" position="after">
|
||||||
<label name="equipment"/>
|
<label name="equipment"/>
|
||||||
<field name="equipment"/>
|
<field name="equipment"/>
|
||||||
|
<label name="equipment_serial"/>
|
||||||
|
<field name="equipment_serial"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</data>
|
</data>
|
||||||
|
6
view/sale_line_tree.xml
Normal file
6
view/sale_line_tree.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<data>
|
||||||
|
<xpath expr="//field[@name='summary']" position="replace">
|
||||||
|
<field name="equipment"/>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
6
view/sale_line_tree_sequence.xml
Normal file
6
view/sale_line_tree_sequence.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<data>
|
||||||
|
<xpath expr="//field[@name='summary']" position="replace">
|
||||||
|
<field name="equipment_serial"/>
|
||||||
|
</xpath>
|
||||||
|
</data>
|
Loading…
Reference in New Issue
Block a user