Browse Source
[10.0][ADD] Add website_portal_contract (#62)
[10.0][ADD] Add website_portal_contract (#62)
* [ADD] Add website_portal_contract * [ADD] website_portal_contract: Add url test, usage video. * [FIX] website_portal_contract: Fix controller test. * [FIX] website_portal_contract: Change all tests to HttpCase.pull/105/head
Brett Wood
7 years ago
committed by
Dave Lasley
26 changed files with 1155 additions and 0 deletions
-
71website_portal_contract/README.rst
-
6website_portal_contract/__init__.py
-
34website_portal_contract/__manifest__.py
-
5website_portal_contract/controllers/__init__.py
-
74website_portal_contract/controllers/main.py
-
115website_portal_contract/data/website_contract_template_data.xml
-
20website_portal_contract/demo/account_analytic_account_demo.xml
-
14website_portal_contract/demo/account_analytic_contract_demo.xml
-
15website_portal_contract/demo/account_analytic_invoice_line_demo.xml
-
14website_portal_contract/demo/assets_demo.xml
-
7website_portal_contract/models/__init__.py
-
31website_portal_contract/models/account_analytic_account.py
-
24website_portal_contract/models/account_analytic_contract.py
-
40website_portal_contract/models/account_analytic_contract_template.py
-
8website_portal_contract/security/ir.model.access.csv
-
BINwebsite_portal_contract/static/description/icon.png
-
37website_portal_contract/static/src/js/tour_test_contract.js
-
8website_portal_contract/tests/__init__.py
-
32website_portal_contract/tests/test_account_analytic_account.py
-
22website_portal_contract/tests/test_account_analytic_contract.py
-
21website_portal_contract/tests/test_account_analytic_contract_template.py
-
37website_portal_contract/tests/test_controller.py
-
18website_portal_contract/views/account_analytic_account_view.xml
-
64website_portal_contract/views/account_analytic_contract_template_view.xml
-
18website_portal_contract/views/account_analytic_contract_view.xml
-
420website_portal_contract/views/website_portal_contract_templates.xml
@ -0,0 +1,71 @@ |
|||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
|||
:alt: License: AGPL-3 |
|||
|
|||
======================= |
|||
Website Portal Contract |
|||
======================= |
|||
|
|||
Extension of contract and website_portal that allows contracts to |
|||
be shown in website portal. Each contract now has a website template tied to it. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
`Usage Video <https://youtu.be/PSulRVdh4C4>`_ |
|||
|
|||
To edit the website template, go to: |
|||
|
|||
* `Invoicing` in the top navigation. |
|||
* `Contracts` => `Website Templates`. |
|||
* When viewing a template in form view, click `View Template`. |
|||
This will direct you to an edit page of the template in website if |
|||
your user has edit permissions. |
|||
|
|||
To view the live template in `My Account` in website, assign the template |
|||
to a contract and go to: |
|||
|
|||
* `Website` |
|||
* Click on your username then select `My Account` in the dropdown. |
|||
* Click `Your Contracts`, then the relevant contract. Your template will show under |
|||
the `Contract` section header, which is also shown in the edit template view for reference. |
|||
|
|||
.. 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 |
|||
====================== |
|||
|
|||
* Add token access to controller |
|||
* Add functionality to print contracts in website portal |
|||
|
|||
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 |
|||
------------ |
|||
|
|||
* Brett Wood <bwood@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. |
@ -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 models |
|||
from . import controllers |
@ -0,0 +1,34 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 LasLabs Inc. |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
{ |
|||
"name": "Website Portal Contract", |
|||
"summary": "Extends website portal with contracts.", |
|||
"version": "10.0.1.0.0", |
|||
"category": "Contract Management", |
|||
"website": "https://laslabs.com", |
|||
"author": "LasLabs, Odoo Community Association (OCA)", |
|||
"license": "AGPL-3", |
|||
"application": False, |
|||
"installable": True, |
|||
"depends": [ |
|||
"contract", |
|||
"contract_show_invoice", |
|||
"website_quote", |
|||
], |
|||
"data": [ |
|||
"security/ir.model.access.csv", |
|||
"data/website_contract_template_data.xml", |
|||
"views/account_analytic_account_view.xml", |
|||
"views/account_analytic_contract_template_view.xml", |
|||
"views/account_analytic_contract_view.xml", |
|||
"views/website_portal_contract_templates.xml", |
|||
], |
|||
"demo": [ |
|||
"demo/account_analytic_invoice_line_demo.xml", |
|||
"demo/account_analytic_contract_demo.xml", |
|||
"demo/account_analytic_account_demo.xml", |
|||
"demo/assets_demo.xml", |
|||
], |
|||
} |
@ -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 main |
@ -0,0 +1,74 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2017 LasLabs Inc. |
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
|||
|
|||
from odoo import http |
|||
from odoo.http import request |
|||
|
|||
from odoo.addons.website_portal_sale.controllers.main import website_account |
|||
|
|||
|
|||
class WebsiteAccount(website_account): |
|||
|
|||
@http.route() |
|||
def account(self, **kw): |
|||
response = super(WebsiteAccount, self).account(**kw) |
|||
contracts = request.env['account.analytic.account']._search_contracts() |
|||
response.qcontext.update({ |
|||
'contract_count': len(contracts), |
|||
}) |
|||
return response |
|||
|
|||
|
|||
class WebsiteContract(http.Controller): |
|||
|
|||
@http.route( |
|||
['/my/contracts'], |
|||
type='http', |
|||
auth='user', |
|||
website=True, |
|||
) |
|||
def portal_my_contracts(self): |
|||
account_mod = request.env['account.analytic.account'] |
|||
values = { |
|||
'user': request.env.user, |
|||
'contracts': account_mod._search_contracts(), |
|||
} |
|||
return request.render( |
|||
'website_portal_contract.portal_my_contracts', |
|||
values, |
|||
) |
|||
|
|||
@http.route( |
|||
['/contract/<model("account.analytic.account"):contract>'], |
|||
type='http', |
|||
auth='user', |
|||
website=True |
|||
) |
|||
def portal_contract(self, contract): |
|||
action = request.env.ref( |
|||
'contract.action_account_analytic_overdue_all' |
|||
) |
|||
values = { |
|||
'user': request.env.user, |
|||
'contract': contract, |
|||
'action': action.id, |
|||
} |
|||
return request.render( |
|||
'website_portal_contract.website_contract', |
|||
values, |
|||
) |
|||
|
|||
@http.route( |
|||
["/contract/template/" |
|||
"<model('account.analytic.contract.template'):contract>"], |
|||
type='http', |
|||
auth='user', |
|||
website=True, |
|||
) |
|||
def template_view(self, contract, **kwargs): |
|||
values = {'template': contract} |
|||
return request.render( |
|||
'website_portal_contract.website_contract_template', |
|||
values, |
|||
) |
@ -0,0 +1,115 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo noupdate="1"> |
|||
|
|||
<record id="website_contract_template_default" model="account.analytic.contract.template"> |
|||
<field name="name">Default Template</field> |
|||
<field name="website_description" type="xml"> |
|||
<section data-snippet-id="text-block"> |
|||
<section> |
|||
<h1 class="page-header">Contract</h1> |
|||
<p class="bg-danger">Disclaimer: This demo contract is not to be used for real business purposes.</p> |
|||
<p> |
|||
This Agreement is made to the start date of Date, between Client, having its principal place of Client Address |
|||
and Company, having its principal place of Company Address. |
|||
In consideration of Client retaining Company to perform support services for Client, it is agreed as follows: |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Compensation and Term</h3> |
|||
<p> |
|||
Client hereby retains Company and Company hereby agrees to perform the following services: Consulting services of Company |
|||
as required by Client,through December 31, 20--. Company will at various times perform services at Client's headquarters, |
|||
at other Client facilities, or at Company facilities, as directed by Client. Company will perform the services at various |
|||
times and for various durations as directed by Client. |
|||
</p> |
|||
<h4>The following fees shall apply:</h4> |
|||
<p> |
|||
<strong>..........$X per hour for services.</strong> |
|||
</p> |
|||
<p> |
|||
Reasonable and necessary business and travel expenses actually incurred by Company shall be reimbursed by Client upon submission |
|||
of expense reports with back-up documentation. All such expenses and all travel plans must be approved in advance by Client. |
|||
Company shall provide detailed invoices and shall maintain, and provide, upon request, backup documentation for a period of |
|||
one year from the date of the respective invoices. Client shall make full payment for services within thirty days of invoice. |
|||
If Company brings a legal action to collect any sums due under this Agreement, it shall be entitled to collect, in addition |
|||
to all damages, its costs of collection, including reasonable attorney's fees. This Agreement shall commence on the date stated |
|||
above, and shall remain in effect until all obligations under this Agreement have been properly completed. Either party to this |
|||
Agreement may terminate this Agreement with or without cause by providing at least 21 days written notice to the other party. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h5>Warranties by Company</h5> |
|||
<p> |
|||
Company represents and warrants to Client that it has the experience and ability to perform the services required by this |
|||
Agreement; that it will perform said services in a professional, competent and timely manner; that it has the power to enter into |
|||
and perform this Agreement; and that its performance of this Agreement shall not infringe upon or violate the rights of any third |
|||
party or violate any federal, provincial and municipal laws. Client shall provide requisite training for additional products or services |
|||
required by this Agreement which are not within Company's area of expertise. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Independent Contractor</h3> |
|||
<p> |
|||
Company acknowledges that the services rendered under this Agreement shall be solely as an independent contractor. |
|||
Company shall not enter into any contract or commitment on behalf of Client. Company further acknowledges that it is |
|||
not considered an affiliate or subsidiary of Client, and is not entitled to any Client employment rights or benefits. It is |
|||
expressly understood that this undertaking is not a joint venture. |
|||
</p> |
|||
<p> |
|||
Company recognizes and acknowledges that this Agreement creates a confidential relationship between Company and Client |
|||
and that information concerning Client's business affairs, customers, vendors, finances, properties, methods of operation, computer |
|||
programs, and documentation, and other such information, whether written, oral, or otherwise, is confidential in nature. All such |
|||
information concerning Client is hereinafter collectively referred to as "Confidential Information." Company agrees to follow |
|||
Client Information Security procedures and otherwise take all reasonable precautions for the protection of Confidential Information. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Non-Disclosure</h3> |
|||
<p> |
|||
Company agrees that, except as directed by Client, it will not at any time during or after the term of this Agreement disclose |
|||
any Confidential Information to any person whatsoever and that upon the termination of this Agreement it will turn over to Client |
|||
all documents, papers, and other matter in its possession or control that relate to Client. Company further agrees to bind its |
|||
employees and subcontractors to the terms and conditions of this Agreement. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Grant</h3> |
|||
<p> |
|||
Company agrees that its work product produced in the performance of this Agreement shall remain the exclusive property of Client, and |
|||
that it will not sell, transfer, publish, disclose or otherwise make the work product available to third parties without Client's prior |
|||
written consent. Any rights granted to Company under this Agreement shall not affect Client's exclusive ownership of the work product. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Office Rules</h3> |
|||
<p> |
|||
Company shall comply with all office rules and regulations, including security requirements, when on Client premises. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Conflict of Interest</h3> |
|||
<p> |
|||
Company shall not offer or give a gratuity of any type to any Client employee or agent. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Governing Law</h3> |
|||
<p> |
|||
This Agreement shall be construed and enforced in accordance with the laws of Governing Authority. |
|||
</p> |
|||
</section> |
|||
<section> |
|||
<h3>Entire Agreement and Notice</h3> |
|||
<p> |
|||
This Agreement contains the entire understanding of the parties and may not be amended without the specific written consent of both parties. |
|||
Any notice given under this Agreement shall be sufficient if it is in writing and if sent by certified or registered mail. |
|||
</p> |
|||
</section> |
|||
</section> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,20 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="account_analytic_account_1" model="account.analytic.account"> |
|||
<field name="name">Demo Contract</field> |
|||
<field name="contract_template_id" ref="account_analytic_contract_1" /> |
|||
<field name="pricelist_id" ref="product.list0" /> |
|||
<field name="date_start" eval="time.strftime('%Y-%m-10')" /> |
|||
<field name="recurring_next_date" eval="time.strftime('%Y-%m-20')" /> |
|||
<field name="partner_id" ref="portal.demo_user0_res_partner" /> |
|||
<field name="recurring_invoices" eval="True" /> |
|||
<field name="website_template_id" ref="website_contract_template_default" /> |
|||
<field name="recurring_invoice_line_ids" |
|||
eval="[(6, 0, [ref('account_analytic_invoice_line_1')])]" /> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,14 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="account_analytic_contract_1" model="account.analytic.contract"> |
|||
<field name="name">Demo Contract Template</field> |
|||
<field name="recurring_invoicing_type">post-paid</field> |
|||
<field name="recurring_interval">10</field> |
|||
<field name="recurring_rule_type">daily</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="account_analytic_invoice_line_1" model="account.analytic.invoice.line"> |
|||
<field name="name">iPad Retina Display</field> |
|||
<field name="product_id" ref="product.product_product_4" /> |
|||
<field name="quantity">10</field> |
|||
<field name="uom_id" ref="product.product_uom_unit" /> |
|||
<field name="price_unit">25</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,14 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<template id="assets_frontend_demo" inherit_id="website.assets_frontend"> |
|||
<xpath expr="."> |
|||
<script type="text/javascript" |
|||
src="/website_portal_contract/static/src/js/tour_test_contract.js" /> |
|||
</xpath> |
|||
</template> |
|||
|
|||
</odoo> |
@ -0,0 +1,7 @@ |
|||
# -*- 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_template |
|||
from . import account_analytic_contract |
@ -0,0 +1,31 @@ |
|||
# -*- 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 |
|||
|
|||
|
|||
class AccountAnalyticAccount(models.Model): |
|||
|
|||
_inherit = 'account.analytic.account' |
|||
|
|||
website_template_id = fields.Many2one( |
|||
string='Website Template', |
|||
comodel_name='account.analytic.contract.template', |
|||
help='Website layout for contract', |
|||
) |
|||
account_invoice_ids = fields.Many2many( |
|||
string='Invoices', |
|||
comodel_name='account.invoice', |
|||
) |
|||
|
|||
@api.model |
|||
def _search_contracts(self, domain=None): |
|||
partner = self.env.user.partner_id |
|||
contract_mod = self.env['account.analytic.account'] |
|||
if not domain: |
|||
domain = [ |
|||
('partner_id', 'child_of', [partner.commercial_partner_id.id]), |
|||
('recurring_invoices', '=', True), |
|||
] |
|||
return contract_mod.search(domain) |
@ -0,0 +1,24 @@ |
|||
# -*- 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 |
|||
|
|||
|
|||
class AccountAnalyticContract(models.Model): |
|||
|
|||
_inherit = 'account.analytic.contract' |
|||
|
|||
website_template_id = fields.Many2one( |
|||
string='Website Template', |
|||
comodel_name='account.analytic.contract.template', |
|||
help='Website layout for contract', |
|||
default=lambda s: s._get_default_template(), |
|||
) |
|||
|
|||
@api.model |
|||
def _get_default_template(self): |
|||
return self.env.ref( |
|||
'website_portal_contract.website_contract_template_default', |
|||
raise_if_not_found=False, |
|||
) |
@ -0,0 +1,40 @@ |
|||
# -*- 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 |
|||
from odoo.tools.translate import html_translate |
|||
|
|||
|
|||
class AccountAnalyticContractTemplate(models.Model): |
|||
|
|||
_name = 'account.analytic.contract.template' |
|||
_description = 'Contract Website Templates' |
|||
|
|||
name = fields.Char( |
|||
help='Template name', |
|||
) |
|||
website_description = fields.Html( |
|||
string='Description', |
|||
translate=html_translate, |
|||
sanitize_attributes=False, |
|||
) |
|||
analytic_account_id = fields.One2many( |
|||
string='Analytic Account', |
|||
comodel_name='account.analytic.account', |
|||
inverse_name='website_template_id', |
|||
) |
|||
analytic_contract_id = fields.One2many( |
|||
string='Contract Template', |
|||
comodel_name='account.analytic.account', |
|||
inverse_name='website_template_id', |
|||
) |
|||
|
|||
@api.multi |
|||
def open_template(self): |
|||
self.ensure_one() |
|||
return { |
|||
'type': 'ir.actions.act_url', |
|||
'target': 'self', |
|||
'url': '/contract/template/%d' % self.id |
|||
} |
@ -0,0 +1,8 @@ |
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|||
account_analytic_contract_template_manager,account.analytic.contract.template.manager,model_account_analytic_contract_template,account.group_account_manager,1,1,1,1 |
|||
account_analytic_contract_template_user,account.analytic.contract.template.user,model_account_analytic_contract_template,account.group_account_user,1,0,0,0 |
|||
account_analytic_account_portal,account.analytic.account.portal,analytic.model_account_analytic_account,base.group_portal,1,1,0,0 |
|||
account_analytic_invoice_line_portal,account.analytic.invoice.line.portal,contract.model_account_analytic_invoice_line,base.group_portal,1,1,0,0 |
|||
account_analytic_contract_portal,account.analytic.contract.portal,contract.model_account_analytic_contract,base.group_portal,1,0,0,0 |
|||
account_analytic_contract_template_portal,account.analytic.contract.template.portal,model_account_analytic_contract_template,base.group_portal,1,0,0,0 |
|||
account_analytic_line_portal,account.analytic.line.portal,sale.model_account_analytic_line,base.group_portal,1,0,0,0 |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,37 @@ |
|||
/* Copyright 2017 Laslabs Inc. |
|||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
|||
|
|||
odoo.define('website_portal_contract.tour_test_contract', function(require) { |
|||
'use strict'; |
|||
|
|||
var base = require('web_editor.base'); |
|||
var _t = require('web.core')._t; |
|||
var tour = require('web_tour.tour'); |
|||
|
|||
tour.register( |
|||
'test_contract_view', |
|||
{ |
|||
test: true, |
|||
url: '/my/home', |
|||
name: 'Test website portal contract view', |
|||
wait_for: base.ready() |
|||
}, |
|||
[ |
|||
{ |
|||
content: _t('Click on Your Contracts'), |
|||
trigger: "a:contains('Your Contracts')" |
|||
}, |
|||
{ |
|||
content: _t('Click on Demo Project'), |
|||
trigger: "a:contains('Demo Contract - Demo Portal User')" |
|||
}, |
|||
{ |
|||
content: _t('Click History'), |
|||
trigger: "a:contains('History')" |
|||
} |
|||
] |
|||
); |
|||
|
|||
return {}; |
|||
|
|||
}); |
@ -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 test_account_analytic_account |
|||
from . import test_account_analytic_contract_template |
|||
from . import test_account_analytic_contract |
|||
from . import test_controller |
@ -0,0 +1,32 @@ |
|||
# -*- 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 HttpCase |
|||
|
|||
|
|||
class TestAccountAnalyticAccount(HttpCase): |
|||
|
|||
def setUp(self): |
|||
super(TestAccountAnalyticAccount, self).setUp() |
|||
self.account = self.env.ref( |
|||
'website_portal_contract.account_analytic_account_1' |
|||
) |
|||
self.contract = self.env.ref( |
|||
'website_portal_contract.account_analytic_contract_1' |
|||
) |
|||
|
|||
def test_website_template_id(self): |
|||
""" Test website_template_id inherited from contract """ |
|||
self.assertEquals( |
|||
self.account.website_template_id, |
|||
self.contract.website_template_id, |
|||
) |
|||
|
|||
def test_search_contracts(self): |
|||
""" Test returns correct contracts """ |
|||
self.account.partner_id = self.env.ref('base.partner_root') |
|||
self.assertIn( |
|||
self.account, |
|||
self.env['account.analytic.account']._search_contracts(), |
|||
) |
@ -0,0 +1,22 @@ |
|||
# -*- 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 HttpCase |
|||
|
|||
|
|||
class TestAccountAnalyticContract(HttpCase): |
|||
|
|||
def setUp(self): |
|||
super(TestAccountAnalyticContract, self).setUp() |
|||
self.contract_mod = self.env['account.analytic.contract'] |
|||
self.template = self.env.ref( |
|||
'website_portal_contract.website_contract_template_default' |
|||
) |
|||
|
|||
def test_get_default_template(self): |
|||
""" Test get_default_template returns correct template """ |
|||
self.assertEquals( |
|||
self.contract_mod._get_default_template(), |
|||
self.template, |
|||
) |
@ -0,0 +1,21 @@ |
|||
# -*- 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 HttpCase |
|||
|
|||
|
|||
class TestAccountAnalyticContractTemplate(HttpCase): |
|||
|
|||
def setUp(self): |
|||
super(TestAccountAnalyticContractTemplate, self).setUp() |
|||
self.template = self.env.ref( |
|||
'website_portal_contract.website_contract_template_default' |
|||
) |
|||
|
|||
def test_open_template(self): |
|||
""" Test open_template returns correct url """ |
|||
self.assertEquals( |
|||
self.template.open_template()['url'], |
|||
'/contract/template/%d' % self.template.id, |
|||
) |
@ -0,0 +1,37 @@ |
|||
# -*- 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 HttpCase |
|||
from odoo.addons.website.models.website import slug |
|||
|
|||
|
|||
class TestController(HttpCase): |
|||
|
|||
post_install = True |
|||
at_install = False |
|||
|
|||
def test_template_view(self): |
|||
""" It should respond with 200 status """ |
|||
contract = self.env.ref( |
|||
'website_portal_contract.' |
|||
'website_contract_template_default' |
|||
) |
|||
self.authenticate('admin', 'admin') |
|||
response = self.url_open( |
|||
'/contract/template/%s' % slug(contract) |
|||
) |
|||
self.assertEquals( |
|||
response.getcode(), |
|||
200, |
|||
) |
|||
|
|||
def test_portal_contract_view_tour(self): |
|||
""" Tests contract view is correct """ |
|||
tour = "odoo.__DEBUG__.services['web_tour.tour']" |
|||
self.phantom_js( |
|||
url_path='/my/home', |
|||
code="%s.run('test_contract_view')" % tour, |
|||
ready="%s.tours.test_contract_view.ready" % tour, |
|||
login='portal', |
|||
) |
@ -0,0 +1,18 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="account_analytic_account_recurring_form_form" model="ir.ui.view"> |
|||
<field name="name">account.analytic.account.invoice.recurring.form.inherit</field> |
|||
<field name="model">account.analytic.account</field> |
|||
<field name="inherit_id" ref="contract.account_analytic_account_recurring_form_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='date_start']" position="after"> |
|||
<field name="website_template_id" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,64 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="account_analytic_contract_template_view_form" model="ir.ui.view"> |
|||
<field name="name">account.analytic.contract.template.form</field> |
|||
<field name="model">account.analytic.contract.template</field> |
|||
<field name="arch" type="xml"> |
|||
<form string="Website Template"> |
|||
<sheet> |
|||
<button string="View Template" type="object" name="open_template" class="oe_highlight oe_right" /> |
|||
<div class="oe_title"> |
|||
<label for="name" class="oe_edit_only" /> |
|||
<h1> |
|||
<field name="name" placeholder="Contract Website Template" /> |
|||
</h1> |
|||
</div> |
|||
</sheet> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="account_analytic_contract_template_view_tree" model="ir.ui.view"> |
|||
<field name="name">account.analytic.contract.template.tree</field> |
|||
<field name="model">account.analytic.contract.template</field> |
|||
<field name="arch" type="xml"> |
|||
<tree string="Website Templates"> |
|||
<field name="name" /> |
|||
</tree> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="account_analytic_contract_template_view_search" model="ir.ui.view"> |
|||
<field name="name">account.analytic.contract.template.search</field> |
|||
<field name="model">account.analytic.contract.template</field> |
|||
<field name="arch" type="xml"> |
|||
<search string="Website Templates"> |
|||
<field name="name" /> |
|||
</search> |
|||
</field> |
|||
</record> |
|||
|
|||
<record id="account_analytic_contract_template_action" model="ir.actions.act_window"> |
|||
<field name="name">Website Templates</field> |
|||
<field name="res_model">account.analytic.contract.template</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="help" type="html"> |
|||
<p class="oe_view_nocontent_create"> |
|||
Click to create a new contract template. |
|||
</p> |
|||
</field> |
|||
</record> |
|||
|
|||
<menuitem id="account_analytic_contract_template_menu" |
|||
parent="contract.menu_config_contract" |
|||
action="account_analytic_contract_template_action" |
|||
sequence="1" |
|||
name="Website Templates" |
|||
/> |
|||
|
|||
</odoo> |
@ -0,0 +1,18 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<record id="account_analytic_contract_view_form" model="ir.ui.view"> |
|||
<field name="name">Account Analytic Contract Form View</field> |
|||
<field name="model">account.analytic.contract</field> |
|||
<field name="inherit_id" ref="contract.account_analytic_contract_view_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='pricelist_id']" position="after"> |
|||
<field name="website_template_id" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</odoo> |
@ -0,0 +1,420 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- Copyright 2017 LasLabs Inc. |
|||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
|||
|
|||
<odoo> |
|||
|
|||
<template id="portal_my_home_menu_contracts" name="Portal Home Contracts" inherit_id="website_portal.portal_layout" priority="25"> |
|||
<xpath expr="//ul[contains(@class,'o_portal_submenu')]" position="inside"> |
|||
<li> |
|||
<a href="/my/contracts">Contracts</a> |
|||
</li> |
|||
</xpath> |
|||
</template> |
|||
|
|||
<template id="portal_my_home_contracts" name="portal.my.home.contracts" inherit_id="website_portal.portal_my_home" priority="25"> |
|||
<xpath expr="//div[contains(@class,'o_my_home_content')]" position="inside"> |
|||
<h3 class="page-header"> |
|||
<a href="/my/contracts">Your Contracts |
|||
<small class="ml8"> |
|||
<t t-if="contract_count"> |
|||
<span class='badge'><t t-esc="contract_count" /></span> |
|||
</t> |
|||
<t t-if="not contract_count"> |
|||
There are currently no contracts for your account. |
|||
</t> |
|||
</small> |
|||
</a> |
|||
</h3> |
|||
</xpath> |
|||
</template> |
|||
|
|||
<template id="portal_my_contracts" name="My Contracts"> |
|||
<t t-call="website_portal.portal_layout"> |
|||
<h3 class="page-header">Your Contracts</h3> |
|||
<t t-if="not contracts"> |
|||
<p>There are currently no contracts for your account.</p> |
|||
</t> |
|||
<t t-if="contracts"> |
|||
<table class="table table-hover o_my_status_table"> |
|||
<thead> |
|||
<tr class="active"> |
|||
<th>Account</th> |
|||
<th>Debit</th> |
|||
<th>Credit</th> |
|||
<th>Balance</th> |
|||
</tr> |
|||
</thead> |
|||
<t t-foreach="contracts" t-as="contract"> |
|||
<tr> |
|||
<td> |
|||
<a t-attf-href="/contract/#{slug(contract)}"><t t-esc="contract.display_name" /></a> |
|||
</td> |
|||
<td> |
|||
<span t-field="contract.debit" /> |
|||
</td> |
|||
<td> |
|||
<span t-field="contract.credit" /> |
|||
</td> |
|||
<td> |
|||
<span t-field="contract.balance" /> |
|||
</td> |
|||
</tr> |
|||
</t> |
|||
</table> |
|||
<div t-if="pager" class="o_portal_pager text-center"> |
|||
<t t-call="website.pager" /> |
|||
</div> |
|||
</t> |
|||
</t> |
|||
</template> |
|||
|
|||
<!-- Complete page of the contract --> |
|||
<template id="website_contract" name="Website Contract"> |
|||
<t t-call="website.layout"> |
|||
<body data-spy="scroll" data-target=".navspy" data-offset="50"> |
|||
<div class="container o_website_quote"> |
|||
<div class="row"> |
|||
<div class="col-sm-4"> |
|||
<ol class="breadcrumb mt8"> |
|||
<li><a href="/my/home"><i class="fa fa-home" /></a></li> |
|||
<li><a t-attf-href="/my/contracts">My Contracts</a></li> |
|||
<li> |
|||
<t t-esc="contract.name" /> |
|||
</li> |
|||
</ol> |
|||
</div> |
|||
</div> |
|||
<div class="row mt16"> |
|||
<!-- Sidebar --> |
|||
<div class="col-md-3 hidden-print"> |
|||
<div class="bs-sidebar"> |
|||
<div class="text-center" style="padding: 10px"> |
|||
<div class="mt8 bs-header"> |
|||
<div> |
|||
<a href="#discussion"> |
|||
Give Feedback |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<hr class="mt0 mb0" /> |
|||
<t t-call="website_portal_contract.contract_navigation_menu" /> |
|||
<hr class="mt0 mb0" /> |
|||
<div class="bs-footer" /> |
|||
</div> |
|||
</div> |
|||
<!-- Page content --> |
|||
<div id="contract_page_content" class="col-md-9"> |
|||
<t t-call="website_portal_contract.contract_content" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</t> |
|||
</template> |
|||
|
|||
<!-- |
|||
This template should contains all the printable element of the Contract. This is the |
|||
template rendered in PDF with the report engine. |
|||
--> |
|||
<template id="contract_content" name="Contract Content"> |
|||
<!-- Intro --> |
|||
<div id="contract_introduction" class="page-header mt16"> |
|||
<h1> |
|||
<em t-esc="contract.name" /> |
|||
<div t-ignore="true" class="pull-right css_editable_mode_hidden hidden-print"> |
|||
<ul class="list-inline"> |
|||
<li groups="sales_team.group_sale_salesman"> |
|||
<a class="btn btn-info" |
|||
id="edit_contract" |
|||
t-att-href="'/web#return_label=Website&model=%s&id=%s&action=%s&view_type=form' % (contract._name, contract.id, action)"> |
|||
Edit |
|||
</a> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
</h1> |
|||
</div> |
|||
<!-- Informations --> |
|||
<div class="row mt32"> |
|||
<div class="col-md-6 col-xs-6"> |
|||
<div class="row"> |
|||
<label class="col-sm-4 col-xs-4 text-right">Customer:</label> |
|||
<div class="col-sm-8 col-xs-8"> |
|||
<div t-field="contract.partner_id" t-options='{ |
|||
"widget": "contact", |
|||
"fields": ["address", "name", "phone"] |
|||
}'/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="col-md-6 col-xs-6"> |
|||
<div class="row"> |
|||
<div> |
|||
<label class="col-sm-5 col-xs-5 text-right">Start Date:</label> |
|||
<div class="col-sm-7 col-xs-7"> |
|||
<span t-field="contract.date_start" /> |
|||
</div> |
|||
</div> |
|||
<div class="clearfix" /> |
|||
<div> |
|||
<label class="col-sm-5 col-xs-5 text-right">Repeat Every:</label> |
|||
<div class="col-sm-7 col-xs-7"> |
|||
<span t-field="contract.recurring_interval" /> |
|||
<span t-field="contract.recurring_rule_type" /> |
|||
<span t-field="contract.recurring_invoicing_type" /> |
|||
</div> |
|||
</div> |
|||
<div class="clearfix" /> |
|||
<div> |
|||
<label class="col-sm-5 col-xs-5 text-right">Next Invoice:</label> |
|||
<div class="col-sm-7 col-xs-7"> |
|||
<span t-field="contract.recurring_next_date" /> |
|||
</div> |
|||
</div> |
|||
<div class="clearfix" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- Recurring Items --> |
|||
<t t-call="website_portal_contract.contract_recurring_items" /> |
|||
<!-- Balance --> |
|||
<t t-call="website_portal_contract.contract_invoices" /> |
|||
<!-- Descriptions --> |
|||
<div t-field="contract.website_template_id.website_description" class="oe_no_empty" /> |
|||
<div class="oe_structure" /> |
|||
</template> |
|||
|
|||
<template id="contract_navigation_menu" name="Navigation Menu"> |
|||
<div class="navspy" t-ignore="true" role="complementary"> |
|||
<ul class="nav bs-sidenav" data-id="quote_sidebar"> |
|||
</ul> |
|||
</div> |
|||
</template> |
|||
|
|||
<template id="contract_chatter" name="Contract Comments" customize_show="True" inherit_id="website_portal_contract.website_contract"> |
|||
<xpath expr="//div[@id='contract_page_content']" position="inside"> |
|||
<section id="discussion" class="hidden-print"> |
|||
<h1 class="page-header">History</h1> |
|||
<t t-call="website_mail.message_thread"> |
|||
<t t-set="object" t-value="contract" /> |
|||
<t t-set="chatter_mode" t-value="'json'" /> |
|||
</t> |
|||
</section> |
|||
</xpath> |
|||
</template> |
|||
|
|||
<!-- Template to edit the contract template with the website editor --> |
|||
<template id="website_contract_template" name="website_contract_template"> |
|||
<t t-call="website.layout"> |
|||
<body data-spy="scroll" data-target=".navspy" data-offset="50"> |
|||
<div class="container o_website_quote"> |
|||
<div class="row mt16"> |
|||
<div class="col-md-3 hidden-print"> |
|||
<div class="bs-sidebar"> |
|||
<hr class="mt0 mb0" /> |
|||
<div class="navspy" role="complementary" t-ignore="True"> |
|||
<ul class="nav bs-sidenav" data-id="quote_sidebar" /> |
|||
</div> |
|||
<hr class="mt0 mb0" /> |
|||
</div> |
|||
</div> |
|||
<div class="col-md-9"> |
|||
<div class="row"> |
|||
<div t-ignore="true" class="css_editable_mode_hidden col-md-offset-11"> |
|||
<a class="btn btn-info hidden-print" |
|||
t-att-href="'/web#return_label=Website&model=%s&id=%s&action=%s&view_type=form' % (template._name, template.id, request.env.ref('website_portal_contract.account_analytic_contract_template_action').id)"> |
|||
Back |
|||
</a> |
|||
</div> |
|||
</div> |
|||
<div class="alert alert-info alert-dismissable" t-ignore="True"> |
|||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> |
|||
<p> |
|||
<strong>Template Header:</strong> this content |
|||
will appear on all contracts using this |
|||
template. |
|||
</p> |
|||
<p class="text-muted"> |
|||
Titles with style <i>Heading 1</i> and |
|||
<i>Heading 2</i> will be used to generate the |
|||
table of content automatically. |
|||
</p> |
|||
</div> |
|||
<section id="contract_recurring_items"> |
|||
<h1 class="page-header">Recurring Invoice Items</h1> |
|||
<p> |
|||
This section lists the recurring invoice items |
|||
when new invoices are generated. Editing will not |
|||
change its display for customers. |
|||
</p> |
|||
<table class="table wq-table"> |
|||
<thead> |
|||
<tr> |
|||
<th>Name</th> |
|||
<th>Quantity</th> |
|||
<th>UoM</th> |
|||
<th>Subtotal</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr> |
|||
<td> |
|||
<span>Development Services</span> |
|||
</td> |
|||
<td> |
|||
<span>100.0</span> |
|||
</td> |
|||
<td> |
|||
<span>Hour(s)</span> |
|||
</td> |
|||
<td> |
|||
<span>8000.0</span> |
|||
</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</section> |
|||
<section id="contract_invoices"> |
|||
<h1 class="page-header">Invoices</h1> |
|||
<p> |
|||
This section lists the contract invoices. Same |
|||
as the recurring section, editing this section |
|||
will not change the customer-facing view. |
|||
</p> |
|||
<table class="table wq-table"> |
|||
<thead> |
|||
<tr> |
|||
<th>Invoice #</th> |
|||
<th>Invoice Date</th> |
|||
<th>Due Date</th> |
|||
<th></th> |
|||
<th></th> |
|||
<th>Amount Due</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr> |
|||
<td> |
|||
<span>1002645</span> |
|||
</td> |
|||
<td> |
|||
<span>Some Date</span> |
|||
</td> |
|||
<td> |
|||
<span>Some Date</span> |
|||
</td> |
|||
<td> |
|||
<span>Invoice Status</span> |
|||
</td> |
|||
<td> |
|||
<span>Pay Now</span> |
|||
</td> |
|||
<td> |
|||
<span>$8000.00</span> |
|||
</td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</section> |
|||
<p><mark> |
|||
Editing the content within the Contract header section will change |
|||
what is displayed for customers. |
|||
</mark></p> |
|||
<div id="template_introduction" t-field="template.website_description" class="oe_no_empty" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</t> |
|||
</template> |
|||
|
|||
<template id="contract_recurring_items" name="Recurring Items"> |
|||
<section id="recurring_items"> |
|||
<t t-if="contract.recurring_invoice_line_ids"> |
|||
<h1 class="page-header">Recurring Invoice Items</h1> |
|||
<table class="table wq-table"> |
|||
<thead> |
|||
<tr> |
|||
<th>Name</th> |
|||
<th>Quantity</th> |
|||
<th>UoM</th> |
|||
<th>Subtotal</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<t t-foreach="contract.recurring_invoice_line_ids" t-as="invoice_line"> |
|||
<tr> |
|||
<td> |
|||
<span t-field="invoice_line.display_name" /> |
|||
</td> |
|||
<td> |
|||
<span t-field="invoice_line.quantity" /> |
|||
</td> |
|||
<td> |
|||
<span t-field="invoice_line.uom_id" /> |
|||
</td> |
|||
<td> |
|||
<span t-field="invoice_line.price_subtotal" /> |
|||
</td> |
|||
</tr> |
|||
</t> |
|||
</tbody> |
|||
</table> |
|||
</t> |
|||
</section> |
|||
</template> |
|||
|
|||
<template id="contract_invoices" name="Contract Invoices"> |
|||
<section id="invoices"> |
|||
<t t-if="contract.account_invoice_ids"> |
|||
<h1 class="page-header">Invoices</h1> |
|||
<table class="table wq-table"> |
|||
<thead> |
|||
<tr> |
|||
<th>Invoice #</th> |
|||
<th>Invoice Date</th> |
|||
<th>Due Date</th> |
|||
<th></th> |
|||
<th></th> |
|||
<th>Amount Due</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<t t-foreach="contract.account_invoice_ids" t-as="invoice"> |
|||
<tr> |
|||
<td class="cell_overflow"> |
|||
<span t-field="invoice.number" /> |
|||
</td> |
|||
<td><span t-field="invoice.date_invoice"/></td> |
|||
<td><span t-field="invoice.date_due"/></td> |
|||
<td> |
|||
<t t-if="invoice.state == 'open'"> |
|||
<span class="label label-info"><i class="fa fa-fw fa-clock-o"/> Waiting for Payment</span> |
|||
</t> |
|||
<t t-if="invoice.state == 'paid'"> |
|||
<span class="label label-default"><i class="fa fa-fw fa-check"/> Paid</span> |
|||
</t> |
|||
<t t-if="invoice.state == 'cancel'"> |
|||
<span class="label label-default"><i class="fa fa-fw fa-remove"/> Cancelled</span> |
|||
</t> |
|||
</td> |
|||
<td> |
|||
<a t-if="invoice.state == 'open'" |
|||
t-attf-href="/website_payment/pay?reference=#{invoice.number}&amount=#{invoice.residual}&currency_id=#{invoice.currency_id.id}&country_id=#{invoice.partner_id.country_id.id}" |
|||
alt="Pay Now" class="btn btn-xs btn-primary"> |
|||
<i class="fa fa-arrow-circle-right" /> |
|||
Pay Now |
|||
</a> |
|||
</td> |
|||
<td><span t-field="invoice.residual" t-options='{"widget": "monetary", "display_currency": invoice.currency_id}'/></td> |
|||
</tr> |
|||
</t> |
|||
</tbody> |
|||
</table> |
|||
</t> |
|||
</section> |
|||
</template> |
|||
|
|||
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue