Merge PR #207 into 12.0

Signed-off-by pedrobaeza
This commit is contained in:
OCA-git-bot
2019-09-14 13:31:17 +00:00
80 changed files with 5463 additions and 1597 deletions

1
.gitignore vendored
View File

@@ -21,6 +21,7 @@ var/
*.egg-info/ *.egg-info/
.installed.cfg .installed.cfg
*.egg *.egg
*.eggs
# Installer logs # Installer logs
pip-log.txt pip-log.txt

View File

@@ -1 +1,2 @@
from . import models from . import models
from . import wizards

View File

@@ -4,11 +4,12 @@
# Copyright 2016-2018 Tecnativa - Carlos Dauden # Copyright 2016-2018 Tecnativa - Carlos Dauden
# Copyright 2017 Tecnativa - Vicent Cubells # Copyright 2017 Tecnativa - Vicent Cubells
# Copyright 2016-2017 LasLabs Inc. # Copyright 2016-2017 LasLabs Inc.
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
'name': 'Contracts Management - Recurring', 'name': 'Recurring - Contracts Management',
'version': '12.0.1.0.0', 'version': '12.0.4.0.0',
'category': 'Contract Management', 'category': 'Contract Management',
'license': 'AGPL-3', 'license': 'AGPL-3',
'author': "OpenERP SA, " 'author': "OpenERP SA, "
@@ -16,17 +17,22 @@
"LasLabs, " "LasLabs, "
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",
'website': 'https://github.com/oca/contract', 'website': 'https://github.com/oca/contract',
'depends': ['base', 'account', 'analytic'], 'depends': ['base', 'account', 'product'],
"external_dependencies": {"python": ["dateutil"]},
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'security/contract_security.xml', 'security/contract_security.xml',
'report/report_contract.xml', 'report/report_contract.xml',
'report/contract_views.xml', 'report/contract_views.xml',
'data/contract_cron.xml', 'data/contract_cron.xml',
'data/contract_renew_cron.xml',
'data/mail_template.xml', 'data/mail_template.xml',
'views/account_analytic_account_view.xml', 'wizards/contract_line_wizard.xml',
'views/account_analytic_contract_view.xml', 'views/abstract_contract_line.xml',
'views/account_invoice_view.xml', 'views/contract.xml',
'views/contract_line.xml',
'views/contract_template.xml',
'views/contract_template_line.xml',
'views/res_partner_view.xml', 'views/res_partner_view.xml',
], ],
'installable': True, 'installable': True,

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding='UTF-8'?> <?xml version="1.0" encoding='UTF-8'?>
<odoo noupdate="1"> <odoo noupdate="1">
<record model="ir.cron" id="account_analytic_cron_for_invoice"> <record model="ir.cron" id="contract_cron_for_invoice">
<field name="name">Generate Recurring Invoices from Contracts</field> <field name="name">Generate Recurring Invoices from Contracts</field>
<field name="model_id" ref="analytic.model_account_analytic_account"/> <field name="model_id" ref="model_contract_contract"/>
<field name="state">code</field> <field name="state">code</field>
<field name="code">model.cron_recurring_create_invoice()</field> <field name="code">model.cron_recurring_create_invoice()</field>
<field name="user_id" ref="base.user_root" /> <field name="user_id" ref="base.user_root" />

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding='UTF-8'?>
<odoo noupdate="1">
<record model="ir.cron" id="contract_line_cron_for_renew">
<field name="name">Renew Contract lines</field>
<field name="model_id" ref="model_contract_line"/>
<field name="state">code</field>
<field name="code">model.cron_renew_contract_line()</field>
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
</record>
</odoo>

View File

@@ -6,7 +6,7 @@
<field name="email_from">${(object.user_id.email and '%s &lt;%s&gt;' % (object.user_id.name, object.user_id.email) or '')|safe}</field> <field name="email_from">${(object.user_id.email and '%s &lt;%s&gt;' % (object.user_id.name, object.user_id.email) or '')|safe}</field>
<field name="subject">${object.company_id.name} Contract (Ref ${object.name or 'n/a'})</field> <field name="subject">${object.company_id.name} Contract (Ref ${object.name or 'n/a'})</field>
<field name="partner_to">${object.partner_id.id}</field> <field name="partner_to">${object.partner_id.id}</field>
<field name="model_id" ref="contract.model_account_analytic_account"/> <field name="model_id" ref="model_contract_contract"/>
<field name="auto_delete" eval="True"/> <field name="auto_delete" eval="True"/>
<field name="report_template" ref="contract.report_contract"/> <field name="report_template" ref="contract.report_contract"/>
<field name="report_name">Contract</field> <field name="report_name">Contract</field>

View File

@@ -0,0 +1,94 @@
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from openupgradelib import openupgrade
_logger = logging.getLogger(__name__)
def _set_finished_contract(cr):
_logger.info("set recurring_next_date to false for finished contract")
openupgrade.logged_query(
cr,
"""
UPDATE account_analytic_account
SET recurring_next_date=NULL
WHERE recurring_next_date > date_end
""",
)
def _move_contract_recurrence_info_to_contract_line(cr):
_logger.info("Move contract data to line level")
openupgrade.logged_query(
cr,
"""
ALTER TABLE account_analytic_invoice_line
ADD COLUMN IF NOT EXISTS recurring_rule_type VARCHAR(255),
ADD COLUMN IF NOT EXISTS recurring_invoicing_type VARCHAR(255),
ADD COLUMN IF NOT EXISTS recurring_interval INTEGER,
ADD COLUMN IF NOT EXISTS recurring_next_date DATE,
ADD COLUMN IF NOT EXISTS date_start DATE,
ADD COLUMN IF NOT EXISTS date_end DATE
""",
)
openupgrade.logged_query(
cr,
"""
UPDATE account_analytic_invoice_line AS contract_line
SET
recurring_rule_type=contract.recurring_rule_type,
recurring_invoicing_type=contract.recurring_invoicing_type,
recurring_interval=contract.recurring_interval,
recurring_next_date=contract.recurring_next_date,
date_start=contract.date_start,
date_end=contract.date_end
FROM
account_analytic_account AS contract
WHERE
contract.id=contract_line.analytic_account_id
""",
)
def _move_contract_template_recurrence_info_to_contract_template_line(cr):
_logger.info("Move contract template data to line level")
openupgrade.logged_query(
cr,
"""
ALTER TABLE account_analytic_contract_line
ADD COLUMN IF NOT EXISTS recurring_rule_type VARCHAR(255),
ADD COLUMN IF NOT EXISTS recurring_invoicing_type VARCHAR(255),
ADD COLUMN IF NOT EXISTS recurring_interval INTEGER
""",
)
openupgrade.logged_query(
cr,
"""
UPDATE account_analytic_contract_line AS contract_template_line
SET
recurring_rule_type=contract_template.recurring_rule_type,
recurring_invoicing_type=contract_template.recurring_invoicing_type,
recurring_interval=contract_template.recurring_interval
FROM
account_analytic_contract AS contract_template
WHERE
contract_template.id=contract_template_line.analytic_account_id
""",
)
@openupgrade.migrate()
def migrate(env, version):
"""
set recurring_next_date to false for finished contract
"""
_logger.info(">> Pre-Migration 12.0.2.0.0")
cr = env.cr
_set_finished_contract(cr)
_move_contract_recurrence_info_to_contract_line(cr)
_move_contract_template_recurrence_info_to_contract_template_line(cr)

View File

@@ -0,0 +1,47 @@
# Copyright 2019 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from openupgradelib import openupgrade
from odoo.tools import parse_version
_logger = logging.getLogger(__name__)
def _update_no_update_ir_cron(env):
# Update ir.cron
env.ref('contract.contract_cron_for_invoice').model_id = env.ref(
'contract.model_contract_contract'
)
env.ref('contract.contract_line_cron_for_renew').model_id = env.ref(
'contract.model_contract_line'
)
env.ref('contract.email_contract_template').model_id = env.ref(
'contract.model_contract_contract'
)
def _init_last_date_invoiced_on_contract_lines(env):
_logger.info("init last_date_invoiced field for contract lines")
contract_lines = env["contract.line"].search(
[("recurring_next_date", "!=", False)]
)
contract_lines._init_last_date_invoiced()
def _init_invoicing_partner_id_on_contracts(env):
_logger.info("Populate invoicing partner field on contracts")
contracts = env["contract.contract"].search([])
contracts._inverse_partner_id()
@openupgrade.migrate()
def migrate(env, version):
_update_no_update_ir_cron(env)
if parse_version(version) < parse_version('12.0.2.0.0'):
# We check the version here as this post-migration script was in
# 12.0.2.0.0 and already done for those who used the module when
# it was a PR
_init_last_date_invoiced_on_contract_lines(env)
_init_invoicing_partner_id_on_contracts(env)

View File

@@ -0,0 +1,113 @@
# Copyright 2019 ACSONE SA/NV
# Copyright 2019 Tecnativa 2019 - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from openupgradelib import openupgrade
from psycopg2 import sql
_logger = logging.getLogger(__name__)
models_to_rename = [
# Contract Line Wizard
('account.analytic.invoice.line.wizard', 'contract.line.wizard'),
# Abstract Contract
('account.abstract.analytic.contract', 'contract.abstract.contract'),
# Abstract Contract Line
(
'account.abstract.analytic.contract.line',
'contract.abstract.contract.line',
),
# Contract Line
('account.analytic.invoice.line', 'contract.line'),
# Contract Template
('account.analytic.contract', 'contract.template'),
# Contract Template Line
('account.analytic.contract.line', 'contract.template.line'),
]
tables_to_rename = [
# Contract Line
('account_analytic_invoice_line', 'contract_line'),
# Contract Template
('account_analytic_contract', 'contract_template'),
# Contract Template Line
('account_analytic_contract_line', 'contract_template_line'),
]
columns_to_copy = {
'contract_line': [
('analytic_account_id', 'contract_id', None),
],
}
xmlids_to_rename = [
(
'contract.account_analytic_cron_for_invoice',
'contract.contract_cron_for_invoice',
),
(
'contract.account_analytic_contract_manager',
'contract.contract_template_manager',
),
(
'contract.account_analytic_contract_user',
'contract.contract_template_user',
),
(
'contract.account_analytic_invoice_line_manager',
'contract.contract_line_manager',
),
(
'contract.account_analytic_invoice_line_user',
'contract.contract_line_user',
),
(
'contract.account_analytic_contract_line_manager',
'contract.contract_template_line_manager',
),
(
'contract.account_analytic_contract_line_user',
'contract.contract_template_line_user',
),
]
def _get_contract_field_name(cr):
"""
Contract field changed the name from analytic_account_id to contract_id
in 12.0.2.0.0. This method used to get the contract field name in
account_analytic_invoice_line"""
return (
'contract_id'
if openupgrade.column_exists(
cr, 'account_analytic_invoice_line', 'contract_id'
)
else 'analytic_account_id'
)
def create_contract_records(cr):
contract_field_name = _get_contract_field_name(cr)
openupgrade.logged_query(
cr, """
CREATE TABLE contract_contract
(LIKE account_analytic_account INCLUDING ALL)""",
)
openupgrade.logged_query(
cr, sql.SQL("""
INSERT INTO contract_contract
SELECT * FROM account_analytic_account
WHERE id IN (SELECT DISTINCT {} FROM contract_line)
""").format(
sql.Identifier(contract_field_name),
),
)
@openupgrade.migrate()
def migrate(env, version):
cr = env.cr
openupgrade.rename_models(cr, models_to_rename)
openupgrade.rename_tables(cr, tables_to_rename)
openupgrade.rename_xmlids(cr, xmlids_to_rename)
openupgrade.copy_columns(cr, columns_to_copy)
create_contract_records(cr)

View File

@@ -1,8 +1,11 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import account_analytic_contract from . import abstract_contract
from . import account_analytic_account from . import abstract_contract_line
from . import account_analytic_contract_line from . import contract_template
from . import account_analytic_invoice_line from . import contract
from . import contract_template_line
from . import contract_line
from . import account_invoice from . import account_invoice
from . import account_invoice_line
from . import res_partner from . import res_partner

View File

@@ -0,0 +1,73 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields
class ContractAbstractContract(models.AbstractModel):
_name = 'contract.abstract.contract'
_description = 'Abstract Recurring Contract'
# These fields will not be synced to the contract
NO_SYNC = ['name', 'partner_id']
name = fields.Char(required=True)
# Needed for avoiding errors on several inherited behaviors
partner_id = fields.Many2one(
comodel_name="res.partner", string="Partner (always False)", index=True
)
pricelist_id = fields.Many2one(
comodel_name='product.pricelist', string='Pricelist'
)
contract_type = fields.Selection(
selection=[('sale', 'Customer'), ('purchase', 'Supplier')],
default='sale',
index=True,
)
journal_id = fields.Many2one(
'account.journal',
string='Journal',
default=lambda s: s._default_journal(),
domain="[('type', '=', contract_type),"
"('company_id', '=', company_id)]",
index=True,
)
company_id = fields.Many2one(
'res.company',
string='Company',
required=True,
default=lambda self: self.env['res.company']._company_default_get(
self._name
),
)
@api.onchange('contract_type')
def _onchange_contract_type(self):
if self.contract_type == 'purchase':
self.contract_line_ids.filtered('automatic_price').update(
{'automatic_price': False}
)
self.journal_id = self.env['account.journal'].search(
[
('type', '=', self.contract_type),
('company_id', '=', self.company_id.id),
],
limit=1,
)
@api.model
def _default_journal(self):
company_id = self.env.context.get(
'company_id', self.env.user.company_id.id
)
domain = [
('type', '=', self.contract_type),
('company_id', '=', company_id),
]
return self.env['account.journal'].search(domain, limit=1)

View File

@@ -0,0 +1,206 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields
from odoo.addons import decimal_precision as dp
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
class ContractAbstractContractLine(models.AbstractModel):
_name = 'contract.abstract.contract.line'
_description = 'Abstract Recurring Contract Line'
product_id = fields.Many2one(
'product.product', string='Product', required=True
)
name = fields.Text(string='Description', required=True)
quantity = fields.Float(default=1.0, required=True)
uom_id = fields.Many2one(
'uom.uom', string='Unit of Measure', required=True
)
automatic_price = fields.Boolean(
string="Auto-price?",
help="If this is marked, the price will be obtained automatically "
"applying the pricelist to the product. If not, you will be "
"able to introduce a manual price",
)
specific_price = fields.Float(string='Specific Price')
price_unit = fields.Float(
string='Unit Price',
compute="_compute_price_unit",
inverse="_inverse_price_unit",
)
price_subtotal = fields.Float(
compute='_compute_price_subtotal',
digits=dp.get_precision('Account'),
string='Sub Total',
)
discount = fields.Float(
string='Discount (%)',
digits=dp.get_precision('Discount'),
help='Discount that is applied in generated invoices.'
' It should be less or equal to 100',
)
sequence = fields.Integer(
string="Sequence",
default=10,
help="Sequence of the contract line when displaying contracts",
)
recurring_rule_type = fields.Selection(
[
('daily', 'Day(s)'),
('weekly', 'Week(s)'),
('monthly', 'Month(s)'),
('monthlylastday', 'Month(s) last day'),
('yearly', 'Year(s)'),
],
default='monthly',
string='Recurrence',
help="Specify Interval for automatic invoice generation.",
required=True,
)
recurring_invoicing_type = fields.Selection(
[('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')],
default='pre-paid',
string='Invoicing type',
help="Specify if process date is 'from' or 'to' invoicing date",
required=True,
)
recurring_interval = fields.Integer(
default=1,
string='Invoice Every',
help="Invoice every (Days/Week/Month/Year)",
required=True,
)
date_start = fields.Date(string='Date Start')
recurring_next_date = fields.Date(string='Date of Next Invoice')
last_date_invoiced = fields.Date(string='Last Date Invoiced')
is_canceled = fields.Boolean(string="Canceled", default=False)
is_auto_renew = fields.Boolean(string="Auto Renew", default=False)
auto_renew_interval = fields.Integer(
default=1,
string='Renew Every',
help="Renew every (Days/Week/Month/Year)",
)
auto_renew_rule_type = fields.Selection(
[
('daily', 'Day(s)'),
('weekly', 'Week(s)'),
('monthly', 'Month(s)'),
('yearly', 'Year(s)'),
],
default='yearly',
string='Renewal type',
help="Specify Interval for automatic renewal.",
)
termination_notice_interval = fields.Integer(
default=1, string='Termination Notice Before'
)
termination_notice_rule_type = fields.Selection(
[('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)')],
default='monthly',
string='Termination Notice type',
)
contract_id = fields.Many2one(
string='Contract',
comodel_name='contract.abstract.contract',
required=True,
ondelete='cascade',
)
@api.depends(
'automatic_price',
'specific_price',
'product_id',
'quantity',
'contract_id.pricelist_id',
'contract_id.partner_id',
)
def _compute_price_unit(self):
"""Get the specific price if no auto-price, and the price obtained
from the pricelist otherwise.
"""
for line in self:
if line.automatic_price:
product = line.product_id.with_context(
quantity=line.env.context.get(
'contract_line_qty',
line.quantity,
),
pricelist=line.contract_id.pricelist_id.id,
partner=line.contract_id.partner_id.id,
date=line.env.context.get(
'old_date', fields.Date.context_today(line)
),
)
line.price_unit = product.price
else:
line.price_unit = line.specific_price
# Tip in https://github.com/odoo/odoo/issues/23891#issuecomment-376910788
@api.onchange('price_unit')
def _inverse_price_unit(self):
"""Store the specific price in the no auto-price records."""
for line in self.filtered(lambda x: not x.automatic_price):
line.specific_price = line.price_unit
@api.multi
@api.depends('quantity', 'price_unit', 'discount')
def _compute_price_subtotal(self):
for line in self:
subtotal = line.quantity * line.price_unit
discount = line.discount / 100
subtotal *= 1 - discount
if line.contract_id.pricelist_id:
cur = line.contract_id.pricelist_id.currency_id
line.price_subtotal = cur.round(subtotal)
else:
line.price_subtotal = subtotal
@api.multi
@api.constrains('discount')
def _check_discount(self):
for line in self:
if line.discount > 100:
raise ValidationError(
_("Discount should be less or equal to 100")
)
@api.multi
@api.onchange('product_id')
def _onchange_product_id(self):
if not self.product_id:
return {'domain': {'uom_id': []}}
vals = {}
domain = {
'uom_id': [
('category_id', '=', self.product_id.uom_id.category_id.id)
]
}
if not self.uom_id or (
self.product_id.uom_id.category_id.id != self.uom_id.category_id.id
):
vals['uom_id'] = self.product_id.uom_id
date = self.recurring_next_date or fields.Date.context_today(self)
partner = self.contract_id.partner_id or self.env.user.partner_id
product = self.product_id.with_context(
lang=partner.lang,
partner=partner.id,
quantity=self.quantity,
date=date,
pricelist=self.contract_id.pricelist_id.id,
uom=self.uom_id.id,
)
vals['name'] = self.product_id.get_product_multiline_description_sale()
vals['price_unit'] = product.price
self.update(vals)
return {'domain': domain}

View File

@@ -1,361 +0,0 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
class AccountAnalyticAccount(models.Model):
_name = 'account.analytic.account'
_inherit = ['account.analytic.account',
'account.analytic.contract',
]
contract_template_id = fields.Many2one(
string='Contract Template',
comodel_name='account.analytic.contract',
)
recurring_invoice_line_ids = fields.One2many(
string='Invoice Lines',
comodel_name='account.analytic.invoice.line',
inverse_name='analytic_account_id',
copy=True,
)
date_start = fields.Date(
string='Date Start',
default=fields.Date.context_today,
)
date_end = fields.Date(
string='Date End',
index=True,
)
recurring_invoices = fields.Boolean(
string='Generate recurring invoices automatically',
)
recurring_next_date = fields.Date(
default=fields.Date.context_today,
copy=False,
string='Date of Next Invoice',
)
user_id = fields.Many2one(
comodel_name='res.users',
string='Responsible',
index=True,
default=lambda self: self.env.user,
)
create_invoice_visibility = fields.Boolean(
compute='_compute_create_invoice_visibility',
)
@api.depends('recurring_next_date', 'date_end')
def _compute_create_invoice_visibility(self):
for contract in self:
contract.create_invoice_visibility = (
not contract.date_end or
contract.recurring_next_date <= contract.date_end
)
@api.onchange('contract_template_id')
def _onchange_contract_template_id(self):
"""Update the contract fields with that of the template.
Take special consideration with the `recurring_invoice_line_ids`,
which must be created using the data from the contract lines. Cascade
deletion ensures that any errant lines that are created are also
deleted.
"""
contract = self.contract_template_id
if not contract:
return
for field_name, field in contract._fields.items():
if field.name == 'recurring_invoice_line_ids':
lines = self._convert_contract_lines(contract)
self.recurring_invoice_line_ids = lines
elif not any((
field.compute, field.related, field.automatic,
field.readonly, field.company_dependent,
field.name in self.NO_SYNC,
)):
self[field_name] = self.contract_template_id[field_name]
@api.onchange('date_start')
def _onchange_date_start(self):
if self.date_start:
self.recurring_next_date = self.date_start
@api.onchange('partner_id')
def _onchange_partner_id(self):
self.pricelist_id = self.partner_id.property_product_pricelist.id
@api.constrains('partner_id', 'recurring_invoices')
def _check_partner_id_recurring_invoices(self):
for contract in self.filtered('recurring_invoices'):
if not contract.partner_id:
raise ValidationError(
_("You must supply a customer for the contract '%s'") %
contract.name
)
@api.constrains('recurring_next_date', 'date_start')
def _check_recurring_next_date_start_date(self):
for contract in self.filtered('recurring_next_date'):
if contract.date_start > contract.recurring_next_date:
raise ValidationError(
_("You can't have a next invoicing date before the start "
"of the contract '%s'") % contract.name
)
@api.constrains('recurring_next_date', 'recurring_invoices')
def _check_recurring_next_date_recurring_invoices(self):
for contract in self.filtered('recurring_invoices'):
if not contract.recurring_next_date:
raise ValidationError(
_("You must supply a next invoicing date for contract "
"'%s'") % contract.name
)
@api.constrains('date_start', 'recurring_invoices')
def _check_date_start_recurring_invoices(self):
for contract in self.filtered('recurring_invoices'):
if not contract.date_start:
raise ValidationError(
_("You must supply a start date for contract '%s'") %
contract.name
)
@api.constrains('date_start', 'date_end')
def _check_start_end_dates(self):
for contract in self.filtered('date_end'):
if contract.date_start > contract.date_end:
raise ValidationError(
_("Contract '%s' start date can't be later than end date")
% contract.name
)
@api.multi
def _convert_contract_lines(self, contract):
self.ensure_one()
new_lines = []
for contract_line in contract.recurring_invoice_line_ids:
vals = contract_line._convert_to_write(contract_line.read()[0])
# Remove template link field named as analytic account field
vals.pop('analytic_account_id', False)
new_lines.append((0, 0, vals))
return new_lines
@api.model
def get_relative_delta(self, recurring_rule_type, interval):
if recurring_rule_type == 'daily':
return relativedelta(days=interval)
elif recurring_rule_type == 'weekly':
return relativedelta(weeks=interval)
elif recurring_rule_type == 'monthly':
return relativedelta(months=interval)
elif recurring_rule_type == 'monthlylastday':
return relativedelta(months=interval, day=31)
else:
return relativedelta(years=interval)
@api.model
def _insert_markers(self, line, date_format):
date_from = fields.Date.from_string(line.date_from)
date_to = fields.Date.from_string(line.date_to)
name = line.name
name = name.replace('#START#', date_from.strftime(date_format))
name = name.replace('#END#', date_to.strftime(date_format))
return name
@api.model
def _prepare_invoice_line(self, line, invoice_id):
invoice_line = self.env['account.invoice.line'].new({
'invoice_id': invoice_id,
'product_id': line.product_id.id,
'quantity': line.quantity,
'uom_id': line.uom_id.id,
'discount': line.discount,
})
# Get other invoice line values from product onchange
invoice_line._onchange_product_id()
invoice_line_vals = invoice_line._convert_to_write(invoice_line._cache)
# Insert markers
contract = line.analytic_account_id
lang_obj = self.env['res.lang']
lang = lang_obj.search(
[('code', '=', contract.partner_id.lang)])
date_format = lang.date_format or '%m/%d/%Y'
name = self._insert_markers(line, date_format)
invoice_line_vals.update({
'name': name,
'account_analytic_id': contract.id,
'price_unit': line.price_unit,
})
return invoice_line_vals
@api.multi
def _prepare_invoice(self, journal=None):
self.ensure_one()
if not self.partner_id:
if self.contract_type == 'purchase':
raise ValidationError(
_("You must first select a Supplier for Contract %s!") %
self.name)
else:
raise ValidationError(
_("You must first select a Customer for Contract %s!") %
self.name)
if not journal:
journal = self.journal_id or self.env['account.journal'].search([
('type', '=', self.contract_type),
('company_id', '=', self.company_id.id)
], limit=1)
if not journal:
raise ValidationError(
_("Please define a %s journal for the company '%s'.") %
(self.contract_type, self.company_id.name or '')
)
currency = (
self.pricelist_id.currency_id or
self.partner_id.property_product_pricelist.currency_id or
self.company_id.currency_id
)
invoice_type = 'out_invoice'
if self.contract_type == 'purchase':
invoice_type = 'in_invoice'
invoice = self.env['account.invoice'].new({
'reference': self.code,
'type': invoice_type,
'partner_id': self.partner_id.address_get(
['invoice'])['invoice'],
'currency_id': currency.id,
'journal_id': journal.id,
'date_invoice': self.recurring_next_date,
'origin': self.name,
'company_id': self.company_id.id,
'contract_id': self.id,
'user_id': self.partner_id.user_id.id,
})
# Get other invoice values from partner onchange
invoice._onchange_partner_id()
return invoice._convert_to_write(invoice._cache)
@api.multi
def _prepare_invoice_update(self, invoice):
vals = self._prepare_invoice()
update_vals = {
'contract_id': self.id,
'date_invoice': vals.get('date_invoice', False),
'reference': ' '.join(filter(None, [
invoice.reference, vals.get('reference')])),
'origin': ' '.join(filter(None, [
invoice.origin, vals.get('origin')])),
}
return update_vals
@api.multi
def _create_invoice(self, invoice=False):
"""
:param invoice: If not False add lines to this invoice
:return: invoice created or updated
"""
self.ensure_one()
if invoice and invoice.state == 'draft':
invoice.update(self._prepare_invoice_update(invoice))
else:
invoice = self.env['account.invoice'].create(
self._prepare_invoice())
for line in self.recurring_invoice_line_ids:
invoice_line_vals = self._prepare_invoice_line(line, invoice.id)
if invoice_line_vals:
self.env['account.invoice.line'].create(invoice_line_vals)
invoice.compute_taxes()
return invoice
@api.multi
def recurring_create_invoice(self):
"""Create invoices from contracts
:return: invoices created
"""
invoices = self.env['account.invoice']
for contract in self:
ref_date = contract.recurring_next_date or fields.Date.today()
if (contract.date_start > ref_date or
contract.date_end and contract.date_end < ref_date):
if self.env.context.get('cron'):
continue # Don't fail on cron jobs
raise ValidationError(
_("You must review start and end dates!\n%s") %
contract.name
)
old_date = fields.Date.from_string(ref_date)
new_date = old_date + self.get_relative_delta(
contract.recurring_rule_type, contract.recurring_interval)
ctx = self.env.context.copy()
ctx.update({
'old_date': old_date,
'next_date': new_date,
# Force company for correct evaluation of domain access rules
'force_company': contract.company_id.id,
})
# Re-read contract with correct company
invoices |= contract.with_context(ctx)._create_invoice()
contract.write({
'recurring_next_date': fields.Date.to_string(new_date)
})
return invoices
@api.model
def cron_recurring_create_invoice(self):
today = fields.Date.today()
contracts = self.with_context(cron=True).search([
('recurring_invoices', '=', True),
('recurring_next_date', '<=', today),
'|',
('date_end', '=', False),
('date_end', '>=', today),
])
return contracts.recurring_create_invoice()
@api.multi
def action_contract_send(self):
self.ensure_one()
template = self.env.ref(
'contract.email_contract_template',
False,
)
compose_form = self.env.ref('mail.email_compose_message_wizard_form')
ctx = dict(
default_model='account.analytic.account',
default_res_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
default_composition_mode='comment',
)
return {
'name': _('Compose Email'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form.id, 'form')],
'view_id': compose_form.id,
'target': 'new',
'context': ctx,
}
@api.multi
def button_show_recurring_invoices(self):
self.ensure_one()
action = self.env.ref(
'contract.act_purchase_recurring_invoices')
if self.contract_type == 'sale':
action = self.env.ref(
'contract.act_recurring_invoices')
return action.read()[0]

View File

@@ -1,100 +0,0 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2015-2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountAnalyticContract(models.Model):
_name = 'account.analytic.contract'
_description = "Account Analytic Contract"
# These fields will not be synced to the contract
NO_SYNC = [
'name',
'partner_id',
]
name = fields.Char(
required=True,
)
# Needed for avoiding errors on several inherited behaviors
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Partner (always False)",
)
contract_type = fields.Selection(
selection=[
('sale', 'Customer'),
('purchase', 'Supplier'),
], default='sale',
)
pricelist_id = fields.Many2one(
comodel_name='product.pricelist',
string='Pricelist',
)
recurring_invoice_line_ids = fields.One2many(
comodel_name='account.analytic.contract.line',
inverse_name='analytic_account_id',
copy=True,
string='Invoice Lines',
)
recurring_rule_type = fields.Selection(
[('daily', 'Day(s)'),
('weekly', 'Week(s)'),
('monthly', 'Month(s)'),
('monthlylastday', 'Month(s) last day'),
('yearly', 'Year(s)'),
],
default='monthly',
string='Recurrence',
help="Specify Interval for automatic invoice generation.",
)
recurring_invoicing_type = fields.Selection(
[('pre-paid', 'Pre-paid'),
('post-paid', 'Post-paid'),
],
default='pre-paid',
string='Invoicing type',
help="Specify if process date is 'from' or 'to' invoicing date",
)
recurring_interval = fields.Integer(
default=1,
string='Repeat Every',
help="Repeat every (Days/Week/Month/Year)",
)
journal_id = fields.Many2one(
'account.journal',
string='Journal',
default=lambda s: s._default_journal(),
domain="[('type', '=', contract_type),"
"('company_id', '=', company_id)]",
)
company_id = fields.Many2one(
'res.company',
string='Company',
required=True,
default=lambda self: self.env.user.company_id,
)
@api.onchange('contract_type')
def _onchange_contract_type(self):
if self.contract_type == 'purchase':
self.recurring_invoice_line_ids.filtered('automatic_price').update(
{'automatic_price': False})
self.journal_id = self.env['account.journal'].search([
('type', '=', self.contract_type),
('company_id', '=', self.company_id.id)
], limit=1)
@api.model
def _default_journal(self):
company_id = self.env.context.get(
'company_id', self.env.user.company_id.id)
domain = [
('type', '=', self.contract_type),
('company_id', '=', company_id)]
return self.env['account.journal'].search(domain, limit=1)

View File

@@ -1,221 +0,0 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2015-2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models
from odoo.addons import decimal_precision as dp
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
class AccountAnalyticContractLine(models.Model):
_name = 'account.analytic.contract.line'
_description = 'Contract Lines'
_order = "sequence,id"
product_id = fields.Many2one(
'product.product',
string='Product',
required=True,
)
analytic_account_id = fields.Many2one(
string='Contract',
comodel_name='account.analytic.contract',
required=True,
ondelete='cascade',
)
name = fields.Text(
string='Description',
required=True,
)
quantity = fields.Float(
default=1.0,
required=True,
)
uom_id = fields.Many2one(
'uom.uom',
string='Unit of Measure',
required=True,
)
automatic_price = fields.Boolean(
string="Auto-price?",
help="If this is marked, the price will be obtained automatically "
"applying the pricelist to the product. If not, you will be "
"able to introduce a manual price",
)
specific_price = fields.Float(
string='Specific Price',
)
price_unit = fields.Float(
string='Unit Price',
compute="_compute_price_unit",
inverse="_inverse_price_unit",
)
price_subtotal = fields.Float(
compute='_compute_price_subtotal',
digits=dp.get_precision('Account'),
string='Sub Total',
)
discount = fields.Float(
string='Discount (%)',
digits=dp.get_precision('Discount'),
help='Discount that is applied in generated invoices.'
' It should be less or equal to 100',
)
sequence = fields.Integer(
string="Sequence",
default=10,
help="Sequence of the contract line when displaying contracts",
)
date_from = fields.Date(
string='Date From',
compute='_compute_date_from',
help='Date from invoiced period',
)
date_to = fields.Date(
string='Date To',
compute='_compute_date_to',
help='Date to invoiced period',
)
@api.depends(
'automatic_price',
'specific_price',
'product_id',
'quantity',
'analytic_account_id.pricelist_id',
'analytic_account_id.partner_id',
)
def _compute_price_unit(self):
"""Get the specific price if no auto-price, and the price obtained
from the pricelist otherwise.
"""
for line in self:
if line.automatic_price:
product = line.product_id.with_context(
quantity=line.env.context.get(
'contract_line_qty', line.quantity,
),
pricelist=line.analytic_account_id.pricelist_id.id,
partner=line.analytic_account_id.partner_id.id,
date=line.env.context.get('old_date', fields.Date.today()),
)
line.price_unit = product.price
else:
line.price_unit = line.specific_price
# Tip in https://github.com/odoo/odoo/issues/23891#issuecomment-376910788
@api.onchange('price_unit')
def _inverse_price_unit(self):
"""Store the specific price in the no auto-price records."""
for line in self.filtered(lambda x: not x.automatic_price):
line.specific_price = line.price_unit
@api.multi
@api.depends('quantity', 'price_unit', 'discount')
def _compute_price_subtotal(self):
for line in self:
subtotal = line.quantity * line.price_unit
discount = line.discount / 100
subtotal *= 1 - discount
if line.analytic_account_id.pricelist_id:
cur = line.analytic_account_id.pricelist_id.currency_id
line.price_subtotal = cur.round(subtotal)
else:
line.price_subtotal = subtotal
def _compute_date_from(self):
# When call from template line.analytic_account_id comodel is
# 'account.analytic.contract',
if self._name != 'account.analytic.invoice.line':
return
for line in self:
contract = line.analytic_account_id
date_start = (
self.env.context.get('old_date') or fields.Date.from_string(
contract.recurring_next_date or fields.Date.today())
)
if contract.recurring_invoicing_type == 'pre-paid':
date_from = date_start
else:
date_from = (date_start - contract.get_relative_delta(
contract.recurring_rule_type,
contract.recurring_interval) + relativedelta(days=1))
line.date_from = fields.Date.to_string(date_from)
def _compute_date_to(self):
# When call from template line.analytic_account_id comodel is
# 'account.analytic.contract',
if self._name != 'account.analytic.invoice.line':
return
for line in self:
contract = line.analytic_account_id
date_start = (
self.env.context.get('old_date') or fields.Date.from_string(
contract.recurring_next_date or fields.Date.today())
)
next_date = (
self.env.context.get('next_date') or
date_start + contract.get_relative_delta(
contract.recurring_rule_type, contract.recurring_interval)
)
if contract.recurring_invoicing_type == 'pre-paid':
date_to = next_date - relativedelta(days=1)
else:
date_to = date_start
line.date_to = fields.Date.to_string(date_to)
@api.multi
@api.constrains('discount')
def _check_discount(self):
for line in self:
if line.discount > 100:
raise ValidationError(
_("Discount should be less or equal to 100"))
@api.multi
@api.onchange('product_id')
def _onchange_product_id(self):
if not self.product_id:
return {'domain': {'uom_id': []}}
vals = {}
domain = {'uom_id': [
('category_id', '=', self.product_id.uom_id.category_id.id)]}
if not self.uom_id or (self.product_id.uom_id.category_id.id !=
self.uom_id.category_id.id):
vals['uom_id'] = self.product_id.uom_id
if self.analytic_account_id._name == 'account.analytic.account':
date = (
self.analytic_account_id.recurring_next_date or
fields.Date.today()
)
partner = self.analytic_account_id.partner_id
else:
date = fields.Date.today()
partner = self.env.user.partner_id
product = self.product_id.with_context(
lang=partner.lang,
partner=partner.id,
quantity=self.quantity,
date=date,
pricelist=self.analytic_account_id.pricelist_id.id,
uom=self.uom_id.id
)
name = product.name_get()[0][1]
if product.description_sale:
name += '\n' + product.description_sale
vals['name'] = name
vals['price_unit'] = product.price
self.update(vals)
return {'domain': domain}

View File

@@ -1,16 +0,0 @@
# Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class AccountAnalyticInvoiceLine(models.Model):
_name = 'account.analytic.invoice.line'
_inherit = 'account.analytic.contract.line'
analytic_account_id = fields.Many2one(
comodel_name='account.analytic.account',
string='Analytic Account',
required=True,
ondelete='cascade',
)

View File

@@ -7,6 +7,5 @@ from odoo import fields, models
class AccountInvoice(models.Model): class AccountInvoice(models.Model):
_inherit = 'account.invoice' _inherit = 'account.invoice'
contract_id = fields.Many2one( # We keep this field for migration purpose
'account.analytic.account', old_contract_id = fields.Many2one('contract.contract')
string='Contract')

View File

@@ -0,0 +1,12 @@
# Copyright 2018 ACSONE SA/NV.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class AccountInvoiceLine(models.Model):
_inherit = 'account.invoice.line'
contract_line_id = fields.Many2one(
'contract.line', string='Contract Line', index=True
)

457
contract/models/contract.py Normal file
View File

@@ -0,0 +1,457 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
class ContractContract(models.Model):
_name = 'contract.contract'
_description = "Contract"
_order = 'code, name asc'
_inherit = [
'mail.thread',
'mail.activity.mixin',
'contract.abstract.contract',
]
active = fields.Boolean(
default=True,
)
code = fields.Char(
string="Reference",
)
group_id = fields.Many2one(
string="Group",
comodel_name='account.analytic.account',
ondelete='restrict',
)
currency_id = fields.Many2one(
related="company_id.currency_id",
string="Currency",
readonly=True,
)
contract_template_id = fields.Many2one(
string='Contract Template', comodel_name='contract.template'
)
contract_line_ids = fields.One2many(
string='Contract lines',
comodel_name='contract.line',
inverse_name='contract_id',
copy=True,
)
user_id = fields.Many2one(
comodel_name='res.users',
string='Responsible',
index=True,
default=lambda self: self.env.user,
)
create_invoice_visibility = fields.Boolean(
compute='_compute_create_invoice_visibility'
)
recurring_next_date = fields.Date(
compute='_compute_recurring_next_date',
string='Date of Next Invoice',
store=True,
)
date_end = fields.Date(
compute='_compute_date_end', string='Date End', store=True
)
payment_term_id = fields.Many2one(
comodel_name='account.payment.term', string='Payment Terms', index=True
)
invoice_count = fields.Integer(compute="_compute_invoice_count")
fiscal_position_id = fields.Many2one(
comodel_name='account.fiscal.position',
string='Fiscal Position',
ondelete='restrict',
)
invoice_partner_id = fields.Many2one(
string="Invoicing contact",
comodel_name='res.partner',
ondelete='restrict',
)
partner_id = fields.Many2one(
comodel_name='res.partner',
inverse='_inverse_partner_id',
required=True
)
@api.multi
def _inverse_partner_id(self):
for rec in self:
if not rec.invoice_partner_id:
rec.invoice_partner_id = rec.partner_id.address_get(
['invoice']
)['invoice']
@api.multi
def _get_related_invoices(self):
self.ensure_one()
invoices = (
self.env['account.invoice.line']
.search(
[
(
'contract_line_id',
'in',
self.contract_line_ids.ids,
)
]
)
.mapped('invoice_id')
)
invoices |= self.env['account.invoice'].search(
[('old_contract_id', '=', self.id)]
)
return invoices
@api.multi
def _compute_invoice_count(self):
for rec in self:
rec.invoice_count = len(rec._get_related_invoices())
@api.multi
def action_show_invoices(self):
self.ensure_one()
tree_view_ref = (
'account.invoice_supplier_tree'
if self.contract_type == 'purchase'
else 'account.invoice_tree_with_onboarding'
)
form_view_ref = (
'account.invoice_supplier_form'
if self.contract_type == 'purchase'
else 'account.invoice_form'
)
tree_view = self.env.ref(tree_view_ref, raise_if_not_found=False)
form_view = self.env.ref(form_view_ref, raise_if_not_found=False)
action = {
'type': 'ir.actions.act_window',
'name': 'Invoices',
'res_model': 'account.invoice',
'view_type': 'form',
'view_mode': 'tree,kanban,form,calendar,pivot,graph,activity',
'domain': [('id', 'in', self._get_related_invoices().ids)],
}
if tree_view and form_view:
action['views'] = [(tree_view.id, 'tree'), (form_view.id, 'form')]
return action
@api.depends('contract_line_ids.date_end')
def _compute_date_end(self):
for contract in self:
contract.date_end = False
date_end = contract.contract_line_ids.mapped('date_end')
if date_end and all(date_end):
contract.date_end = max(date_end)
@api.depends(
'contract_line_ids.recurring_next_date',
'contract_line_ids.is_canceled',
)
def _compute_recurring_next_date(self):
for contract in self:
recurring_next_date = contract.contract_line_ids.filtered(
lambda l: l.recurring_next_date and not l.is_canceled
).mapped('recurring_next_date')
if recurring_next_date:
contract.recurring_next_date = min(recurring_next_date)
@api.depends('contract_line_ids.create_invoice_visibility')
def _compute_create_invoice_visibility(self):
for contract in self:
contract.create_invoice_visibility = any(
contract.contract_line_ids.mapped(
'create_invoice_visibility'
)
)
@api.onchange('contract_template_id')
def _onchange_contract_template_id(self):
"""Update the contract fields with that of the template.
Take special consideration with the `contract_line_ids`,
which must be created using the data from the contract lines. Cascade
deletion ensures that any errant lines that are created are also
deleted.
"""
contract_template_id = self.contract_template_id
if not contract_template_id:
return
for field_name, field in contract_template_id._fields.items():
if field.name == 'contract_line_ids':
lines = self._convert_contract_lines(contract_template_id)
self.contract_line_ids += lines
elif not any(
(
field.compute,
field.related,
field.automatic,
field.readonly,
field.company_dependent,
field.name in self.NO_SYNC,
)
):
self[field_name] = self.contract_template_id[field_name]
@api.onchange('partner_id')
def _onchange_partner_id(self):
self.pricelist_id = self.partner_id.property_product_pricelist.id
self.fiscal_position_id = self.partner_id.property_account_position_id
if self.contract_type == 'purchase':
self.payment_term_id = \
self.partner_id.property_supplier_payment_term_id
else:
self.payment_term_id = \
self.partner_id.property_payment_term_id
self.invoice_partner_id = self.partner_id.address_get(['invoice'])[
'invoice'
]
return {
'domain': {
'invoice_partner_id': [
'|',
('id', 'parent_of', self.partner_id.id),
('id', 'child_of', self.partner_id.id),
]
}
}
@api.multi
def _convert_contract_lines(self, contract):
self.ensure_one()
new_lines = self.env['contract.line']
contract_line_model = self.env['contract.line']
for contract_line in contract.contract_line_ids:
vals = contract_line._convert_to_write(contract_line.read()[0])
# Remove template link field
vals.pop('contract_template_id', False)
vals['date_start'] = fields.Date.context_today(contract_line)
vals['recurring_next_date'] = fields.Date.context_today(
contract_line
)
new_lines += contract_line_model.new(vals)
new_lines._onchange_date_start()
new_lines._onchange_is_auto_renew()
return new_lines
@api.multi
def _prepare_invoice(self, date_invoice, journal=None):
self.ensure_one()
if not journal:
journal = (
self.journal_id
if self.journal_id.type == self.contract_type
else self.env['account.journal'].search(
[
('type', '=', self.contract_type),
('company_id', '=', self.company_id.id),
],
limit=1,
)
)
if not journal:
raise ValidationError(
_("Please define a %s journal for the company '%s'.")
% (self.contract_type, self.company_id.name or '')
)
currency = (
self.pricelist_id.currency_id
or self.partner_id.property_product_pricelist.currency_id
or self.company_id.currency_id
)
invoice_type = 'out_invoice'
if self.contract_type == 'purchase':
invoice_type = 'in_invoice'
return {
'name': self.code,
'type': invoice_type,
'partner_id': self.invoice_partner_id.id,
'currency_id': currency.id,
'date_invoice': date_invoice,
'journal_id': journal.id,
'origin': self.name,
'company_id': self.company_id.id,
'user_id': self.user_id.id,
'payment_term_id': self.payment_term_id.id,
'fiscal_position_id': self.fiscal_position_id.id,
}
@api.multi
def action_contract_send(self):
self.ensure_one()
template = self.env.ref('contract.email_contract_template', False)
compose_form = self.env.ref('mail.email_compose_message_wizard_form')
ctx = dict(
default_model='contract.contract',
default_res_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
default_composition_mode='comment',
)
return {
'name': _('Compose Email'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form.id, 'form')],
'view_id': compose_form.id,
'target': 'new',
'context': ctx,
}
@api.model
def _finalize_invoice_values(self, invoice_values):
"""
This method adds the missing values in the invoice lines dictionaries.
If no account on the product, the invoice lines account is
taken from the invoice's journal in _onchange_product_id
This code is not in finalize_creation_from_contract because it's
not possible to create an invoice line with no account
:param invoice_values: dictionary (invoice values)
:return: updated dictionary (invoice values)
"""
# If no account on the product, the invoice lines account is
# taken from the invoice's journal in _onchange_product_id
# This code is not in finalize_creation_from_contract because it's
# not possible to create an invoice line with no account
new_invoice = self.env['account.invoice'].new(invoice_values)
for invoice_line in new_invoice.invoice_line_ids:
name = invoice_line.name
account_analytic_id = invoice_line.account_analytic_id
price_unit = invoice_line.price_unit
invoice_line.invoice_id = new_invoice
invoice_line._onchange_product_id()
invoice_line.update(
{
'name': name,
'account_analytic_id': account_analytic_id,
'price_unit': price_unit,
}
)
return new_invoice._convert_to_write(new_invoice._cache)
@api.model
def _finalize_invoice_creation(self, invoices):
for invoice in invoices:
payment_term = invoice.payment_term_id
fiscal_position = invoice.fiscal_position_id
invoice._onchange_partner_id()
invoice.payment_term_id = payment_term
invoice.fiscal_position_id = fiscal_position
invoices.compute_taxes()
@api.model
def _finalize_and_create_invoices(self, invoices_values):
"""
This method:
- finalizes the invoices values (onchange's...)
- creates the invoices
- finalizes the created invoices (onchange's, tax computation...)
:param invoices_values: list of dictionaries (invoices values)
:return: created invoices (account.invoice)
"""
if isinstance(invoices_values, dict):
invoices_values = [invoices_values]
final_invoices_values = []
for invoice_values in invoices_values:
final_invoices_values.append(
self._finalize_invoice_values(invoice_values)
)
invoices = self.env['account.invoice'].create(final_invoices_values)
self._finalize_invoice_creation(invoices)
return invoices
@api.model
def _get_contracts_to_invoice_domain(self, date_ref=None):
"""
This method builds the domain to use to find all
contracts (contract.contract) to invoice.
:param date_ref: optional reference date to use instead of today
:return: list (domain) usable on contract.contract
"""
domain = []
if not date_ref:
date_ref = fields.Date.context_today(self)
domain.extend([('recurring_next_date', '<=', date_ref)])
return domain
@api.multi
def _get_lines_to_invoice(self, date_ref):
"""
This method fetches and returns the lines to invoice on the contract
(self), based on the given date.
:param date_ref: date used as reference date to find lines to invoice
:return: contract lines (contract.line recordset)
"""
self.ensure_one()
return self.contract_line_ids.filtered(
lambda l: not l.is_canceled
and l.recurring_next_date
and l.recurring_next_date <= date_ref
)
@api.multi
def _prepare_recurring_invoices_values(self, date_ref=False):
"""
This method builds the list of invoices values to create, based on
the lines to invoice of the contracts in self.
!!! The date of next invoice (recurring_next_date) is updated here !!!
:return: list of dictionaries (invoices values)
"""
invoices_values = []
for contract in self:
if not date_ref:
date_ref = contract.recurring_next_date
if not date_ref:
# this use case is possible when recurring_create_invoice is
# called for a finished contract
continue
contract_lines = contract._get_lines_to_invoice(date_ref)
if not contract_lines:
continue
invoice_values = contract._prepare_invoice(date_ref)
for line in contract_lines:
invoice_values.setdefault('invoice_line_ids', [])
invoice_line_values = line._prepare_invoice_line(
invoice_id=False
)
if invoice_line_values:
invoice_values['invoice_line_ids'].append(
(0, 0, invoice_line_values)
)
invoices_values.append(invoice_values)
contract_lines._update_recurring_next_date()
return invoices_values
@api.multi
def recurring_create_invoice(self):
"""
This method triggers the creation of the next invoices of the contracts
even if their next invoicing date is in the future.
"""
return self._recurring_create_invoice()
@api.multi
def _recurring_create_invoice(self, date_ref=False):
invoices_values = self._prepare_recurring_invoices_values(date_ref)
return self._finalize_and_create_invoices(invoices_values)
@api.model
def cron_recurring_create_invoice(self):
domain = self._get_contracts_to_invoice_domain()
contracts_to_invoice = self.search(domain)
date_ref = fields.Date.context_today(contracts_to_invoice)
contracts_to_invoice._recurring_create_invoice(date_ref)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,428 @@
# Copyright 2018 ACSONE SA/NV.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import itertools
from collections import namedtuple
from odoo.fields import Date
Criteria = namedtuple(
'Criteria',
[
'when', # Contract line relatively to today (BEFORE, IN, AFTER)
'has_date_end', # Is date_end set on contract line (bool)
'has_last_date_invoiced', # Is last_date_invoiced set on contract line
'is_auto_renew', # Is is_auto_renew set on contract line (bool)
'has_successor', # Is contract line has_successor (bool)
'predecessor_has_successor',
# Is contract line predecessor has successor (bool)
# In almost of the cases
# contract_line.predecessor.successor == contract_line
# But at cancel action,
# contract_line.predecessor.successor == False
# This is to permit plan_successor on predecessor
# If contract_line.predecessor.successor != False
# and contract_line is canceled, we don't allow uncancel
# else we re-link contract_line and its predecessor
'canceled', # Is contract line canceled (bool)
],
)
Allowed = namedtuple(
'Allowed',
['plan_successor', 'stop_plan_successor', 'stop', 'cancel', 'uncancel'],
)
def _expand_none(criteria):
variations = []
for attribute, value in criteria._asdict().items():
if value is None:
if attribute == 'when':
variations.append(['BEFORE', 'IN', 'AFTER'])
else:
variations.append([True, False])
else:
variations.append([value])
return itertools.product(*variations)
def _add(matrix, criteria, allowed):
""" Expand None values to True/False combination """
for c in _expand_none(criteria):
matrix[c] = allowed
CRITERIA_ALLOWED_DICT = {
Criteria(
when='BEFORE',
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=True,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
has_successor=True,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=True,
stop_plan_successor=True,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=False,
has_last_date_invoiced=False,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=True,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
has_successor=True,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=True,
stop_plan_successor=True,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=False,
has_last_date_invoiced=False,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=True,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=True,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
has_successor=True,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=True,
stop_plan_successor=True,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='BEFORE',
has_date_end=False,
has_last_date_invoiced=True,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=True,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
has_successor=True,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=True,
stop_plan_successor=True,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='IN',
has_date_end=False,
has_last_date_invoiced=True,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=True,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='AFTER',
has_date_end=True,
has_last_date_invoiced=None,
is_auto_renew=True,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when='AFTER',
has_date_end=True,
has_last_date_invoiced=None,
is_auto_renew=False,
has_successor=True,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=False,
cancel=False,
uncancel=False,
),
Criteria(
when='AFTER',
has_date_end=True,
has_last_date_invoiced=None,
is_auto_renew=False,
has_successor=False,
predecessor_has_successor=None,
canceled=False,
): Allowed(
plan_successor=True,
stop_plan_successor=False,
stop=True,
cancel=False,
uncancel=False,
),
Criteria(
when=None,
has_date_end=None,
has_last_date_invoiced=None,
is_auto_renew=None,
has_successor=None,
predecessor_has_successor=False,
canceled=True,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=False,
cancel=False,
uncancel=True,
),
Criteria(
when=None,
has_date_end=None,
has_last_date_invoiced=None,
is_auto_renew=None,
has_successor=None,
predecessor_has_successor=True,
canceled=True,
): Allowed(
plan_successor=False,
stop_plan_successor=False,
stop=False,
cancel=False,
uncancel=False,
),
}
criteria_allowed_dict = {}
for c in CRITERIA_ALLOWED_DICT:
_add(criteria_allowed_dict, c, CRITERIA_ALLOWED_DICT[c])
def compute_when(date_start, date_end):
today = Date.today()
if today < date_start:
return 'BEFORE'
if date_end and today > date_end:
return 'AFTER'
return 'IN'
def compute_criteria(
date_start,
date_end,
has_last_date_invoiced,
is_auto_renew,
successor_contract_line_id,
predecessor_contract_line_id,
is_canceled,
):
return Criteria(
when=compute_when(date_start, date_end),
has_date_end=bool(date_end),
has_last_date_invoiced=bool(has_last_date_invoiced),
is_auto_renew=is_auto_renew,
has_successor=bool(successor_contract_line_id),
predecessor_has_successor=bool(
predecessor_contract_line_id.successor_contract_line_id
),
canceled=is_canceled,
)
def get_allowed(
date_start,
date_end,
has_last_date_invoiced,
is_auto_renew,
successor_contract_line_id,
predecessor_contract_line_id,
is_canceled,
):
criteria = compute_criteria(
date_start,
date_end,
has_last_date_invoiced,
is_auto_renew,
successor_contract_line_id,
predecessor_contract_line_id,
is_canceled,
)
if criteria in criteria_allowed_dict:
return criteria_allowed_dict[criteria]
return False

View File

@@ -0,0 +1,22 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ContractTemplate(models.Model):
_name = 'contract.template'
_inherit = 'contract.abstract.contract'
_description = "Contract Template"
contract_line_ids = fields.One2many(
comodel_name='contract.template.line',
inverse_name='contract_id',
copy=True,
string='Contract template lines',
)

View File

@@ -0,0 +1,24 @@
# Copyright 2004-2010 OpenERP SA
# Copyright 2014 Angel Moya <angel.moya@domatix.com>
# Copyright 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# Copyright 2016-2018 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016-2017 LasLabs Inc.
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ContractTemplateLine(models.Model):
_name = 'contract.template.line'
_inherit = 'contract.abstract.contract.line'
_description = "Contract Template Line"
_order = "sequence,id"
contract_id = fields.Many2one(
string='Contract',
comodel_name='contract.template',
required=True,
ondelete='cascade',
oldname='analytic_account_id',
)

View File

@@ -15,16 +15,16 @@ class ResPartner(models.Model):
string='Purchase Contracts', string='Purchase Contracts',
compute='_compute_contract_count', compute='_compute_contract_count',
) )
contract_ids = fields.One2many(
comodel_name='contract.contract',
inverse='partner_id',
string="Contracts",
)
def _compute_contract_count(self): def _compute_contract_count(self):
contract_model = self.env['account.analytic.account'] contract_model = self.env['contract.contract']
today = fields.Date.today()
fetch_data = contract_model.read_group([ fetch_data = contract_model.read_group([
('recurring_invoices', '=', True), ('partner_id', 'child_of', self.ids)],
('partner_id', 'child_of', self.ids),
'|',
('date_end', '=', False),
('date_end', '>=', today)],
['partner_id', 'contract_type'], ['partner_id', 'contract_type'], ['partner_id', 'contract_type'], ['partner_id', 'contract_type'],
lazy=False) lazy=False)
result = [[data['partner_id'][0], data['contract_type'], result = [[data['partner_id'][0], data['contract_type'],
@@ -49,11 +49,8 @@ class ResPartner(models.Model):
res.update( res.update(
context=dict( context=dict(
self.env.context, self.env.context,
search_default_recurring_invoices=True,
search_default_not_finished=True,
search_default_partner_id=self.id, search_default_partner_id=self.id,
default_partner_id=self.id, default_partner_id=self.id,
default_recurring_invoices=True,
default_pricelist_id=self.property_product_pricelist.id, default_pricelist_id=self.property_product_pricelist.id,
), ),
) )
@@ -62,7 +59,9 @@ class ResPartner(models.Model):
def _get_act_window_contract_xml(self, contract_type): def _get_act_window_contract_xml(self, contract_type):
if contract_type == 'purchase': if contract_type == 'purchase':
return self.env['ir.actions.act_window'].for_xml_id( return self.env['ir.actions.act_window'].for_xml_id(
'contract', 'action_account_analytic_purchase_overdue_all') 'contract', 'action_supplier_contract'
)
else: else:
return self.env['ir.actions.act_window'].for_xml_id( return self.env['ir.actions.act_window'].for_xml_id(
'contract', 'action_account_analytic_sale_overdue_all') 'contract', 'action_customer_contract'
)

View File

@@ -5,3 +5,6 @@
* Vicent Cubells <vicent.cubells@tecnativa.com> * Vicent Cubells <vicent.cubells@tecnativa.com>
* Miquel Raïch <miquel.raich@eficent.com> * Miquel Raïch <miquel.raich@eficent.com>
* Souheil Bejaoui <souheil.bejaoui@acsone.eu> * Souheil Bejaoui <souheil.bejaoui@acsone.eu>
* Thomas Binsfeld <thomas.binsfeld@acsone.eu>
* Rafael Blasco <rafael.blasco@tecnativa.com>
* Guillaume Vandamme <guillaume.vandamme@acsone.eu>

View File

@@ -1,27 +1,25 @@
To use this module, you need to: #. Contracts are in Invoicing -> Customers -> Customer and Invoicing -> Vendors -> Supplier Contracts
#. When creating a contract, fill fields for selecting the invoicing parameters:
#. Go to Accounting -> Contracts and select or create a new contract. * a journal
#. Check *Generate recurring invoices automatically*. * a price list (optional)
#. Fill fields for selecting the recurrency and invoice parameters:
* Journal #. And add the lines to be invoiced with:
* Pricelist
* Period. It can be any interval of days, weeks, months, months last day or
years.
* Start date and next invoice date.
* Invoicing type: pre-paid or post-paid.
#. Add the lines to be invoiced with the product, description, quantity and * the product with a description, a quantity and a price
price. * the recurrence parameters: interval (days, weeks, months, months last day or years),
#. You can mark Auto-price? for having a price automatically obtained applying start date, date of next invoice (automatically computed, can be modified) and end date (optional)
the pricelist to the product price. * auto-price, for having a price automatically obtained from the price list
#. You have the possibility to use the markers #START# or #END# in the * #START# or #END# in the description field to display the start/end date of
description field to show the start and end date of the invoiced period. the invoiced period in the invoice line description
#. Choosing between pre-paid and post-paid, you modify the dates that are shown * pre-paid (invoice at period start) or post-paid (invoice at start of next period)
with the markers.
#. A cron is created with daily interval, but if you are in debug mode, you can #. The "Generate Recurring Invoices from Contracts" cron runs daily to generate the invoices.
click on *Create invoices* to force this action. If you are in debug mode, you can click on the invoice creation button.
#. Click *Show recurring invoices* link to show all invoices created by the #. The *Show recurring invoices* shortcut on contracts shows all invoices created from the
contract. contract.
#. Click on *Print > Contract* menu to print contract report. #. The contract report can be printed from the Print menu
#. Click on *Send by Email* button to send contract by email. #. The contract can be sent by email with the *Send by Email* button
#. Contract templates can be created from the Configuration -> Contracts -> Contract Templates menu.
They allow to define default journal, price list and lines when creating a contract.
To use it, just select the template on the contract and fields will be filled automatically.

View File

@@ -3,7 +3,7 @@
<report <report
id="report_contract" id="report_contract"
model="account.analytic.account" model="contract.contract"
string="Contract" string="Contract"
report_type="qweb-pdf" report_type="qweb-pdf"
name="contract.report_contract_document" name="contract.report_contract_document"

View File

@@ -16,7 +16,6 @@
</div> </div>
<div class="row" id="header_info"> <div class="row" id="header_info">
<div class="col-xs-3"> <div class="col-xs-3">
<strong>Date Start: </strong><p t-field="o.date_start"/>
<strong>Responsible: </strong><p t-field="o.user_id"/> <strong>Responsible: </strong><p t-field="o.user_id"/>
<strong>Contract: </strong><p t-field="o.code"/> <strong>Contract: </strong><p t-field="o.code"/>
</div> </div>
@@ -33,6 +32,7 @@
<th class="text-right"><strong>Quantity</strong></th> <th class="text-right"><strong>Quantity</strong></th>
<th class="text-right"><strong>Unit Price</strong></th> <th class="text-right"><strong>Unit Price</strong></th>
<th class="text-right"><strong>Price</strong></th> <th class="text-right"><strong>Price</strong></th>
<th class="text-right"><strong>Date Start</strong></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -49,6 +49,9 @@
<td class="text-right"> <td class="text-right">
<span t-field="l.price_subtotal" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> <span t-field="l.price_subtotal" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
</td> </td>
<td>
<span t-field="l.date_start"/>
</td>
<t t-set="total" t-value="total + l.price_subtotal"/> <t t-set="total" t-value="total + l.price_subtotal"/>
</tr> </tr>
</tbody> </tbody>

View File

@@ -2,7 +2,7 @@
<record id="rule_contract_template_multi_company" model="ir.rule"> <record id="rule_contract_template_multi_company" model="ir.rule">
<field name="name">Contract template multi-company</field> <field name="name">Contract template multi-company</field>
<field name="model_id" ref="model_account_analytic_contract"/> <field name="model_id" ref="model_contract_template"/>
<field name="global" eval="True"/> <field name="global" eval="True"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field> <field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field>
</record> </record>

View File

@@ -1,7 +1,9 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"account_analytic_contract_manager","Recurring manager","model_account_analytic_contract","account.group_account_manager",1,1,1,1 "contract_template_manager","Recurring manager","model_contract_template","account.group_account_manager",1,1,1,1
"account_analytic_contract_user","Recurring user","model_account_analytic_contract","account.group_account_invoice",1,0,0,0 "contract_template_user","Recurring user","model_contract_template","account.group_account_invoice",1,0,0,0
"account_analytic_invoice_line_manager","Recurring manager","model_account_analytic_invoice_line","account.group_account_manager",1,1,1,1 "contract_manager","Recurring manager","model_contract_contract","account.group_account_manager",1,1,1,1
"account_analytic_invoice_line_user","Recurring user","model_account_analytic_invoice_line","account.group_account_invoice",1,0,0,0 "contract_user","Recurring user","model_contract_contract","account.group_account_invoice",1,0,0,0
"account_analytic_contract_line_manager","Recurring manager","model_account_analytic_contract_line","account.group_account_manager",1,1,1,1 "contract_line_manager","Recurring manager","model_contract_line","account.group_account_manager",1,1,1,1
"account_analytic_contract_line_user","Recurring user","model_account_analytic_contract_line","account.group_account_invoice",1,0,0,0 "contract_line_user","Recurring user","model_contract_line","account.group_account_invoice",1,0,0,0
"contract_template_line_manager","Recurring manager","model_contract_template_line","account.group_account_manager",1,1,1,1
"contract_template_line_user","Recurring user","model_contract_template_line","account.group_account_invoice",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 account_analytic_contract_manager contract_template_manager Recurring manager model_account_analytic_contract model_contract_template account.group_account_manager 1 1 1 1
3 account_analytic_contract_user contract_template_user Recurring user model_account_analytic_contract model_contract_template account.group_account_invoice 1 0 0 0
4 account_analytic_invoice_line_manager contract_manager Recurring manager model_account_analytic_invoice_line model_contract_contract account.group_account_manager 1 1 1 1
5 account_analytic_invoice_line_user contract_user Recurring user model_account_analytic_invoice_line model_contract_contract account.group_account_invoice 1 0 0 0
6 account_analytic_contract_line_manager contract_line_manager Recurring manager model_account_analytic_contract_line model_contract_line account.group_account_manager 1 1 1 1
7 account_analytic_contract_line_user contract_line_user Recurring user model_account_analytic_contract_line model_contract_line account.group_account_invoice 1 0 0 0
8 contract_template_line_manager Recurring manager model_contract_template_line account.group_account_manager 1 1 1 1
9 contract_template_line_user Recurring user model_contract_template_line account.group_account_invoice 1 0 0 0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--FORM view-->
<record id="contract_abstract_contract_line_form_view" model="ir.ui.view">
<field name="name">contract.abstract.contract.line form view (in contract)</field>
<field name="model">contract.abstract.contract.line</field>
<field name="arch" type="xml">
<form>
<header/>
<sheet>
<group col="4">
<field colspan="4" name="product_id"/>
<field colspan="4" name="name"/>
<field colspan="2" name="quantity"/>
<field colspan="2" name="uom_id"/>
<field colspan="2" name="automatic_price"/>
<field name="specific_price" invisible="1"/>
<field colspan="2" name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"/>
<field colspan="2" name="discount" groups="base.group_no_one"/>
</group>
<group col="4">
<field colspan="2" name="is_auto_renew"/>
<field colspan="2" name="is_canceled" invisible="1"/>
</group>
<group attrs="{'invisible':[('is_auto_renew', '=', False)]}">
<group>
<label for="auto_renew_interval"/>
<div>
<field name="auto_renew_interval"
class="oe_inline" nolabel="1"
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
<field name="auto_renew_rule_type"
class="oe_inline" nolabel="1"
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
</div>
</group>
<group>
<label for="termination_notice_interval"/>
<div>
<field name="termination_notice_interval"
class="oe_inline" nolabel="1"
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
<field name="termination_notice_rule_type"
class="oe_inline" nolabel="1"
attrs="{'required':[('is_auto_renew', '=', True)]}"/>
</div>
</group>
</group>
<group name="recurrence_info">
<group>
<label for="recurring_interval"/>
<div>
<field name="recurring_interval"
class="oe_inline" nolabel="1"/>
<field name="recurring_rule_type"
class="oe_inline" nolabel="1"/>
</div>
</group>
<group>
<field name="recurring_invoicing_type"
attrs="{'invisible': [('recurring_rule_type', '=', 'monthlylastday')]}"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
</odoo>

View File

@@ -1,279 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_analytic_account_recurring_form_form" model="ir.ui.view">
<field name="name">Contract form</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
<field name="mode">primary</field>
<field name="priority" eval="9999"/>
<field name="arch" type="xml">
<field name="partner_id" position="attributes">
<attribute name="attrs">{'required': [('recurring_invoices', '=', True)]}</attribute>
</field>
<xpath expr="//div[@name='button_box']/.." position="before">
<header>
<button name="action_contract_send" type="object" string="Send by Email" groups="base.group_user"/>
</header>
</xpath>
<xpath expr='//field[@name="code"]' position='before'>
<field name="contract_type" invisible="1" required="1"/>
</xpath>
<group name="main" position="after">
<separator string="Recurring Invoices"
attrs="{'invisible': [('recurring_invoices','!=',True)]}"
/>
<div>
<field name="recurring_invoices" class="oe_inline"/>
<field name="create_invoice_visibility" invisible="1"/>
<label for="recurring_invoices" />
<button name="recurring_create_invoice"
type="object"
attrs="{'invisible': ['|', ('recurring_invoices', '!=', True), ('create_invoice_visibility', '=', False)]}"
string="Create invoices"
class="oe_link"
groups="base.group_no_one"
/>
<button name="button_show_recurring_invoices"
type="object"
attrs="{'invisible': [('recurring_invoices','!=',True)]}"
string="⇒ Show recurring invoices"
class="oe_link"
/>
</div>
<group col="4" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<field name="contract_template_id" colspan="4" domain="['|', ('contract_type', '=', contract_type), ('contract_type', '=', False)]" context="{'default_contract_type': contract_type}"/>
<field name="journal_id"
domain="[('type', '=', contract_type),('company_id', '=', company_id)]"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
<field name="pricelist_id"/>
<field name="company_id" groups="base.group_multi_company"/>
<label for="recurring_interval"/>
<div>
<field name="recurring_interval"
class="oe_inline"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
<field name="recurring_rule_type"
class="oe_inline"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
</div>
<field name="recurring_invoicing_type"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
<field name="date_start"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
<field name="date_end"/>
<field name="recurring_next_date"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
</group>
<label for="recurring_invoice_line_ids"
attrs="{'invisible': [('recurring_invoices','=',False)]}"
/>
<div attrs="{'invisible': [('recurring_invoices','=',False)]}">
<field name="recurring_invoice_line_ids">
<tree string="Account Analytic Lines" editable="bottom">
<field name="sequence" widget="handle" />
<field name="product_id"/>
<field name="name"/>
<field name="quantity"/>
<field name="uom_id"/>
<field name="automatic_price"/>
<field name="price_unit" attrs="{'readonly': [('automatic_price', '=', True)]}"/>
<field name="specific_price" invisible="1"/>
<field name="discount" groups="base.group_no_one" />
<field name="price_subtotal"/>
</tree>
</field>
</div>
<group string="Legend (for the markers inside invoice lines description)"
name="group_legend" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<p colspan="2"> <strong>#START#</strong>: Start date of the invoiced period</p>
<p colspan="2"> <strong>#END#</strong>: End date of the invoiced period</p>
</group>
</group>
</field>
</record>
<record id="account_analytic_account_sale_form" model="ir.ui.view">
<field name="name">account.analytic.account.sale.form</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="account_analytic_account_recurring_form_form"/>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="partner_id" position="attributes">
<attribute name="string">Customer</attribute>
<attribute name="domain">[('customer', '=', True)]</attribute>
<attribute name="context">{'default_customer': True, 'default_supplier': False}</attribute>
</field>
<field name="journal_id" position="attributes">
<attribute name="domain">[('type', '=', 'sale'),('company_id', '=', company_id)]</attribute>
</field>
<field name="product_id" position="attributes">
<attribute name="domain">[('sale_ok', '=', True)]</attribute>
</field>
</field>
</record>
<record id="account_analytic_account_purchase_form" model="ir.ui.view">
<field name="name">account.analytic.account.purchase.form</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="account_analytic_account_recurring_form_form"/>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="partner_id" position="attributes">
<attribute name="string">Supplier</attribute>
<attribute name="domain">[('supplier', '=', True)]</attribute>
<attribute name="context">{'default_customer': False, 'default_supplier': True}</attribute>
</field>
<field name="journal_id" position="attributes">
<attribute name="domain">[('type', '=', 'purchase'),('company_id', '=', company_id)]</attribute>
</field>
<field name="product_id" position="attributes">
<attribute name="domain">[('purchase_ok', '=', True)]</attribute>
</field>
<xpath expr="//field[@name='recurring_invoice_line_ids']/tree/field[@name='automatic_price']" position="attributes">
<attribute name="invisible">True</attribute>
</xpath>
</field>
</record>
<!-- Inherited Analytic Account list for contracts -->
<record id="view_account_analytic_account_journal_tree" model="ir.ui.view">
<field name="name">Contract list</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_list" />
<field name="mode">primary</field>
<field name="priority" eval="9999"/>
<field name="arch" type="xml">
<field name="partner_id" position="before">
<field name="journal_id" groups="account.group_account_user"/>
</field>
<field name="partner_id" position="after">
<field name="recurring_next_date" invisible="not context.get('is_contract', False)"/>
</field>
</field>
</record>
<!-- Analytic Account search view for contract -->
<record id="view_account_analytic_account_contract_search" model="ir.ui.view">
<field name="name">Contract search</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_search"/>
<field name="arch" type="xml">
<field name="partner_id" position="after">
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"
string="Partner and dependents"/>
</field>
<field name="name" position="after">
<field name="journal_id"/>
<field name="pricelist_id"/>
<separator/>
<filter name="recurring_invoices"
string="Recurring Invoices"
domain="[('recurring_invoices','=',True)]"
/>
<separator/>
<filter name="not_finished"
string="Valid"
domain="['|', ('date_end', '=', False), ('date_end', '&gt;=', time.strftime('%Y-%m-%d'))]"
/>
<filter name="finished"
string="Finished"
domain="[('date_end', '&lt;', time.strftime('%Y-%m-%d'))]"
/>
<group expand="0" string="Group By...">
<filter name="next_invoice"
string="Next Invoice"
domain="[]"
context="{'group_by':'recurring_next_date'}"
/>
<filter name="date_end"
string="Date End"
domain="[]"
context="{'group_by':'date_end'}"
/>
</group>
</field>
</field>
</record>
<!-- Action Sales/Sales/Contracts -->
<record id="action_account_analytic_sale_overdue_all" model="ir.actions.act_window">
<field name="name">Customer Contracts</field>
<field name="res_model">account.analytic.account</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('contract_type', '=', 'sale')]</field>
<field name="context">{'is_contract':1, 'search_default_not_finished':1, 'search_default_recurring_invoices':1, 'default_recurring_invoices': 1, 'default_contract_type': 'sale'}</field>
<field name="search_view_id" ref="view_account_analytic_account_contract_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p>
</field>
</record>
<record id="action_account_analytic_sale_overdue_all_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_account_analytic_account_journal_tree"/>
<field name="act_window_id" ref="action_account_analytic_sale_overdue_all"/>
</record>
<record id="action_account_analytic_sale_overdue_all_form" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="account_analytic_account_sale_form"/>
<field name="act_window_id" ref="action_account_analytic_sale_overdue_all"/>
</record>
<menuitem id="menu_action_account_analytic_sale_overdue_all"
parent="account.menu_finance_receivables"
action="action_account_analytic_sale_overdue_all"
sequence="99"
/>
<!-- Action Purchases/Purchases/Contracts -->
<record id="action_account_analytic_purchase_overdue_all" model="ir.actions.act_window">
<field name="name">Supplier Contracts</field>
<field name="res_model">account.analytic.account</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('contract_type', '=', 'purchase')]</field>
<field name="context">{'is_contract':1, 'search_default_not_finished':1, 'search_default_recurring_invoices':1, 'default_recurring_invoices': 1, 'default_contract_type': 'purchase'}</field>
<field name="search_view_id" ref="view_account_analytic_account_contract_search"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p>
</field>
</record>
<record id="action_account_analytic_purchase_overdue_all_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_account_analytic_account_journal_tree"/>
<field name="act_window_id" ref="action_account_analytic_purchase_overdue_all"/>
</record>
<record id="action_account_analytic_purchase_overdue_all_form" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="account_analytic_account_purchase_form"/>
<field name="act_window_id" ref="action_account_analytic_purchase_overdue_all"/>
</record>
<menuitem id="menu_action_account_analytic_purchase_overdue_all"
parent="account.menu_finance_payables"
action="action_account_analytic_purchase_overdue_all"
sequence="99"
/>
</odoo>

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_invoice_filter_contract" model="ir.ui.view">
<field name="name">account.invoice.select.contract</field>
<field name="model">account.invoice</field>
<field name="inherit_id" ref="account.view_account_invoice_filter"/>
<field name="arch" type="xml">
<field name="date" position="after">
<separator/>
<field name="contract_id"/>
</field>
</field>
</record>
<record id="act_recurring_invoices" model="ir.actions.act_window">
<field name="name">Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_ids"
eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('account.invoice_tree')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('account.invoice_form')})]"/>
<field name="context">{
'search_default_contract_id': [active_id],
'default_contract_id': active_id}
</field>
<field name="domain">[('type','in', ['out_invoice', 'out_refund'])]</field>
</record>
<record id="act_purchase_recurring_invoices" model="ir.actions.act_window">
<field name="name">Vendor Bills</field>
<field name="res_model">account.invoice</field>
<field name="view_ids"
eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('account.invoice_supplier_tree')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('account.invoice_supplier_form')})]"/>
<field name="context">{
'search_default_contract_id': [active_id],
'default_contract_id': active_id}
</field>
<field name="domain">[('type','in', ['in_invoice', 'in_refund'])]</field>
</record>
</odoo>

293
contract/views/contract.xml Normal file
View File

@@ -0,0 +1,293 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--Main FORM view-->
<record id="contract_contract_form_view" model="ir.ui.view">
<field name="name">contract.contract form view (in contract)</field>
<field name="model">contract.contract</field>
<field name="arch" type="xml">
<form>
<header>
<button name="action_contract_send"
type="object"
string="Send by Email"
groups="base.group_user"/>
<button name="recurring_create_invoice"
type="object"
attrs="{'invisible': [('create_invoice_visibility', '=', False)]}"
string="Create invoices"
groups="base.group_no_one"/>
</header>
<sheet string="Contract">
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object"
name="toggle_active" icon="fa-archive">
<field name="active" widget="boolean_button"
options="{&quot;terminology&quot;: &quot;archive&quot;}"/>
</button>
<button name="action_show_invoices"
type="object" icon="fa-list"
class="oe_stat_button">
<field string="Invoices"
name="invoice_count"
widget="statinfo"/>
</button>
</div>
<div class="oe_title">
<label for="name" string="Contract Name"
class="oe_edit_only"/>
<h3>
<field name="name" class="oe_inline"
placeholder="e.g. Contract XYZ"/>
</h3>
</div>
<group name="main">
<group>
<field name="partner_id" required="1"/>
<field name="payment_term_id"/>
<field name="user_id"/>
</group>
<group>
<field name="contract_template_id"
domain="['|', ('contract_type', '=', contract_type), ('contract_type', '=', False)]"
context="{'default_contract_type': contract_type}"/>
<field name="contract_type" invisible="1"
required="1"/>
<field name="fiscal_position_id"/>
</group>
</group>
<group name="recurring_invoices">
<group>
<field name="journal_id" required="1"/>
<field name="recurring_next_date"/>
</group>
<group>
<field name="pricelist_id"/>
<field name="date_end"/>
</group>
</group>
<notebook>
<page name="recurring_invoice_line"
string="Recurring Invoices">
<field name="contract_line_ids"
context="{'default_contract_type': contract_type}"/>
</page>
<page name="info" string="Other Information">
<field name="create_invoice_visibility"
invisible="1"/>
<group>
<field name="code"/>
<field name="group_id"/>
<field name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"/>
<field name="currency_id"
options="{'no_create': True}"
groups="base.group_multi_currency"/>
<field name="invoice_partner_id"
required="1"/>
</group>
<group string="Legend (for the markers inside invoice lines description)"
name="group_legend">
<p colspan="2"><strong>#START#</strong>: Start
date
of the
invoiced period
</p>
<p colspan="2"><strong>#END#</strong>: End date
of
the
invoiced period
</p>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<!--Customer FORM view-->
<record id="contract_contract_customer_form_view" model="ir.ui.view">
<field name="name">contract.contract customer form view (in contract)</field>
<field name="model">contract.contract</field>
<field name="inherit_id" ref="contract_contract_form_view"/>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="partner_id" position="attributes">
<attribute name="string">Customer</attribute>
<attribute name="domain">[('customer', '=', True)]</attribute>
<attribute name="context">{'default_customer': True, 'default_supplier': False}</attribute>
</field>
<field name="journal_id" position="attributes">
<attribute name="domain">[('type', '=', 'sale'),('company_id', '=', company_id)]</attribute>
</field>
</field>
</record>
<!--Supplier FORM view-->
<record id="contract_contract_supplier_form_view" model="ir.ui.view">
<field name="name">contract.contract supplier form view (in contract)</field>
<field name="model">contract.contract</field>
<field name="inherit_id" ref="contract_contract_form_view"/>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="partner_id" position="attributes">
<attribute name="string">Supplier</attribute>
<attribute name="domain">[('supplier', '=', True)]</attribute>
<attribute name="context">{'default_customer': False, 'default_supplier': True}</attribute>
</field>
<field name="journal_id" position="attributes">
<attribute name="domain">[('type', '=', 'purchase'),('company_id', '=', company_id)]</attribute>
</field>
</field>
</record>
<!--TREE view-->
<record id="contract_contract_tree_view" model="ir.ui.view">
<field name="name">contract.contract tree view (in contract)</field>
<field name="model">contract.contract</field>
<field name="arch" type="xml">
<tree>
<field name="name" string="Name"/>
<field name="code"/>
<field name="journal_id" groups="account.group_account_user"/>
<field name="partner_id"/>
<field name="active" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<!--SEARCH view-->
<record id="contract_contract_search_view" model="ir.ui.view">
<field name="name">contract.contract search view (in contract)</field>
<field name="model">contract.contract</field>
<field name="arch" type="xml">
<search>
<field name="name"
filter_domain="['|', ('name','ilike',self), ('code','ilike',self)]"/>
<field name="journal_id"/>
<field name="pricelist_id"/>
<separator/>
<separator/>
<filter name="not_finished"
string="In progress"
domain="['|', ('date_end', '&gt;=', context_today().strftime('%Y-%m-%d')), ('date_end', '=', False)]"
/>
<filter name="finished"
string="Finished"
domain="[('date_end', '&lt;', context_today().strftime('%Y-%m-%d')), ('recurring_next_date', '=', False)]"
/>
<field name="partner_id"/>
<filter string="Archived"
domain="[('active', '=', False)]"
name="inactive"/>
<group expand="0" string="Group By...">
<filter string="Associated Partner"
name="group_by_partner"
domain="[]"
context="{'group_by':'partner_id'}"/>
<filter name="group_by_next_invoice"
string="Next Invoice"
domain="[('recurring_next_date', '!=', False)]"
context="{'group_by':'recurring_next_date'}"
/>
<filter name="group_by_date_end"
string="Date End"
domain="[]"
context="{'group_by':'date_end'}"
/>
</group>
</search>
</field>
</record>
<!--ACTION customer contracts-->
<record id="action_customer_contract" model="ir.actions.act_window">
<field name="name">Customer Contracts</field>
<field name="res_model">contract.contract</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('contract_type', '=', 'sale')]</field>
<field name="context">{'is_contract':1,
'search_default_not_finished':1,
'default_contract_type': 'sale'}
</field>
<field name="search_view_id" ref="contract_contract_search_view"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p>
</field>
</record>
<record id="action_customer_contract_view_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="contract_contract_tree_view"/>
<field name="act_window_id" ref="action_customer_contract"/>
</record>
<record id="action_customer_contract_view_form" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="contract_contract_customer_form_view"/>
<field name="act_window_id" ref="action_customer_contract"/>
</record>
<menuitem id="menu_contract_contract_customer"
parent="account.menu_finance_receivables"
action="action_customer_contract"
sequence="99"
/>
<!--ACTION supplier contracts-->
<record id="action_supplier_contract" model="ir.actions.act_window">
<field name="name">Supplier Contracts</field>
<field name="res_model">contract.contract</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('contract_type', '=', 'purchase')]</field>
<field name="context">{'is_contract':1,
'search_default_not_finished':1,
'default_contract_type': 'purchase'}
</field>
<field name="search_view_id" ref="contract_contract_search_view"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new contract.
</p>
</field>
</record>
<record id="action_supplier_contract_view_tree" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="contract_contract_tree_view"/>
<field name="act_window_id" ref="action_supplier_contract"/>
</record>
<record id="action_supplier_contract_view_form" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/>
<field name="view_mode">form</field>
<field name="view_id" ref="contract_contract_supplier_form_view"/>
<field name="act_window_id" ref="action_supplier_contract"/>
</record>
<menuitem id="menu_contract_contract_supplier"
parent="account.menu_finance_payables"
action="action_supplier_contract"
sequence="99"
/>
</odoo>

View File

@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--FORM view-->
<record id="contract_line_form_view" model="ir.ui.view">
<field name="name">contract.line form view (in contract)</field>
<field name="model">contract.line</field>
<field name="inherit_id" ref="contract_abstract_contract_line_form_view"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<header position="inside">
<field name="state" widget="statusbar"/>
</header>
<group name="recurrence_info" position="inside">
<group>
<field name="create_invoice_visibility" invisible="1"/>
<field name="date_start" required="1"/>
<field name="recurring_next_date"/>
</group>
<group>
<field name="date_end"
attrs="{'required': [('is_auto_renew', '=', True)]}"/>
</group>
<group groups="base.group_no_one">
<field name="last_date_invoiced" readonly="True"/>
<field name="termination_notice_date" readonly="True"/>
</group>
<group>
<field name="manual_renew_needed"/>
</group>
<group>
<field name="predecessor_contract_line_id"/>
</group>
<group>
<field name="successor_contract_line_id"/>
</group>
</group>
<group name="recurrence_info" position="after">
<group name="analytic" groups="analytic.group_analytic_accounting">
<field name="analytic_account_id"/>
</group>
</group>
</field>
</record>
<!--Customer FORM view-->
<record id="contract_line_customer_form_view" model="ir.ui.view">
<field name="name">contract.line customer form view (in contract)</field>
<field name="model">contract.line</field>
<field name="inherit_id" ref="contract_line_form_view"/>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="product_id" position="attributes">
<attribute name="domain">[('sale_ok', '=', True)]</attribute>
</field>
</field>
</record>
<!--Supplier FORM view-->
<record id="contract_line_supplier_form_view" model="ir.ui.view">
<field name="name">contract.line supplier form view (in contract)</field>
<field name="model">contract.line</field>
<field name="inherit_id" ref="contract_line_form_view"/>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="arch" type="xml">
<field name="product_id" position="attributes">
<attribute name="domain">[('purchase_ok', '=', True)]</attribute>
</field>
<field name="automatic_price" position="attributes">
<attribute name="invisible">True</attribute>
</field>
</field>
</record>
<!--TREE view-->
<record id="contract_line_tree_view" model="ir.ui.view">
<field name="name">contract.line tree view (in contract)</field>
<field name="model">contract.line</field>
<field name="arch" type="xml">
<tree decoration-muted="is_canceled"
decoration-info="create_invoice_visibility and not is_canceled">
<field name="sequence" widget="handle"/>
<field name="product_id"/>
<field name="name"/>
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
<field name="quantity"/>
<field name="uom_id"/>
<field name="automatic_price"/>
<field name="price_unit"
attrs="{'readonly': [('automatic_price', '=', True)]}"/>
<field name="specific_price"
invisible="1"/>
<field name="discount"
groups="base.group_no_one"/>
<field name="price_subtotal"/>
<field name="recurring_interval"
invisible="1"/>
<field name="recurring_rule_type"
invisible="1"/>
<field name="recurring_invoicing_type"
invisible="1"/>
<field name="date_start" required="1"/>
<field name="date_end"/>
<field name="recurring_next_date"
required="1"/>
<field name="last_date_invoiced"
groups="base.group_no_one"/>
<field name="create_invoice_visibility"
invisible="1"/>
<field name="is_plan_successor_allowed"
invisible="1"/>
<field name="is_stop_plan_successor_allowed"
invisible="1"/>
<field name="is_stop_allowed"
invisible="1"/>
<field name="is_cancel_allowed"
invisible="1"/>
<field name="is_un_cancel_allowed"
invisible="1"/>
<field name="is_auto_renew" invisible="1"/>
<field name="is_canceled" invisible="1"/>
<button name="action_plan_successor"
string="Plan Start" type="object"
icon="fa-calendar text-success"
attrs="{'invisible': [('is_plan_successor_allowed', '=', False)]}"/>
<button name="action_stop_plan_successor"
string="Stop Plan Successor"
type="object"
icon="fa-pause text-muted"
attrs="{'invisible': [('is_stop_plan_successor_allowed', '=', False)]}"/>
<button name="action_stop" string="Stop"
type="object"
icon="fa-stop text-danger"
attrs="{'invisible': [('is_stop_allowed', '=', False)]}"/>
<button name="cancel" string="Cancel"
type="object"
icon="fa-ban text-danger"
confirm="Are you sure you want to cancel this line"
attrs="{'invisible': [('is_cancel_allowed', '=', False)]}"/>
<button name="action_uncancel"
string="Un-cancel" type="object"
icon="fa-ban text-success"
attrs="{'invisible': [('is_un_cancel_allowed', '=', False)]}"/>
<button name="renew" string="Renew"
type="object"
icon="fa-fast-forward text-success"
groups="base.group_no_one"
attrs="{'invisible': [('is_auto_renew', '=', False)]}"/>
</tree>
</field>
</record>
<!--Supplier TREE view-->
<record id="contract_line_supplier_tree_view" model="ir.ui.view">
<field name="name">contract.line supplier tree view (in contract)</field>
<field name="model">contract.line</field>
<field name="mode">primary</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="contract_line_tree_view"/>
<field name="arch" type="xml">
<field name="automatic_price" position="attributes">
<attribute name="invisible">True</attribute>
</field>
</field>
</record>
</odoo>

View File

@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record id="account_analytic_contract_view_form" model="ir.ui.view"> <!--FORM view-->
<field name="name">Account Analytic Contract Form View</field> <record id="contract_template_form_view" model="ir.ui.view">
<field name="model">account.analytic.contract</field> <field name="name">contract.template form view (in contract)</field>
<field name="model">contract.template</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Contract Template"> <form string="Contract Template">
<group name="name"> <group name="name">
@@ -16,24 +17,10 @@
<field name="pricelist_id" /> <field name="pricelist_id" />
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/> <field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
</group> </group>
<group name="group_main_right">
<field name="recurring_invoicing_type" />
<label for="recurring_interval" />
<div>
<field name="recurring_interval"
class="oe_inline"
required="True"
/>
<field name="recurring_rule_type"
class="oe_inline"
required="True"
/>
</div>
</group>
</group> </group>
<group name="group_invoice_lines" string="Invoice Lines"> <group name="group_invoice_lines" string="Contract Template Lines">
<field name="recurring_invoice_line_ids" nolabel="1"> <field name="contract_line_ids" nolabel="1">
<tree string="Account Analytic Lines" editable="bottom"> <tree>
<field name="sequence" widget="handle" /> <field name="sequence" widget="handle" />
<field name="product_id" /> <field name="product_id" />
<field name="name" /> <field name="name" />
@@ -44,6 +31,9 @@
<field name="specific_price" invisible="1"/> <field name="specific_price" invisible="1"/>
<field name="discount" groups="base.group_no_one" /> <field name="discount" groups="base.group_no_one" />
<field name="price_subtotal" /> <field name="price_subtotal" />
<field name="recurring_rule_type" invisible="1"/>
<field name="recurring_interval" invisible="1"/>
<field name="recurring_invoicing_type" invisible="1"/>
</tree> </tree>
</field> </field>
</group> </group>
@@ -57,45 +47,33 @@
</field> </field>
</record> </record>
<record id="account_analytic_contract_view_tree" model="ir.ui.view"> <!--TREE view-->
<field name="name">Account Analytic Contract Tree View</field> <record id="contract_template_tree_view" model="ir.ui.view">
<field name="model">account.analytic.contract</field> <field name="name">contract.template tree view (in contract)</field>
<field name="model">contract.template</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Contract Templates"> <tree>
<field name="name" /> <field name="name" />
<field name="contract_type" /> <field name="contract_type" />
<field name="recurring_rule_type" />
<field name="recurring_interval" />
<field name="recurring_invoicing_type" />
<field name="pricelist_id" /> <field name="pricelist_id" />
</tree> </tree>
</field> </field>
</record> </record>
<record id="account_analytic_contract_view_search" model="ir.ui.view"> <!--SEARCH view-->
<field name="name">Account Analytic Contract Search View</field> <record id="contract_template_search_view" model="ir.ui.view">
<field name="model">account.analytic.contract</field> <field name="name">contract.template search view (in contract)</field>
<field name="model">contract.template</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Contract Templates"> <search>
<field name="name" /> <field name="name" />
<field name="contract_type" /> <field name="contract_type" />
<field name="recurring_rule_type" />
<field name="recurring_interval" />
<field name="recurring_invoicing_type" />
<field name="pricelist_id" /> <field name="pricelist_id" />
<field name="journal_id" /> <field name="journal_id" />
<filter name="contract_type" <filter name="contract_type"
string="Contract Type" string="Contract Type"
context="{'group_by': 'contract_type'}" context="{'group_by': 'contract_type'}"
/> />
<filter name="recurring_rule_type"
string="Recurrence"
context="{'group_by': 'recurring_rule_type'}"
/>
<filter name="recurring_invoicing_type"
string="Invoicing type"
context="{'group_by': 'recurring_invoicing_type'}"
/>
<filter name="pricelist_id" <filter name="pricelist_id"
string="Pricelist" string="Pricelist"
context="{'group_by': 'pricelist_id'}" context="{'group_by': 'pricelist_id'}"
@@ -108,12 +86,13 @@
</field> </field>
</record> </record>
<record id="account_analytic_contract_action" model="ir.actions.act_window"> <!--ACTION-->
<record id="contract_template_action" model="ir.actions.act_window">
<field name="name">Contract Templates</field> <field name="name">Contract Templates</field>
<field name="res_model">account.analytic.contract</field> <field name="res_model">contract.template</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="search_view_id" ref="account_analytic_contract_view_search"/> <field name="search_view_id" ref="contract_template_search_view"/>
<field name="help" type="html"> <field name="help" type="html">
<p class="oe_view_nocontent_create"> <p class="oe_view_nocontent_create">
Click to create a new contract template. Click to create a new contract template.
@@ -127,9 +106,9 @@
parent="account.menu_finance_configuration" parent="account.menu_finance_configuration"
/> />
<menuitem id="account_analytic_contract_menu" <menuitem id="contract_template_menu"
parent="menu_config_contract" parent="menu_config_contract"
action="account_analytic_contract_action" action="contract_template_action"
sequence="1" sequence="1"
/> />

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--FORM view-->
<record id="contract_template_line_form_view" model="ir.ui.view">
<field name="name">contract.template.line form view (in contract)</field>
<field name="model">contract.template.line</field>
<field name="inherit_id" ref="contract_abstract_contract_line_form_view"/>
<field name="mode">primary</field>
<field name="arch" type="xml">
<form position="attributes">
<attribute name="string">Contract Template Line</attribute>
</form>
</field>
</record>
</odoo>

View File

@@ -3,7 +3,7 @@
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo> <odoo>
<record id="view_partner_form" model="ir.ui.view"> <record id="view_partner_form" model="ir.ui.view">
<field name="inherit_id" ref="base.view_partner_form" /> <field name="inherit_id" ref="base.view_partner_form" />
<field name="model">res.partner</field> <field name="model">res.partner</field>
<field type="xml" name="arch"> <field type="xml" name="arch">
@@ -21,7 +21,22 @@
<field name="purchase_contract_count" widget="statinfo" string="Purchase Contracts"/> <field name="purchase_contract_count" widget="statinfo" string="Purchase Contracts"/>
</button> </button>
</xpath> </xpath>
</field> </field>
</record> </record>
<record id="view_res_partner_filter" model="ir.ui.view">
<field name="inherit_id" ref="base.view_res_partner_filter" />
<field name="model">res.partner</field>
<field type="xml" name="arch">
<filter name="inactive" position="after">
<separator/>
<filter
name="filter_running_contract"
string="With running contracts"
domain="['|', ('contract_ids.date_end', '&gt;=', context_today().strftime('%Y-%m-%d')), ('contract_ids.date_end', '=', False)]"
/>
</filter>
</field>
</record>
</odoo> </odoo>

View File

@@ -0,0 +1 @@
from . import contract_line_wizard

View File

@@ -0,0 +1,58 @@
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class ContractLineWizard(models.TransientModel):
_name = 'contract.line.wizard'
_description = 'Contract Line Wizard'
date_start = fields.Date(string='Date Start')
date_end = fields.Date(string='Date End')
recurring_next_date = fields.Date(string='Next Invoice Date')
is_auto_renew = fields.Boolean(string="Auto Renew", default=False)
manual_renew_needed = fields.Boolean(
string="Manual renew needed",
default=False,
help="This flag is used to make a difference between a definitive stop"
"and temporary one for which a user is not able to plan a"
"successor in advance",
)
contract_line_id = fields.Many2one(
comodel_name="contract.line",
string="Contract Line",
required=True,
index=True,
)
@api.multi
def stop(self):
for wizard in self:
wizard.contract_line_id.stop(
wizard.date_end, manual_renew_needed=wizard.manual_renew_needed
)
return True
@api.multi
def plan_successor(self):
for wizard in self:
wizard.contract_line_id.plan_successor(
wizard.date_start, wizard.date_end, wizard.is_auto_renew
)
return True
@api.multi
def stop_plan_successor(self):
for wizard in self:
wizard.contract_line_id.stop_plan_successor(
wizard.date_start, wizard.date_end, wizard.is_auto_renew
)
return True
@api.multi
def uncancel(self):
for wizard in self:
wizard.contract_line_id.uncancel(wizard.recurring_next_date)
return True

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 ACSONE SA/NV
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="contract_line_wizard_stop_form_view">
<field name="name">contract.line.stop.wizard.form (in contract)</field>
<field name="model">contract.line.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="contract_line_id" invisible="True"/>
<field string="Stop Date" name="date_end" required="True"/>
<field string="Is suspension without end date" name="manual_renew_needed"/>
</group>
<footer>
<button name="stop"
string="Validate"
class="btn-primary"
type="object"/>
<button string="Cancel"
class="btn-default"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record model="ir.ui.view" id="contract_line_wizard_plan_successor_form_view">
<field name="name">contract.line.plan_successor.wizard.form (in contract)</field>
<field name="model">contract.line.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="contract_line_id" invisible="True"/>
<field name="date_start" required="True"/>
<field name="date_end" attrs="{'required': [('is_auto_renew', '=', True)]}"/>
<field name="is_auto_renew"/>
</group>
<footer>
<button name="plan_successor"
string="Validate"
class="btn-primary"
type="object"/>
<button string="Cancel"
class="btn-default"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record model="ir.ui.view" id="contract_line_wizard_stop_plan_successor_form_view">
<field name="name">contract.line.stop_plan_successor.wizard.form (in contract)</field>
<field name="model">contract.line.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="contract_line_id" invisible="True"/>
<field string="Suspension Start Date" name="date_start" required="True"/>
<field string="Suspension End Date" name="date_end" required="True"/>
<field name="is_auto_renew" invisible="1"/>
</group>
<footer>
<button name="stop_plan_successor"
string="Validate"
class="btn-primary"
type="object"/>
<button string="Cancel"
class="btn-default"
special="cancel"/>
</footer>
</form>
</field>
</record>
<record model="ir.ui.view" id="contract_line_wizard_uncancel_form_view">
<field name="name">contract.line.stop_plan_successor.wizard.form (in contract)</field>
<field name="model">contract.line.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="contract_line_id" invisible="True"/>
<field name="recurring_next_date" required="True"/>
</group>
<footer>
<button name="uncancel"
string="Validate"
class="btn-primary"
type="object"/>
<button string="Cancel"
class="btn-default"
special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>

View File

@@ -3,7 +3,7 @@
{ {
'name': 'Contract from Sale', 'name': 'Contract from Sale',
'version': '12.0.1.0.0', 'version': '12.0.2.0.0',
'category': 'Sales', 'category': 'Sales',
'author': 'Tecnativa, ' 'author': 'Tecnativa, '
'Odoo Community Association (OCA)', 'Odoo Community Association (OCA)',
@@ -14,9 +14,11 @@
], ],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'security/account_analytic_account_security.xml', 'security/contract_security.xml',
'views/account_analytic_account_view.xml', 'views/abstract_contract_line.xml',
'views/account_analytic_contract_view.xml', 'views/contract.xml',
'views/contract_line.xml',
'views/contract_template.xml',
], ],
'license': 'AGPL-3', 'license': 'AGPL-3',
'installable': True, 'installable': True,

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 12.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-05-29 10:00+0000\n"
"PO-Revision-Date: 2019-05-29 10:00+0000\n"
"Last-Translator: <>\n" "Last-Translator: <>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@@ -1,11 +1,12 @@
# Translation of Odoo Server. # Translation of Odoo Server.
# This file contains the translation of the following modules: # This file contains the translation of the following modules:
# * contract_sale # * contract_sale
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 12.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-05-29 10:00+0000\n"
"PO-Revision-Date: 2019-02-04 18:50+0000\n" "PO-Revision-Date: 2019-02-04 18:50+0000\n"
"Last-Translator: Marta Vázquez Rodríguez <vazrodmar@gmail.com>\n" "Last-Translator: Marta Vázquez Rodríguez <vazrodmar@gmail.com>\n"
"Language-Team: none\n" "Language-Team: none\n"

View File

@@ -0,0 +1,32 @@
# Copyright 2019 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from openupgradelib import openupgrade
_logger = logging.getLogger(__name__)
def migrate(cr, version):
xmlids_to_rename = [
('contract_sale.account_analytic_account_own_salesman',
'contract_sale.contract_contract_own_salesman'),
('contract_sale.account_analytic_account_see_all',
'contract_sale.contract_contract_see_all'),
('contract_sale.account_analytic_contract_salesman',
'contract_sale.contract_template_salesman'),
('contract_sale.account_analytic_contract_sale_manager',
'contract_sale.contract_template_sale_manager'),
('contract_sale.account_analytic_invoice_line_saleman',
'contract_sale.contract_line_saleman'),
('contract_sale.account_analytic_invoice_line_manager',
'contract_sale.contract_line_manager'),
('contract_sale.account_analytic_contract_line_salesman',
'contract_sale.contract_template_line_salesman'),
('contract_sale.account_analytic_contract_line_manager',
'contract_sale.contract_template_line_manager'),
('contract_sale.account_analytic_account_contract_salesman',
'contract_sale.contract_contract_salesman'),
]
openupgrade.rename_xmlids(cr, xmlids_to_rename)

View File

@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1"> <odoo noupdate="1">
<record id="account_analytic_account_own_salesman" model="ir.rule"> <record id="contract_contract_own_salesman" model="ir.rule">
<field name="name">See Own Contracts</field> <field name="name">See Own Contracts</field>
<field name="model_id" ref="analytic.model_account_analytic_account"/> <field name="model_id" ref="contract.model_contract_contract"/>
<field name="domain_force">['|', ('user_id','=',user.id), ('user_id','=',False)]</field> <field name="domain_force">['|', ('user_id','=',user.id), ('user_id','=',False)]</field>
<field name="groups" eval="[(4,ref('sales_team.group_sale_salesman'))]"/> <field name="groups" eval="[(4,ref('sales_team.group_sale_salesman'))]"/>
</record> </record>
<record id="account_analytic_account_see_all" model="ir.rule"> <record id="contract_contract_see_all" model="ir.rule">
<field name="name">See All Contracts</field> <field name="name">See All Contracts</field>
<field name="model_id" ref="analytic.model_account_analytic_account"/> <field name="model_id" ref="contract.model_contract_contract"/>
<field name="domain_force">[(1,'=',1)]</field> <field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[ <field name="groups" eval="[
(4,ref('sales_team.group_sale_salesman_all_leads')), (4,ref('sales_team.group_sale_salesman_all_leads')),

View File

@@ -1,12 +1,12 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"account_analytic_contract_salesman","Recurring Salesman","contract.model_account_analytic_contract","sales_team.group_sale_salesman",1,1,1,0 "contract_template_salesman","Recurring Salesman","contract.model_contract_template","sales_team.group_sale_salesman",1,1,1,0
"account_analytic_contract_sale_manager","Recurring Sale Manager","contract.model_account_analytic_contract","sales_team.group_sale_manager",1,1,1,1 "contract_template_sale_manager","Recurring Sale Manager","contract.model_contract_template","sales_team.group_sale_manager",1,1,1,1
"account_analytic_invoice_line_saleman","Recurring Invoice Line Saleman","contract.model_account_analytic_invoice_line","sales_team.group_sale_salesman",1,1,1,0 "contract_line_saleman","Recurring Invoice Line Saleman","contract.model_contract_line","sales_team.group_sale_salesman",1,1,1,0
"account_analytic_invoice_line_manager","Recurring Invoice Line Manager","contract.model_account_analytic_invoice_line","sales_team.group_sale_manager",1,1,1,1 "contract_line_manager","Recurring Invoice Line Manager","contract.model_contract_line","sales_team.group_sale_manager",1,1,1,1
"account_analytic_contract_line_salesman","Recurring Contract Line Salesman","contract.model_account_analytic_contract_line","sales_team.group_sale_salesman",1,1,1,0 "contract_template_line_salesman","Recurring Contract Line Salesman","contract.model_contract_template_line","sales_team.group_sale_salesman",1,1,1,0
"account_analytic_contract_line_manager","Recurring Contract Line Manager","contract.model_account_analytic_contract_line","sales_team.group_sale_manager",1,1,1,1 "contract_template_line_manager","Recurring Contract Line Manager","contract.model_contract_template_line","sales_team.group_sale_manager",1,1,1,1
"account_analytic_line_contract_salesman","Recurring Analytic Line Salesman","analytic.model_account_analytic_line","sales_team.group_sale_salesman",1,1,1,0 "account_analytic_line_contract_salesman","Recurring Analytic Line Salesman","analytic.model_account_analytic_line","sales_team.group_sale_salesman",1,1,1,0
"account_analytic_account_contract_salesman","Recurring Analytic Account Salesman","analytic.model_account_analytic_account","sales_team.group_sale_salesman",1,1,1,0 "contract_contract_salesman","Recurring Analytic Account Salesman","contract.model_contract_contract","sales_team.group_sale_salesman",1,1,1,0
"account_analytic_tag_contract_salesman","Recurring Account Analytic Tag Salesman","analytic.model_account_analytic_tag","sales_team.group_sale_salesman",1,1,1,0 "account_analytic_tag_contract_salesman","Recurring Account Analytic Tag Salesman","analytic.model_account_analytic_tag","sales_team.group_sale_salesman",1,1,1,0
"account_invoice_contract_salesman","Recurring Account Inoice Salesman","account.model_account_invoice","sales_team.group_sale_salesman",1,0,0,0 "account_invoice_contract_salesman","Recurring Account Inoice Salesman","account.model_account_invoice","sales_team.group_sale_salesman",1,0,0,0
"account_journal_contract_salesman","Recurring Account Journal Salesman","account.model_account_journal","sales_team.group_sale_salesman",1,0,0,0 "account_journal_contract_salesman","Recurring Account Journal Salesman","account.model_account_journal","sales_team.group_sale_salesman",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 account_analytic_contract_salesman contract_template_salesman Recurring Salesman contract.model_account_analytic_contract contract.model_contract_template sales_team.group_sale_salesman 1 1 1 0
3 account_analytic_contract_sale_manager contract_template_sale_manager Recurring Sale Manager contract.model_account_analytic_contract contract.model_contract_template sales_team.group_sale_manager 1 1 1 1
4 account_analytic_invoice_line_saleman contract_line_saleman Recurring Invoice Line Saleman contract.model_account_analytic_invoice_line contract.model_contract_line sales_team.group_sale_salesman 1 1 1 0
5 account_analytic_invoice_line_manager contract_line_manager Recurring Invoice Line Manager contract.model_account_analytic_invoice_line contract.model_contract_line sales_team.group_sale_manager 1 1 1 1
6 account_analytic_contract_line_salesman contract_template_line_salesman Recurring Contract Line Salesman contract.model_account_analytic_contract_line contract.model_contract_template_line sales_team.group_sale_salesman 1 1 1 0
7 account_analytic_contract_line_manager contract_template_line_manager Recurring Contract Line Manager contract.model_account_analytic_contract_line contract.model_contract_template_line sales_team.group_sale_manager 1 1 1 1
8 account_analytic_line_contract_salesman Recurring Analytic Line Salesman analytic.model_account_analytic_line sales_team.group_sale_salesman 1 1 1 0
9 account_analytic_account_contract_salesman contract_contract_salesman Recurring Analytic Account Salesman analytic.model_account_analytic_account contract.model_contract_contract sales_team.group_sale_salesman 1 1 1 0
10 account_analytic_tag_contract_salesman Recurring Account Analytic Tag Salesman analytic.model_account_analytic_tag sales_team.group_sale_salesman 1 1 1 0
11 account_invoice_contract_salesman Recurring Account Inoice Salesman account.model_account_invoice sales_team.group_sale_salesman 1 0 0 0
12 account_journal_contract_salesman Recurring Account Journal Salesman account.model_account_journal sales_team.group_sale_salesman 1 0 0 0

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--FORM view-->
<record id="contract_abstract_contract_line_form_view" model="ir.ui.view">
<field name="name">contract.abstract.contract.line form view (in contract_sale)</field>
<field name="model">contract.abstract.contract.line</field>
<field name="inherit_id" ref="contract.contract_abstract_contract_line_form_view"/>
<field name="arch" type="xml">
<field name="discount" position="attributes">
<attribute name="groups">sale.group_discount_per_so_line</attribute>
</field>
</field>
</record>
</odoo>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_analytic_account_recurring_form_form"
model="ir.ui.view">
<field name="name">Contract form (in contract_sale)</field>
<field name="model">account.analytic.account</field>
<field name="inherit_id"
ref="contract.account_analytic_account_recurring_form_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='discount']" position="attributes">
<attribute name="groups">sale.group_discount_per_so_line
</attribute>
</xpath>
</field>
</record>
<menuitem
id="menu_contract_sale" name="Contracts"
parent="sale.sale_order_menu"
action="contract.action_account_analytic_sale_overdue_all"
sequence="2"
groups="sales_team.group_sale_salesman"
/>
</odoo>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_analytic_contract_view_form" model="ir.ui.view">
<field name="name">Account Analytic Contract Form View (in
sale_contract)
</field>
<field name="model">account.analytic.contract</field>
<field name="inherit_id"
ref="contract.account_analytic_contract_view_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='discount']" position="attributes">
<attribute name="groups">sale.group_discount_per_so_line
</attribute>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem
id="menu_contract_sale" name="Contracts"
parent="sale.sale_order_menu"
action="contract.action_supplier_contract"
sequence="2"
groups="sales_team.group_sale_salesman"
/>
</odoo>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--TREE view-->
<record id="contract_line_tree_view" model="ir.ui.view">
<field name="name">contract.template.line tree view (in contract_sale)</field>
<field name="model">contract.line</field>
<field name="inherit_id" ref="contract.contract_line_tree_view"/>
<field name="arch" type="xml">
<field name="discount" position="attributes">
<attribute name="groups">sale.group_discount_per_so_line</attribute>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!--FORM view-->
<record id="contract_template_form_view" model="ir.ui.view">
<field name="name">contract.template form view (in contract_sale)</field>
<field name="model">contract.template</field>
<field name="inherit_id" ref="contract.contract_template_form_view"/>
<field name="arch" type="xml">
<field name="discount" position="attributes">
<attribute name="groups">sale.group_discount_per_so_line</attribute>
</field>
</field>
</record>
</odoo>

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" "Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Compte analític"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Compte analític"

View File

@@ -6,6 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 12.0\n" "Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2019-05-29 14:59+0000\n"
"Last-Translator: <>\n" "Last-Translator: <>\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -14,17 +16,17 @@ msgstr ""
"Plural-Forms: \n" "Plural-Forms: \n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "If checked include sales with same analytic account to invoice in contract invoice creation." msgid "If checked include sales with same analytic account to invoice in contract invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""

View File

@@ -8,33 +8,32 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2019-06-28 13:42+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: Maria Sparenberg <maria.sparenberg@gmx.net>\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" "Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n"
"Language: de\n" "Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n" "Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Weblate 3.6.1\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Kostenstelle"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
"Wenn der Haken gesetzt ist, dann werden alle noch abzurechnenden "
"Verkaufsaufträge mit derselben Kostenstelle bei der Rechnungserstellung für "
"den Vertrag einbezogen."
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "Ausstehende Verkaufsaufträge abrechnen" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Kostenstelle"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Greek (Greece) (https://www.transifex.com/oca/teams/23907/" "Language-Team: Greek (Greece) (https://www.transifex.com/oca/teams/23907/"
@@ -20,18 +20,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Αναλυτικός Λογαριασμός"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Αναλυτικός Λογαριασμός"

View File

@@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-06 17:36+0200\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-06 17:38+0200\n" "PO-Revision-Date: 2018-04-06 17:38+0200\n"
"Last-Translator: Carlos Dauden <carlos.dauden@tecnativa.com>\n" "Last-Translator: Carlos Dauden <carlos.dauden@tecnativa.com>\n"
"Language-Team: \n" "Language-Team: \n"
@@ -18,12 +18,7 @@ msgstr ""
"X-Generator: Poedit 1.8.7.1\n" "X-Generator: Poedit 1.8.7.1\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Cuenta analítica"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
@@ -32,6 +27,14 @@ msgstr ""
"cuenta analítica en la creación de la factura del contrato" "cuenta analítica en la creación de la factura del contrato"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "Facturar pedidos pendientes" msgstr "Facturar pedidos pendientes"
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Cuenta analítica"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Spanish (Mexico) (https://www.transifex.com/oca/teams/23907/" "Language-Team: Spanish (Mexico) (https://www.transifex.com/oca/teams/23907/"
@@ -20,18 +20,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Cuenta analítica"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Cuenta analítica"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n" "Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analyyttinen tili"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analyyttinen tili"

View File

@@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-05-05 02:28+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-05-05 02:28+0000\n" "PO-Revision-Date: 2018-05-05 02:28+0000\n"
"Last-Translator: Quentin THEURET <odoo@kerpeo.com>, 2018\n" "Last-Translator: Quentin THEURET <odoo@kerpeo.com>, 2018\n"
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" "Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n"
@@ -20,12 +20,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Compte analytique"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
@@ -34,6 +29,14 @@ msgstr ""
"de la création de facture du contrat." "de la création de facture du contrat."
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "Commandes avec une facture en attente" msgstr "Commandes avec une facture en attente"
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Compte analytique"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" "Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Conta analítica"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Conta analítica"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Hindi (India) (https://www.transifex.com/oca/teams/23907/" "Language-Team: Hindi (India) (https://www.transifex.com/oca/teams/23907/"
@@ -20,18 +20,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "विश्लेषणात्मक खाता"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "विश्लेषणात्मक खाता"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" "Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n"
@@ -20,18 +20,21 @@ msgstr ""
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analitički konto"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analitički konto"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Croatian (Croatia) (https://www.transifex.com/oca/teams/23907/" "Language-Team: Croatian (Croatia) (https://www.transifex.com/oca/teams/23907/"
@@ -21,18 +21,21 @@ msgstr ""
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Konto analitike"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Konto analitike"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Hungarian (https://www.transifex.com/oca/teams/23907/hu/)\n" "Language-Team: Hungarian (https://www.transifex.com/oca/teams/23907/hu/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analitikus gyűjtőkód könyvelés"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analitikus gyűjtőkód könyvelés"

View File

@@ -8,32 +8,32 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2019-06-26 15:42+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: Sergio Zanchetta <primes2h@gmail.com>\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n"
"Language: it\n" "Language: it\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n" "Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Weblate 3.6.1\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Conto analitico"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
"Se selezionato, in fase di creazione del contratto aggiunge alla fattura le "
"vendite con lo stesso conto analitico."
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "Ordini di vendita in sospeso della fattura" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Conto Analitico"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" "Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Kostenplaats"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Kostenplaats"

View File

@@ -8,9 +8,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2019-08-14 13:44+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: Pedro Castro Silva <pedrocs@exo.pt>\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n" "Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n"
"Language: pt\n" "Language: pt\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -20,12 +20,7 @@ msgstr ""
"X-Generator: Weblate 3.7.1\n" "X-Generator: Weblate 3.7.1\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Conta Analítica"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
@@ -34,6 +29,6 @@ msgstr ""
"faturas do contrato." "faturas do contrato."
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "Faturar Encomendas de Venda Pendentes" msgstr "Faturar Encomendas de Venda Pendentes"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Portuguese (Portugal) (https://www.transifex.com/oca/" "Language-Team: Portuguese (Portugal) (https://www.transifex.com/oca/"
@@ -20,18 +20,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Conta Analítica"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Conta Analítica"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Romanian (https://www.transifex.com/oca/teams/23907/ro/)\n" "Language-Team: Romanian (https://www.transifex.com/oca/teams/23907/ro/)\n"
@@ -20,18 +20,21 @@ msgstr ""
"2:1));\n" "2:1));\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Cont analitic"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Cont analitic"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Slovak (Slovakia) (https://www.transifex.com/oca/teams/23907/" "Language-Team: Slovak (Slovakia) (https://www.transifex.com/oca/teams/23907/"
@@ -20,18 +20,21 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analytický účet"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analytický účet"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" "Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n"
@@ -20,18 +20,21 @@ msgstr ""
"%100==4 ? 2 : 3);\n" "%100==4 ? 2 : 3);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analitični konto"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analitični konto"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n" "Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analitik Hesap"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analitik Hesap"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-17 02:41+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-17 02:41+0000\n" "PO-Revision-Date: 2018-04-17 02:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n" "Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2018\n"
"Language-Team: Turkish (Turkey) (https://www.transifex.com/oca/teams/23907/" "Language-Team: Turkish (Turkey) (https://www.transifex.com/oca/teams/23907/"
@@ -20,18 +20,21 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "Analitik Hesap"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "" msgstr ""
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "" msgstr ""
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "Analitik Hesap"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Odoo Server 11.0\n" "Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-04-27 01:12+0000\n" "POT-Creation-Date: 2019-05-29 14:59+0000\n"
"PO-Revision-Date: 2018-04-27 01:12+0000\n" "PO-Revision-Date: 2018-04-27 01:12+0000\n"
"Last-Translator: DIT INTL <ditintlgroup@gmail.com>, 2018\n" "Last-Translator: DIT INTL <ditintlgroup@gmail.com>, 2018\n"
"Language-Team: Chinese (https://www.transifex.com/oca/teams/23907/zh/)\n" "Language-Team: Chinese (https://www.transifex.com/oca/teams/23907/zh/)\n"
@@ -19,18 +19,21 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n" "Plural-Forms: nplurals=1; plural=0;\n"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_account_analytic_account #: model:ir.model.fields,help:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Analytic Account"
msgstr "分析会计"
#. module: contract_sale_invoicing
#: model:ir.model.fields,help:contract_sale_invoicing.field_account_analytic_account__invoicing_sales
msgid "" msgid ""
"If checked include sales with same analytic account to invoice in contract " "If checked include sales with same analytic account to invoice in contract "
"invoice creation." "invoice creation."
msgstr "如果选中,则在销售发票中包含分析帐户。" msgstr "如果选中,则在销售发票中包含分析帐户。"
#. module: contract_sale_invoicing #. module: contract_sale_invoicing
#: model:ir.model.fields,field_description:contract_sale_invoicing.field_account_analytic_account__invoicing_sales #: model:ir.model.fields,field_description:contract_sale_invoicing.field_contract_contract__invoicing_sales
msgid "Invoice Pending Sales Orders" msgid "Invoice Pending Sales Orders"
msgstr "发票挂起的销售订单" msgstr "发票挂起的销售订单"
#. module: contract_sale_invoicing
#: model:ir.model,name:contract_sale_invoicing.model_contract_contract
msgid "contract.contract"
msgstr ""
#~ msgid "Analytic Account"
#~ msgstr "分析会计"

View File

@@ -4,8 +4,8 @@
from odoo import api, fields, models from odoo import api, fields, models
class AccountAnalyticAccount(models.Model): class ContractContract(models.Model):
_inherit = 'account.analytic.account' _inherit = 'contract.contract'
invoicing_sales = fields.Boolean( invoicing_sales = fields.Boolean(
string='Invoice Pending Sales Orders', string='Invoice Pending Sales Orders',
@@ -14,11 +14,12 @@ class AccountAnalyticAccount(models.Model):
) )
@api.multi @api.multi
def _create_invoice(self, invoice=False): def _recurring_create_invoice(self, date_ref=False):
invoices = super()._recurring_create_invoice(date_ref)
if not self.invoicing_sales: if not self.invoicing_sales:
return super(AccountAnalyticAccount, self)._create_invoice() return invoices
sales = self.env['sale.order'].search([ sales = self.env['sale.order'].search([
('analytic_account_id', '=', self.id), ('analytic_account_id', '=', self.analytic_account_id.id),
('partner_invoice_id', 'child_of', ('partner_invoice_id', 'child_of',
self.partner_id.commercial_partner_id.ids), self.partner_id.commercial_partner_id.ids),
('invoice_status', '=', 'to invoice'), ('invoice_status', '=', 'to invoice'),
@@ -27,6 +28,4 @@ class AccountAnalyticAccount(models.Model):
]) ])
if sales: if sales:
invoice_ids = sales.action_invoice_create() invoice_ids = sales.action_invoice_create()
invoice = self.env['account.invoice'].browse(invoice_ids)[:1] invoices |= self.env['account.invoice'].browse(invoice_ids)[:1]
return super(AccountAnalyticAccount, self)._create_invoice(
invoice=invoice)

View File

@@ -8,6 +8,8 @@ class TestContractSaleInvoicing(TestContractBase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
super(TestContractSaleInvoicing, cls).setUpClass() super(TestContractSaleInvoicing, cls).setUpClass()
cls.contract.analytic_account_id = \
cls.env['account.analytic.account'].search([], limit=1)
cls.product_so = cls.env.ref( cls.product_so = cls.env.ref(
'product.product_product_1') 'product.product_product_1')
cls.product_so.invoice_policy = 'order' cls.product_so.invoice_policy = 'order'
@@ -21,7 +23,7 @@ class TestContractSaleInvoicing(TestContractBase):
'product_uom': cls.product_so.uom_id.id, 'product_uom': cls.product_so.uom_id.id,
'price_unit': cls.product_so.list_price})], 'price_unit': cls.product_so.list_price})],
'pricelist_id': cls.partner.property_product_pricelist.id, 'pricelist_id': cls.partner.property_product_pricelist.id,
'analytic_account_id': cls.contract.id, 'analytic_account_id': cls.contract.analytic_account_id.id,
'date_order': '2016-02-15', 'date_order': '2016-02-15',
}) })

View File

@@ -4,14 +4,14 @@
<odoo> <odoo>
<record id="account_analytic_account_recurring_form_form" model="ir.ui.view"> <record id="contract_contract_form_view" model="ir.ui.view">
<field name="model">account.analytic.account</field> <field name="model">contract.contract</field>
<field name="inherit_id" ref="contract.account_analytic_account_recurring_form_form"/> <field name="inherit_id" ref="contract.contract_contract_form_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="recurring_next_date" position="after"> <field name="recurring_next_date" position="after">
<field name="invoicing_sales"/> <field name="invoicing_sales"/>
</field>
</field> </field>
</field> </record>
</record>
</odoo> </odoo>