robin.keunen
5 years ago
55 changed files with 3943 additions and 3370 deletions
-
2.isort.cfg
-
42README.md
-
100easy_my_coop/__manifest__.py
-
59easy_my_coop/migrations/8.0.1.0/pre-migration.py
-
372easy_my_coop/models/account_invoice.py
-
27easy_my_coop/models/account_journal.py
-
176easy_my_coop/models/company.py
-
1713easy_my_coop/models/coop.py
-
767easy_my_coop/models/operation_request.py
-
185easy_my_coop/models/partner.py
-
78easy_my_coop/models/product.py
-
29easy_my_coop/models/res_partner_bank.py
-
32easy_my_coop/report/account_invoice_report.py
-
10easy_my_coop/wizard/account_invoice_refund.py
-
216easy_my_coop/wizard/create_subscription_from_partner.py
-
49easy_my_coop/wizard/update_partner_info.py
-
44easy_my_coop/wizard/update_share_line.py
-
8easy_my_coop/wizard/validate_subscription_request.py
-
19easy_my_coop_be/__manifest__.py
-
53easy_my_coop_be/models/coop.py
-
24easy_my_coop_be/models/partner.py
-
46easy_my_coop_ch/__manifest__.py
-
47easy_my_coop_ch/models/coop.py
-
34easy_my_coop_ch/models/partner.py
-
63easy_my_coop_ch/views/certificate_template.xml
-
37easy_my_coop_dividend/__manifest__.py
-
403easy_my_coop_dividend/models/dividend.py
-
31easy_my_coop_export_xlsx/__manifest__.py
-
603easy_my_coop_export_xlsx/wizard/export_global_wizard.py
-
17easy_my_coop_fr/__manifest__.py
-
40easy_my_coop_fr/models/coop.py
-
26easy_my_coop_fr/models/partner.py
-
56easy_my_coop_loan/__manifest__.py
-
124easy_my_coop_loan/models/interest_line.py
-
196easy_my_coop_loan/models/loan.py
-
120easy_my_coop_loan/models/loan_issue_line.py
-
6easy_my_coop_loan/models/partner.py
-
7easy_my_coop_loan/tests/test_emc_loan.py
-
45easy_my_coop_loan_website/__manifest__.py
-
198easy_my_coop_loan_website/controllers/main.py
-
2easy_my_coop_taxshelter_report/__manifest__.py
-
6easy_my_coop_taxshelter_report/models/mail_template.py
-
82easy_my_coop_taxshelter_report/models/tax_shelter_declaration.py
-
22easy_my_coop_website/__manifest__.py
-
408easy_my_coop_website/controllers/main.py
-
23easy_my_coop_website_portal/__manifest__.py
-
303easy_my_coop_website_portal/controllers/main.py
-
33easy_my_coop_website_taxshelter/__manifest__.py
-
122easy_my_coop_website_taxshelter/controllers/main.py
-
16partner_age/__manifest__.py
-
75partner_age/models/partner.py
-
28theme_light/__manifest__.py
-
32website_recaptcha_reloaded/__manifest__.py
-
18website_recaptcha_reloaded/models/res_config.py
-
39website_recaptcha_reloaded/website.py
@ -1,2 +1,44 @@ |
|||||
# vertical-cooperative |
# vertical-cooperative |
||||
This repository gather odoo modules for cooperatives |
This repository gather odoo modules for cooperatives |
||||
|
|
||||
|
# MAKE TRAVIS GREEN AGAIN |
||||
|
|
||||
|
pre-commit still issues these messages. They need to be fixed. |
||||
|
|
||||
|
``` |
||||
|
************* Module easy_my_coop.models.partner |
||||
|
easy_my_coop/models/partner.py:56: [E8103(sql-injection), ResPartner._invoice_total] SQL injection risk. Use parameters if you can. - More info https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#no-sql-injection |
||||
|
************* Module partner_age.models.partner |
||||
|
partner_age/models/partner.py:13: [E8103(sql-injection), ResPartner._search_age] SQL injection risk. Use parameters if you can. - More info https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#no-sql-injection |
||||
|
************* Module easy_my_coop_taxshelter_report.models.tax_shelter_declaration |
||||
|
easy_my_coop_taxshelter_report/models/tax_shelter_declaration.py:325: [E8102(invalid-commit), TaxShelterCertificate.send_certificates] Use of cr.commit() directly - More info https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#never-commit-the-transaction |
||||
|
************* Module easy_my_coop.models.account_invoice |
||||
|
easy_my_coop/models/account_invoice.py:11: [C8104(class-camelcase), account_invoice] Use `CamelCase` "AccountInvoice" in class name "account_invoice". You can use oca-autopep8 of https://github.com/OCA/maintainer-tools to auto fix it. |
||||
|
************* Module easy_my_coop.models.operation_request |
||||
|
easy_my_coop/models/operation_request.py:12: [C8104(class-camelcase), operation_request] Use `CamelCase` "OperationRequest" in class name "operation_request". You can use oca-autopep8 of https://github.com/OCA/maintainer-tools to auto fix it. |
||||
|
************* Module easy_my_coop.models.coop |
||||
|
easy_my_coop/models/coop.py:287: [C8108(method-compute), SubscriptionRequest] Name of compute method should start with "_compute_" |
||||
|
************* Module website_recaptcha_reloaded.models.res_config |
||||
|
website_recaptcha_reloaded/models/res_config.py:7: [C8104(class-camelcase), website_config_settings] Use `CamelCase` "WebsiteConfigSettings" in class name "website_config_settings". You can use oca-autopep8 of https://github.com/OCA/maintainer-tools to auto fix it. |
||||
|
************* Module easy_my_coop.models.company |
||||
|
easy_my_coop/models/company.py:61: [C8108(method-compute), ResCompany] Name of compute method should start with "_compute_" |
||||
|
|
||||
|
pylint with mandatory checks.............................................Failed |
||||
|
- hook id: pylint |
||||
|
- exit code: 18 |
||||
|
|
||||
|
************* Module easy_my_coop.models.partner |
||||
|
easy_my_coop/models/partner.py:56: [E8103(sql-injection), ResPartner._invoice_total] SQL injection risk. Use parameters if you can. - More info https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#no-sql-injection |
||||
|
************* Module partner_age.models.partner |
||||
|
partner_age/models/partner.py:13: [E8103(sql-injection), ResPartner._search_age] SQL injection risk. Use parameters if you can. - More info https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#no-sql-injection |
||||
|
************* Module easy_my_coop.models.account_invoice |
||||
|
easy_my_coop/models/account_invoice.py:11: [C8104(class-camelcase), account_invoice] Use `CamelCase` "AccountInvoice" in class name "account_invoice". You can use oca-autopep8 of https://github.com/OCA/maintainer-tools to auto fix it. |
||||
|
************* Module easy_my_coop.models.operation_request |
||||
|
easy_my_coop/models/operation_request.py:12: [C8104(class-camelcase), operation_request] Use `CamelCase` "OperationRequest" in class name "operation_request". You can use oca-autopep8 of https://github.com/OCA/maintainer-tools to auto fix it. |
||||
|
************* Module easy_my_coop.models.coop |
||||
|
easy_my_coop/models/coop.py:287: [C8108(method-compute), SubscriptionRequest] Name of compute method should start with "_compute_" |
||||
|
************* Module website_recaptcha_reloaded.models.res_config |
||||
|
website_recaptcha_reloaded/models/res_config.py:7: [C8104(class-camelcase), website_config_settings] Use `CamelCase` "WebsiteConfigSettings" in class name "website_config_settings". You can use oca-autopep8 of https://github.com/OCA/maintainer-tools to auto fix it. |
||||
|
************* Module easy_my_coop.models.company |
||||
|
easy_my_coop/models/company.py:61: [C8108(method-compute), ResCompany] Name of compute method should start with "_compute_" |
||||
|
``` |
@ -1,30 +1,29 @@ |
|||||
# -*- 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) |
|
||||
|
|
||||
|
import logging |
||||
|
|
||||
|
from openerp.openupgrade import openupgrade |
||||
|
|
||||
|
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) |
@ -1,175 +1,197 @@ |
|||||
# Copyright 2019 Coop IT Easy SCRL fs |
|
||||
# Houssine Bakkali <houssine@coopiteasy.be> |
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|
||||
|
|
||||
|
|
||||
from datetime import datetime |
|
||||
|
|
||||
from odoo 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 create_user(self, partner): |
|
||||
user_obj = self.env['res.users'] |
|
||||
email = partner.email |
|
||||
|
|
||||
user = user_obj.search([('login', '=', email)]) |
|
||||
if not user: |
|
||||
user = user_obj.search([('login', '=', email), |
|
||||
('active', '=', False)]) |
|
||||
if user: |
|
||||
user.sudo().write({'active': True}) |
|
||||
else: |
|
||||
user_values = {'partner_id': partner.id, 'login': email} |
|
||||
user = user_obj.sudo()._signup_create_user(user_values) |
|
||||
user.sudo().with_context({'create_user': True}).action_reset_password() |
|
||||
|
|
||||
return user |
|
||||
|
|
||||
def get_mail_template_certificate(self): |
|
||||
if self.partner_id.member: |
|
||||
mail_template = 'easy_my_coop.email_template_certificat_increase' |
|
||||
else: |
|
||||
mail_template = 'easy_my_coop.email_template_certificat' |
|
||||
return self.env.ref(mail_template) |
|
||||
|
|
||||
def get_sequence_register(self): |
|
||||
return self.env.ref('easy_my_coop.sequence_subscription', False) |
|
||||
|
|
||||
def get_sequence_operation(self): |
|
||||
return self.env.ref('easy_my_coop.sequence_register_operation', False) |
|
||||
|
|
||||
def get_share_line_vals(self, line, effective_date): |
|
||||
return { |
|
||||
'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 |
|
||||
} |
|
||||
|
|
||||
def get_subscription_register_vals(self, line, effective_date): |
|
||||
return { |
|
||||
'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' |
|
||||
} |
|
||||
|
|
||||
def get_membership_vals(self): |
|
||||
# flag the partner as an effective member |
|
||||
# if not yet cooperator we generate a cooperator number |
|
||||
vals = {} |
|
||||
if self.partner_id.member is False \ |
|
||||
and self.partner_id.old_member is False: |
|
||||
sequence_id = self.get_sequence_register() |
|
||||
sub_reg_num = sequence_id.next_by_id() |
|
||||
vals = {'member': True, 'old_member': False, |
|
||||
'cooperator_register_number': int(sub_reg_num) |
|
||||
} |
|
||||
elif self.partner_id.old_member: |
|
||||
vals = {'member': True, 'old_member': False} |
|
||||
|
|
||||
return vals |
|
||||
|
|
||||
def set_membership(self): |
|
||||
vals = self.get_membership_vals() |
|
||||
self.partner_id.write(vals) |
|
||||
|
|
||||
return True |
|
||||
|
|
||||
def send_certificate_email(self, certificate_email_template, sub_reg_line): |
|
||||
# we send the email with the certificate in attachment |
|
||||
certificate_email_template.sudo().send_mail(self.partner_id.id, False) |
|
||||
|
|
||||
def set_cooperator_effective(self, effective_date): |
|
||||
sub_register_obj = self.env['subscription.register'] |
|
||||
share_line_obj = self.env['share.line'] |
|
||||
|
|
||||
certificate_email_template = self.get_mail_template_certificate() |
|
||||
|
|
||||
self.set_membership() |
|
||||
|
|
||||
sequence_operation = self.get_sequence_operation() |
|
||||
sub_reg_operation = sequence_operation.next_by_id() |
|
||||
|
|
||||
for line in self.invoice_line_ids: |
|
||||
sub_reg_vals = self.get_subscription_register_vals(line, |
|
||||
effective_date) |
|
||||
sub_reg_vals['name'] = sub_reg_operation |
|
||||
sub_reg_vals['register_number_operation'] = int(sub_reg_operation) |
|
||||
|
|
||||
sub_reg_line = sub_register_obj.create(sub_reg_vals) |
|
||||
|
|
||||
share_line_vals = self.get_share_line_vals(line, effective_date) |
|
||||
share_line_obj.create(share_line_vals) |
|
||||
|
|
||||
if line.product_id.mail_template: |
|
||||
certificate_email_template = line.product_id.mail_template |
|
||||
|
|
||||
self.send_certificate_email(certificate_email_template, sub_reg_line) |
|
||||
|
|
||||
if self.company_id.create_user: |
|
||||
self.create_user(self.partner_id) |
|
||||
|
|
||||
return True |
|
||||
|
|
||||
def post_process_confirm_paid(self, effective_date): |
|
||||
self.set_cooperator_effective(effective_date) |
|
||||
|
|
||||
return True |
|
||||
|
|
||||
def get_refund_domain(self, invoice): |
|
||||
return [ |
|
||||
('type', '=', 'out_refund'), |
|
||||
('origin', '=', invoice.move_name) |
|
||||
] |
|
||||
|
|
||||
@api.multi |
|
||||
def action_invoice_paid(self): |
|
||||
super(account_invoice, self).action_invoice_paid() |
|
||||
for invoice in self: |
|
||||
# we check if there is an open refund for this invoice. in this |
|
||||
# case we don't run the process_subscription function as the |
|
||||
# invoice has been reconciled with a refund and not a payment. |
|
||||
domain = self.get_refund_domain(invoice) |
|
||||
refund = self.search(domain) |
|
||||
|
|
||||
if invoice.partner_id.cooperator \ |
|
||||
and invoice.release_capital_request \ |
|
||||
and invoice.type == 'out_invoice' and not refund: |
|
||||
# take the effective date from the payment. |
|
||||
# by default the confirmation date is the payment date |
|
||||
effective_date = datetime.now().strftime("%d/%m/%Y") |
|
||||
|
|
||||
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) |
|
||||
# if there is a open refund we mark the subscription as cancelled |
|
||||
elif invoice.partner_id.cooperator \ |
|
||||
and invoice.release_capital_request \ |
|
||||
and invoice.type == 'out_invoice' and refund: |
|
||||
invoice.subscription_request.state = 'cancelled' |
|
||||
return True |
|
||||
|
# Copyright 2019 Coop IT Easy SCRL fs |
||||
|
# Houssine Bakkali <houssine@coopiteasy.be> |
||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
|
||||
|
from datetime import datetime |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class AccountInvoice(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(AccountInvoice, self)._prepare_refund( |
||||
|
invoice, date_invoice, date, description, journal_id |
||||
|
) |
||||
|
values["release_capital_request"] = self.release_capital_request |
||||
|
|
||||
|
return values |
||||
|
|
||||
|
def create_user(self, partner): |
||||
|
user_obj = self.env["res.users"] |
||||
|
email = partner.email |
||||
|
|
||||
|
user = user_obj.search([("login", "=", email)]) |
||||
|
if not user: |
||||
|
user = user_obj.search( |
||||
|
[("login", "=", email), ("active", "=", False)] |
||||
|
) |
||||
|
if user: |
||||
|
user.sudo().write({"active": True}) |
||||
|
else: |
||||
|
user_values = {"partner_id": partner.id, "login": email} |
||||
|
user = user_obj.sudo()._signup_create_user(user_values) |
||||
|
user.sudo().with_context( |
||||
|
{"create_user": True} |
||||
|
).action_reset_password() |
||||
|
|
||||
|
return user |
||||
|
|
||||
|
def get_mail_template_certificate(self): |
||||
|
if self.partner_id.member: |
||||
|
mail_template = "easy_my_coop.email_template_certificat_increase" |
||||
|
else: |
||||
|
mail_template = "easy_my_coop.email_template_certificat" |
||||
|
return self.env.ref(mail_template) |
||||
|
|
||||
|
def get_sequence_register(self): |
||||
|
return self.env.ref("easy_my_coop.sequence_subscription", False) |
||||
|
|
||||
|
def get_sequence_operation(self): |
||||
|
return self.env.ref("easy_my_coop.sequence_register_operation", False) |
||||
|
|
||||
|
def get_share_line_vals(self, line, effective_date): |
||||
|
return { |
||||
|
"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, |
||||
|
} |
||||
|
|
||||
|
def get_subscription_register_vals(self, line, effective_date): |
||||
|
return { |
||||
|
"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", |
||||
|
} |
||||
|
|
||||
|
def get_membership_vals(self): |
||||
|
# flag the partner as an effective member |
||||
|
# if not yet cooperator we generate a cooperator number |
||||
|
vals = {} |
||||
|
if ( |
||||
|
self.partner_id.member is False |
||||
|
and self.partner_id.old_member is False |
||||
|
): |
||||
|
sequence_id = self.get_sequence_register() |
||||
|
sub_reg_num = sequence_id.next_by_id() |
||||
|
vals = { |
||||
|
"member": True, |
||||
|
"old_member": False, |
||||
|
"cooperator_register_number": int(sub_reg_num), |
||||
|
} |
||||
|
elif self.partner_id.old_member: |
||||
|
vals = {"member": True, "old_member": False} |
||||
|
|
||||
|
return vals |
||||
|
|
||||
|
def set_membership(self): |
||||
|
vals = self.get_membership_vals() |
||||
|
self.partner_id.write(vals) |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
def send_certificate_email(self, certificate_email_template, sub_reg_line): |
||||
|
# we send the email with the certificate in attachment |
||||
|
certificate_email_template.sudo().send_mail(self.partner_id.id, False) |
||||
|
|
||||
|
def set_cooperator_effective(self, effective_date): |
||||
|
sub_register_obj = self.env["subscription.register"] |
||||
|
share_line_obj = self.env["share.line"] |
||||
|
|
||||
|
certificate_email_template = self.get_mail_template_certificate() |
||||
|
|
||||
|
self.set_membership() |
||||
|
|
||||
|
sequence_operation = self.get_sequence_operation() |
||||
|
sub_reg_operation = sequence_operation.next_by_id() |
||||
|
|
||||
|
for line in self.invoice_line_ids: |
||||
|
sub_reg_vals = self.get_subscription_register_vals( |
||||
|
line, effective_date |
||||
|
) |
||||
|
sub_reg_vals["name"] = sub_reg_operation |
||||
|
sub_reg_vals["register_number_operation"] = int(sub_reg_operation) |
||||
|
|
||||
|
sub_reg_line = sub_register_obj.create(sub_reg_vals) |
||||
|
|
||||
|
share_line_vals = self.get_share_line_vals(line, effective_date) |
||||
|
share_line_obj.create(share_line_vals) |
||||
|
|
||||
|
if line.product_id.mail_template: |
||||
|
certificate_email_template = line.product_id.mail_template |
||||
|
|
||||
|
self.send_certificate_email(certificate_email_template, sub_reg_line) |
||||
|
|
||||
|
if self.company_id.create_user: |
||||
|
self.create_user(self.partner_id) |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
def post_process_confirm_paid(self, effective_date): |
||||
|
self.set_cooperator_effective(effective_date) |
||||
|
|
||||
|
return True |
||||
|
|
||||
|
def get_refund_domain(self, invoice): |
||||
|
return [ |
||||
|
("type", "=", "out_refund"), |
||||
|
("origin", "=", invoice.move_name), |
||||
|
] |
||||
|
|
||||
|
@api.multi |
||||
|
def action_invoice_paid(self): |
||||
|
super(AccountInvoice, self).action_invoice_paid() |
||||
|
for invoice in self: |
||||
|
# we check if there is an open refund for this invoice. in this |
||||
|
# case we don't run the process_subscription function as the |
||||
|
# invoice has been reconciled with a refund and not a payment. |
||||
|
domain = self.get_refund_domain(invoice) |
||||
|
refund = self.search(domain) |
||||
|
|
||||
|
if ( |
||||
|
invoice.partner_id.cooperator |
||||
|
and invoice.release_capital_request |
||||
|
and invoice.type == "out_invoice" |
||||
|
and not refund |
||||
|
): |
||||
|
# take the effective date from the payment. |
||||
|
# by default the confirmation date is the payment date |
||||
|
effective_date = datetime.now().strftime("%d/%m/%Y") |
||||
|
|
||||
|
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) |
||||
|
# if there is a open refund we mark the subscription as cancelled |
||||
|
elif ( |
||||
|
invoice.partner_id.cooperator |
||||
|
and invoice.release_capital_request |
||||
|
and invoice.type == "out_invoice" |
||||
|
and refund |
||||
|
): |
||||
|
invoice.subscription_request.state = "cancelled" |
||||
|
return True |
@ -1,14 +1,13 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# Copyright 2019 Coop IT Easy SCRL fs |
|
||||
# Houssine Bakkali <houssine@coopiteasy.be> |
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|
||||
|
|
||||
|
|
||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class AccountJournal(models.Model): |
|
||||
_inherit = "account.journal" |
|
||||
|
|
||||
get_cooperator_payment = fields.Boolean('Get cooperator payments?') |
|
||||
get_general_payment = fields.Boolean(string='Get general payments?') |
|
||||
|
# Copyright 2019 Coop IT Easy SCRL fs |
||||
|
# Houssine Bakkali <houssine@coopiteasy.be> |
||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountJournal(models.Model): |
||||
|
_inherit = "account.journal" |
||||
|
|
||||
|
get_cooperator_payment = fields.Boolean("Get cooperator payments?") |
||||
|
get_general_payment = fields.Boolean(string="Get general payments?") |
@ -1,83 +1,93 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# Copyright 2019 Coop IT Easy SCRL fs |
|
||||
# Houssine Bakkali <houssine@coopiteasy.be> |
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|
||||
|
|
||||
|
|
||||
from odoo import api, fields, models |
|
||||
|
|
||||
|
|
||||
class ResCompany(models.Model): |
|
||||
_inherit = 'res.company' |
|
||||
|
|
||||
def _get_base_logo(self): |
|
||||
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') |
|
||||
self.logo_url = base_url + "/logo.png" |
|
||||
|
|
||||
coop_email_contact = fields.Char(string="Contact email address for the" |
|
||||
" cooperator") |
|
||||
subscription_maximum_amount = fields.Float(string="Maximum authorised" |
|
||||
" 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") |
|
||||
allow_id_card_upload = fields.Boolean(string="Allow ID Card upload") |
|
||||
create_user = fields.Boolean(string="Create user for cooperator", |
|
||||
default=False) |
|
||||
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", |
|
||||
default=True, |
|
||||
help="If checked, A cooperator will be" |
|
||||
" authorised to have only one type" |
|
||||
" of share") |
|
||||
display_logo1 = fields.Boolean(string="Display logo 1") |
|
||||
display_logo2 = fields.Boolean(string="Display logo 2") |
|
||||
bottom_logo1 = fields.Binary(string="Bottom logo 1") |
|
||||
bottom_logo2 = fields.Binary(string="Bottom logo 2") |
|
||||
logo_url = fields.Char(string="logo url", |
|
||||
compute="_get_base_logo") |
|
||||
display_data_policy_approval = fields.Boolean( |
|
||||
help="Choose to display a data policy checkbox on the cooperator" |
|
||||
" website form." |
|
||||
) |
|
||||
data_policy_approval_required = fields.Boolean( |
|
||||
string="Is data policy approval required?" |
|
||||
) |
|
||||
data_policy_approval_text = fields.Html( |
|
||||
translate=True, |
|
||||
help="Text to display aside the checkbox to approve data policy." |
|
||||
) |
|
||||
display_internal_rules_approval = fields.Boolean( |
|
||||
help="Choose to display an internal rules checkbox on the" |
|
||||
" cooperator website form." |
|
||||
) |
|
||||
internal_rules_approval_required = fields.Boolean( |
|
||||
string="Is internal rules approval required?" |
|
||||
) |
|
||||
internal_rules_approval_text = fields.Html( |
|
||||
translate=True, |
|
||||
help="Text to display aside the checkbox to approve internal rules." |
|
||||
) |
|
||||
|
|
||||
@api.onchange('data_policy_approval_required') |
|
||||
def onchange_data_policy_approval_required(self): |
|
||||
if self.data_policy_approval_required: |
|
||||
self.display_data_policy_approval = True |
|
||||
|
|
||||
@api.onchange('internal_rules_approval_required') |
|
||||
def onchange_internal_rules_approval_required(self): |
|
||||
if self.internal_rules_approval_required: |
|
||||
self.display_internal_rules_approval = True |
|
||||
|
# Copyright 2019 Coop IT Easy SCRL fs |
||||
|
# Houssine Bakkali <houssine@coopiteasy.be> |
||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class ResCompany(models.Model): |
||||
|
_inherit = "res.company" |
||||
|
|
||||
|
def _get_base_logo(self): |
||||
|
base_url = ( |
||||
|
self.env["ir.config_parameter"].sudo().get_param("web.base.url") |
||||
|
) |
||||
|
self.logo_url = base_url + "/logo.png" |
||||
|
|
||||
|
coop_email_contact = fields.Char( |
||||
|
string="Contact email address for the" " cooperator" |
||||
|
) |
||||
|
subscription_maximum_amount = fields.Float( |
||||
|
string="Maximum authorised" " 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") |
||||
|
allow_id_card_upload = fields.Boolean(string="Allow ID Card upload") |
||||
|
create_user = fields.Boolean( |
||||
|
string="Create user for cooperator", default=False |
||||
|
) |
||||
|
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", |
||||
|
default=True, |
||||
|
help="If checked, A cooperator will be" |
||||
|
" authorised to have only one type" |
||||
|
" of share", |
||||
|
) |
||||
|
display_logo1 = fields.Boolean(string="Display logo 1") |
||||
|
display_logo2 = fields.Boolean(string="Display logo 2") |
||||
|
bottom_logo1 = fields.Binary(string="Bottom logo 1") |
||||
|
bottom_logo2 = fields.Binary(string="Bottom logo 2") |
||||
|
logo_url = fields.Char(string="logo url", compute="_get_base_logo") |
||||
|
display_data_policy_approval = fields.Boolean( |
||||
|
help="Choose to display a data policy checkbox on the cooperator" |
||||
|
" website form." |
||||
|
) |
||||
|
data_policy_approval_required = fields.Boolean( |
||||
|
string="Is data policy approval required?" |
||||
|
) |
||||
|
data_policy_approval_text = fields.Html( |
||||
|
translate=True, |
||||
|
help="Text to display aside the checkbox to approve data policy.", |
||||
|
) |
||||
|
display_internal_rules_approval = fields.Boolean( |
||||
|
help="Choose to display an internal rules checkbox on the" |
||||
|
" cooperator website form." |
||||
|
) |
||||
|
internal_rules_approval_required = fields.Boolean( |
||||
|
string="Is internal rules approval required?" |
||||
|
) |
||||
|
internal_rules_approval_text = fields.Html( |
||||
|
translate=True, |
||||
|
help="Text to display aside the checkbox to approve internal rules.", |
||||
|
) |
||||
|
|
||||
|
@api.onchange("data_policy_approval_required") |
||||
|
def onchange_data_policy_approval_required(self): |
||||
|
if self.data_policy_approval_required: |
||||
|
self.display_data_policy_approval = True |
||||
|
|
||||
|
@api.onchange("internal_rules_approval_required") |
||||
|
def onchange_internal_rules_approval_required(self): |
||||
|
if self.internal_rules_approval_required: |
||||
|
self.display_internal_rules_approval = True |
1713
easy_my_coop/models/coop.py
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,335 +1,432 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# Copyright 2019 Coop IT Easy SCRL fs |
|
||||
# Houssine Bakkali <houssine@coopiteasy.be> |
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|
||||
|
|
||||
|
|
||||
from datetime import datetime |
|
||||
|
|
||||
from odoo import api, fields, models, _ |
|
||||
from odoo.exceptions import ValidationError |
|
||||
|
|
||||
|
|
||||
class operation_request(models.Model): |
|
||||
_name = 'operation.request' |
|
||||
_description = "Operation request" |
|
||||
|
|
||||
def get_date_now(self): |
|
||||
# fixme odoo 12 uses date types |
|
||||
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_to_product_id = fields.Many2one('product.product', |
|
||||
string='Convert to this share type', |
|
||||
domain=[('is_share', '=', True)]) |
|
||||
share_short_name = fields.Char(related='share_product_id.short_name', |
|
||||
string='Share type name') |
|
||||
share_to_short_name = fields.Char(related='share_to_product_id.short_name', |
|
||||
string='Share to type name') |
|
||||
share_unit_price = fields.Float(related='share_product_id.list_price', |
|
||||
string='Share price') |
|
||||
share_to_unit_price = fields.Float(related='share_to_product_id.list_price', |
|
||||
string='Share to price') |
|
||||
subscription_amount = fields.Float(compute='_compute_subscription_amount', |
|
||||
string='Operation 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()) |
|
||||
|
|
||||
invoice = fields.Many2one('account.invoice', |
|
||||
string="Invoice") |
|
||||
|
|
||||
@api.multi |
|
||||
def approve_operation(self): |
|
||||
for rec in self: |
|
||||
rec.write({'state': 'approved'}) |
|
||||
|
|
||||
@api.multi |
|
||||
def refuse_operation(self): |
|
||||
for rec in self: |
|
||||
rec.write({'state': 'refused'}) |
|
||||
|
|
||||
@api.multi |
|
||||
def submit_operation(self): |
|
||||
for rec in self: |
|
||||
rec.validate() |
|
||||
rec.write({'state': 'waiting'}) |
|
||||
|
|
||||
@api.multi |
|
||||
def cancel_operation(self): |
|
||||
for rec in self: |
|
||||
rec.write({'state': 'cancelled'}) |
|
||||
|
|
||||
@api.multi |
|
||||
def reset_to_draft(self): |
|
||||
for rec in self: |
|
||||
rec.write({'state': 'draft'}) |
|
||||
|
|
||||
def get_total_share_dic(self, partner): |
|
||||
total_share_dic = {} |
|
||||
share_products = self.env['product.product'].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")) |
|
||||
|
|
||||
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 |
|
||||
# an 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 |
|
||||
|
|
||||
def validate(self): |
|
||||
if not self.has_share_type() and \ |
|
||||
self.operation_type in ['sell_back', 'transfer']: |
|
||||
raise ValidationError(_("The cooperator doesn't own this share" |
|
||||
" type. Please choose the appropriate" |
|
||||
" share type.")) |
|
||||
|
|
||||
if self.operation_type in ['sell_back', 'convert', 'transfer']: |
|
||||
total_share_dic = self.get_total_share_dic(self.partner_id) |
|
||||
|
|
||||
if self.quantity > total_share_dic[self.share_product_id.id]: |
|
||||
raise ValidationError(_("The cooperator can't hand over more" |
|
||||
" shares that he/she owns.")) |
|
||||
|
|
||||
if self.operation_type == 'convert': |
|
||||
if self.company_id.unmix_share_type: |
|
||||
if self.share_product_id.code == self.share_to_product_id.code: |
|
||||
raise ValidationError(_("You can't convert the share to" |
|
||||
" the same share type.")) |
|
||||
if self.subscription_amount != self.partner_id.total_value: |
|
||||
raise ValidationError(_("You must convert all the shares" |
|
||||
" to the selected type.")) |
|
||||
else: |
|
||||
if self.subscription_amount != self.partner_id.total_value: |
|
||||
raise ValidationError(_("Converting just part of the" |
|
||||
" shares is not yet implemented")) |
|
||||
elif self.operation_type == 'transfer': |
|
||||
if not self.receiver_not_member and 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 self.partner_id_to.is_company \ |
|
||||
and not self.share_product_id.by_company: |
|
||||
raise ValidationError(_("This share can not be" |
|
||||
" subscribed by a company")) |
|
||||
if not self.partner_id_to.is_company \ |
|
||||
and not self.share_product_id.by_individual: |
|
||||
raise ValidationError(_("This share can not be" |
|
||||
" subscribed an individual")) |
|
||||
if self.receiver_not_member and self.subscription_request \ |
|
||||
and not self.subscription_request.validated: |
|
||||
raise ValidationError(_("The information of the receiver" |
|
||||
" are not correct. Please correct" |
|
||||
" the information before" |
|
||||
" submitting")) |
|
||||
|
|
||||
def get_share_trans_mail_template(self): |
|
||||
return self.env.ref('easy_my_coop.email_template_share_transfer', |
|
||||
False) |
|
||||
|
|
||||
def get_share_update_mail_template(self): |
|
||||
return self.env.ref('easy_my_coop.email_template_share_update', |
|
||||
False) |
|
||||
|
|
||||
def send_share_trans_mail(self, sub_register_line): # Unused argument is used in synergie project. Do not remove. |
|
||||
cert_email_template = self.get_share_trans_mail_template() |
|
||||
cert_email_template.send_mail(self.partner_id_to.id, False) |
|
||||
|
|
||||
def send_share_update_mail(self, sub_register_line): # Unused argument is used in synergie project. Do not remove. |
|
||||
cert_email_template = self.get_share_update_mail_template() |
|
||||
cert_email_template.send_mail(self.partner_id.id, False) |
|
||||
|
|
||||
def get_subscription_register_vals(self, effective_date): |
|
||||
return { |
|
||||
'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, |
|
||||
} |
|
||||
|
|
||||
@api.multi |
|
||||
def execute_operation(self): |
|
||||
self.ensure_one() |
|
||||
|
|
||||
effective_date = self.get_date_now() |
|
||||
sub_request = self.env['subscription.request'] |
|
||||
|
|
||||
self.validate() |
|
||||
|
|
||||
if self.state != 'approved': |
|
||||
raise ValidationError(_("This operation must be approved" |
|
||||
" before to be executed")) |
|
||||
|
|
||||
values = self.get_subscription_register_vals(effective_date) |
|
||||
|
|
||||
if self.operation_type == 'sell_back': |
|
||||
self.hand_share_over(self.partner_id, self.share_product_id, |
|
||||
self.quantity) |
|
||||
elif self.operation_type == 'convert': |
|
||||
amount_to_convert = self.share_unit_price * self.quantity |
|
||||
convert_quant = int(amount_to_convert / self.share_to_product_id.list_price) |
|
||||
remainder = amount_to_convert % self.share_to_product_id.list_price |
|
||||
|
|
||||
if convert_quant > 0 and remainder == 0: |
|
||||
share_ids = self.partner_id.share_ids |
|
||||
line = share_ids[0] |
|
||||
if len(share_ids) > 1: |
|
||||
share_ids[1:len(share_ids)].unlink() |
|
||||
line.write({ |
|
||||
'share_number': convert_quant, |
|
||||
'share_product_id': self.share_to_product_id.id, |
|
||||
'share_unit_price': self.share_to_unit_price, |
|
||||
'share_short_name': self.share_to_short_name |
|
||||
}) |
|
||||
values['share_to_product_id'] = self.share_to_product_id.id |
|
||||
values['quantity_to'] = convert_quant |
|
||||
else: |
|
||||
raise ValidationError(_("Converting just part of the" |
|
||||
" shares is not yet implemented")) |
|
||||
elif self.operation_type == 'transfer': |
|
||||
sequence_id = self.env.ref('easy_my_coop.sequence_subscription', False) |
|
||||
partner_vals = {'member': True} |
|
||||
if self.receiver_not_member: |
|
||||
partner = self.subscription_request.create_coop_partner() |
|
||||
# get cooperator number |
|
||||
sub_reg_num = int(sequence_id.next_by_id()) |
|
||||
partner_vals.update(sub_request.get_eater_vals( |
|
||||
partner, |
|
||||
self.share_product_id)) |
|
||||
partner_vals['cooperator_register_number'] = sub_reg_num |
|
||||
partner.write(partner_vals) |
|
||||
self.partner_id_to = partner |
|
||||
else: |
|
||||
# means an old member or cooperator candidate |
|
||||
if not self.partner_id_to.member: |
|
||||
if self.partner_id_to.cooperator_register_number == 0: |
|
||||
sub_reg_num = int(sequence_id.next_by_id()) |
|
||||
partner_vals['cooperator_register_number'] = sub_reg_num |
|
||||
partner_vals.update(sub_request.get_eater_vals( |
|
||||
self.partner_id_to, |
|
||||
self.share_product_id)) |
|
||||
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}) |
|
||||
values['partner_id_to'] = self.partner_id_to.id |
|
||||
else: |
|
||||
raise ValidationError(_("This operation is not yet" |
|
||||
" implemented.")) |
|
||||
|
|
||||
sequence_operation = self.env.ref('easy_my_coop.sequence_register_operation', False) #noqa |
|
||||
sub_reg_operation = sequence_operation.next_by_id() |
|
||||
|
|
||||
values['name'] = sub_reg_operation |
|
||||
values['register_number_operation'] = int(sub_reg_operation) |
|
||||
|
|
||||
self.write({'state': 'done'}) |
|
||||
|
|
||||
sub_register_line = self.env['subscription.register'].create(values) |
|
||||
|
|
||||
# send mail to the receiver |
|
||||
if self.operation_type == 'transfer': |
|
||||
self.send_share_trans_mail(sub_register_line) |
|
||||
|
|
||||
self.send_share_update_mail(sub_register_line) |
|
||||
|
# Copyright 2019 Coop IT Easy SCRL fs |
||||
|
# Houssine Bakkali <houssine@coopiteasy.be> |
||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
|
||||
|
from datetime import datetime |
||||
|
|
||||
|
from odoo import _, api, fields, models |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class OperationRequest(models.Model): |
||||
|
_name = "operation.request" |
||||
|
_description = "Operation request" |
||||
|
|
||||
|
def get_date_now(self): |
||||
|
# fixme odoo 12 uses date types |
||||
|
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_to_product_id = fields.Many2one( |
||||
|
"product.product", |
||||
|
string="Convert to this share type", |
||||
|
domain=[("is_share", "=", True)], |
||||
|
) |
||||
|
share_short_name = fields.Char( |
||||
|
related="share_product_id.short_name", string="Share type name" |
||||
|
) |
||||
|
share_to_short_name = fields.Char( |
||||
|
related="share_to_product_id.short_name", string="Share to type name" |
||||
|
) |
||||
|
share_unit_price = fields.Float( |
||||
|
related="share_product_id.list_price", string="Share price" |
||||
|
) |
||||
|
share_to_unit_price = fields.Float( |
||||
|
related="share_to_product_id.list_price", string="Share to price" |
||||
|
) |
||||
|
subscription_amount = fields.Float( |
||||
|
compute="_compute_subscription_amount", string="Operation 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(), |
||||
|
) |
||||
|
|
||||
|
invoice = fields.Many2one("account.invoice", string="Invoice") |
||||
|
|
||||
|
@api.multi |
||||
|
def approve_operation(self): |
||||
|
for rec in self: |
||||
|
rec.write({"state": "approved"}) |
||||
|
|
||||
|
@api.multi |
||||
|
def refuse_operation(self): |
||||
|
for rec in self: |
||||
|
rec.write({"state": "refused"}) |
||||
|
|
||||
|
@api.multi |
||||
|
def submit_operation(self): |
||||
|
for rec in self: |
||||
|
rec.validate() |
||||
|
rec.write({"state": "waiting"}) |
||||
|
|
||||
|
@api.multi |
||||
|
def cancel_operation(self): |
||||
|
for rec in self: |
||||
|
rec.write({"state": "cancelled"}) |
||||
|
|
||||
|
@api.multi |
||||
|
def reset_to_draft(self): |
||||
|
for rec in self: |
||||
|
rec.write({"state": "draft"}) |
||||
|
|
||||
|
def get_total_share_dic(self, partner): |
||||
|
total_share_dic = {} |
||||
|
share_products = self.env["product.product"].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" |
||||
|
) |
||||
|
) |
||||
|
|
||||
|
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 |
||||
|
# an 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 |
||||
|
|
||||
|
def validate(self): |
||||
|
if not self.has_share_type() and self.operation_type in [ |
||||
|
"sell_back", |
||||
|
"transfer", |
||||
|
]: |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"The cooperator doesn't own this share" |
||||
|
" type. Please choose the appropriate" |
||||
|
" share type." |
||||
|
) |
||||
|
) |
||||
|
|
||||
|
if self.operation_type in ["sell_back", "convert", "transfer"]: |
||||
|
total_share_dic = self.get_total_share_dic(self.partner_id) |
||||
|
|
||||
|
if self.quantity > total_share_dic[self.share_product_id.id]: |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"The cooperator can't hand over more" |
||||
|
" shares that he/she owns." |
||||
|
) |
||||
|
) |
||||
|
|
||||
|
if self.operation_type == "convert": |
||||
|
if self.company_id.unmix_share_type: |
||||
|
if self.share_product_id.code == self.share_to_product_id.code: |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"You can't convert the share to" |
||||
|
" the same share type." |
||||
|
) |
||||
|
) |
||||
|
if self.subscription_amount != self.partner_id.total_value: |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"You must convert all the shares" |
||||
|
" to the selected type." |
||||
|
) |
||||
|
) |
||||
|
else: |
||||
|
if self.subscription_amount != self.partner_id.total_value: |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"Converting just part of the" |
||||
|
" shares is not yet implemented" |
||||
|
) |
||||
|
) |
||||
|
elif self.operation_type == "transfer": |
||||
|
if ( |
||||
|
not self.receiver_not_member |
||||
|
and 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 ( |
||||
|
self.partner_id_to.is_company |
||||
|
and not self.share_product_id.by_company |
||||
|
): |
||||
|
raise ValidationError( |
||||
|
_("This share can not be" " subscribed by a company") |
||||
|
) |
||||
|
if ( |
||||
|
not self.partner_id_to.is_company |
||||
|
and not self.share_product_id.by_individual |
||||
|
): |
||||
|
raise ValidationError( |
||||
|
_("This share can not be" " subscribed an individual") |
||||
|
) |
||||
|
if ( |
||||
|
self.receiver_not_member |
||||
|
and self.subscription_request |
||||
|
and not self.subscription_request.validated |
||||
|
): |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"The information of the receiver" |
||||
|
" are not correct. Please correct" |
||||
|
" the information before" |
||||
|
" submitting" |
||||
|
) |
||||
|
) |
||||
|
|
||||
|
def get_share_trans_mail_template(self): |
||||
|
return self.env.ref( |
||||
|
"easy_my_coop.email_template_share_transfer", False |
||||
|
) |
||||
|
|
||||
|
def get_share_update_mail_template(self): |
||||
|
return self.env.ref("easy_my_coop.email_template_share_update", False) |
||||
|
|
||||
|
def send_share_trans_mail( |
||||
|
self, sub_register_line |
||||
|
): # Unused argument is used in synergie project. Do not remove. |
||||
|
cert_email_template = self.get_share_trans_mail_template() |
||||
|
cert_email_template.send_mail(self.partner_id_to.id, False) |
||||
|
|
||||
|
def send_share_update_mail( |
||||
|
self, sub_register_line |
||||
|
): # Unused argument is used in synergie project. Do not remove. |
||||
|
cert_email_template = self.get_share_update_mail_template() |
||||
|
cert_email_template.send_mail(self.partner_id.id, False) |
||||
|
|
||||
|
def get_subscription_register_vals(self, effective_date): |
||||
|
return { |
||||
|
"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, |
||||
|
} |
||||
|
|
||||
|
@api.multi |
||||
|
def execute_operation(self): |
||||
|
self.ensure_one() |
||||
|
|
||||
|
effective_date = self.get_date_now() |
||||
|
sub_request = self.env["subscription.request"] |
||||
|
|
||||
|
self.validate() |
||||
|
|
||||
|
if self.state != "approved": |
||||
|
raise ValidationError( |
||||
|
_("This operation must be approved" " before to be executed") |
||||
|
) |
||||
|
|
||||
|
values = self.get_subscription_register_vals(effective_date) |
||||
|
|
||||
|
if self.operation_type == "sell_back": |
||||
|
self.hand_share_over( |
||||
|
self.partner_id, self.share_product_id, self.quantity |
||||
|
) |
||||
|
elif self.operation_type == "convert": |
||||
|
amount_to_convert = self.share_unit_price * self.quantity |
||||
|
convert_quant = int( |
||||
|
amount_to_convert / self.share_to_product_id.list_price |
||||
|
) |
||||
|
remainder = amount_to_convert % self.share_to_product_id.list_price |
||||
|
|
||||
|
if convert_quant > 0 and remainder == 0: |
||||
|
share_ids = self.partner_id.share_ids |
||||
|
line = share_ids[0] |
||||
|
if len(share_ids) > 1: |
||||
|
share_ids[1 : len(share_ids)].unlink() |
||||
|
line.write( |
||||
|
{ |
||||
|
"share_number": convert_quant, |
||||
|
"share_product_id": self.share_to_product_id.id, |
||||
|
"share_unit_price": self.share_to_unit_price, |
||||
|
"share_short_name": self.share_to_short_name, |
||||
|
} |
||||
|
) |
||||
|
values["share_to_product_id"] = self.share_to_product_id.id |
||||
|
values["quantity_to"] = convert_quant |
||||
|
else: |
||||
|
raise ValidationError( |
||||
|
_( |
||||
|
"Converting just part of the" |
||||
|
" shares is not yet implemented" |
||||
|
) |
||||
|
) |
||||
|
elif self.operation_type == "transfer": |
||||
|
sequence_id = self.env.ref( |
||||
|
"easy_my_coop.sequence_subscription", False |
||||
|
) |
||||
|
partner_vals = {"member": True} |
||||
|
if self.receiver_not_member: |
||||
|
partner = self.subscription_request.create_coop_partner() |
||||
|
# get cooperator number |
||||
|
sub_reg_num = int(sequence_id.next_by_id()) |
||||
|
partner_vals.update(sub_request.get_eater_vals( |
||||
|
partner, |
||||
|
self.share_product_id)) |
||||
|
partner_vals['cooperator_register_number'] = sub_reg_num |
||||
|
partner.write(partner_vals) |
||||
|
self.partner_id_to = partner |
||||
|
else: |
||||
|
# means an old member or cooperator candidate |
||||
|
if not self.partner_id_to.member: |
||||
|
if self.partner_id_to.cooperator_register_number == 0: |
||||
|
sub_reg_num = int(sequence_id.next_by_id()) |
||||
|
partner_vals['cooperator_register_number'] = sub_reg_num |
||||
|
partner_vals.update(sub_request.get_eater_vals( |
||||
|
self.partner_id_to, |
||||
|
self.share_product_id)) |
||||
|
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, |
||||
|
} |
||||
|
) |
||||
|
values["partner_id_to"] = self.partner_id_to.id |
||||
|
else: |
||||
|
raise ValidationError( |
||||
|
_("This operation is not yet" " implemented.") |
||||
|
) |
||||
|
|
||||
|
sequence_operation = self.env.ref( |
||||
|
"easy_my_coop.sequence_register_operation", False |
||||
|
) # noqa |
||||
|
sub_reg_operation = sequence_operation.next_by_id() |
||||
|
|
||||
|
values["name"] = sub_reg_operation |
||||
|
values["register_number_operation"] = int(sub_reg_operation) |
||||
|
|
||||
|
self.write({"state": "done"}) |
||||
|
|
||||
|
sub_register_line = self.env["subscription.register"].create(values) |
||||
|
|
||||
|
# send mail to the receiver |
||||
|
if self.operation_type == "transfer": |
||||
|
self.send_share_trans_mail(sub_register_line) |
||||
|
|
||||
|
self.send_share_update_mail(sub_register_line) |
@ -1,37 +1,41 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# Copyright 2019 Coop IT Easy SCRL fs |
|
||||
# Houssine Bakkali <houssine@coopiteasy.be> |
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|
||||
|
|
||||
|
|
||||
from odoo 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) |
|
||||
force_min_qty = fields.Boolean(String="Force minimum quantity?") |
|
||||
by_company = fields.Boolean(string="Can be subscribed by companies?") |
|
||||
by_individual = fields.Boolean(string="Can be subscribed by individuals?") |
|
||||
customer = fields.Boolean(string="Become customer") |
|
||||
mail_template = fields.Many2one('mail.template', |
|
||||
string="Mail template") |
|
||||
|
|
||||
@api.multi |
|
||||
def get_web_share_products(self, is_company): |
|
||||
if is_company is True: |
|
||||
product_templates = self.env['product.template'].search([ |
|
||||
('is_share', '=', True), |
|
||||
('display_on_website', '=', True), |
|
||||
('by_company', '=', True)]) |
|
||||
else: |
|
||||
product_templates = self.env['product.template'].search([ |
|
||||
('is_share', '=', True), |
|
||||
('display_on_website', '=', True), |
|
||||
('by_individual', '=', True)]) |
|
||||
return product_templates |
|
||||
|
# Copyright 2019 Coop IT Easy SCRL fs |
||||
|
# Houssine Bakkali <houssine@coopiteasy.be> |
||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
|
||||
|
from odoo 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) |
||||
|
force_min_qty = fields.Boolean(String="Force minimum quantity?") |
||||
|
by_company = fields.Boolean(string="Can be subscribed by companies?") |
||||
|
by_individual = fields.Boolean(string="Can be subscribed by individuals?") |
||||
|
customer = fields.Boolean(string="Become customer") |
||||
|
mail_template = fields.Many2one("mail.template", string="Mail template") |
||||
|
|
||||
|
@api.multi |
||||
|
def get_web_share_products(self, is_company): |
||||
|
if is_company is True: |
||||
|
product_templates = self.env["product.template"].search( |
||||
|
[ |
||||
|
("is_share", "=", True), |
||||
|
("display_on_website", "=", True), |
||||
|
("by_company", "=", True), |
||||
|
] |
||||
|
) |
||||
|
else: |
||||
|
product_templates = self.env["product.template"].search( |
||||
|
[ |
||||
|
("is_share", "=", True), |
||||
|
("display_on_website", "=", True), |
||||
|
("by_individual", "=", True), |
||||
|
] |
||||
|
) |
||||
|
return product_templates |
@ -1,15 +1,14 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
# Copyright 2019 Coop IT Easy SCRL fs |
|
||||
# Houssine Bakkali <houssine@coopiteasy.be> |
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
|
||||
|
|
||||
|
|
||||
from odoo import models |
|
||||
|
|
||||
|
|
||||
class ResPartnerBank(models.Model): |
|
||||
_inherit = 'res.partner.bank' |
|
||||
|
|
||||
_sql_constraints = [ |
|
||||
('unique_number', 'Check(1=1)', 'Account Number must be unique!'), |
|
||||
] |
|
||||
|
# Copyright 2019 Coop IT Easy SCRL fs |
||||
|
# Houssine Bakkali <houssine@coopiteasy.be> |
||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
|
||||
|
from odoo import models |
||||
|
|
||||
|
|
||||
|
class ResPartnerBank(models.Model): |
||||
|
_inherit = "res.partner.bank" |
||||
|
|
||||
|
_sql_constraints = [ |
||||
|
("unique_number", "Check(1=1)", "Account Number must be unique!") |
||||
|
] |
@ -1,13 +1,19 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class AccountInvoiceReport(models.Model): |
|
||||
_inherit = "account.invoice.report" |
|
||||
|
|
||||
release_capital_request = fields.Boolean(string="Release capital request") |
|
||||
|
|
||||
def _select(self): |
|
||||
return super(AccountInvoiceReport, self)._select() + ", sub.release_capital_request as release_capital_request" |
|
||||
|
|
||||
def _sub_select(self): |
|
||||
return super(AccountInvoiceReport, self)._sub_select() + ", ai.release_capital_request as release_capital_request" |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountInvoiceReport(models.Model): |
||||
|
_inherit = "account.invoice.report" |
||||
|
|
||||
|
release_capital_request = fields.Boolean(string="Release capital request") |
||||
|
|
||||
|
def _select(self): |
||||
|
return ( |
||||
|
super(AccountInvoiceReport, self)._select() |
||||
|
+ ", sub.release_capital_request as release_capital_request" |
||||
|
) |
||||
|
|
||||
|
def _sub_select(self): |
||||
|
return ( |
||||
|
super(AccountInvoiceReport, self)._sub_select() |
||||
|
+ ", ai.release_capital_request as release_capital_request" |
||||
|
) |
@ -1,27 +1,26 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class SubscriptionRequest(models.Model): |
|
||||
_inherit = 'subscription.request' |
|
||||
|
|
||||
company_type = fields.Selection([('scrl', 'SCRL'), |
|
||||
('asbl', 'ASBL'), |
|
||||
('sprl', 'SPRL'), |
|
||||
('sa', 'SA')]) |
|
||||
|
|
||||
def get_partner_company_vals(self): |
|
||||
vals = super(SubscriptionRequest, self).get_partner_company_vals() |
|
||||
vals['out_inv_comm_algorithm'] = 'random' |
|
||||
return vals |
|
||||
|
|
||||
def get_partner_vals(self): |
|
||||
vals = super(SubscriptionRequest, self).get_partner_vals() |
|
||||
vals['out_inv_comm_type'] = 'bba' |
|
||||
vals['out_inv_comm_algorithm'] = 'random' |
|
||||
return vals |
|
||||
|
|
||||
def get_representative_valst(self): |
|
||||
vals = super(SubscriptionRequest, self).get_representative_vals() |
|
||||
vals['out_inv_comm_type'] = 'bba' |
|
||||
vals['out_inv_comm_algorithm'] = 'random' |
|
||||
return vals |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class SubscriptionRequest(models.Model): |
||||
|
_inherit = "subscription.request" |
||||
|
|
||||
|
company_type = fields.Selection( |
||||
|
[("scrl", "SCRL"), ("asbl", "ASBL"), ("sprl", "SPRL"), ("sa", "SA")] |
||||
|
) |
||||
|
|
||||
|
def get_partner_company_vals(self): |
||||
|
vals = super(SubscriptionRequest, self).get_partner_company_vals() |
||||
|
vals["out_inv_comm_algorithm"] = "random" |
||||
|
return vals |
||||
|
|
||||
|
def get_partner_vals(self): |
||||
|
vals = super(SubscriptionRequest, self).get_partner_vals() |
||||
|
vals["out_inv_comm_type"] = "bba" |
||||
|
vals["out_inv_comm_algorithm"] = "random" |
||||
|
return vals |
||||
|
|
||||
|
def get_representative_valst(self): |
||||
|
vals = super(SubscriptionRequest, self).get_representative_vals() |
||||
|
vals["out_inv_comm_type"] = "bba" |
||||
|
vals["out_inv_comm_algorithm"] = "random" |
||||
|
return vals |
@ -1,10 +1,14 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class ResPartner(models.Model): |
|
||||
_inherit = 'res.partner' |
|
||||
|
|
||||
legal_form = fields.Selection(selection_add=[('scrl', 'SCRL'), |
|
||||
('asbl', 'ASBL'), |
|
||||
('sprl', 'SPRL'), |
|
||||
('sa', 'SA')]) |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = "res.partner" |
||||
|
|
||||
|
legal_form = fields.Selection( |
||||
|
selection_add=[ |
||||
|
("scrl", "SCRL"), |
||||
|
("asbl", "ASBL"), |
||||
|
("sprl", "SPRL"), |
||||
|
("sa", "SA"), |
||||
|
] |
||||
|
) |
@ -1,37 +1,19 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
############################################################################## |
|
||||
# |
|
||||
# Copyright (C) 2013-2017 Open Architects Consulting SPRL. |
|
||||
# Copyright (C) 2018- Coop IT Easy SCRLfs. |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
|
# Copyright 2013-2018 Open Architects Consulting SPRL. |
||||
|
# Copyright 2018 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 CH", |
|
||||
|
"name": "Easy My Coop Switzerland", |
||||
|
"summary": "Easy My Coop Switzerland localization", |
||||
"version": "12.0.1.0.2", |
"version": "12.0.1.0.2", |
||||
"depends": ["easy_my_coop", |
|
||||
"l10n_ch"], |
|
||||
"author": "Houssine BAKKALI <houssine@coopiteasy.be>", |
|
||||
|
"license": "AGPL-3", |
||||
|
"depends": ["easy_my_coop", "l10n_ch"], |
||||
|
"author": "Coop IT Easy SCRLfs", |
||||
"category": "Cooperative management", |
"category": "Cooperative management", |
||||
'webstite': "www.coopiteasy.be", |
|
||||
"description": """ |
|
||||
This is the swiss localization for the easy my coop module |
|
||||
""", |
|
||||
'data': [ |
|
||||
'views/subscription_template.xml', |
|
||||
'views/subscription_request_view.xml' |
|
||||
|
"webstite": "www.coopiteasy.be", |
||||
|
"data": [ |
||||
|
"views/subscription_template.xml", |
||||
|
"views/subscription_request_view.xml", |
||||
], |
], |
||||
'installable': True, |
|
||||
|
"installable": True, |
||||
} |
} |
@ -1,22 +1,25 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class SubscriptionRequest(models.Model): |
|
||||
_inherit = 'subscription.request' |
|
||||
|
|
||||
company_type = fields.Selection(selection_add=[ |
|
||||
('ei', 'Individual company'), |
|
||||
('snc', 'Partnership'), |
|
||||
('sa', 'Limited company (SA)'), |
|
||||
('sarl', 'Limited liability company (Ltd)'), #noqa |
|
||||
('sc', 'Cooperative'), |
|
||||
('asso', 'Association'), |
|
||||
('fond', 'Foundation'), |
|
||||
('edp', 'Company under public law')]) |
|
||||
|
|
||||
def get_required_field(self): |
|
||||
req_fields = super(SubscriptionRequest, self).get_required_field() |
|
||||
if 'iban' in req_fields: |
|
||||
req_fields.remove('iban') |
|
||||
|
|
||||
return req_fields |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class SubscriptionRequest(models.Model): |
||||
|
_inherit = "subscription.request" |
||||
|
|
||||
|
company_type = fields.Selection( |
||||
|
selection_add=[ |
||||
|
("ei", "Individual company"), |
||||
|
("snc", "Partnership"), |
||||
|
("sa", "Limited company (SA)"), |
||||
|
("sarl", "Limited liability company (Ltd)"), # noqa |
||||
|
("sc", "Cooperative"), |
||||
|
("asso", "Association"), |
||||
|
("fond", "Foundation"), |
||||
|
("edp", "Company under public law"), |
||||
|
] |
||||
|
) |
||||
|
|
||||
|
def get_required_field(self): |
||||
|
req_fields = super(SubscriptionRequest, self).get_required_field() |
||||
|
if "iban" in req_fields: |
||||
|
req_fields.remove("iban") |
||||
|
|
||||
|
return req_fields |
@ -1,16 +1,18 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class ResPartner(models.Model): |
|
||||
_inherit = 'res.partner' |
|
||||
|
|
||||
legal_form = fields.Selection(selection_add=[ |
|
||||
('ei', 'Individual company'), |
|
||||
('snc', 'Partnership'), |
|
||||
('sa', 'Limited company (SA)'), |
|
||||
('sarl', 'Limited liability company (Ltd)'), |
|
||||
('sc', 'Cooperative'), |
|
||||
('asso', 'Association'), |
|
||||
('fond', 'Foundation'), |
|
||||
('edp', 'Company under public law') |
|
||||
]) |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = "res.partner" |
||||
|
|
||||
|
legal_form = fields.Selection( |
||||
|
selection_add=[ |
||||
|
("ei", "Individual company"), |
||||
|
("snc", "Partnership"), |
||||
|
("sa", "Limited company (SA)"), |
||||
|
("sarl", "Limited liability company (Ltd)"), |
||||
|
("sc", "Cooperative"), |
||||
|
("asso", "Association"), |
||||
|
("fond", "Foundation"), |
||||
|
("edp", "Company under public law"), |
||||
|
] |
||||
|
) |
@ -1,63 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<odoo> |
|
||||
<data> |
|
||||
<template id="certificate_i18n_fr" inherit_id="easy_my_coop.cooperator_certificat_G001_document" name="French Layout Certificate"> |
|
||||
<xpath expr="//div[@name='label_coop_number']" position="replace"> |
|
||||
<div name="label_coop_number" style="position:relative;top:35px;font-size:16;"> |
|
||||
<span>Ce document atteste de la souscription de parts sociales au capital de la SAS Coopérative à Capital Variable SuperQuinquin par </span> |
|
||||
<b><span t-field="o.name"></span></b> |
|
||||
<span>, enregistré(e) sous le <b>numéro de coopérateur </b></span> |
|
||||
<span t-field="o.cooperator_register_number"></span> |
|
||||
</div> |
|
||||
</xpath> |
|
||||
|
|
||||
<xpath expr="//div[@name='total_table']" position="after"> |
|
||||
<div name="legal_text" style="position:relative;top:145px;font-size:12;"> |
|
||||
<div>Ce document atteste d’une souscription en numéraire au capital d’une société, répondant à la définition communautaire de la Petite et Moyenne Entreprise, dont les titres ne sont pas admis aux négociations sur un marché d’instruments financiers français ou étranger en application de l’article 199 terdecies 0A du CGI.<br/> |
|
||||
Conformément aux statuts, les souscriptions de parts sociales de type A et B n’ouvre pas droit à rémunération.<br/> |
|
||||
La société remplit les conditions mentionnées aux c, d et e du 2° du I de l’article 199 terdecies-0 A du code général des impôts : <br/> |
|
||||
c) La société est soumise à l’impôt sur les sociétés dans les conditions de droit commun ;<br/> |
|
||||
<br/> |
|
||||
c bis) La société compte au moins deux salariés à la clôture de son premier exercice ou un salarié si elle est soumise à l’obligation de s’inscrire à la chambre de métiers et de l’artisanat ;<br/> |
|
||||
<br/> |
|
||||
d) La société exerce une activité commerciale, industrielle, artisanale, libérale ou agricole, à l’exclusion des activités procurant des revenus garantis en raison de l’existence d’un tarif réglementé de rachat de la production, des activités financières, des activités de gestion de patrimoine mobilier définie à l’article 885 O quater et des activités immobilières. Toutefois, les exclusions relatives à l’exercice d’une activité financière ou immobilière ne sont pas applicables aux entreprises solidaires mentionnées à l’article L. 3332-17-1 du code du travail.<br/> |
|
||||
La société n’exerce pas une activité de production d’électricité utilisant l’énergie radiative du soleil ;<br/> |
|
||||
<br/> |
|
||||
d bis) Les actifs de la société ne sont pas constitués de façon prépondérante de métaux précieux, d’œuvres d’art, d’objets de collection, d’antiquités, de chevaux de course ou de concours ou, sauf si l’objet même de son activité consiste en leur consommation ou en leur vente au détail, de vins ou d’alcools ;<br/> |
|
||||
<br/> |
|
||||
d ter) Les souscriptions au capital de la société confèrent aux souscripteurs les seuls droits résultant de la qualité d’actionnaire ou d’associé, à l’exclusion de toute autre contrepartie notamment sous la forme de tarifs préférentiels ou d’accès prioritaire aux biens produits ou aux services rendus par la société ;<br/> |
|
||||
<br/> |
|
||||
e) La société doit être une petite et moyenne entreprise qui satisfait à la définition des petites et moyennes entreprises qui figure à l’annexe I au règlement (CE) n° 800/2008 de la Commission du 6 août 2008 déclarant certaines catégories d’aide compatibles avec le marché commun en application des articles 87 et 88 du traité (Règlement général d’exemption par catégorie) ;<br/> |
|
||||
</div> |
|
||||
</div> |
|
||||
</xpath> |
|
||||
<xpath expr="//div[@name='board_commitee']" position="replace"> |
|
||||
<div name="" class="col-xs-6 pull-left" style="position:relative;top:105px;font-size:20;color:black;font-family:Roboto-Regular;"> |
|
||||
<div style="position:relative;top:105px;"> |
|
||||
Pour le Conseil d'administration de <span t-field="o.company_id.name"/>. |
|
||||
</div> |
|
||||
<div style="position:relative;top:110px;"> |
|
||||
<strong><span t-field="o.company_id.board_representative"/></strong> |
|
||||
</div> |
|
||||
<div style="position:relative;top:115px;"> |
|
||||
<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:180px;padding-bottom:5px;"/> |
|
||||
</div> |
|
||||
</div> |
|
||||
</xpath> |
|
||||
</template> |
|
||||
|
|
||||
<template id="capital_release_request_i18n_fr" inherit_id="easy_my_coop.theme_invoice_G002_document" name="French Layout Certificate"> |
|
||||
<xpath expr="//p[@t-if='o.comment']" position="before"> |
|
||||
<div class="row"> |
|
||||
<div style="position:relative;top:225px;font-size:16;"> |
|
||||
Votre demande de souscription de parts sociales, détaillé dans le tableau ci-dessus, a bien été prise en compte.<br/> |
|
||||
<br/> |
|
||||
Afin de valider votre enregistrement en tant que coopérateur, vous devez tout d’abord procéder au paiement de celles-ci.<br/> |
|
||||
<br/> |
|
||||
Un email contenant les instructions de paiement vous a également été envoyé.<br/> |
|
||||
</div> |
|
||||
</div> |
|
||||
</xpath> |
|
||||
</template> |
|
||||
</data> |
|
||||
</odoo> |
|
@ -1,190 +1,213 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from __future__ import division |
|
||||
from datetime import datetime |
|
||||
import openerp.addons.decimal_precision as dp |
|
||||
|
|
||||
from openerp import fields, models, api |
|
||||
|
|
||||
|
|
||||
class dividend_year(models.Model): |
|
||||
_name = 'dividend.year' |
|
||||
|
|
||||
@api.multi |
|
||||
def _compute_dividend_info(self): |
|
||||
res = {} |
|
||||
for dividend in self: |
|
||||
res[dividend.id] = {'grand_total_dividend': 0.0, |
|
||||
'grand_total_taxes': 0.0} |
|
||||
for line in dividend.dividend_ids: |
|
||||
res[dividend.id]['grand_total_dividend'] += line.dividend_amount |
|
||||
res[dividend.id]['grand_total_taxes'] += line.dividend_taxes |
|
||||
return res |
|
||||
|
|
||||
name = fields.Char(string='Code') |
|
||||
date_from = fields.Date(string='Date from') |
|
||||
date_to = fields.Date(string='Date to') |
|
||||
# fiscal_year_id = fields.Many2one('account.fiscalyear', |
|
||||
# string='Fiscal year') |
|
||||
percentage = fields.Float(string='Percentage') |
|
||||
withholding_tax = fields.Float(string='Withholding tax') |
|
||||
detailed_dividend_ids = fields.One2many('detailed.dividend.line', |
|
||||
'dividend_year_id', |
|
||||
string='Dividend lines') |
|
||||
dividend_ids = fields.One2many('dividend.line', |
|
||||
'dividend_year_id', |
|
||||
string='Dividend lines') |
|
||||
grand_total_dividend = fields.Float( |
|
||||
compute=_compute_dividend_info, |
|
||||
string='Grand total dividend', |
|
||||
digits_compute=dp.get_precision('Account')) |
|
||||
grand_total_taxes = fields.Float( |
|
||||
compute=_compute_dividend_info, |
|
||||
string='Grand total taxes', |
|
||||
digits_compute=dp.get_precision('Account')) |
|
||||
|
|
||||
@api.multi |
|
||||
def compute_dividend(self): |
|
||||
self.ensure_one() |
|
||||
det_div_line_obj = self.env['detailed.dividend.line'] |
|
||||
div_line_obj = self.env['dividend.line'] |
|
||||
res_partner_obj = self.env['res.partner'] |
|
||||
|
|
||||
# delete lines if any |
|
||||
detailed_dividend_ids = det_div_line_obj.search([('dividend_year_id', '=', self.id)]) |
|
||||
detailed_dividend_ids.unlink() |
|
||||
dividend_ids = div_line_obj.search([('dividend_year_id', '=', self.id)]) |
|
||||
dividend_ids.unlink() |
|
||||
|
|
||||
partner_ids = res_partner_obj.search([ |
|
||||
('cooperator', '=', True), |
|
||||
('member', '=', True)], |
|
||||
order='cooperator_register_number') |
|
||||
number_of_days = (datetime.strptime(self.date_to, '%Y-%m-%d') |
|
||||
- datetime.strptime(self.date_from, '%Y-%m-%d') |
|
||||
).days + 1 |
|
||||
|
|
||||
for partner in partner_ids: |
|
||||
total_amount_dividend = 0.0 |
|
||||
for line in partner.share_ids: |
|
||||
vals = {} |
|
||||
vals2 = {} |
|
||||
line_id = False |
|
||||
if line.effective_date >= self.date_from \ |
|
||||
and line.effective_date <= self.date_to: |
|
||||
date_res = (datetime.strptime(self.date_to, '%Y-%m-%d') |
|
||||
- datetime.strptime(line.effective_date, '%Y-%m-%d')).days |
|
||||
coeff = (date_res / number_of_days) * self.percentage |
|
||||
dividend_amount = line.total_amount_line * coeff |
|
||||
|
|
||||
vals['days'] = date_res |
|
||||
vals['dividend_year_id'] = self.id |
|
||||
vals['coop_number'] = line.partner_id.cooperator_register_number |
|
||||
vals['partner_id'] = partner.id |
|
||||
vals['share_line_id'] = line.id |
|
||||
vals['coeff'] = coeff |
|
||||
vals['dividend_amount'] = dividend_amount |
|
||||
total_amount_dividend += dividend_amount |
|
||||
|
|
||||
line_id = det_div_line_obj.create(vals) |
|
||||
elif line.effective_date < self.date_from: |
|
||||
dividend_amount = line.total_amount_line * self.percentage |
|
||||
vals['days'] = number_of_days |
|
||||
vals['dividend_year_id'] = self.id |
|
||||
vals['coop_number'] = line.partner_id.cooperator_register_number |
|
||||
vals['partner_id'] = partner.id |
|
||||
vals['share_line_id'] = line.id |
|
||||
vals['coeff'] = self.percentage |
|
||||
vals['dividend_amount'] = dividend_amount |
|
||||
total_amount_dividend += dividend_amount |
|
||||
|
|
||||
line_id = det_div_line_obj.create(vals) |
|
||||
if line_id: |
|
||||
vals2['coop_number'] = line.partner_id.cooperator_register_number |
|
||||
vals2['dividend_year_id'] = self.id |
|
||||
vals2['partner_id'] = line.partner_id.id |
|
||||
|
|
||||
vals2['dividend_amount_net'] = total_amount_dividend |
|
||||
vals2['dividend_amount'] = total_amount_dividend |
|
||||
|
|
||||
# TODO set as a parameter on dividend year object |
|
||||
if total_amount_dividend <= 190.00: |
|
||||
vals2['dividend_taxes'] = 0.0 |
|
||||
else: |
|
||||
div_tax = (total_amount_dividend - 190) * self.withholding_tax |
|
||||
vals2['dividend_taxes'] = div_tax |
|
||||
vals2['dividend_amount_net'] = total_amount_dividend - div_tax |
|
||||
|
|
||||
div_line_obj.create(vals2) |
|
||||
return True |
|
||||
|
|
||||
|
|
||||
class DetailedDividendLine(models.Model): |
|
||||
_name = 'detailed.dividend.line' |
|
||||
|
|
||||
@api.multi |
|
||||
def _compute_total_line(self): |
|
||||
res = {} |
|
||||
for line in self: |
|
||||
res[line.id] = line.share_unit_price * line.share_number |
|
||||
return res |
|
||||
|
|
||||
dividend_year_id = fields.Many2one('dividend.year', |
|
||||
string='Dividend year') |
|
||||
coop_number = fields.Integer(string='Cooperator Number') |
|
||||
days = fields.Integer(string='Days') |
|
||||
partner_id = fields.Many2one('res.partner', |
|
||||
string='Cooperator', |
|
||||
readonly=True) |
|
||||
share_line_id = fields.Many2one('share.line', |
|
||||
string='Share line', |
|
||||
readonly=True) |
|
||||
share_number = fields.Integer(related='share_line_id.share_number', |
|
||||
string='Number of Share') |
|
||||
share_unit_price = fields.Monetary( |
|
||||
string='Share unit price', |
|
||||
related='share_line_id.share_unit_price', |
|
||||
) |
|
||||
effective_date = fields.Date(related='share_line_id.effective_date', |
|
||||
string='Effective date') |
|
||||
total_amount_line = fields.Monetary( |
|
||||
string="Total value of share", |
|
||||
currency_field="company_currency_id", |
|
||||
compute=_compute_total_line, |
|
||||
readonly=True, |
|
||||
) |
|
||||
coeff = fields.Float(string='Coefficient to apply', |
|
||||
digits=(2, 4)) |
|
||||
dividend_amount = fields.Float(string='Gross Dividend') |
|
||||
dividend_amount_net = fields.Float(string='Dividend net') |
|
||||
dividend_taxes = fields.Float(string='Taxes') |
|
||||
company_currency_id = fields.Many2one( |
|
||||
related="share_line_id.company_currency_id", |
|
||||
readonly=True, |
|
||||
) |
|
||||
|
|
||||
|
|
||||
class dividend_line(models.Model): |
|
||||
_name = 'dividend.line' |
|
||||
|
|
||||
@api.multi |
|
||||
def _get_account_number(self): |
|
||||
res = {} |
|
||||
for line in self: |
|
||||
bank_accounts = self.env['res.partner.bank'].search( |
|
||||
[('partner_id', '=', line.partner_id.id)]) |
|
||||
res[line.id] = bank_accounts[0].acc_number |
|
||||
|
|
||||
return res |
|
||||
|
|
||||
coop_number = fields.Integer(string='Coop Number') |
|
||||
dividend_year_id = fields.Many2one('dividend.year', |
|
||||
string='Dividend year') |
|
||||
partner_id = fields.Many2one('res.partner', |
|
||||
string='Cooperator', |
|
||||
readonly=True) |
|
||||
account_number = fields.Char(compute=_get_account_number, |
|
||||
string='Account Number') |
|
||||
dividend_amount = fields.Float(string='Gross Dividend') |
|
||||
dividend_amount_net = fields.Float(string='Dividend net') |
|
||||
dividend_taxes = fields.Float(string='Taxes') |
|
||||
|
from __future__ import division |
||||
|
|
||||
|
from datetime import datetime |
||||
|
|
||||
|
import openerp.addons.decimal_precision as dp |
||||
|
from openerp import api, fields, models |
||||
|
|
||||
|
|
||||
|
class DividendYear(models.Model): |
||||
|
_name = "dividend.year" |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_dividend_info(self): |
||||
|
res = {} |
||||
|
for dividend in self: |
||||
|
res[dividend.id] = { |
||||
|
"grand_total_dividend": 0.0, |
||||
|
"grand_total_taxes": 0.0, |
||||
|
} |
||||
|
for line in dividend.dividend_ids: |
||||
|
res[dividend.id][ |
||||
|
"grand_total_dividend" |
||||
|
] += line.dividend_amount |
||||
|
res[dividend.id]["grand_total_taxes"] += line.dividend_taxes |
||||
|
return res |
||||
|
|
||||
|
name = fields.Char(string="Code") |
||||
|
date_from = fields.Date(string="Date from") |
||||
|
date_to = fields.Date(string="Date to") |
||||
|
# fiscal_year_id = fields.Many2one('account.fiscalyear', |
||||
|
# string='Fiscal year') |
||||
|
percentage = fields.Float(string="Percentage") |
||||
|
withholding_tax = fields.Float(string="Withholding tax") |
||||
|
detailed_dividend_ids = fields.One2many( |
||||
|
"detailed.dividend.line", "dividend_year_id", string="Dividend lines" |
||||
|
) |
||||
|
dividend_ids = fields.One2many( |
||||
|
"dividend.line", "dividend_year_id", string="Dividend lines" |
||||
|
) |
||||
|
grand_total_dividend = fields.Float( |
||||
|
compute=_compute_dividend_info, |
||||
|
string="Grand total dividend", |
||||
|
digits_compute=dp.get_precision("Account"), |
||||
|
) |
||||
|
grand_total_taxes = fields.Float( |
||||
|
compute=_compute_dividend_info, |
||||
|
string="Grand total taxes", |
||||
|
digits_compute=dp.get_precision("Account"), |
||||
|
) |
||||
|
|
||||
|
@api.multi |
||||
|
def compute_dividend(self): |
||||
|
self.ensure_one() |
||||
|
det_div_line_obj = self.env["detailed.dividend.line"] |
||||
|
div_line_obj = self.env["dividend.line"] |
||||
|
res_partner_obj = self.env["res.partner"] |
||||
|
|
||||
|
# delete lines if any |
||||
|
detailed_dividend_ids = det_div_line_obj.search( |
||||
|
[("dividend_year_id", "=", self.id)] |
||||
|
) |
||||
|
detailed_dividend_ids.unlink() |
||||
|
dividend_ids = div_line_obj.search( |
||||
|
[("dividend_year_id", "=", self.id)] |
||||
|
) |
||||
|
dividend_ids.unlink() |
||||
|
|
||||
|
partner_ids = res_partner_obj.search( |
||||
|
[("cooperator", "=", True), ("member", "=", True)], |
||||
|
order="cooperator_register_number", |
||||
|
) |
||||
|
number_of_days = ( |
||||
|
datetime.strptime(self.date_to, "%Y-%m-%d") |
||||
|
- datetime.strptime(self.date_from, "%Y-%m-%d") |
||||
|
).days + 1 |
||||
|
|
||||
|
for partner in partner_ids: |
||||
|
total_amount_dividend = 0.0 |
||||
|
for line in partner.share_ids: |
||||
|
vals = {} |
||||
|
vals2 = {} |
||||
|
line_id = False |
||||
|
if ( |
||||
|
line.effective_date >= self.date_from |
||||
|
and line.effective_date <= self.date_to |
||||
|
): |
||||
|
date_res = ( |
||||
|
datetime.strptime(self.date_to, "%Y-%m-%d") |
||||
|
- datetime.strptime(line.effective_date, "%Y-%m-%d") |
||||
|
).days |
||||
|
coeff = (date_res / number_of_days) * self.percentage |
||||
|
dividend_amount = line.total_amount_line * coeff |
||||
|
|
||||
|
vals["days"] = date_res |
||||
|
vals["dividend_year_id"] = self.id |
||||
|
vals[ |
||||
|
"coop_number" |
||||
|
] = line.partner_id.cooperator_register_number |
||||
|
vals["partner_id"] = partner.id |
||||
|
vals["share_line_id"] = line.id |
||||
|
vals["coeff"] = coeff |
||||
|
vals["dividend_amount"] = dividend_amount |
||||
|
total_amount_dividend += dividend_amount |
||||
|
|
||||
|
line_id = det_div_line_obj.create(vals) |
||||
|
elif line.effective_date < self.date_from: |
||||
|
dividend_amount = line.total_amount_line * self.percentage |
||||
|
vals["days"] = number_of_days |
||||
|
vals["dividend_year_id"] = self.id |
||||
|
vals[ |
||||
|
"coop_number" |
||||
|
] = line.partner_id.cooperator_register_number |
||||
|
vals["partner_id"] = partner.id |
||||
|
vals["share_line_id"] = line.id |
||||
|
vals["coeff"] = self.percentage |
||||
|
vals["dividend_amount"] = dividend_amount |
||||
|
total_amount_dividend += dividend_amount |
||||
|
|
||||
|
line_id = det_div_line_obj.create(vals) |
||||
|
if line_id: |
||||
|
vals2[ |
||||
|
"coop_number" |
||||
|
] = line.partner_id.cooperator_register_number |
||||
|
vals2["dividend_year_id"] = self.id |
||||
|
vals2["partner_id"] = line.partner_id.id |
||||
|
|
||||
|
vals2["dividend_amount_net"] = total_amount_dividend |
||||
|
vals2["dividend_amount"] = total_amount_dividend |
||||
|
|
||||
|
# TODO set as a parameter on dividend year object |
||||
|
if total_amount_dividend <= 190.00: |
||||
|
vals2["dividend_taxes"] = 0.0 |
||||
|
else: |
||||
|
div_tax = ( |
||||
|
total_amount_dividend - 190 |
||||
|
) * self.withholding_tax |
||||
|
vals2["dividend_taxes"] = div_tax |
||||
|
vals2["dividend_amount_net"] = ( |
||||
|
total_amount_dividend - div_tax |
||||
|
) |
||||
|
|
||||
|
div_line_obj.create(vals2) |
||||
|
return True |
||||
|
|
||||
|
|
||||
|
class DetailedDividendLine(models.Model): |
||||
|
_name = "detailed.dividend.line" |
||||
|
|
||||
|
@api.multi |
||||
|
def _compute_total_line(self): |
||||
|
res = {} |
||||
|
for line in self: |
||||
|
res[line.id] = line.share_unit_price * line.share_number |
||||
|
return res |
||||
|
|
||||
|
dividend_year_id = fields.Many2one("dividend.year", string="Dividend year") |
||||
|
coop_number = fields.Integer(string="Cooperator Number") |
||||
|
days = fields.Integer(string="Days") |
||||
|
partner_id = fields.Many2one( |
||||
|
"res.partner", string="Cooperator", readonly=True |
||||
|
) |
||||
|
share_line_id = fields.Many2one( |
||||
|
"share.line", string="Share line", readonly=True |
||||
|
) |
||||
|
share_number = fields.Integer( |
||||
|
related="share_line_id.share_number", string="Number of Share" |
||||
|
) |
||||
|
share_unit_price = fields.Monetary( |
||||
|
string="Share unit price", related="share_line_id.share_unit_price" |
||||
|
) |
||||
|
effective_date = fields.Date( |
||||
|
related="share_line_id.effective_date", string="Effective date" |
||||
|
) |
||||
|
total_amount_line = fields.Monetary( |
||||
|
string="Total value of share", |
||||
|
currency_field="company_currency_id", |
||||
|
compute=_compute_total_line, |
||||
|
readonly=True, |
||||
|
) |
||||
|
coeff = fields.Float(string="Coefficient to apply", digits=(2, 4)) |
||||
|
dividend_amount = fields.Float(string="Gross Dividend") |
||||
|
dividend_amount_net = fields.Float(string="Dividend net") |
||||
|
dividend_taxes = fields.Float(string="Taxes") |
||||
|
company_currency_id = fields.Many2one( |
||||
|
related="share_line_id.company_currency_id", readonly=True |
||||
|
) |
||||
|
|
||||
|
|
||||
|
class DividendLine(models.Model): |
||||
|
_name = "dividend.line" |
||||
|
|
||||
|
@api.multi |
||||
|
def _get_account_number(self): |
||||
|
res = {} |
||||
|
for line in self: |
||||
|
bank_accounts = self.env["res.partner.bank"].search( |
||||
|
[("partner_id", "=", line.partner_id.id)] |
||||
|
) |
||||
|
res[line.id] = bank_accounts[0].acc_number |
||||
|
|
||||
|
return res |
||||
|
|
||||
|
coop_number = fields.Integer(string="Coop Number") |
||||
|
dividend_year_id = fields.Many2one("dividend.year", string="Dividend year") |
||||
|
partner_id = fields.Many2one( |
||||
|
"res.partner", string="Cooperator", readonly=True |
||||
|
) |
||||
|
account_number = fields.Char( |
||||
|
compute=_get_account_number, string="Account Number" |
||||
|
) |
||||
|
dividend_amount = fields.Float(string="Gross Dividend") |
||||
|
dividend_amount_net = fields.Float(string="Dividend net") |
||||
|
dividend_taxes = fields.Float(string="Taxes") |
@ -1,281 +1,322 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
|
|
||||
from openerp import fields, models, api |
|
||||
|
|
||||
import time |
|
||||
from cStringIO import StringIO |
|
||||
import base64 |
|
||||
|
|
||||
import xlsxwriter |
|
||||
|
|
||||
HEADER = [ |
|
||||
'Num. Coop', |
|
||||
'Nom', |
|
||||
'Email', |
|
||||
'Banque', |
|
||||
'Mobile', |
|
||||
'Adresse', |
|
||||
'Rue', |
|
||||
'Code Postal', |
|
||||
'Ville', |
|
||||
'Pays', |
|
||||
'Nombre de part total', |
|
||||
'Montant total des parts', |
|
||||
'Demande de liberation de capital', |
|
||||
'Communication', |
|
||||
'Nombre de part', |
|
||||
'Montant', |
|
||||
'Reception du paiement', |
|
||||
'Date de la souscription' |
|
||||
] |
|
||||
HEADER2 = [ |
|
||||
'Date de la souscription', |
|
||||
'Nom', |
|
||||
'Type', |
|
||||
'Nombre de part', |
|
||||
'Montant', |
|
||||
'Statut', |
|
||||
'Email', |
|
||||
'Mobile', |
|
||||
'Adresse', |
|
||||
'Code Postal', |
|
||||
'Ville', |
|
||||
'Pays', |
|
||||
] |
|
||||
|
|
||||
|
|
||||
class export_global_report(models.TransientModel): |
|
||||
_name = 'export.global.report' |
|
||||
|
|
||||
name = fields.Char('Name') |
|
||||
|
|
||||
def write_header(self, worksheet, headers): |
|
||||
i = 0 |
|
||||
for header in headers: |
|
||||
worksheet.write(0, i, header) |
|
||||
i += 1 |
|
||||
return True |
|
||||
|
|
||||
@api.multi |
|
||||
def export_global_report_xlsx(self): |
|
||||
partner_obj = self.env['res.partner'] |
|
||||
invoice_obj = self.env['account.invoice'] |
|
||||
subscription_obj = self.env['subscription.request'] |
|
||||
|
|
||||
file_data = StringIO() |
|
||||
workbook = xlsxwriter.Workbook(file_data) |
|
||||
worksheet1 = workbook.add_worksheet() |
|
||||
|
|
||||
self.write_header(worksheet1, HEADER) |
|
||||
cooperators = partner_obj.search([('cooperator', '=', True), |
|
||||
('member', '=', True)]) |
|
||||
|
|
||||
j = 1 |
|
||||
for coop in cooperators: |
|
||||
i = 0 |
|
||||
worksheet1.write(j, i, coop.cooperator_register_number) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.name) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.email) |
|
||||
i += 1 |
|
||||
acc_number = "" |
|
||||
if coop.bank_ids: |
|
||||
acc_number = coop.bank_ids[0].acc_number |
|
||||
worksheet1.write(j, i, acc_number) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.phone) |
|
||||
i += 1 |
|
||||
address = coop.street + ' ' + coop.zip + ' ' \ |
|
||||
+ coop.city + ' ' + coop.country_id.name |
|
||||
worksheet1.write(j, i, address) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.street) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, int(coop.zip)) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.city) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.country_id.name) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.number_of_share) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, coop.total_value) |
|
||||
|
|
||||
invoice_ids = invoice_obj.search([('release_capital_request', '=', True), |
|
||||
('partner_id', '=', coop.id)]) |
|
||||
j += 1 |
|
||||
for invoice in invoice_ids: |
|
||||
i = 11 |
|
||||
worksheet1.write(j, i, invoice.number) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, invoice.state) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, invoice.date_invoice) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, invoice.reference) |
|
||||
i += 1 |
|
||||
for line in invoice.invoice_line_ids: |
|
||||
worksheet1.write(j, i, line.quantity) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, line.price_subtotal) |
|
||||
i += 1 |
|
||||
if invoice.payment_ids: |
|
||||
worksheet1.write(j, i, invoice.payment_ids[0].payment_date) |
|
||||
i += 1 |
|
||||
if invoice.subscription_request: |
|
||||
ind = len(invoice.subscription_request)-1 |
|
||||
worksheet1.write(j, i, invoice.subscription_request[ind].date) |
|
||||
j += 1 |
|
||||
|
|
||||
sub_requests = subscription_obj.search([('state', 'in', |
|
||||
['draft', 'waiting']), |
|
||||
('partner_id', '=', coop.id) |
|
||||
]) |
|
||||
for sub_request in sub_requests: |
|
||||
i = 11 |
|
||||
worksheet1.write(j, i, dict(subscription_obj._columns['type'].selection).get(sub_request.type,False)) |
|
||||
i += 1 |
|
||||
worksheet1.write(j, i, sub_request.state) |
|
||||
i += 3 |
|
||||
quantity = int(sub_request.ordered_parts) |
|
||||
worksheet1.write(j, i, quantity) |
|
||||
i += 1 |
|
||||
amount = quantity * sub_request.share_unit_price |
|
||||
worksheet1.write(j, i, amount) |
|
||||
i += 2 |
|
||||
worksheet1.write(j, i, sub_request.date) |
|
||||
j += 1 |
|
||||
|
|
||||
worksheet1bis = workbook.add_worksheet() |
|
||||
self.write_header(worksheet1bis, HEADER) |
|
||||
cooperators = partner_obj.search([('cooperator', '=', True), |
|
||||
('member', '=', False)]) |
|
||||
|
|
||||
j = 1 |
|
||||
for coop in cooperators: |
|
||||
i = 0 |
|
||||
worksheet1bis.write(j, i, coop.cooperator_register_number) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.name) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.email) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.phone) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.street) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, int(coop.zip)) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.city) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.country_id.name) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.number_of_share) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, coop.total_value) |
|
||||
|
|
||||
invoice_ids = invoice_obj.search([('release_capital_request', '=', True), |
|
||||
('partner_id', '=', coop.id)]) |
|
||||
j += 1 |
|
||||
for invoice in invoice_ids: |
|
||||
i = 11 |
|
||||
worksheet1bis.write(j, i, invoice.number) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, invoice.state) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, invoice.date_invoice) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, invoice.reference) |
|
||||
i += 1 |
|
||||
for line in invoice.invoice_line_ids: |
|
||||
worksheet1bis.write(j, i, line.quantity) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, line.price_subtotal) |
|
||||
i += 1 |
|
||||
if invoice.payment_ids: |
|
||||
worksheet1bis.write(j, i, invoice.payment_ids[0].date) |
|
||||
i += 1 |
|
||||
if invoice.subscription_request: |
|
||||
ind = len(invoice.subscription_request)-1 |
|
||||
worksheet1bis.write(j, i, invoice.subscription_request[ind].date) |
|
||||
j += 1 |
|
||||
|
|
||||
sub_requests = subscription_obj.search([('state', 'in', |
|
||||
['draft', 'waiting']), |
|
||||
('partner_id', '=', coop.id) |
|
||||
]) |
|
||||
for sub_request in sub_requests: |
|
||||
i = 11 |
|
||||
worksheet1bis.write(j, i, dict(subscription_obj._columns['type'].selection).get(sub_request.type,False)) |
|
||||
i += 1 |
|
||||
worksheet1bis.write(j, i, sub_request.state) |
|
||||
i += 3 |
|
||||
quantity = int(sub_request.ordered_parts) |
|
||||
worksheet1bis.write(j, i, quantity) |
|
||||
i += 1 |
|
||||
amount = quantity * sub_request.share_unit_price |
|
||||
worksheet1bis.write(j, i, amount) |
|
||||
i += 2 |
|
||||
worksheet1bis.write(j, i, sub_request.date) |
|
||||
j += 1 |
|
||||
|
|
||||
worksheet2 = workbook.add_worksheet() |
|
||||
self.write_header(worksheet2, HEADER2) |
|
||||
sub_requests = subscription_obj.search([('state', 'in', |
|
||||
['draft', 'waiting']), |
|
||||
]) |
|
||||
|
|
||||
j = 1 |
|
||||
for sub_request in sub_requests: |
|
||||
i = 0 |
|
||||
worksheet2.write(j, i, sub_request.date) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.name) |
|
||||
i += 1 |
|
||||
sub_type_sel = subscription_obj._columns['type'].selection |
|
||||
worksheet2.write(j, i, dict(sub_type_sel).get(sub_request.type, False)) |
|
||||
i += 1 |
|
||||
quantity = int(sub_request.ordered_parts) |
|
||||
worksheet2.write(j, i, quantity) |
|
||||
i += 1 |
|
||||
amount = quantity * sub_request.share_unit_price |
|
||||
worksheet2.write(j, i, amount) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.state) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.email) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.phone) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.address) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.city) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, int(sub_request.zip_code)) |
|
||||
i += 1 |
|
||||
worksheet2.write(j, i, sub_request.country_id.name) |
|
||||
j += 1 |
|
||||
|
|
||||
workbook.close() |
|
||||
file_data.seek(0) |
|
||||
|
|
||||
data = base64.encodestring(file_data.read()) |
|
||||
|
|
||||
attachment_id = self.env['ir.attachment'].create({ |
|
||||
'name': "Global export" + time.strftime('%Y-%m-%d %H:%M') |
|
||||
+ ".xlsx", |
|
||||
'datas': data, |
|
||||
'datas_fname': 'Global_export.xlsx', |
|
||||
'res_model': 'export.global.report', |
|
||||
},) |
|
||||
|
|
||||
# Prepare your download URL |
|
||||
download_url = '/web/content/' + str(attachment_id.id) + '?download=True' |
|
||||
base_url = self.env['ir.config_parameter'].get_param('web.base.url') |
|
||||
|
|
||||
return { |
|
||||
"type": "ir.actions.act_url", |
|
||||
"url": str(base_url) + str(download_url), |
|
||||
"target": "new", |
|
||||
} |
|
||||
|
import base64 |
||||
|
import time |
||||
|
|
||||
|
import xlsxwriter |
||||
|
from cStringIO import StringIO |
||||
|
from openerp import api, fields, models |
||||
|
|
||||
|
HEADER = [ |
||||
|
"Num. Coop", |
||||
|
"Nom", |
||||
|
"Email", |
||||
|
"Banque", |
||||
|
"Mobile", |
||||
|
"Adresse", |
||||
|
"Rue", |
||||
|
"Code Postal", |
||||
|
"Ville", |
||||
|
"Pays", |
||||
|
"Nombre de part total", |
||||
|
"Montant total des parts", |
||||
|
"Demande de liberation de capital", |
||||
|
"Communication", |
||||
|
"Nombre de part", |
||||
|
"Montant", |
||||
|
"Reception du paiement", |
||||
|
"Date de la souscription", |
||||
|
] |
||||
|
HEADER2 = [ |
||||
|
"Date de la souscription", |
||||
|
"Nom", |
||||
|
"Type", |
||||
|
"Nombre de part", |
||||
|
"Montant", |
||||
|
"Statut", |
||||
|
"Email", |
||||
|
"Mobile", |
||||
|
"Adresse", |
||||
|
"Code Postal", |
||||
|
"Ville", |
||||
|
"Pays", |
||||
|
] |
||||
|
|
||||
|
|
||||
|
class ExportGlobalReport(models.TransientModel): |
||||
|
_name = "export.global.report" |
||||
|
|
||||
|
name = fields.Char("Name") |
||||
|
|
||||
|
def write_header(self, worksheet, headers): |
||||
|
i = 0 |
||||
|
for header in headers: |
||||
|
worksheet.write(0, i, header) |
||||
|
i += 1 |
||||
|
return True |
||||
|
|
||||
|
@api.multi |
||||
|
def export_global_report_xlsx(self): |
||||
|
partner_obj = self.env["res.partner"] |
||||
|
invoice_obj = self.env["account.invoice"] |
||||
|
subscription_obj = self.env["subscription.request"] |
||||
|
|
||||
|
file_data = StringIO() |
||||
|
workbook = xlsxwriter.Workbook(file_data) |
||||
|
worksheet1 = workbook.add_worksheet() |
||||
|
|
||||
|
self.write_header(worksheet1, HEADER) |
||||
|
cooperators = partner_obj.search( |
||||
|
[("cooperator", "=", True), ("member", "=", True)] |
||||
|
) |
||||
|
|
||||
|
j = 1 |
||||
|
for coop in cooperators: |
||||
|
i = 0 |
||||
|
worksheet1.write(j, i, coop.cooperator_register_number) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.name) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.email) |
||||
|
i += 1 |
||||
|
acc_number = "" |
||||
|
if coop.bank_ids: |
||||
|
acc_number = coop.bank_ids[0].acc_number |
||||
|
worksheet1.write(j, i, acc_number) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.phone) |
||||
|
i += 1 |
||||
|
address = ( |
||||
|
coop.street |
||||
|
+ " " |
||||
|
+ coop.zip |
||||
|
+ " " |
||||
|
+ coop.city |
||||
|
+ " " |
||||
|
+ coop.country_id.name |
||||
|
) |
||||
|
worksheet1.write(j, i, address) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.street) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, int(coop.zip)) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.city) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.country_id.name) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.number_of_share) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, coop.total_value) |
||||
|
|
||||
|
invoice_ids = invoice_obj.search( |
||||
|
[ |
||||
|
("release_capital_request", "=", True), |
||||
|
("partner_id", "=", coop.id), |
||||
|
] |
||||
|
) |
||||
|
j += 1 |
||||
|
for invoice in invoice_ids: |
||||
|
i = 11 |
||||
|
worksheet1.write(j, i, invoice.number) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, invoice.state) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, invoice.date_invoice) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, invoice.reference) |
||||
|
i += 1 |
||||
|
for line in invoice.invoice_line_ids: |
||||
|
worksheet1.write(j, i, line.quantity) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, line.price_subtotal) |
||||
|
i += 1 |
||||
|
if invoice.payment_ids: |
||||
|
worksheet1.write(j, i, invoice.payment_ids[0].payment_date) |
||||
|
i += 1 |
||||
|
if invoice.subscription_request: |
||||
|
ind = len(invoice.subscription_request) - 1 |
||||
|
worksheet1.write( |
||||
|
j, i, invoice.subscription_request[ind].date |
||||
|
) |
||||
|
j += 1 |
||||
|
|
||||
|
sub_requests = subscription_obj.search( |
||||
|
[ |
||||
|
("state", "in", ["draft", "waiting"]), |
||||
|
("partner_id", "=", coop.id), |
||||
|
] |
||||
|
) |
||||
|
for sub_request in sub_requests: |
||||
|
i = 11 |
||||
|
worksheet1.write( |
||||
|
j, |
||||
|
i, |
||||
|
dict(subscription_obj._columns["type"].selection).get( |
||||
|
sub_request.type, False |
||||
|
), |
||||
|
) |
||||
|
i += 1 |
||||
|
worksheet1.write(j, i, sub_request.state) |
||||
|
i += 3 |
||||
|
quantity = int(sub_request.ordered_parts) |
||||
|
worksheet1.write(j, i, quantity) |
||||
|
i += 1 |
||||
|
amount = quantity * sub_request.share_unit_price |
||||
|
worksheet1.write(j, i, amount) |
||||
|
i += 2 |
||||
|
worksheet1.write(j, i, sub_request.date) |
||||
|
j += 1 |
||||
|
|
||||
|
worksheet1bis = workbook.add_worksheet() |
||||
|
self.write_header(worksheet1bis, HEADER) |
||||
|
cooperators = partner_obj.search( |
||||
|
[("cooperator", "=", True), ("member", "=", False)] |
||||
|
) |
||||
|
|
||||
|
j = 1 |
||||
|
for coop in cooperators: |
||||
|
i = 0 |
||||
|
worksheet1bis.write(j, i, coop.cooperator_register_number) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.name) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.email) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.phone) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.street) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, int(coop.zip)) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.city) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.country_id.name) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.number_of_share) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, coop.total_value) |
||||
|
|
||||
|
invoice_ids = invoice_obj.search( |
||||
|
[ |
||||
|
("release_capital_request", "=", True), |
||||
|
("partner_id", "=", coop.id), |
||||
|
] |
||||
|
) |
||||
|
j += 1 |
||||
|
for invoice in invoice_ids: |
||||
|
i = 11 |
||||
|
worksheet1bis.write(j, i, invoice.number) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, invoice.state) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, invoice.date_invoice) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, invoice.reference) |
||||
|
i += 1 |
||||
|
for line in invoice.invoice_line_ids: |
||||
|
worksheet1bis.write(j, i, line.quantity) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, line.price_subtotal) |
||||
|
i += 1 |
||||
|
if invoice.payment_ids: |
||||
|
worksheet1bis.write(j, i, invoice.payment_ids[0].date) |
||||
|
i += 1 |
||||
|
if invoice.subscription_request: |
||||
|
ind = len(invoice.subscription_request) - 1 |
||||
|
worksheet1bis.write( |
||||
|
j, i, invoice.subscription_request[ind].date |
||||
|
) |
||||
|
j += 1 |
||||
|
|
||||
|
sub_requests = subscription_obj.search( |
||||
|
[ |
||||
|
("state", "in", ["draft", "waiting"]), |
||||
|
("partner_id", "=", coop.id), |
||||
|
] |
||||
|
) |
||||
|
for sub_request in sub_requests: |
||||
|
i = 11 |
||||
|
worksheet1bis.write( |
||||
|
j, |
||||
|
i, |
||||
|
dict(subscription_obj._columns["type"].selection).get( |
||||
|
sub_request.type, False |
||||
|
), |
||||
|
) |
||||
|
i += 1 |
||||
|
worksheet1bis.write(j, i, sub_request.state) |
||||
|
i += 3 |
||||
|
quantity = int(sub_request.ordered_parts) |
||||
|
worksheet1bis.write(j, i, quantity) |
||||
|
i += 1 |
||||
|
amount = quantity * sub_request.share_unit_price |
||||
|
worksheet1bis.write(j, i, amount) |
||||
|
i += 2 |
||||
|
worksheet1bis.write(j, i, sub_request.date) |
||||
|
j += 1 |
||||
|
|
||||
|
worksheet2 = workbook.add_worksheet() |
||||
|
self.write_header(worksheet2, HEADER2) |
||||
|
sub_requests = subscription_obj.search( |
||||
|
[("state", "in", ["draft", "waiting"])] |
||||
|
) |
||||
|
|
||||
|
j = 1 |
||||
|
for sub_request in sub_requests: |
||||
|
i = 0 |
||||
|
worksheet2.write(j, i, sub_request.date) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.name) |
||||
|
i += 1 |
||||
|
sub_type_sel = subscription_obj._columns["type"].selection |
||||
|
worksheet2.write( |
||||
|
j, i, dict(sub_type_sel).get(sub_request.type, False) |
||||
|
) |
||||
|
i += 1 |
||||
|
quantity = int(sub_request.ordered_parts) |
||||
|
worksheet2.write(j, i, quantity) |
||||
|
i += 1 |
||||
|
amount = quantity * sub_request.share_unit_price |
||||
|
worksheet2.write(j, i, amount) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.state) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.email) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.phone) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.address) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.city) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, int(sub_request.zip_code)) |
||||
|
i += 1 |
||||
|
worksheet2.write(j, i, sub_request.country_id.name) |
||||
|
j += 1 |
||||
|
|
||||
|
workbook.close() |
||||
|
file_data.seek(0) |
||||
|
|
||||
|
data = base64.encodestring(file_data.read()) |
||||
|
|
||||
|
attachment_id = self.env["ir.attachment"].create( |
||||
|
{ |
||||
|
"name": "Global export" |
||||
|
+ time.strftime("%Y-%m-%d %H:%M") |
||||
|
+ ".xlsx", |
||||
|
"datas": data, |
||||
|
"datas_fname": "Global_export.xlsx", |
||||
|
"res_model": "export.global.report", |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
# Prepare your download URL |
||||
|
download_url = ( |
||||
|
"/web/content/" + str(attachment_id.id) + "?download=True" |
||||
|
) |
||||
|
base_url = self.env["ir.config_parameter"].get_param("web.base.url") |
||||
|
|
||||
|
return { |
||||
|
"type": "ir.actions.act_url", |
||||
|
"url": str(base_url) + str(download_url), |
||||
|
"target": "new", |
||||
|
} |
@ -1,19 +1,21 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class SubscriptionRequest(models.Model): |
|
||||
_inherit = 'subscription.request' |
|
||||
|
|
||||
company_type = fields.Selection(selection_add=[ |
|
||||
('asso', 'Association'), |
|
||||
('eurl', 'EURL / Entreprise individuelle'), |
|
||||
('sarl', 'SARL'), |
|
||||
('sa', 'SA / SAS') |
|
||||
]) |
|
||||
|
|
||||
def get_required_field(self): |
|
||||
req_fields = super(SubscriptionRequest, self).get_required_field() |
|
||||
if 'iban' in req_fields: |
|
||||
req_fields.remove('iban') |
|
||||
|
|
||||
return req_fields |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class SubscriptionRequest(models.Model): |
||||
|
_inherit = "subscription.request" |
||||
|
|
||||
|
company_type = fields.Selection( |
||||
|
selection_add=[ |
||||
|
("asso", "Association"), |
||||
|
("eurl", "EURL / Entreprise individuelle"), |
||||
|
("sarl", "SARL"), |
||||
|
("sa", "SA / SAS"), |
||||
|
] |
||||
|
) |
||||
|
|
||||
|
def get_required_field(self): |
||||
|
req_fields = super(SubscriptionRequest, self).get_required_field() |
||||
|
if "iban" in req_fields: |
||||
|
req_fields.remove("iban") |
||||
|
|
||||
|
return req_fields |
@ -1,12 +1,14 @@ |
|||||
from odoo import fields, models |
|
||||
|
|
||||
|
|
||||
class ResPartner(models.Model): |
|
||||
_inherit = 'res.partner' |
|
||||
|
|
||||
legal_form = fields.Selection(selection_add=[ |
|
||||
('asso', 'Association'), |
|
||||
('eurl', 'EURL / Entreprise individuelle'), |
|
||||
('sarl', 'SARL'), |
|
||||
('sa', 'SA / SAS') |
|
||||
]) |
|
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = "res.partner" |
||||
|
|
||||
|
legal_form = fields.Selection( |
||||
|
selection_add=[ |
||||
|
("asso", "Association"), |
||||
|
("eurl", "EURL / Entreprise individuelle"), |
||||
|
("sarl", "SARL"), |
||||
|
("sa", "SA / SAS"), |
||||
|
] |
||||
|
) |
@ -1,30 +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 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/loan_view.xml', |
|
||||
'views/partner_view.xml', |
|
||||
'views/menus.xml', |
|
||||
'data/mail_template_data.xml', |
|
||||
], |
|
||||
"demo": [ |
|
||||
"demo/coop.xml", |
|
||||
], |
|
||||
'installable': True, |
|
||||
} |
|
||||
|
# 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", |
||||
|
"summary": """ |
||||
|
This module allows to manage the bonds and |
||||
|
subordinated loans subscription life cycle. |
||||
|
""", |
||||
|
"data": [ |
||||
|
"security/ir.model.access.csv", |
||||
|
"views/loan_view.xml", |
||||
|
"views/partner_view.xml", |
||||
|
"views/menus.xml", |
||||
|
"data/mail_template_data.xml", |
||||
|
], |
||||
|
"demo": ["demo/coop.xml"], |
||||
|
"installable": True, |
||||
|
} |
@ -1,26 +1,19 @@ |
|||||
# 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, |
|
||||
} |
|
||||
|
# 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", |
||||
|
"summary": """ |
||||
|
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,95 +1,103 @@ |
|||||
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'] |
|
||||
partner = request.env.user.partner_id |
|
||||
if loan_issue_id: |
|
||||
loan_issue = loan_issue_obj.sudo().browse(int(loan_issue_id)) |
|
||||
max_amount = loan_issue.get_max_amount(partner) |
|
||||
return { |
|
||||
loan_issue.id: { |
|
||||
'max_amount': max_amount, |
|
||||
'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) |
|
||||
|
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"] |
||||
|
partner = request.env.user.partner_id |
||||
|
if loan_issue_id: |
||||
|
loan_issue = loan_issue_obj.sudo().browse(int(loan_issue_id)) |
||||
|
max_amount = loan_issue.get_max_amount(partner) |
||||
|
return { |
||||
|
loan_issue.id: { |
||||
|
"max_amount": max_amount, |
||||
|
"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) |
@ -1,34 +1,41 @@ |
|||||
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 [] |
|
||||
query = """SELECT id |
|
||||
FROM "%s" |
|
||||
WHERE extract(year from age(CURRENT_DATE, |
|
||||
birthdate_date)) %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_date') |
|
||||
def _compute_age(self): |
|
||||
if self.birthdate_date: |
|
||||
dBday = datetime.strptime(str(self.birthdate_date), |
|
||||
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') |
|
||||
|
from datetime import datetime |
||||
|
|
||||
|
from openerp import api, fields, models |
||||
|
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as OE_DFORMAT |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
_inherit = "res.partner" |
||||
|
|
||||
|
def _search_age(self, operator, value): |
||||
|
if operator not in ("=", "!=", "<", "<=", ">", ">=", "in", "not in"): |
||||
|
return [] |
||||
|
query = """SELECT id |
||||
|
FROM "%s" |
||||
|
WHERE extract(year from age(CURRENT_DATE, |
||||
|
birthdate_date)) %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.multi |
||||
|
@api.depends("birthdate_date") |
||||
|
def _compute_age(self): |
||||
|
self.ensure_one() |
||||
|
if self.birthdate_date: |
||||
|
dBday = datetime.strptime( |
||||
|
str(self.birthdate_date), 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" |
||||
|
) |
@ -1,26 +1,14 @@ |
|||||
# Copyright 2004 Tech-Receptives Solutions Pvt. Ltd. |
# Copyright 2004 Tech-Receptives Solutions Pvt. Ltd. |
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). |
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). |
||||
{ |
{ |
||||
'name': 'Website reCAPTCHA Reloaded', |
|
||||
'version': '12.0.0.1', |
|
||||
'category': 'Website', |
|
||||
'depends': ['website'], |
|
||||
'author': 'Tech Receptives', |
|
||||
'license': 'AGPL-3', |
|
||||
'website': 'https://www.techreceptives.com', |
|
||||
'description': """ |
|
||||
Odoo Website reCAPTCHA Reloaded |
|
||||
================================ |
|
||||
This modules allows you to integrate Google reCAPTCHA v2.0 to your website |
|
||||
forms. You can configure your Google reCAPTCHA site and public keys |
|
||||
in "Settings" -> "Website Settings" |
|
||||
|
|
||||
You will need to install various website_<module>_recaptcha modules |
|
||||
to use it in your various pages. |
|
||||
""", |
|
||||
'data': [ |
|
||||
'views/website_view.xml', |
|
||||
'views/res_config.xml', |
|
||||
], |
|
||||
'installable': True, |
|
||||
|
"name": "Website reCAPTCHA Reloaded", |
||||
|
"version": "12.0.0.0.1", |
||||
|
"category": "Website", |
||||
|
"depends": ["website"], |
||||
|
"author": "Tech Receptives", |
||||
|
"license": "AGPL-3", |
||||
|
"website": "https://www.techreceptives.com", |
||||
|
"summary": "Add google recaptcha to forms.", |
||||
|
"data": ["views/website_view.xml", "views/res_config.xml"], |
||||
|
"installable": True, |
||||
} |
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue