Carlos Almeida
7 years ago
committed by
GitHub
185 changed files with 8116 additions and 294 deletions
-
15.travis.yml
-
10README.md
-
75agreement_account/README.rst
-
3agreement_account/__init__.py
-
22agreement_account/__manifest__.py
-
59agreement_account/demo/demo.xml
-
4agreement_account/models/__init__.py
-
26agreement_account/models/account_invoice.py
-
48agreement_account/models/agreement.py
-
17agreement_account/security/agreement_security.xml
-
3agreement_account/security/ir.model.access.csv
-
51agreement_account/views/account_invoice.xml
-
87agreement_account/views/agreement.xml
-
49agreement_sale/README.rst
-
4agreement_sale/__init__.py
-
23agreement_sale/__manifest__.py
-
4agreement_sale/models/__init__.py
-
14agreement_sale/models/agreement.py
-
20agreement_sale/models/sale_order.py
-
24agreement_sale/views/agreement.xml
-
35agreement_sale/views/sale_order.xml
-
3agreement_sale/wizard/__init__.py
-
17agreement_sale/wizard/sale_make_invoice_advance.py
-
8contract/README.rst
-
13contract/__manifest__.py
-
64contract/data/mail_template.xml
-
6contract/i18n/ca.po
-
139contract/i18n/de.po
-
6contract/i18n/el_GR.po
-
185contract/i18n/es.po
-
6contract/i18n/es_MX.po
-
139contract/i18n/fr.po
-
489contract/i18n/hi_IN.po
-
139contract/i18n/hr.po
-
144contract/i18n/hr_HR.po
-
139contract/i18n/it.po
-
139contract/i18n/nl.po
-
489contract/i18n/nl_NL.po
-
231contract/i18n/pt.po
-
139contract/i18n/pt_BR.po
-
224contract/i18n/tr.po
-
139contract/i18n/tr_TR.po
-
6contract/i18n/zh_CN.po
-
1contract/models/__init__.py
-
68contract/models/account_analytic_account.py
-
2contract/models/account_analytic_contract.py
-
19contract/models/account_analytic_contract_line.py
-
57contract/models/account_analytic_invoice_line.py
-
12contract/report/contract_views.xml
-
74contract/report/report_contract.xml
-
2contract/security/ir.model.access.csv
-
141contract/tests/test_contract.py
-
28contract/views/account_analytic_account_view.xml
-
89contract_payment_auto/README.rst
-
5contract_payment_auto/__init__.py
-
27contract_payment_auto/__manifest__.py
-
19contract_payment_auto/data/ir_cron_data.xml
-
98contract_payment_auto/data/mail_template_data.xml
-
8contract_payment_auto/models/__init__.py
-
174contract_payment_auto/models/account_analytic_account.py
-
108contract_payment_auto/models/account_analytic_contract.py
-
12contract_payment_auto/models/account_invoice.py
-
18contract_payment_auto/models/res_partner.py
-
6contract_payment_auto/tests/__init__.py
-
303contract_payment_auto/tests/test_account_analytic_account.py
-
51contract_payment_auto/tests/test_account_analytic_contract.py
-
44contract_payment_auto/views/account_analytic_account_view.xml
-
36contract_payment_auto/views/account_analytic_contract_view.xml
-
22contract_payment_auto/views/res_partner_view.xml
-
69contract_payment_mode/README.rst
-
5contract_payment_mode/__init__.py
-
29contract_payment_mode/__manifest__.py
-
26contract_payment_mode/hooks.py
-
30contract_payment_mode/i18n/ca.po
-
29contract_payment_mode/i18n/de.po
-
28contract_payment_mode/i18n/el_GR.po
-
29contract_payment_mode/i18n/es.po
-
28contract_payment_mode/i18n/es_MX.po
-
29contract_payment_mode/i18n/fi.po
-
29contract_payment_mode/i18n/fr.po
-
30contract_payment_mode/i18n/gl.po
-
29contract_payment_mode/i18n/hi_IN.po
-
29contract_payment_mode/i18n/hr.po
-
30contract_payment_mode/i18n/hr_HR.po
-
29contract_payment_mode/i18n/hu.po
-
30contract_payment_mode/i18n/it.po
-
30contract_payment_mode/i18n/nl.po
-
30contract_payment_mode/i18n/pt.po
-
29contract_payment_mode/i18n/pt_BR.po
-
29contract_payment_mode/i18n/pt_PT.po
-
29contract_payment_mode/i18n/ro.po
-
28contract_payment_mode/i18n/sk_SK.po
-
29contract_payment_mode/i18n/sl.po
-
29contract_payment_mode/i18n/tr.po
-
29contract_payment_mode/i18n/tr_TR.po
-
29contract_payment_mode/i18n/zh_CN.po
-
2contract_payment_mode/models/__init__.py
-
27contract_payment_mode/models/contract.py
-
5contract_payment_mode/tests/__init__.py
-
90contract_payment_mode/tests/test_contract_payment.py
@ -0,0 +1,75 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
=================== |
||||
|
Agreement (Account) |
||||
|
=================== |
||||
|
|
||||
|
This module adds an *Agreement* object with the following properties: |
||||
|
|
||||
|
* type (*Sale* or *Purchase*), |
||||
|
* link to a partner, |
||||
|
* name, |
||||
|
* code, |
||||
|
* signature date. |
||||
|
|
||||
|
You can link an invoice to an agreement. |
||||
|
|
||||
|
If you also install the module *agreement_sale*, you will be able to link a quotation/sale order to an agreement, and this information will be copied to the customer invoice. |
||||
|
|
||||
|
An *Agreement* can be used for: |
||||
|
|
||||
|
* Private business contracts |
||||
|
* Public markets |
||||
|
|
||||
|
It will allow you to group all the orders and invoices related to the same agreement and display the references of this agreement on the documents where you have to display it. For example, the *code* property of the agreement is used in the module *account_invoice_factur-x* (from the `edi <https://github.com/OCA/edi>`_ project) in the XML tag */CrossIndustryInvoice/SupplyChainTradeTransaction/ApplicableHeaderTradeAgreement/ContractReferencedDocument/IssuerAssignedID*. |
||||
|
|
||||
|
The main differences with the *Contract* object of Odoo: |
||||
|
|
||||
|
* a contract is an analytic account; an agreement is not related to analytic accounting. |
||||
|
* on the invoice, the contract/analytic account is per-line; an agreement is attached to the invoice (not to the lines). |
||||
|
* an agreement is a very simple object with just a few basic fields; a contract has a lot of properties and a lot of related features. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
Go to the menu *Accounting > Configuration > Management > Agreements* to create new agreements. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/110/10.0 |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/contract/issues>`_. In case of trouble, please |
||||
|
check there if your issue has already been reported. If you spotted it first, |
||||
|
help us smashing it by providing a detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,3 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import models |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
{ |
||||
|
'name': u'Agreement (Account)', |
||||
|
'summary': "Adds an agreement object linked to an invoice", |
||||
|
'version': '10.0.1.0.0', |
||||
|
'category': 'Contract', |
||||
|
'author': "Akretion,Odoo Community Association (OCA)", |
||||
|
'website': 'http://www.akretion.com', |
||||
|
'license': 'AGPL-3', |
||||
|
'depends': ['account'], |
||||
|
'data': [ |
||||
|
'security/ir.model.access.csv', |
||||
|
'security/agreement_security.xml', |
||||
|
'views/agreement.xml', |
||||
|
'views/account_invoice.xml', |
||||
|
], |
||||
|
'demo': ['demo/demo.xml'], |
||||
|
'installable': True, |
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
|
||||
|
<odoo noupdate="1"> |
||||
|
|
||||
|
|
||||
|
<record id="market1" model="agreement"> |
||||
|
<field name="code">C2C-IT0042</field> |
||||
|
<field name="name">Hardware IT</field> |
||||
|
<field name="partner_id" ref="base.res_partner_12"/> |
||||
|
<field name="agreement_type">sale</field> |
||||
|
<field name="signature_date">2017-09-10</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="market2" model="agreement"> |
||||
|
<field name="code">C2C-IT0043</field> |
||||
|
<field name="name">Fiber access office Lausanne</field> |
||||
|
<field name="partner_id" ref="base.res_partner_12"/> |
||||
|
<field name="agreement_type">sale</field> |
||||
|
<field name="signature_date" eval="time.strftime('%Y-01-01')"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="market3" model="agreement"> |
||||
|
<field name="code">AGR-VETO001</field> |
||||
|
<field name="name">Vétérinaire</field> |
||||
|
<field name="partner_id" ref="base.res_partner_2"/> |
||||
|
<field name="agreement_type">sale</field> |
||||
|
<field name="signature_date">2017-08-01</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="market4" model="agreement"> |
||||
|
<field name="code">AGR-TEL001</field> |
||||
|
<field name="name">Wazo IPBX deployment and maintenance</field> |
||||
|
<field name="partner_id" ref="base.res_partner_2"/> |
||||
|
<field name="agreement_type">sale</field> |
||||
|
<field name="signature_date">2017-05-05</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="market5" model="agreement"> |
||||
|
<field name="code">BUY-VOIP012</field> |
||||
|
<field name="name">SIP Phones supply</field> |
||||
|
<field name="partner_id" ref="base.res_partner_1"/> |
||||
|
<field name="agreement_type">purchase</field> |
||||
|
<field name="signature_date" eval="time.strftime('%Y-01-01')"/> |
||||
|
</record> |
||||
|
|
||||
|
<record id="market6" model="agreement"> |
||||
|
<field name="code">BUY-VOIP013</field> |
||||
|
<field name="name">SIP-ISDN gateways</field> |
||||
|
<field name="partner_id" ref="base.res_partner_3"/> |
||||
|
<field name="agreement_type">purchase</field> |
||||
|
<field name="signature_date">2017-09-02</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import agreement |
||||
|
from . import account_invoice |
@ -0,0 +1,26 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (http://www.akretion.com) |
||||
|
# @author: Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import models, fields, api |
||||
|
|
||||
|
|
||||
|
class AccountInvoice(models.Model): |
||||
|
_inherit = 'account.invoice' |
||||
|
|
||||
|
agreement_id = fields.Many2one( |
||||
|
'agreement', string='Agreement', ondelete='restrict', |
||||
|
readonly=True, states={'draft': [('readonly', False)]}, |
||||
|
track_visibility='onchange') |
||||
|
|
||||
|
@api.model |
||||
|
def _prepare_refund( |
||||
|
self, invoice, date_invoice=None, date=None, description=None, |
||||
|
journal_id=None): |
||||
|
values = super(AccountInvoice, self)._prepare_refund( |
||||
|
invoice, date_invoice=date_invoice, date=date, |
||||
|
description=description, journal_id=journal_id) |
||||
|
if invoice.agreement_id: |
||||
|
values['agreement_id'] = invoice.agreement_id.id |
||||
|
return values |
@ -0,0 +1,48 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
|
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class Agreement(models.Model): |
||||
|
_name = 'agreement' |
||||
|
_description = 'Agreement' |
||||
|
|
||||
|
code = fields.Char(required=True, copy=False) |
||||
|
name = fields.Char(required=True) |
||||
|
agreement_type = fields.Selection([ |
||||
|
('sale', 'Sale'), |
||||
|
('purchase', 'Purchase'), |
||||
|
], string='Type', required=True) |
||||
|
partner_id = fields.Many2one( |
||||
|
'res.partner', string='Partner', ondelete='restrict', required=True, |
||||
|
domain=[('parent_id', '=', False)]) |
||||
|
company_id = fields.Many2one( |
||||
|
'res.company', string='Company', |
||||
|
default=lambda self: self.env['res.company']._company_default_get( |
||||
|
'agreement')) |
||||
|
active = fields.Boolean(default=True) |
||||
|
signature_date = fields.Date() |
||||
|
out_invoice_ids = fields.One2many( |
||||
|
'account.invoice', 'agreement_id', string='Customer Invoices', |
||||
|
readonly=True, domain=[('type', 'in', ('out_invoice', 'out_refund'))]) |
||||
|
in_invoice_ids = fields.One2many( |
||||
|
'account.invoice', 'agreement_id', string='Supplier Invoices', |
||||
|
readonly=True, domain=[('type', 'in', ('in_invoice', 'in_refund'))]) |
||||
|
|
||||
|
def name_get(self): |
||||
|
res = [] |
||||
|
for agr in self: |
||||
|
name = agr.name |
||||
|
if agr.code: |
||||
|
name = u'[%s] %s' % (agr.code, agr.name) |
||||
|
res.append((agr.id, name)) |
||||
|
return res |
||||
|
|
||||
|
_sql_constraints = [( |
||||
|
'code_partner_company_unique', |
||||
|
'unique(code, partner_id, company_id)', |
||||
|
'This agreement code already exists for this partner!' |
||||
|
)] |
@ -0,0 +1,17 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
|
||||
|
<odoo noupdate="1"> |
||||
|
|
||||
|
|
||||
|
<record id="agreement_rule" model="ir.rule"> |
||||
|
<field name="name">Agreement multi-company</field> |
||||
|
<field name="model_id" ref="model_agreement"/> |
||||
|
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])]</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,3 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
access_agreement_read,Read access on agreement to Employees,model_agreement,base.group_user,1,0,0,0 |
||||
|
access_agreement_full,Full access on agreement to Invoicing and Payment grp,model_agreement,account.group_account_invoice,1,1,1,1 |
@ -0,0 +1,51 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<!-- |
||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
|
||||
|
<record id="invoice_form" model="ir.ui.view"> |
||||
|
<field name="name">agreement.customer.invoice.form</field> |
||||
|
<field name="model">account.invoice</field> |
||||
|
<field name="inherit_id" ref="account.invoice_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//page/group/group/field[@name='name']" position="after"> |
||||
|
<field name="agreement_id" |
||||
|
domain="[('partner_id', 'child_of', commercial_partner_id), ('agreement_type', '=', 'sale')]" |
||||
|
context="{'default_partner_id': commercial_partner_id, 'default_agreement_type': 'sale'}"/> |
||||
|
<field name="commercial_partner_id" invisible="1"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="invoice_supplier_form" model="ir.ui.view"> |
||||
|
<field name="name">agreement.supplier.invoice.form</field> |
||||
|
<field name="model">account.invoice</field> |
||||
|
<field name="inherit_id" ref="account.invoice_supplier_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//page/group/group/field[@name='company_id']" position="after"> |
||||
|
<field name="agreement_id" |
||||
|
domain="[('partner_id', 'child_of', commercial_partner_id), ('agreement_type', '=', 'purchase')]" |
||||
|
context="{'default_partner_id': commercial_partner_id, 'default_agreement_type': 'purchase'}"/> |
||||
|
<field name="commercial_partner_id" invisible="1"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="view_account_invoice_filter" model="ir.ui.view"> |
||||
|
<field name="name">agreement.account.invoice.search</field> |
||||
|
<field name="model">account.invoice</field> |
||||
|
<field name="inherit_id" ref="account.view_account_invoice_filter"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<group expand="0" position="inside"> |
||||
|
<filter string="Agreement" name="agreement_groupby" |
||||
|
context="{'group_by': 'agreement_id'}"/> |
||||
|
</group> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,87 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<!-- |
||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
|
||||
|
<record id="agreement_form" model="ir.ui.view"> |
||||
|
<field name="name">agreement.form</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Agreement"> |
||||
|
<div class="oe_button_box" name="button_box"> |
||||
|
<button name="toggle_active" type="object" |
||||
|
class="oe_stat_button" icon="fa-archive"> |
||||
|
<field name="active" widget="boolean_button" |
||||
|
options='{"terminology": "archive"}'/> |
||||
|
</button> |
||||
|
</div> |
||||
|
<group name="main"> |
||||
|
<field name="partner_id"/> |
||||
|
<field name="name"/> |
||||
|
<field name="code"/> |
||||
|
<field name="agreement_type"/> |
||||
|
<field name="signature_date"/> |
||||
|
<field name="company_id" groups="base.group_multi_company"/> |
||||
|
</group> |
||||
|
<group string="Customer Invoices" name="out_invoices" attrs="{'invisible': [('agreement_type', '!=', 'sale')]}"> |
||||
|
<field name="out_invoice_ids" nolabel="1"/> |
||||
|
</group> |
||||
|
<group string="Supplier Invoices" name="in_invoices" attrs="{'invisible': [('agreement_type', '!=', 'purchase')]}"> |
||||
|
<field name="in_invoice_ids" nolabel="1"/> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_tree" model="ir.ui.view"> |
||||
|
<field name="name">agreement.tree</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Agreements"> |
||||
|
<field name="partner_id"/> |
||||
|
<field name="code"/> |
||||
|
<field name="name"/> |
||||
|
<field name="agreement_type"/> |
||||
|
<field name="signature_date"/> |
||||
|
<field name="company_id" groups="base.group_multi_company"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_search" model="ir.ui.view"> |
||||
|
<field name="name">agreement.search</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Search Agreements"> |
||||
|
<field name="name" filter_domain="['|', ('name', 'ilike', self), ('code', 'ilike', self)]" string="Name or Number"/> |
||||
|
<field name="partner_id"/> |
||||
|
<filter name="sale" string="Sale" domain="[('agreement_type', '=', 'sale')]"/> |
||||
|
<filter name="purchase" string="Purchase" domain="[('agreement_type', '=', 'purchase')]"/> |
||||
|
<separator/> |
||||
|
<filter name="inactive" string="Archived" domain="[('active', '=', False)]"/> |
||||
|
<group name="groupby"> |
||||
|
<filter name="partner_groupby" string="Customer" |
||||
|
context="{'group_by': 'partner_id'}"/> |
||||
|
<filter name="signature_date_groupby" string="Signature Date" |
||||
|
context="{'group_by': 'signature_date'}"/> |
||||
|
<filter name="agreement_type_groupby" string="Type" |
||||
|
context="{'group_by': 'agreement_type'}"/> |
||||
|
</group> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="agreement_action" model="ir.actions.act_window"> |
||||
|
<field name="name">Agreements</field> |
||||
|
<field name="res_model">agreement</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="agreement_menu" action="agreement_action" |
||||
|
parent="account.account_management_menu" sequence="100"/> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,49 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
================ |
||||
|
Agreement (Sale) |
||||
|
================ |
||||
|
|
||||
|
This module is an extension of the module *agreement_account* for sale orders. |
||||
|
|
||||
|
With this module, you will be able to link a quotation/sale order to a sale agreement. Upon invoice creation, this information will be copied to the customer invoice. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/110/10.0 |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/contract/issues>`_. In case of trouble, please |
||||
|
check there if your issue has already been reported. If you spotted it first, |
||||
|
help us smashing it by providing a detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import models |
||||
|
from . import wizard |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
{ |
||||
|
'name': u'Agreement (Sale)', |
||||
|
'summary': "Link an agreement to a sale order and copy to invoice", |
||||
|
'version': '10.0.1.0.0', |
||||
|
'category': 'Contract', |
||||
|
'author': "Akretion,Odoo Community Association (OCA)", |
||||
|
'website': 'http://www.akretion.com', |
||||
|
'license': 'AGPL-3', |
||||
|
'depends': [ |
||||
|
'agreement_account', |
||||
|
'sale_commercial_partner', |
||||
|
], |
||||
|
'data': [ |
||||
|
'views/sale_order.xml', |
||||
|
'views/agreement.xml', |
||||
|
], |
||||
|
'installable': True, |
||||
|
'auto_install': True, |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import sale_order |
||||
|
from . import agreement |
@ -0,0 +1,14 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
|
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class Agreement(models.Model): |
||||
|
_inherit = 'agreement' |
||||
|
|
||||
|
sale_ids = fields.One2many( |
||||
|
'sale.order', 'agreement_id', string='Sale Orders', readonly=True, |
||||
|
domain=[('state', 'not in', ('draft', 'sent', 'cancel'))]) |
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (http://www.akretion.com) |
||||
|
# @author: Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class SaleOrder(models.Model): |
||||
|
_inherit = 'sale.order' |
||||
|
|
||||
|
agreement_id = fields.Many2one( |
||||
|
'agreement', string='Agreement', ondelete='restrict', |
||||
|
track_visibility='onchange', readonly=True, |
||||
|
states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}) |
||||
|
|
||||
|
def _prepare_invoice(self): |
||||
|
vals = super(SaleOrder, self)._prepare_invoice() |
||||
|
vals['agreement_id'] = self.agreement_id.id or False |
||||
|
return vals |
@ -0,0 +1,24 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<!-- |
||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
|
||||
|
<record id="agreement_form" model="ir.ui.view"> |
||||
|
<field name="name">agreement.form</field> |
||||
|
<field name="model">agreement</field> |
||||
|
<field name="inherit_id" ref="agreement_account.agreement_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<group name="in_invoices" position="after"> |
||||
|
<group name="sale_orders" string="Sales Orders" attrs="{'invisible': [('agreement_type', '!=', 'sale')]}"> |
||||
|
<field name="sale_ids" nolabel="1"/> |
||||
|
</group> |
||||
|
</group> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,35 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<!-- |
||||
|
© 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>) |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
|
||||
|
<record id="view_order_form" model="ir.ui.view"> |
||||
|
<field name="name">agreement.sale.order.form</field> |
||||
|
<field name="model">sale.order</field> |
||||
|
<field name="inherit_id" ref="sale_commercial_partner.view_order_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="client_order_ref" position="after"> |
||||
|
<field name="agreement_id" |
||||
|
domain="[('partner_id', 'child_of', commercial_partner_id), ('agreement_type', '=', 'sale')]" |
||||
|
context="{'default_partner_id': commercial_partner_id, 'default_agreement_type': 'sale'}"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="view_sales_order_filter" model="ir.ui.view"> |
||||
|
<field name="name">agreement.sale.order.search</field> |
||||
|
<field name="model">sale.order</field> |
||||
|
<field name="inherit_id" ref="sale.view_sales_order_filter"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<group expand="0" position="inside"> |
||||
|
<filter string="Agreement" name="agreement_groupby" context="{'group_by': 'agreement_id'}"/> |
||||
|
</group> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,3 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import sale_make_invoice_advance |
@ -0,0 +1,17 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2017 Akretion (http://www.akretion.com) |
||||
|
# @author: Alexis de Lattre <alexis.delattre@akretion.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import models |
||||
|
|
||||
|
|
||||
|
class SaleAdvancePaymentInv(models.TransientModel): |
||||
|
_inherit = 'sale.advance.payment.inv' |
||||
|
|
||||
|
def _create_invoice(self, order, so_line, amount): |
||||
|
inv = super(SaleAdvancePaymentInv, self)._create_invoice( |
||||
|
order, so_line, amount) |
||||
|
if order.agreement_id: |
||||
|
inv.agreement_id = order.agreement_id.id |
||||
|
return inv |
@ -0,0 +1,64 @@ |
|||||
|
<?xml version="1.0" ?> |
||||
|
<odoo noupdate="1"> |
||||
|
|
||||
|
<record id="email_contract_template" model="mail.template"> |
||||
|
<field name="name">Email Contract Template</field> |
||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (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="partner_to">${object.partner_id.id}</field> |
||||
|
<field name="model_id" ref="contract.model_account_analytic_account"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="report_template" ref="contract.report_contract"/> |
||||
|
<field name="report_name">Contract</field> |
||||
|
<field name="lang">${object.partner_id.lang}</field> |
||||
|
<field name="body_html"><![CDATA[ |
||||
|
<div style="font-family: 'Lucida Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; "> |
||||
|
<p>Hello ${object.partner_id.name or ''},</p> |
||||
|
<p>A new contract has been created: </p> |
||||
|
|
||||
|
<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> |
||||
|
<strong>REFERENCES</strong><br /> |
||||
|
Contract: <strong>${object.name}</strong><br /> |
||||
|
% if object.date_start: |
||||
|
Contract Date Start: ${object.date_start or ''}<br /> |
||||
|
% endif |
||||
|
|
||||
|
% if object.user_id: |
||||
|
% if object.user_id.email: |
||||
|
Your Contact: <a href="mailto:${object.user_id.email or ''}?subject=Contract%20${object.name}">${object.user_id.name}</a> |
||||
|
% else: |
||||
|
Your Contact: ${object.user_id.name} |
||||
|
% endif |
||||
|
% endif |
||||
|
</p> |
||||
|
|
||||
|
<br/> |
||||
|
<p>If you have any questions, do not hesitate to contact us.</p> |
||||
|
<p>Thank you for choosing ${object.company_id.name or 'us'}!</p> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<div style="width: 375px; margin: 0px; padding: 0px; background-color: #8E0000; border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; background-repeat: repeat no-repeat;"> |
||||
|
<h3 style="margin: 0px; padding: 2px 14px; font-size: 12px; color: #DDD;"> |
||||
|
<strong style="text-transform:uppercase;">${object.company_id.name}</strong></h3> |
||||
|
</div> |
||||
|
<div style="width: 347px; margin: 0px; padding: 5px 14px; line-height: 16px; background-color: #F2F2F2;"> |
||||
|
<span style="color: #222; margin-bottom: 5px; display: block; "> |
||||
|
${object.company_id.partner_id.sudo().with_context(show_address=True, html_format=True).name_get()[0][1] | safe} |
||||
|
</span> |
||||
|
% if object.company_id.phone: |
||||
|
<div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "> |
||||
|
Phone: ${object.company_id.phone} |
||||
|
</div> |
||||
|
% endif |
||||
|
% if object.company_id.website: |
||||
|
<div> |
||||
|
Web: <a href="${object.company_id.website}">${object.company_id.website}</a> |
||||
|
</div> |
||||
|
%endif |
||||
|
<p></p> |
||||
|
</div> |
||||
|
</div> |
||||
|
]]></field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,489 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract |
||||
|
# |
||||
|
# Translators: |
||||
|
# Ashish Deshmukh <ashish.p.deshmukh@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-08-17 01:05+0000\n" |
||||
|
"PO-Revision-Date: 2017-08-17 01:05+0000\n" |
||||
|
"Last-Translator: Ashish Deshmukh <ashish.p.deshmukh@gmail.com>, 2017\n" |
||||
|
"Language-Team: Hindi (India) (https://www.transifex.com/oca/teams/23907/hi_IN/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: hi_IN\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:mail.template,body_html:contract.email_contract_template |
||||
|
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" |
||||
|
"\n" |
||||
|
" <p style=\"border-left: 1px solid #8e0000; margin-left: 30px;\">\n" |
||||
|
" <strong>REFERENCES</strong><br />\n" |
||||
|
" Contract: <strong>${object.name}</strong><br />\n" |
||||
|
" % if object.date_start:\n" |
||||
|
" Contract Date Start: ${object.date_start or ''}<br />\n" |
||||
|
" % endif\n" |
||||
|
"\n" |
||||
|
" % if object.user_id:\n" |
||||
|
" % if object.user_id.email:\n" |
||||
|
" Your Contact: <a href=\"mailto:${object.user_id.email or ''}?subject=Contract%20${object.name}\">${object.user_id.name}</a>\n" |
||||
|
" % else:\n" |
||||
|
" Your Contact: ${object.user_id.name}\n" |
||||
|
" % endif\n" |
||||
|
" % endif\n" |
||||
|
" </p>\n" |
||||
|
"\n" |
||||
|
" <br/>\n" |
||||
|
" <p>If you have any questions, do not hesitate to contact us.</p>\n" |
||||
|
" <p>Thank you for choosing ${object.company_id.name or 'us'}!</p>\n" |
||||
|
" <br/>\n" |
||||
|
" <br/>\n" |
||||
|
" <div style=\"width: 375px; margin: 0px; padding: 0px; background-color: #8E0000; border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; background-repeat: repeat no-repeat;\">\n" |
||||
|
" <h3 style=\"margin: 0px; padding: 2px 14px; font-size: 12px; color: #DDD;\">\n" |
||||
|
" <strong style=\"text-transform:uppercase;\">${object.company_id.name}</strong></h3>\n" |
||||
|
" </div>\n" |
||||
|
" <div style=\"width: 347px; margin: 0px; padding: 5px 14px; line-height: 16px; background-color: #F2F2F2;\">\n" |
||||
|
" <span style=\"color: #222; margin-bottom: 5px; display: block; \">\n" |
||||
|
" ${object.company_id.partner_id.sudo().with_context(show_address=True, html_format=True).name_get()[0][1] | safe}\n" |
||||
|
" </span>\n" |
||||
|
" % if object.company_id.phone:\n" |
||||
|
" <div style=\"margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; \">\n" |
||||
|
" Phone: ${object.company_id.phone}\n" |
||||
|
" </div>\n" |
||||
|
" % endif\n" |
||||
|
" % if object.company_id.website:\n" |
||||
|
" <div>\n" |
||||
|
" Web: <a href=\"${object.company_id.website}\">${object.company_id.website}</a>\n" |
||||
|
" </div>\n" |
||||
|
" %endif\n" |
||||
|
" <p></p>\n" |
||||
|
" </div>\n" |
||||
|
"</div>\n" |
||||
|
" " |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:mail.template,subject:contract.email_contract_template |
||||
|
msgid "${object.company_id.name} Contract (Ref ${object.name or 'n/a'})" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "<strong>#END#</strong>: End date of the invoiced period" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "<strong>#START#</strong>: Start date of the invoiced period" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Contract: </strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Date Start: </strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Description</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Partner:</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Price</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Quantity</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Recurring Items</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Responsible: </strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Total</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Unit Price</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "Account Analytic Lines" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_analytic_account |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_analytic_account_id |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "विश्लेषणात्मक खाता" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,help:contract.account_analytic_contract_action |
||||
|
msgid "Click to create a new contract template." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,help:contract.action_account_analytic_overdue_all |
||||
|
msgid "Click to create a new contract." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_account.py:216 |
||||
|
#, python-format |
||||
|
msgid "Compose Email" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.report.xml,name:contract.report_contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_invoice_contract_id |
||||
|
#: model:mail.template,report_name:contract.email_contract_template |
||||
|
msgid "Contract" |
||||
|
msgstr "अनुबंध" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_contract_template_id |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form |
||||
|
msgid "Contract Template" |
||||
|
msgstr "अनुबंध टेम्पलेट" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,name:contract.account_analytic_contract_action |
||||
|
#: model:ir.ui.menu,name:contract.account_analytic_contract_menu |
||||
|
#: 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 "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,name:contract.action_account_analytic_overdue_all |
||||
|
#: model:ir.ui.menu,name:contract.menu_action_account_analytic_overdue_all |
||||
|
#: model:ir.ui.menu,name:contract.menu_config_contract |
||||
|
msgid "Contracts" |
||||
|
msgstr "अनुबंध" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
msgid "Create invoices" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_create_uid |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_create_uid |
||||
|
msgid "Created by" |
||||
|
msgstr "द्वारा बनाया गया" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_create_date |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_create_date |
||||
|
msgid "Created on" |
||||
|
msgstr "को निर्मित" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_next_date |
||||
|
msgid "Date of Next Invoice" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_start |
||||
|
msgid "Date start" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Day(s)" |
||||
|
msgstr "दिन()" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_name |
||||
|
msgid "Description" |
||||
|
msgstr "विवरण" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_discount |
||||
|
msgid "Discount (%)" |
||||
|
msgstr "छूट (%)" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_invoice_line.py:56 |
||||
|
#, python-format |
||||
|
msgid "Discount should be less or equal to 100" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_display_name |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_display_name |
||||
|
msgid "Display Name" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoices |
||||
|
msgid "Generate recurring invoices automatically" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search |
||||
|
msgid "Group By..." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_id |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_id |
||||
|
msgid "ID" |
||||
|
msgstr "आईडी" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_invoice |
||||
|
msgid "Invoice" |
||||
|
msgstr "बीजक" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_form |
||||
|
msgid "Invoice Lines" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,name:contract.act_recurring_invoices |
||||
|
msgid "Invoices" |
||||
|
msgstr "चालान" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Invoicing type" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_search |
||||
|
msgid "Journal" |
||||
|
msgstr "पत्रिका" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract___last_update |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line___last_update |
||||
|
msgid "Last Modified on" |
||||
|
msgstr "अंतिम बार संशोधित" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_write_uid |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_write_uid |
||||
|
msgid "Last Updated by" |
||||
|
msgstr "द्वारा अंतिम अद्यतन" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_write_date |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_write_date |
||||
|
msgid "Last Updated on" |
||||
|
msgstr "अंतिम बार अद्यतन किया गया" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Month(s)" |
||||
|
msgstr "माह(महीने)" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Month(s) last day" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_name |
||||
|
msgid "Name" |
||||
|
msgstr "नाम" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search |
||||
|
msgid "Next Invoice" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_account.py:137 |
||||
|
#, python-format |
||||
|
msgid "Please define a sale journal for the company '%s'." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_invoicing_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_invoicing_type:0 |
||||
|
msgid "Post-paid" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_invoicing_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_invoicing_type:0 |
||||
|
msgid "Pre-paid" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_search |
||||
|
msgid "Pricelist" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_product_id |
||||
|
msgid "Product" |
||||
|
msgstr "प्रोडक्ट" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_quantity |
||||
|
msgid "Quantity" |
||||
|
msgstr "संख्या" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_search |
||||
|
msgid "Recurrence" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search |
||||
|
msgid "Recurring Invoices" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Repeat Every" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Repeat every (Days/Week/Month/Year)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_user_id |
||||
|
msgid "Responsible" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
msgid "Send by Email" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Specify Interval for automatic invoice generation." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Specify if process date is 'from' or 'to' invoicing date" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_price_subtotal |
||||
|
msgid "Sub Total" |
||||
|
msgstr "उप कुल" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_price_unit |
||||
|
msgid "Unit Price" |
||||
|
msgstr "यूनिट मूल्य" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_uom_id |
||||
|
msgid "Unit of Measure" |
||||
|
msgstr "माप की इकाई" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "VAT:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Week(s)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Year(s)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_account.py:129 |
||||
|
#, python-format |
||||
|
msgid "You must first select a Customer for Contract %s!" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_analytic_contract |
||||
|
msgid "account.analytic.contract" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_analytic_invoice_line |
||||
|
msgid "account.analytic.invoice.line" |
||||
|
msgstr "account.analytic.invoice.line" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
msgid "⇒ Show recurring invoices" |
||||
|
msgstr "" |
@ -0,0 +1,489 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract |
||||
|
# |
||||
|
# Translators: |
||||
|
# Peter Hageman <hageman.p@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-08-17 01:05+0000\n" |
||||
|
"PO-Revision-Date: 2017-08-17 01:05+0000\n" |
||||
|
"Last-Translator: Peter Hageman <hageman.p@gmail.com>, 2017\n" |
||||
|
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/teams/23907/nl_NL/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: nl_NL\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:mail.template,body_html:contract.email_contract_template |
||||
|
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" |
||||
|
"\n" |
||||
|
" <p style=\"border-left: 1px solid #8e0000; margin-left: 30px;\">\n" |
||||
|
" <strong>REFERENCES</strong><br />\n" |
||||
|
" Contract: <strong>${object.name}</strong><br />\n" |
||||
|
" % if object.date_start:\n" |
||||
|
" Contract Date Start: ${object.date_start or ''}<br />\n" |
||||
|
" % endif\n" |
||||
|
"\n" |
||||
|
" % if object.user_id:\n" |
||||
|
" % if object.user_id.email:\n" |
||||
|
" Your Contact: <a href=\"mailto:${object.user_id.email or ''}?subject=Contract%20${object.name}\">${object.user_id.name}</a>\n" |
||||
|
" % else:\n" |
||||
|
" Your Contact: ${object.user_id.name}\n" |
||||
|
" % endif\n" |
||||
|
" % endif\n" |
||||
|
" </p>\n" |
||||
|
"\n" |
||||
|
" <br/>\n" |
||||
|
" <p>If you have any questions, do not hesitate to contact us.</p>\n" |
||||
|
" <p>Thank you for choosing ${object.company_id.name or 'us'}!</p>\n" |
||||
|
" <br/>\n" |
||||
|
" <br/>\n" |
||||
|
" <div style=\"width: 375px; margin: 0px; padding: 0px; background-color: #8E0000; border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; background-repeat: repeat no-repeat;\">\n" |
||||
|
" <h3 style=\"margin: 0px; padding: 2px 14px; font-size: 12px; color: #DDD;\">\n" |
||||
|
" <strong style=\"text-transform:uppercase;\">${object.company_id.name}</strong></h3>\n" |
||||
|
" </div>\n" |
||||
|
" <div style=\"width: 347px; margin: 0px; padding: 5px 14px; line-height: 16px; background-color: #F2F2F2;\">\n" |
||||
|
" <span style=\"color: #222; margin-bottom: 5px; display: block; \">\n" |
||||
|
" ${object.company_id.partner_id.sudo().with_context(show_address=True, html_format=True).name_get()[0][1] | safe}\n" |
||||
|
" </span>\n" |
||||
|
" % if object.company_id.phone:\n" |
||||
|
" <div style=\"margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; \">\n" |
||||
|
" Phone: ${object.company_id.phone}\n" |
||||
|
" </div>\n" |
||||
|
" % endif\n" |
||||
|
" % if object.company_id.website:\n" |
||||
|
" <div>\n" |
||||
|
" Web: <a href=\"${object.company_id.website}\">${object.company_id.website}</a>\n" |
||||
|
" </div>\n" |
||||
|
" %endif\n" |
||||
|
" <p></p>\n" |
||||
|
" </div>\n" |
||||
|
"</div>\n" |
||||
|
" " |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:mail.template,subject:contract.email_contract_template |
||||
|
msgid "${object.company_id.name} Contract (Ref ${object.name or 'n/a'})" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "<strong>#END#</strong>: End date of the invoiced period" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "<strong>#START#</strong>: Start date of the invoiced period" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Contract: </strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Date Start: </strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Description</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Partner:</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Price</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Quantity</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Recurring Items</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Responsible: </strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Total</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "<strong>Unit Price</strong>" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "Account Analytic Lines" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_analytic_account |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_analytic_account_id |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,help:contract.account_analytic_contract_action |
||||
|
msgid "Click to create a new contract template." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,help:contract.action_account_analytic_overdue_all |
||||
|
msgid "Click to create a new contract." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_account.py:216 |
||||
|
#, python-format |
||||
|
msgid "Compose Email" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.report.xml,name:contract.report_contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_invoice_contract_id |
||||
|
#: model:mail.template,report_name:contract.email_contract_template |
||||
|
msgid "Contract" |
||||
|
msgstr "Contract" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_contract_template_id |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_contract_view_form |
||||
|
msgid "Contract Template" |
||||
|
msgstr "Contractsjabloon" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,name:contract.account_analytic_contract_action |
||||
|
#: model:ir.ui.menu,name:contract.account_analytic_contract_menu |
||||
|
#: 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 "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,name:contract.action_account_analytic_overdue_all |
||||
|
#: model:ir.ui.menu,name:contract.menu_action_account_analytic_overdue_all |
||||
|
#: model:ir.ui.menu,name:contract.menu_config_contract |
||||
|
msgid "Contracts" |
||||
|
msgstr "Contracten" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
msgid "Create invoices" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_create_uid |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_create_uid |
||||
|
msgid "Created by" |
||||
|
msgstr "Aangemaakt door" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_create_date |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_create_date |
||||
|
msgid "Created on" |
||||
|
msgstr "Aangemaakt op" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_next_date |
||||
|
msgid "Date of Next Invoice" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_date_start |
||||
|
msgid "Date start" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Day(s)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_name |
||||
|
msgid "Description" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_discount |
||||
|
msgid "Discount (%)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_invoice_line.py:56 |
||||
|
#, python-format |
||||
|
msgid "Discount should be less or equal to 100" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_display_name |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_display_name |
||||
|
msgid "Display Name" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_recurring_invoices |
||||
|
msgid "Generate recurring invoices automatically" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search |
||||
|
msgid "Group By..." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_id |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_id |
||||
|
msgid "ID" |
||||
|
msgstr "ID" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_invoice |
||||
|
msgid "Invoice" |
||||
|
msgstr "Factuur" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_form |
||||
|
msgid "Invoice Lines" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.actions.act_window,name:contract.act_recurring_invoices |
||||
|
msgid "Invoices" |
||||
|
msgstr "Facturen" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Invoicing type" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_search |
||||
|
msgid "Journal" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract___last_update |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line___last_update |
||||
|
msgid "Last Modified on" |
||||
|
msgstr "Laatst aangepast op" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_write_uid |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_write_uid |
||||
|
msgid "Last Updated by" |
||||
|
msgstr "Laatst bijgewerkt door" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_write_date |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_write_date |
||||
|
msgid "Last Updated on" |
||||
|
msgstr "Laatst bijgewerkt op" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: 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 "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Month(s)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Month(s) last day" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_contract_name |
||||
|
msgid "Name" |
||||
|
msgstr "Naam" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search |
||||
|
msgid "Next Invoice" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_account.py:137 |
||||
|
#, python-format |
||||
|
msgid "Please define a sale journal for the company '%s'." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_invoicing_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_invoicing_type:0 |
||||
|
msgid "Post-paid" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_invoicing_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_invoicing_type:0 |
||||
|
msgid "Pre-paid" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_search |
||||
|
msgid "Pricelist" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_product_id |
||||
|
msgid "Product" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_quantity |
||||
|
msgid "Quantity" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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.ui.view,arch_db:contract.account_analytic_contract_view_search |
||||
|
msgid "Recurrence" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
#: model:ir.ui.view,arch_db:contract.view_account_analytic_account_contract_search |
||||
|
msgid "Recurring Invoices" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Repeat Every" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Repeat every (Days/Week/Month/Year)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_account_user_id |
||||
|
msgid "Responsible" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
msgid "Send by Email" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Specify Interval for automatic invoice generation." |
||||
|
msgstr "" |
||||
|
|
||||
|
#. 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 |
||||
|
msgid "Specify if process date is 'from' or 'to' invoicing date" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_price_subtotal |
||||
|
msgid "Sub Total" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_price_unit |
||||
|
msgid "Unit Price" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model.fields,field_description:contract.field_account_analytic_invoice_line_uom_id |
||||
|
msgid "Unit of Measure" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.report_contract_document |
||||
|
msgid "VAT:" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Week(s)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: selection:account.analytic.account,recurring_rule_type:0 |
||||
|
#: selection:account.analytic.contract,recurring_rule_type:0 |
||||
|
msgid "Year(s)" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: code:addons/contract/models/account_analytic_account.py:129 |
||||
|
#, python-format |
||||
|
msgid "You must first select a Customer for Contract %s!" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_analytic_contract |
||||
|
msgid "account.analytic.contract" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.model,name:contract.model_account_analytic_invoice_line |
||||
|
msgid "account.analytic.invoice.line" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: contract |
||||
|
#: model:ir.ui.view,arch_db:contract.account_analytic_account_recurring_form_form |
||||
|
msgid "⇒ Show recurring invoices" |
||||
|
msgstr "" |
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountAnalyticContractLine(models.Model): |
||||
|
|
||||
|
_name = 'account.analytic.contract.line' |
||||
|
_description = 'Contract Lines' |
||||
|
_inherit = 'account.analytic.invoice.line' |
||||
|
|
||||
|
analytic_account_id = fields.Many2one( |
||||
|
string='Contract', |
||||
|
comodel_name='account.analytic.contract', |
||||
|
required=True, |
||||
|
ondelete='cascade', |
||||
|
) |
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
|
||||
|
<report |
||||
|
id="report_contract" |
||||
|
model="account.analytic.account" |
||||
|
string="Contract" |
||||
|
report_type="qweb-pdf" |
||||
|
name="contract.report_contract_document" |
||||
|
file="contract.report_contract"/> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,74 @@ |
|||||
|
<?xml version="1.0" ?> |
||||
|
<odoo> |
||||
|
|
||||
|
<template id="report_contract_document"> |
||||
|
<t t-call="report.html_container"> |
||||
|
<t t-foreach="docs" t-as="o"> |
||||
|
<t t-call="report.external_layout"> |
||||
|
<div class="page"> |
||||
|
<div class="oe_structure"/> |
||||
|
<div class="row" id="partner_info"> |
||||
|
<div class="col-xs-5 col-xs-offset-7"> |
||||
|
<p id="partner_info"><strong>Partner:</strong></p> |
||||
|
<div t-field="o.partner_id" t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "mobile", "fax", "email"], "no_marker": true, "phone_icons": true}'/> |
||||
|
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row" id="header_info"> |
||||
|
<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>Contract: </strong><p t-field="o.code"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="row" id="invoice_info"> |
||||
|
<t t-set="total" t-value="0"/> |
||||
|
<div class="col-xs-12"> |
||||
|
<t t-set="total" t-value="0"/> |
||||
|
<p id="services_info"><strong>Recurring Items</strong></p> |
||||
|
<table class="table table-condensed"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th><strong>Description</strong></th> |
||||
|
<th class="text-right"><strong>Quantity</strong></th> |
||||
|
<th class="text-right"><strong>Unit Price</strong></th> |
||||
|
<th class="text-right"><strong>Price</strong></th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<tr t-foreach="o.recurring_invoice_line_ids" t-as="l"> |
||||
|
<td> |
||||
|
<span t-field="l.name"/> |
||||
|
</td> |
||||
|
<td class="text-right"> |
||||
|
<span t-field="l.quantity"/> |
||||
|
</td> |
||||
|
<td class="text-right"> |
||||
|
<span t-field="l.price_unit" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> |
||||
|
</td> |
||||
|
<td class="text-right"> |
||||
|
<span t-field="l.price_subtotal" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> |
||||
|
</td> |
||||
|
<t t-set="total" t-value="total + l.price_subtotal"/> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
<div class="col-xs-4 pull-right"> |
||||
|
<table class="table table-condensed"> |
||||
|
<tr class="border-black"> |
||||
|
<td><strong>Total</strong></td> |
||||
|
<td class="text-right"> |
||||
|
<span t-esc="total" t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</t> |
||||
|
</template> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,89 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
===================== |
||||
|
Contract Auto Payment |
||||
|
===================== |
||||
|
|
||||
|
This module allows for the configuration of automatic payments on invoices that are created by a contract. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
Enable Automatic Payment |
||||
|
------------------------ |
||||
|
|
||||
|
* Navigate to a customer contract |
||||
|
* Check the `Auto Pay?` box to enable automatic payment |
||||
|
* Configure the options as desired |
||||
|
* Set the `Payment Token` to the payment token that should be used for automatic payment |
||||
|
|
||||
|
Automatic Payment Settings |
||||
|
-------------------------- |
||||
|
|
||||
|
The following settings are available at both the contract and contract template level: |
||||
|
|
||||
|
| Name | Description | |
||||
|
|------|-------------| |
||||
|
| Invoice Message | Message template that is used to send invoices to customers upon creation. | |
||||
|
| Payment Retry Message | Message template that is used to alert a customer that their automatic payment failed for some reason and will be retried. | |
||||
|
| Payment Fail Message | Message template that is used to alert a customer that their automatic payment failed and will no longer be retried. | |
||||
|
| Auto Pay Retries | Amount of times to attempt an automatic payment before discontinuing and removing the payment token from the contract/account payment method. | |
||||
|
| Auto Pay Retry Hours | Amount of hours that should lapse until retrying failed payments. | |
||||
|
|
||||
|
Payment Token |
||||
|
------------- |
||||
|
|
||||
|
A valid payment token is required to use this module. These tokens are typically created during the `website_sale` checkout process, but they can also be created manually at the acquirer. |
||||
|
|
||||
|
A payment token can be defined in one of two areas: |
||||
|
|
||||
|
* Contract - Defining a payment token in the contract will allow for the use of this token for automatic payments on this contract only. |
||||
|
* Partner - Defining a payment token in the partner will allow for the use of this token for automatic payments on all contracts for this partner that do not have a payment token defined. |
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/110/10.0 |
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
* None |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/contract/issues>`_. In case of trouble, please |
||||
|
check there if your issue has already been reported. If you spotted it first, |
||||
|
help us smash it by providing detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Images |
||||
|
------ |
||||
|
|
||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Dave Lasley <dave@laslabs.com> |
||||
|
|
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import models |
@ -0,0 +1,27 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
{ |
||||
|
"name": "Contract - Auto Payment", |
||||
|
"summary": "Adds automatic payments to contracts.", |
||||
|
"version": "10.0.1.0.0", |
||||
|
"category": "Contract Management", |
||||
|
"license": "AGPL-3", |
||||
|
"author": "LasLabs, " |
||||
|
"Odoo Community Association (OCA)", |
||||
|
"website": "https://laslabs.com", |
||||
|
"depends": [ |
||||
|
"contract", |
||||
|
"payment", |
||||
|
], |
||||
|
"data": [ |
||||
|
"data/mail_template_data.xml", |
||||
|
"data/ir_cron_data.xml", |
||||
|
"views/account_analytic_account_view.xml", |
||||
|
"views/account_analytic_contract_view.xml", |
||||
|
"views/res_partner_view.xml", |
||||
|
], |
||||
|
"installable": True, |
||||
|
"application": False, |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright 2017 LasLabs Inc. |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
|
||||
|
<odoo noupdate="1"> |
||||
|
|
||||
|
<record id="ir_cron_auto_pay" model="ir.cron"> |
||||
|
<field name="name">Contract Automatic Payments</field> |
||||
|
<field name="interval_type">hours</field> |
||||
|
<field name="interval_number">1</field> |
||||
|
<field name="model">account.analytic.account</field> |
||||
|
<field name="function">cron_retry_auto_pay</field> |
||||
|
<field name="args">()</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,98 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright 2017 LasLabs Inc. |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
|
||||
|
<odoo noupdate="1"> |
||||
|
|
||||
|
<record id="mail_template_auto_pay_retry" model="mail.template"> |
||||
|
<field name="name">Invoice - AutoPay To Retry</field> |
||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.name, object.user_id.email) or '')|safe}</field> |
||||
|
<field name="subject">Automatic Payment Failure (Ref ${object.number or 'n/a'})</field> |
||||
|
<field name="partner_to">${object.partner_id.id}</field> |
||||
|
<field name="model_id" ref="account.model_account_invoice"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="report_template" ref="account.account_invoices"/> |
||||
|
<field name="report_name">Invoice_${(object.number or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field> |
||||
|
<field name="lang">${object.partner_id.lang}</field> |
||||
|
<field name="body_html"><![CDATA[ |
||||
|
|
||||
|
<p> |
||||
|
Hello ${object.partner_id.name} |
||||
|
% set access_action = object.get_access_action() |
||||
|
% set access_url = access_action['type'] == 'ir.actions.act_url' and access_action['url'] or '/report/pdf/account.report_invoice/' + str(object.id) |
||||
|
% if object.partner_id.parent_id: |
||||
|
(<i>${object.partner_id.parent_id.name}</i>) |
||||
|
% endif |
||||
|
, |
||||
|
</p> |
||||
|
|
||||
|
<p> |
||||
|
The automatic payment for your invoice |
||||
|
<a href="${access_url}"> |
||||
|
<strong> |
||||
|
${object.number} |
||||
|
</strong> |
||||
|
% if object.origin: |
||||
|
(with reference: ${object.origin} ) |
||||
|
% endif |
||||
|
</a> |
||||
|
failed. |
||||
|
</p> |
||||
|
|
||||
|
<p> |
||||
|
Please verify that your payment information is correct, and that funds are |
||||
|
available in the account. |
||||
|
</p> |
||||
|
|
||||
|
]]> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="mail_template_auto_pay_fail" model="mail.template"> |
||||
|
<field name="name">Invoice - AutoPay Failed</field> |
||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.name, object.user_id.email) or '')|safe}</field> |
||||
|
<field name="subject">Automatic Payment Failure (Ref ${object.number or 'n/a'})</field> |
||||
|
<field name="partner_to">${object.partner_id.id}</field> |
||||
|
<field name="model_id" ref="account.model_account_invoice"/> |
||||
|
<field name="auto_delete" eval="True"/> |
||||
|
<field name="report_template" ref="account.account_invoices"/> |
||||
|
<field name="report_name">Invoice_${(object.number or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field> |
||||
|
<field name="lang">${object.partner_id.lang}</field> |
||||
|
<field name="body_html"><![CDATA[ |
||||
|
|
||||
|
<p> |
||||
|
Hello ${object.partner_id.name} |
||||
|
% set access_action = object.get_access_action() |
||||
|
% set access_url = access_action['type'] == 'ir.actions.act_url' and access_action['url'] or '/report/pdf/account.report_invoice/' + str(object.id) |
||||
|
% if object.partner_id.parent_id: |
||||
|
(<i>${object.partner_id.parent_id.name}</i>) |
||||
|
% endif |
||||
|
, |
||||
|
</p> |
||||
|
|
||||
|
<p> |
||||
|
The automatic payment for your invoice |
||||
|
<a href="${access_url}"> |
||||
|
<strong> |
||||
|
${object.number} |
||||
|
</strong> |
||||
|
% if object.origin: |
||||
|
(with reference: ${object.origin} ) |
||||
|
% endif |
||||
|
</a> |
||||
|
failed. |
||||
|
</p> |
||||
|
|
||||
|
<p> |
||||
|
Please verify that your payment information is correct, and that funds are |
||||
|
available in the account. |
||||
|
</p> |
||||
|
|
||||
|
]]> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,8 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import account_analytic_account |
||||
|
from . import account_analytic_contract |
||||
|
from . import account_invoice |
||||
|
from . import res_partner |
@ -0,0 +1,174 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
import logging |
||||
|
|
||||
|
from datetime import datetime, timedelta |
||||
|
|
||||
|
from odoo import api, fields, models, _ |
||||
|
|
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
class AccountAnalyticAccount(models.Model): |
||||
|
_inherit = 'account.analytic.account' |
||||
|
|
||||
|
payment_token_id = fields.Many2one( |
||||
|
string='Payment Token', |
||||
|
comodel_name='payment.token', |
||||
|
domain="[('partner_id', '=', partner_id)]", |
||||
|
context="{'default_partner_id': partner_id}", |
||||
|
help='This is the payment token that will be used to automatically ' |
||||
|
'reconcile debts against this account. If none is set, the ' |
||||
|
'bill to partner\'s default token will be used.', |
||||
|
) |
||||
|
|
||||
|
@api.multi |
||||
|
@api.onchange('partner_id') |
||||
|
def _onchange_partner_id_payment_token(self): |
||||
|
""" Clear the payment token when the partner is changed. """ |
||||
|
self.payment_token_id = self.env['payment.token'] |
||||
|
|
||||
|
@api.model |
||||
|
def cron_retry_auto_pay(self): |
||||
|
""" Retry automatic payments for appropriate invoices. """ |
||||
|
|
||||
|
invoice_lines = self.env['account.invoice.line'].search([ |
||||
|
('invoice_id.state', '=', 'open'), |
||||
|
('invoice_id.auto_pay_attempts', '>', 0), |
||||
|
('account_analytic_id.is_auto_pay', '=', True), |
||||
|
]) |
||||
|
now = datetime.now() |
||||
|
|
||||
|
for invoice_line in invoice_lines: |
||||
|
|
||||
|
account = invoice_line.account_analytic_id |
||||
|
invoice = invoice_line.invoice_id |
||||
|
fail_time = fields.Datetime.from_string(invoice.auto_pay_failed) |
||||
|
retry_delta = timedelta(hours=account.auto_pay_retry_hours) |
||||
|
retry_time = fail_time + retry_delta |
||||
|
|
||||
|
if retry_time < now: |
||||
|
account._do_auto_pay(invoice) |
||||
|
|
||||
|
@api.multi |
||||
|
def _create_invoice(self): |
||||
|
""" If automatic payment is enabled, perform auto pay actions. """ |
||||
|
invoice = super(AccountAnalyticAccount, self)._create_invoice() |
||||
|
if not self.is_auto_pay: |
||||
|
return invoice |
||||
|
self._do_auto_pay(invoice) |
||||
|
return invoice |
||||
|
|
||||
|
@api.multi |
||||
|
def _do_auto_pay(self, invoice): |
||||
|
""" Perform all automatic payment operations on open invoices. """ |
||||
|
self.ensure_one() |
||||
|
invoice.ensure_one() |
||||
|
invoice.action_invoice_open() |
||||
|
self._send_invoice_message(invoice) |
||||
|
self._pay_invoice(invoice) |
||||
|
|
||||
|
@api.multi |
||||
|
def _pay_invoice(self, invoice): |
||||
|
""" Pay the invoice using the account or partner token. """ |
||||
|
|
||||
|
if invoice.state != 'open': |
||||
|
_logger.info('Cannot pay an invoice that is not in open state.') |
||||
|
return |
||||
|
|
||||
|
if not invoice.residual: |
||||
|
_logger.debug('Cannot pay an invoice with no balance.') |
||||
|
return |
||||
|
|
||||
|
token = self.payment_token_id or self.partner_id.payment_token_id |
||||
|
if not token: |
||||
|
_logger.debug( |
||||
|
'Cannot pay an invoice without defining a payment token', |
||||
|
) |
||||
|
return |
||||
|
|
||||
|
transaction = self.env['payment.transaction'].create( |
||||
|
self._get_tx_vals(invoice), |
||||
|
) |
||||
|
valid_states = ['authorized', 'done'] |
||||
|
|
||||
|
try: |
||||
|
result = transaction.s2s_do_transaction() |
||||
|
if not result or transaction.state not in valid_states: |
||||
|
_logger.debug( |
||||
|
'Payment transaction failed (%s)', |
||||
|
transaction.state_message, |
||||
|
) |
||||
|
else: |
||||
|
# Success |
||||
|
return True |
||||
|
|
||||
|
except Exception: |
||||
|
_logger.exception( |
||||
|
'Payment transaction (%s) generated a gateway error.', |
||||
|
transaction.id, |
||||
|
) |
||||
|
|
||||
|
transaction.state = 'error' |
||||
|
invoice.write({ |
||||
|
'auto_pay_attempts': invoice.auto_pay_attempts + 1, |
||||
|
'auto_pay_failed': fields.Datetime.now(), |
||||
|
}) |
||||
|
|
||||
|
if invoice.auto_pay_attempts >= self.auto_pay_retries: |
||||
|
template = self.pay_fail_mail_template_id |
||||
|
self.write({ |
||||
|
'is_auto_pay': False, |
||||
|
'payment_token_id': False, |
||||
|
}) |
||||
|
if token == self.partner_id.payment_token_id: |
||||
|
self.partner_id.payment_token_id = False |
||||
|
|
||||
|
else: |
||||
|
template = self.pay_retry_mail_template_id |
||||
|
|
||||
|
if template: |
||||
|
template.send_mail(invoice.id) |
||||
|
|
||||
|
return |
||||
|
|
||||
|
@api.multi |
||||
|
def _get_tx_vals(self, invoice): |
||||
|
""" Return values for create of payment.transaction for invoice.""" |
||||
|
amount_due = invoice.residual |
||||
|
token = self.payment_token_id |
||||
|
partner = token.partner_id |
||||
|
reference = self.env['payment.transaction'].get_next_reference( |
||||
|
invoice.number, |
||||
|
) |
||||
|
return { |
||||
|
'reference': '%s' % reference, |
||||
|
'acquirer_id': token.acquirer_id.id, |
||||
|
'payment_token_id': token.id, |
||||
|
'amount': amount_due, |
||||
|
'state': 'draft', |
||||
|
'currency_id': invoice.currency_id.id, |
||||
|
'partner_id': partner.id, |
||||
|
'partner_country_id': partner.country_id.id, |
||||
|
'partner_city': partner.city, |
||||
|
'partner_zip': partner.zip, |
||||
|
'partner_email': partner.email, |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def _send_invoice_message(self, invoice): |
||||
|
""" Send the appropriate emails for the invoices if needed. """ |
||||
|
if invoice.sent: |
||||
|
return |
||||
|
if not self.invoice_mail_template_id: |
||||
|
return |
||||
|
_logger.info('Sending invoice %s, %s (template %s)', |
||||
|
invoice, invoice.number, self.invoice_mail_template_id) |
||||
|
mail_id = self.invoice_mail_template_id.send_mail(invoice.id) |
||||
|
invoice.with_context(mail_post_autofollow=True) |
||||
|
invoice.sent = True |
||||
|
invoice.message_post(body=_("Invoice sent")) |
||||
|
return self.env['mail.mail'].browse(mail_id) |
@ -0,0 +1,108 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
def _context_mail_templates(env): |
||||
|
return env['account.analytic.contract']._context_mail_templates() |
||||
|
|
||||
|
|
||||
|
class AccountAnalyticContract(models.Model): |
||||
|
_inherit = 'account.analytic.contract' |
||||
|
|
||||
|
invoice_mail_template_id = fields.Many2one( |
||||
|
string='Invoice Message', |
||||
|
comodel_name='mail.template', |
||||
|
default=lambda s: s._default_invoice_mail_template_id(), |
||||
|
domain="[('model', '=', 'account.invoice')]", |
||||
|
context=_context_mail_templates, |
||||
|
help="During the automatic payment process, an invoice will be " |
||||
|
"created and validated. If this template is selected, it will " |
||||
|
"automatically be sent to the customer during this process " |
||||
|
"using the defined template.", |
||||
|
) |
||||
|
pay_retry_mail_template_id = fields.Many2one( |
||||
|
string='Payment Retry Message', |
||||
|
comodel_name='mail.template', |
||||
|
default=lambda s: s._default_pay_retry_mail_template_id(), |
||||
|
domain="[('model', '=', 'account.invoice')]", |
||||
|
context=_context_mail_templates, |
||||
|
help="If automatic payment fails for some reason, but will be " |
||||
|
"re-attempted later, this message will be sent to the billed " |
||||
|
"partner.", |
||||
|
) |
||||
|
pay_fail_mail_template_id = fields.Many2one( |
||||
|
string='Payment Failed Message', |
||||
|
comodel_name='mail.template', |
||||
|
default=lambda s: s._default_pay_fail_mail_template_id(), |
||||
|
domain="[('model', '=', 'account.invoice')]", |
||||
|
context=_context_mail_templates, |
||||
|
help="If automatic payment fails for some reason, this message " |
||||
|
"will be sent to the billed partner.", |
||||
|
) |
||||
|
is_auto_pay = fields.Boolean( |
||||
|
string='Auto Pay?', |
||||
|
default=True, |
||||
|
help="Check this to enable automatic payment for invoices that are " |
||||
|
"created for this contract.", |
||||
|
) |
||||
|
auto_pay_retries = fields.Integer( |
||||
|
default=lambda s: s._default_auto_pay_retries(), |
||||
|
help="Amount times to retry failed/declined automatic payment " |
||||
|
"before giving up." |
||||
|
) |
||||
|
auto_pay_retry_hours = fields.Integer( |
||||
|
default=lambda s: s._default_auto_pay_retry_hours(), |
||||
|
help="Amount of hours that should lapse until a failed automatic " |
||||
|
"is retried.", |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def _default_invoice_mail_template_id(self): |
||||
|
return self.env.ref( |
||||
|
'account.email_template_edi_invoice', |
||||
|
raise_if_not_found=False, |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def _default_pay_retry_mail_template_id(self): |
||||
|
return self.env.ref( |
||||
|
'contract_payment_auto.mail_template_auto_pay_retry', |
||||
|
raise_if_not_found=False, |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def _default_pay_fail_mail_template_id(self): |
||||
|
return self.env.ref( |
||||
|
'contract_payment_auto.mail_template_auto_pay_fail', |
||||
|
raise_if_not_found=False, |
||||
|
) |
||||
|
|
||||
|
@api.model |
||||
|
def _default_auto_pay_retries(self): |
||||
|
return 3 |
||||
|
|
||||
|
@api.model |
||||
|
def _default_auto_pay_retry_hours(self): |
||||
|
return 24 |
||||
|
|
||||
|
@api.model |
||||
|
def _context_mail_templates(self): |
||||
|
""" Return a context for use in mail templates. """ |
||||
|
default_model = self.env.ref('account.model_account_invoice') |
||||
|
report_template = self.env.ref('account.account_invoices') |
||||
|
return { |
||||
|
'default_model_id': default_model.id, |
||||
|
'default_email_from': "${(object.user_id.email and '%s <%s>' % " |
||||
|
"(object.user_id.name, object.user_id.email)" |
||||
|
" or '')|safe}", |
||||
|
'default_partner_to': '${object.partner_id.id}', |
||||
|
'default_lang': '${object.partner_id.lang}', |
||||
|
'default_auto_delete': True, |
||||
|
'report_template': report_template.id, |
||||
|
'report_name': "Invoice_${(object.number or '').replace('/','_')}" |
||||
|
"_${object.state == 'draft' and 'draft' or ''}", |
||||
|
|
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountInvoice(models.Model): |
||||
|
_inherit = 'account.invoice' |
||||
|
|
||||
|
auto_pay_attempts = fields.Integer() |
||||
|
auto_pay_failed = fields.Datetime() |
@ -0,0 +1,18 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = 'res.partner' |
||||
|
|
||||
|
payment_token_id = fields.Many2one( |
||||
|
string='Payment Token', |
||||
|
comodel_name='payment.token', |
||||
|
domain="[('id', 'in', payment_token_ids)]", |
||||
|
help='This is the payment token that will be used to automatically ' |
||||
|
'reconcile debts for this partner, if there is not one already ' |
||||
|
'set on the analytic account.', |
||||
|
) |
@ -0,0 +1,6 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import test_account_analytic_account |
||||
|
from . import test_account_analytic_contract |
@ -0,0 +1,303 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
import mock |
||||
|
|
||||
|
from contextlib import contextmanager |
||||
|
|
||||
|
from odoo import fields |
||||
|
from odoo.tools import mute_logger |
||||
|
from odoo.tests.common import TransactionCase |
||||
|
|
||||
|
from ..models import account_analytic_account |
||||
|
|
||||
|
|
||||
|
class TestAccountAnalyticAccount(TransactionCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(TestAccountAnalyticAccount, self).setUp() |
||||
|
self.Model = self.env['account.analytic.account'] |
||||
|
self.partner = self.env.ref('base.res_partner_2') |
||||
|
self.product = self.env.ref('product.product_product_2') |
||||
|
self.product.taxes_id += self.env['account.tax'].search( |
||||
|
[('type_tax_use', '=', 'sale')], limit=1) |
||||
|
self.product.description_sale = 'Test description sale' |
||||
|
self.template_vals = { |
||||
|
'recurring_rule_type': 'yearly', |
||||
|
'recurring_interval': 12345, |
||||
|
'name': 'Test Contract Template', |
||||
|
'is_auto_pay': True, |
||||
|
} |
||||
|
self.template = self.env['account.analytic.contract'].create( |
||||
|
self.template_vals, |
||||
|
) |
||||
|
self.acquirer = self.env['payment.acquirer'].create({ |
||||
|
'name': 'Test Acquirer', |
||||
|
'provider': 'manual', |
||||
|
'view_template_id': self.env['ir.ui.view'].search([], limit=1).id, |
||||
|
}) |
||||
|
self.payment_token = self.env['payment.token'].create({ |
||||
|
'name': 'Test Token', |
||||
|
'partner_id': self.partner.id, |
||||
|
'active': True, |
||||
|
'acquirer_id': self.acquirer.id, |
||||
|
'acquirer_ref': 'Test', |
||||
|
}) |
||||
|
self.contract = self.Model.create({ |
||||
|
'name': 'Test Contract', |
||||
|
'partner_id': self.partner.id, |
||||
|
'pricelist_id': self.partner.property_product_pricelist.id, |
||||
|
'recurring_invoices': True, |
||||
|
'date_start': '2016-02-15', |
||||
|
'recurring_next_date': fields.Datetime.now(), |
||||
|
'payment_token_id': self.payment_token.id, |
||||
|
}) |
||||
|
self.contract_line = self.env['account.analytic.invoice.line'].create({ |
||||
|
'analytic_account_id': self.contract.id, |
||||
|
'product_id': self.product.id, |
||||
|
'name': 'Services from #START# to #END#', |
||||
|
'quantity': 1, |
||||
|
'uom_id': self.product.uom_id.id, |
||||
|
'price_unit': 100, |
||||
|
'discount': 50, |
||||
|
}) |
||||
|
|
||||
|
def _validate_invoice(self, invoice): |
||||
|
self.assertEqual(len(invoice), 1) |
||||
|
self.assertEqual(invoice._name, 'account.invoice') |
||||
|
|
||||
|
def _create_invoice(self, open=False, sent=False): |
||||
|
self.contract.is_auto_pay = False |
||||
|
invoice = self.contract._create_invoice() |
||||
|
if open or sent: |
||||
|
invoice.action_invoice_open() |
||||
|
if sent: |
||||
|
invoice.sent = True |
||||
|
self.contract.is_auto_pay = True |
||||
|
return invoice |
||||
|
|
||||
|
@contextmanager |
||||
|
def _mock_transaction(self, state='authorized', s2s_side_effect=None): |
||||
|
|
||||
|
Transactions = self.contract.env['payment.transaction'] |
||||
|
TransactionsCreate = Transactions.create |
||||
|
|
||||
|
if not callable(s2s_side_effect): |
||||
|
s2s_side_effect = [s2s_side_effect] |
||||
|
|
||||
|
s2s = mock.MagicMock() |
||||
|
s2s.side_effect = s2s_side_effect |
||||
|
|
||||
|
def create(vals): |
||||
|
record = TransactionsCreate(vals) |
||||
|
record.state = state |
||||
|
return record |
||||
|
|
||||
|
model_create = mock.MagicMock() |
||||
|
model_create.side_effect = create |
||||
|
|
||||
|
Transactions._patch_method('create', model_create) |
||||
|
Transactions._patch_method('s2s_do_transaction', s2s) |
||||
|
|
||||
|
try: |
||||
|
yield |
||||
|
finally: |
||||
|
Transactions._revert_method('create') |
||||
|
Transactions._revert_method('s2s_do_transaction') |
||||
|
|
||||
|
def test_onchange_partner_id_payment_token(self): |
||||
|
""" It should clear the payment token. """ |
||||
|
self.assertTrue(self.contract.payment_token_id) |
||||
|
self.contract._onchange_partner_id_payment_token() |
||||
|
self.assertFalse(self.contract.payment_token_id) |
||||
|
|
||||
|
def test_create_invoice_no_autopay(self): |
||||
|
""" It should return the new invoice without calling autopay. """ |
||||
|
self.contract.is_auto_pay = False |
||||
|
with mock.patch.object(self.contract, '_do_auto_pay') as method: |
||||
|
invoice = self.contract._create_invoice() |
||||
|
self._validate_invoice(invoice) |
||||
|
method.assert_not_called() |
||||
|
|
||||
|
def test_create_invoice_autopay(self): |
||||
|
""" It should return the new invoice after calling autopay. """ |
||||
|
with mock.patch.object(self.contract, '_do_auto_pay') as method: |
||||
|
invoice = self.contract._create_invoice() |
||||
|
self._validate_invoice(invoice) |
||||
|
method.assert_called_once_with(invoice) |
||||
|
|
||||
|
def test_do_auto_pay_ensure_one(self): |
||||
|
""" It should ensure_one on self. """ |
||||
|
with self.assertRaises(ValueError): |
||||
|
self.env['account.analytic.account']._do_auto_pay( |
||||
|
self._create_invoice(), |
||||
|
) |
||||
|
|
||||
|
def test_do_auto_pay_invoice_ensure_one(self): |
||||
|
""" It should ensure_one on the invoice. """ |
||||
|
with self.assertRaises(ValueError): |
||||
|
self.contract._do_auto_pay( |
||||
|
self.env['account.invoice'], |
||||
|
) |
||||
|
|
||||
|
def test_do_auto_pay_open_invoice(self): |
||||
|
""" It should open the invoice. """ |
||||
|
invoice = self._create_invoice() |
||||
|
self.contract._do_auto_pay(invoice) |
||||
|
self.assertEqual(invoice.state, 'open') |
||||
|
|
||||
|
def test_do_auto_pay_sends_message(self): |
||||
|
""" It should call the send message method with the invoice. """ |
||||
|
with mock.patch.object(self.contract, '_send_invoice_message') as m: |
||||
|
invoice = self._create_invoice() |
||||
|
self.contract._do_auto_pay(invoice) |
||||
|
m.assert_called_once_with(invoice) |
||||
|
|
||||
|
def test_do_auto_pay_does_pay(self): |
||||
|
""" It should try to pay the invoice. """ |
||||
|
with mock.patch.object(self.contract, '_pay_invoice') as m: |
||||
|
invoice = self._create_invoice() |
||||
|
self.contract._do_auto_pay(invoice) |
||||
|
m.assert_called_once_with(invoice) |
||||
|
|
||||
|
def test_pay_invoice_not_open(self): |
||||
|
""" It should return None if the invoice isn't open. """ |
||||
|
invoice = self._create_invoice() |
||||
|
res = self.contract._pay_invoice(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
def test_pay_invoice_no_residual(self): |
||||
|
""" It should return None if no residual on the invoice. """ |
||||
|
invoice = self._create_invoice() |
||||
|
invoice.state = 'open' |
||||
|
res = self.contract._pay_invoice(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
def test_pay_invoice_no_token(self): |
||||
|
""" It should return None if no payment token. """ |
||||
|
self.contract.payment_token_id = False |
||||
|
invoice = self._create_invoice(True) |
||||
|
res = self.contract._pay_invoice(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
def test_pay_invoice_success(self): |
||||
|
""" It should return True on success. """ |
||||
|
with self._mock_transaction(s2s_side_effect=True): |
||||
|
invoice = self._create_invoice(True) |
||||
|
res = self.contract._pay_invoice(invoice) |
||||
|
self.assertTrue(res) |
||||
|
|
||||
|
@mute_logger(account_analytic_account.__name__) |
||||
|
def test_pay_invoice_exception(self): |
||||
|
""" It should catch exceptions. """ |
||||
|
with self._mock_transaction(s2s_side_effect=Exception): |
||||
|
invoice = self._create_invoice(True) |
||||
|
res = self.contract._pay_invoice(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
def test_pay_invoice_invalid_state(self): |
||||
|
""" It should return None on invalid state. """ |
||||
|
with self._mock_transaction(s2s_side_effect=True): |
||||
|
invoice = self._create_invoice(True) |
||||
|
invoice.state = 'draft' |
||||
|
res = self.contract._pay_invoice(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
@mute_logger(account_analytic_account.__name__) |
||||
|
def test_pay_invoice_increments_retries(self): |
||||
|
""" It should increment invoice retries on failure. """ |
||||
|
with self._mock_transaction(s2s_side_effect=False): |
||||
|
invoice = self._create_invoice(True) |
||||
|
self.assertFalse(invoice.auto_pay_attempts) |
||||
|
self.contract._pay_invoice(invoice) |
||||
|
self.assertTrue(invoice.auto_pay_attempts) |
||||
|
|
||||
|
def test_pay_invoice_updates_fail_date(self): |
||||
|
""" It should update the invoice auto pay fail date on failure. """ |
||||
|
with self._mock_transaction(s2s_side_effect=False): |
||||
|
invoice = self._create_invoice(True) |
||||
|
self.assertFalse(invoice.auto_pay_failed) |
||||
|
self.contract._pay_invoice(invoice) |
||||
|
self.assertTrue(invoice.auto_pay_failed) |
||||
|
|
||||
|
def test_pay_invoice_too_many_attempts(self): |
||||
|
""" It should clear autopay after too many attempts. """ |
||||
|
with self._mock_transaction(s2s_side_effect=False): |
||||
|
invoice = self._create_invoice(True) |
||||
|
invoice.auto_pay_attempts = self.contract.auto_pay_retries - 1 |
||||
|
self.contract._pay_invoice(invoice) |
||||
|
self.assertFalse(self.contract.is_auto_pay) |
||||
|
self.assertFalse(self.contract.payment_token_id) |
||||
|
|
||||
|
def test_pay_invoice_too_many_attempts_partner_token(self): |
||||
|
""" It should clear the partner token when attempts were on it. """ |
||||
|
self.partner.payment_token_id = self.contract.payment_token_id |
||||
|
with self._mock_transaction(s2s_side_effect=False): |
||||
|
invoice = self._create_invoice(True) |
||||
|
invoice.auto_pay_attempts = self.contract.auto_pay_retries |
||||
|
self.contract._pay_invoice(invoice) |
||||
|
self.assertFalse(self.partner.payment_token_id) |
||||
|
|
||||
|
def test_get_tx_vals(self): |
||||
|
""" It should return a dict. """ |
||||
|
self.assertIsInstance( |
||||
|
self.contract._get_tx_vals(self._create_invoice()), |
||||
|
dict, |
||||
|
) |
||||
|
|
||||
|
def test_send_invoice_message_sent(self): |
||||
|
""" It should return None if the invoice has already been sent. """ |
||||
|
invoice = self._create_invoice(sent=True) |
||||
|
res = self.contract._send_invoice_message(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
def test_send_invoice_message_no_template(self): |
||||
|
""" It should return None if the invoice isn't sent. """ |
||||
|
invoice = self._create_invoice(True) |
||||
|
self.contract.invoice_mail_template_id = False |
||||
|
res = self.contract._send_invoice_message(invoice) |
||||
|
self.assertIs(res, None) |
||||
|
|
||||
|
def test_send_invoice_message_sets_invoice_state(self): |
||||
|
""" It should set the invoice to sent. """ |
||||
|
invoice = self._create_invoice(True) |
||||
|
self.assertFalse(invoice.sent) |
||||
|
self.contract._send_invoice_message(invoice) |
||||
|
self.assertTrue(invoice.sent) |
||||
|
|
||||
|
def test_send_invoice_message_returns_mail(self): |
||||
|
""" It should create and return the message. """ |
||||
|
invoice = self._create_invoice(True) |
||||
|
res = self.contract._send_invoice_message(invoice) |
||||
|
self.assertEqual(res._name, 'mail.mail') |
||||
|
|
||||
|
def test_cron_retry_auto_pay_needed(self): |
||||
|
""" It should auto-pay the correct invoice if needed. """ |
||||
|
invoice = self._create_invoice(True) |
||||
|
invoice.write({ |
||||
|
'auto_pay_attempts': 1, |
||||
|
'auto_pay_failed': '2015-01-01 00:00:00', |
||||
|
}) |
||||
|
meth = mock.MagicMock() |
||||
|
self.contract._patch_method('_do_auto_pay', meth) |
||||
|
try: |
||||
|
self.contract.cron_retry_auto_pay() |
||||
|
finally: |
||||
|
self.contract._revert_method('_do_auto_pay') |
||||
|
meth.assert_called_once_with(invoice) |
||||
|
|
||||
|
def test_cron_retry_auto_pay_skip(self): |
||||
|
""" It should skip invoices that don't need to be paid. """ |
||||
|
invoice = self._create_invoice(True) |
||||
|
invoice.write({ |
||||
|
'auto_pay_attempts': 1, |
||||
|
'auto_pay_failed': fields.Datetime.now(), |
||||
|
}) |
||||
|
meth = mock.MagicMock() |
||||
|
self.contract._patch_method('_do_auto_pay', meth) |
||||
|
try: |
||||
|
self.contract.cron_retry_auto_pay() |
||||
|
finally: |
||||
|
self.contract._revert_method('_do_auto_pay') |
||||
|
meth.assert_not_called() |
@ -0,0 +1,51 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 LasLabs Inc. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo.tests.common import TransactionCase |
||||
|
|
||||
|
|
||||
|
class TestAccountAnalyticContract(TransactionCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(TestAccountAnalyticContract, self).setUp() |
||||
|
self.Model = self.env['account.analytic.contract'] |
||||
|
|
||||
|
def test_default_invoice_mail_template_id(self): |
||||
|
""" It should return a mail template associated with invoice. """ |
||||
|
res = self.Model._default_invoice_mail_template_id() |
||||
|
self.assertEqual( |
||||
|
res.model, 'account.invoice', |
||||
|
) |
||||
|
|
||||
|
def test_default_pay_retry_mail_template_id(self): |
||||
|
""" It should return a mail template associated with invoice. """ |
||||
|
res = self.Model._default_pay_retry_mail_template_id() |
||||
|
self.assertEqual( |
||||
|
res.model, 'account.invoice', |
||||
|
) |
||||
|
|
||||
|
def test_default_pay_fail_mail_template_id(self): |
||||
|
""" It should return a mail template associated with invoice. """ |
||||
|
res = self.Model._default_pay_fail_mail_template_id() |
||||
|
self.assertEqual( |
||||
|
res.model, 'account.invoice', |
||||
|
) |
||||
|
|
||||
|
def test_default_auto_pay_retries(self): |
||||
|
""" It should return an int. """ |
||||
|
self.assertIsInstance( |
||||
|
self.Model._default_auto_pay_retries(), int, |
||||
|
) |
||||
|
|
||||
|
def test_default_auto_pay_retry_hours(self): |
||||
|
""" It should return an int. """ |
||||
|
self.assertIsInstance( |
||||
|
self.Model._default_auto_pay_retry_hours(), int, |
||||
|
) |
||||
|
|
||||
|
def test_context_mail_templates(self): |
||||
|
""" It should return a dict. """ |
||||
|
self.assertIsInstance( |
||||
|
self.Model._context_mail_templates(), dict, |
||||
|
) |
@ -0,0 +1,44 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright 2017 LasLabs Inc. |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record id="account_analytic_account_recurring_form_form" model="ir.ui.view"> |
||||
|
<field name="name">Contract Auto Pay</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="//button[@name='contract.act_recurring_invoices']" position="after"> |
||||
|
<br attrs="{'invisible': [('recurring_invoices','!=',True)]}" /> |
||||
|
<field name="is_auto_pay" |
||||
|
class="oe_inline" |
||||
|
attrs="{'invisible': [('recurring_invoices','!=',True)]}" |
||||
|
/> |
||||
|
<label for="is_auto_pay" |
||||
|
attrs="{'invisible': [('recurring_invoices','!=',True)]}" |
||||
|
/> |
||||
|
</xpath> |
||||
|
<xpath expr="//label[@for='recurring_invoice_line_ids']" position="before"> |
||||
|
<group name="group_auto_pay" |
||||
|
attrs="{'invisible': [('is_auto_pay', '=', False)]}" |
||||
|
> |
||||
|
<group> |
||||
|
<field name="payment_token_id" /> |
||||
|
<field name="invoice_mail_template_id" /> |
||||
|
<field name="pay_retry_mail_template_id" /> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="pay_fail_mail_template_id" /> |
||||
|
<field name="auto_pay_retries" /> |
||||
|
<field name="auto_pay_retry_hours" /> |
||||
|
</group> |
||||
|
</group> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,36 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright 2017 LasLabs Inc. |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record id="account_analytic_contract_view_form" model="ir.ui.view"> |
||||
|
<field name="name">Contract Template Auto Pay</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="//group[@name='group_main_right']" position="inside"> |
||||
|
<field name="is_auto_pay" /> |
||||
|
</xpath> |
||||
|
<xpath expr="//group[@name='group_main']" position="after"> |
||||
|
<group name="group_auto_pay" |
||||
|
attrs="{'invisible': [('is_auto_pay', '=', False)]}" |
||||
|
> |
||||
|
<group> |
||||
|
<field name="invoice_mail_template_id" /> |
||||
|
<field name="pay_retry_mail_template_id" /> |
||||
|
<field name="auto_pay_retry_hours" /> |
||||
|
</group> |
||||
|
<group> |
||||
|
<field name="pay_fail_mail_template_id" /> |
||||
|
<field name="auto_pay_retries" /> |
||||
|
</group> |
||||
|
</group> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
|
||||
|
<!-- |
||||
|
Copyright 2017 LasLabs Inc. |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
--> |
||||
|
|
||||
|
<odoo> |
||||
|
|
||||
|
<record id="view_partner_form" model="ir.ui.view"> |
||||
|
<field name="name">Res Partner Auto Pay</field> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="base.view_partner_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//group[@name='sale']" position="inside"> |
||||
|
<field name="payment_token_ids" invisible="1" /> |
||||
|
<field name="payment_token_id" /> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,69 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
===================== |
||||
|
Contract Payment Mode |
||||
|
===================== |
||||
|
|
||||
|
This module allows to set a payment mode on contract for creating the invoices |
||||
|
with this payment mode. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
Your user should be a Sales Manager or Accountant. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
#. Go to *Accounting > Sales > Contracts*. |
||||
|
#. Create one. |
||||
|
#. Select a partner to which invoice. |
||||
|
#. If the partner has a payment mode, this payment mode is selected here. |
||||
|
#. If not, or if you want another payment mode, you can change it in the |
||||
|
corresponding field. |
||||
|
#. Click on **Generate recurring invoices automatically** checkbox. |
||||
|
#. Add a product to invoice. |
||||
|
#. If you create an invoice, new invoice will have the selected payment mode. |
||||
|
|
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/110/10.0 |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues <https://github.com/OCA/contract/issues>`_. |
||||
|
In case of trouble, please |
||||
|
check there if your issue has already been reported. If you spotted it first, |
||||
|
help us smash it by providing detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Ángel Moya <angel.moya@domatix.com> |
||||
|
* Antonio Espinosa <antonioea@antiun.com> |
||||
|
* Vicent Cubells <vicent.cubells@tecnativa.com> |
||||
|
* David Vidal <david.vidal@tecnativa.com> |
||||
|
* Carlos Dauden <carlos.dauden@tecnativa.com> |
||||
|
|
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import models |
||||
|
from .hooks import post_init_hook |
@ -0,0 +1,29 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2015 Domatix (<www.domatix.com>) |
||||
|
# Copyright 2016 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# Copyright 2017 Tecnativa - Vicent Cubells |
||||
|
# Copyright 2017 Tecnativa - David Vidal |
||||
|
# Copyright 2017 Tecnativa - Carlos Dauden <carlos.dauden@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
{ |
||||
|
'name': 'Contract Payment Mode', |
||||
|
'summary': 'Payment mode in contracts and their invoices', |
||||
|
'version': '10.0.1.0.1', |
||||
|
'author': 'Domatix, ' |
||||
|
'Tecnativa, ' |
||||
|
'Odoo Community Association (OCA)', |
||||
|
'website': 'http://www.domatix.com', |
||||
|
'depends': [ |
||||
|
'contract', |
||||
|
'account_payment_partner' |
||||
|
], |
||||
|
'category': 'Sales Management', |
||||
|
'license': 'AGPL-3', |
||||
|
'data': [ |
||||
|
'views/contract_view.xml', |
||||
|
], |
||||
|
'post_init_hook': 'post_init_hook', |
||||
|
'installable': True, |
||||
|
'auto_install': True, |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2016 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import api, SUPERUSER_ID |
||||
|
import logging |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
def post_init_hook(cr, registry): |
||||
|
"""Copy payment mode from partner to the new field at contract.""" |
||||
|
with api.Environment.manage(): |
||||
|
env = api.Environment(cr, SUPERUSER_ID, {}) |
||||
|
m_contract = env['account.analytic.account'] |
||||
|
contracts = m_contract.search([ |
||||
|
('payment_mode_id', '=', False), |
||||
|
]) |
||||
|
if contracts: |
||||
|
_logger.info('Setting payment mode: %d contracts' % |
||||
|
len(contracts)) |
||||
|
for contract in contracts: |
||||
|
payment_mode = contract.partner_id.customer_payment_mode_id |
||||
|
if payment_mode: |
||||
|
contract.payment_mode_id = payment_mode.id |
||||
|
_logger.info('Setting payment mode: Done') |
@ -0,0 +1,30 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
# Marc Tormo i Bochaca <mtbochaca@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: Marc Tormo i Bochaca <mtbochaca@gmail.com>, 2017\n" |
||||
|
"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: ca\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Compte analític" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Forma de pagament " |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: de\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Kostenstelle" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Zahlweise" |
@ -0,0 +1,28 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: contract (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-11-07 03:42+0000\n" |
||||
|
"PO-Revision-Date: 2015-11-07 12:33+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: Greek (Greece) (http://www.transifex.com/oca/OCA-contract-8-0/language/el_GR/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: el_GR\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Αναλυτικός Λογαριασμός" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: field:account.analytic.account,payment_mode_id:0 |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\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" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Cuenta analítica" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Modo de pago" |
@ -0,0 +1,28 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: contract (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-12-03 01:11+0000\n" |
||||
|
"PO-Revision-Date: 2015-11-07 12:33+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: Spanish (Mexico) (http://www.transifex.com/oca/OCA-contract-8-0/language/es_MX/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: es_MX\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Cuenta analítica" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: field:account.analytic.account,payment_mode_id:0 |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Finnish (https://www.transifex.com/oca/teams/23907/fi/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: fi\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analyyttinen tili" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Maksutapa" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: fr\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Compte analytique" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Mode de paiement" |
@ -0,0 +1,30 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# César Castro Cruz <ulmroan@gmail.com>, 2017 |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Galician (https://www.transifex.com/oca/teams/23907/gl/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: gl\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Conta analítica" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Modo de pagamento" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# Ashish Deshmukh <ashish.p.deshmukh@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-08-17 01:05+0000\n" |
||||
|
"PO-Revision-Date: 2017-08-17 01:05+0000\n" |
||||
|
"Last-Translator: Ashish Deshmukh <ashish.p.deshmukh@gmail.com>, 2017\n" |
||||
|
"Language-Team: Hindi (India) (https://www.transifex.com/oca/teams/23907/hi_IN/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: hi_IN\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "विश्लेषणात्मक खाता" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "भुगतान का प्रकार" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# Bole <bole@dajmi5.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: Bole <bole@dajmi5.com>, 2017\n" |
||||
|
"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: hr\n" |
||||
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analitički konto" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,30 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
# Bole <bole@dajmi5.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-06-17 01:39+0000\n" |
||||
|
"PO-Revision-Date: 2017-06-17 01:39+0000\n" |
||||
|
"Last-Translator: Bole <bole@dajmi5.com>, 2017\n" |
||||
|
"Language-Team: Croatian (Croatia) (https://www.transifex.com/oca/teams/23907/hr_HR/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: hr_HR\n" |
||||
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Konto analitike" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Način plaćanja" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Hungarian (https://www.transifex.com/oca/teams/23907/hu/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: hu\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analitikus gyűjtőkód könyvelés" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,30 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# Nicola Malcontenti <nicola.malcontenti@gmail.com>, 2017 |
||||
|
# Stefano <stefano.sforzi@agilebg.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: Stefano <stefano.sforzi@agilebg.com>, 2017\n" |
||||
|
"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: it\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Conto Analitico" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Modo di pagamento" |
@ -0,0 +1,30 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
# Erwin van der Ploeg <erwin@odooexperts.nl>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: Erwin van der Ploeg <erwin@odooexperts.nl>, 2017\n" |
||||
|
"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: nl\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Kostenplaats" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Betaalmode" |
@ -0,0 +1,30 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
# Pedro Castro Silva <pedrocs@sossia.pt>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-07-15 01:24+0000\n" |
||||
|
"PO-Revision-Date: 2017-07-15 01:24+0000\n" |
||||
|
"Last-Translator: Pedro Castro Silva <pedrocs@sossia.pt>, 2017\n" |
||||
|
"Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: pt\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Conta Analítica" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Modo de Pagamento" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/teams/23907/pt_BR/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: pt_BR\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Conta Analítica" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Modo de pagamento" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# Daniel Reis <dreis.pt@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: Daniel Reis <dreis.pt@gmail.com>, 2017\n" |
||||
|
"Language-Team: Portuguese (Portugal) (https://www.transifex.com/oca/teams/23907/pt_PT/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: pt_PT\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Conta Analítica" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Romanian (https://www.transifex.com/oca/teams/23907/ro/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: ro\n" |
||||
|
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Cont analitic" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,28 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: contract (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-05-21 10:53+0000\n" |
||||
|
"PO-Revision-Date: 2015-11-07 12:33+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: Slovak (Slovakia) (http://www.transifex.com/oca/OCA-contract-8-0/language/sk_SK/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: sk_SK\n" |
||||
|
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analytický účet" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: field:account.analytic.account,payment_mode_id:0 |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# OCA Transbot <transbot@odoo-community.org>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
||||
|
"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: sl\n" |
||||
|
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analitični konto" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "Način plačila" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# Ediz Duman <neps1192@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-06-13 02:40+0000\n" |
||||
|
"PO-Revision-Date: 2017-06-13 02:40+0000\n" |
||||
|
"Last-Translator: Ediz Duman <neps1192@gmail.com>, 2017\n" |
||||
|
"Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: tr\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analitik Hesap" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# Ediz Duman <neps1192@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-06-13 02:40+0000\n" |
||||
|
"PO-Revision-Date: 2017-06-13 02:40+0000\n" |
||||
|
"Last-Translator: Ediz Duman <neps1192@gmail.com>, 2017\n" |
||||
|
"Language-Team: Turkish (Turkey) (https://www.transifex.com/oca/teams/23907/tr_TR/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: tr_TR\n" |
||||
|
"Plural-Forms: nplurals=1; plural=0;\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "Analitik Hesap" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "" |
@ -0,0 +1,29 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * contract_payment_mode |
||||
|
# |
||||
|
# Translators: |
||||
|
# ITGeeker <alanljj@qq.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 9.0c\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-04-01 02:46+0000\n" |
||||
|
"PO-Revision-Date: 2017-04-01 02:46+0000\n" |
||||
|
"Last-Translator: ITGeeker <alanljj@qq.com>, 2017\n" |
||||
|
"Language-Team: Chinese (China) (https://www.transifex.com/oca/teams/23907/zh_CN/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: zh_CN\n" |
||||
|
"Plural-Forms: nplurals=1; plural=0;\n" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model,name:contract_payment_mode.model_account_analytic_account |
||||
|
msgid "Analytic Account" |
||||
|
msgstr "核算科目" |
||||
|
|
||||
|
#. module: contract_payment_mode |
||||
|
#: model:ir.model.fields,field_description:contract_payment_mode.field_account_analytic_account_payment_mode_id |
||||
|
msgid "Payment Mode" |
||||
|
msgstr "支付方式" |
@ -0,0 +1,2 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
from . import contract |
@ -0,0 +1,27 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AccountAnalyticAccount(models.Model): |
||||
|
_inherit = 'account.analytic.account' |
||||
|
|
||||
|
payment_mode_id = fields.Many2one( |
||||
|
comodel_name='account.payment.mode', |
||||
|
string='Payment Mode', |
||||
|
domain=[('payment_type', '=', 'inbound')], |
||||
|
) |
||||
|
|
||||
|
@api.onchange('partner_id') |
||||
|
def on_change_partner_id(self): |
||||
|
if self.partner_id.customer_payment_mode_id: |
||||
|
self.payment_mode_id = self.partner_id.customer_payment_mode_id.id |
||||
|
|
||||
|
@api.multi |
||||
|
def _prepare_invoice(self): |
||||
|
invoice_vals = super(AccountAnalyticAccount, self)._prepare_invoice() |
||||
|
if self.payment_mode_id: |
||||
|
invoice_vals['payment_mode_id'] = self.payment_mode_id.id |
||||
|
invoice = self.env['account.invoice'].new(invoice_vals) |
||||
|
invoice.payment_mode_id_change() |
||||
|
invoice_vals = invoice._convert_to_write(invoice._cache) |
||||
|
return invoice_vals |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2016 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import test_contract_payment |
@ -0,0 +1,90 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# Copyright 2017 Tecnativa - Vicent Cubells |
||||
|
# Copyright 2017 Tecnativa - David Vidal |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo.tests import common |
||||
|
from ..hooks import post_init_hook |
||||
|
|
||||
|
|
||||
|
class TestContractPaymentInit(common.SavepointCase): |
||||
|
@classmethod |
||||
|
def setUpClass(cls): |
||||
|
super(TestContractPaymentInit, cls).setUpClass() |
||||
|
|
||||
|
cls.payment_method = cls.env['account.payment.method'].create({ |
||||
|
'name': 'Test Payment Method', |
||||
|
'code': 'Test', |
||||
|
'payment_type': 'inbound', |
||||
|
}) |
||||
|
cls.payment_mode = cls.env['account.payment.mode'].create({ |
||||
|
'name': 'Test payment mode', |
||||
|
'active': True, |
||||
|
'payment_method_id': cls.payment_method.id, |
||||
|
'bank_account_link': 'variable', |
||||
|
}) |
||||
|
cls.partner = cls.env['res.partner'].create({ |
||||
|
'name': 'Test contract partner', |
||||
|
'customer_payment_mode_id': cls.payment_mode, |
||||
|
}) |
||||
|
cls.product = cls.env['product.product'].create({ |
||||
|
'name': 'Custom Service', |
||||
|
'type': 'service', |
||||
|
'uom_id': cls.env.ref('product.product_uom_hour').id, |
||||
|
'uom_po_id': cls.env.ref('product.product_uom_hour').id, |
||||
|
'sale_ok': True, |
||||
|
}) |
||||
|
cls.contract = cls.env['account.analytic.account'].create({ |
||||
|
'name': 'Maintenance of Servers', |
||||
|
}) |
||||
|
company = cls.env.ref('base.main_company') |
||||
|
cls.journal = cls.env['account.journal'].create({ |
||||
|
'name': 'Sale Journal - Test', |
||||
|
'code': 'HRTSJ', |
||||
|
'type': 'sale', |
||||
|
'company_id': company.id}) |
||||
|
|
||||
|
def test_post_init_hook(self): |
||||
|
contract = self.env['account.analytic.account'].create({ |
||||
|
'name': 'Test contract', |
||||
|
'partner_id': self.partner.id, |
||||
|
'payment_mode_id': self.payment_mode.id, |
||||
|
}) |
||||
|
self.assertEqual(contract.payment_mode_id, |
||||
|
self.payment_mode) |
||||
|
|
||||
|
contract.payment_mode_id = False |
||||
|
self.assertEqual(contract.payment_mode_id.id, False) |
||||
|
|
||||
|
post_init_hook(self.cr, self.env) |
||||
|
self.assertEqual(contract.payment_mode_id, |
||||
|
self.payment_mode) |
||||
|
|
||||
|
def test_contract_and_invoices(self): |
||||
|
self.contract.write({'partner_id': self.partner.id}) |
||||
|
self.contract.on_change_partner_id() |
||||
|
self.assertEqual(self.contract.payment_mode_id, |
||||
|
self.contract.partner_id.customer_payment_mode_id) |
||||
|
self.contract.write({ |
||||
|
'recurring_invoices': True, |
||||
|
'recurring_interval': 1, |
||||
|
'recurring_invoice_line_ids': [(0, 0, { |
||||
|
'quantity': 2.0, |
||||
|
'price_unit': 200.0, |
||||
|
'name': 'Database Administration 25', |
||||
|
'product_id': self.product.id, |
||||
|
'uom_id': self.product.uom_id.id, |
||||
|
})] |
||||
|
}) |
||||
|
self.contract.recurring_create_invoice() |
||||
|
new_invoice = self.env['account.invoice'].search([ |
||||
|
('contract_id', '=', self.contract.id) |
||||
|
]) |
||||
|
self.assertEqual(new_invoice.partner_id, self.contract.partner_id) |
||||
|
self.assertEqual(new_invoice.payment_mode_id, |
||||
|
self.contract.payment_mode_id) |
||||
|
self.assertEqual(len(new_invoice.ids), 1) |
||||
|
self.contract.recurring_create_invoice() |
||||
|
self.assertEqual(self.contract.payment_mode_id, |
||||
|
new_invoice.payment_mode_id) |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue