Browse Source

[10.0][FIX+IMP] contract: Improve usability and don't fail on wrong data (#130)

* [FIX+IMP] contract: Improve usability and don't fail on wrong data

* Cron create invoices masked for avoiding silent errors
* New constraints for assuring data consistency
* UI helps for entering consistent data
* Spanish translation
* Remove double company_id field on form

* [FIX] contract_sale_generation: Adapt tests to upstream contract
pull/133/head
Pedro M. Baeza 7 years ago
committed by Dave Lasley
parent
commit
18f545653d
  1. 2
      contract/__manifest__.py
  2. 151
      contract/i18n/es.po
  3. 77
      contract/models/account_analytic_account.py
  4. 73
      contract/tests/test_contract.py
  5. 23
      contract/views/account_analytic_account_view.xml
  6. 2
      contract/views/account_analytic_contract_view.xml
  7. 2
      contract/views/res_partner_view.xml
  8. 13
      contract_sale_generation/tests/test_contract_sale.py

2
contract/__manifest__.py

@ -9,7 +9,7 @@
{
'name': 'Contracts Management - Recurring',
'version': '10.0.3.2.0',
'version': '10.0.3.3.0',
'category': 'Contract Management',
'license': 'AGPL-3',
'author': "OpenERP SA, "

151
contract/i18n/es.po

@ -1,27 +1,23 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * contract
#
# Translators:
# OCA Transbot <transbot@odoo-community.org>, 2017
# * contract
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-11-30 01:41+0000\n"
"PO-Revision-Date: 2017-11-30 01:41+0000\n"
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n"
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n"
"POT-Creation-Date: 2017-12-02 14:59+0000\n"
"PO-Revision-Date: 2017-12-02 14:59+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Plural-Forms: \n"
#. module: contract
#: model:mail.template,body_html:contract.email_contract_template
msgid ""
"\n"
msgid "\n"
"<div style=\"font-family: 'Lucida Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; \">\n"
" <p>Hello ${object.partner_id.name or ''},</p>\n"
" <p>A new contract has been created: </p>\n"
@ -69,8 +65,7 @@ msgid ""
" </div>\n"
"</div>\n"
" "
msgstr ""
"\n"
msgstr "\n"
"<div style=\"font-family: 'Lucida Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; \">\n"
" <p>Hola ${object.partner_id.name or ''},</p>\n"
" <p>Se ha creado un nuevo contrato: </p>\n"
@ -120,7 +115,7 @@ msgstr ""
#. module: contract
#: model:mail.template,subject:contract.email_contract_template
msgid "${object.company_id.name} Contract (Ref ${object.name or 'n/a'})"
msgstr ""
msgstr "${object.company_id.name} Contract (Ref ${object.name or 'n/a'})"
#. module: contract
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form
@ -137,12 +132,12 @@ msgstr "<strong>#START#</strong>: Fecha inicio del periodo facturado"
#. module: contract
#: model:ir.ui.view,arch_db:contract.report_contract_document
msgid "<strong>Contract: </strong>"
msgstr ""
msgstr "<strong>Contrato: </strong>"
#. module: contract
#: model:ir.ui.view,arch_db:contract.report_contract_document
msgid "<strong>Date Start: </strong>"
msgstr ""
msgstr "<strong>Fecha de inicio: </strong>"
#. module: contract
#: model:ir.ui.view,arch_db:contract.report_contract_document
@ -172,7 +167,7 @@ msgstr "<strong>Elementos recurrentes</strong>"
#. module: contract
#: model:ir.ui.view,arch_db:contract.report_contract_document
msgid "<strong>Responsible: </strong>"
msgstr ""
msgstr "<strong>Responsable: </strong>"
#. module: contract
#: model:ir.ui.view,arch_db:contract.report_contract_document
@ -199,20 +194,20 @@ msgstr "Cuenta analítica"
#. module: contract
#: model:ir.actions.act_window,help:contract.account_analytic_contract_action
msgid "Click to create a new contract template."
msgstr ""
msgstr "Pulse para crear una nueva plantilla de contrato."
#. module: contract
#: model:ir.actions.act_window,help:contract.action_account_analytic_overdue_all
msgid "Click to create a new contract."
msgstr "Pinche para crear un contrato nuevo. "
msgstr "Pulse para crear un contrato nuevo. "
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_company_id
msgid "Company"
msgstr ""
msgstr "Compañía"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:263
#: code:addons/contract/models/account_analytic_account.py:321
#, python-format
msgid "Compose Email"
msgstr "Componer correo electrónico"
@ -225,16 +220,23 @@ msgstr "Componer correo electrónico"
msgid "Contract"
msgstr "Contrato"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:138
#, python-format
msgid "Contract '%s' start date can't be later than end date"
msgstr "La fecha de inicio del contrato '%s' no puede ser superior a la fecha de fin"
#. module: contract
#: model:ir.model,name:contract.model_account_analytic_contract_line
msgid "Contract Lines"
msgstr ""
msgstr "Lineas de contrato"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_contract_template_id
#: model:ir.model.fields,field_description:contract.field_project_project_contract_template_id
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form
msgid "Contract Template"
msgstr ""
msgstr "Plantilla de contrato"
#. module: contract
#: model:ir.actions.act_window,name:contract.account_analytic_contract_action
@ -242,7 +244,7 @@ msgstr ""
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_tree
msgid "Contract Templates"
msgstr ""
msgstr "Plantillas de contrato"
#. module: contract
#: model:ir.actions.act_window,name:contract.action_account_analytic_overdue_all
@ -254,6 +256,12 @@ msgstr ""
msgid "Contracts"
msgstr "Contratos"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_create_invoice_visibility
#: model:ir.model.fields,field_description:contract.field_project_project_create_invoice_visibility
msgid "Create invoice visibility"
msgstr "Visibilidad de crear factura"
#. module: contract
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form
msgid "Create invoices"
@ -275,17 +283,19 @@ msgstr "Creado en"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_end
#: model:ir.model.fields,field_description:contract.field_project_project_date_end
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search
msgid "Date End"
msgstr ""
msgstr "Fecha fin"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_start
msgid "Date Start"
msgstr ""
msgstr "Fecha de inicio"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_next_date
#: model:ir.model.fields,field_description:contract.field_project_project_recurring_next_date
msgid "Date of Next Invoice"
msgstr "Próxima fecha de factura"
@ -316,12 +326,8 @@ msgstr "El descuento debería ser menor o igual a 100"
#. module: contract
#: model:ir.model.fields,help:contract.field_account_analytic_contract_line_discount
#: model:ir.model.fields,help:contract.field_account_analytic_invoice_line_discount
msgid ""
"Discount that is applied in generated invoices. It should be less or equal "
"to 100"
msgstr ""
"Descuento que es aplicado en las facturas generadas. Debería ser menor o "
"igual a 100"
msgid "Discount that is applied in generated invoices. It should be less or equal to 100"
msgstr "Descuento que es aplicado en las facturas generadas. Debería ser menor o igual a 100"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_display_name
@ -333,10 +339,11 @@ msgstr "Nombre mostrado"
#. module: contract
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search
msgid "Finished"
msgstr ""
msgstr "Finalizado"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoices
#: model:ir.model.fields,field_description:contract.field_project_project_recurring_invoices
msgid "Generate recurring invoices automatically"
msgstr "Generar facturas recurrentes automáticamente."
@ -360,6 +367,7 @@ msgstr "Factura"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoice_line_ids
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_recurring_invoice_line_ids
#: model:ir.model.fields,field_description:contract.field_project_project_recurring_invoice_line_ids
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form
msgid "Invoice Lines"
msgstr "Líneas de factura"
@ -369,20 +377,18 @@ msgstr "Líneas de factura"
msgid "Invoices"
msgstr "Facturas"
#. module: contract
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search
msgid "Invoicing Type"
msgstr ""
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoicing_type
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_recurring_invoicing_type
#: model:ir.model.fields,field_description:contract.field_project_project_recurring_invoicing_type
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search
msgid "Invoicing type"
msgstr "Tipo de facturación"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_journal_id
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_journal_id
#: model:ir.model.fields,field_description:contract.field_project_project_journal_id
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search
msgid "Journal"
msgstr "Diario"
@ -412,8 +418,7 @@ msgstr "Última actualización en"
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form
msgid "Legend (for the markers inside invoice lines description)"
msgstr ""
"Leyenda (para los marcadores dentro de descripción en lineas de factura)"
msgstr "Leyenda (para los marcadores dentro de descripción en lineas de factura)"
#. module: contract
#: selection:account.analytic.account,recurring_rule_type:0
@ -440,15 +445,15 @@ msgstr "Próxima factura"
#. module: contract
#: model:ir.model,name:contract.model_res_partner
msgid "Partner"
msgstr ""
msgstr "Empresa"
#. module: contract
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search
msgid "Partner and dependents"
msgstr ""
msgstr "Empresa y contactos"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:169
#: code:addons/contract/models/account_analytic_account.py:224
#, python-format
msgid "Please define a sale journal for the company '%s'."
msgstr "Por favor define un diario de ventas para la compañía '%s'."
@ -468,6 +473,7 @@ msgstr "Prepago"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_pricelist_id
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_pricelist_id
#: model:ir.model.fields,field_description:contract.field_project_project_pricelist_id
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search
msgid "Pricelist"
msgstr "Lista de precios"
@ -487,9 +493,10 @@ msgstr "Cantidad"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_rule_type
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_recurring_rule_type
#: model:ir.model.fields,field_description:contract.field_project_project_recurring_rule_type
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_search
msgid "Recurrence"
msgstr ""
msgstr "Recurrencia"
#. module: contract
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form
@ -500,12 +507,14 @@ msgstr "Facturas recurrentes"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_interval
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_recurring_interval
#: model:ir.model.fields,field_description:contract.field_project_project_recurring_interval
msgid "Repeat Every"
msgstr "Repetir cada"
#. module: contract
#: model:ir.model.fields,help:contract.field_account_analytic_account_recurring_interval
#: model:ir.model.fields,help:contract.field_account_analytic_contract_recurring_interval
#: model:ir.model.fields,help:contract.field_project_project_recurring_interval
msgid "Repeat every (Days/Week/Month/Year)"
msgstr "Repetir cada (días/semana/mes/año)"
@ -523,26 +532,27 @@ msgstr "Enviar por correo electrónico"
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_sequence
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_sequence
msgid "Sequence"
msgstr ""
msgstr "Secuencia"
#. module: contract
#: model:ir.model.fields,help:contract.field_account_analytic_contract_line_sequence
#: model:ir.model.fields,help:contract.field_account_analytic_invoice_line_sequence
msgid "Sequence of the contract line when displaying contracts"
msgstr ""
msgstr "Secuencia de la linea de contrato cuando se muestra en los contratos"
#. module: contract
#: model:ir.model.fields,help:contract.field_account_analytic_account_recurring_rule_type
#: model:ir.model.fields,help:contract.field_account_analytic_contract_recurring_rule_type
#: model:ir.model.fields,help:contract.field_project_project_recurring_rule_type
msgid "Specify Interval for automatic invoice generation."
msgstr "Especifica el intervalo para la generación de facturas automática."
#. module: contract
#: model:ir.model.fields,help:contract.field_account_analytic_account_recurring_invoicing_type
#: model:ir.model.fields,help:contract.field_account_analytic_contract_recurring_invoicing_type
#: model:ir.model.fields,help:contract.field_project_project_recurring_invoicing_type
msgid "Specify if process date is 'from' or 'to' invoicing date"
msgstr ""
"Especifica si la fecha de proceso es desde o hasta la fecha de facturación"
msgstr "Especifica si la fecha de proceso es desde o hasta la fecha de facturación"
#. module: contract
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_line_price_subtotal
@ -570,7 +580,7 @@ msgstr "NIF:"
#. module: contract
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search
msgid "Valid"
msgstr ""
msgstr "Válido"
#. module: contract
#: selection:account.analytic.account,recurring_rule_type:0
@ -585,23 +595,47 @@ msgid "Year(s)"
msgstr "Año(s)"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:161
#: code:addons/contract/models/account_analytic_account.py:111
#, python-format
msgid "You can't have a next invoicing date before the start of the contract '%s'"
msgstr "No puede tener una fecha de próxima factura anterior a la fecha de inicio del contrato '%s'"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:216
#, python-format
msgid "You must first select a Customer for Contract %s!"
msgstr "¡Seleccione un cliente para este contrato %s!"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:216
#: code:addons/contract/models/account_analytic_account.py:273
#, python-format
msgid ""
"You must review start and end dates!\n"
msgid "You must review start and end dates!\n"
"%s"
msgstr ""
msgstr "Debe revisar las fechas de inicio y de fin\n"
"%s"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:102
#, python-format
msgid "You must supply a customer for the contract '%s'"
msgstr "Debe especificar un cliente para el contrato '%s'"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:120
#, python-format
msgid "You must supply a next invoicing date for contract '%s'"
msgstr "Debe suministrar una fecha de próxima factura para el contrato '%s'"
#. module: contract
#: code:addons/contract/models/account_analytic_account.py:129
#, python-format
msgid "You must supply a start date for contract '%s'"
msgstr "Debe suministrar una fecha de inicio para el contrato '%s'"
#. module: contract
#: model:ir.model,name:contract.model_account_analytic_contract
msgid "account.analytic.contract"
msgstr ""
msgstr "account.analytic.contract"
#. module: contract
#: model:ir.model,name:contract.model_account_analytic_invoice_line
@ -610,10 +644,11 @@ msgstr "account.analytic.invoice.line"
#. module: contract
#: model:ir.ui.view,arch_db:contract.view_partner_form
msgid "show the contracts for this partner"
msgstr ""
msgid "Show the contracts for this partner"
msgstr "Muestra los contratos para esta empresa/contacto"
#. module: contract
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form
msgid "⇒ Show recurring invoices"
msgstr "⇒ Mostrar facturas recurrentes"

77
contract/models/account_analytic_account.py

@ -51,6 +51,17 @@ class AccountAnalyticAccount(models.Model):
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):
@ -75,15 +86,60 @@ class AccountAnalyticAccount(models.Model):
)):
self[field_name] = self.contract_template_id[field_name]
@api.onchange('recurring_invoices')
def _onchange_recurring_invoices(self):
if self.date_start and self.recurring_invoices:
@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()
@ -203,8 +259,8 @@ class AccountAnalyticAccount(models.Model):
@api.multi
def recurring_create_invoice(self):
"""
Create invoices from contracts
"""Create invoices from contracts
:return: invoices created
"""
invoices = self.env['account.invoice']
@ -212,9 +268,12 @@ class AccountAnalyticAccount(models.Model):
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)
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)
@ -222,20 +281,20 @@ class AccountAnalyticAccount(models.Model):
ctx.update({
'old_date': old_date,
'next_date': new_date,
# Force company for correct evaluate domain access rules
# 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': new_date.strftime('%Y-%m-%d')
'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.search([
contracts = self.with_context(cron=True).search([
('recurring_invoices', '=', True),
('recurring_next_date', '<=', today),
'|',

73
contract/tests/test_contract.py

@ -65,18 +65,14 @@ class TestContract(TestContractBase):
res = self.acct_line._onchange_product_id()
self.assertIn('uom_id', res['domain'])
self.acct_line.price_unit = 100.0
self.contract.partner_id = False
with self.assertRaises(ValidationError):
self.contract.recurring_create_invoice()
self.contract.partner_id = False
self.contract.partner_id = self.partner.id
self.contract.recurring_create_invoice()
self.invoice_monthly = self.env['account.invoice'].search(
[('contract_id', '=', self.contract.id)])
self.assertTrue(self.invoice_monthly)
self.assertEqual(self.contract.recurring_next_date, '2016-03-29')
self.inv_line = self.invoice_monthly.invoice_line_ids[0]
self.assertTrue(self.inv_line.invoice_line_tax_ids)
self.assertAlmostEqual(self.inv_line.price_subtotal, 50.0)
@ -129,11 +125,11 @@ class TestContract(TestContractBase):
self.assertEqual(self.contract.pricelist_id,
self.contract.partner_id.property_product_pricelist)
def test_onchange_recurring_invoices(self):
self.contract.recurring_next_date = False
self.contract._onchange_recurring_invoices()
self.assertEqual(self.contract.recurring_next_date,
self.contract.date_start)
def test_onchange_date_start(self):
date = '2016-01-01'
self.contract.date_start = date
self.contract._onchange_date_start()
self.assertEqual(self.contract.recurring_next_date, date)
def test_uom(self):
uom_litre = self.env.ref('product.product_uom_litre')
@ -160,6 +156,31 @@ class TestContract(TestContractBase):
with self.assertRaises(ValidationError):
contract_no_journal.recurring_create_invoice()
def test_check_date_end(self):
with self.assertRaises(ValidationError):
self.contract.date_end = '2015-12-31'
def test_check_recurring_next_date_start_date(self):
with self.assertRaises(ValidationError):
self.contract.write({
'date_start': '2017-01-01',
'recurring_next_date': '2016-01-01',
})
def test_check_recurring_next_date_recurring_invoices(self):
with self.assertRaises(ValidationError):
self.contract.write({
'recurring_invoices': True,
'recurring_next_date': False,
})
def test_check_date_start_recurring_invoices(self):
with self.assertRaises(ValidationError):
self.contract.write({
'recurring_invoices': True,
'date_start': False,
})
def test_onchange_contract_template_id(self):
"""It should change the contract values to match the template."""
self.contract.contract_template_id = self.template
@ -241,24 +262,14 @@ class TestContract(TestContractBase):
self.contract.copy()
self.assertEqual(self.partner.contract_count, count)
def test_date_end(self):
"""It should don't create invoices from finished contract."""
AccountInvoice = self.env['account.invoice']
self.contract.date_end = '2015-12-31'
with self.assertRaises(ValidationError):
self.contract.recurring_create_invoice()
init_count = AccountInvoice.search_count(
[('contract_id', '=', self.contract.id)])
self.contract.cron_recurring_create_invoice()
last_count = AccountInvoice.search_count(
[('contract_id', '=', self.contract.id)])
self.assertEqual(last_count, init_count)
def test_same_date_start_and_date_end(self):
"""It should create one invoice with same start and end date."""
AccountInvoice = self.env['account.invoice']
self.contract.date_start = self.contract.date_end = fields.Date.today()
self.contract.recurring_next_date = self.contract.date_start
self.contract.write({
'date_start': fields.Date.today(),
'date_end': fields.Date.today(),
'recurring_next_date': fields.Date.today(),
})
init_count = AccountInvoice.search_count(
[('contract_id', '=', self.contract.id)])
self.contract.cron_recurring_create_invoice()
@ -267,3 +278,15 @@ class TestContract(TestContractBase):
self.assertEqual(last_count, init_count + 1)
with self.assertRaises(ValidationError):
self.contract.recurring_create_invoice()
def test_compute_create_invoice_visibility(self):
self.contract.write({
'recurring_next_date': '2017-01-01',
'date_start': '2016-01-01',
'date_end': False,
})
self.assertTrue(self.contract.create_invoice_visibility)
self.contract.date_end = '2017-01-01'
self.assertTrue(self.contract.create_invoice_visibility)
self.contract.date_end = '2016-01-01'
self.assertFalse(self.contract.create_invoice_visibility)

23
contract/views/account_analytic_account_view.xml

@ -8,6 +8,9 @@
<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"/>
@ -19,10 +22,11 @@
/>
<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)]}"
attrs="{'invisible': ['|', ('recurring_invoices', '!=', True), ('create_invoice_visibility', '=', False)]}"
string="Create invoices"
class="oe_link"
groups="base.group_no_one"
@ -36,9 +40,10 @@
</div>
<group col="4" attrs="{'invisible': [('recurring_invoices','!=',True)]}">
<field name="contract_template_id" colspan="4"/>
<field name="journal_id"/>
<field name="journal_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"
@ -50,10 +55,16 @@
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
</div>
<field name="recurring_invoicing_type"/>
<field name="date_start"/>
<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"/>
<field name="recurring_next_date"
attrs="{'required': [('recurring_invoices', '=', True)]}"
/>
</group>
<label for="recurring_invoice_line_ids"
attrs="{'invisible': [('recurring_invoices','=',False)]}"

2
contract/views/account_analytic_contract_view.xml

@ -80,7 +80,7 @@
<filter string="Recurrence"
context="{'group_by': 'recurring_rule_type'}"
/>
<filter string="Invoicing Type"
<filter string="Invoicing type"
context="{'group_by': 'recurring_invoicing_type'}"
/>
<filter string="Pricelist"

2
contract/views/res_partner_view.xml

@ -10,7 +10,7 @@
<xpath expr="//div[@name='button_box']" position="inside">
<button name="act_show_contract" type="object" class="oe_stat_button"
icon="fa-book"
help="show the contracts for this partner">
help="Show the contracts for this partner">
<field name="contract_count" widget="statinfo" string="Contracts"/>
</button>
</xpath>

13
contract_sale_generation/tests/test_contract_sale.py

@ -57,19 +57,12 @@ class TestContractSale(TransactionCase):
res = self.contract_line._onchange_product_id()
self.assertIn('uom_id', res['domain'])
self.contract_line.price_unit = 100.0
self.contract.partner_id = False
with self.assertRaises(ValidationError):
self.contract.recurring_create_sale()
self.contract.partner_id = self.partner.id
self.contract.recurring_create_sale()
self.sale_monthly = self.env['sale.order'].search(
[('project_id', '=', self.contract.id),
('state', '=', 'draft')])
self.assertTrue(self.sale_monthly)
self.assertEqual(self.contract.recurring_next_date, '2017-02-28')
self.sale_line = self.sale_monthly.order_line[0]
self.assertAlmostEqual(self.sale_line.price_subtotal, 50.0)
self.assertEqual(self.contract.partner_id.user_id,
@ -81,12 +74,6 @@ class TestContractSale(TransactionCase):
res = self.contract_line._onchange_product_id()
self.assertIn('uom_id', res['domain'])
self.contract_line.price_unit = 100.0
self.contract.partner_id = False
with self.assertRaises(ValidationError):
self.contract.recurring_create_sale()
self.contract.partner_id = self.partner.id
self.contract.recurring_create_sale()
self.sale_monthly = self.env['sale.order'].search(
[('project_id', '=', self.contract.id),

Loading…
Cancel
Save