Browse Source

[ADD] moving odoo cooperative modules on github

pull/1/head
houssine 7 years ago
parent
commit
221055bc25
  1. 3
      easy_my_coop/__init__.py
  2. 61
      easy_my_coop/__openerp__.py
  3. 1
      easy_my_coop/controllers/__init__.py
  4. 186
      easy_my_coop/controllers/main.py
  5. 36
      easy_my_coop/data/easy_my_coop_data.xml
  6. 381
      easy_my_coop/data/mail_template_data.xml
  7. 24
      easy_my_coop/data/website_cooperator_data.xml
  8. 2292
      easy_my_coop/i18n/fr.po
  9. 1857
      easy_my_coop/i18n/fr_BE.po
  10. 1414
      easy_my_coop/i18n/nl_BE.po
  11. 30
      easy_my_coop/migrations/8.0.1.0/pre-migration.py
  12. 9
      easy_my_coop/models/__init__.py
  13. 86
      easy_my_coop/models/account_invoice.py
  14. 9
      easy_my_coop/models/account_journal.py
  15. 22
      easy_my_coop/models/company.py
  16. 344
      easy_my_coop/models/coop.py
  17. 53
      easy_my_coop/models/mail_mail.py
  18. 212
      easy_my_coop/models/operation_request.py
  19. 61
      easy_my_coop/models/partner.py
  20. 21
      easy_my_coop/models/product.py
  21. 9
      easy_my_coop/models/res_partner_bank.py
  22. 173
      easy_my_coop/report/cooperator_certificat_G001.xml
  23. 255
      easy_my_coop/report/cooperator_invoice_G002.xml
  24. 128
      easy_my_coop/report/cooperator_register_G001.xml
  25. 110
      easy_my_coop/report/cooperator_subscription_G001.xml
  26. 63
      easy_my_coop/report/easy_my_coop_report.xml
  27. 31
      easy_my_coop/security/easy_my_coop_security.xml
  28. 13
      easy_my_coop/security/ir.model.access.csv
  29. 27
      easy_my_coop/static/src/css/coop_report.css
  30. 49
      easy_my_coop/static/src/js/easy_my_coop.js
  31. 66
      easy_my_coop/view/account_invoice_view.xml
  32. 28
      easy_my_coop/view/account_journal_view.xml
  33. 54
      easy_my_coop/view/cooperator_register_view.xml
  34. 16
      easy_my_coop/view/email_template_view.xml
  35. 102
      easy_my_coop/view/operation_request_view.xml
  36. 143
      easy_my_coop/view/product_view.xml
  37. 25
      easy_my_coop/view/res_company_view.xml
  38. 115
      easy_my_coop/view/res_partner_view.xml
  39. 154
      easy_my_coop/view/subscription_request_view.xml
  40. 566
      easy_my_coop/view/subscription_template.xml
  41. 2
      easy_my_coop/wizard/__init__.py
  42. 69
      easy_my_coop/wizard/cooperative_history_wizard.py
  43. 56
      easy_my_coop/wizard/cooperative_history_wizard.xml
  44. 0
      easy_my_coop_be/__init__.py
  45. 35
      easy_my_coop_be/__openerp__.py
  46. 1
      easy_my_coop_eater/__init__.py
  47. 34
      easy_my_coop_eater/__openerp__.py
  48. 2
      easy_my_coop_eater/models/__init__.py
  49. 28
      easy_my_coop_eater/models/coop.py
  50. 8
      easy_my_coop_eater/models/product.py
  51. 14
      easy_my_coop_eater/view/product_view.xml
  52. 1
      easy_my_coop_fr/__init__.py
  53. 37
      easy_my_coop_fr/__openerp__.py
  54. 1
      easy_my_coop_fr/models/__init__.py
  55. 16
      easy_my_coop_fr/models/coop.py
  56. 14
      easy_my_coop_fr/views/layout_template.xml
  57. 11
      easy_my_coop_fr/views/subscription_template.xml
  58. 2
      easy_my_coop_online_payment/__init__.py
  59. 37
      easy_my_coop_online_payment/__openerp__.py
  60. 1
      easy_my_coop_online_payment/controllers/__init__.py
  61. 104
      easy_my_coop_online_payment/controllers/main.py
  62. 65
      easy_my_coop_online_payment/i18n/fr.po
  63. 2
      easy_my_coop_online_payment/models/__init__.py
  64. 8
      easy_my_coop_online_payment/models/coop.py
  65. 45
      easy_my_coop_online_payment/models/payment_transaction.py
  66. 25
      easy_my_coop_online_payment/views/online_payment_template.xml
  67. 3
      easy_my_coop_recompute_coop_number/__init__.py
  68. 35
      easy_my_coop_recompute_coop_number/__openerp__.py
  69. 2
      easy_my_coop_recompute_coop_number/wizard/__init__.py
  70. 49
      easy_my_coop_recompute_coop_number/wizard/cooperator_number_wizard.py
  71. 39
      easy_my_coop_recompute_coop_number/wizard/cooperator_number_wizard.xml
  72. 0
      easy_my_coop_taxshelter_report/__init__.py
  73. 35
      easy_my_coop_taxshelter_report/__openerp__.py
  74. 141
      easy_my_coop_taxshelter_report/report/tax_shelter_report.xml
  75. 19
      easy_my_coop_taxshelter_report/static/src/css/coop_report.css
  76. 1
      easy_my_coop_taxshelter_report/wizard/__init__.py
  77. 49
      easy_my_coop_taxshelter_report/wizard/tax_shelter_report_wizard.py
  78. 38
      easy_my_coop_taxshelter_report/wizard/tax_shelter_report_wizard.xml
  79. 1
      partner_age/__init__.py
  80. 34
      partner_age/__openerp__.py
  81. 1
      partner_age/models/__init__.py
  82. 30
      partner_age/models/partner.py
  83. 24
      partner_age/view/partner_view.xml
  84. 0
      theme_light/__init__.py
  85. 15
      theme_light/__openerp__.py
  86. 197
      theme_light/report/header_report_G002.xml
  87. 5774
      theme_light/static/css/bootstrap.css
  88. 19
      theme_light/static/css/global_theme.css
  89. 21
      theme_light/static/css/global_theme.sass
  90. 161
      theme_light/static/css/invoice_B001.css
  91. 194
      theme_light/static/css/invoice_B002.css
  92. 161
      theme_light/static/css/invoice_G001.css
  93. 216
      theme_light/static/css/invoice_G002.css
  94. 194
      theme_light/static/css/invoice_O002.css
  95. 204
      theme_light/static/css/invoice_P002.css
  96. 165
      theme_light/static/css/invoice_orange.css
  97. 64
      theme_light/static/css/mail_template_B001.css
  98. 9505
      theme_light/static/css/theme_zen_black.css
  99. 9648
      theme_light/static/css/theme_zen_blue.css
  100. 9512
      theme_light/static/css/theme_zen_brown.css

3
easy_my_coop/__init__.py

@ -0,0 +1,3 @@
from . import models
from . import controllers
#import wizard

61
easy_my_coop/__openerp__.py

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop",
"version": "1.0",
"depends": ["base",
"sale",
"purchase",
"account_accountant",
"product",
"website",
"website_recaptcha_reloaded",
"theme_light",
"base_iban"],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This module allows to manage the cooperator subscription and all the cooperative business processes.
""",
'data': [
'security/easy_my_coop_security.xml',
'security/ir.model.access.csv',
'view/subscription_request_view.xml',
'view/email_template_view.xml',
'view/res_partner_view.xml',
'view/cooperator_register_view.xml',
'view/operation_request_view.xml',
'view/account_invoice_view.xml',
'view/subscription_template.xml',
'view/product_view.xml',
'view/res_company_view.xml',
'view/account_journal_view.xml',
'data/easy_my_coop_data.xml',
'report/easy_my_coop_report.xml',
'report/cooperator_invoice_G002.xml',
'report/cooperator_certificat_G001.xml',
'report/cooperator_subscription_G001.xml',
'report/cooperator_register_G001.xml',
'data/mail_template_data.xml',
#'wizard/cooperative_history_wizard.xml',
],
'installable': True,
'application': True,
}

1
easy_my_coop/controllers/__init__.py

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

186
easy_my_coop/controllers/main.py

@ -0,0 +1,186 @@
# -*- coding: utf-8 -*-
import base64
import datetime
import re
import werkzeug
import werkzeug.urls
from openerp import http, SUPERUSER_ID
from openerp.http import request
from openerp.tools.translate import _
_TECHNICAL = ['view_from', 'view_callback'] # Only use for behavior, don't stock it
_BLACKLIST = ['id', 'create_uid', 'create_date', 'write_uid', 'write_date', 'user_id', 'active'] # Allow in description
#_REQUIRED = ['email','firstname','lastname','birthdate','address','share_product_id','ordered_parts','zip_code','city','iban','no_registre','gender'] # Could be improved including required from model
class WebsiteSubscription(http.Controller):
@http.route(['/page/become_cooperator','/become_cooperator'], type='http', auth="public", website=True)
def display_become_cooperator_page(self, **kwargs):
values = {}
values = self.fill_values(values,is_company=False)
for field in ['email','firstname','lastname','birthdate','iban','share_product_id','no_registre','address','city','zip_code','country_id','phone','lang','nb_parts','total_parts','error_msg']:
if kwargs.get(field):
values[field] = kwargs.pop(field)
values.update(kwargs=kwargs.items())
return request.website.render("easy_my_coop.becomecooperator", values)
@http.route(['/page/become_company_cooperator','/become_company_cooperator'], type='http', auth="public", website=True)
def display_become_company_cooperator_page(self, **kwargs):
values = {}
values = self.fill_values(values,is_company=True)
for field in ['is_company','company_register_number','company_name','company_email','company_type','email','firstname','lastname','birthdate','iban','share_product_id','no_registre','address','city','zip_code','country_id','phone','lang','nb_parts','total_parts','error_msg']:
if kwargs.get(field):
values[field] = kwargs.pop(field)
values.update(kwargs=kwargs.items())
return request.website.render("easy_my_coop.becomecompanycooperator", values)
def preRenderThanks(self, values, kwargs):
""" Allow to be overrided """
return {
'_values': values,
'_kwargs': kwargs,
}
def get_subscription_response(self, values, kwargs):
values = self.preRenderThanks(values, kwargs)
return request.website.render(kwargs.get("view_callback", "easy_my_coop.cooperator_thanks"), values)
def fill_values(self, values, is_company):
company = request.website.company_id
values['countries'] = self.get_countries()
values['langs'] = self.get_langs()
values['products'] = self.get_products_share(is_company)
fields_desc = request.env['subscription.request'].sudo().fields_get(['company_type','gender'])
values['company_types'] = fields_desc['company_type']['selection']
values['genders'] = fields_desc['gender']['selection']
if not values.get('share_product_id'):
products = request.env['product.template'].sudo().get_web_share_products(is_company)
for product in products:
if product.default_share_product == True:
values['share_product_id'] = product.id
break
if not values.get('country_id'):
if company.default_country_id:
values['country_id'] = company.default_country_id.id
else:
values['country_id'] = '21'
if not values.get('activities_country_id'):
if company.default_country_id:
values['activities_country_id'] = company.default_country_id.id
else:
values['activities_country_id'] = '21'
if not values.get('lang'):
if company.default_lang_id:
values['lang'] = company.default_lang_id.code
return values
def get_products_share(self, is_company):
products = request.env['product.template'].sudo().get_web_share_products(is_company)
return products
def get_countries(self):
countries = request.env['res.country'].sudo().search([])
return countries
def get_langs(self):
langs = request.env['res.lang'].sudo().search([])
return langs
@http.route(['/subscription/get_share_product'], type='json', auth="public", methods=['POST'], website=True)
def get_share_product(self, share_product_id, **kw):
product = request.env['product.template'].sudo().browse(int(share_product_id))
return {product.id: {'list_price':product.list_price,'min_qty':product.minimum_quantity}}
@http.route(['/subscription/subscribe_share'], type='http', auth="public", website=True)
def share_subscription(self, **kwargs):
post_file = [] # List of file to add to ir_attachment once we have the ID
post_description = [] # Info to add after the message
values = {}
for field_name, field_value in kwargs.items():
if hasattr(field_value, 'filename'):
post_file.append(field_value)
elif field_name in request.registry['subscription.request']._fields and field_name not in _BLACKLIST:
values[field_name] = field_value
elif field_name not in _TECHNICAL: # allow to add some free fields or blacklisted field like ID
post_description.append("%s: %s" % (field_name, field_value))
is_company = False
if kwargs.get("is_company") == 'on':
is_company = True
values["is_company"] = is_company
redirect = "easy_my_coop.becomecooperator"
if is_company:
redirect = "easy_my_coop.becomecompanycooperator"
if not kwargs.has_key('g-recaptcha-response') or not request.website.is_captcha_valid(kwargs['g-recaptcha-response']):
values = self.fill_values(values,is_company)
values["error_msg"] = "the captcha has not been validated, please fill in the captcha"
return request.website.render(kwargs.get("view_from", redirect), values)
# fields validation : Check that required field from model subscription_request exists
required_fields = request.env['subscription.request'].sudo().get_required_field()
error = set(field for field in required_fields if not values.get(field))
if error:
values = self.fill_values(values, is_company)
values["error_msg"] = "Some mandatory fields have not been filled"
values = dict(values, error=error, kwargs=kwargs.items())
return request.website.render(kwargs.get("view_from", redirect), values)
if kwargs.get("already_cooperator") == 'on':
already_cooperator = True
lastname = kwargs.get("lastname").upper()
firstname = kwargs.get("firstname").title()
values["name"] = firstname + " " + lastname
values["lastname"] = lastname
values["firstname"] = firstname
values["birthdate"] = datetime.datetime.strptime(kwargs.get("birthdate"), "%d/%m/%Y").date()
#check the subscription's amount
company = request.website.company_id
max_amount = company.subscription_maximum_amount
total_amount = float(kwargs.get('total_parts'))
if max_amount > 0 and total_amount > max_amount:
values = self.fill_values(values)
values["error_msg"] = "You can't suscribe for an amount that exceed " + str(max_amount) + company.currency_id.symbol
return request.website.render("easy_my_coop.becomecooperator", values)
if values["is_company"] == True:
if kwargs.get("company_register_number"):
values["company_register_number"] = re.sub('[^0-9a-zA-Z]+', '', kwargs.get("company_register_number"))
subscription_id = request.env['subscription.request'].sudo().create_comp_sub_req(values)
else:
if kwargs.get("no_registre"):
values["no_registre"] = re.sub('[^0-9a-zA-Z]+', '', kwargs.get("no_registre"))
subscription_id = request.env['subscription.request'].sudo().create(values)
values.update(subscription_id = subscription_id)
if subscription_id:
for field_value in post_file:
attachment_value = {
'name': field_value.filename,
'res_name': field_value.filename,
'res_model': 'subscription.request',
'res_id': subscription_id,
'datas': base64.encodestring(field_value.read()),
'datas_fname': field_value.filename,
}
request.registry['ir.attachment'].create(request.cr, SUPERUSER_ID, attachment_value, context=request.context)
return self.get_subscription_response(values, kwargs)

36
easy_my_coop/data/easy_my_coop_data.xml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- Product -->
<record id="product_category_company_share" model="product.category">
<field name="name">Company Share</field>
</record>
<record id="sequence_subscription_journal" model="ir.sequence">
<field name="name">Account Default Subscription Journal</field>
<field eval="3" name="padding"/>
<field name="prefix">SUBJ/%(year)s/</field>
</record>
<record id="subscription_journal" model="account.journal">
<field name="name">Subscription Journal</field>
<field name="code">SUBJ</field>
<field name="type">sale</field>
<field name="sequence_id" ref="sequence_subscription_journal"/>
</record>
<record id="sequence_subscription" model="ir.sequence">
<field name="name">Subscription Register</field>
<field name="code">subscription.register</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
</record>
<record id="sequence_register_operation" model="ir.sequence">
<field name="name">Register Operation</field>
<field name="code">register.operation</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
</record>
</data>
</openerp>

381
easy_my_coop/data/mail_template_data.xml

@ -0,0 +1,381 @@
<openerp>
<!-- Mail template are declared in a NOUPDATE block
so users can freely customize/delete them -->
<data noupdate="1">
<!--Request to release capital Email template -->
<record id="email_template_release_capital" model="mail.template">
<field name="name">Request to Release Capital - Send by Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">${object.company_id.name} Request to Release Capital (Ref ${object.number or 'n/a'})</field>
<field name="partner_to">${object.partner_id.id}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="account.model_account_invoice"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="action_cooperator_invoices"/>
<field name="report_name">${(object.number or '').replace('/','_')}_${object.state == 'draft' and 'draft' or ''}</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.partner_id.name},</p>
<p>You will find in attachment all the necessary information for the payment. We kindly remind you that your subscription will be effective only once we received the payment.</p>
<p>Do not forget to add the structured communication to the payment.</p>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
<record id="email_template_confirmation" model="mail.template">
<field name="name">Confirmation Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">Subscription request confirmation</field>
<field name="email_to">${object.email}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="model_subscription_request"/>
<field name="auto_delete" eval="True"/>
<field name="lang">${object.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.name},</p>
<p>Your request will be soon processed by our team. If all the provided info are correct you will soon receive the payment information in another email</p>
<br/>
<p>If you have any question, do not hesitate to contact us.</p>
<br/>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
<record id="email_template_confirmation_company" model="mail.template">
<field name="name">Company Confirmation Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">Subscription request confirmation</field>
<field name="email_to">${object.email},${object.company_email}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="model_subscription_request"/>
<field name="auto_delete" eval="True"/>
<field name="lang">${object.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.name},</p>
<p>We have received your subscription request for ${object.company_name} ${object.company_type}. Thank you for your support.</p>
<p>Your request will be soon processed by our team "gestion et participation des membres". If all the provided info are correct you will soon receive the payment information in another email</p>
<br/>
<p>If you have any question, do not hesitate to contact us.</p>
<br/>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
<record id="email_template_certificat" model="mail.template">
<field name="name">Payment Received Confirmation - Send By Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">Payment Received Confirmation</field>
<!-- <field name="email_recipients">${object.partner_id.id}</field> -->
<field name="partner_to">${object.id}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="action_cooperator_report_certificat"/>
<field name="report_name">Certificat ${(object.cooperator_register_number or '')}</field>
<field name="lang">${object.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.name},</p>
<p>We confirm the reception of you payment. You are now shareholder of our cooperative</p>
<br/>
<p>Find in attachment your ${object.company_id.name} certificate.</p>
<p>Thank you for choosing ${object.company_id.name or 'us'}!</p>
<br/>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
<record id="email_template_certificat_increase" model="mail.template">
<field name="name">Share Increase - Payment Received Confirmation - Send By Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">Payment Received Confirmation</field>
<field name="partner_to">${object.id}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="action_cooperator_report_certificat"/>
<field name="report_name">${object.company_id} Certificat ${(object.cooperator_register_number or '')}</field>
<field name="lang">${object.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.name},</p>
<p>We confirm the reception of you payment for the new share(s) you have taken.</p>
<br/>
<p>Find in attachment your ${object.company_id} certificate.</p>
<p>Thank you for trusting ${object.company_id.name or 'us'}!</p>
<br/>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
<record id="email_template_share_transfer" model="mail.template">
<field name="name">Share transfer - Send By Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">Share transfert</field>
<field name="partner_to">${object.id}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="action_cooperator_report_certificat"/>
<field name="report_name">Certificat ${(object.cooperator_register_number or '')}</field>
<field name="lang">${object.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.name},</p>
<p>We confirm you that the shares have been transfered to you. If you was not already cooperator, you are now shareholder of our cooperative</p>
<br/>
<p>Find in attachment your ${object.company_id.name} certificate.</p>
<p>Thank you for choosing ${object.company_id.name or 'us'}!</p>
<br/>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
<record id="email_template_share_update" model="mail.template">
<field name="name">Share update - Send By Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="subject">Share update</field>
<field name="partner_to">${object.id}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.user_id.email)|safe}</field>
<field name="model_id" ref="model_res_partner"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="action_cooperator_report_certificat"/>
<field name="report_name">Certificat ${(object.cooperator_register_number or '')}</field>
<field name="lang">${object.lang}</field>
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello ${object.name},</p>
<p>We confirm you that the adaptation on shares portfolio has been succesfully performed. Your cooperator certificate has been adapted accordingly</p>
<br/>
<p>Find in attachment your ${object.company_id.name} certificate.</p>
<p>Thank you for choosing ${object.company_id.name or 'us'}!</p>
<br/>
<p>Sustainably your,</p>
<p>${object.company_id.name}.</p>
% if object.company_id.street:
${object.company_id.street}
% endif
% if object.company_id.street2:
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
% if object.company_id.phone:
Phone:&nbsp; ${object.company_id.phone}
% endif
% if object.company_id.website:
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
<div>
<img src=${object.company_id.logo_web}>
</div>
</div>
]]></field>
</record>
</data>
</openerp>

24
easy_my_coop/data/website_cooperator_data.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="action_open_website" model="ir.actions.act_url">
<field name="name">Website Cooperator contact Form</field>
<field name="target">self</field>
<field name="url">/page/website.contactus</field>
</record>
<record id="base.open_menu" model="ir.actions.todo">
<field name="action_id" ref="action_open_website"/>
<field name="state">open</field>
</record>
<record model="crm.case.section" id="website.salesteam_website_sales">
<field name="name">Website Sales</field>
<field name="code">WS</field>
<field name="member_ids" eval="[(4, ref('base.user_root'))]"/>
<field name="use_leads">True</field>
<field name="use_opportunities" eval="False"/>
</record>
</data>
</openerp>

2292
easy_my_coop/i18n/fr.po
File diff suppressed because it is too large
View File

1857
easy_my_coop/i18n/fr_BE.po
File diff suppressed because it is too large
View File

1414
easy_my_coop/i18n/nl_BE.po
File diff suppressed because it is too large
View File

30
easy_my_coop/migrations/8.0.1.0/pre-migration.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from openerp.openupgrade import openupgrade
import logging
logger = logging.getLogger('OpenUpgrade')
column_renames = {
'job_sync_line': [
('adresse', 'address'),
('ville', 'city'),
('codepostal', 'zip'),
('sync_date','date'),
],
}
tables_renames = [
('job_sync_line','subscription_request'),
('job_sync',None),
('external_db',None),
]
@openupgrade.migrate()
def migrate(cr, version):
if not version:
return
openupgrade.rename_columns(cr, column_renames)
openupgrade.rename_tables(cr, tables_renames)

9
easy_my_coop/models/__init__.py

@ -0,0 +1,9 @@
from . import coop
from . import operation_request
from . import product
from . import partner
from . import account_invoice
from . import company
from . import res_partner_bank
from . import account_journal
#import mail_mail

86
easy_my_coop/models/account_invoice.py

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from openerp import api, fields, models, _
class account_invoice(models.Model):
_inherit = 'account.invoice'
subscription_request = fields.Many2one('subscription.request', string='Subscription request')
release_capital_request = fields.Boolean(string='Release of capital request')
@api.model
def _prepare_refund(self, invoice, date_invoice=None, date=None, description=None, journal_id=None):
values = super(account_invoice, self)._prepare_refund(invoice, date_invoice, date, description, journal_id)
values['release_capital_request'] = self.release_capital_request
return values
def set_cooperator_effective(self, effective_date):
# flag the partner as a effective member
obj_sequence = self.env['ir.sequence']
# if not yet cooperator we generate a cooperator number
if self.partner_id.member == False :
sequence_id = obj_sequence.search([('name','=','Subscription Register')])[0]
sub_reg_num = sequence_id.next_by_id()
self.partner_id.write({'member':True,
'cooperator_register_number':int(sub_reg_num)})
sequence_operation = obj_sequence.search([('name','=','Register Operation')])[0]
sub_reg_operation = sequence_operation.next_by_id()
for line in self.invoice_line_ids:
sub_reg = self.env['subscription.register'].create(
{'name':sub_reg_operation,
'register_number_operation':int(sub_reg_operation),
'partner_id':self.partner_id.id,
'quantity':line.quantity,
'share_product_id':line.product_id.id,
'share_unit_price':line.price_unit,
'date':effective_date,
'type':'subscription'})
self.env['share.line'].create({'share_number':line.quantity,
'share_product_id':line.product_id.id,
'partner_id':self.partner_id.id,
'share_unit_price':line.price_unit,
'effective_date':effective_date})
mail_template_name = 'Payment Received Confirmation - Send By Email'
if self.partner_id.member :
mail_template_name = 'Share Increase - Payment Received Confirmation - Send By Email'
email_template_obj = self.env['mail.template']
certificat_email_template = email_template_obj.search([('name', '=', mail_template_name)])[0]
# we send the email with the certificat in attachment
certificat_email_template.send_mail(self.partner_id.id, False)
return True
def post_process_confirm_paid(self, effective_date):
self.set_cooperator_effective(effective_date)
return True
@api.multi
def confirm_paid(self):
super(account_invoice, self).confirm_paid()
for invoice in self:
if invoice.partner_id.cooperator and invoice.release_capital_request and invoice.type == 'out_invoice':
effective_date = datetime.now().strftime("%d/%m/%Y")
#take the effective date from the payment. by default the confirmation date is the payment date
if invoice.payment_move_line_ids :
move_line = invoice.payment_move_line_ids[0]
effective_date = move_line.date
invoice.subscription_request.state = 'paid'
invoice.post_process_confirm_paid(effective_date)
return True
@api.multi
def invoice_print(self):
""" Print the invoice and mark it as sent, so that we can see more
easily the next step of the workflow
"""
self.ensure_one()
self.sent = True
return self.env['report'].get_action(self, 'easy_my_coop.report_sexy_invoice')

9
easy_my_coop/models/account_journal.py

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class AccountJournal(models.Model):
_inherit = "account.journal"
get_cooperator_payment = fields.Boolean('Get cooperator payments?')
get_general_payment = fields.Boolean('Get general payments?')

22
easy_my_coop/models/company.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class ResCompany(models.Model):
_inherit = 'res.company'
coop_email_contact = fields.Char(string="Contact email address for the cooperator")
subscription_maximum_amount = fields.Float(string="Maximum authorized subscription amount")
default_country_id = fields.Many2one('res.country', string="Default country", default=lambda self: self.country_id)
default_lang_id = fields.Many2one('res.lang', string="Default lang")
board_representative = fields.Char(string="Board representative name")
signature_scan = fields.Binary(string="Board representative signature")
property_cooperator_account = fields.Many2one('account.account', company_dependent=True,
string="Cooperator Account",
domain="[('internal_type', '=', 'receivable'), ('deprecated', '=', False)]",
help="This account will be the default one as the receivable account for the cooperators",
required=True)
unmix_share_type = fields.Boolean(string="Unmix share type",
help="If checked, A cooperator will be authorized "
"to have only one type of share")
display_logo1 = fields.Boolean(string="Display logo1")
display_logo2 = fields.Boolean(string="Display logo2")

344
easy_my_coop/models/coop.py

@ -0,0 +1,344 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from openerp import api, fields, models, _
from openerp.addons.base_iban import base_iban
from openerp.exceptions import UserError, ValidationError
import openerp.addons.decimal_precision as dp
_REQUIRED = ['email','firstname','lastname','birthdate','address','share_product_id','ordered_parts','zip_code','city','iban','no_registre','gender'] # Could be improved including required from model
@api.model
def _lang_get(self):
languages = self.env['res.lang'].search([])
return [(language.code, language.name) for language in languages]
class subscription_request(models.Model):
_name = 'subscription.request'
_description = 'Subscription Request'
def get_required_field(self):
return _REQUIRED
@api.model
def create(self,vals):
if not vals.get('partner_id'):
cooperator = False
if vals.get('no_registre'):
cooperator = self.env['res.partner'].get_cooperator_from_nin(vals.get('no_registre'))
if cooperator:
if cooperator.member:
vals['type'] = 'increase'
vals['already_cooperator'] = True
else:
vals['type'] = 'subscription'
vals['partner_id'] = cooperator.id
subscr_request = super(subscription_request, self).create(vals)
mail_template_obj = self.env['mail.template']
confirmation_mail_template = mail_template_obj.search([('name', '=', 'Confirmation Email')])[0]
confirmation_mail_template.send_mail(subscr_request.id, True)
return subscr_request
@api.model
def create_comp_sub_req(self, vals):
if not vals.get('partner_id'):
cooperator = self.env['res.partner'].get_cooperator_from_crn(vals.get('company_register_number'))
if cooperator:
vals['partner_id'] = cooperator.id
vals['type'] = 'increase'
vals['already_cooperator'] = True
subscr_request = super(subscription_request, self).create(vals)
mail_template_obj = self.env['mail.template']
confirmation_mail_template = mail_template_obj.search([('name', '=', 'Company Confirmation Email')])[0]
confirmation_mail_template.send_mail(subscr_request.id, True)
return subscr_request
def check_belgian_identification_id(self, nat_register_num):
if not self.check_empty_string(nat_register_num):
return False
if len(nat_register_num) != 11:
return False
if not nat_register_num.isdigit():
return False
birthday_number = nat_register_num[0:9]
controle = nat_register_num[9:11]
check_controle = 97 - (int(birthday_number) % 97)
if int(check_controle) != int(controle):
check_controle = 97 - ((2000000000 + int(birthday_number)) % 97)
if int(check_controle) != int(controle):
return False
return True
def check_empty_string(self, value):
if value == None or value == False or value == '':
return False
return True
@api.multi
@api.depends('iban', 'no_registre','skip_control_ng')
def _validated_lines(self):
for sub_request in self:
try:
base_iban.validate_iban(sub_request.iban)
sub_request.validated = True
except ValidationError:
sub_request.validated = False
if not sub_request.is_company and (sub_request.skip_control_ng or self.check_belgian_identification_id(sub_request.no_registre)):
sub_request.validated = True
@api.multi
@api.depends('share_product_id', 'share_product_id.list_price','ordered_parts')
def _compute_subscription_amount(self):
for sub_request in self:
sub_request.subscription_amount = sub_request.share_product_id.list_price * sub_request.ordered_parts
already_cooperator = fields.Boolean(string="I'm already cooperator")
name = fields.Char(string='Name', required=True)
firstname = fields.Char(string='Firstname')
lastname = fields.Char(string='Lastname')
birthdate = fields.Date(string="Birthdate")
gender = fields.Selection([('male', 'Male'),
('female', 'Female'),
('other', 'Other')], string='Gender')
type = fields.Selection([('new','New Cooperator'),
('subscription','Subscription'),
('increase','Increase number of share')]
,string='Type', default="new")
state = fields.Selection([('draft','Draft'),
('block','Blocked'),
('done','Done'),
('cancelled','Cancelled'),
('paid','paid')],
string='State',required=True, default="draft")
email = fields.Char(string='Email')
iban = fields.Char(string='Account Number')
partner_id = fields.Many2one('res.partner',string='Cooperator')
share_product_id = fields.Many2one('product.product', string='Share type', domain=[('is_share','=',True)])
share_short_name = fields.Char(related='share_product_id.short_name', string='Share type name')
share_unit_price = fields.Float(related='share_product_id.list_price', string='Share price')
subscription_amount = fields.Float(compute='_compute_subscription_amount', string='Subscription amount')
ordered_parts = fields.Integer(string='Number of Share')
address = fields.Char(string='Address')
city = fields.Char(string='City')
zip_code = fields.Char(string='Zip Code')
country_id = fields.Many2one('res.country', string='Country', ondelete='restrict')
phone = fields.Char(string='Phone')
no_registre = fields.Char(string='National Register Number')
user_id = fields.Many2one('res.users', string='Responsible', readonly=True)
validated = fields.Boolean(compute='_validated_lines', string='Valid Line?', readonly=True)
skip_control_ng = fields.Boolean(string="Skip control",
help="if this field is checked then no control will be done on the national register number and on the iban bank account. To be done in case of the id card is from abroad or in case of a passport")
lang = fields.Selection(_lang_get, 'Language', default='fr_BE',
help="If the selected language is loaded in the system, all documents related to this contact will be printed in this language. If not, it will be English.")
date = fields.Date(string='Subscription date request', default=lambda self: datetime.strftime(datetime.now(), '%Y-%m-%d'))
company_id = fields.Many2one('res.company', string='Company', required=True,
change_default=True, readonly=True,
default=lambda self: self.env['res.company']._company_default_get())
is_company = fields.Boolean(string='Is a company')
is_operation = fields.Boolean(string='Is an operation')
company_name = fields.Char(string="Company name")
company_email = fields.Char(string="Company email")
company_register_number = fields.Char(string='Company register number')
company_type = fields.Selection([('scrl','SCRL'),
('asbl','ASBL'),
('sprl','SPRL'),
('sa','SA'),
('other','Other')])
same_address = fields.Boolean(string='Same address')
activities_address = fields.Char(string='Activities address')
activities_city = fields.Char(string='Activities city')
activities_zip_code = fields.Char(string='Activities zip Code')
activities_country_id = fields.Many2one('res.country', string='Activities country', ondelete='restrict')
contact_person_function = fields.Char(string='Function')
operation_request_id = fields.Many2one('operation.request', string="Operation Request")
is_operation = fields.Boolean(string="Is Operation request")
capital_release_request = fields.One2many('account.invoice','subscription_request', string='Subscription request')
_order = "id desc"
def _prepare_invoice_line(self, product, partner, qty):
self.ensure_one()
res = {}
account = product.property_account_income_id or product.categ_id.property_account_income_categ_id
if not account:
raise UserError(_('Please define income account for this product: "%s" (id:%d) - or for its category: "%s".') % \
(product.name, product.id, product.categ_id.name))
fpos = partner.property_account_position_id
if fpos:
account = fpos.map_account(account)
res = {
'name': product.name,
'account_id': account.id,
'price_unit': product.lst_price,
'quantity': qty,
'uom_id': product.uom_id.id,
'product_id': product.id or False,
}
return res
def create_invoice(self, partner):
# get subscription journal
journal = self.env['account.journal'].search([('code','=','SUBJ')])[0]
# get the account for associate
# TODO this should be defined in configuration
if self.company_id.property_cooperator_account:
account = self.company_id.property_cooperator_account
else:
account = self.env['account.account'].search([('code','=','416000')])[0]
# creating invoice and invoice lines
invoice = self.env['account.invoice'].create({'partner_id':partner.id,
'journal_id':journal.id,'account_id':account.id,
'type': 'out_invoice', 'release_capital_request':True,
'subscription_request':self.id})
vals = self._prepare_invoice_line(self.share_product_id, partner, self.ordered_parts)
vals['invoice_id'] = invoice.id
line = self.env['account.invoice.line'].create(vals)
# run the validation on the invoice
invoice.signal_workflow('invoice_open')
invoice_email_template = self.env['mail.template'].search([('name', '=', 'Request to Release Capital - Send by Email')])[0]
# we send the email with the invoice in attachment
invoice_email_template.send_mail(invoice.id, True)
invoice.sent = True
return invoice
def get_partner_company_vals(self):
# this should go to the many2many tag field
#'title':'company',
#self.env['res.partner.title'].search([('shortcut','=',self.company_type)])
partner_vals = {'name':self.company_name, 'is_company': self.is_company,
'company_register_number':self.company_register_number, 'customer':False,
'cooperator':True, 'street':self.address, 'zip':self.zip_code,
'city': self.city,'email':self.email, 'out_inv_comm_type':'bba',
'out_inv_comm_algorithm':'random', 'country_id': self.country_id.id, 'lang':self.lang}
return partner_vals
def get_partner_vals(self):
partner_vals = {'name':self.name, 'first_name':self.firstname, 'last_name': self.lastname,
'customer':False, 'gender':self.gender,'cooperator':True, 'street':self.address,'zip':self.zip_code,
'city': self.city, 'phone': self.phone, 'email':self.email,
'national_register_number':self.no_registre, 'out_inv_comm_type':'bba',
'out_inv_comm_algorithm':'random', 'country_id': self.country_id.id,
'lang':self.lang, 'birthdate':self.birthdate}
return partner_vals
def create_coop_partner(self):
partner_obj = self.env['res.partner']
if self.is_company:
partner_vals = self.get_partner_company_vals()
else:
partner_vals = self.get_partner_vals()
partner = partner_obj.create(partner_vals)
if self.iban :
self.env['res.partner.bank'].create({'partner_id':partner.id,'acc_number':self.iban})
return partner
@api.one
def validate_subscription_request(self):
partner_obj = self.env['res.partner']
if self.partner_id:
partner = self.partner_id
else:
if self.already_cooperator:
raise UserError(_('The checkbox already cooperator is checked please select a cooperator.'))
elif self.is_company:
partner = partner_obj.search([('company_register_number','=',self.company_register_number)])
elif self.no_registre:
partner = partner_obj.search([('national_register_number','=',self.no_registre)])
else:
partner = None
if not partner:
partner = self.create_coop_partner()
if self.is_company:
contact = partner_obj.search([('national_register_number','=',self.no_registre)])
if not contact:
contact_vals = {'name':self.name, 'first_name':self.firstname, 'last_name': self.lastname,
'customer':False, 'street':self.address,'zip':self.zip_code,
'city': self.city, 'phone': self.phone, 'email':self.email,
'national_register_number':self.no_registre, 'out_inv_comm_type':'bba',
'out_inv_comm_algorithm':'random', 'country_id': self.country_id.id,
'lang':self.lang, 'birthdate':self.birthdate, 'parent_id': partner.id,'function':self.contact_person_function}
contact = partner_obj.create(contact_vals)
else:
partner = partner[0]
invoice = self.create_invoice(partner)
self.write({'partner_id':partner.id, 'state':'done'})
return invoice
@api.one
def block_subscription_request(self):
self.write({'state':'block'})
@api.one
def unblock_subscription_request(self):
self.write({'state':'draft'})
@api.one
def cancel_subscription_request(self):
self.write({'state':'cancelled'})
class share_line(models.Model):
_name='share.line'
@api.multi
def _compute_total_line(self):
res = {}
for line in self:
line.total_amount_line = line.share_unit_price * line.share_number
return res
share_product_id = fields.Many2one('product.product', string='Share type', required=True, readonly=True)
share_number = fields.Integer(string='Number of Share', required=True, readonly=True)
share_short_name = fields.Char(related='share_product_id.short_name', string='Share type name')
share_unit_price = fields.Float(string='Share price', readonly=True)
effective_date = fields.Date(string='Effective Date', readonly=True)
partner_id = fields.Many2one('res.partner',string='Cooperator', required=True, ondelete='cascade', readonly=True)
total_amount_line = fields.Float(compute='_compute_total_line', string='Total amount line')
class subscription_register(models.Model):
_name= 'subscription.register'
@api.multi
def _compute_total_line(self):
res = {}
for register_line in self:
register_line.total_amount_line = register_line.share_unit_price * register_line.quantity
name = fields.Char(string='Register Number Operation', required=True, readonly=True)
register_number_operation = fields.Integer(string='Register Number Operation', required=True, readonly=True)
partner_id = fields.Many2one('res.partner',string='Cooperator', required=True, readonly=True)
partner_id_to = fields.Many2one('res.partner',string='Transfered to', readonly=True)
date = fields.Date(string='Subscription Date', required= True, readonly=True)
quantity = fields.Integer(string='Number of share', readonly=True)
share_unit_price = fields.Float(string='Share price', readonly=True)
total_amount_line = fields.Float(compute='_compute_total_line', string='Total amount line')
share_product_id = fields.Many2one('product.product', string='Share type', required=True, readonly=True, domain=[('is_share','=',True)])
share_short_name = fields.Char(related='share_product_id.short_name', string='Share type name', readonly=True)
type = fields.Selection([('subscription','Subscription'),
('transfer','Transfer'),
('sell_back','Sell Back'),
('convert','Conversion')],
string='Operation Type', readonly=True)
company_id = fields.Many2one('res.company', string='Company', required=True,
change_default=True, readonly=True,
default=lambda self: self.env['res.company']._company_default_get(),)
user_id = fields.Many2one('res.users', string='Responsible', readonly=True, default=lambda self: self.env.user)
_order = "register_number_operation asc"

53
easy_my_coop/models/mail_mail.py

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2011 OpenERP S.A (<http://www.openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import SUPERUSER_ID
from openerp.osv import osv
from openerp.osv.orm import except_orm
from openerp.tools import append_content_to_html
from openerp.tools.translate import _
class mail_mail(models.Model):
""" Update of mail_mail class, to remove the signin url added in the portal module """
_inherit = 'mail.mail'
def send_get_mail_body(self, cr, uid, mail, partner=None, context=None):
partner_obj = self.pool.get('res.partner')
body = mail.body_html
if partner:
contex_signup = dict(context or {}, signup_valid=True)
partner = partner_obj.browse(cr, SUPERUSER_ID, partner.id, context=contex_signup)
#text = _("""<p>Access your messages and personal documents through <a href="%s">our Customer Portal</a></p>""") % partner.signup_url
text =''
# partner is an user: add a link to the document if read access
if partner.user_ids and mail.model and mail.res_id \
and self.check_access_rights(cr, partner.user_ids[0].id, 'read', raise_exception=False):
related_user = partner.user_ids[0]
try:
self.pool.get(mail.model).check_access_rule(cr, related_user.id, [mail.res_id], 'read', context=context)
url = partner_obj._get_signup_url_for_action(cr, related_user.id, [partner.id], action='', res_id=mail.res_id, model=mail.model, context=context)[partner.id]
text = _("""<p>Access this document <a href="%s">directly in OpenERP</a></p>""") % url
except except_orm, e:
pass
body = append_content_to_html(body, ("<div><p>%s</p></div>" % text), plaintext=False)
return body

212
easy_my_coop/models/operation_request.py

@ -0,0 +1,212 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from openerp import api, fields, models, _
from openerp.addons.base_iban import base_iban
from openerp.exceptions import UserError, ValidationError
class operation_request(models.Model):
_name = 'operation.request'
def get_date_now(self):
return datetime.strftime(datetime.now(), '%Y-%m-%d')
@api.multi
@api.depends('share_product_id', 'share_product_id.list_price','quantity')
def _compute_subscription_amount(self):
for operation_request in self:
operation_request.subscription_amount = operation_request.share_product_id.list_price * operation_request.quantity
request_date = fields.Date(string='Request date', default=lambda self: self.get_date_now())
partner_id = fields.Many2one('res.partner', string='Cooperator', domain=[('member','=',True)],required=True)
partner_id_to = fields.Many2one('res.partner',string='Transfered to', domain=[('cooperator','=',True)])
operation_type = fields.Selection([('subscription','Subscription'),
('transfer','Transfer'),
('sell_back','Sell Back'),
('convert','Conversion')],string='Operation Type', required=True)
share_product_id = fields.Many2one('product.product', string='Share type', domain=[('is_share','=',True)], required=True)
share_short_name = fields.Char(related='share_product_id.short_name', string='Share type name')
share_unit_price = fields.Float(related='share_product_id.list_price', string='Share price')
subscription_amount = fields.Float(compute='_compute_subscription_amount', string='Subscription amount')
quantity = fields.Integer(string='Number of share', required=True)
state = fields.Selection([('draft','Draft'),
('waiting','Waiting'),
('approved','Approved'),
('done','Done'),
('cancelled','Cancelled'),
('refused','Refused')], string='State',required=True, default='draft')
user_id = fields.Many2one('res.users', string='Responsible', readonly=True, default=lambda self: self.env.user)
subscription_request = fields.One2many('subscription.request','operation_request_id',
string="Share Receiver Info",
help="In case on a transfer of share. "
"If the share receiver isn't a effective member "
"then a subscription form should be filled.")
receiver_not_member = fields.Boolean(string='Receiver is not a member')
company_id = fields.Many2one('res.company', string='Company', required=True,
change_default=True, readonly=True,
default=lambda self: self.env['res.company']._company_default_get())
# def create_credit_note(self):
# # getting info in order to fill in the invoice
# product_obj = self.env['product.product']
# product = product_obj.search([('default_code','=','share_250')])[0]
# #product = product_obj.browse(cr, uid, product_id, context)
# journal = self.env['account.journal'].search([('code','=','SUBJ')])[0]
# # TODO check that this account in the right one and do the same on the product
# account = self.env['account.account'].search([('code','=','416000')])[0]
# capital_account_id = self.pool.get('account.account').search(cr, uid, [('code','=','416000')])[0]
# # creating invoice and invoice lines
# account_obj = self.env['account.invoice']
# account_invoice_id = account_obj.create({'partner_id':vals['partner_id'],
# 'journal_id':journal.id,'account_id':account.id,
# 'type': 'out_refund', 'release_capital_request':True})
# result = self.pool.get('account.invoice.line').product_id_change(cr, uid, False, product.id, False, vals['quantity'], '', 'out_invoice', vals['partner_id'])
# self.pool.get('account.invoice.line').create({'invoice_id':account_invoice_id,
# 'product_id':product.id,'quantity':vals['quantity'],
# 'price_unit':result['value']['price_unit'],
# 'uos_id':result['value']['uos_id'],'account_id':result['value']['account_id'],
# 'name':product.name})
# # run the validation on the invoice
# wf_service = netsvc.LocalService("workflow")
# wf_service.trg_validate(uid, 'account.invoice', account_invoice_id, 'invoice_open', cr)
# #we get the print service for the invoice and send directly the invoice by mail
# email_template_obj = self.pool.get('email.template')
# invoice_email_template_id = email_template_obj.search(cr, uid, [('name', '=', 'Request to Release Capital - Send by Email')])[0]
# # we send the email with the invoice in attachment
# email_template_obj.send_mail(cr, uid, invoice_email_template_id, account_invoice_id, True, context)
# account_obj.write(cr, uid, account_invoice_id,{'sent':True},context)
# return True
@api.one
def approve_operation(self):
self.write({'state':'approved'})
@api.one
def refuse_operation(self):
self.write({'state':'refused'})
@api.one
def submit_operation(self):
self.write({'state':'waiting'})
@api.one
def cancel_operation(self):
self.write({'state':'cancelled'})
@api.one
def reset_to_draft(self):
self.write({'state':'draft'})
def get_total_share_dic(self, partner):
total_share_dic = {}
share_products = self.env['product.template'].search([('is_share','=',True)])
for share_product in share_products:
total_share_dic[share_product.id] = 0
for line in partner.share_ids:
total_share_dic[line.share_product_id.id] += line.share_number
return total_share_dic
# This function doesn't handle the case of a cooperator can own
# different kinds of share type
def hand_share_over(self, partner, share_product_id, quantity):
if not partner.member:
raise ValidationError(_("This operation can't be executed if the cooperator is not an effective member"))
total_share_dic = self.get_total_share_dic(partner)
if quantity > total_share_dic[share_product_id.id]:
raise ValidationError(_("The cooperator can't hand over more shares that he/she owns."))
share_ind = len(partner.share_ids)
i = 1
while quantity > 0:
line = self.partner_id.share_ids[share_ind-i]
if line.share_product_id.id == share_product_id.id:
if quantity > line.share_number:
quantity -= line.share_number
line.unlink()
else:
share_left = line.share_number - quantity
quantity = 0
line.write({'share_number': share_left})
i += 1
# if the cooperator sold all his shares he's no more a effective member
remaning_share_dict = 0
for share_quant in self.get_total_share_dic(partner).values():
remaning_share_dict += share_quant
if remaning_share_dict == 0:
self.partner_id.write({'member': False,'old_member':True})
def has_share_type(self):
for line in self.partner_id.share_ids:
if line.share_product_id.id == self.share_product_id.id:
return True
return False
@api.one
def execute_operation(self):
effective_date = self.get_date_now()
if not self.has_share_type():
raise ValidationError(_("The cooperator doesn't own this share type. Please choose the appropriate share type."))
if self.state != 'approved':
raise ValidationError(_("This operation must be approved before to be executed"))
if self.operation_type == 'sell_back':
self.hand_share_over(self.partner_id, self.share_product_id, self.quantity)
elif self.operation_type == 'transfer':
if self.receiver_not_member:
partner = self.subscription_request.create_coop_partner()
#get cooperator number
sequence_id = self.env['ir.sequence'].search([('name','=','Subscription Register')])[0]
sub_reg_num = sequence_id.next_by_id()
partner_vals = self.env['subscription.request'].get_eater_vals(partner, self.share_product_id)
partner_vals['member'] = True
partner_vals['cooperator_register_number'] = int(sub_reg_num)
partner.write(partner_vals)
self.partner_id_to = partner
else:
if self.company_id.unmix_share_type and (self.partner_id_to.cooperator_type and self.partner_id.cooperator_type != self.partner_id_to.cooperator_type):
raise ValidationError(_("This share type could not be transfered "
"to " + self.partner_id_to.name))
if not self.partner_id_to.member:
partner_vals = self.env['subscription.request'].get_eater_vals(self.partner_id_to, self.share_product_id)
partner_vals['member'] = True
partner_vals['old_member'] = False
self.partner_id_to.write(partner_vals)
#remove the parts to the giver
self.hand_share_over(self.partner_id, self.share_product_id, self.quantity)
#give the share to the receiver
self.env['share.line'].create({'share_number':self.quantity,
'partner_id':self.partner_id_to.id,
'share_product_id':self.share_product_id.id,
'share_unit_price':self.share_unit_price,
'effective_date':effective_date})
else:
raise ValidationError(_("This operation is not yet implemented."))
sequence_operation = self.env['ir.sequence'].search([('name','=','Register Operation')])[0]
sub_reg_operation = sequence_operation.next_by_id()
values = {'name':sub_reg_operation,'register_number_operation':int(sub_reg_operation),
'partner_id':self.partner_id.id, 'quantity':self.quantity,
'share_product_id':self.share_product_id.id, 'type':self.operation_type,
'share_unit_price': self.share_unit_price, 'date':effective_date,
}
self.write({'state':'done'})
email_template_obj = self.env['mail.template']
if self.operation_type == 'transfer':
values['partner_id_to'] = self.partner_id_to.id
certificat_email_template = email_template_obj.search([('name', '=', "Share transfer - Send By Email")])[0]
certificat_email_template.send_mail(self.partner_id_to.id, False)
self.env['subscription.register'].create(values)
certificat_email_template = email_template_obj.search([('name', '=', "Share update - Send By Email")])[0]
certificat_email_template.send_mail(self.partner_id.id, False)

61
easy_my_coop/models/partner.py

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class res_partner(models.Model):
_inherit = 'res.partner'
@api.multi
def _get_share_type(self):
share_type_list = [('','')]
for share_type in self.env['product.template'].search([('is_share','=',True)]):
share_type_list.append((str(share_type.id),share_type.short_name))
return share_type_list
@api.multi
@api.depends('share_ids')
def _compute_effective_date(self):
for partner in self:
if partner.share_ids:
partner.effective_date = partner.share_ids[0].effective_date
@api.multi
@api.depends('share_ids')
def _compute_cooperator_type(self):
for partner in self:
share_type = ''
for line in partner.share_ids:
share_type = str(line.share_product_id.id)
if share_type != '':
partner.cooperator_type = share_type
@api.multi
@api.depends('share_ids')
def _compute_share_info(self):
for partner in self:
number_of_share = 0
total_value = 0.0
for line in partner.share_ids:
number_of_share += line.share_number
total_value += line.share_unit_price * line.share_number
partner.number_of_share = number_of_share
partner.total_value = total_value
cooperator = fields.Boolean(string='Cooperator', help="Check this box if this contact is a cooperator(effective or not).")
member = fields.Boolean(string='Effective cooperator', help="Check this box if this cooperator is an effective member.")
old_member = fields.Boolean(string='Old cooperator', help="Check this box if this cooperator is no more an effective member.")
gender = fields.Selection([('male', 'Male'), ('female', 'Female'), ('other', 'Other')], string='Gender')
national_register_number = fields.Char(string='National Register Number')
share_ids = fields.One2many('share.line','partner_id',string='Share Lines')
cooperator_register_number = fields.Integer(string='Cooperator Number')
birthdate = fields.Date(string="Birthdate")
number_of_share = fields.Integer(compute="_compute_share_info", multi='share', string='Number of share', readonly=True)
total_value = fields.Float(compute="_compute_share_info", multi='share', string='Total value of shares', readonly=True)
company_register_number = fields.Char(string='National Register Number')
cooperator_type = fields.Selection(selection='_get_share_type', compute='_compute_cooperator_type', string='Cooperator Type', store=True)
effective_date = fields.Date(sting="Effective Date", compute='_compute_effective_date', store=True)
def get_cooperator_from_nin(self, national_id_number):
return self.search([('cooperator','=',True),('national_register_number','=',national_id_number)])
def get_cooperator_from_crn(self, company_register_number):
return self.search([('cooperator','=',True),('company_register_number','=',company_register_number)])

21
easy_my_coop/models/product.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class ProductTemplate(models.Model):
_inherit = 'product.template'
is_share = fields.Boolean(string='Is share?')
short_name = fields.Char(string='Short name')
display_on_website = fields.Boolean(string='Display on website')
default_share_product = fields.Boolean(string='Default share product')
minimum_quantity = fields.Integer(string='Minimum quantity', default=1)
by_company = fields.Boolean(string="Can be subscribed by companies?")
by_individual = fields.Boolean(string="Can be subscribed by individuals?")
@api.multi
def get_web_share_products(self, is_company):
if is_company == True:
ids = self.env['product.template'].search([('is_share','=',True), ('display_on_website','=',True),('by_company','=',True)])
else:
ids = self.env['product.template'].search([('is_share','=',True), ('display_on_website','=',True),('by_individual','=',True)])
return ids

9
easy_my_coop/models/res_partner_bank.py

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from openerp import models, _
class ResPartnerBank(models.Model):
_inherit = 'res.partner.bank'
_sql_constraints = [
('unique_number', 'Check(1=1)', 'Account Number must be unique!'),
]

173
easy_my_coop/report/cooperator_certificat_G001.xml

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="cooperator_certificat_G001_document">
<t t-call="theme_light.invoice_layout">
<div class="page">
<head>
<link href="/easy_my_coop/static/src/css/coop_report.css" rel="stylesheet"/>
<style type="text/css">
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Roboto Regular */
@font-face {
font-family: 'Roboto-Regular';
font-style: normal;
src: local('Roboto Regular'), url('/theme_light/static/font/Roboto-Regular.ttf') format('truetype');
}
/* Roboto Bold */
@font-face {
font-family: 'Roboto-Bold';
font-style: normal;
src: local('Roboto Bold'), url('/theme_light/static/font/Roboto-Bold.ttf') format('truetype');
}
/* BEBASNEUE Bold */
@font-face {
font-family: 'Bebasneue-Bold';
font-style: normal;
src: local('Bebasneue-Bold'), url('/theme_light/static/font/BEBASNEUE_BOLD.ttf') format('truetype');
}
</style>
</head>
<t t-call="theme_light.invoice_header"/>
<div class="row">
<div class="col-xs-5 col-xs-offset-7 easymy-coop-address" style="top:90px;">
<strong><span t-field="o.name" /><br/><br/></strong>
<span t-field="o.street" /><br/>
<span>
<span t-field="o.zip"/>
<span t-field="o.city"/>
</span><br/>
<span t-field="o.country_id.name" /><br/>
</div>
</div>
<div style="position:absolute; top:364px">
<h2 style="font-family:Bebasneue-Bold;font-size:20pt;line-height:14pt;">
<div>
<span>COOPERATOR CERTIFICAT</span>
</div>
<div style="width:125px;position:relative;top:10px;border-bottom: 4pt solid #fcc300;"/>
</h2>
<div style="position:relative;top:55px;">
<span t-field="o.name"></span>
<span> is recorded in the register of cooperators under number </span>
<span t-field="o.cooperator_register_number"></span>
</div>
<table class="table border-easymy-coop-cert" style="position:relative;top:85px;width:90%;align:center;">
<thead class="easymy-coop-info-title">
<tr>
<th width="15%">Effective date</th>
<th width="10%">Share type</th>
<th width="10%">Quantity</th>
<th width="15%">Unit Price</th>
<th width="15%">Total</th>
</tr>
</thead>
<tbody class="easymy-coop-normal">
<t t-set="nb_ligne" t-value="0"/>
<t t-foreach="o.share_ids" t-as="line">
<t t-set="nb_ligne" t-value="nb_ligne+1"/>
<tr height="40px">
<div t-if="(nb_ligne%2)==1" >
<td class="lgn_impair">
<span t-field="line.effective_date" ></span>
</td>
<td>
<span t-field="line.share_short_name" ></span>
</td>
<td>
<span t-field="line.share_number" ></span>
</td>
<td>
<span t-field="line.share_unit_price"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td>
<span t-field="line.total_amount_line"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</div>
<div t-if="(nb_ligne%2)==0" >
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.effective_date"> </span>
</td>
<td>
<span t-field="line.share_short_name" ></span>
</td>
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.share_number" ></span>
</td>
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.share_unit_price"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.total_amount_line"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</div>
</tr>
</t>
</tbody>
</table>
<div class="row">
<div class="col-xs-6 pull-right">
<table class="table table-condensed easymy-coop-info-title" style="position:relative;top:145px;width:85%">
<tr class="border-top-easymy-coop-cert">
<td width="20%"/>
<td class="total_table color_text" style="text-align:center" width="20%">TOTAL : </td>
<td class="total_table" style="text-align:center" width="25%">
<span t-field="o.number_of_share"/>
<span> share(s) </span>
</td>
<td class="total_table" width="25%">
<span t-field="o.total_value"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</tr>
</table>
</div>
</div>
<div class="row">
<div class="col-xs-6 pull-left" style="position:relative;top:205px;font-size:20;color:black;font-family:Roboto-Regular;">
<div style="position:relative;top:205px;">
Pour le Conseil d'administration de <span t-field="o.company_id.name"/>.
</div>
<div style="position:relative;top:215px;">
<strong><span t-field="o.company_id.board_representative"/></strong>
</div>
<div style="position:relative;top:225px;">
<img t-if="o.company_id.signature_scan" t-att-src="'data:image/png;base64,%s' % o.company_id.signature_scan" style="width:240px;height:200px;padding-bottom:5px;"/>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
<template id="cooperator_certificat_G001">
<t t-call="theme_light.html_container">
<t t-set="data_report_margin_top" t-value="10"/>
<t t-set="data_report_header_spacing" t-value="5"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-foreach="docs" t-as="o">
<t t-call="easy_my_coop.cooperator_certificat_G001_document" t-lang="o.lang"/>
</t>
</t>
</template>
</data>
</openerp>

255
easy_my_coop/report/cooperator_invoice_G002.xml

@ -0,0 +1,255 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="theme_invoice_G002_document">
<t t-call="theme_light.invoice_layout">
<t t-set="o" t-value="o.with_context({'lang':o.partner_id.lang})" />
<div class="page">
<head>
<link href="/easy_my_coop/static/src/css/coop_report.css" rel="stylesheet"/>
<style type="text/css">
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Roboto Regular */
@font-face {
font-family: 'Roboto-Regular';
font-style: normal;
src: local('Roboto Regular'), url('/theme_light/static/font/Roboto-Regular.ttf') format('truetype');
}
/* Roboto Bold */
@font-face {
font-family: 'Roboto-Bold';
font-style: normal;
src: local('Roboto Bold'), url('/theme_light/static/font/Roboto-Bold.ttf') format('truetype');
}
/* BEBASNEUE Bold */
@font-face {
font-family: 'Bebasneue-Bold';
font-style: normal;
src: local('Bebasneue-Bold'), url('/theme_light/static/font/BEBASNEUE_BOLD.ttf') format('truetype');
}
</style>
</head>
<t t-call="theme_light.invoice_header"/>
<div class="row">
<div class="col-xs-5 col-xs-offset-7 easymy-coop-address" style="top:90px;">
<address t-field="o.partner_id"
t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' />
<span t-if="o.partner_id.vat">TIN: <span t-field="o.partner_id.vat"/></span>
</div>
</div>
<div style="position:absolute; top:364px">
<h2 style="font-family:Bebasneue-Bold;font-size:20pt;line-height:14pt;">
<span t-if="o.release_capital_request == True">REQUEST TO RELEASE CAPITAL</span>
<span t-if="o.release_capital_request == False">
<span t-if="o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')">Invoice</span>
<span t-if="o.type == 'out_invoice' and o.state == 'proforma2'">PRO-FORMA</span>
<span t-if="o.type == 'out_invoice' and o.state == 'draft'">Draft Invoice</span>
<span t-if="o.type == 'out_invoice' and o.state == 'cancel'">Cancelled Invoice</span>
<span t-if="o.type == 'out_refund'">Refund</span>
<span t-if="o.type == 'in_refund'">Vendor Refund</span>
<span t-if="o.type == 'in_invoice'">Vendor Bill</span>
</span>
<span t-field="o.number"/>
<div style="width:220px;position:relative;top:10px;border-bottom: 4pt solid #e7511e;"/>
</h2>
<div class="row mt32 mb32 easymy-coop-info-title" style="top:102px;">
<div class="col-xs-2" t-if="o.name">
<strong>Description:</strong>
<p t-field="o.name"/>
</div>
<div class="col-xs-2" t-if="o.release_capital_request == True and o.date_invoice">
<strong>Request Date:</strong>
<p t-field="o.date_invoice"/>
</div>
<div class="col-xs-2" t-if="o.release_capital_request == False and o.date_invoice">
<strong>Invoice Date:</strong>
<p t-field="o.date_invoice"/>
</div>
<div class="col-xs-2" t-if="o.release_capital_request == False and (o.date_due and o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid'))">
<strong>Due Date:</strong>
<p t-field="o.date_due"/>
</div>
<div class="col-xs-2" t-if="o.release_capital_request == False and o.origin">
<strong>Source:</strong>
<p t-field="o.origin"/>
</div>
<div class="col-xs-2" t-if="o.release_capital_request == False and o.partner_id.ref">
<strong>Customer Code:</strong>
<p t-field="o.partner_id.ref"/>
</div>
<div name="reference" class="col-xs-3" t-if="o.reference">
<strong>Structured Communication:</strong>
<p t-field="o.reference"/>
</div>
<div name="account_number" class="col-xs-3">
<strong>Account Number:</strong>
<t t-foreach="o.company_id.bank_journal_ids" t-as="journal">
<t t-set="b" t-value="journal.bank_account_id"/>
<t t-if="o.release_capital_request == True and journal.get_cooperator_payment">
<span t-field="b.acc_number"/>
</t>
<t t-if="o.release_capital_request == False and journal.get_general_payment">
<span t-field="b.acc_number"/>
</t>
</t>
</div>
<br/>
<div name="contact" class="col-xs-3" t-if="o.user_id" style="position:relative;top:15px;">
<strong>Your contact:</strong>
<p t-field="o.user_id"/>
</div>
</div>
<!-- Is there a discount on at least one line? -->
<t t-set="display_discount" t-value="any([l.discount for l in o.invoice_line_ids])"/>
<table class="table border-easymy-coop" style="position:relative;top:85px;width:90%;align:center;">
<thead class="easymy-coop-info-title">
<tr>
<th>Description</th>
<th t-if="o.release_capital_request == True">Part Type</th>
<th class="text-right">Quantity</th>
<th class="text-right">Unit Price</th>
<th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th>
<th t-if="o.release_capital_request == False" class="text-right">Taxes</th>
<th class="text-right">Price</th>
</tr>
</thead>
<tbody class="invoice_tbody easymy-coop-normal">
<tr t-foreach="o.invoice_line_ids" t-as="l">
<td><span t-field="l.name"/></td>
<td t-if="o.release_capital_request == True">
<span t-field="l.product_id.short_name"/>
</td>
<td class="text-right">
<span t-if="l.quantity%1>0"><span t-esc='"%0.2f" % l.quantity'/></span>
<span t-if="l.quantity%1==0"><span t-esc='"%0.0f" % l.quantity'/></span>
<!-- <span t-field="l.quantity"/> -->
<span t-if="o.release_capital_request == False" t-field="l.uom_id" groups="product.group_uom"/>
</td>
<td class="text-right">
<span t-field="l.price_unit"/>
</td>
<td t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">
<span t-field="l.discount"/>
</td>
<td t-if="o.release_capital_request == False" class="text-right">
<span t-esc="', '.join(map(lambda x: (x.description or x.name), l.invoice_line_tax_ids))"/>
</td>
<td class="text-right">
<span t-field="l.price_subtotal"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-xs-4 pull-right">
<table class="table table-condensed easymy-coop-info-title" style="position:relative;top:130px;width:68%">
<tr t-if="o.release_capital_request == False">
<td><strong>Subtotal</strong></td>
<td class="text-right">
<span t-field="o.amount_untaxed" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
</td>
</tr>
<t t-if="o.release_capital_request == False">
<t t-foreach="o._get_tax_amount_by_group()" t-as="amount_by_group">
<tr>
<td><span t-esc="amount_by_group[0]"/></td>
<td class="text-right">
<span t-esc="amount_by_group[1]"/>
</td>
</tr>
</t>
</t>
<tr class="border-top-easymy-coop">
<td><strong>Total</strong></td>
<td class="text-right">
<span t-field="o.amount_total" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
</td>
</tr>
</table>
</div>
</div>
<div class="row" t-if="o.tax_line_ids">
<div class="col-xs-6">
<table class="table border-easymy-coop">
<thead>
<tr>
<th>Tax</th>
<th class="text-right">Base</th>
<th class="text-right">Amount</th>
</tr>
</thead>
<tbody>
<tr t-foreach="o.tax_line_ids" t-as="t">
<td>
<span t-field="t.name"/>
</td>
<td class="text-right">
<span t-field="t.base"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
</td>
<td class="text-right">
<span t-field="t.amount"
t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p t-if="o.comment">
<strong>Comment:</strong>
<span t-field="o.comment"/>
</p>
<p t-if="o.release_capital_request == False and o.payment_term_id">
<span t-field="o.payment_term_id.note"/>
</p>
<p t-if="o.release_capital_request == False and o.fiscal_position_id.note">
<strong>Fiscal Position Remark:</strong>
<span t-field="o.fiscal_position_id.note"/>
</p>
</div>
</div>
</t>
</template>
<template id="theme_invoice_G002">
<t t-call="theme_light.html_container">
<t t-set="data_report_margin_top" t-value="10"/>
<t t-set="data_report_header_spacing" t-value="5"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-foreach="docs" t-as="o">
<t t-call="easy_my_coop.theme_invoice_G002_document" t-lang="o.partner_id.lang"/>
</t>
</t>
</template>
<template id="report_sexy_invoice">
<t t-call="theme_light.html_container">
<t t-set="data_report_margin_top" t-value="10"/>
<t t-set="data_report_header_spacing" t-value="5"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-foreach="docs" t-as="o">
<t t-call="easy_my_coop.theme_invoice_G002_document" t-lang="o.partner_id.lang"/>
</t>
</t>
</template>
</data>
</openerp>

128
easy_my_coop/report/cooperator_register_G001.xml

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="cooperator_register_G001">
<t t-call="theme_light.html_container">
<t t-set="data_report_margin_top" t-value="5"/>
<t t-set="data_report_header_spacing" t-value="0"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-call="theme_light.report_layout_002">
<div class="page">
<head>
<link href="/theme_light/static/css/invoice_G002.css" rel="stylesheet"/>
</head>
<t t-call="theme_light.list_header_G002"/>
<br/><br/><br/><br/><br/>
<table class="title_table">
<tr>
<td>
<span class="color_text" t-esc="time.strftime('%Y-%m-%d')"/>
</td>
<td>
<div class="title_doc" style="font-size:16px">
<span>COOPERATOR REGISTER</span>
</div>
</td>
</tr>
</table>
<br/><br/><br/><br/><br/>
<table class="list_line_table_head" width="100%" >
<t t-set="total_quantity" t-value="0"/>
<t t-set="total_amount" t-value="0"/>
<br />
<tr>
<th width="15%" style="text-align: center;" >Number</th>
<th width="25%" style="text-align: center;" >Name</th>
<th width="20%" style="text-align: center;" >Email</th>
<th width="15%" style="text-align: center;" >Effective date</th>
<th width="10%" style="text-align: center;" >Quantity</th>
<th width="15%" style="text-align: center;" >Total</th>
</tr>
<t t-set="nb_ligne" t-value="0"/>
<t t-foreach="docs" t-as="partner">
<t t-set="new_partner" t-value="0"/>
<t t-foreach="partner.share_ids" t-as="line">
<t t-set="nb_ligne" t-value="nb_ligne+1"/>
<tr height="40px">
<div t-if="(nb_ligne%2)==1" >
<div t-if="(new_partner)==0">
<td class="lgn_impair" style="text-align:left;text-indent:20px;">
<span t-field="partner.cooperator_register_number" ></span>
</td>
<td style="text-align:left">
<span t-field="partner.name" ></span>
</td>
<td style="text-align:left">
<span t-field="partner.email" ></span>
</td>
</div>
<div t-if="(new_partner)!=0">
<td class="lgn_impair" style="text-align:left;text-indent:20px;" colspan="3">
</td>
</div>
<td>
<span t-field="line.effective_date" ></span>
</td>
<td>
<span t-field="line.share_number" ></span>
</td>
<td>
<span t-field="line.total_amount_line"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</div>
<div t-if="(nb_ligne%2)==0" >
<div t-if="(new_partner)==0" >
<td class="lgn_pair" style="text-align:left;text-indent:20px;background-color:#ffffff">
<span t-field="partner.cooperator_register_number" ></span>
</td>
<td class="lgn_pair" style="background-color:#ffffff;text-align:left">
<span t-field="partner.name" ></span>
</td>
<td class="lgn_pair" style="background-color:#ffffff;text-align:left">
<span t-field="partner.email" ></span>
</td>
</div>
<div t-if="(new_partner)!=0" style="background-color:#ffffff">
<td class="lgn_pair" style="text-align:left;text-indent:20px;background-color:#ffffff" colspan="3">
</td>
</div>
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.effective_date"> </span>
</td>
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.share_number" ></span>
</td>
<td class="lgn_pair" style="background-color:#ffffff">
<span t-field="line.total_amount_line"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</div>
</tr>
<t t-set="new_partner" t-value="new_partner+1"/>
</t>
</t>
</table>
</div>
</t>
</t>
</template>
</data>
</openerp>

110
easy_my_coop/report/cooperator_subscription_G001.xml

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="cooperator_subscription_G001">
<t t-call="theme_light.html_container">
<t t-set="data_report_margin_top" t-value="5"/>
<t t-set="data_report_header_spacing" t-value="0"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-call="theme_light.report_layout_002">
<div class="page">
<head>
<link href="/theme_light/static/css/invoice_G002.css" rel="stylesheet"/>
</head>
<t t-call="theme_light.list_header_G002"/>
<br/><br/><br/><br/><br/>
<table class="title_table">
<tr>
<td>
<span class="color_text" t-esc="time.strftime('%Y-%m-%d')"/>
</td>
<td>
<div class="title_doc" style="font-size:16px">
<span>SUBSCRIPTION REGISTER</span>
</div>
</td>
</tr>
</table>
<br/><br/><br/><br/><br/>
<table class="list_line_table_head" width="100%" >
<br />
<tr>
<th width="15%" style="text-align: center;" >Operation number</th>
<th width="30%" style="text-align: left;text-indent:15px" >Cooperator</th>
<th width="15%" style="text-align: center;" >Subscription date</th>
<th width="25%" style="text-align: center;" >Operation type</th>
<th width="15%" style="text-align: center;" >Share number</th>
</tr>
<t t-set="nb_ligne" t-value="0"/>
<p t-foreach="docs" t-as="transaction">
<t t-set="nb_ligne" t-value="nb_ligne+1"/>
<tr height="40px">
<div t-if="(nb_ligne%2)==1" >
<td class="lgn_impair" style="text-align:left;text-indent:10px">
<span t-field="transaction.register_number_operation" ></span>
</td>
<td style="text-align:left;text-indent:15px">
<span t-field="transaction.partner_id.name" ></span>
</td>
<td style="text-align:center">
<span t-field="transaction.date" ></span>
</td>
<td style="text-align:center">
<span t-field="transaction.type"/>
</td>
<td style="text-align:center">
<span t-field="transaction.quantity" ></span>
</td>
</div>
<div t-if="(nb_ligne%2)==0" >
<td class="lgn_pair" style="text-align:left;text-indent:10px;background-color:#ffffff">
<span t-field="transaction.register_number_operation" ></span>
</td>
<td class="lgn_pair" style="text-align:left;text-indent:15px;background-color:#ffffff">
<span t-field="transaction.partner_id.name" ></span>
</td>
<td style="text-align:center;background-color:#ffffff">
<span t-field="transaction.date" ></span>
</td>
<td style="text-align:center;background-color:#ffffff">
<span t-field="transaction.type"/>
</td>
<td style="text-align:center;background-color:#ffffff">
<span t-field="transaction.quantity" ></span>
</td>
</div>
</tr>
</p>
</table>
<table width="100%" >
<br />
<tr height="40px">
<th width="15%"></th>
<th width="30%"></th>
<th width="15%"></th>
<th class="total_table color_text" width="25%"> TOTAL : </th>
<th class="total_table" style="text-align:center" width="15%">
<span t-esc="sum(t.quantity for t in docs)"/>
</th>
</tr>
</table>
</div>
</t>
</t>
</template>
</data>
</openerp>

63
easy_my_coop/report/easy_my_coop_report.xml

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<report
id="action_cooperator_invoices"
model="account.invoice"
string="Capital release request"
report_type="qweb-pdf"
name="easy_my_coop.theme_invoice_G002"
file="easy_my_coop.cooperator_invoice_G002.xml"
attachment="(object.state in ('open','paid')) and ('SUBJ'+(object.number or '').replace('/','')+'.pdf')"
/>
<report
id="action_account_invoices"
model="account.invoice"
string="Invoices"
report_type="qweb-pdf"
name="easy_my_coop.report_sexy_invoice"
file="easy_my_coop.cooperator_invoice_G002.xml"
attachment_use="False"
attachment="(object.state in ('open','paid')) and ('INV'+(object.number or '').replace('/','')+'.pdf')"
/>
</data>
<data noupdate="1">
<report
id="action_cooperator_subscription_report"
model="subscription.register"
string="Subscription Register Report"
report_type="qweb-pdf"
name="easy_my_coop.cooperator_subscription_G001"
file="easy_my_coop.cooperator_subscription_G001.xml"
multi="True"
menu="True"
/>
<report
id="action_cooperator_report_certificat"
model="res.partner"
string="Cooperator certificat"
report_type="qweb-pdf"
name="easy_my_coop.cooperator_certificat_G001"
file="easy_my_coop.cooperator_certificat_G001.xml"
multi="True"
menu="True"
/>
<report
id="action_report_cooperator_register"
model="res.partner"
string="Cooperator register"
report_type="qweb-pdf"
name="easy_my_coop.cooperator_register_G001"
file="easy_my_coop.cooperator_register_G001.xml"
multi="True"
menu="True"
/>
</data>
</openerp>

31
easy_my_coop/security/easy_my_coop_security.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.module.category" id="module_category_cooperator_management">
<field name="name">EasyMy Coop</field>
<field name="description">Helps you manage your cooperator.</field>
<field name="sequence">3</field>
</record>
<record id="group_energiris_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="module_category_cooperator_management"/>
</record>
<record id="group_energiris_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id" ref="module_category_cooperator_management"/>
<field name="implied_ids" eval="[(4, ref('group_energiris_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
<record id="group_energiris_super_manager" model="res.groups">
<field name="name">Super Manager</field>
<field name="category_id" ref="module_category_cooperator_management"/>
<field name="implied_ids" eval="[(4, ref('group_energiris_manager'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
</data>
</openerp>

13
easy_my_coop/security/ir.model.access.csv

@ -0,0 +1,13 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_subscription_request,subscription.request,model_subscription_request,group_energiris_manager,1,1,1,0
access_res_partner,res.partner,model_res_partner,group_energiris_manager,1,1,1,0
access_share_line_employee,share.line,model_share_line,base.group_user,1,0,0,0
access_share_line_manager,share.line,model_share_line,group_energiris_manager,1,1,1,0
access_account_invoice,account.invoice,model_account_invoice,group_energiris_manager,1,1,1,0
access_subscription_register,subscription_register,model_subscription_register,group_energiris_manager,1,1,1,0
access_account_invoice_super_manager,account.invoice,model_account_invoice,group_energiris_super_manager,1,1,1,1
access_share_line_super_manager,share.line,model_share_line,group_energiris_super_manager,1,1,1,1
access_subscription_register_super_manager,subscription_register,model_subscription_register,group_energiris_super_manager,1,1,1,1
access_subscription_request_super_manager,subscription.request,model_subscription_request,group_energiris_super_manager,1,1,1,1
access_operation_request,operation.request,model_operation_request,group_energiris_manager,1,1,1,0
access_operation_request_super_manager,operation.request,model_operation_request,group_energiris_super_manager,1,1,1,1

27
easy_my_coop/static/src/css/coop_report.css

@ -0,0 +1,27 @@
.border-top-easymy-coop td {
border-top: 1pt solid #e7511e !important;
}
.border-easymy-coop th {
border-bottom: 1pt solid #e7511e !important;
}
.border-top-easymy-coop-cert td {
border-top: 1pt solid #fcc300 !important;
}
.border-easymy-coop-cert th {
border-bottom: 1pt solid #fcc300 !important;
}
.easymy-coop-normal {
font-family:Roboto-Regular;
font-size:12pt;
line-height:16pt;
}
.easymy-coop-info-title {
font-family:Roboto-Bold;
font-size:12pt;
line-height:16pt;
}

49
easy_my_coop/static/src/js/easy_my_coop.js

@ -0,0 +1,49 @@
odoo.define('easy_my_coop.oe_easymy_coop', function (require) {
$(document).ready(function () {
"use strict";
var ajax = require('web.ajax');
$('.oe_easymy_coop').each(function () {
var oe_easymy_coop = this;
$('#share_product_id').change(function () {
var share_product_id = $("#share_product_id").val();
ajax.jsonRpc("/subscription/get_share_product", 'call', {
'share_product_id': share_product_id
})
.then(function (data) {
$('#share_price').text(data[share_product_id].list_price);
$('input.js_quantity').val(data[share_product_id].min_qty);
$('input.js_quantity').change();
var $share_price = $('#share_price').text()
$('input[name="total_parts"]').val($('input.js_quantity').val()*$share_price);
$('input[name="total_parts"]').change();
});
});
$(oe_easymy_coop).on('click', 'a.js_add_cart_json', function (ev) {
var $share_price = $('#share_price').text()
var $link = $(ev.currentTarget);
var $input = $link.parent().parent().find("input");
var $input_total = $("div").find(".total");
var min = parseFloat($input.data("min") || 1);
var amount_max = parseFloat($('input[name="total_parts"]').data("max"));
var quantity = ($link.has(".fa-minus").length ? -1 : 1) + parseFloat($input.val(),10);
var total_part = quantity * $share_price;
var quantity_max = amount_max / $share_price;
$input.val(quantity > min ? (total_part <= amount_max ? quantity : quantity_max) : min);
$input.change();
$('input[name="total_parts"]').val($input.val()*$share_price);
return false;
});
$(oe_easymy_coop).on('focusout', 'input.js_quantity', function (ev) {
$('a.js_add_cart_json').trigger('click');
});
$('#share_product_id').trigger('change');
$("[name='birthdate']").inputmask();
});
});
});

66
easy_my_coop/view/account_invoice_view.xml

@ -0,0 +1,66 @@
<openerp>
<data>
<record id="action_invoice_tree_coop" model="ir.actions.act_window">
<field name="name">Cooperator Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field eval="False" name="view_id"/>
<field name="domain">[('type','in',('out_invoice', 'out_refund')),('release_capital_request','=',True)]</field>
<field name="context">{'default_type':'out_invoice', 'type':'out_invoice', 'journal_type': 'sale'}</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a cooperator invoice.
</p><p>
OpenERP's electronic invoicing allows to ease and fasten the
collection of cooperator payments. The cooperator customer receives the
invoice by email and he can pay online and/or import it
in his own system.
</p><p>
The discussions with the cooperator are automatically displayed at
the bottom of each invoice.
</p>
</field>
</record>
<record id="action_invoice_tree1_view1" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="act_window_id" ref="action_invoice_tree_coop"/>
</record>
<record id="action_invoice_tree1_view2" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="account.invoice_form"/>
<field name="act_window_id" ref="action_invoice_tree_coop"/>
</record>
<menuitem action="action_invoice_tree_coop" id="menu_action_invoice_tree_coop" parent="menu_easy_my_coop_main_coop" groups="easy_my_coop.group_energiris_user"/>
<record id="account.action_invoice_tree1" model="ir.actions.act_window">
<field name="name">Customer Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph</field>
<field eval="False" name="view_id"/>
<field name="domain">[('type','in',('out_invoice', 'out_refund')),('release_capital_request','=',False)]</field>
<field name="context">{'default_type':'out_invoice', 'type':'out_invoice', 'journal_type': 'sale'}</field>
<field name="search_view_id" ref="account.view_account_invoice_filter"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a customer invoice.
</p><p>
Odoo's electronic invoicing allows to ease and fasten the
collection of customer payments. Your customer receives the
invoice by email and he can pay online and/or import it
in his own system.
</p><p>
The discussions with your customer are automatically displayed at
the bottom of each invoice.
</p>
</field>
</record>
</data>
</openerp>

28
easy_my_coop/view/account_journal_view.xml

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_account_journal_form_coop" model="ir.ui.view">
<field name="name">account.journal.form</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='display_on_footer']" position="after">
<field name="get_cooperator_payment" groups="easy_my_coop.group_energiris_super_manager"/>
<field name="get_general_payment"/>
</xpath>
</field>
</record>
<record id="view_account_bank_journal_form_coop" model="ir.ui.view">
<field name="name">account.bank.journal.form</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_bank_journal_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='display_on_footer']" position="after">
<field name="get_cooperator_payment" groups="easy_my_coop.group_energiris_super_manager"/>
<field name="get_general_payment"/>
</xpath>
</field>
</record>
</data>
</odoo>

54
easy_my_coop/view/cooperator_register_view.xml

@ -0,0 +1,54 @@
<openerp>
<data>
<record id="subscription_register_tree" model="ir.ui.view">
<field name="name">subscription.register.tree</field>
<field name="model">subscription.register</field>
<field name="arch" type="xml">
<tree string="Subscription Register">
<field name="register_number_operation"/>
<field name="date"/>
<field name="partner_id"/>
<field name="share_short_name"/>
<field name="quantity" sum="Total quantity"/>
<field name="share_unit_price"/>
<field name="total_amount_line" sum="Total amount"/>
<field name="type"/>
</tree>
</field>
</record>
<record id="subscription_register_form" model="ir.ui.view">
<field name="name">subscription.register.form</field>
<field name="model">subscription.register</field>
<field name="arch" type="xml">
<form string="Subscription Register">
<group>
<group>
<field name="register_number_operation"/>
<field name="date"/>
<field name="share_short_name"/>
<field name="partner_id"/>
<field name="partner_id_to" attrs="{'invisible':[('type','!=','transfer')]}"/>
<field name="user_id" invisible="True"/>
</group>
<group>
<field name="type"/>
<field name="quantity"/>
<field name="share_unit_price"/>
<field name="total_amount_line"/>
</group>
</group>
</form>
</field>
</record>
<record id="subscription_register_action" model="ir.actions.act_window">
<field name="name">Subscription Register</field>
<field name="res_model">subscription.register</field>
<field name="view_type">form</field>
<field name="view_id" ref="subscription_register_tree"/>
</record>
<menuitem action="subscription_register_action" name="Subscription Register" id="menu_easy_my_coop_subscription_register" parent="menu_easy_my_coop_main_subscription" sequence="20"/>
</data>
</openerp>

16
easy_my_coop/view/email_template_view.xml

@ -0,0 +1,16 @@
<openerp>
<data>
<menuitem name="Configuration" id="menu_easy_my_coop_config" parent="menu_main_easy_my_coop" sequence="20"/>
<record model="ir.actions.act_window" id="action_easy_my_coop_email_templates">
<field name="name">Mail Templates</field>
<field name="res_model">mail.template</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="mail.email_template_tree" />
<field name="search_view_id" ref="mail.view_email_template_search"/>
</record>
<menuitem id="menu_easy_my_coop_templates" parent="menu_easy_my_coop_config" action="action_easy_my_coop_email_templates" sequence="10" groups="group_energiris_manager"/>
</data>
</openerp>

102
easy_my_coop/view/operation_request_view.xml

@ -0,0 +1,102 @@
<openerp>
<data>
<record id="operation_request_tree" model="ir.ui.view">
<field name="name">operation.request.tree</field>
<field name="model">operation.request</field>
<field name="arch" type="xml">
<tree string="Operation requests" colors="green:state in ('approved'); blue:state in ('draft');grey: state in ('done')">
<field name="request_date"/>
<field name="partner_id"/>
<field name="operation_type"/>
<field name="quantity"/>
<field name="user_id"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="operation_request_form" model="ir.ui.view">
<field name="name">operation.request.form</field>
<field name="model">operation.request</field>
<field name="arch" type="xml">
<form string="Operation request">
<header>
<button string="Submit" type="object" name="submit_operation" states="draft"/>
<button string="Approve" type="object" name="approve_operation" states="waiting"/>
<button string="Refuse" type="object" name="refuse_operation" states="waiting"/>
<button string="Cancel" type="object" name="cancel_operation" states="draft,waiting"/>
<button string="Draft" type="object" name="reset_to_draft" states="waiting,cancelled"/>
<button string="Execute" type="object" name="execute_operation" states="approved"/>
<field name="state" widget="statusbar" statusbar_visible="draft,done,cancelled,refused" statusbar_colors='{"draft":"grey","done":"green","cancelled":"orange","refused":"red"}'/>
</header>
<sheet>
<group>
<group>
<field name="request_date" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="operation_type" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="receiver_not_member" attrs="{'invisible':[('operation_type','!=','transfer')]}"/>
<field name="partner_id" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="partner_id_to" attrs="{'invisible':['|',('operation_type','!=','transfer'), ('receiver_not_member','=',True)]}"/>
</group>
<group>
<field name="user_id"/>
<field name="share_product_id" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="share_short_name" readonly="True"/>
<field name="quantity" attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="share_unit_price" readonly="True"/>
<field name="subscription_amount" attrs="{'readonly':[('state','!=','draft')]}"/>
</group>
</group>
<group>
<field name="subscription_request" attrs="{'invisible':['|',('operation_type','!=','transfer'),('receiver_not_member','=',False)]}" context="{'default_is_operation': True, 'default_share_product_id': share_product_id}">
<tree>
<field name="name"/>
<field name="no_registre"/>
<field name="birthdate"/>
<field name="phone"/>
<field name="email"/>
<field name="iban"/>
</tree>
<form string="Subscription Requests">
<sheet>
<group>
<group>
<field name="name"/>
<field name="firstname"/>
<field name="lastname"/>
<field name="birthdate"/>
<field name="gender"/>
<field name="email"/>
<field name="phone"/>
<field name="no_registre"/>
<field name="iban"/>
</group>
<group>
<field name="address"/>
<field name="zip_code"/>
<field name="city"/>
<field name="country_id"/>
<field name="lang"/>
<field name="validated"/>
<field name="skip_control_ng"/>
</group>
</group>
</sheet>
</form>
</field>
</group>
</sheet>
</form>
</field>
</record>
<record id="operation_request_action" model="ir.actions.act_window">
<field name="name">Operation request</field>
<field name="res_model">operation.request</field>
<field name="view_type">form</field>
<field name="view_id" ref="operation_request_tree"/>
</record>
<menuitem action="operation_request_action" name="Operation request" id="menu_easy_my_coop_operation_request" parent="menu_easy_my_coop_main_subscription" sequence="20" groups="easy_my_coop.group_energiris_manager"/>
</data>
</openerp>

143
easy_my_coop/view/product_view.xml

@ -0,0 +1,143 @@
<openerp>
<data>
<record id="product_template_share_form_view" model="ir.ui.view">
<field name="name">product.template.share.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="purchase.view_product_supplier_inherit"/>
<field name="arch" type="xml">
<xpath expr="//label[@for='purchase_ok']/.." position="after">
<div groups="easy_my_coop.group_energiris_super_manager">
<field name="is_share"/>
<label for="is_share"/>
</div>
<div attrs="{'invisible':[('is_share','=',False)]}" groups="easy_my_coop.group_energiris_user">
<field name="display_on_website"/>
<label for="display_on_website"/>
</div>
</xpath>
</field>
</record>
<record id="product_template_form_view" model="ir.ui.view">
<field name="name">product.template.common.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='type']" position="after">
<field name="short_name" attrs="{'invisible':[('is_share','=',False)]}" groups="easy_my_coop.group_energiris_user"/>
<field name="default_share_product" attrs="{'invisible':[('is_share','=',False)]}" groups="easy_my_coop.group_energiris_user"/>
<field name="minimum_quantity" attrs="{'invisible':[('is_share','=',False)]}" groups="easy_my_coop.group_energiris_user"/>
<field name="by_company" attrs="{'invisible':[('is_share','=',False)]}" groups="easy_my_coop.group_energiris_user"/>
<field name="by_individual" attrs="{'invisible':[('is_share','=',False)]}" groups="easy_my_coop.group_energiris_user"/>
</xpath>
</field>
</record>
<record id="share_product_action" model="ir.actions.act_window">
<field name="name">Share type</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<!-- <field name="context">{"search_default_filter_to_purchase":1}</field> -->
<field name="search_view_id" eval="False"/> <!-- Force empty -->
<field name="view_id" eval="False"/> <!-- Force empty -->
<field name="domain">[('is_share','=',True)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new share product.
</p>
</field>
</record>
<menuitem action="share_product_action" name="Share type" id="menu_easy_my_coop_share_product" parent="menu_easy_my_coop_main_subscription" sequence="20"/>
<!-- overriding product views to not display share product in the purchase and sale views-->
<record id="product.product_normal_action" model="ir.actions.act_window">
<field name="name">Product</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.product</field>
<field name="view_mode">tree,form,kanban</field>
<field name="view_type">form</field>
<field name="search_view_id" ref="product.product_search_form_view"/>
<field name="view_id" eval="False"/> <!-- Force empty -->
<field name="domain">[('is_share','=',False)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new product.
</p><p>
You must define a product for everything you sell, whether it's
a physical product, a consumable or a service you offer to
customers.
</p><p>
The product form contains information to simplify the sale
process: price, notes in the quotation, accounting data,
procurement methods, etc.
</p>
</field>
</record>
<record id="product.product_template_action" model="ir.actions.act_window">
<field name="name">Products</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_type">form</field>
<field name="view_id" ref="product.product_template_kanban_view"/>
<field name="context">{"search_default_filter_to_sell":1}</field>
<field name="domain">[('is_share','=',False)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new product.
</p><p>
You must define a product for everything you sell, whether it's a physical product, a consumable or a service you offer to customers.
</p><p>
The product form contains information to simplify the sale process: price, notes in the quotation, accounting data, procurement methods, etc.
</p>
</field>
</record>
<record id="product.product_template_action_product" model="ir.actions.act_window">
<field name="name">Products</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_type">form</field>
<field name="context">{"search_default_products": 1, 'default_type': 'product'}</field>
<field name="domain">[('is_share','=',False)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new product.
</p>
</field>
</record>
<record id="product.product_normal_action_puchased" model="ir.actions.act_window">
<field name="name">Products</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="context">{"search_default_filter_to_purchase":1}</field>
<field name="search_view_id" eval="False"/> <!-- Force empty -->
<field name="view_id" eval="False"/> <!-- Force empty -->
<field name="domain">[('is_share','=',False)]</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new product.
</p><p>
You must define a product for everything you purchase, whether
it's a physical product, a consumable or services you buy to
subcontractants.
</p><p>
The product form contains detailed information to improve the
purchase process: prices, procurement logistics, accounting data,
available vendors, etc.
</p>
</field>
</record>
</data>
</openerp>

25
easy_my_coop/view/res_company_view.xml

@ -0,0 +1,25 @@
<openerp>
<data>
<record model="ir.ui.view" id="view_company_inherit_form2">
<field name="name">res.company.form.easymy.coop</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="model">res.company</field>
<field name="arch" type="xml">
<xpath expr="//group[@name='account_grp']" position="after">
<group name="coop_grp" string="EasyMy Coop" groups="easy_my_coop.group_energiris_manager">
<field name="unmix_share_type"/>
<field name="display_logo1"/>
<field name="display_logo2"/>
<field name="coop_email_contact"/>
<field name="subscription_maximum_amount"/>
<field name="property_cooperator_account"/>
<field name="default_country_id"/>
<field name="default_lang_id"/>
<field name="board_representative"/>
<field name="signature_scan"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>

115
easy_my_coop/view/res_partner_view.xml

@ -0,0 +1,115 @@
<openerp>
<data>
<record id="view_partner_form_easy_my_coop" model="ir.ui.view">
<field name="name">res.partner.form.easy_my_coop</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/group" position='before'>
<group>
<field name="cooperator_register_number" readonly="True" attrs="{'invisible':[('member','=',False)]}"/>
<field name="cooperator" groups="easy_my_coop.group_energiris_super_manager"/>
<field name="member" groups="easy_my_coop.group_energiris_super_manager"/>
<field name="cooperator_type"/>
<field name="effective_date"/>
</group>
<group>
<field name="birthdate" attrs="{'invisible':[('is_company','=',True)]}"/>
<field name="gender"/>
</group>
</xpath>
<xpath expr="//page[@name='sales_purchases']" position='after'>
<page string="Shares" name="share" attrs="{'invisible':[('member','=',False)]}" groups="easy_my_coop.group_energiris_user">
<group>
<field name="number_of_share"/>
<field name="total_value"/>
</group>
<field name="share_ids">
<tree>
<field name="effective_date"/>
<field name="share_short_name"/>
<field name="share_number" sum="Total of shares"/>
<field name="share_unit_price"/>
<field name="total_amount_line" sum="Total subscribed amount"/>
</tree>
</field>
</page>
</xpath>
</field>
</record>
<record id="view_partner_tree_easy_my_coop" model="ir.ui.view">
<field name="name">res.partner.tree.easy_my_coop</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field name="arch" type="xml">
<xpath expr="/tree/field[@name='display_name']" position='after'>
<field name="cooperator_register_number" />
<field name="cooperator_type"/>
<field name="effective_date"/>
</xpath>
</field>
</record>
<record id="view_res_partner_filter_coop" model="ir.ui.view">
<field name="name">res.partner.select</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='supplier']" position='after'>
<filter string="Cooperators" name="cooperator" domain="[('cooperator','=',1)]" help="Cooperator Partners"/>
</xpath>
<filter name="salesperson" position="before">
<filter name="Cooperator Type" context="{'group_by': 'cooperator_type'}"/>
</filter>
</field>
</record>
<menuitem name="Cooperators" id="menu_easy_my_coop_main_coop" parent="menu_main_easy_my_coop" sequence="5" />
<record id="action_partner_cooperator_form" model="ir.actions.act_window">
<field name="name">Cooperator</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[('cooperator','=',True),('member','=',True)]</field>
<field name="context">{'default_cooperator':1, 'search_default_cooperator':1}</field>
<field name="filter" eval="True"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a contact in your address book.
</p><p>
OpenERP helps you easily track all activities related to
a cooperator: discussions, history of business opportunities,
documents, etc.
</p>
</field>
</record>
<menuitem id="menu_easy_my_coop_cooperator" name="Cooperators" parent="menu_easy_my_coop_main_coop" action="action_partner_cooperator_form" sequence="100"/>
<record id="action_partner_cooperator_candidate_form" model="ir.actions.act_window">
<field name="name">Cooperator</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner</field>
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[('cooperator','=',True),('member','=',False)]</field>
<field name="context">{'default_cooperator':1, 'search_default_cooperator':1}</field>
<field name="filter" eval="True"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to add a contact in your address book.
</p><p>
OpenERP helps you easily track all activities related to
a cooperator: discussions, history of business opportunities,
documents, etc.
</p>
</field>
</record>
<menuitem id="menu_easy_my_coop_cooperator_candidate" name="Cooperator Candidates" parent="menu_easy_my_coop_main_coop" action="action_partner_cooperator_candidate_form" sequence="150"/>
</data>
</openerp>

154
easy_my_coop/view/subscription_request_view.xml

@ -0,0 +1,154 @@
<openerp>
<data>
<menuitem name="Easy-My Coop" id="menu_main_easy_my_coop" sequence="40" groups="easy_my_coop.group_energiris_user"/>
<menuitem name="Subscription" id="menu_easy_my_coop_main_subscription" parent="menu_main_easy_my_coop" sequence="10" groups="easy_my_coop.group_energiris_manager"/>
<record id="subscription_request_tree" model="ir.ui.view">
<field name="name">subscription.request.tree</field>
<field name="model">subscription.request</field>
<field name="arch" type="xml">
<tree string="Cooperator Subscriptions Request" colors="red:validated == False; blue:state in ('draft');grey: state in ('done')">
<field name="name"/>
<field name="date" string="Request Date"/>
<field name="type"/>
<field name="share_short_name" string="Share Type"/>
<field name="ordered_parts" string="Quantity" sum="Total ordered parts"/>
<field name="subscription_amount" sum="Total amount"/>
<field name="email"/>
<field name="iban"/>
<field name="partner_id"/>
<field name="state"/>
<field name="validated" invisible="True"/>
<button type="object" name="validate_subscription_request" attrs="{'invisible':['|',('state','!=','draft'),('validated','=',False)]}" icon="STOCK_MEDIA_PLAY" />
<button type="object" name="block_subscription_request" states="draft" groups="easy_my_coop.group_energiris_user" icon="gtk-cancel"/>
<button type="object" name="unblock_subscription_request" states="block" groups="easy_my_coop.group_energiris_manager" icon="gtk-jump-to"/>
</tree>
</field>
</record>
<record id="subscription_request_form" model="ir.ui.view">
<field name="name">subscription.request.form</field>
<field name="model">subscription.request</field>
<field name="arch" type="xml">
<form string="Subscription Requests">
<header>
<button string="Validate" type="object" name="validate_subscription_request" attrs="{'invisible':['|',('state','!=','draft'),('validated','=',False)]}"/>
<button string="Cancel" type="object" name="cancel_subscription_request" states="draft,done,block" groups="easy_my_coop.group_energiris_manager"/>
<field name="state" widget="statusbar" statusbar_visible="draft,cancelled,done,failed"/>
</header>
<sheet>
<group>
<group>
<field name="already_cooperator"/>
<field name="is_company" invisible="True"/>
<field name="is_operation" invisible="True"/>
<field name="company_name" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="company_email" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="company_type" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="company_register_number" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="name"/>
<field name="firstname"/>
<field name="lastname"/>
<field name="birthdate"/>
<field name="gender"/>
<field name="email"/>
<field name="phone"/>
<field name="contact_person_function" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="no_registre"/>
<field name="iban"/>
<field name="address"/>
<field name="zip_code"/>
<field name="city"/>
<field name="country_id"/>
</group>
<group>
<field name="date"/>
<field name="activities_address" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="activities_zip_code" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="activities_city" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="activities_country_id" attrs="{'invisible':[('is_company','=',False)]}"/>
<field name="ordered_parts"/>
<field name="share_product_id"/>
<field name="share_short_name"/>
<field name="share_unit_price"/>
<field name="subscription_amount"/>
<field name="partner_id"/>
<field name="type"/>
<field name="lang"/>
<field name="validated"/>
<field name="skip_control_ng"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_subscription_request_filter" model="ir.ui.view">
<field name="name">Cooperator Subscription Search</field>
<field name="model">subscription.request</field>
<field name="arch" type="xml">
<search string="Search Subscription Request">
<field name="name"
filter_domain="['|',('name','ilike',self),('email','ilike',self)]"/>
<separator/>
<filter string="draft" name="state_draft" domain="[('state','=','draft')]"/>
<filter string="done" name="state_done" domain="[('state','=','done')]"/>
<separator/>
<filter string="Unvalid" name="Unvalid" domain="[('validated', '=', False)]"/>
<group expand="0" name="group_by" string="Group By">
<filter string="Request type" context="{'group_by' : 'type'}" />
<!-- <filter string="Part type" context="{'group_by': 'share_short_name'}"/> -->
<filter string="Date Month" context="{'group_by': 'date'}"/>
</group>
</search>
</field>
</record>
<record id="subscription_request_action" model="ir.actions.act_window">
<field name="name">Cooperator Subscription</field>
<field name="res_model">subscription.request</field>
<field name="view_type">form</field>
<field name="domain">[('is_company','=',False),('is_operation','=',False)]</field>
<field name="view_id" ref="subscription_request_tree"/>
<field name="search_view_id" ref="view_subscription_request_filter"/>
</record>
<menuitem action="subscription_request_action" name="Cooperator Subscription" id="menu_easy_my_coop_subscription_request" parent="menu_easy_my_coop_main_subscription" sequence="10"/>
<record id="company_subscription_request_tree" model="ir.ui.view">
<field name="name">subscription.request.tree</field>
<field name="model">subscription.request</field>
<field name="arch" type="xml">
<tree string="Company Cooperator Subscriptions Request" colors="red:validated == False; blue:state in ('draft');grey: state in ('done')">
<field name="company_name"/>
<field name="name"/>
<field name="date" string="Request Date"/>
<field name="type"/>
<field name="share_short_name" string="Share Type"/>
<field name="ordered_parts" string="Quantity" sum="Total ordered parts"/>
<field name="subscription_amount" sum="Total amount"/>
<field name="email"/>
<field name="iban"/>
<field name="partner_id"/>
<field name="state"/>
<field name="validated" invisible="True"/>
<button type="object" name="validate_subscription_request" attrs="{'invisible':['|',('state','!=','draft'),('validated','=',False)]}" icon="STOCK_MEDIA_PLAY"/>
<button type="object" name="block_subscription_request" states="draft" groups="easy_my_coop.group_energiris_user" icon="gtk-cancel"/>
<button type="object" name="unblock_subscription_request" states="block" groups="easy_my_coop.group_energiris_manager" icon="gtk-jump-to"/>
</tree>
</field>
</record>
<record id="company_subscription_request_action" model="ir.actions.act_window">
<field name="name">Company Subscription</field>
<field name="res_model">subscription.request</field>
<field name="view_type">form</field>
<field name="domain">[('is_company','=',True),('is_operation','=',False)]</field>
<field name="view_id" ref="company_subscription_request_tree"/>
<field name="search_view_id" ref="view_subscription_request_filter"/>
</record>
<menuitem action="company_subscription_request_action" name="Company Subscription" id="menu_easy_my_coop_company_subscription_request" parent="menu_easy_my_coop_main_subscription" sequence="12"/>
</data>
</openerp>

566
easy_my_coop/view/subscription_template.xml

@ -0,0 +1,566 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="assets_frontend" inherit_id="website.assets_frontend" name="Coop">
<xpath expr="." position="inside">
<script type="text/javascript" src="/easy_my_coop/static/src/js/easy_my_coop.js"></script>
<script type="text/javascript" src="/easy_my_coop/static/src/lib/jquery.inputmask.bundle.js"></script>
</xpath>
</template>
<template id="cooperator_thanks" name="Cooperator contact us" page="True">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure"/>
<div class="container">
<h1>Thanks!</h1>
<div class="row">
<div class="col-md-8">
<div class="alert alert-success">
Your subscription has been successfully registered.
<button type="button" class="close" data-dismiss="alert">&amp;times;</button>
</div>
<p>
We will get back to you shortly.
</p>
<ul class="list-unstyled">
<li><i class="fa fa-phone"></i> : <span t-field="res_company.phone"/></li>
<li><i class="fa fa-envelope"></i> : <span t-field="res_company.email"/></li>
</ul>
</div>
<div class="col-md-4">
<t t-call="website.company_description"/>
</div>
</div>
</div>
<div class="oe_structure"/>
</div>
</t>
</template>
<template id="easy_my_coop.becomecooperator" name="Become Cooperator" page="True">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure"/>
<div class="container oe_easymy_coop">
<h2 class="energie">Become Cooperator</h2><br/>
<div class="row">
<div class="col-md-8">
<form action="/subscription/subscribe_share" method="post" class="form-horizontal mt32" enctype="multipart/form-data">
<p style="color:red;"><t t-esc="error_msg"/></p>
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<div t-attf-class="form-group">
<label>
<input type="checkbox" t-att-value="already_cooperator" name="already_cooperator" />
Already cooperator?
</label>
</div>
<div name="email_from_container" t-attf-class="form-group #{error and 'email_from' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="email">Email</label>
<div class="col-md-7 col-sm-8 bottom-line" style="padding-bottom:20px">
<input type="email" class="form-control mandatory-field" name="email" required="True" t-attf-value="#{email or ''}" placeholder="didier.bourdon@bees-coop.be"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'firstname' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="name">First Name</label>
<div class="col-md-7 col-sm-8" style="padding-top:5px">
<input type="text" class="form-control mandatory-field" name="firstname" required="True" t-attf-value="#{firstname or ''}" placeholder="Didier"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'lastname' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="name">Last Name</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="lastname" required="True" t-attf-value="#{lastname or ''}" placeholder="Bourdon"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'gender' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="company_type">Gender</label>
<select name="gender" class="col-md-7 col-sm-8 form-control" required="True" style="width:54%;margin-left:15px">
<option value=""></option>
<t t-foreach="genders or []" t-as="type">
<option t-att-value="type[0]" t-att-selected="type[0] == gender"><t t-esc="type[1]"/></option>
</t>
</select>
</div>
<div t-attf-class="form-group #{error and 'birthdate' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="birthdate">Birthdate</label>
<div class="col-md-7 col-sm-8">
<input type="text" data-inputmask="'alias': 'date'" class="form-control mandatory-field" name="birthdate" required="True" t-attf-value="#{birthdate or ''}" placeholder="05/03/1978"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'no_registre' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="no_registre">National Register Number</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="no_registre" t-attf-value="#{no_registre or ''}" placeholder="78230226321"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'iban' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="iban">Bank Account Number</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="iban" required="True" t-attf-value="#{iban or ''}" placeholder="BE48523080767127"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'lang' in error and 'has-error' or ''}" >
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="lang">Language</label>
<select name="lang" class="col-md-7 col-sm-8 form-control " style="width:30%;margin-left:15px">
<option value="2">Language...</option>
<t t-foreach="langs or []" t-as="langue">
<option t-att-value="langue.code" t-att-selected="langue.code == lang"><t t-esc="langue.name"/></option>
</t>
</select>
<br/>
<div class="bottom-line" style="margin-left:25%;margin-top:35px;width:59%"></div>
</div>
<div t-attf-class="form-group #{error and 'address' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="address">Address</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="address" required="True" t-attf-value="#{address or ''}" placeholder="rue Van Hove, 19"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'zip_code' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="zip_code">City</label>
<div class="col-md-7 col-sm-8">
<table>
<tr>
<td width="20%">
<input type="text" class="form-control mandatory-field" name="zip_code" required="True" t-attf-value="#{zip_code or ''}" placeholder="1030"/>
</td>
<td width="3%"></td>
<td>
<input type="text" class="form-control mandatory-field" name="city" required="True" t-attf-value="#{city or ''}" placeholder="Bruxelles"/>
</td>
</tr>
</table>
</div>
</div>
<div t-attf-class="form-group #{error and 'country_id' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="country_id">Country</label>
<select name="country_id" class="col-md-7 col-sm-8 form-control " style="width:54%;margin-left:15px">
<option value="">Country...</option>
<t t-foreach="countries or []" t-as="country">
<option t-att-value="country.id" t-att-selected="country.id == int(country_id)"><t t-esc="country.name"/></option>
</t>
</select>
</div>
<div t-attf-class="form-group #{error and 'phone' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="phone">Phone</label>
<div class="col-md-7 col-sm-8 bottom-line" style="padding-bottom:20px">
<input type="text" class="form-control" name="phone" required="True" t-attf-value="#{phone or ''}" placeholder="e.g. (+32).81.81.37.00"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'product_id' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="country_id">Parts type</label>
<select id="share_product_id" name="share_product_id" class="col-md-7 col-sm-8 form-control " style="width:54%;margin-left:15px">
<t t-foreach="products or []" t-as="product">
<option t-att-value="product.id" t-att-selected="product.id == int(share_product_id)"><t t-esc="product.short_name"/></option>
</t>
</select>
</div>
<div name="share_div" class="form-group">
<table style="width:80%">
<tr>
<td width="30%">
<label style="text-align:right; width:100%;padding-right:30px">Parts number</label>
</td>
<td width="15%">
<div class="css_quantity input-group oe_website_spinner">
<span class="input-group-addon" style="margin-left:0px">
<a t-attf-href="#" class="mb8 js_add_cart_json">
<i class="fa fa-minus"></i>
</a>
</span>
<input type="text" class="js_quantity form-control" data-min="1" name="ordered_parts" t-attf-value="#{ordered_parts or 1}"/>
<span class="input-group-addon">
<a t-attf-href="#" class="mb8 float_left js_add_cart_json">
<i class="fa fa-plus"></i>
</a>
</span>
</div>
</td>
<td width="5%">x </td>
<td id="share_price" width="7%">25</td>
<td width="3%"></td>
<td width="5%">= </td>
<td width="20%">
<div style="margin-top:12px" t-attf-class="form-group #{error and 'total_parts' in error and 'has-error' or ''}">
<div>
<input type="text" class="form-control total" name="total_parts" value="25" data-max="5000"
t-att-readonly="'readonly'"
/>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="bottom-line" style="margin-left:178px;margin-top:0px;width:61%"></div>
<br/>
<table style="margin-left:195px">
<tr>
<td width="80%">
<div class="g-recaptcha" t-att-data-sitekey="website.recaptcha_site_key" data-theme="green"/><br/>
</td>
<td>
<div class="form-group">
<div class="col-md-offset-3 col-sm-offset-4 col-sm-8 col-md-7">
<button class="btn btn-primary btn-lg">Send</button>
</div>
</div>
</td>
</tr>
</table>
<br/>
</form>
</div>
</div>
</div>
<div class="oe_structure"/>
</div>
</t>
</template>
<template id="easy_my_coop.becomecompanycooperator" name="Become Cooperator" page="True">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure"/>
<div class="container oe_easymy_coop">
<h2 class="energie">Become Cooperator</h2><br/>
<div class="row">
<div class="col-md-8">
<form action="/subscription/subscribe_share" method="post" class="form-horizontal mt32" enctype="multipart/form-data">
<p style="color:red;"><t t-esc="error_msg"/></p>
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<div t-attf-class="form-group" style="display: none;">
<label>
<input type="checkbox" t-att-value="company" checked="checked" name="is_company" />
Is a company?
</label>
</div>
<div t-attf-class="form-group">
<label>
Company Info
</label>
</div>
<div t-attf-class="form-group #{error and 'company_register_number' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="no_registre">Company Register Number</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="company_register_number" required="True" t-attf-value="#{company_register_number or ''}" placeholder="0647980091"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'company_name' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="company_name">Company name</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="company_name" required="True" t-attf-value="#{company_name or ''}" placeholder="La super coopérative"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'company_type' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="company_type">Company type</label>
<select name="company_type" class="col-md-7 col-sm-8 form-control" required="True" style="width:54%;margin-left:15px">
<option value=""></option>
<t t-foreach="company_types or []" t-as="type">
<option t-att-value="type[0]" t-att-selected="type[0] == company_type"><t t-esc="type[1]"/></option>
</t>
</select>
</div>
<div t-attf-class="form-group #{error and 'company_email' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="company_email">Company email</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="company_email" required="True" t-attf-value="#{company_email or ''}" placeholder="administration@beescoop.be"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'iban' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="iban">Bank Account Number</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="iban" required="True" t-attf-value="#{iban or ''}" placeholder="BE48523080767127"/>
</div>
</div>
<br/>
<div t-attf-class="form-group">
<label>
Main Address
</label>
</div>
<div t-attf-class="form-group #{error and 'address' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="address">Address</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="address" required="True" t-attf-value="#{address or ''}" placeholder="rue Van Hove, 19"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'zip_code' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="zip_code">City</label>
<div class="col-md-7 col-sm-8">
<table>
<tr>
<td width="20%">
<input type="text" class="form-control mandatory-field" name="zip_code" required="True" t-attf-value="#{zip_code or ''}" placeholder="1030"/>
</td>
<td width="3%"></td>
<td>
<input type="text" class="form-control mandatory-field" name="city" required="True" t-attf-value="#{city or ''}" placeholder="Bruxelles"/>
</td>
</tr>
</table>
</div>
</div>
<div t-attf-class="form-group #{error and 'country_id' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="country_id">Country</label>
<select name="country_id" class="col-md-7 col-sm-8 form-control" style="width:54%;margin-left:15px">
<option value="">Country...</option>
<t t-foreach="countries or []" t-as="country">
<option t-att-value="country.id" t-att-selected="country.id == int(country_id)"><t t-esc="country.name"/></option>
</t>
</select>
</div>
<br/>
<div t-attf-class="form-group">
<label>
Operational Address
</label>
</div>
<div t-attf-class="form-group #{error and 'activities_address' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="activities_address">Address</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="activities_address" required="True" t-attf-value="#{activities_address or ''}" placeholder="rue du brochet, 48"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'activities_zip_code' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="activities_zip_code">City</label>
<div class="col-md-7 col-sm-8">
<table>
<tr>
<td width="20%">
<input type="text" class="form-control mandatory-field" name="activities_zip_code" required="True" t-attf-value="#{activities_zip_code or ''}" placeholder="1080"/>
</td>
<td width="3%"></td>
<td>
<input type="text" class="form-control mandatory-field" name="activities_city" required="True" t-attf-value="#{activities_city or ''}" placeholder="Bruxelles"/>
</td>
</tr>
</table>
</div>
</div>
<div t-attf-class="form-group #{error and 'activities_country_id' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="activities_country_id">Country</label>
<select name="activities_country_id" class="col-md-7 col-sm-8 form-control" style="width:54%;margin-left:15px">
<option value="">Country...</option>
<t t-foreach="countries or []" t-as="country">
<option t-att-value="country.id" t-att-selected="country.id == int(activities_country_id)"><t t-esc="country.name"/></option>
</t>
</select>
</div>
<br/>
<div t-attf-class="form-group">
<label>
Contact Person
</label>
</div>
<div t-attf-class="form-group #{error and 'firstname' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="firstname">First Name</label>
<div class="col-md-7 col-sm-8" style="padding-top:5px">
<input type="text" class="form-control mandatory-field" name="firstname" required="True" t-attf-value="#{firstname or ''}" placeholder="Didier"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'lastname' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="lastname">Last Name</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="lastname" required="True" t-attf-value="#{lastname or ''}" placeholder="Bourdon"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'gender' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="company_type">Gender</label>
<select name="gender" class="col-md-7 col-sm-8 form-control" required="True" style="width:54%;margin-left:15px">
<option value=""></option>
<t t-foreach="genders or []" t-as="type">
<option t-att-value="type[0]" t-att-selected="type[0] == gender"><t t-esc="type[1]"/></option>
</t>
</select>
</div>
<div name="email_from_container" t-attf-class="form-group #{error and 'email_from' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="email">Email</label>
<div class="col-md-7 col-sm-8 bottom-line" style="padding-bottom:20px">
<input type="email" class="form-control mandatory-field" name="email" required="True" t-attf-value="#{email or ''}" placeholder="didier.bourdon@bees-coop.be"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'phone' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="phone">Phone</label>
<div class="col-md-7 col-sm-8 bottom-line" style="padding-bottom:20px">
<input type="text" class="form-control" name="phone" required="True" t-attf-value="#{phone or ''}" placeholder="e.g. (+32).81.81.37.00"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'contact_person_function' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="contact_person_function">Function</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="contact_person_function" required="True" t-attf-value="#{lastname or ''}" placeholder="Bourdon"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'no_registre' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="no_registre">National Register Number</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control mandatory-field" name="no_registre" required="True" t-attf-value="#{no_registre or ''}" placeholder="78230226321"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'birthday' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="birthdate">Birthdate</label>
<div class="col-md-7 col-sm-8">
<input type="text" data-inputmask="'alias': 'date'" class="form-control mandatory-field" name="birthdate" required="True" t-attf-value="#{birthdate or ''}" placeholder="05/03/1978"/>
</div>
</div>
<div t-attf-class="form-group #{error and 'lang' in error and 'has-error' or ''}" >
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="lang">Language</label>
<select name="lang" class="col-md-7 col-sm-8 form-control " style="width:30%;margin-left:15px">
<option value="2">Language...</option>
<t t-foreach="langs or []" t-as="langue">
<option t-att-value="langue.code" t-att-selected="langue.code == lang"><t t-esc="langue.name"/></option>
</t>
</select>
<br/>
<div class="bottom-line" style="margin-left:25%;margin-top:35px;width:59%"></div>
</div>
<div t-attf-class="form-group #{error and 'product_id' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="share_product_id">Parts type</label>
<select id="share_product_id" name="share_product_id" class="col-md-7 col-sm-8 form-control " style="width:54%;margin-left:15px">
<t t-foreach="products or []" t-as="product">
<option t-att-value="product.id" t-att-selected="product.id == int(share_product_id)"><t t-esc="product.short_name"/></option>
</t>
</select>
</div>
<div class="form-group">
<table style="width:80%">
<tr>
<td width="30%">
<label style="text-align:right; width:100%;padding-right:30px">Parts number</label>
</td>
<td width="15%">
<div class="css_quantity input-group oe_website_spinner">
<span class="input-group-addon" style="margin-left:0px">
<a t-attf-href="#" class="mb8 js_add_cart_json">
<i class="fa fa-minus"></i>
</a>
</span>
<input type="text" class="js_quantity form-control" data-min="1" name="ordered_parts" t-attf-value="#{ordered_parts or 1}"/>
<span class="input-group-addon">
<a t-attf-href="#" class="mb8 float_left js_add_cart_json">
<i class="fa fa-plus"></i>
</a>
</span>
</div>
</td>
<td width="5%">x </td>
<td id="share_price" width="7%">25</td>
<td width="3%"></td>
<td width="5%">= </td>
<td width="20%">
<div style="margin-top:12px" t-attf-class="form-group #{error and 'total_parts' in error and 'has-error' or ''}">
<div>
<input type="text" class="form-control total" name="total_parts" value="25" data-max="5000"
t-att-readonly="'readonly'"
/>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="bottom-line" style="margin-left:178px;margin-top:0px;width:61%"></div>
<br/>
<table style="margin-left:195px">
<tr>
<td width="80%">
<div class="g-recaptcha" t-att-data-sitekey="website.recaptcha_site_key" data-theme="green"/><br/>
</td>
<td>
<div class="form-group">
<div class="col-md-offset-3 col-sm-offset-4 col-sm-8 col-md-7">
<button class="btn btn-primary btn-lg">Send</button>
</div>
</div>
</td>
</tr>
</table>
<br/>
</form>
</div>
</div>
</div>
<div class="oe_structure"/>
</div>
</t>
</template>
<record id="menu_becomecooperator" model="website.menu">
<field name="name">Become cooperator</field>
<field name="url">/page/become_cooperator</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">65</field>
</record>
<template id="footer_coop_email_contact" inherit_id="website.footer_default" customize_show="True" name="Coop email contact">
<xpath expr="//span[@t-field='res_company.email']" position="replace">
<span t-field="res_company.coop_email_contact"></span>
</xpath>
</template>
<template id="company_description_coop_email_contact" inherit_id="website.company_description" name="Company Description Email Contact">
<xpath expr="//div[@t-field='res_company.partner_id']" position="replace">
<div t-field="res_company.partner_id" t-field-options='{
"widget": "contact",
"fields": ["name", "address", "phone", "mobile", "fax"]}'/>
<ul class="list-unstyled">
<li t-ignore="true"><i class="fa fa-envelope"></i><span t-field="res_company.coop_email_contact"></span></li>
</ul>
</xpath>
</template>
</data>
</openerp>

2
easy_my_coop/wizard/__init__.py

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import cooperative_history_wizard

69
easy_my_coop/wizard/cooperative_history_wizard.py

@ -0,0 +1,69 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Author: Houssine BAKKALI
# Copyright Open Architects Consulting
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import api, fields, models, _
class cooperative_report(models.TransientModel):
_name = 'cooperative.history.report'
def _print_report(self, data):
return {'type': 'ir.actions.report.xml',
'report_name': data['report'],
'datas': data}
def check_report(self):
data = {}
report_name = ''
obj_ids = []
if self._context.get('active_ids') :
data['ids'] = self._context.get('active_ids', [])
else:
if self.report == 'coop_register':
report_name = 'easy_my_coop.cooperator_register_G001'
res_partner_obj = self.pool.get('res.partner')
domain = []
domain.append(('cooperator','=','True'))
if self.display_cooperator == 'member' :
domain.append(('member','=','True'))
obj_ids = res_partner_obj.search(cr,uid, domain, order='cooperator_register_number')
elif self.report == 'operation_register' :
report_name = 'energiris_wp_sync.cooperator_subscription_G001'
obj_ids = self.pool.get('subscription.register').search(cr,uid,[], order='register_number_operation')
else :
raise osv.except_osv(_("Error!"), _("the report you've specified doesn't exist !"))
data['model'] = context.get('active_model', 'ir.ui.menu')
data['report'] = report_name
#data['form'] = self.read(cr, uid, ids, ['date_from', 'date_to','display_time','display_cooperator','group_by_task','group_by_task_work'], context=context)[0]
data['ids'] = obj_ids
return self._print_report(cr, uid, ids, data, context=context)
name = fields.Char(string='Name')
report = fields.Selection([('coop_register', 'Cooperators Register'),
('operation_register', 'Operations Register')],
string='Report',
required=True, default='coop_register')
display_cooperator = fields.Selection([('all', 'All'),
('member', 'Effective member')],
string='Display cooperator',
required=True, default='all')

56
easy_my_coop/wizard/cooperative_history_wizard.xml

@ -0,0 +1,56 @@
<?xml version="1.0" ?>
<openerp>
<data>
<record id="view_cooperative_history_wizard" model="ir.ui.view">
<field name="name">cooperative.history.wizard.form</field>
<field name="model">cooperative.history.report</field>
<field name="arch" type="xml">
<form string="Reporting" version="7.0">
<separator string="Cooperative History"/>
<group>
<field name="report"/>
</group>
<label string="This report allows you to print a pdf of history and number of share for each cooperator"/>
<group>
<field name="display_cooperator"/>
<!--<field name="display_time"/>-->
</group>
<footer>
<button name="check_report" string="Print" type="object" default_focus="1" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_cooperative_history_wizard" model="ir.actions.act_window">
<field name="name">Cooperative history</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">cooperative.history.report</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_cooperative_history_wizard"/>
<field name="target">new</field>
<field name="multi">True</field>
</record>
<!--
<record model="ir.values" id="action_mission_history_wizard_values">
<field name="model_id" ref="fiducis.model_mission_mission"/>
<field name="object" eval="1"/>
<field name="name">Mission history</field>
<field name="key2">client_print_multi</field>
<field name="value"
eval="'ir.actions.act_window,' +str(ref('action_mission_history_wizard'))"/>
<field name="key">action</field>
<field name="model">mission.mission</field>
</record>
-->
<menuitem id="menu_energiris_reporting" name="Reporting" parent="menu_main_energiris" sequence="20"/>
<menuitem id="menu_coop_history_wizard_report" name="Cooperative history report" parent="menu_energiris_reporting" action="action_cooperative_history_wizard" sequence="10"/>
<!--<menuitem id="menu_optify_rep_history" name="Mission hours history" action="action_mission_history_wizard" parent="menu_optify_reporting" sequence="2"/>-->
</data>
</openerp>

0
easy_my_coop_be/__init__.py

35
easy_my_coop_be/__openerp__.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop Be",
"version": "1.0",
"depends": ["easy_my_coop",
"l10n_be",
"l10n_be_invoice_bba",
],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This is the belgian localization for the easy my coop module.
""",
'data': [],
'installable': True,
'application': False,
}

1
easy_my_coop_eater/__init__.py

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

34
easy_my_coop_eater/__openerp__.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OAC, Business Open Source Solution
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop Eater/worker",
"version": "1.0",
"depends": ["easy_my_coop"],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This module allows to manage the activity of the cooperator.
""",
'data': [
'view/product_view.xml',
],
'installable': True,
}

2
easy_my_coop_eater/models/__init__.py

@ -0,0 +1,2 @@
from . import coop
from . import product

28
easy_my_coop_eater/models/coop.py

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models
class subscription_request(models.Model):
_inherit='subscription.request'
def get_eater_vals(self, partner, share_product_id):
vals = {}
eater = share_product_id.eater
if partner.is_company or partner.age < 18:
eater = 'eater'
vals['eater'] = eater
vals['customer'] = share_product_id.customer
return vals
@api.one
def validate_subscription_request(self):
invoice = super(subscription_request, self).validate_subscription_request()[0]
partner = invoice.partner_id
vals = self.get_eater_vals(partner, self.share_product_id)
partner.write(vals)
return invoice

8
easy_my_coop_eater/models/product.py

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class ProductTemplate(models.Model):
_inherit = 'product.template'
customer = fields.Boolean(string='Become customer')
eater = fields.Selection([('eater', 'Eater'), ('worker_eater', 'Worker and Eater')], string="Eater/Worker")

14
easy_my_coop_eater/view/product_view.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_template_form_view_eater" model="ir.ui.view">
<field name="name">product.template.share.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="easy_my_coop.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='minimum_quantity']" position="after">
<field name="customer" attrs="{'invisible':[('is_share','=',False)]}"/>
<field name="eater" attrs="{'invisible':[('is_share','=',False)]}"/>
</xpath>
</field>
</record>
</odoo>

1
easy_my_coop_fr/__init__.py

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

37
easy_my_coop_fr/__openerp__.py

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop Fr",
"version": "1.0",
"depends": ["easy_my_coop",
"l10n_fr",
"theme_light",],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This is the french localization for the easy my coop module
""",
'data': [
'views/subscription_template.xml',
'views/layout_template.xml'
],
'installable': True,
'application': False,
}

1
easy_my_coop_fr/models/__init__.py

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

16
easy_my_coop_fr/models/coop.py

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class subscription_request(models.Model):
_inherit = 'subscription.request'
def get_required_field(self):
required_fields = super(subscription_request,self).get_required_field()
# if 'no_registre' in required_fields:
# required_fields.remove('no_registre')
if 'iban' in required_fields:
required_fields.remove('iban')
return required_fields

14
easy_my_coop_fr/views/layout_template.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="layout_i18n_fr" inherit_id="theme_light.invoice_footer" name="French Layout Customization">
<xpath expr="//t[@t-if='company.company_registry']" position="before">
<t t-if="company.siret">
<span>Siret</span> :
<span t-field="company.siret"/> -
</t>
</xpath>
</template>
</data>
</odoo>

11
easy_my_coop_fr/views/subscription_template.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="subscription_i18n" inherit_id="easy_my_coop.becomecooperator" name="Removing fields">
<!-- <xpath expr="//label[@for='no_registre']/.." position="replace">
</xpath> -->
<xpath expr="//label[@for='iban']/.." position="replace">
</xpath>
</template>
</data>
</odoo>

2
easy_my_coop_online_payment/__init__.py

@ -0,0 +1,2 @@
from . import models
from . import controllers

37
easy_my_coop_online_payment/__openerp__.py

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop Online Payment",
"version": "1.0",
"depends": ["easy_my_coop",
"website_payment",
"payment_paypal"],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This module allows the cooperator to pay the subscribed shares online
during the subscription process
""",
'data': [
"views/online_payment_template.xml",
],
'installable': True,
'application': False,
}

1
easy_my_coop_online_payment/controllers/__init__.py

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

104
easy_my_coop_online_payment/controllers/main.py

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
# import datetime
# import re
import werkzeug
import werkzeug.urls
from openerp import http, SUPERUSER_ID
from openerp.http import request
from openerp.tools.translate import _
from openerp.addons.easy_my_coop.controllers.main import WebsiteSubscription
from openerp.addons.website_payment.controllers.main import website_payment
class SubscriptionOnlinePayment(WebsiteSubscription):
def fill_values(self, values, is_company):
values = super(SubscriptionOnlinePayment,self).fill_values(values, is_company)
fields_desc = request.env['subscription.request'].sudo().fields_get(['payment_type'])
values['payment_types'] = fields_desc['payment_type']['selection']
return values
def get_subscription_response(self, values, kwargs):
subscription = values.get('subscription_id', False)
invoice = subscription.validate_subscription_request()[0]
if kwargs.get('payment_type') == 'online':
acquirer = request.env['payment.acquirer'].search([('website_published', '=', True)])[0]
return website_payment().pay(reference=invoice.number, amount=invoice.residual, currency_id=invoice.currency_id.id, acquirer_id=acquirer.id)
else:
values = self.preRenderThanks(values, kwargs)
return request.website.render(kwargs.get("view_callback", "easy_my_coop.cooperator_thanks"), values)
return True
class SubscriptionWebsitePayment(website_payment):
@http.route(['/website_payment/transaction'], type='json', auth="public", website=True)
def transaction(self, reference, amount, currency_id, acquirer_id):
partner_id = request.env.user.partner_id.id if request.env.user.partner_id != request.website.partner_id else False
capital_release_request = request.env['account.invoice'].sudo().search([('release_capital_request','=',True),('number','=',reference)])
values = {
'acquirer_id': int(acquirer_id),
'reference': reference,
'amount': float(amount),
'currency_id': int(currency_id),
'partner_id': partner_id,
'release_capital_request' : capital_release_request.id,
}
if len(capital_release_request) > 0:
values['partner_id'] = capital_release_request.partner_id.id
values['release_capital_request'] = capital_release_request.id
tx = request.env['payment.transaction'].sudo().create(values)
request.session['website_payment_tx_id'] = tx.id
return tx.id
@http.route(['/website_payment/confirm'], type='http', auth='public', website=True)
def confirm(self, **kw):
tx_id = request.session.pop('website_payment_tx_id', False)
if tx_id:
tx = request.env['payment.transaction'].sudo().browse(tx_id)
status = (tx.state == 'done' and 'success') or 'danger'
message = (tx.state == 'done' and 'Your payment was successful! It may take some time to be validated on our end.') or 'OOps! There was a problem with your payment.'
return request.website.render('website_payment.confirm', {'tx': tx, 'status': status, 'message': message})
else:
return request.redirect('/my/home')
@http.route(['/website_payment/pay'], type='http', auth='public', website=True)
def pay(self, reference='', amount=False, currency_id=None, acquirer_id=None, **kw):
env = request.env
user = env.user.sudo()
currency_id = currency_id and int(currency_id) or user.company_id.currency_id.id
currency = env['res.currency'].browse(currency_id)
# Try default one then fallback on first
acquirer_id = acquirer_id and int(acquirer_id) or \
env['ir.values'].get_default('payment.transaction', 'acquirer_id', company_id=user.company_id.id) or \
env['payment.acquirer'].search([('website_published', '=', True), ('company_id', '=', user.company_id.id)])[0].id
acquirer = env['payment.acquirer'].with_context(submit_class='btn btn-primary pull-right',
submit_txt=_('Pay Now')).browse(acquirer_id)
# auto-increment reference with a number suffix if the reference already exists
reference = request.env['payment.transaction'].get_next_reference(reference)
partner_id = user.partner_id.id if user.partner_id.id != request.website.partner_id.id else False
capital_release_request = request.env['account.invoice'].sudo().search([('release_capital_request','=',True),('number','=',reference)])
if len(capital_release_request) > 0:
partner_id = capital_release_request.partner_id.id
payment_form = acquirer.sudo().render(reference, float(amount), currency.id, values={'return_url': '/website_payment/confirm', 'partner_id': partner_id})[0]
values = {
'reference': reference,
'acquirer': acquirer,
'currency': currency,
'amount': float(amount),
'payment_form': payment_form,
}
return request.website.render('website_payment.pay', values)

65
easy_my_coop_online_payment/i18n/fr.po

@ -0,0 +1,65 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * easy_my_coop_online_payment
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-18 21:56+0000\n"
"PO-Revision-Date: 2017-01-18 23:19+0100\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 1.6.5\n"
"Language: fr\n"
#. module: easy_my_coop_online_payment
#: model:ir.ui.view,arch_db:easy_my_coop_online_payment.SubscriptionOnlinePayment
msgid "<i class=\"fa fa-arrow-circle-right\"/> Pay Now"
msgstr "<i class=\"fa fa-arrow-circle-right\"/> Pay Now"
#. module: easy_my_coop_online_payment
#: selection:subscription.request,payment_type:0
msgid "Deferred"
msgstr "Différé"
#. module: easy_my_coop_online_payment
#: selection:subscription.request,payment_type:0
msgid "Online"
msgstr "En ligne"
#. module: easy_my_coop_online_payment
#: code:addons/easy_my_coop_online_payment/controllers/main.py:86
#: model:ir.ui.view,arch_db:easy_my_coop_online_payment.SubscriptionOnlinePayment
#, python-format
msgid "Pay Now"
msgstr "Payer Maintenant"
#. module: easy_my_coop_online_payment
#: model:ir.model,name:easy_my_coop_online_payment.model_payment_transaction
msgid "Payment Transaction"
msgstr "Transaction"
#. module: easy_my_coop_online_payment
#: model:ir.model.fields,field_description:easy_my_coop_online_payment.field_subscription_request_payment_type
msgid "Payment Type"
msgstr "Type de paiement"
#. module: easy_my_coop_online_payment
#: model:ir.ui.view,arch_db:easy_my_coop_online_payment.subscription_payment_type
msgid "Payment type"
msgstr "Type de paiement"
#. module: easy_my_coop_online_payment
#: model:ir.model.fields,field_description:easy_my_coop_online_payment.field_payment_transaction_release_capital_request
msgid "Release Capital request"
msgstr "Demande de libération de capital"
#. module: easy_my_coop_online_payment
#: model:ir.model,name:easy_my_coop_online_payment.model_subscription_request
msgid "Subscription Request"
msgstr "Demande de souscription"

2
easy_my_coop_online_payment/models/__init__.py

@ -0,0 +1,2 @@
from . import payment_transaction
from . import coop

8
easy_my_coop_online_payment/models/coop.py

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class subscription_request(models.Model):
_inherit = 'subscription.request'
payment_type = fields.Selection([('online', 'Online'),
('deferred', 'Deferred')], string='Payment Type')

45
easy_my_coop_online_payment/models/payment_transaction.py

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
from datetime import datetime
import logging
from openerp import api, fields, models, _
_logger = logging.getLogger(__name__)
class PaymentTransaction(models.Model):
_inherit = 'payment.transaction'
release_capital_request = fields.Many2one('account.invoice', string="Release Capital request")
@api.model
def process_online_payment_reception(self,tx):
release_capital_request = tx.release_capital_request
release_capital_request.subscription_request[0].state = 'paid'
effective_date = datetime.now().strftime("%d/%m/%Y")
release_capital_request.sudo().set_cooperator_effective(effective_date)
return True
@api.v7
def _paypal_form_validate(self, cr, uid, tx, data, context=None):
status = data.get('payment_status')
res = {
'acquirer_reference': data.get('txn_id'),
'paypal_txn_type': data.get('payment_type'),
}
if status in ['Completed', 'Processed']:
_logger.info('Validated Paypal payment for tx %s: set as done' % (tx.reference))
res.update(state='done', date_validate=fields.Datetime.now())
result = tx.write(res)
self.process_online_payment_reception(cr, uid, tx)
return result
elif status in ['Pending', 'Expired']:
_logger.info('Received notification for Paypal payment %s: set as pending' % (tx.reference))
res.update(state='pending', state_message=data.get('pending_reason', ''))
return tx.write(res)
else:
error = 'Received unrecognized status for Paypal payment %s: %s, set as error' % (tx.reference, status)
_logger.info(error)
res.update(state='error', state_message=error)
return tx.write(res)

25
easy_my_coop_online_payment/views/online_payment_template.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="subscription_payment_type" inherit_id="easy_my_coop.becomecooperator" name="Removing fields">
<xpath expr="//div[@name='share_div']" position="after">
<div t-attf-class="form-group #{error and 'payment_type' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="company_type">Payment type</label>
<select name="payment_type" class="col-md-7 col-sm-8 form-control" required="True" style="width:54%;margin-left:15px">
<option value=""></option>
<t t-foreach="payment_types or []" t-as="pay_type">
<option t-att-value="pay_type[0]" t-att-selected="pay_type[0] == payment_type"><t t-esc="pay_type[1]"/></option>
</t>
</select>
</div>
</xpath>
</template>
<template id="easy_my_coop_online_payment.SubscriptionOnlinePayment" name="Subscription Online Payment" page="True">
<a t-if="invoice.state == 'open'" t-attf-href="/website_payment/pay?reference=#{invoice.number}&amp;amount=#{invoice.residual}&amp;currency_id=#{invoice.currency_id.id}&amp;acquirer_id=#{acquirer_id}&amp;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>
</template>
</data>
</odoo>

3
easy_my_coop_recompute_coop_number/__init__.py

@ -0,0 +1,3 @@
from . import models
from . import controllers
import wizard

35
easy_my_coop_recompute_coop_number/__openerp__.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OAC, Business Open Source Solution
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop Recompute Coop Number",
"version": "1.0",
"depends": ["easy_my_coop"],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This module allows to recompute the cooperator number subscription it has to be used carefully.
""",
'data': [
'wizard/cooperator_number_wizard.xml',
],
'installable': True,
'active': False,
}

2
easy_my_coop_recompute_coop_number/wizard/__init__.py

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import cooperator_number_wizard

49
easy_my_coop_recompute_coop_number/wizard/cooperator_number_wizard.py

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
from openerp import models, fields, api
class AddRespondentsWizard(models.TransientModel):
_name = 'cooperator.number.wizard'
from_number = fields.Integer(string="From number")
to_number = fields.Integer(string="To number")
reference = fields.Char(string="Reference", required=True, help='Enter your emails or references separeted by a semicolon')
on_reference = fields.Boolean('On reference')
on_email = fields.Boolean('On email', default=True)
@api.onchange('on_reference')
def onchange_reference(self):
if self.on_reference:
self.on_email = False
@api.onchange('on_email')
def onchange_email(self):
if self.on_email:
self.on_reference = False
@api.one
def compute_cooperator_number(self):
obj_sequence = self.env['ir.sequence']
list = self.reference.split(',')
for ref in list:
coop = self.env['res.partner'].search([('cooperator','=',True),('member','=',True),('email','=',ref)])
if coop:
sequence_id = obj_sequence.search([('name','=','Subscription Register')])[0]
sub_reg_num = sequence_id.next_by_id()
coop.write({'cooperator_register_number':int(sub_reg_num)})
subscription_register = self.env['subscription.register'].search([('partner_id','=',coop.id)])
if subscription_register:
sequence_operation = obj_sequence.search([('name','=','Register Operation')])[0]
sub_reg_operation = sequence_operation.next_by_id()
subscription_register.write({'name':sub_reg_operation,'register_number_operation':int(sub_reg_operation)})
else:
print "subscription register not found for " + coop.name
else:
print "cooperator not found for " + ref

39
easy_my_coop_recompute_coop_number/wizard/cooperator_number_wizard.xml

@ -0,0 +1,39 @@
<openerp>
<data>
<record id="view_cooperator_number_wizard" model="ir.ui.view">
<field name="name">Cooperator number wizard</field>
<field name="model">cooperator.number.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="reference" default_focus="1" />
</group>
<group>
<field name="on_reference"/>
<field name="on_email"/>
</group>
<footer>
<button name="compute_cooperator_number" string="Compute" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_cooperator_number_wizard" model="ir.actions.act_window">
<field name="name">Cooperator number</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">cooperator.number.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_cooperator_number_wizard"/>
<field name="target">new</field>
<field name="multi">True</field>
</record>
<menuitem id="menu_cooperator_number_wizard" parent="menu_easy_my_coop_config" action="action_cooperator_number_wizard" sequence="30" groups="easy_my_coop.group_energiris_super_manager"/>
</data>
</openerp>

0
easy_my_coop_taxshelter_report/__init__.py

35
easy_my_coop_taxshelter_report/__openerp__.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OAC, Business Open Source Solution
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Easy My Coop tax shelter report",
"version": "1.0",
"depends": ["easy_my_coop"],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This module allows to print a tax shelter report for the selected cooperators
""",
'data': [
'report/tax_shelter_report.xml',
#'wizard/tax_shelter_report_wizard.xml'
],
'installable': True,
}

141
easy_my_coop_taxshelter_report/report/tax_shelter_report.xml

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
<report
id="action_tax_shelter_report"
model="res.partner"
string="Tax shelter report"
report_type="qweb-pdf"
name="easy_my_coop_taxshelter_report.tax_shelter_report"
file="easy_my_coop_taxshelter_report.tax_shelter_report.xml"
multi="True"
menu="True"/>
</data>
<data>
<template id="tax_shelter_report_document">
<t t-call="theme_light.invoice_layout">
<div class="page">
<head>
<link href="/easy_my_coop_taxshelter_report/static/src/css/coop_report.css" rel="stylesheet"/>
<style type="text/css">
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Roboto Regular */
@font-face {
font-family: 'Roboto-Regular';
font-style: normal;
src: local('Roboto Regular'), url('/theme_light/static/font/Roboto-Regular.ttf') format('truetype');
}
/* Roboto Bold */
@font-face {
font-family: 'Roboto-Bold';
font-style: normal;
src: local('Roboto Bold'), url('/theme_light/static/font/Roboto-Bold.ttf') format('truetype');
}
/* BEBASNEUE Bold */
@font-face {
font-family: 'Bebasneue-Bold';
font-style: normal;
src: local('Bebasneue-Bold'), url('/theme_light/static/font/BEBASNEUE_BOLD.ttf') format('truetype');
}
</style>
</head>
<t t-call="theme_light.invoice_header"/>
<div class="row">
<div class="col-xs-5 col-xs-offset-7 easymy-coop-address" style="top:40px;">
<strong><span t-field="o.name" /><br/></strong>
<span> numéro de coopérateur </span>
<span t-field="o.cooperator_register_number"></span><br/><br/>
<span t-field="o.street" /><br/>
<span>
<span t-field="o.zip"/>
<span t-field="o.city"/>
</span><br/>
<span t-field="o.country_id.name" /><br/>
</div>
</div>
<div style="position:absolute; top:300px">
<h2 style="font-family:Bebasneue-Bold;font-size:20pt;line-height:14pt;">
<div>
<span>Déclaration Tax Shelter</span>
</div>
<div style="width:125px;position:relative;top:10px;border-bottom: 4pt solid #fcc300;"/>
</h2>
<div class="row">
<div class="col-xs-12 pull-left" style="position:relative;top:35px;font-size:16;color:black;font-family:Roboto-Regular;">
<div>
Cher membre fondateur,
</div>
<div style="position:relative;top:30px;">
Durant l'année 2015 vous êtes devenu coopérateur de la BEES Coop SCRLfs.<br/>
<t t-foreach="o.share_ids" t-as="line">
Vous avez souscrits en date <span t-field="line.effective_date" ></span>, <span t-field="line.share_number" ></span> parts pour un montant total de <span t-field="line.total_amount_line"
t-field-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/> euros.<br/>
</t>
</div>
<div style="position:relative;top:45px;">
L' Article 145/26, CIR 92 sur les revenus 2015, connu aussi comme normative Tax Shelter, donnent droit à une réduction d’impôt à hauteur de 45% du montant de la valeur des parts souscrites depuis juillet 2015 (et avant décembre 2015 pour la déclaration des revenus 2015).<br/>
<br/>
Cette lettre vaut donc comme certificat que BEES coop scrl fs remplit en effet tous les critères permettant un tel avantage fiscal. Dans les grandes lignes : <br/>
<br/>
être une micro-entreprise qui répond à au moins deux des trois critères suivants : <br/><br/>
- le total du bilan est inférieur ou égal à 350.000 euros ; <br/>
- le chiffre d’affaires, hors taxe sur la valeur ajoutée, est inférieur ou égal à 700.000 euros ; <br/>
- la moyenne des travailleurs occupés pendant l’année est inférieure ou égale à 10. <br/>
<br/>
être une entreprise n’ayant encore jamais distribué de dividende et qui n'est pas issue d’une fusion ou scission de sociétés.<br/><br/>
Le maintien de la réduction d’impôt n’est possible que si l'investisseur conserve les parts de la coopérative pendant 4 ans au minimum, sauf si la sortie est imposée par des conditions extérieures (telles que la faillite, par exemple). En cas de sortie volontaire avant la période de 4 ans, l’avantage fiscal devra être remboursé au prorata du nombre de mois entre la sortie et les 4 ans. La coopérative s’engage à fournir pour chacune des quatre années suivant l’année d’acquisition une attestation certifiant que ces parts sont toujours en possession du souscripteur.<br/><br/>
L’apport de capitaux par le chef d’entreprise lui-même ou par des administrateurs existants de la société ne permet pas de bénéficier du tax shelter.<br/>
<br/>
Pour bénéficier de la réduction d’impôts, vous pouvez joindre cette lettre à votre déclaration fiscale pour les revenus 2015.<br/>
<br/>
<![CDATA[
Pour toute information complémentaire, consultez le texte de <a href="http://ccff02.minfin.fgov.be/KMWeb/document.do?method=view&id=e5996d67-4f3e-4465-b21e-7e59d968a55d">l’Arrêté Royale en ligne</a>.<br/>
]]>
<br/>
Cordialement,
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6 pull-left" style="position:relative;top:100px;font-size:16;color:black;font-family:Roboto-Regular;">
<div style="position:relative;top:10px;">
Pour le Conseil d'administration de BEES coop SCRLFs.
</div>
<div style="position:relative;top:20px;">
<strong>Carine Sottiaux</strong>
</div>
<div style="position:relative;top:30px;">
<img src="/theme_light/static/img/gallery/signature_certificat.png" style="width:240px;height:200px;padding-bottom:5px;"/>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
<template id="tax_shelter_report">
<t t-call="theme_light.html_container">
<t t-set="data_report_margin_top" t-value="10"/>
<t t-set="data_report_header_spacing" t-value="5"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-foreach="docs" t-as="o">
<t t-call="easy_my_coop_taxshelter_report.tax_shelter_report_document" t-lang="o.lang"/>
</t>
</t>
</template>
</data>
</openerp>

19
easy_my_coop_taxshelter_report/static/src/css/coop_report.css

@ -0,0 +1,19 @@
.border-top-easymy-coop td {
border-top: 1pt solid #e7511e !important;
}
.border-easymy-coop th {
border-bottom: 1pt solid #e7511e !important;
}
.easymy-coop-normal {
font-family:Roboto-Regular;
font-size:12pt;
line-height:16pt;
}
.easymy-coop-info-title {
font-family:Roboto-Bold;
font-size:12pt;
line-height:16pt;
}

1
easy_my_coop_taxshelter_report/wizard/__init__.py

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

49
easy_my_coop_taxshelter_report/wizard/tax_shelter_report_wizard.py

@ -0,0 +1,49 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Author: Houssine BAKKALI
# Copyright Open Architects Consulting
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import api, fields, models, _
class TaxShelterReport(models.TransientModel):
_name = 'tax.shelter.report'
name = fields.Char(string='Name')
year = fields.Integer(string='Year', help='Introduce the year for which you want to get the report')
def _print_report(self, data):
return {'type': 'ir.actions.report.xml',
'report_name': data['report'],
'datas': data}
@api.one
def print_report(self):
data = {}
domain = [('cooperator','=','True'),('member','=','True')]
coop = self.env['res.partner'].search(domain, order='cooperator_register_number')
data['model'] = 'res.partner'
data['report'] = 'easy_my_coop_taxshelter_report.taxshelter_report'
data['ids'] = coop.ids
#return self._print_report(data)
return self.env['report'].get_action(coop, 'easy_my_coop_taxshelter_report.tax_shelter_report')

38
easy_my_coop_taxshelter_report/wizard/tax_shelter_report_wizard.xml

@ -0,0 +1,38 @@
<?xml version="1.0" ?>
<openerp>
<data>
<record id="view_tax_shelter_wizard" model="ir.ui.view">
<field name="name">tax.shelter.report.wizard.form</field>
<field name="model">tax.shelter.report</field>
<field name="arch" type="xml">
<form string="Reporting">
<separator string="Tax shelter report"/>
<group>
<field name="year"/>
</group>
<footer>
<button name="print_report" string="Print" type="object" default_focus="1" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_tax_shelter_wizard" model="ir.actions.act_window">
<field name="name">Tax shelter report</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">tax.shelter.report</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_tax_shelter_wizard"/>
<field name="target">new</field>
<field name="multi">True</field>
</record>
<menuitem id="menu_easy_my_reporting" name="Reporting" parent="easy_my_coop.menu_main_easy_my_coop" sequence="60"/>
<menuitem id="menu_tax_shelter_wizard_report" name="Tax shelter report" parent="menu_easy_my_reporting" action="action_tax_shelter_wizard" sequence="10"/>
</data>
</openerp>

1
partner_age/__init__.py

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

34
partner_age/__openerp__.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OAC, Business Open Source Solution
# Copyright (C) 2013-2016 Open Architects Consulting SPRL.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
"name": "Partner Age",
"version": "1.0",
"depends": ["easy_my_coop","beesdoo_base"],
"author": "Houssine BAKKALI <houssine.bakkali@gmail.com>",
"category": "Cooperative management",
"description": """
This module allows to recompute the cooperator number subscription it has to be used carefully.
""",
'data': [
'view/partner_view.xml',
],
'installable': True,
}

1
partner_age/models/__init__.py

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

30
partner_age/models/partner.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as OE_DFORMAT
from openerp import models, fields, api, _
class ResPartner(models.Model):
_inherit = 'res.partner'
def _search_age(self, operator, value):
if operator not in ('=', '!=', '<', '<=', '>', '>=', 'in', 'not in'):
return []
# retrieve all the messages that match with a specific SQL query
query = """SELECT id FROM "%s" WHERE extract(year from age(CURRENT_DATE, birthdate)) %s %%s""" % \
(self._table, operator)
self.env.cr.execute(query, (value,))
ids = [t[0] for t in self.env.cr.fetchall()]
return [('id', 'in', ids)]
@api.one
@api.depends('birthdate')
def _compute_age(self):
if self.birthdate:
dBday = datetime.strptime(self.birthdate, OE_DFORMAT).date()
dToday = datetime.now().date()
self.age = dToday.year - dBday.year - ((
dToday.month, dToday.day) < (dBday.month, dBday.day))
age = fields.Integer(string='Age',compute='_compute_age',search='_search_age')

24
partner_age/view/partner_view.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_tree_age" model="ir.ui.view">
<field name="name">res.partner.tree.age</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="easy_my_coop.view_partner_form_easy_my_coop"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='birthdate']" position='after'>
<field name="age" attrs="{'invisible':[('is_company','=',True)]}"/>
</xpath>
</field>
</record>
<record id="view_partner_tree_age" model="ir.ui.view">
<field name="name">res.partner.tree.easy_my_coop</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="easy_my_coop.view_partner_tree_easy_my_coop"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='cooperator_type']" position='after'>
<field name="age"/>
</xpath>
</field>
</record>
</odoo>

0
theme_light/__init__.py

15
theme_light/__openerp__.py

@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
{
'name': 'Theme light',
'description': 'extract of the theme zen',
'category': 'Website',
'version': '1.0',
'author': 'Open Architect Consulting sprl',
'depends': ['base',
],
'data': [
'views/layout_template.xml',
'report/header_report_G002.xml',
],
'application': True,
}

197
theme_light/report/header_report_G002.xml

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="theme_light.invoice_header_G002">
<table style="width: 100%;font-size:10px">
<tr height="30px">
<td style="width:20%;padding-right:15px" rowspan="4">
<img t-if="o.company_id.logo" t-att-src="'data:image/png;base64,%s' % o.company_id.logo" style="max-height: 100px;"/>
</td>
<td style="width:29%"></td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/location_green.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/phone_green.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/www_green.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
</tr>
<tr height="20px">
<td style="font-size:14px"></td>
<td>
<span t-field="o.company_id.partner_id.street"/>
</td>
<td>
<span>Phone</span>
<span t-field="o.company_id.partner_id.phone"/>
</td>
<td>
<span t-field="o.company_id.partner_id.website"/>
</td>
</tr>
<tr style="vertical-align:top" height="20px">
<td style="vertical-align:middle"></td>
<td style="vertical-align:middle">
<span t-field="o.company_id.partner_id.zip"/> -
<span t-field="o.company_id.partner_id.city"/>
</td>
<td style="vertical-align:middle">
<span>Fax</span>
<span t-field="o.company_id.partner_id.fax"/>
</td>
</tr>
<tr>
<td></td>
<td style="vertical-align:top">
<span t-field="o.company_id.partner_id.country_id.name"/>
</td>
<td></td>
</tr>
<tr>
<td colspan="2"><span style="margin-left:10px" t-field="o.company_id.rml_header1"/> </td>
<td style="vertical-align:bottom">
<span t-field="o.company_id.partner_id.vat"/>
</td>
<td></td>
<td></td>
</tr>
</table>
</template>
<template id="theme_light.invoice_header_P002">
<table style="width: 100%;font-size:10px">
<tr height="30px">
<td style="width:20%;padding-right:15px" rowspan="4">
<img t-if="o.company_id.logo" t-att-src="'data:image/png;base64,%s' % o.company_id.logo" style="max-height: 100px;"/>
</td>
<td style="width:29%"></td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/location_purple.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/phone_purple.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/www_purple.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
</tr>
<tr height="20px">
<td style="font-size:14px"></td>
<td>
<span t-field="o.company_id.partner_id.street"/>
</td>
<td>
<span>Phone</span>
<span t-field="o.company_id.partner_id.phone"/>
</td>
<td>
<span t-field="o.company_id.partner_id.website"/>
</td>
</tr>
<tr style="vertical-align:top" height="20px">
<td style="vertical-align:middle"></td>
<td style="vertical-align:middle">
<span t-field="o.company_id.partner_id.zip"/> -
<span t-field="o.company_id.partner_id.city"/>
</td>
<td style="vertical-align:middle">
<span>Fax</span>
<span t-field="o.company_id.partner_id.fax"/>
</td>
</tr>
<tr>
<td></td>
<td style="vertical-align:top">
<span t-field="o.company_id.partner_id.country_id.name"/>
</td>
<td></td>
</tr>
<tr>
<td colspan="2"><span style="margin-left:10px" t-field="o.company_id.rml_header1"/> </td>
<td style="vertical-align:bottom">
<span t-field="o.company_id.partner_id.vat"/>
</td>
<td></td>
<td></td>
</tr>
</table>
</template>
<template id="theme_light.list_header_G002">
<table style="width: 100%;font-size:10px">
<tr height="30px">
<td style="width:20%;padding-right:15px" rowspan="4">
<img t-if="res_company.logo" t-att-src="'data:image/png;base64,%s' % res_company.logo" style="max-height: 100px;"/>
</td>
<td style="width:29%"></td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/location_green.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/phone_green.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
<td style='width:17%'>
<img src="theme_light/static/img/gallery/www_green.png" style="max-height: 30px;padding-bottom:10px"/>
</td>
</tr>
<tr height="20px">
<td style="font-size:14px"></td>
<td>
<span t-field="res_company.partner_id.street"/>
</td>
<td>
<span>Phone</span>
<span t-field="res_company.partner_id.phone"/>
</td>
<td>
<span t-field="res_company.partner_id.website"/>
</td>
</tr>
<tr style="vertical-align:top" height="20px">
<td style="vertical-align:middle"></td>
<td style="vertical-align:middle">
<span t-field="res_company.partner_id.zip"/> -
<span t-field="res_company.partner_id.city"/>
</td>
<td style="vertical-align:middle">
<span>Fax</span>
<span t-field="res_company.partner_id.fax"/>
</td>
</tr>
<tr>
<td></td>
<td style="vertical-align:top">
<span t-field="res_company.partner_id.country_id.name"/>
</td>
<td></td>
</tr>
<tr>
<td colspan="2"><span style="margin-left:10px" t-field="res_company.rml_header1"/> </td>
<td style="vertical-align:bottom">
<span t-field="res_company.partner_id.vat"/>
</td>
<td></td>
<td></td>
</tr>
</table>
</template>
</data>
</openerp>

5774
theme_light/static/css/bootstrap.css
File diff suppressed because it is too large
View File

19
theme_light/static/css/global_theme.css

@ -0,0 +1,19 @@
.particle_banner {
position: relative;
overflow: hidden;
}
.particle_banner .container {
width: 100%;
position: absolute;
top: 0;
}
.particle_banner .container h1 {
color: white;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
font-size: 5em;
}
.particle_banner .container h2 {
color: rgba(255, 255, 255, 0.6);
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
font-size: 3em;
}

21
theme_light/static/css/global_theme.sass

@ -0,0 +1,21 @@
// Particle banner
@import "compass/css3"
.particle_banner
position: relative
overflow: hidden
.container
width: 100%
position: absolute
top: 0
h1
color: rgb(255,255,255)
+text-shadow(0 0 5px rgba(0,0,0,.5))
font-size: 5em
h2
color: rgba(255,255,255,0.6)
+text-shadow(0 0 5px rgba(0,0,0,.5))
font-size: 3em

161
theme_light/static/css/invoice_B001.css

@ -0,0 +1,161 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
font-family:Lato-Regular;
font-size: 18px;
}
address::first-line {
font-weight:bold;
color: #000;
}
.doc_title {
font-family:Montserrat-Regular;
font-size: 18px;
border-bottom: #009ceb 1px solid;
padding-bottom: 10px;
width: 150px;
}
.doc_num {
font-family:Montserrat-Regular;
font-size: 18px;
padding-top: 15px;
width: 150px;
}
.info_table {
margin-top:20px;
border: 2px ridge #009ceb;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #009ceb), color-stop(1, #0c1cea) );
margin-top : 5px;
height: 25px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
font-family:Lato-Regular;
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #009ceb 1px solid;
}
div h4 {
font-size: 14px;
clear: both;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
color : #009ceb;
padding-bottom: 10px;
border-bottom: #009ceb 3px ridge;
}
.list_line_table_head td {
font-family:Lato-Regular;
vertical-align : middle;
}
.tva_table {
margin-top:20px;
border: 2px ridge #009ceb;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #009ceb;
text-align: center ;
border-bottom: #009ceb 1px solid;
}
.standard_line {
border-top : 1px solid #009ceb;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#009ceb;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#e2f4fd;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

194
theme_light/static/css/invoice_B002.css

@ -0,0 +1,194 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
}
address::first-line {
font-weight:bold;
color: #000;
}
.title_table {
width: 100%;
border-bottom: #009ceb 1px solid;
}
.title_doc {
font-family:Montserrat-Regular;
font-size: 36px;
padding-bottom: 10px;
text-align : right;
}
.color_text {
color:#009ceb;
}
.color_background {
background-color:#009ceb;
}
.white_line_border {
background-color:#ffffff;
border-bottom: #009ceb 1px solid;
height:15px;
}
.info_table {
margin-top:20px;
border: 2px solid #009ceb;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background-color :#009ceb;
margin-top : 5px;
height: 40px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #009ceb 1px solid;
}
div h4 {
font-size: 14px;
clear: both;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
padding-bottom: 10px;
border-bottom: #009ceb 3px ridge;
}
.list_line_table_head td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #e2f4fd;
padding-right:5px;
}
.total_table {
text-align: center ;
}
.total_table th {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #e2f4fd;
padding-right:5px;
}
.total_table td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #009ceb;
padding-right:5px;
}
.tva_table {
margin-top:20px;
border: 2px ridge #009ceb;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #009ceb;
text-align: center ;
border-bottom: #009ceb 1px solid;
}
.orange_line {
border-top : 1px solid #009ceb;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#009ceb;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#e2f4fd;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

161
theme_light/static/css/invoice_G001.css

@ -0,0 +1,161 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
font-family:Lato-Regular;
font-size: 18px;
}
address::first-line {
font-weight:bold;
color: #000;
}
.doc_title {
font-family:Montserrat-Regular;
font-size: 18px;
border-bottom: #53cf00 1px solid;
padding-bottom: 10px;
width: 150px;
}
.doc_num {
font-family:Montserrat-Regular;
font-size: 18px;
padding-top: 15px;
width: 150px;
}
.info_table {
margin-top:20px;
border: 2px ridge #53cf00;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #53cf00), color-stop(1, #408512) );
margin-top : 5px;
height: 25px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
font-family:Lato-Regular;
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #53cf00 1px solid;
}
div h4 {
font-size: 14px;
clear: both;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
color : #53cf00;
padding-bottom: 10px;
border-bottom: #53cf00 3px ridge;
}
.list_line_table_head td {
font-family:Lato-Regular;
vertical-align : middle;
}
.tva_table {
margin-top:20px;
border: 2px ridge #53cf00;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #53cf00;
text-align: center ;
border-bottom: #53cf00 1px solid;
}
.standard_line {
border-top : 1px solid #53cf00;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#53cf00;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#def1d1;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

216
theme_light/static/css/invoice_G002.css

@ -0,0 +1,216 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
}
address::first-line {
font-weight:bold;
color: #000;
}
.title_table {
width: 100%;
border-bottom: #53cf00 1px solid;
vertical-align:middle;
color:#53cf00;
}
.title_doc {
font-family:Montserrat-Regular;
font-size: 36px;
padding-bottom: 10px;
text-align : right;
}
.color_text {
color:#53cf00;
}
.color_background {
background-color:#53cf00;
}
.white_line_border {
background-color:#ffffff;
border-bottom: #53cf00 1px solid;
height:15px;
}
.total_table {
text-align: right;
vertical-align:middle;
font-weight:bold;
border-bottom : 1px solid #53cf00;
border-top : 1px solid #53cf00;
}
.info_table {
margin-top:20px;
border: 2px solid #53cf00;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background-color :#53cf00;
margin-top : 5px;
height: 40px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #53cf00 1px solid;
}
div h4 {
font-size: 14px;
clear: both;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
padding-bottom: 10px;
border-bottom: #53cf00 3px ridge;
}
.list_line_table_head td {
vertical-align : middle;
border-collapse: separate;
border-spacing: 2px;
padding-right:5px;
font-size: 11px;
}
.single_line {
background-color:#ffffff;
border-bottom: #53cf00 1px solid;
height:20px;
margin-top:5px;
}
.line_only {
border-bottom: #8b8b8b 1px solid;
}
.total_table {
text-align: center ;
}
.total_table th {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #def1d1;
padding-right:5px;
}
.total_table td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #53cf00;
padding-right:5px;
}
.tva_table {
margin-top:20px;
border: 2px ridge #53cf00;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #53cf00;
text-align: center ;
border-bottom: #53cf00 1px solid;
}
.orange_line {
border-top : 1px solid #53cf00;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#53cf00;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#def1d1;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

194
theme_light/static/css/invoice_O002.css

@ -0,0 +1,194 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
}
address::first-line {
font-weight:bold;
color: #000;
}
.title_table {
width: 100%;
border-bottom: #e36522 1px solid;
}
.title_doc {
font-family:Montserrat-Regular;
font-size: 36px;
padding-bottom: 10px;
text-align : right;
}
.color_text {
color:#ff7f00;
}
.color_background {
background-color:#ff7f00;
}
.white_line_border {
background-color:#ffffff;
border-bottom: #ff7f00 1px solid;
height:15px;
}
.info_table {
margin-top:20px;
border: 2px solid #ff7f00;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background-color :#ff7f00;
margin-top : 5px;
height: 40px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #ff7f00 1px solid;
}
div h4 {
font-size: 14px;
clear: both;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
padding-bottom: 10px;
border-bottom: #ff7f00 3px ridge;
}
.list_line_table_head td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #fff0e6;
padding-right:5px;
}
.total_table {
text-align: center ;
}
.total_table th {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #fff0e6;
padding-right:5px;
}
.total_table td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #ff7f00;
padding-right:5px;
}
.tva_table {
margin-top:20px;
border: 2px ridge #ff7f00;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #ff7f00;
text-align: center ;
border-bottom: #ff7f00 1px solid;
}
.orange_line {
border-top : 1px solid #ff7f00;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#ff7f00;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#ffe0b0;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

204
theme_light/static/css/invoice_P002.css

@ -0,0 +1,204 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
}
address::first-line {
font-weight:bold;
color: #000;
}
.title_table {
width: 100%;
border-bottom: #c655b0 1px solid;
vertical-align:middle;
color:#c655b0;
}
.title_doc {
font-family:Montserrat-Regular;
font-size: 36px;
padding-bottom: 10px;
text-align : right;
}
.color_text {
color:#c655b0;
}
.color_background {
background-color:#c655b0;
}
.white_line_border {
background-color:#ffffff;
border-bottom: #c655b0 1px solid;
height:15px;
}
.total_table {
text-align: right;
vertical-align:middle;
font-weight:bold;
border-bottom : 1px solid #c655b0;
border-top : 1px solid #c655b0;
}
.info_table {
margin-top:20px;
border: 2px solid #c655b0;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background-color :#c655b0;
margin-top : 5px;
height: 40px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #c655b0 1px solid;
}
div h4 {
font-size: 14px;
clear: both;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
padding-bottom: 10px;
border-bottom: #c655b0 3px ridge;
}
.list_line_table_head td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #eddeea;
padding-right:5px;
}
.total_table {
text-align: center ;
}
.total_table th {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #eddeea;
padding-right:5px;
}
.total_table td {
vertical-align : middle;
border-bottom: 2px solid #ffffff;
border-collapse: separate;
border-spacing: 2px;
background-color : #c655b0;
padding-right:5px;
}
.tva_table {
margin-top:20px;
border: 2px ridge #c655b0;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #c655b0;
text-align: center ;
border-bottom: #c655b0 1px solid;
}
.orange_line {
border-top : 1px solid #c655b0;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#c655b0;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#eddeea;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

165
theme_light/static/css/invoice_orange.css

@ -0,0 +1,165 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
html {
font-family: alef;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
font-family:Montserrat-Regular;
margin: 0;
color: #000
}
address {
font-family:Lato-Regular;
font-size: 18px;
}
address::first-line {
font-weight:bold;
color: #000;
}
.color_text {
color:#f48c11;
}
.doc_title {
font-family:Montserrat-Regular;
font-size: 18px;
border-bottom: #e36522 1px solid;
padding-bottom: 10px;
width: 150px;
}
.doc_num {
font-family:Montserrat-Regular;
font-size: 18px;
padding-top: 15px;
width: 150px;
}
.info_table {
margin-top:20px;
border: 2px ridge #ff7f00;
border-collapse: separate;
border-spacing: 3px;
}
.info_table th {
color: white;
text-align: center;
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ff7f00), color-stop(1, #bf5f00) );
margin-top : 5px;
height: 25px;
vertical-align:middle;
font-size: 12px;
}
.info_table td {
font-family:Lato-Regular;
text-align: center;
height: 25px;
vertical-align:middle;
border-right: #ff7f00 1px solid;
}
div h4 {
font-size: 18px;
width: 150px;
text-align: center
}
.list_line_table_head {
text-align: center ;
}
.list_line_table_head th {
text-align: center ;
font-weight:bold;
color : #ff7f00;
padding-bottom: 10px;
border-bottom: #ff7f00 3px ridge;
}
.list_line_table_head td {
font-family:Lato-Regular;
vertical-align : middle;
}
.tva_table {
margin-top:20px;
border: 2px ridge #ff7f00;
border-collapse: separate;
border-spacing: 3px;
}
.tva_table th {
color : #ff7f00;
text-align: center ;
border-bottom: #ff7f00 1px solid;
}
.orange_line {
border-top : 1px solid #ff7f00;
}
.comment_table {
vertical-align:middle;
margin-left:10px;
margin-right:10px;
margin-top:30px;
}
.comment_table td {
color :#ff7f00;
text-align:left;
}
.lgn_impair{
background-color:#ffffff;
}
.lgn_pair{
background-color:#ffe0b0;
}
/* Alef */
@font-face {
font-family: 'Alef-regular';
font-style: normal;
font-weight: 400;
src: local('Alef Regular'), url('/theme_light/static/font/Alef-Regular.ttf') format('truetype');
}
/* Montserrat */
@font-face {
font-family: 'Montserrat-Regular';
font-style: normal;
font-weight: 400;
src: local('Montserrat Regular'), url('/theme_light/static/font/Montserrat-Regular.ttf') format('truetype');
}
/* Lato */
@font-face {
font-family: 'Lato-Regular';
font-style: normal;
font-weight: 400;
src: local('Lato Regular'), url('/theme_light/static/font/Lato-Regular.ttf') format('truetype');
}

64
theme_light/static/css/mail_template_B001.css

@ -0,0 +1,64 @@
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */
.main_table
{
background:#d6f4fb;
font-family:Alef-Regular;
font-size: 16px;
border="0";
cellspacing="0";
cellpadding="0";
width="100%";
mso-cellspacing:0cm;
mso-yfti-tbllook:1184;
mso-padding-alt:0cm 0cm 0cm 0cm;
}
hr {
color: #4a94a6;
background: #4a94a6;
width: 100%;
height: 2px;
}
.box_title {
width: 375px;
margin: 0px;
margin-top:15px;
padding: 0px;
height:25px;
background-color: #4a94a6;
border-top-left-radius: 5px 5px;
border-top-right-radius: 5px 5px;
background-repeat: repeat no-repeat;
color: white;
font-family:Calibri;
font-size: 16px;
}
.box-body {
width: 375px;
border-left: 1px solid #4a94a6;
border-right: 1px solid #4a94a6;
font-family:Calibri;
font-size: 16px;
}
.box_bottom {
width: 375px;
margin: 0px;
padding: 0px;
height:25px;
background-color: #4a94a6;
border-bottom-left-radius: 5px 5px;
border-bottom-right-radius: 5px 5px;
background-repeat: repeat no-repeat;
}
.company_text {
font-family:Calibri;
font-size: 12px;
color: #4a94a6;
}

9505
theme_light/static/css/theme_zen_black.css
File diff suppressed because it is too large
View File

9648
theme_light/static/css/theme_zen_blue.css
File diff suppressed because it is too large
View File

9512
theme_light/static/css/theme_zen_brown.css
File diff suppressed because it is too large
View File

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save