Browse Source

[ADD] bond and loan issues management

[ADD] bond and loan issues management module skeleton

[IMP] change increase menu sequence

[IMP] add models, fields and views

[IMP] add xml declaration in head of file

[ADD] add easy_my_coop_loan_website - WIP

[IMP] add access rights

[IMP] this raise inconsistency so replace id by default_code.

[IMP] change import openerp to odoo

[IMP] add website loan module

[FIX] put website display in loan

[FIX] fix import

[FIX] fix function

[IMP] use correct name

[IMP] make the loan and bond visible

[IMP] add js, field and logic to set amount limit per subscription

[IMP] remove dependency on recaptcha as user is logged to subscribe

[IMP] add fields

[IMP] save loan issue subscription still in WIP

[IMP] remove alert pop up

[IMP] add dependency to easy_my_coop_website

[IMP] remove force send for sub request creation email notification

[IMP] add mail templates

[IMP] save subscription in the corresponding loan issue. add email notif

[FIX] fix loan issue line view

[FIX] add related field to loan issue. It is where the data stand

[IMP] move term_view up

[FIX] fix js error when false is returned

[FIX] fix function when loan_issue_id in None

[IMP] add actions and button

[FIX] fix action

[FIX] fix mail template

[IMP] set noupdate=1

[IMP] change order

[IMP] display loan issue lines on partner form

[IMP] add loan view in partner form

[IMP] add face value on loan issue and line

add face value on loan issue and line. add as well the quantity and
computation of the amount

[FIX] missing id overriding values wasn't working

[IMP] getting bond face value and setting it as step.

[IMP] subscribed_amount computed field is the sum of the amount lines

[IMP] allow a waiting payment to be cancelled

[IMP] make field required

[REFACT] move loan issue line code to dedicated file

[IMP] add interest calculation and model

[ADD] bond and loan issues management module skeleton

[IMP] add models, fields and views

[IMP] allow creation by hand

[IMP] adding partner related field

[IMP] put code in separate function

[FIX] pass it to get method

[IMP] routes consistent form

[FIX] fix eof

[FIX] GET is working for ajax call

[IMP] website page for loan issue subscription
pull/24/head
houssine 5 years ago
committed by robin.keunen
parent
commit
1ea48e8277
  1. 2
      easy_my_coop/models/coop.py
  2. 24
      easy_my_coop/views/email_template_view.xml
  3. 3
      easy_my_coop/views/operation_request_view.xml
  4. 1
      easy_my_coop/views/product_view.xml
  5. 1
      easy_my_coop/views/res_company_view.xml
  6. 2
      easy_my_coop/views/res_partner_view.xml
  7. 4
      easy_my_coop/views/subscription_request_view.xml
  8. 1
      easy_my_coop_loan/__init__.py
  9. 27
      easy_my_coop_loan/__manifest__.py
  10. 112
      easy_my_coop_loan/data/mail_template_data.xml
  11. 4
      easy_my_coop_loan/models/__init__.py
  12. 59
      easy_my_coop_loan/models/interest_line.py
  13. 186
      easy_my_coop_loan/models/loan.py
  14. 95
      easy_my_coop_loan/models/loan_issue_line.py
  15. 9
      easy_my_coop_loan/models/partner.py
  16. 9
      easy_my_coop_loan/security/ir.model.access.csv
  17. 163
      easy_my_coop_loan/views/loan_view.xml
  18. 23
      easy_my_coop_loan/views/partner_view.xml
  19. 40
      easy_my_coop_loan/views/term_view.xml
  20. 1
      easy_my_coop_loan_website/__init__.py
  21. 26
      easy_my_coop_loan_website/__manifest__.py
  22. 1
      easy_my_coop_loan_website/controllers/__init__.py
  23. 93
      easy_my_coop_loan_website/controllers/main.py
  24. 16
      easy_my_coop_loan_website/data/website_loan_data.xml
  25. 23
      easy_my_coop_loan_website/static/src/js/loan_issue.js
  26. 54
      easy_my_coop_loan_website/template/loan_issue_template.xml
  27. 8
      easy_my_coop_website/controllers/main.py

2
easy_my_coop/models/coop.py

@ -101,7 +101,7 @@ class SubscriptionRequest(models.Model):
subscr_request = super(SubscriptionRequest, self).create(vals) subscr_request = super(SubscriptionRequest, self).create(vals)
confirmation_mail_template = self.env.ref(mail_template, False) confirmation_mail_template = self.env.ref(mail_template, False)
confirmation_mail_template.send_mail(subscr_request.id, True)
confirmation_mail_template.send_mail(subscr_request.id)
return subscr_request return subscr_request

24
easy_my_coop/views/email_template_view.xml

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data>
<menuitem name="Configuration" id="menu_easy_my_coop_config" parent="menu_main_easy_my_coop" sequence="20"/>
<menuitem name="Configuration" id="menu_easy_my_coop_config" parent="menu_main_easy_my_coop" sequence="80" />
<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>
<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_easy_my_coop_manager"/>
</data>
<menuitem id="menu_easy_my_coop_templates" parent="menu_easy_my_coop_config" action="action_easy_my_coop_email_templates" sequence="10" groups="group_easy_my_coop_manager" />
</odoo> </odoo>

3
easy_my_coop/views/operation_request_view.xml

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<record id="operation_request_tree" model="ir.ui.view"> <record id="operation_request_tree" model="ir.ui.view">
<field name="name">operation.request.tree</field> <field name="name">operation.request.tree</field>
@ -102,5 +103,5 @@
<field name="view_id" ref="operation_request_tree"/> <field name="view_id" ref="operation_request_tree"/>
</record> </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_easy_my_coop_manager"/>
<menuitem action="operation_request_action" name="Operation request" id="menu_easy_my_coop_operation_request" parent="menu_easy_my_coop_main_subscription" sequence="30" groups="easy_my_coop.group_easy_my_coop_manager"/>
</odoo> </odoo>

1
easy_my_coop/views/product_view.xml

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<record id="product_template_share_form_view" model="ir.ui.view"> <record id="product_template_share_form_view" model="ir.ui.view">
<field name="name">product.template.share.form</field> <field name="name">product.template.share.form</field>

1
easy_my_coop/views/res_company_view.xml

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<record model="ir.ui.view" id="view_company_inherit_form2"> <record model="ir.ui.view" id="view_company_inherit_form2">
<field name="name">res.company.form.easymy.coop</field> <field name="name">res.company.form.easymy.coop</field>

2
easy_my_coop/views/res_partner_view.xml

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<data> <data>
<record id="view_partner_form_easy_my_coop" model="ir.ui.view"> <record id="view_partner_form_easy_my_coop" model="ir.ui.view">

4
easy_my_coop/views/subscription_request_view.xml

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<odoo> <odoo>
<menuitem name="Easy-My Coop" id="menu_main_easy_my_coop" sequence="40" groups="easy_my_coop.group_easy_my_coop_user"/> <menuitem name="Easy-My Coop" id="menu_main_easy_my_coop" sequence="40" groups="easy_my_coop.group_easy_my_coop_user"/>
<menuitem name="Subscription" id="menu_easy_my_coop_main_subscription" parent="menu_main_easy_my_coop" sequence="10" groups="easy_my_coop.group_easy_my_coop_manager"/> <menuitem name="Subscription" id="menu_easy_my_coop_main_subscription" parent="menu_main_easy_my_coop" sequence="10" groups="easy_my_coop.group_easy_my_coop_manager"/>
@ -166,7 +166,7 @@
<field name="search_view_id" ref="view_subscription_request_filter"/> <field name="search_view_id" ref="view_subscription_request_filter"/>
</record> </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"/>
<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="15"/>
<record id="share_line_form" model="ir.ui.view"> <record id="share_line_form" model="ir.ui.view">
<field name="name">share.line.form</field> <field name="name">share.line.form</field>

1
easy_my_coop_loan/__init__.py

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

27
easy_my_coop_loan/__manifest__.py

@ -0,0 +1,27 @@
# Copyright 2019 Coop IT Easy SCRLfs (<http://www.coopiteasy.be>)
# - Houssine BAKKALI - <houssine@coopiteasy.be>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Easy My Coop Bond and Subordinated Loan Issues",
"version": "12.0.1.0.1",
"depends": [
"easy_my_coop",
],
"author": "Coop IT Easy SCRLfs",
"category": "Cooperative management",
"website": "http://www.coopiteasy.be",
"license": "AGPL-3",
"description": """
This module allows to manage the bonds and subordinated loans subscription
life cycle.
""",
'data': [
'security/ir.model.access.csv',
'views/term_view.xml',
'views/loan_view.xml',
'views/partner_view.xml',
'data/mail_template_data.xml',
],
'installable': True,
}

112
easy_my_coop_loan/data/mail_template_data.xml

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Mail template are declared in a NOUPDATE block
so users can freely customize/delete them -->
<data noupdate="1">
<!--<data>-->
<record id="loan_subscription_confirmation" model="mail.template">
<field name="name">Loan Subscription Confirmation Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.loan_issue_id.user_id.email)|safe}</field>
<field name="subject">${object.company_id.name} Loan subscription confirmation (Ref ${object.loan_issue_id.name or 'n/a'})</field>
<field name="email_to">${object.partner_id.email}</field>
<field name="reply_to">${(object.company_id.coop_email_contact or object.loan_issue_id.user_id.email)|safe}</field>
<field name="model_id" ref="easy_my_coop_loan.model_loan_issue_line"/>
<field name="auto_delete" eval="True"/>
<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>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_url}>
</div>
</div>
]]></field>
</record>
<!--Request the payment of the subscribed loan issue -->
<record id="loan_issue_payment_request" model="mail.template">
<field name="name">Loan Issue Payment Request - Send by Email</field>
<field name="email_from">${(object.company_id.coop_email_contact or object.loan_issue_id.user_id.email)|safe}</field>
<field name="subject">${object.company_id.name} Payment request (Ref ${object.loan_issue_id.name 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.loan_issue_id.user_id.email)|safe}</field>
<field name="model_id" ref="easy_my_coop_loan.model_loan_issue_line"/>
<field name="auto_delete" eval="True"/>
<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>Find here after the necessary information for the payment. We kindly remind you that your subscription will be effective only once we received the payment.</p>
<p>Amount: ${object.amount} ${object.loan_issue_id.company_currency_id.symbol}</p>
<p>Account number: ${object.company_id.partner_id.bank_ids[0].sanitized_acc_number}</p>
<p>Communication: ${object.loan_issue_id.name} + ${object.partner_id.name}</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_url}>
</div>
</div>
]]></field>
</record>
</data>
</odoo>

4
easy_my_coop_loan/models/__init__.py

@ -0,0 +1,4 @@
from . import loan
from . import loan_issue_line
from . import interest_line
from . import partner

59
easy_my_coop_loan/models/interest_line.py

@ -0,0 +1,59 @@
from odoo import fields, models
class LoanInterestLine(models.Model):
_name = 'loan.interest.line'
name = fields.Integer(string="Year",
required=True)
issue_line = fields.Many2one('loan.issue.line',
string="Subscribed loan",
required=True)
partner_id = fields.Many2one(related='issue_line.partner_id',
store=True,
readlonly=True)
amount = fields.Monetary(related='issue_line.amount',
string="Subscribed amount",
currency_field='company_currency_id',
readonly=True)
interest = fields.Monetary(string="Gross interest amount",
currency_field='company_currency_id',
readonly=True)
net_interest = fields.Monetary(string="Net interest amount",
currency_field='company_currency_id',
readonly=True)
taxes_rate = fields.Float(string="Taxes on interest",
required=True)
taxes_amount = fields.Monetary(string="Taxes amount",
currency_field='company_currency_id',
readonly=True)
accrued_amount = fields.Monetary(string="Accrued amount",
currency_field='company_currency_id',
readonly=True)
accrued_interest = fields.Monetary(string="Accrued gross interest",
currency_field='company_currency_id',
readonly=True)
accrued_net_interest = fields.Monetary(
string="Accrued net interest",
currency_field='company_currency_id',
readonly=True)
accrued_taxes = fields.Monetary(string="Accrued taxes to pay",
currency_field='company_currency_id',
readonly=True)
due_date = fields.Date(string="Due date")
company_currency_id = fields.Many2one('res.currency',
related='company_id.currency_id',
string="Company Currency",
readonly=True)
company_id = fields.Many2one('res.company',
related='issue_line.company_id',
string="Company",
readonly=True)
state = fields.Selection([('draft', 'Draft'),
('due', 'Due'),
('requested', 'Payment requested'),
('donation', 'Donation'),
('paid', 'Paid')
],
string="State",
default="draft")

186
easy_my_coop_loan/models/loan.py

@ -0,0 +1,186 @@
import logging
from odoo import api, fields, models
_logger = logging.getLogger(__name__)
class LoanTerm(models.Model):
_name = 'loan.term'
name = fields.Char(string="Name",
required=True)
term = fields.Float(string="Term",
required=True)
class LoanIssue(models.Model):
_name = 'loan.issue'
@api.multi
def _compute_subscribed_amount(self):
for issue in self:
susbscribed_amount = 0.0
for line in issue.loan_issue_lines.filtered(
lambda record: record.state != 'cancelled'):
susbscribed_amount += line.amount
issue.subscribed_amount = susbscribed_amount
name = fields.Char(string="Name")
is_bond = fields.Boolean(string="Is a bond issue?")
is_loan = fields.Boolean(string="Is a subordinated loan issue?")
default_issue = fields.Boolean(string="Default issue")
subscription_start_date = fields.Date(string="Start date")
subscription_end_date = fields.Date(string="End date")
user_id = fields.Many2one('res.users',
string="Responsible")
term_date = fields.Date(string="Term date")
rate = fields.Float(string="Interest rate")
face_value = fields.Monetary(string="Facial value",
currency_field='company_currency_id',
required=True)
minimum_amount = fields.Monetary(string="Minimum amount",
currency_field='company_currency_id')
maximum_amount = fields.Monetary(string="Maximum amount",
currency_field='company_currency_id')
maximum_amount_per_sub = fields.Monetary(
string="Maximum amount per subscription",
currency_field='company_currency_id')
subscribed_amount = fields.Monetary(string="Subscribed amount",
compute="_compute_subscribed_amount",
currency_field='company_currency_id')
interest_payment = fields.Selection([('end', 'End'),
('yearly', 'Yearly')],
string="Interest payment")
term = fields.Many2one('loan.term',
string="term of the loan")
loan_issue_lines = fields.One2many('loan.issue.line',
'loan_issue_id',
string="Loan issue lines")
state = fields.Selection([('draft', 'Draft'),
('confirmed', 'Confirmed'),
('cancelled', 'Cancelled'),
('ongoing', 'Ongoing'),
('closed', 'Closed')],
string="State",
default='draft')
company_currency_id = fields.Many2one('res.currency',
related='company_id.currency_id',
string="Company Currency",
readonly=True)
company_id = fields.Many2one('res.company',
string='Company',
required=True,
readonly=True,
default=lambda self: self.env['res.company']._company_default_get()) #noqa
by_company = fields.Boolean(string="By company")
by_individual = fields.Boolean(string='By individuals')
display_on_website = fields.Boolean(sting='Display on website')
taxes_rate = fields.Float(string="Taxes on interest",
required=True)
@api.multi
def toggle_display(self):
for loan_issue in self:
loan_issue.display_on_website = not loan_issue.display_on_website
@api.multi
def get_web_loan_issues(self, is_company):
loan_issues = self.search([
('is_loan', '=', True),
('display_on_website', '=', True),
('state', '=', 'ongoing')
])
if is_company is True:
return loan_issues.filtered('by_company')
else:
return loan_issues.filtered('by_individual')
@api.multi
def get_web_bond_issues(self, is_company):
bond_issues = self.search([
('is_bond', '=', True),
('display_on_website', '=', True),
('state', '=', 'ongoing')
])
if is_company is True:
return bond_issues.filtered('by_company')
else:
return bond_issues.filtered('by_company')
@api.multi
def get_web_issues(self, is_company):
issues = self.get_web_loan_issues(is_company)
issues = issues + self.get_web_bond_issues(is_company)
return issues
@api.multi
def action_confirm(self):
self.ensure_one()
self.write({'state': 'confirmed'})
@api.multi
def action_open(self):
self.ensure_one()
self.write({'state': 'ongoing'})
@api.multi
def action_draft(self):
self.ensure_one()
self.write({'state': 'draft'})
@api.multi
def action_cancel(self):
self.ensure_one()
self.write({'state': 'cancelled'})
@api.multi
def action_close(self):
self.ensure_one()
self.write({'state': 'closed'})
def get_interest_vals(self, line, vals):
interest_obj = self.env['loan.interest.line']
accrued_amount = line.amount
accrued_interest = 0
accrued_net_interest = 0
accrued_taxes = 0
for year in range(1, int(self.term.term) + 1):
interest = accrued_amount * (line.loan_issue_id.rate / 100)
accrued_amount += interest
taxes_amount = interest * (self.taxes_rate / 100)
net_interest = interest - taxes_amount
accrued_interest += interest
accrued_net_interest += net_interest
accrued_taxes += taxes_amount
vals['interest'] = interest
vals['net_interest'] = net_interest
vals['taxes_amount'] = taxes_amount
vals['accrued_amount'] = accrued_amount
vals['accrued_interest'] = accrued_interest
vals['accrued_net_interest'] = accrued_net_interest
vals['accrued_taxes'] = accrued_taxes
vals['name'] = year
interest_obj.create(vals)
@api.multi
def compute_loan_interest(self):
self.ensure_one()
if self.interest_payment == 'end':
due_date = self.term_date
for line in self.loan_issue_lines:
# TODO remove this line
line.interest_lines.unlink()
# Please Do not Forget
vals = {
'issue_line': line.id,
'due_date': due_date,
'taxes_rate': self.taxes_rate
}
self.get_interest_vals(line, vals)
rounded_term = int(self.term.term)
if self.term.term - rounded_term > 0:
# TODO Handle this case
_logger.info("todo")

95
easy_my_coop_loan/models/loan_issue_line.py

@ -0,0 +1,95 @@
from datetime import datetime
from odoo import api, fields, models
class LoanIssueLine(models.Model):
_name = 'loan.issue.line'
_order = 'date desc, id'
@api.multi
@api.depends('quantity', 'face_value')
def _compute_amount(self):
for line in self:
line.amount = line.face_value * line.quantity
name = fields.Char(string="Reference")
loan_issue_id = fields.Many2one('loan.issue',
string="Loan issue",
required=True)
interest_lines = fields.One2many('loan.interest.line',
'issue_line',
string="Interest lines")
quantity = fields.Integer(string='quantity',
required=True)
face_value = fields.Monetary(related='loan_issue_id.face_value',
currency_field='company_currency_id',
store=True,
readonly=True)
partner_id = fields.Many2one('res.partner',
string="Subscriber",
required=True)
date = fields.Date(string="Subscription date",
default=lambda self: datetime.strftime(datetime.now(),
'%Y-%m-%d'),
required=True)
amount = fields.Monetary(string="Subscribed amount",
currency_field='company_currency_id',
compute='_compute_amount',
store=True)
state = fields.Selection([('draft', 'Draft'),
('subscribed', 'Subscribed'),
('waiting', 'Waiting payment'),
('paid', 'paid'),
('cancelled', 'Cancelled'),
('ended', 'Ended')],
string="State",
required=True,
default="draft")
company_currency_id = fields.Many2one('res.currency',
related='company_id.currency_id',
string="Company Currency",
readonly=True)
company_id = fields.Many2one('res.company',
related='loan_issue_id.company_id',
string="Company",
readonly=True)
def create(self, vals):
mail_template = 'easy_my_coop_loan.loan_subscription_confirmation'
confirmation_mail_template = self.env.ref(mail_template, False)
line = super(LoanIssueLine, self).create(vals)
confirmation_mail_template.send_mail(line.id)
return line
@api.multi
def action_draft(self):
for line in self:
line.write({'state': 'draft'})
@api.multi
def action_validate(self):
for line in self:
line.write({'state': 'subscribed'})
@api.multi
def action_request_payment(self):
mail_template = 'easy_my_coop_loan.loan_issue_payment_request'
pay_req_mail_template = self.env.ref(mail_template, False)
for line in self:
pay_req_mail_template.send_mail(line.id)
line.write({'state': 'waiting'})
@api.multi
def action_cancel(self):
for line in self:
line.write({'state': 'cancelled'})
@api.multi
def action_paid(self):
for line in self:
line.write({'state': 'paid'})

9
easy_my_coop_loan/models/partner.py

@ -0,0 +1,9 @@
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
loan_line_ids = fields.One2many('loan.issue.line',
'partner_id',
string="Name")

9
easy_my_coop_loan/security/ir.model.access.csv

@ -0,0 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_loan_issue_user,loan.issue,model_loan_issue,base.group_user,1,0,0,0
access_loan_issue_manager,loan.issue,model_loan_issue,easy_my_coop.group_easy_my_coop_manager,1,1,1,0
access_loan_issue_line_user,loan.issue.line,model_loan_issue_line,base.group_user,1,0,0,0
access_loan_issue_line_manager,loan.issue.line,model_loan_issue_line,easy_my_coop.group_easy_my_coop_manager,1,1,1,0
access_loan_term_user,loan.term,model_loan_term,base.group_user,1,0,0,0
access_loan_term_manager,loan.term,model_loan_term,easy_my_coop.group_easy_my_coop_manager,1,1,1,0
access_loan_interest_line_user,loan.interest.line,model_loan_interest_line,base.group_user,1,0,0,0
access_loan_interest_line_manager,loan.interest.line,model_loan_interest_line,easy_my_coop.group_easy_my_coop_manager,1,1,1,1

163
easy_my_coop_loan/views/loan_view.xml

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem name="Loan Issue" id="menu_easy_my_coop_main_loan_issue" parent="easy_my_coop.menu_main_easy_my_coop" sequence="20" groups="easy_my_coop.group_easy_my_coop_user"/>
<record id="view_loan_issue_tree" model="ir.ui.view">
<field name="name">loan.issue.tree</field>
<field name="model">loan.issue</field>
<field name="arch" type="xml">
<tree string="Loan issues">
<field name="name" />
<field name="subscription_start_date" />
<field name="subscription_end_date" />
<field name="term_date" />
<field name="term" />
<field name="rate" />
<field name="minimum_amount" />
<field name="maximum_amount" />
<field name="subscribed_amount" />
<field name="user_id" />
<field name="state" />
</tree>
</field>
</record>
<record id="view_loan_issue_form" model="ir.ui.view">
<field name="name">loan.issue.form</field>
<field name="model">loan.issue</field>
<field name="arch" type="xml">
<form string="Loan issue">
<header>
<button name="action_confirm" string="Confirm" type="object" states="draft"
groups="easy_my_coop.group_easy_my_coop_manager"/>
<button name="action_cancel" string="Cancel" type="object" states="draft,ongoing"
confirm="Are you sure you want to cancel this loan issue?"
groups="easy_my_coop.group_easy_my_coop_manager"/>
<button name="action_open" string="Open" type="object"
states="confirmed" groups="easy_my_coop.group_easy_my_coop_manager"/>
<button name="action_close" string="Close" type="object" states="ongoing"
confirm="Are you sure you want to close this loan issue?"
groups="easy_my_coop.group_easy_my_coop_manager"/>
<button name="action_draft" string="Set to draft"
type="object" states="confirmed,cancelled"
groups="easy_my_coop.group_easy_my_coop_manager"/>
<button name="compute_loan_interest" string="Compute interest"
type="object" states="closed,ongoing"
groups="easy_my_coop.group_easy_my_coop_manager"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,ongoing,closed"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_display" type="object"
class="oe_stat_button" icon="fa-globe">
<field name="display_on_website" widget="website_button"/>
</button>
</div>
<group>
<group>
<field name="name" />
<field name="is_loan" />
<field name="is_bond" />
<field name="default_issue" />
<field name="face_value" />
<field name="minimum_amount" />
<field name="maximum_amount" />
<field name="maximum_amount_per_sub" />
<field name="subscribed_amount" />
<field name="by_individual" />
<field name="by_company" />
</group>
<group>
<field name="user_id" widget="selection" />
<field name="rate" />
<field name="taxes_rate" />
<field name="subscription_start_date" />
<field name="subscription_end_date" />
<field name="term_date" />
<field name="term" widget="selection"/>
<field name="interest_payment" widget="selection" />
</group>
</group>
<notebook>
<page string="Lines">
<field name="loan_issue_lines">
<tree delete="false">
<field name="name" />
<field name="partner_id" />
<field name="date" />
<field name="quantity" />
<field name="face_value" />
<field name="amount" />
<field name="state" />
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="action_loan_issue" model="ir.actions.act_window">
<field name="name">Loan issue</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">loan.issue</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem action="action_loan_issue" id="loan_issue_menu" parent="menu_easy_my_coop_main_loan_issue" sequence="25" />
<record id="view_loan_issue_line_form" model="ir.ui.view">
<field name="name">loan.issue.line.form</field>
<field name="model">loan.issue.line</field>
<field name="arch" type="xml">
<form string="Loan issue">
<header>
<button name="action_validate" string="Validate"
type="object" states="draft" />
<button name="action_request_payment" string="Request Payment"
type="object" states="subscribed" />
<button name="action_cancel" string="Cancel" type="object"
states="draft,subscribed,waiting"
confirm="Are you sure you want to cancel this loan subscription ?" />
<button name="action_draft" string="Set to draft"
type="object" states="cancelled" />
<button name="action_paid" string="Paid"
type="object" states="waiting" />
<field name="state" widget="statusbar" />
</header>
<sheet>
<group>
<group>
<field name="name" />
<field name="quantity" />
<field name="face_value" />
</group>
<group>
<field name="date" />
<field name="partner_id" />
<field name="amount" />
</group>
</group>
<notebook>
<page string="Interst lines">
<field name="interest_lines">
<tree delete="false" create="false">
<field name="name" />
<field name="amount" />
<field name="accrued_amount" />
<field name="interest" />
<field name="net_interest" />
<field name="taxes_amount" />
<field name="due_date" />
<field name="state" />
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
</odoo>

23
easy_my_coop_loan/views/partner_view.xml

@ -0,0 +1,23 @@
<odoo>
<record id="view_partner_form_loan_issue" model="ir.ui.view">
<field name="name">res.partner.form.loan.issue</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">
<page name="share_subscription" position="after">
<page string="Loan issue lines" name="loan_issue_lines" groups="easy_my_coop.group_easy_my_coop_user">
<field name="loan_line_ids">
<tree create="false" delete="false" edit="false">
<field name="loan_issue_id"/>
<field name="date"/>
<field name="quantity"/>
<field name="face_value"/>
<field name="amount"/>
<field name="state"/>
</tree>
</field>
</page>
</page>
</field>
</record>
</odoo>

40
easy_my_coop_loan/views/term_view.xml

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_loan_term_tree" model="ir.ui.view">
<field name="name">loan.term.tree</field>
<field name="model">loan.term</field>
<field name="arch" type="xml">
<tree string="Loan terms">
<field name="name" />
<field name="term" />
</tree>
</field>
</record>
<record id="view_loan_term_form" model="ir.ui.view">
<field name="name">loan.term.form</field>
<field name="model">loan.term</field>
<field name="arch" type="xml">
<form string="Loan terms">
<group>
<group>
<field name="name" />
</group>
<group>
<field name="term" />
</group>
</group>
</form>
</field>
</record>
<record id="action_loan_term" model="ir.actions.act_window">
<field name="name">Loan term</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">loan.term</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem action="action_loan_term" id="loan_term_menu" parent="easy_my_coop.menu_easy_my_coop_config" sequence="5" />
</odoo>

1
easy_my_coop_loan_website/__init__.py

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

26
easy_my_coop_loan_website/__manifest__.py

@ -0,0 +1,26 @@
# Copyright 2019 Coop IT Easy SCRLfs (<http://www.coopiteasy.be>)
# - Houssine BAKKALI - <houssine@coopiteasy.be>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Easy My Coop Loan Issues Website",
"version": "12.0.1.0.1",
"depends": [
"easy_my_coop_loan",
"easy_my_coop_website",
"website",
],
"author": "Coop IT Easy SCRLfs",
"category": "Cooperative management",
"website": "http://www.coopiteasy.be",
"license": "AGPL-3",
"description": """
This module implements the subscription page for bonds and
subordinated loans.
""",
'data': [
'data/website_loan_data.xml',
'template/loan_issue_template.xml'
],
'installable': True,
}

1
easy_my_coop_loan_website/controllers/__init__.py

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

93
easy_my_coop_loan_website/controllers/main.py

@ -0,0 +1,93 @@
from odoo import http
from odoo.http import request
from odoo.tools.translate import _
class WebsiteLoanIssueSubscription(http.Controller):
@http.route(['/subscription/get_loan_issue'],
type='json',
auth="user",
methods=['POST'], website=True)
def get_loan_issue(self, loan_issue_id, **kw):
loan_issue_obj = request.env['loan.issue']
if loan_issue_id:
loan_issue = loan_issue_obj.sudo().browse(int(loan_issue_id))
return {
loan_issue.id: {
'max_amount': loan_issue.maximum_amount_per_sub,
'face_value': loan_issue.face_value,
}
}
else:
return False
@http.route(['/subscription/loan_issue_form'],
type='http', auth="user", website=True)
def display_loan_issue_subscription_page(self, **kwargs):
values = {}
partner = request.env.user.partner_id
is_company = partner.is_company
values = self.fill_values(values, is_company)
values.update(kwargs=kwargs.items())
return request.render(
"easy_my_coop_loan_website.loanissuesubscription",
values)
def get_loan_issues(self, is_company):
loan_obj = request.env['loan.issue']
loan_issues = loan_obj.sudo().get_web_issues(is_company)
return loan_issues
def fill_values(self, values, is_company):
company = request.website.company_id
loan_issues = self.get_loan_issues(is_company)
values['loan_issues'] = loan_issues
values['company'] = company
if not values.get('loan_issue_id'):
for loan_issue in loan_issues:
if loan_issue.default_issue is True:
values['loan_issue_id'] = loan_issue.id
break
if not values.get('loan_issue_id', False) and loan_issues:
values['loan_issue_id'] = loan_issues[0].id
return values
def validation(self, loan_issue, kwargs):
sub_amount = kwargs.get('subscription_amount')
redirect = "easy_my_coop_loan_website.loanissuesubscription"
values = {}
if not loan_issue:
values["error_msg"] = _("The selected loan issue is not found")
return request.render(redirect, values)
if sub_amount:
values["error_msg"] = _("The amount shoud be of monetary type")
return request.render(redirect, values)
return True
@http.route(['/subscription/subscribe_loan_issue'],
type='http',
auth="user", website=True)
def loan_issue_subscription(self, **kwargs):
loan_obj = request.env['loan.issue']
loan_obj_line = request.env['loan.issue.line']
loan_issue = loan_obj.sudo().browse(kwargs.get('loan_issue_id'))
partner = request.env.user.partner_id
if self.validation(loan_issue, kwargs):
values = {
'loan_issue_id': loan_issue.id,
'partner_id': partner.id,
'amount': kwargs['subscription_amount'],
'state': 'subscribed'
}
loan_obj_line.sudo().create(values)
return request.render("easy_my_coop_website.cooperator_thanks", values)

16
easy_my_coop_loan_website/data/website_loan_data.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="menu_subscribeloanissue" model="website.menu">
<field name="name">Subscribe to loan issue</field>
<field name="url">/subscription/loan_issue_form</field>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">65</field>
</record>
<record id="subscribe_loan_issue_page" model="website.page">
<field name="website_published">True</field>
<field name="url">/subscription/loan_issue_form</field>
<field name="view_id" ref="menu_subscribeloanissue"/>
</record>
</data>
</odoo>

23
easy_my_coop_loan_website/static/src/js/loan_issue.js

@ -0,0 +1,23 @@
odoo.define('easy_my_coop_loan_website.oe_easymy_coop_loan', function (require) {
$(document).ready(function () {
"use strict";
var ajax = require('web.ajax');
$('.oe_easymy_coop_loan').each(function () {
var oe_easymy_coop_loan = this;
$('#loan_issue').change(function () {
var loan_issue_id = $("#loan_issue").val();
ajax.jsonRpc("/subscription/get_loan_issue", 'call', {
'loan_issue_id': loan_issue_id
})
.then(function (data) {
if (data !== false) {
$("#subscription_amount").prop('max',data[loan_issue_id].maximum_amount_per_sub);
$("#subscription_amount").prop('step',data[loan_issue_id].face_value);
}
});
});
$('#loan_issue').trigger('change');
});
});
});

54
easy_my_coop_loan_website/template/loan_issue_template.xml

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_frontend" inherit_id="web.assets_frontend" name="Coop">
<xpath expr="." position="inside">
<script type="text/javascript" src="/easy_my_coop_loan_website/static/src/js/loan_issue.js"></script>
</xpath>
</template>
<template id="loanissuesubscription" name="Loan Issue Subscription">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure"/>
<div class="container oe_easymy_coop_loan">
<h2 class="energie">Subscribe to Loan Issue</h2><br/>
<div class="row">
<div class="col-md-8">
<form action="/subscription/subscribe_loan_issue" 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 #{error and 'loan_issue_id' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="share_product_id">Loan issue</label>
<select id="loan_issue" name="loan_issue_id" class="col-md-7 col-sm-8 form-control" style="width:54%;margin-left:15px">
<t t-foreach="loan_issues or []" t-as="loan_issue">
<option t-att-value="loan_issue.id" t-att-selected="loan_issue.id == int(loan_issue_id)"><t t-esc="loan_issue.name"/></option>
</t>
</select>
</div>
<div t-attf-class="form-group #{error and 'subscription_amount' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" style="width:25%" for="subscription_amount">Amount</label>
<input id="subscription_amount" type="number" class="col-md-7 col-sm-8 form-control total" name="subscription_amount" min="0" step="100" max="5000"/>
</div>
<table style="margin-left:195px">
<tr>
<!--<td width="80%">
<div class="g-recaptcha" t-att-data-sitekey="website.recaptcha_key_site" 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>
</form>
</div>
</div>
</div>
</div>
</t>
</template>
</odoo>

8
easy_my_coop_website/controllers/main.py

@ -2,9 +2,9 @@ import base64
from datetime import datetime from datetime import datetime
import re import re
from openerp import http
from openerp.http import request
from openerp.tools.translate import _
from odoo import http
from odoo.http import request
from odoo.tools.translate import _
# Only use for behavior, don't stock it # Only use for behavior, don't stock it
_TECHNICAL = ['view_from', 'view_callback'] _TECHNICAL = ['view_from', 'view_callback']
@ -280,7 +280,7 @@ class WebsiteSubscription(http.Controller):
max_amount = max_amount - partner.total_value max_amount = max_amount - partner.total_value
if company.unmix_share_type: if company.unmix_share_type:
share = self.get_selected_share(kwargs) share = self.get_selected_share(kwargs)
if int(partner.cooperator_type) != share.id:
if partner.cooperator_type != share.default_code:
values = self.fill_values(values, is_company, logged) values = self.fill_values(values, is_company, logged)
values["error_msg"] = (_("You can't subscribe two " values["error_msg"] = (_("You can't subscribe two "
"different types of share")) "different types of share"))

Loading…
Cancel
Save