merge
This commit is contained in:
commit
df798989ca
|
@ -1,3 +1,4 @@
|
|||
* Add sequence on contract lines
|
||||
* Make contracts start date and end date functional fields based on lines
|
||||
* Improve rec_names of all fields
|
||||
* Initial release
|
||||
|
|
|
@ -18,8 +18,10 @@ def register():
|
|||
CreateInvoicesStart,
|
||||
Configuration,
|
||||
InvoiceLine,
|
||||
CreditInvoiceStart,
|
||||
module='contract', type_='model')
|
||||
Pool.register(
|
||||
CreateConsumptions,
|
||||
CreateInvoices,
|
||||
CreditInvoice,
|
||||
module='contract', type_='wizard')
|
||||
|
|
165
contract.py
165
contract.py
|
@ -12,7 +12,7 @@ from decimal import Decimal
|
|||
from trytond.config import config
|
||||
from trytond.model import Workflow, ModelSQL, ModelView, Model, fields
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval, Bool
|
||||
from trytond.pyson import Eval, Bool, If
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.tools import reduce_ids, grouped_slice
|
||||
from trytond.wizard import Wizard, StateView, StateAction, Button
|
||||
|
@ -106,11 +106,10 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
start_period_date = fields.Date('Start Period Date', required=True,
|
||||
states=_STATES, depends=_DEPENDS)
|
||||
lines = fields.One2Many('contract.line', 'contract', 'Lines',
|
||||
context={
|
||||
'start_date': Eval('start_date'),
|
||||
'end_date': Eval('end_date'),
|
||||
states={
|
||||
'readonly': Eval('state') == 'cancel',
|
||||
},
|
||||
depends=['start_date', 'end_date'])
|
||||
depends=['state'])
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('validated', 'Validated'),
|
||||
|
@ -144,10 +143,6 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
'icon': 'tryton-cancel',
|
||||
},
|
||||
})
|
||||
cls._error_messages.update({
|
||||
'start_date_not_valid': ('Contract %(contract)s with '
|
||||
'invalid date "%(date)s"'),
|
||||
})
|
||||
|
||||
def _get_rec_name(self, name):
|
||||
rec_name = []
|
||||
|
@ -285,6 +280,14 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
date = r.after(last_invoice_date)
|
||||
return date.date()
|
||||
|
||||
def get_start_period_date(self, start_date):
|
||||
r = rrule(self.rrule._freq, interval=self.rrule._interval,
|
||||
dtstart=self.start_period_date)
|
||||
date = r.before(todatetime(start_date), inc=True)
|
||||
if date:
|
||||
return date.date()
|
||||
return self.start_period_date
|
||||
|
||||
def get_consumptions(self, end_date=None):
|
||||
pool = Pool()
|
||||
Date = pool.get('ir.date')
|
||||
|
@ -295,7 +298,7 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
consumptions = []
|
||||
|
||||
for line in self.lines:
|
||||
start_period_date = line.start_date or self.start_period_date
|
||||
start_period_date = self.get_start_period_date(line.start_date)
|
||||
|
||||
last_consumption_date = line.last_consumption_date
|
||||
if last_consumption_date:
|
||||
|
@ -309,7 +312,6 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
if end_contract:
|
||||
self.rrule.until = end_contract
|
||||
|
||||
|
||||
last_invoice_date = line.last_consumption_invoice_date
|
||||
|
||||
next_period = self.rrule.after(todatetime(start)) + \
|
||||
|
@ -318,7 +320,6 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
if end_contract and next_period.date() < end_contract:
|
||||
next_period = todatetime(end_contract)
|
||||
|
||||
|
||||
for date in self.rrule.between(todatetime(start), next_period):
|
||||
date -= relativedelta(days=+1)
|
||||
date = date.date()
|
||||
|
@ -339,8 +340,10 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
start_period = start_period_date
|
||||
start = line.start_date or self.start
|
||||
|
||||
if (not end_contract or (invoice_date <= end_contract) or
|
||||
(finish_date <= end_contract) or (invoice_date < end_date)):
|
||||
if ((not end_contract or (invoice_date <= end_contract) or
|
||||
(finish_date <= end_contract) or
|
||||
(invoice_date < end_date))
|
||||
and not start > date):
|
||||
consumptions.append(line.get_consumption(start, date,
|
||||
invoice_date, start_period, finish_date))
|
||||
date += relativedelta(days=+1)
|
||||
|
@ -363,23 +366,6 @@ class Contract(RRuleMixin, Workflow, ModelSQL, ModelView):
|
|||
|
||||
return ContractConsumption.create([c._save_values for c in to_create])
|
||||
|
||||
def check_start_date(self):
|
||||
if not hasattr(self, 'rrule') or not self.start_date:
|
||||
return
|
||||
d = self.rrule.after(todatetime(self.start_period_date)).date()
|
||||
if self.start_date >= self.start_period_date and self.start_date < d:
|
||||
return True
|
||||
self.raise_user_error('start_date_not_valid', {
|
||||
'contract': self.rec_name,
|
||||
'date': self.start_date,
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def validate(cls, contracts):
|
||||
super(Contract, cls).validate(contracts)
|
||||
for contract in contracts:
|
||||
contract.check_start_date()
|
||||
|
||||
|
||||
class ContractLine(Workflow, ModelSQL, ModelView):
|
||||
'Contract Line'
|
||||
|
@ -388,8 +374,20 @@ class ContractLine(Workflow, ModelSQL, ModelView):
|
|||
contract = fields.Many2One('contract', 'Contract', required=True,
|
||||
ondelete='CASCADE')
|
||||
service = fields.Many2One('contract.service', 'Service')
|
||||
start_date = fields.Date('Start Date', required=True)
|
||||
end_date = fields.Date('End Date')
|
||||
start_date = fields.Date('Start Date', required=True,
|
||||
domain=[
|
||||
If(Bool(Eval('end_date')),
|
||||
('start_date', '<=', Eval('end_date', None)),
|
||||
()),
|
||||
],
|
||||
depends=['end_date'])
|
||||
end_date = fields.Date('End Date',
|
||||
domain=[
|
||||
If(Bool(Eval('end_date')),
|
||||
('end_date', '>=', Eval('start_date', None)),
|
||||
()),
|
||||
],
|
||||
depends=['start_date'])
|
||||
description = fields.Text('Description', required=True)
|
||||
unit_price = fields.Numeric('Unit Price', digits=(16, DIGITS),
|
||||
required=True)
|
||||
|
@ -399,7 +397,18 @@ class ContractLine(Workflow, ModelSQL, ModelView):
|
|||
'Last Invoice Date'), 'get_last_consumption_invoice_date')
|
||||
consumptions = fields.One2Many('contract.consumption', 'contract_line',
|
||||
'Consumptions', readonly=True)
|
||||
first_invoice_date = fields.Date('First Invoice Date')
|
||||
first_invoice_date = fields.Date('First Invoice Date', required=True)
|
||||
sequence = fields.Integer('Sequence')
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(ContractLine, cls).__setup__()
|
||||
cls._order = [('contract', 'ASC'), ('sequence', 'ASC')]
|
||||
|
||||
@staticmethod
|
||||
def order_sequence(tables):
|
||||
table, _ = tables[None]
|
||||
return [table.sequence == None, table.sequence]
|
||||
|
||||
def get_rec_name(self, name):
|
||||
rec_name = self.contract.rec_name
|
||||
|
@ -414,18 +423,6 @@ class ContractLine(Workflow, ModelSQL, ModelView):
|
|||
('service.rec_name',) + tuple(clause[1:]),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def default_start_date():
|
||||
return Transaction().context.get('start_date')
|
||||
|
||||
@staticmethod
|
||||
def default_end_date():
|
||||
return Transaction().context.get('end_date')
|
||||
|
||||
@staticmethod
|
||||
def default_first_invoice_date():
|
||||
return Transaction().context.get('first_invoice_date')
|
||||
|
||||
@fields.depends('service', 'unit_price', 'description')
|
||||
def on_change_service(self):
|
||||
changes = {}
|
||||
|
@ -437,6 +434,13 @@ class ContractLine(Workflow, ModelSQL, ModelView):
|
|||
changes['description'] = self.service.product.rec_name
|
||||
return changes
|
||||
|
||||
@fields.depends('start_date', 'first_invoice_date')
|
||||
def on_change_start_date(self):
|
||||
changes = {}
|
||||
if self.start_date and not self.first_invoice_date:
|
||||
changes['first_invoice_date'] = self.start_date
|
||||
return changes
|
||||
|
||||
@classmethod
|
||||
def get_last_consumption_date(cls, lines, name):
|
||||
pool = Pool()
|
||||
|
@ -490,13 +494,35 @@ class ContractConsumption(ModelSQL, ModelView):
|
|||
|
||||
contract_line = fields.Many2One('contract.line', 'Contract Line',
|
||||
required=True)
|
||||
init_period_date = fields.Date('Start Period Date', required=True)
|
||||
end_period_date = fields.Date('Finish Period Date', required=True)
|
||||
start_date = fields.Date('Start Date', required=True)
|
||||
end_date = fields.Date('End Date', required=True)
|
||||
init_period_date = fields.Date('Start Period Date', required=True,
|
||||
domain=[
|
||||
('init_period_date', '<=', Eval('end_period_date', None)),
|
||||
],
|
||||
depends=['end_period_date'])
|
||||
end_period_date = fields.Date('Finish Period Date', required=True,
|
||||
domain=[
|
||||
('end_period_date', '>=', Eval('init_period_date', None)),
|
||||
],
|
||||
depends=['init_period_date'])
|
||||
start_date = fields.Date('Start Date', required=True,
|
||||
domain=[
|
||||
('start_date', '<=', Eval('end_date', None)),
|
||||
],
|
||||
depends=['end_date'])
|
||||
end_date = fields.Date('End Date', required=True,
|
||||
domain=[
|
||||
('end_date', '>=', Eval('start_date', None)),
|
||||
],
|
||||
depends=['start_date'])
|
||||
invoice_date = fields.Date('Invoice Date', required=True)
|
||||
invoice_line = fields.One2Many('account.invoice.line', 'origin',
|
||||
'Invoice Line', size=1)
|
||||
invoice_lines = fields.One2Many('account.invoice.line', 'origin',
|
||||
'Invoice Lines', readonly=True)
|
||||
credit_lines = fields.Function(fields.One2Many('account.invoice.line',
|
||||
None, 'Credit Lines',
|
||||
states={
|
||||
'invisible': ~Bool(Eval('credit_lines')),
|
||||
}),
|
||||
'get_credit_lines')
|
||||
contract = fields.Function(fields.Many2One('contract',
|
||||
'Contract'), 'get_contract', searcher='search_contract')
|
||||
|
||||
|
@ -510,14 +536,22 @@ class ContractConsumption(ModelSQL, ModelView):
|
|||
'missing_account_revenue_property': ('Contract Line '
|
||||
'"%(contract_line)s" misses an "account revenue" default '
|
||||
'property.'),
|
||||
'delete_invoiced_consumption': ('Consumption "%s" can not be'
|
||||
' deleted because it is already invoiced.'),
|
||||
})
|
||||
cls._buttons.update({
|
||||
'invoice': {
|
||||
'invisible': Bool(Eval('invoice_line')),
|
||||
'icon': 'tryton-go-next',
|
||||
},
|
||||
})
|
||||
|
||||
def get_credit_lines(self, name):
|
||||
pool = Pool()
|
||||
InvoiceLine = pool.get('account.invoice.line')
|
||||
return [x.id for x in InvoiceLine.search([
|
||||
('origin.id', 'in', [l.id for l in self.invoice_lines],
|
||||
'account.invoice.line')])]
|
||||
|
||||
def get_contract(self, name=None):
|
||||
return self.contract_line.contract.id
|
||||
|
||||
|
@ -558,6 +592,7 @@ class ContractConsumption(ModelSQL, ModelView):
|
|||
invoice_line.origin = self
|
||||
invoice_line.company = self.contract_line.contract.company
|
||||
invoice_line.currency = self.contract_line.contract.currency
|
||||
invoice_line.sequence = self.contract_line.sequence
|
||||
invoice_line.product = None
|
||||
if self.contract_line.service:
|
||||
invoice_line.product = self.contract_line.service.product
|
||||
|
@ -603,9 +638,12 @@ class ContractConsumption(ModelSQL, ModelView):
|
|||
})
|
||||
invoice_line.taxes = taxes
|
||||
invoice_line.invoice_type = 'out_invoice'
|
||||
# Compute quantity based on dates
|
||||
quantity = ((self.end_date - self.start_date).total_seconds() /
|
||||
(self.end_period_date - self.init_period_date).total_seconds())
|
||||
if self.end_period_date == self.init_period_date:
|
||||
quantity = 0.0
|
||||
else:
|
||||
# Compute quantity based on dates
|
||||
quantity = ((self.end_date - self.start_date).total_seconds() /
|
||||
(self.end_period_date - self.init_period_date).total_seconds())
|
||||
rounding = invoice_line.unit.rounding if invoice_line.unit else 1
|
||||
invoice_line.quantity = Uom.round(quantity, rounding)
|
||||
return invoice_line
|
||||
|
@ -677,8 +715,6 @@ class ContractConsumption(ModelSQL, ModelView):
|
|||
Invoice = pool.get('account.invoice')
|
||||
lines = {}
|
||||
for consumption in consumptions:
|
||||
if consumption.invoice_line:
|
||||
continue
|
||||
line = consumption.get_invoice_line()
|
||||
lines[consumption.id] = line
|
||||
|
||||
|
@ -698,6 +734,19 @@ class ContractConsumption(ModelSQL, ModelView):
|
|||
Invoice.update_taxes(invoices)
|
||||
return invoices
|
||||
|
||||
@classmethod
|
||||
def delete(cls, consumptions):
|
||||
pool = Pool()
|
||||
InvoiceLine = pool.get('account.invoice.line')
|
||||
lines = InvoiceLine.search([
|
||||
('origin', 'in', [str(c) for c in consumptions])
|
||||
], limit=1)
|
||||
if lines:
|
||||
line, = lines
|
||||
cls.raise_user_error('delete_invoiced_consumption',
|
||||
line.origin.rec_name)
|
||||
super(ContractConsumption, cls).delete(consumptions)
|
||||
|
||||
|
||||
class CreateConsumptionsStart(ModelView):
|
||||
'Create Consumptions Start'
|
||||
|
|
25
contract.xml
25
contract.xml
|
@ -113,7 +113,7 @@
|
|||
id="act_contract_consumption_domain_to_invoiced">
|
||||
<field name="name">To Invoice</field>
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="domain">[('invoice_line', '=', None)]</field>
|
||||
<field name="domain">[('invoice_lines', '=', None)]</field>
|
||||
<field name="act_window" ref="act_contract_consumption"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.domain"
|
||||
|
@ -122,7 +122,6 @@
|
|||
<field name="sequence" eval="9999"/>
|
||||
<field name="act_window" ref="act_contract_consumption"/>
|
||||
</record>
|
||||
<!-- TODO: Add relate from consumption to invoices
|
||||
<record model="ir.action.act_window" id="act_invoices">
|
||||
<field name="name">Invoices</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
|
@ -133,7 +132,27 @@
|
|||
<field name="model">contract.consumption,-1</field>
|
||||
<field name="action" ref="act_invoices"/>
|
||||
</record>
|
||||
-->
|
||||
<record model="ir.action.act_window" id="act_consumption_contracts">
|
||||
<field name="name">Consumptions</field>
|
||||
<field name="res_model">contract.consumption</field>
|
||||
<field name="domain">[('contract', 'in', Eval('active_ids'))]</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="act_consumption_contracts_keyword1">
|
||||
<field name="keyword">form_relate</field>
|
||||
<field name="model">contract,-1</field>
|
||||
<field name="action" ref="act_consumption_contracts"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_consumption_contract_line">
|
||||
<field name="name">Consumptions</field>
|
||||
<field name="res_model">contract.consumption</field>
|
||||
<field name="domain">[('contract_line', 'in', Eval('active_ids'))]</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword"
|
||||
id="act_consumption_contract_line_keyword1">
|
||||
<field name="keyword">form_relate</field>
|
||||
<field name="model">contract.line,-1</field>
|
||||
<field name="action" ref="act_consumption_contract_line"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_contract_consumption">
|
||||
<field name="model" search="[('model', '=', 'contract.consumption')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
|
|
56
invoice.py
56
invoice.py
|
@ -1,12 +1,13 @@
|
|||
# This file is part of contract_invoice module for Tryton.
|
||||
# The COPYRIGHT file at the top level of this repository contains
|
||||
# the full copyright notices and license terms.
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.model import ModelView, fields
|
||||
from trytond.pool import Pool
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wizard import Wizard, StateView, StateAction, Button
|
||||
|
||||
__all__ = ['InvoiceLine', 'CreateInvoicesStart', 'CreateInvoices']
|
||||
__all__ = ['InvoiceLine', 'CreateInvoicesStart', 'CreateInvoices',
|
||||
'CreditInvoiceStart', 'CreditInvoice']
|
||||
__metaclass__ = PoolMeta
|
||||
|
||||
|
||||
|
@ -54,3 +55,50 @@ class CreateInvoices(Wizard):
|
|||
if len(invoices) == 1:
|
||||
action['views'].reverse()
|
||||
return action, data
|
||||
|
||||
|
||||
class CreditInvoiceStart:
|
||||
__name__ = 'account.invoice.credit.start'
|
||||
from_contract = fields.Boolean('From Contract', readonly=True)
|
||||
reinvoice_contract = fields.Boolean('Reinvoice Contract',
|
||||
states={
|
||||
'invisible': ~Bool(Eval('from_contract')),
|
||||
},
|
||||
depends=['from_contract'],
|
||||
help=('If true, the consumption that generated this line will be '
|
||||
'reinvoiced.'))
|
||||
|
||||
|
||||
class CreditInvoice:
|
||||
__name__ = 'account.invoice.credit'
|
||||
|
||||
def default_start(self, fields):
|
||||
pool = Pool()
|
||||
Invoice = pool.get('account.invoice')
|
||||
Consumption = pool.get('contract.consumption')
|
||||
|
||||
default = super(CreditInvoice, self).default_start(fields)
|
||||
default.update({
|
||||
'from_contract': False,
|
||||
'reinvoice_contract': False,
|
||||
})
|
||||
for invoice in Invoice.browse(Transaction().context['active_ids']):
|
||||
for line in invoice.lines:
|
||||
if isinstance(line.origin, Consumption):
|
||||
default['from_contract'] = True
|
||||
break
|
||||
return default
|
||||
|
||||
def do_credit(self, action):
|
||||
pool = Pool()
|
||||
Invoice = pool.get('account.invoice')
|
||||
Consumption = pool.get('contract.consumption')
|
||||
|
||||
action, data = super(CreditInvoice, self).do_credit(action)
|
||||
consumptions = set([])
|
||||
for invoice in Invoice.browse(Transaction().context['active_ids']):
|
||||
for line in invoice.lines:
|
||||
if isinstance(line.origin, Consumption):
|
||||
consumptions.add(line.origin)
|
||||
Consumption.invoice(list(consumptions))
|
||||
return action, data
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="credit_start_view_form">
|
||||
<field name="model">account.invoice.credit.start</field>
|
||||
<field name="name">credit_start_form</field>
|
||||
<field name="inherit" ref="account_invoice.credit_start_view_form"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
|
@ -2,6 +2,10 @@
|
|||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=utf-8\n"
|
||||
|
||||
msgctxt "error:contract.consumption:"
|
||||
msgid "Consumption \"%s\" can not be deleted because it is already invoiced."
|
||||
msgstr "No es pot eliminar el consum \"%s\" perquè ja esta facturat."
|
||||
|
||||
msgctxt "error:contract.consumption:"
|
||||
msgid ""
|
||||
"Contract Line \"%(contract_line)s\" misses an \"account revenue\" default "
|
||||
|
@ -18,9 +22,13 @@ msgstr ""
|
|||
"Falta el compte d'ingressos al producte \"%(product)s\" de la línia de "
|
||||
"contracte \"%(contract_line)s\"."
|
||||
|
||||
msgctxt "error:contract:"
|
||||
msgid "Contract %(contract)s with invalid date \"%(date)s\""
|
||||
msgstr "El contracte \"%(contract)s\" té dates invàlides \"%(date)s\""
|
||||
msgctxt "field:account.invoice.credit.start,from_contract:"
|
||||
msgid "From Contract"
|
||||
msgstr "Provinent de contracte"
|
||||
|
||||
msgctxt "field:account.invoice.credit.start,reinvoice_contract:"
|
||||
msgid "Reinvoice Contract"
|
||||
msgstr "Refacturar el contracte"
|
||||
|
||||
msgctxt "field:contract,company:"
|
||||
msgid "Company"
|
||||
|
@ -134,6 +142,10 @@ msgctxt "field:contract.consumption,create_uid:"
|
|||
msgid "Create User"
|
||||
msgstr "Usuari creació"
|
||||
|
||||
msgctxt "field:contract.consumption,credit_lines:"
|
||||
msgid "Credit Lines"
|
||||
msgstr "Línies d'abonament"
|
||||
|
||||
msgctxt "field:contract.consumption,end_date:"
|
||||
msgid "End Date"
|
||||
msgstr "Data finalització"
|
||||
|
@ -154,9 +166,9 @@ msgctxt "field:contract.consumption,invoice_date:"
|
|||
msgid "Invoice Date"
|
||||
msgstr "Data factura"
|
||||
|
||||
msgctxt "field:contract.consumption,invoice_line:"
|
||||
msgid "Invoice Line"
|
||||
msgstr "Línia de factura"
|
||||
msgctxt "field:contract.consumption,invoice_lines:"
|
||||
msgid "Invoice Lines"
|
||||
msgstr "Línies de factura"
|
||||
|
||||
msgctxt "field:contract.consumption,rec_name:"
|
||||
msgid "Name"
|
||||
|
@ -234,6 +246,10 @@ msgctxt "field:contract.line,rec_name:"
|
|||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
msgctxt "field:contract.line,sequence:"
|
||||
msgid "Sequence"
|
||||
msgstr "Seqüència"
|
||||
|
||||
msgctxt "field:contract.line,service:"
|
||||
msgid "Service"
|
||||
msgstr "Serveis"
|
||||
|
@ -298,6 +314,12 @@ msgctxt "field:party.party,contract_grouping_method:"
|
|||
msgid "Contract Grouping Method"
|
||||
msgstr "Mètode d'agrupació de contractes"
|
||||
|
||||
msgctxt "help:account.invoice.credit.start,reinvoice_contract:"
|
||||
msgid "If true, the consumption that generated this line will be reinvoiced."
|
||||
msgstr ""
|
||||
"Si es marca, es tornaran a facturar els consums que han generat aquestes "
|
||||
"línies de factura."
|
||||
|
||||
msgctxt "model:contract,name:"
|
||||
msgid "Contract"
|
||||
msgstr "Contracte"
|
||||
|
@ -326,6 +348,14 @@ msgctxt "model:contract.service,name:"
|
|||
msgid "Contract Service"
|
||||
msgstr "Servei de contracte"
|
||||
|
||||
msgctxt "model:ir.action,name:act_consumption_contract_line"
|
||||
msgid "Consumptions"
|
||||
msgstr "Consums"
|
||||
|
||||
msgctxt "model:ir.action,name:act_consumption_contracts"
|
||||
msgid "Consumptions"
|
||||
msgstr "Consums"
|
||||
|
||||
msgctxt "model:ir.action,name:act_contract"
|
||||
msgid "Contract"
|
||||
msgstr "Contractes"
|
||||
|
@ -346,6 +376,14 @@ msgctxt "model:ir.action,name:act_contract_service"
|
|||
msgid "Contract Service"
|
||||
msgstr "Servei de contracte"
|
||||
|
||||
msgctxt "model:ir.action,name:act_invoices"
|
||||
msgid "Invoices"
|
||||
msgstr "Factures"
|
||||
|
||||
msgctxt "model:ir.action,name:act_open_contract"
|
||||
msgid "Contracts"
|
||||
msgstr "Contractes"
|
||||
|
||||
msgctxt "model:ir.action,name:wizard_create_consumptions"
|
||||
msgid "Create Consumptions"
|
||||
msgstr "Crea consums"
|
||||
|
@ -484,6 +522,14 @@ msgctxt "selection:party.party,contract_grouping_method:"
|
|||
msgid "None"
|
||||
msgstr "Cap"
|
||||
|
||||
msgctxt "view:account.invoice.credit.start:"
|
||||
msgid ""
|
||||
"Those/this invoice(s) have been generated from contracts, are you sure you "
|
||||
"want to credit them?"
|
||||
msgstr ""
|
||||
"Aquesta(es) factures s'han generat a través de contracte. Esteu segur que "
|
||||
"les voleu abonar? "
|
||||
|
||||
msgctxt "view:contract.configuration:"
|
||||
msgid "Contract Configuration"
|
||||
msgstr "Configuració de contractes"
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=utf-8\n"
|
||||
|
||||
msgctxt "error:contract.consumption:"
|
||||
msgid "Consumption \"%s\" can not be deleted because it is already invoiced."
|
||||
msgstr "No se puede eliminar el consumo \"%s\" porqué ya esta facturado."
|
||||
|
||||
msgctxt "error:contract.consumption:"
|
||||
msgid ""
|
||||
"Contract Line \"%(contract_line)s\" misses an \"account revenue\" default "
|
||||
|
@ -18,9 +22,13 @@ msgstr ""
|
|||
"Falta la cuenta de ingresos par el producto \"%(product)s\" de la linea de "
|
||||
"contracto \"%(contract_line)s\"."
|
||||
|
||||
msgctxt "error:contract:"
|
||||
msgid "Contract %(contract)s with invalid date \"%(date)s\""
|
||||
msgstr "El contracto %(contract)s tiene fecha de comienzo inválida \"%(date)s\""
|
||||
msgctxt "field:account.invoice.credit.start,from_contract:"
|
||||
msgid "From Contract"
|
||||
msgstr "Proveniente de contrato"
|
||||
|
||||
msgctxt "field:account.invoice.credit.start,reinvoice_contract:"
|
||||
msgid "Reinvoice Contract"
|
||||
msgstr "Refacturar el contrato"
|
||||
|
||||
msgctxt "field:contract,company:"
|
||||
msgid "Company"
|
||||
|
@ -134,6 +142,10 @@ msgctxt "field:contract.consumption,create_uid:"
|
|||
msgid "Create User"
|
||||
msgstr "Usuario creación"
|
||||
|
||||
msgctxt "field:contract.consumption,credit_lines:"
|
||||
msgid "Credit Lines"
|
||||
msgstr "Lineas de abono"
|
||||
|
||||
msgctxt "field:contract.consumption,end_date:"
|
||||
msgid "End Date"
|
||||
msgstr "Fecha finalización"
|
||||
|
@ -154,9 +166,9 @@ msgctxt "field:contract.consumption,invoice_date:"
|
|||
msgid "Invoice Date"
|
||||
msgstr "Fecha factura"
|
||||
|
||||
msgctxt "field:contract.consumption,invoice_line:"
|
||||
msgid "Invoice Line"
|
||||
msgstr "Línea de factura"
|
||||
msgctxt "field:contract.consumption,invoice_lines:"
|
||||
msgid "Invoice Lines"
|
||||
msgstr "Líneas de factura"
|
||||
|
||||
msgctxt "field:contract.consumption,rec_name:"
|
||||
msgid "Name"
|
||||
|
@ -234,6 +246,10 @@ msgctxt "field:contract.line,rec_name:"
|
|||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
msgctxt "field:contract.line,sequence:"
|
||||
msgid "Sequence"
|
||||
msgstr "Secuencia"
|
||||
|
||||
msgctxt "field:contract.line,service:"
|
||||
msgid "Service"
|
||||
msgstr "Servicios"
|
||||
|
@ -298,6 +314,12 @@ msgctxt "field:party.party,contract_grouping_method:"
|
|||
msgid "Contract Grouping Method"
|
||||
msgstr "Método agrupación contratos"
|
||||
|
||||
msgctxt "help:account.invoice.credit.start,reinvoice_contract:"
|
||||
msgid "If true, the consumption that generated this line will be reinvoiced."
|
||||
msgstr ""
|
||||
"Si se marca, el consumo que ha generado estas líneas de contracto será "
|
||||
"refacturado."
|
||||
|
||||
msgctxt "model:contract,name:"
|
||||
msgid "Contract"
|
||||
msgstr "Contrato"
|
||||
|
@ -326,6 +348,14 @@ msgctxt "model:contract.service,name:"
|
|||
msgid "Contract Service"
|
||||
msgstr "Servicio de contrato"
|
||||
|
||||
msgctxt "model:ir.action,name:act_consumption_contract_line"
|
||||
msgid "Consumptions"
|
||||
msgstr "Consumos"
|
||||
|
||||
msgctxt "model:ir.action,name:act_consumption_contracts"
|
||||
msgid "Consumptions"
|
||||
msgstr "Consumos"
|
||||
|
||||
msgctxt "model:ir.action,name:act_contract"
|
||||
msgid "Contract"
|
||||
msgstr "Contratos"
|
||||
|
@ -346,6 +376,14 @@ msgctxt "model:ir.action,name:act_contract_service"
|
|||
msgid "Contract Service"
|
||||
msgstr "Servicio de contrato"
|
||||
|
||||
msgctxt "model:ir.action,name:act_invoices"
|
||||
msgid "Invoices"
|
||||
msgstr "Facturas"
|
||||
|
||||
msgctxt "model:ir.action,name:act_open_contract"
|
||||
msgid "Contracts"
|
||||
msgstr "Contratos"
|
||||
|
||||
msgctxt "model:ir.action,name:wizard_create_consumptions"
|
||||
msgid "Create Consumptions"
|
||||
msgstr "Crear consumos"
|
||||
|
@ -488,6 +526,14 @@ msgctxt "selection:party.party,contract_grouping_method:"
|
|||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
msgctxt "view:account.invoice.credit.start:"
|
||||
msgid ""
|
||||
"Those/this invoice(s) have been generated from contracts, are you sure you "
|
||||
"want to credit them?"
|
||||
msgstr ""
|
||||
"Esta factura(s) se ha generado a partir de contratos, estas seguro que las "
|
||||
"quieres abonar?"
|
||||
|
||||
msgctxt "view:contract.configuration:"
|
||||
msgid "Contract Configuration"
|
||||
msgstr "Configuración de contratos"
|
||||
|
|
11
party.xml
11
party.xml
|
@ -8,5 +8,16 @@
|
|||
<field name="inherit" ref="party.party_view_form"/>
|
||||
<field name="name">party_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_open_contract">
|
||||
<field name="name">Contracts</field>
|
||||
<field name="res_model">contract</field>
|
||||
<field name="domain">[('party', 'in', Eval('active_ids'))]</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword"
|
||||
id="act_open_contract_keyword1">
|
||||
<field name="keyword">form_relate</field>
|
||||
<field name="model">party.party,-1</field>
|
||||
<field name="action" ref="act_open_contract"/>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
|
|
@ -197,9 +197,9 @@ Create two contract for grouped party::
|
|||
>>> contract = Contract()
|
||||
>>> contract.party = party
|
||||
>>> contract.start_period_date = datetime.date(today.year, 01, 01)
|
||||
>>> contract.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> line.first_invoice_date = datetime.date(today.year, 01, 31)
|
||||
>>> line.service = service
|
||||
>>> line.unit_price
|
||||
|
@ -213,6 +213,7 @@ Create two contract for grouped party::
|
|||
>>> contract.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> line.first_invoice_date = datetime.date(today.year, 01, 31)
|
||||
>>> line.service = service
|
||||
>>> line.unit_price
|
||||
|
@ -227,9 +228,9 @@ Create two contract for non grouped party::
|
|||
>>> contract = Contract()
|
||||
>>> contract.party = non_grouping_party
|
||||
>>> contract.start_period_date = datetime.date(today.year, 01, 01)
|
||||
>>> contract.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> line.first_invoice_date = datetime.date(today.year, 01, 31)
|
||||
>>> line.service = service
|
||||
>>> line.unit_price
|
||||
|
@ -243,6 +244,7 @@ Create two contract for non grouped party::
|
|||
>>> contract.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.start_date = datetime.date(today.year, 01, 01)
|
||||
>>> line.first_invoice_date = datetime.date(today.year, 01, 31)
|
||||
>>> line.service = service
|
||||
>>> line.unit_price
|
||||
|
@ -289,4 +291,3 @@ Two invoices are generated for non grouping party::
|
|||
Decimal('40.00')
|
||||
>>> second_invoice.total_amount
|
||||
Decimal('44.00')
|
||||
|
||||
|
|
|
@ -201,11 +201,11 @@ Create a contract::
|
|||
>>> Contract = Model.get('contract')
|
||||
>>> contract = Contract()
|
||||
>>> contract.party = party
|
||||
>>> contract.start_period_date = datetime.date(2015,01,01)
|
||||
>>> contract.start_date = datetime.date(2015,01,01)
|
||||
>>> contract.start_period_date = datetime.date(2015, 01, 01)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.first_invoice_date = datetime.date(2015,01,31)
|
||||
>>> line.start_date = datetime.date(2015, 01, 01)
|
||||
>>> line.first_invoice_date = datetime.date(2015, 01, 31)
|
||||
>>> line.service = service
|
||||
>>> line.unit_price
|
||||
Decimal('40')
|
||||
|
@ -232,7 +232,7 @@ Generate consumed lines::
|
|||
Generate invoice for consumed lines::
|
||||
|
||||
>>> invoices = consumption.click('invoice')
|
||||
>>> invoice = consumption.invoice_line[0].invoice
|
||||
>>> invoice = consumption.invoice_lines[0].invoice
|
||||
>>> invoice.type
|
||||
u'out_invoice'
|
||||
>>> invoice.party == party
|
||||
|
@ -243,7 +243,7 @@ Generate invoice for consumed lines::
|
|||
Decimal('4.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('44.00')
|
||||
>>> consumption.invoice_line[0].product == product
|
||||
>>> consumption.invoice_lines[0].product == product
|
||||
True
|
||||
>>> consumption.invoice_date == invoice.invoice_date
|
||||
True
|
||||
|
|
|
@ -234,7 +234,7 @@ Generate consumed lines::
|
|||
Generate invoice for consumed lines::
|
||||
|
||||
>>> invoices = consumption.click('invoice')
|
||||
>>> invoice = consumption.invoice_line[0].invoice
|
||||
>>> invoice = consumption.invoice_lines[0].invoice
|
||||
>>> invoice.type
|
||||
u'out_invoice'
|
||||
>>> invoice.party == party
|
||||
|
@ -245,7 +245,7 @@ Generate invoice for consumed lines::
|
|||
Decimal('4.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('44.00')
|
||||
>>> consumption.invoice_line[0].product == product
|
||||
>>> consumption.invoice_lines[0].product == product
|
||||
True
|
||||
>>> consumption.invoice_date == invoice.invoice_date
|
||||
True
|
||||
|
|
|
@ -202,10 +202,11 @@ Create a contract::
|
|||
>>> contract = Contract()
|
||||
>>> contract.party = party
|
||||
>>> contract.start_period_date = datetime.date(2015,01,05)
|
||||
>>> contract.start_date = datetime.date(2015,01,05)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.service = service
|
||||
>>> line.start_date = datetime.date(2015,01,05)
|
||||
>>> line.first_invoice_date = datetime.date(2015,02,04)
|
||||
>>> line.unit_price
|
||||
Decimal('40')
|
||||
>>> contract.click('validate_contract')
|
||||
|
@ -235,7 +236,7 @@ Generate consumed lines::
|
|||
Generate invoice for consumed lines::
|
||||
|
||||
>>> invoices = consumption.click('invoice')
|
||||
>>> invoice = consumption.invoice_line[0].invoice
|
||||
>>> invoice = consumption.invoice_lines[0].invoice
|
||||
>>> invoice.type
|
||||
u'out_invoice'
|
||||
>>> invoice.party == party
|
||||
|
@ -246,7 +247,7 @@ Generate invoice for consumed lines::
|
|||
Decimal('4.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('44.00')
|
||||
>>> consumption.invoice_line[0].product == product
|
||||
>>> consumption.invoice_lines[0].product == product
|
||||
True
|
||||
>>> consumption.invoice_date == invoice.invoice_date
|
||||
True
|
||||
|
|
|
@ -152,10 +152,17 @@ Create party::
|
|||
>>> party = Party(name='Party')
|
||||
>>> party.save()
|
||||
|
||||
Create product::
|
||||
|
||||
Configure unit to accept decimals::
|
||||
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
|
||||
>>> unit.rounding = 0.01
|
||||
>>> unit.digits = 2
|
||||
>>> unit.save()
|
||||
|
||||
Create product::
|
||||
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> Product = Model.get('product.product')
|
||||
>>> product = Product()
|
||||
|
@ -201,24 +208,23 @@ Create a contract::
|
|||
>>> Contract = Model.get('contract')
|
||||
>>> contract = Contract()
|
||||
>>> contract.party = party
|
||||
>>> contract.start_period_date = datetime.date(2015,01,01)
|
||||
>>> contract.start_date = datetime.date(2015,01,10)
|
||||
>>> contract.start_period_date = datetime.date(2015, 01, 01)
|
||||
>>> contract.freq = 'monthly'
|
||||
>>> contract.interval = 1
|
||||
>>> contract.first_invoice_date = datetime.date(2015,02,10)
|
||||
>>> line = contract.lines.new()
|
||||
>>> line.start_date = datetime.date(2015, 01, 10)
|
||||
>>> line.first_invoice_date = datetime.date(2015, 02, 10)
|
||||
>>> line.service = service
|
||||
>>> line.unit_price
|
||||
Decimal('40')
|
||||
>>> line.end_date = datetime.date(2015,01,31)
|
||||
>>> line.first_invoice_date = contract.first_invoice_date
|
||||
>>> line.end_date = datetime.date(2015, 01, 31)
|
||||
>>> line2 = contract.lines.new()
|
||||
>>> line2.service = service
|
||||
>>> line2.unit_price = Decimal('100')
|
||||
>>> line2.unit_price
|
||||
Decimal('100')
|
||||
>>> line2.start_date = datetime.date(2015,02,01)
|
||||
>>> line2.first_invoice_date = datetime.date(2015,03,01)
|
||||
>>> line2.start_date = datetime.date(2015, 02, 01)
|
||||
>>> line2.first_invoice_date = datetime.date(2015, 03, 01)
|
||||
>>> contract.click('validate_contract')
|
||||
>>> contract.state
|
||||
u'validated'
|
||||
|
@ -228,49 +234,74 @@ Create a contract::
|
|||
Generate consumed lines::
|
||||
|
||||
>>> create_consumptions = Wizard('contract.create_consumptions')
|
||||
>>> create_consumptions.form.date = datetime.date(2015,03,01)
|
||||
>>> create_consumptions.form.date = datetime.date(2015, 03, 01)
|
||||
>>> create_consumptions.execute('create_consumptions')
|
||||
>>> Consumption = Model.get('contract.consumption')
|
||||
>>> consumption, consumption2 = Consumption.find([])
|
||||
>>> consumption.start_date == datetime.date(2015,01,10)
|
||||
>>> consumption.start_date == datetime.date(2015, 01, 10)
|
||||
True
|
||||
>>> consumption.end_date == datetime.date(2015,01,31)
|
||||
>>> consumption.end_date == datetime.date(2015, 01, 31)
|
||||
True
|
||||
>>> consumption.invoice_date == datetime.date(2015,02,10)
|
||||
>>> consumption.invoice_date == datetime.date(2015, 02, 10)
|
||||
True
|
||||
>>> consumption.init_period_date == datetime.date(2015,01,10)
|
||||
>>> consumption.init_period_date == datetime.date(2015, 01, 01)
|
||||
True
|
||||
>>> consumption.end_period_date == datetime.date(2015,01,31)
|
||||
>>> consumption.end_period_date == datetime.date(2015, 01, 31)
|
||||
True
|
||||
|
||||
>>> consumption2.start_date == datetime.date(2015,02,01)
|
||||
>>> consumption2.start_date == datetime.date(2015, 02, 01)
|
||||
True
|
||||
>>> consumption2.end_date == datetime.date(2015,02,28)
|
||||
>>> consumption2.end_date == datetime.date(2015, 02, 28)
|
||||
True
|
||||
>>> consumption2.invoice_date == datetime.date(2015,03,01)
|
||||
>>> consumption2.invoice_date == datetime.date(2015, 03, 01)
|
||||
True
|
||||
>>> consumption2.init_period_date == datetime.date(2015,02,1)
|
||||
>>> consumption2.init_period_date == datetime.date(2015, 02, 1)
|
||||
True
|
||||
>>> consumption2.end_period_date == datetime.date(2015,02,28)
|
||||
>>> consumption2.end_period_date == datetime.date(2015, 02, 28)
|
||||
True
|
||||
|
||||
|
||||
Generate invoice for consumed lines::
|
||||
Invoice first consumed line::
|
||||
|
||||
>>> invoices = consumption.click('invoice')
|
||||
>>> invoice = consumption.invoice_line[0].invoice
|
||||
>>> invoice = consumption.invoice_lines[0].invoice
|
||||
>>> invoice.type
|
||||
u'out_invoice'
|
||||
>>> invoice.party == party
|
||||
True
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('40.00')
|
||||
Decimal('28.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('4.00')
|
||||
Decimal('2.80')
|
||||
>>> invoice.total_amount
|
||||
Decimal('44.00')
|
||||
>>> consumption.invoice_line[0].product == product
|
||||
Decimal('30.80')
|
||||
>>> consumption.invoice_lines[0].product == product
|
||||
True
|
||||
>>> consumption.invoice_date == invoice.invoice_date
|
||||
True
|
||||
>>> invoice_line, = invoice.lines
|
||||
>>> invoice_line.quantity
|
||||
0.7
|
||||
|
||||
Invoice second consumed line::
|
||||
|
||||
>>> invoices = consumption2.click('invoice')
|
||||
>>> invoice = consumption2.invoice_lines[0].invoice
|
||||
>>> invoice.type
|
||||
u'out_invoice'
|
||||
>>> invoice.party == party
|
||||
True
|
||||
>>> invoice.untaxed_amount
|
||||
Decimal('100.00')
|
||||
>>> invoice.tax_amount
|
||||
Decimal('10.00')
|
||||
>>> invoice.total_amount
|
||||
Decimal('110.00')
|
||||
>>> consumption2.invoice_lines[0].product == product
|
||||
True
|
||||
>>> consumption2.invoice_date == invoice.invoice_date
|
||||
True
|
||||
>>> invoice_line, = invoice.lines
|
||||
>>> invoice_line.quantity
|
||||
1.0
|
||||
|
||||
|
|
|
@ -6,3 +6,4 @@ xml:
|
|||
contract.xml
|
||||
configuration.xml
|
||||
party.xml
|
||||
invoice.xml
|
||||
|
|
|
@ -6,12 +6,17 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="contract" colspan="3"/>
|
||||
<label name="contract_line"/>
|
||||
<field name="contract_line"/>
|
||||
<label name="invoice_date"/>
|
||||
<field name="invoice_date"/>
|
||||
<label name="start_date"/>
|
||||
<field name="start_date"/>
|
||||
<label name="end_date"/>
|
||||
<field name="end_date"/>
|
||||
<label name="invoice_date"/>
|
||||
<field name="invoice_date"/>
|
||||
<field name="invoice_line" colspan="4"/>
|
||||
<label name="init_period_date"/>
|
||||
<field name="init_period_date"/>
|
||||
<label name="end_period_date"/>
|
||||
<field name="end_period_date"/>
|
||||
<field name="invoice_lines" colspan="4"/>
|
||||
<field name="credit_lines" colspan="4"/>
|
||||
<button name="invoice" string="Invoice" icon="tryton-go-next" colspan="4"/>
|
||||
</form>
|
||||
|
|
|
@ -9,6 +9,5 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="invoice_date"/>
|
||||
<field name="init_period_date"/>
|
||||
<field name="end_period_date"/>
|
||||
<field name="invoice_line" tree_invisible="1"/>
|
||||
<button name="invoice" string="Invoice" tree_invisible="1"/>
|
||||
</tree>
|
||||
|
|
|
@ -14,6 +14,8 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="unit_price"/>
|
||||
<label name="first_invoice_date"/>
|
||||
<field name="first_invoice_date"/>
|
||||
<label name="sequence"/>
|
||||
<field name="sequence"/>
|
||||
<separator name="description" colspan="4"/>
|
||||
<field name="description" colspan="4"/>
|
||||
</form>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?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. -->
|
||||
<tree string="Contract Line">
|
||||
<tree string="Contract Line" sequence="sequence">
|
||||
<field name="contract"/>
|
||||
<field name="service"/>
|
||||
<field name="unit_price"/>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form" position="inside">
|
||||
<group col="2" name="from_contract" string="" colspan="2">
|
||||
<image name="tryton-dialog-warning" xexpand="0"
|
||||
xfill="0" states="{'invisible': ~Bool(Eval('from_contract'))}"/>
|
||||
<label string="Those/this invoice(s) have been generated from contracts, are you sure you want to credit them?"
|
||||
id="credit_contract" colspan="2" yalign="0.0" xalign="0.0"
|
||||
xexpand="1" states="{'invisible': ~Bool(Eval('from_contract'))}"/>
|
||||
<label name="reinvoice_contract"/>
|
||||
<field name="reinvoice_contract"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</data>
|
Loading…
Reference in New Issue