Fee rules
This commit is contained in:
@@ -137,9 +137,10 @@ def register():
|
||||
open_position.OpenPosition,
|
||||
open_position.OpenPositionReport,
|
||||
open_position.OpenPositionContext,
|
||||
optional.OptionalScenario,
|
||||
fee.Fee,
|
||||
fee.FeeLots,
|
||||
optional.OptionalScenario,
|
||||
fee.Fee,
|
||||
fee.FeeRule,
|
||||
fee.FeeLots,
|
||||
purchase.FeeLots,
|
||||
valuation.Valuation,
|
||||
valuation.ValuationLine,
|
||||
|
||||
@@ -35,7 +35,9 @@ class Fee(ModelSQL,ModelView):
|
||||
"Fee"
|
||||
__name__ = 'fee.fee'
|
||||
|
||||
line = fields.Many2One('purchase.line',"Line")
|
||||
line = fields.Many2One('purchase.line',"Line")
|
||||
source_rule = fields.Many2One('fee.rule', "Source Rule", readonly=True)
|
||||
generated_by_rule = fields.Boolean("Generated by Rule", readonly=True)
|
||||
shipment_in = fields.Many2One('stock.shipment.in')
|
||||
shipment_out = fields.Many2One('stock.shipment.out')
|
||||
shipment_internal = fields.Many2One('stock.shipment.internal')
|
||||
@@ -99,9 +101,13 @@ class Fee(ModelSQL,ModelView):
|
||||
fee_date = fields.Date("Date")
|
||||
|
||||
@classmethod
|
||||
def default_fee_date(cls):
|
||||
Date = Pool().get('ir.date')
|
||||
return Date.today()
|
||||
def default_fee_date(cls):
|
||||
Date = Pool().get('ir.date')
|
||||
return Date.today()
|
||||
|
||||
@classmethod
|
||||
def default_generated_by_rule(cls):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def default_qt_state(cls):
|
||||
@@ -971,7 +977,177 @@ class Fee(ModelSQL,ModelView):
|
||||
description=description,
|
||||
lines=[move_line,move_line_],
|
||||
)
|
||||
|
||||
|
||||
class FeeRule(ModelSQL, ModelView):
|
||||
"Fee Rule"
|
||||
__name__ = 'fee.rule'
|
||||
|
||||
name = fields.Char("Name", required=True)
|
||||
active = fields.Boolean("Active")
|
||||
sequence = fields.Integer("Sequence")
|
||||
apply_on = fields.Selection([
|
||||
('purchase_line', "Purchase Line"),
|
||||
('sale_line', "Sale Line"),
|
||||
], "Apply On", required=True)
|
||||
auto_apply = fields.Boolean("Auto Apply")
|
||||
|
||||
party = fields.Many2One('party.party', "Counterparty")
|
||||
line_product = fields.Many2One('product.product', "Line Product")
|
||||
incoterm = fields.Many2One('incoterm.incoterm', "Incoterm")
|
||||
from_location = fields.Many2One('stock.location', "From Location")
|
||||
to_location = fields.Many2One('stock.location', "To Location")
|
||||
execution_plan = fields.Many2One('workflow.plan', "Execution Plan")
|
||||
|
||||
fee_product = fields.Many2One(
|
||||
'product.product', "Fee Product", required=True,
|
||||
domain=[('type', '=', 'service')])
|
||||
supplier = fields.Many2One('party.party', "Supplier")
|
||||
p_r = fields.Selection([
|
||||
('pay', 'PAY'),
|
||||
('rec', 'REC'),
|
||||
], "P/R", required=True)
|
||||
mode = fields.Selection([
|
||||
('lumpsum', 'Lump sum'),
|
||||
('perqt', 'Per qt'),
|
||||
('pprice', '% price'),
|
||||
('rate', '% rate'),
|
||||
('pcost', '% cost price'),
|
||||
('ppack', 'Per packing'),
|
||||
], "Mode", required=True)
|
||||
price = fields.Numeric("Price", digits=(16, 4))
|
||||
quantity = fields.Numeric("Qt", digits='unit')
|
||||
currency = fields.Many2One('currency.currency', "Currency")
|
||||
unit = fields.Many2One('product.uom', "Unit")
|
||||
qt_state = fields.Many2One('lot.qt.type', "Qt State")
|
||||
weight_type = fields.Selection([
|
||||
('net', 'Net'),
|
||||
('brut', 'Gross'),
|
||||
], "W. type")
|
||||
|
||||
@classmethod
|
||||
def default_active(cls):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def default_sequence(cls):
|
||||
return 10
|
||||
|
||||
@classmethod
|
||||
def default_auto_apply(cls):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def default_p_r(cls):
|
||||
return 'pay'
|
||||
|
||||
@classmethod
|
||||
def default_mode(cls):
|
||||
return 'lumpsum'
|
||||
|
||||
@classmethod
|
||||
def default_weight_type(cls):
|
||||
return 'brut'
|
||||
|
||||
@staticmethod
|
||||
def _same_record(left, right):
|
||||
return bool(
|
||||
left and right
|
||||
and getattr(left, 'id', left) == getattr(right, 'id', right))
|
||||
|
||||
@classmethod
|
||||
def _rules_for_lines(cls, apply_on, auto_only=False):
|
||||
domain = [
|
||||
('active', '=', True),
|
||||
('apply_on', '=', apply_on),
|
||||
]
|
||||
if auto_only:
|
||||
domain.append(('auto_apply', '=', True))
|
||||
return cls.search(domain, order=[('sequence', 'ASC'), ('id', 'ASC')])
|
||||
|
||||
def _matches_line(self, line, apply_on):
|
||||
contract = getattr(line, 'purchase', None) or getattr(line, 'sale', None)
|
||||
if not contract or self.apply_on != apply_on:
|
||||
return False
|
||||
checks = [
|
||||
(self.party, getattr(contract, 'party', None)),
|
||||
(self.line_product, getattr(line, 'product', None)),
|
||||
(self.incoterm, getattr(contract, 'incoterm', None)),
|
||||
(self.from_location, getattr(contract, 'from_location', None)),
|
||||
(self.to_location, getattr(contract, 'to_location', None)),
|
||||
]
|
||||
if any(rule_value and not self._same_record(rule_value, actual)
|
||||
for rule_value, actual in checks):
|
||||
return False
|
||||
if self.execution_plan and not self._same_record(
|
||||
self.execution_plan, getattr(contract, 'plan', None)):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _existing_fee(self, line, apply_on):
|
||||
Fee = Pool().get('fee.fee')
|
||||
field_name = 'line' if apply_on == 'purchase_line' else 'sale_line'
|
||||
existing = Fee.search([
|
||||
('source_rule', '=', self.id),
|
||||
(field_name, '=', line.id),
|
||||
], limit=1)
|
||||
return existing[0] if existing else None
|
||||
|
||||
def _fee_values(self, line, apply_on):
|
||||
contract = getattr(line, 'purchase', None) or getattr(line, 'sale', None)
|
||||
values = {
|
||||
'source_rule': self.id,
|
||||
'generated_by_rule': True,
|
||||
'type': 'budgeted',
|
||||
'p_r': self.p_r,
|
||||
'product': self.fee_product.id,
|
||||
'supplier': (
|
||||
getattr(self.supplier, 'id', None)
|
||||
or getattr(getattr(contract, 'party', None), 'id', None)),
|
||||
'mode': self.mode,
|
||||
'price': self.price if self.price is not None else Decimal(0),
|
||||
'currency': (
|
||||
getattr(self.currency, 'id', None)
|
||||
or getattr(getattr(contract, 'currency', None), 'id', None)),
|
||||
'unit': (
|
||||
getattr(self.unit, 'id', None)
|
||||
or getattr(getattr(line, 'unit', None), 'id', None)),
|
||||
'quantity': (
|
||||
self.quantity if self.quantity is not None
|
||||
else getattr(line, 'quantity_theorical', None)
|
||||
or getattr(line, 'quantity', None)),
|
||||
'qt_state': getattr(self.qt_state, 'id', None),
|
||||
'weight_type': self.weight_type,
|
||||
}
|
||||
values['line' if apply_on == 'purchase_line' else 'sale_line'] = line.id
|
||||
return values
|
||||
|
||||
@classmethod
|
||||
def apply_to_lines(cls, lines, apply_on, auto_only=False):
|
||||
Fee = Pool().get('fee.fee')
|
||||
rules = cls._rules_for_lines(apply_on, auto_only=auto_only)
|
||||
created = []
|
||||
for line in lines:
|
||||
if not getattr(line, 'id', None):
|
||||
continue
|
||||
for rule in rules:
|
||||
if not rule._matches_line(line, apply_on):
|
||||
continue
|
||||
if rule._existing_fee(line, apply_on):
|
||||
continue
|
||||
values = rule._fee_values(line, apply_on)
|
||||
if not (
|
||||
values.get('supplier') and values.get('currency')
|
||||
and values.get('unit')):
|
||||
logger.info(
|
||||
"FEE_RULE_SKIPPED_MISSING_VALUES rule=%s line=%s",
|
||||
rule.id, line.id)
|
||||
continue
|
||||
with Transaction().set_context(
|
||||
_purchase_trade_skip_fee_rules=True):
|
||||
created.extend(Fee.create([values]))
|
||||
return created
|
||||
|
||||
|
||||
class FeeLots(ModelSQL,ModelView):
|
||||
|
||||
"Fee lots"
|
||||
|
||||
@@ -19,11 +19,36 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="name">fee_tree_sequence</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fee_view_tree_sequence2">
|
||||
<field name="model">fee.fee</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">fee_tree_sequence2</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="fee_view_tree_sequence2">
|
||||
<field name="model">fee.fee</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">fee_tree_sequence2</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fee_rule_view_form">
|
||||
<field name="model">fee.rule</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">fee_rule_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="fee_rule_view_tree">
|
||||
<field name="model">fee.rule</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">fee_rule_tree</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_fee_rule_form">
|
||||
<field name="name">Fee Rules</field>
|
||||
<field name="res_model">fee.rule</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_fee_rule_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="fee_rule_view_tree"/>
|
||||
<field name="act_window" ref="act_fee_rule_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_fee_rule_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="fee_rule_view_form"/>
|
||||
<field name="act_window" ref="act_fee_rule_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fee_report_view_list">
|
||||
<field name="model">fee.report</field>
|
||||
@@ -51,13 +76,49 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="name">invoice</field>
|
||||
<field name="string">Invoice</field>
|
||||
</record>
|
||||
<record model="ir.model.button-res.group" id="fee_invoice_button_group_admin">
|
||||
<field name="button" ref="fee_invoice_button"/>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_fee">
|
||||
<field name="model">fee.fee</field>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<record model="ir.model.button-res.group" id="fee_invoice_button_group_admin">
|
||||
<field name="button" ref="fee_invoice_button"/>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="purchase_apply_default_fees_button">
|
||||
<field name="model">purchase.purchase</field>
|
||||
<field name="name">apply_default_fees</field>
|
||||
<field name="string">Apply Default Fees</field>
|
||||
</record>
|
||||
<record model="ir.model.button-res.group" id="purchase_apply_default_fees_button_group">
|
||||
<field name="button" ref="purchase_apply_default_fees_button"/>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="sale_apply_default_fees_button">
|
||||
<field name="model">sale.sale</field>
|
||||
<field name="name">apply_default_fees</field>
|
||||
<field name="string">Apply Default Fees</field>
|
||||
</record>
|
||||
<record model="ir.model.button-res.group" id="sale_apply_default_fees_button_group">
|
||||
<field name="button" ref="sale_apply_default_fees_button"/>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="purchase_line_apply_default_fees_button">
|
||||
<field name="model">purchase.line</field>
|
||||
<field name="name">apply_default_fees</field>
|
||||
<field name="string">Apply Default Fees</field>
|
||||
</record>
|
||||
<record model="ir.model.button-res.group" id="purchase_line_apply_default_fees_button_group">
|
||||
<field name="button" ref="purchase_line_apply_default_fees_button"/>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
</record>
|
||||
<record model="ir.model.button" id="sale_line_apply_default_fees_button">
|
||||
<field name="model">sale.line</field>
|
||||
<field name="name">apply_default_fees</field>
|
||||
<field name="string">Apply Default Fees</field>
|
||||
</record>
|
||||
<record model="ir.model.button-res.group" id="sale_line_apply_default_fees_button_group">
|
||||
<field name="button" ref="sale_line_apply_default_fees_button"/>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_fee">
|
||||
<field name="model">fee.fee</field>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
@@ -67,15 +128,36 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Fee Report"
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_fee_rule">
|
||||
<field name="model">fee.rule</field>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_fee_rule_admin">
|
||||
<field name="model">fee.rule</field>
|
||||
<field name="group" ref="purchase.group_purchase"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Fee Report"
|
||||
parent="purchase_trade.menu_ctrm_other"
|
||||
action="act_fee_report_form"
|
||||
sequence="20"
|
||||
id="menu_fee_report_form"/>
|
||||
</data>
|
||||
sequence="20"
|
||||
id="menu_fee_report_form"/>
|
||||
<menuitem
|
||||
name="Fee Rules"
|
||||
parent="purchase_trade.menu_ctrm_other"
|
||||
action="act_fee_rule_form"
|
||||
sequence="21"
|
||||
id="menu_fee_rule_form"/>
|
||||
</data>
|
||||
</tryton>
|
||||
|
||||
@@ -410,6 +410,14 @@ class Purchase(metaclass=PoolMeta):
|
||||
def default_tolerance_option(cls):
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def apply_default_fees(cls, purchases):
|
||||
lines = [
|
||||
line for purchase in purchases for line in (purchase.lines or [])
|
||||
if getattr(line, 'type', None) == 'line']
|
||||
Pool().get('fee.rule').apply_to_lines(lines, 'purchase_line')
|
||||
|
||||
def _line_quantity_in_unit(self, quantity, from_unit, to_unit):
|
||||
if not from_unit or not to_unit or from_unit == to_unit:
|
||||
return Decimal(str(quantity or 0))
|
||||
@@ -1312,7 +1320,16 @@ class Line(metaclass=PoolMeta):
|
||||
for values in vlist:
|
||||
cls._check_delivery_period_values([cls()], values)
|
||||
cls._set_initial_quantity_values(values)
|
||||
return super().create(vlist)
|
||||
lines = super().create(vlist)
|
||||
if not Transaction().context.get('_purchase_trade_skip_fee_rules'):
|
||||
Pool().get('fee.rule').apply_to_lines(
|
||||
lines, 'purchase_line', auto_only=True)
|
||||
return lines
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def apply_default_fees(cls, lines):
|
||||
Pool().get('fee.rule').apply_to_lines(lines, 'purchase_line')
|
||||
|
||||
def _check_delivery_period(self):
|
||||
if self._has_invalid_delivery_period(self):
|
||||
@@ -1877,6 +1894,9 @@ class Line(metaclass=PoolMeta):
|
||||
|
||||
Pool().get('lot.lot').assert_lines_quantity_consistency(
|
||||
cls._fresh_lines_for_quantity_consistency(lines))
|
||||
if not Transaction().context.get('_purchase_trade_skip_fee_rules'):
|
||||
Pool().get('fee.rule').apply_to_lines(
|
||||
lines, 'purchase_line', auto_only=True)
|
||||
|
||||
@classmethod
|
||||
def _sync_open_lot_quantity(cls, line, vlot, target_quantity):
|
||||
|
||||
@@ -374,6 +374,14 @@ class Sale(metaclass=PoolMeta):
|
||||
def default_tolerance_option(cls):
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def apply_default_fees(cls, sales):
|
||||
lines = [
|
||||
line for sale in sales for line in (sale.lines or [])
|
||||
if getattr(line, 'type', None) == 'line']
|
||||
Pool().get('fee.rule').apply_to_lines(lines, 'sale_line')
|
||||
|
||||
def _line_quantity_in_unit(self, quantity, from_unit, to_unit):
|
||||
if not from_unit or not to_unit or from_unit == to_unit:
|
||||
return abs(Decimal(str(quantity or 0)))
|
||||
@@ -1358,7 +1366,16 @@ class SaleLine(metaclass=PoolMeta):
|
||||
for values in vlist:
|
||||
cls._check_delivery_period_values([cls()], values)
|
||||
cls._set_initial_quantity_values(values)
|
||||
return super().create(vlist)
|
||||
lines = super().create(vlist)
|
||||
if not Transaction().context.get('_purchase_trade_skip_fee_rules'):
|
||||
Pool().get('fee.rule').apply_to_lines(
|
||||
lines, 'sale_line', auto_only=True)
|
||||
return lines
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def apply_default_fees(cls, lines):
|
||||
Pool().get('fee.rule').apply_to_lines(lines, 'sale_line')
|
||||
|
||||
def _check_delivery_period(self):
|
||||
if self._has_invalid_delivery_period(self):
|
||||
@@ -2057,6 +2074,9 @@ class SaleLine(metaclass=PoolMeta):
|
||||
|
||||
Pool().get('lot.lot').assert_lines_quantity_consistency(
|
||||
cls._fresh_lines_for_quantity_consistency(lines))
|
||||
if not Transaction().context.get('_purchase_trade_skip_fee_rules'):
|
||||
Pool().get('fee.rule').apply_to_lines(
|
||||
lines, 'sale_line', auto_only=True)
|
||||
|
||||
@classmethod
|
||||
def _sync_open_lot_quantity(cls, line, vlot, target_quantity):
|
||||
|
||||
@@ -1784,6 +1784,75 @@ class PurchaseTradeTestCase(ModuleTestCase):
|
||||
self.assertEqual(Sale.default_tolerance_option(), '')
|
||||
self.assertEqual(Purchase.default_tolerance_option(), '')
|
||||
|
||||
def test_fee_rule_matches_purchase_line_conditions(self):
|
||||
'fee rule matches purchase line conditions'
|
||||
party = Mock(id=1)
|
||||
product = Mock(id=2)
|
||||
incoterm = Mock(id=3)
|
||||
from_location = Mock(id=4)
|
||||
to_location = Mock(id=5)
|
||||
plan = Mock(id=6)
|
||||
contract = Mock(
|
||||
party=party,
|
||||
incoterm=incoterm,
|
||||
from_location=from_location,
|
||||
to_location=to_location,
|
||||
plan=plan,
|
||||
)
|
||||
line = Mock(product=product, purchase=contract, sale=None)
|
||||
rule = fee_module.FeeRule()
|
||||
rule.apply_on = 'purchase_line'
|
||||
rule.party = party
|
||||
rule.line_product = product
|
||||
rule.incoterm = incoterm
|
||||
rule.from_location = from_location
|
||||
rule.to_location = to_location
|
||||
rule.execution_plan = plan
|
||||
|
||||
self.assertTrue(rule._matches_line(line, 'purchase_line'))
|
||||
|
||||
def test_fee_rule_builds_budgeted_sale_fee_values(self):
|
||||
'fee rule builds budgeted fee values for a sale line'
|
||||
currency = Mock(id=1)
|
||||
unit = Mock(id=2)
|
||||
party = Mock(id=3)
|
||||
product = Mock(id=4)
|
||||
fee_product = Mock(id=5)
|
||||
sale = Mock(party=party, currency=currency)
|
||||
line = Mock(
|
||||
id=10,
|
||||
product=product,
|
||||
sale=sale,
|
||||
purchase=None,
|
||||
unit=unit,
|
||||
quantity_theorical=Decimal('100'),
|
||||
quantity=Decimal('90'),
|
||||
)
|
||||
rule = fee_module.FeeRule()
|
||||
rule.id = 20
|
||||
rule.fee_product = fee_product
|
||||
rule.supplier = None
|
||||
rule.p_r = 'pay'
|
||||
rule.mode = 'perqt'
|
||||
rule.price = Decimal('12.50')
|
||||
rule.quantity = None
|
||||
rule.currency = None
|
||||
rule.unit = None
|
||||
rule.qt_state = None
|
||||
rule.weight_type = 'brut'
|
||||
|
||||
values = rule._fee_values(line, 'sale_line')
|
||||
|
||||
self.assertEqual(values['source_rule'], 20)
|
||||
self.assertTrue(values['generated_by_rule'])
|
||||
self.assertEqual(values['type'], 'budgeted')
|
||||
self.assertEqual(values['sale_line'], 10)
|
||||
self.assertEqual(values['product'], 5)
|
||||
self.assertEqual(values['supplier'], 3)
|
||||
self.assertEqual(values['currency'], 1)
|
||||
self.assertEqual(values['unit'], 2)
|
||||
self.assertEqual(values['quantity'], Decimal('100'))
|
||||
|
||||
def test_sale_line_basis_price_and_progress_use_manual_summary_without_component(self):
|
||||
'sale line basis values use manual summary rows even without a component'
|
||||
SaleLine = Pool().get('sale.line')
|
||||
|
||||
46
modules/purchase_trade/view/fee_rule_form.xml
Normal file
46
modules/purchase_trade/view/fee_rule_form.xml
Normal file
@@ -0,0 +1,46 @@
|
||||
<form>
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="active"/>
|
||||
<field name="active"/>
|
||||
<label name="sequence"/>
|
||||
<field name="sequence"/>
|
||||
<label name="auto_apply"/>
|
||||
<field name="auto_apply"/>
|
||||
<newline/>
|
||||
<label name="apply_on"/>
|
||||
<field name="apply_on"/>
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
<label name="line_product"/>
|
||||
<field name="line_product"/>
|
||||
<label name="incoterm"/>
|
||||
<field name="incoterm"/>
|
||||
<label name="from_location"/>
|
||||
<field name="from_location"/>
|
||||
<label name="to_location"/>
|
||||
<field name="to_location"/>
|
||||
<label name="execution_plan"/>
|
||||
<field name="execution_plan"/>
|
||||
<newline/>
|
||||
<label name="fee_product"/>
|
||||
<field name="fee_product"/>
|
||||
<label name="supplier"/>
|
||||
<field name="supplier"/>
|
||||
<label name="p_r"/>
|
||||
<field name="p_r"/>
|
||||
<label name="mode"/>
|
||||
<field name="mode"/>
|
||||
<label name="price"/>
|
||||
<field name="price"/>
|
||||
<label name="quantity"/>
|
||||
<field name="quantity"/>
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<label name="unit"/>
|
||||
<field name="unit"/>
|
||||
<label name="qt_state"/>
|
||||
<field name="qt_state"/>
|
||||
<label name="weight_type"/>
|
||||
<field name="weight_type"/>
|
||||
</form>
|
||||
18
modules/purchase_trade/view/fee_rule_tree.xml
Normal file
18
modules/purchase_trade/view/fee_rule_tree.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<tree>
|
||||
<field name="sequence"/>
|
||||
<field name="active"/>
|
||||
<field name="name"/>
|
||||
<field name="apply_on"/>
|
||||
<field name="auto_apply"/>
|
||||
<field name="party"/>
|
||||
<field name="line_product"/>
|
||||
<field name="incoterm"/>
|
||||
<field name="from_location"/>
|
||||
<field name="to_location"/>
|
||||
<field name="fee_product"/>
|
||||
<field name="supplier"/>
|
||||
<field name="p_r"/>
|
||||
<field name="mode"/>
|
||||
<field name="price"/>
|
||||
<field name="currency"/>
|
||||
</tree>
|
||||
@@ -38,6 +38,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
xexpand="1" xfill="1"/>
|
||||
<label name="tolerance_option"/>
|
||||
<field name="tolerance_option"/>
|
||||
<button name="apply_default_fees" icon="tryton-launch"/>
|
||||
<field name="tolerance_min" invisible="1"/>
|
||||
<field name="tolerance_max" invisible="1"/>
|
||||
<newline/>
|
||||
|
||||
@@ -86,9 +86,10 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page string="Lots" col="4" id="lots">
|
||||
<field name="lots" mode="tree,form" view_ids="lot.lot_view_tree_sequence,lot.lot_view_form"/>
|
||||
</page>
|
||||
<page string="Fees" col="4" id="fees">
|
||||
<field name="fees" colspan="4" mode="tree,mode" view_ids="purchase_trade.fee_view_tree_sequence,purchase_trade.fee_view_form"/>
|
||||
</page>
|
||||
<page string="Fees" col="4" id="fees">
|
||||
<button name="apply_default_fees" icon="tryton-launch"/>
|
||||
<field name="fees" colspan="4" mode="tree,mode" view_ids="purchase_trade.fee_view_tree_sequence,purchase_trade.fee_view_form"/>
|
||||
</page>
|
||||
<page string="Mtm" col="4" id="mtm">
|
||||
<field name="mtm" colspan="4"/>
|
||||
</page>
|
||||
|
||||
@@ -38,6 +38,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
xexpand="1" xfill="1"/>
|
||||
<label name="tolerance_option"/>
|
||||
<field name="tolerance_option"/>
|
||||
<button name="apply_default_fees" icon="tryton-launch"/>
|
||||
<field name="tolerance_min" invisible="1"/>
|
||||
<field name="tolerance_max" invisible="1"/>
|
||||
<newline/>
|
||||
|
||||
@@ -71,9 +71,10 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page string="Lots" col="4" id="lots">
|
||||
<field name="lots" view_ids="lot.lot_view_tree_sequence"/>
|
||||
</page>
|
||||
<page string="Fees" col="4" id="fees">
|
||||
<field name="fees" view_ids="purchase_trade.fee_view_tree_sequence"/>
|
||||
</page>
|
||||
<page string="Fees" col="4" id="fees">
|
||||
<button name="apply_default_fees" icon="tryton-launch"/>
|
||||
<field name="fees" view_ids="purchase_trade.fee_view_tree_sequence"/>
|
||||
</page>
|
||||
<page string="Mtm" col="4" id="mtm">
|
||||
<field name="mtm" colspan="4"/>
|
||||
</page>
|
||||
|
||||
Reference in New Issue
Block a user