You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

724 lines
33 KiB

5 years ago
[ADD] bond and loan issues management [ADD] bond and loan issues management module skeleton [IMP] change increase menu sequence [IMP] add models, fields and views [IMP] add xml declaration in head of file [ADD] add easy_my_coop_loan_website - WIP [IMP] add access rights [IMP] this raise inconsistency so replace id by default_code. [IMP] change import openerp to odoo [IMP] add website loan module [FIX] put website display in loan [FIX] fix import [FIX] fix function [IMP] use correct name [IMP] make the loan and bond visible [IMP] add js, field and logic to set amount limit per subscription [IMP] remove dependency on recaptcha as user is logged to subscribe [IMP] add fields [IMP] save loan issue subscription still in WIP [IMP] remove alert pop up [IMP] add dependency to easy_my_coop_website [IMP] remove force send for sub request creation email notification [IMP] add mail templates [IMP] save subscription in the corresponding loan issue. add email notif [FIX] fix loan issue line view [FIX] add related field to loan issue. It is where the data stand [IMP] move term_view up [FIX] fix js error when false is returned [FIX] fix function when loan_issue_id in None [IMP] add actions and button [FIX] fix action [FIX] fix mail template [IMP] set noupdate=1 [IMP] change order [IMP] display loan issue lines on partner form [IMP] add loan view in partner form [IMP] add face value on loan issue and line add face value on loan issue and line. add as well the quantity and computation of the amount [FIX] missing id overriding values wasn't working [IMP] getting bond face value and setting it as step. [IMP] subscribed_amount computed field is the sum of the amount lines [IMP] allow a waiting payment to be cancelled [IMP] make field required [REFACT] move loan issue line code to dedicated file [IMP] add interest calculation and model [ADD] bond and loan issues management module skeleton [IMP] add models, fields and views [IMP] allow creation by hand [IMP] adding partner related field [IMP] put code in separate function [FIX] pass it to get method [IMP] routes consistent form [FIX] fix eof [FIX] GET is working for ajax call [IMP] website page for loan issue subscription
5 years ago
7 years ago
7 years ago
7 years ago
7 years ago
6 years ago
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2019 Coop IT Easy SCRL fs
  3. # Houssine Bakkali <houssine@coopiteasy.be>
  4. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  5. from datetime import datetime
  6. from odoo import api, fields, models, _
  7. from addons.base_iban.models.res_partner_bank import validate_iban
  8. from odoo.exceptions import UserError, ValidationError
  9. _REQUIRED = ['email',
  10. 'firstname',
  11. 'lastname',
  12. 'birthdate',
  13. 'address',
  14. 'share_product_id',
  15. 'ordered_parts',
  16. 'zip_code',
  17. 'city',
  18. 'iban',
  19. 'gender']
  20. @api.model
  21. def _lang_get(self):
  22. languages = self.env['res.lang'].search([])
  23. return [(language.code, language.name) for language in languages]
  24. class SubscriptionRequest(models.Model):
  25. _name = 'subscription.request'
  26. _description = 'Subscription Request'
  27. def get_required_field(self):
  28. required_fields = _REQUIRED
  29. company = self.env['res.company']._company_default_get()
  30. if company.data_policy_approval_required:
  31. required_fields.append('data_policy_approved')
  32. if company.internal_rules_approval_required:
  33. required_fields.append('internal_rules_approved')
  34. return required_fields
  35. def get_mail_template_notif(self, is_company=False):
  36. if is_company:
  37. return 'easy_my_coop.email_template_confirmation_company'
  38. else:
  39. return 'easy_my_coop.email_template_confirmation'
  40. def is_member(self, vals, cooperator):
  41. if cooperator.member:
  42. vals['type'] = 'increase'
  43. vals['already_cooperator'] = True
  44. return vals
  45. @api.model
  46. def create(self, vals):
  47. partner_obj = self.env['res.partner']
  48. mail_template = self.get_mail_template_notif(False)
  49. if not vals.get('partner_id'):
  50. cooperator = False
  51. if vals.get('email'):
  52. cooperator = partner_obj.get_cooperator_from_email(
  53. vals.get('email'))
  54. if cooperator:
  55. # TODO remove the following line of code once it has
  56. # been found a way to avoid double encoding
  57. cooperator = cooperator[0]
  58. vals['type'] = 'subscription'
  59. vals = self.is_member(vals, cooperator)
  60. vals['partner_id'] = cooperator.id
  61. if not cooperator.cooperator:
  62. cooperator.write({'cooperator': True})
  63. else:
  64. cooperator_id = vals.get('partner_id')
  65. cooperator = partner_obj.browse(cooperator_id)
  66. vals = self.is_member(vals, cooperator)
  67. subscr_request = super(SubscriptionRequest, self).create(vals)
  68. confirmation_mail_template = self.env.ref(mail_template, False)
  69. confirmation_mail_template.send_mail(subscr_request.id)
  70. return subscr_request
  71. @api.model
  72. def create_comp_sub_req(self, vals):
  73. mail_template = self.get_mail_template_notif(True)
  74. vals["name"] = vals['company_name']
  75. if not vals.get('partner_id'):
  76. cooperator = self.env['res.partner'].get_cooperator_from_crn(vals.get('company_register_number'))
  77. if cooperator:
  78. vals['partner_id'] = cooperator.id
  79. vals['type'] = 'increase'
  80. vals['already_cooperator'] = True
  81. subscr_request = super(SubscriptionRequest, self).create(vals)
  82. confirmation_mail_template = self.env.ref(mail_template, False)
  83. confirmation_mail_template.send_mail(subscr_request.id)
  84. return subscr_request
  85. def check_empty_string(self, value):
  86. if value is None or value is False or value == '':
  87. return False
  88. return True
  89. def check_iban(self, iban):
  90. validated = True
  91. if iban:
  92. try:
  93. validate_iban(iban)
  94. except ValidationError:
  95. validated = False
  96. return validated
  97. @api.multi
  98. @api.depends('iban', 'skip_control_ng', 'is_company')
  99. def _validated_lines(self):
  100. for sub_request in self:
  101. validated = (self.check_iban(sub_request.iban)
  102. or sub_request.skip_control_ng
  103. )
  104. sub_request.validated = validated
  105. @api.multi
  106. @api.depends('share_product_id',
  107. 'share_product_id.list_price',
  108. 'ordered_parts')
  109. def _compute_subscription_amount(self):
  110. for sub_request in self:
  111. sub_request.subscription_amount = (sub_request.share_product_id.
  112. list_price *
  113. sub_request.ordered_parts)
  114. already_cooperator = fields.Boolean(string="I'm already cooperator",
  115. readonly=True,
  116. states={'draft': [('readonly', False)]}
  117. )
  118. name = fields.Char(string='Name',
  119. required=True,
  120. readonly=True,
  121. states={'draft': [('readonly', False)]})
  122. firstname = fields.Char(string='Firstname',
  123. readonly=True,
  124. states={'draft': [('readonly', False)]})
  125. lastname = fields.Char(string='Lastname',
  126. readonly=True,
  127. states={'draft': [('readonly', False)]})
  128. birthdate = fields.Date(string="Birthdate",
  129. readonly=True,
  130. states={'draft': [('readonly', False)]})
  131. gender = fields.Selection([('male', _('Male')),
  132. ('female', _('Female')),
  133. ('other', _('Other'))],
  134. string='Gender',
  135. readonly=True,
  136. states={'draft': [('readonly', False)]})
  137. type = fields.Selection([('new', 'New Cooperator'),
  138. ('subscription', 'Subscription'),
  139. ('increase', 'Increase number of share')],
  140. string='Type', default="new",
  141. readonly=True,
  142. states={'draft': [('readonly', False)]})
  143. state = fields.Selection([('draft', 'Draft'),
  144. ('block', 'Blocked'),
  145. ('done', 'Done'),
  146. ('waiting', 'Waiting'),
  147. ('transfer', 'Transfer'),
  148. ('cancelled', 'Cancelled'),
  149. ('paid', 'paid')],
  150. string='State', required=True, default="draft")
  151. email = fields.Char(string='Email',
  152. required=True,
  153. readonly=True,
  154. states={'draft': [('readonly', False)]})
  155. iban = fields.Char(string='Account Number',
  156. readonly=True,
  157. states={'draft': [('readonly', False)]})
  158. partner_id = fields.Many2one('res.partner',
  159. string='Cooperator',
  160. readonly=True,
  161. states={'draft': [('readonly', False)]})
  162. share_product_id = fields.Many2one('product.product',
  163. string='Share type',
  164. domain=[('is_share', '=', True)],
  165. required=True,
  166. readonly=True,
  167. states={'draft': [('readonly', False)]})
  168. share_short_name = fields.Char(related='share_product_id.short_name',
  169. string='Share type name',
  170. readonly=True,
  171. states={'draft': [('readonly', False)]})
  172. share_unit_price = fields.Float(related='share_product_id.list_price',
  173. string='Share price',
  174. readonly=True,
  175. states={'draft': [('readonly', False)]})
  176. subscription_amount = fields.Float(compute='_compute_subscription_amount',
  177. string='Subscription amount',
  178. readonly=True,
  179. states={'draft': [('readonly', False)]})
  180. ordered_parts = fields.Integer(string='Number of Share',
  181. required=True,
  182. readonly=True,
  183. default=1,
  184. states={'draft': [('readonly', False)]})
  185. address = fields.Char(string='Address',
  186. required=True,
  187. readonly=True,
  188. states={'draft': [('readonly', False)]})
  189. city = fields.Char(string='City',
  190. required=True,
  191. readonly=True,
  192. states={'draft': [('readonly', False)]})
  193. zip_code = fields.Char(string='Zip Code',
  194. required=True,
  195. readonly=True,
  196. states={'draft': [('readonly', False)]})
  197. country_id = fields.Many2one('res.country',
  198. string='Country',
  199. ondelete='restrict',
  200. required=True,
  201. readonly=True,
  202. states={'draft': [('readonly', False)]})
  203. phone = fields.Char(string='Phone',
  204. readonly=True,
  205. states={'draft': [('readonly', False)]})
  206. user_id = fields.Many2one('res.users',
  207. string='Responsible',
  208. readonly=True)
  209. validated = fields.Boolean(compute='_validated_lines',
  210. string='Valid Line?',
  211. readonly=True)
  212. skip_control_ng = fields.Boolean(string="Skip control",
  213. help="if this field is checked then no"
  214. " control will be done on the national"
  215. " register number and on the iban bank"
  216. " account. To be done in case of the id"
  217. " card is from abroad or in case of"
  218. " a passport")
  219. lang = fields.Selection(_lang_get,
  220. string='Language',
  221. required=True,
  222. readonly=True,
  223. states={'draft': [('readonly', False)]},
  224. default=lambda self: self.env['res.company']._company_default_get().default_lang_id.code)
  225. date = fields.Date(string='Subscription date request',
  226. required=True,
  227. readonly=True,
  228. states={'draft': [('readonly', False)]},
  229. default=lambda self: datetime.strftime(datetime.now(),
  230. '%Y-%m-%d'))
  231. company_id = fields.Many2one('res.company',
  232. string='Company',
  233. required=True,
  234. change_default=True,
  235. readonly=True,
  236. default=lambda self: self.env['res.company']._company_default_get())
  237. is_company = fields.Boolean(string='Is a company',
  238. readonly=True,
  239. states={'draft': [('readonly', False)]})
  240. is_operation = fields.Boolean(string='Is an operation',
  241. readonly=True,
  242. states={'draft': [('readonly', False)]})
  243. company_name = fields.Char(string="Company name",
  244. readonly=True,
  245. states={'draft': [('readonly', False)]})
  246. company_email = fields.Char(string="Company email",
  247. readonly=True,
  248. states={'draft': [('readonly', False)]})
  249. company_register_number = fields.Char(string='Company register number',
  250. readonly=True,
  251. states={'draft': [('readonly', False)]})
  252. company_type = fields.Selection([('', '')],
  253. string="Company type",
  254. readonly=True,
  255. states={'draft': [('readonly', False)]})
  256. same_address = fields.Boolean(string='Same address',
  257. readonly=True,
  258. states={'draft': [('readonly', False)]})
  259. activities_address = fields.Char(string='Activities address',
  260. readonly=True,
  261. states={'draft': [('readonly', False)]})
  262. activities_city = fields.Char(string='Activities city',
  263. readonly=True,
  264. states={'draft': [('readonly', False)]})
  265. activities_zip_code = fields.Char(string='Activities zip Code',
  266. readonly=True,
  267. states={'draft': [('readonly', False)]})
  268. activities_country_id = fields.Many2one('res.country',
  269. string='Activities country',
  270. ondelete='restrict',
  271. readonly=True,
  272. states={'draft': [('readonly', False)]})
  273. contact_person_function = fields.Char(string='Function',
  274. readonly=True,
  275. states={'draft': [('readonly', False)]})
  276. operation_request_id = fields.Many2one('operation.request',
  277. string="Operation Request",
  278. readonly=True,
  279. states={'draft': [('readonly', False)]})
  280. capital_release_request = fields.One2many('account.invoice',
  281. 'subscription_request',
  282. string='Capital release request',
  283. readonly=True,
  284. states={'draft': [('readonly', False)]})
  285. capital_release_request_date = fields.Date(string="Force the capital "
  286. "release request date",
  287. help="Keep empty to use the "
  288. "current date",
  289. copy=False,
  290. readonly=True,
  291. states={'draft': [('readonly', False)]})
  292. source = fields.Selection([('website', 'Website'),
  293. ('crm', 'CRM'),
  294. ('manual', 'Manual'),
  295. ('operation', 'Operation')],
  296. string="Source",
  297. default="website",
  298. readonly=True,
  299. states={'draft': [('readonly', False)]})
  300. data_policy_approved = fields.Boolean(
  301. string='Data Policy Approved',
  302. default=False,
  303. )
  304. internal_rules_approved = fields.Boolean(
  305. string='Approved Internal Rules',
  306. default=False,
  307. )
  308. _order = "id desc"
  309. def get_person_info(self, partner):
  310. self.firstname = partner.firstname
  311. self.name = partner.name
  312. self.lastname = partner.lastname
  313. self.email = partner.email
  314. self.birthdate = partner.birthdate_date
  315. self.gender = partner.gender
  316. self.address = partner.street
  317. self.city = partner.city
  318. self.zip_code = partner.zip
  319. self.country_id = partner.country_id
  320. self.phone = partner.phone
  321. self.lang = partner.lang
  322. @api.onchange('partner_id')
  323. def onchange_partner(self):
  324. partner = self.partner_id
  325. if partner:
  326. self.is_company = partner.is_company
  327. self.already_cooperator = partner.member
  328. if partner.bank_ids:
  329. self.iban = partner.bank_ids[0].acc_number
  330. if partner.member:
  331. self.type = 'increase'
  332. if partner.is_company:
  333. self.company_name = partner.name
  334. self.company_email = partner.email
  335. self.company_register_number = partner.company_register_number
  336. representative = partner.get_representative()
  337. self.get_person_info(representative)
  338. self.contact_person_function = representative.function
  339. else:
  340. self.get_person_info(partner)
  341. # declare this function in order to be overriden
  342. def get_eater_vals(self, partner, share_product_id): #noqa
  343. return {}
  344. def _prepare_invoice_line(self, product, partner, qty):
  345. self.ensure_one()
  346. account = product.property_account_income_id \
  347. or product.categ_id.property_account_income_categ_id
  348. if not account:
  349. raise UserError(_('Please define income account for this product:'
  350. ' "%s" (id:%d) - or for its category: "%s".') %
  351. (product.name, product.id, product.categ_id.name))
  352. fpos = partner.property_account_position_id
  353. if fpos:
  354. account = fpos.map_account(account)
  355. res = {
  356. 'name': product.name,
  357. 'account_id': account.id,
  358. 'price_unit': product.lst_price,
  359. 'quantity': qty,
  360. 'uom_id': product.uom_id.id,
  361. 'product_id': product.id or False,
  362. }
  363. return res
  364. def send_capital_release_request(self, invoice):
  365. template = 'easy_my_coop.email_template_release_capital'
  366. email_template = self.env.ref(template, False)
  367. # we send the email with the capital release request in attachment
  368. # TODO remove sudo() and give necessary access right
  369. email_template.sudo().send_mail(invoice.id, True)
  370. invoice.sent = True
  371. def get_journal(self):
  372. return self.env['account.journal'].search([('code', '=', 'SUBJ')])[0]
  373. def get_accounting_account(self):
  374. account_obj = self.env['account.account']
  375. if self.company_id.property_cooperator_account:
  376. account = self.company_id.property_cooperator_account
  377. else:
  378. accounts = account_obj.search([('code', '=', '416000')])
  379. if accounts:
  380. account = accounts[0]
  381. else:
  382. raise UserError(_(
  383. 'You must set a cooperator account on you company.'
  384. ))
  385. return account
  386. def get_invoice_vals(self, partner):
  387. return {
  388. 'partner_id': partner.id,
  389. 'journal_id': self.get_journal().id,
  390. 'account_id': self.get_accounting_account().id,
  391. 'type': 'out_invoice',
  392. 'release_capital_request': True,
  393. 'subscription_request': self.id
  394. }
  395. def create_invoice(self, partner):
  396. # creating invoice and invoice lines
  397. invoice_vals = self.get_invoice_vals(partner)
  398. if self.capital_release_request_date:
  399. invoice_vals['date_invoice'] = self.capital_release_request_date
  400. invoice = self.env['account.invoice'].create(invoice_vals)
  401. vals = self._prepare_invoice_line(self.share_product_id, partner,
  402. self.ordered_parts)
  403. vals['invoice_id'] = invoice.id
  404. self.env['account.invoice.line'].create(vals)
  405. # validate the capital release request
  406. invoice.action_invoice_open()
  407. self.send_capital_release_request(invoice)
  408. return invoice
  409. def get_partner_company_vals(self):
  410. partner_vals = {'name': self.company_name,
  411. 'last_name': self.company_name,
  412. 'is_company': self.is_company,
  413. 'company_register_number': self.company_register_number, #noqa
  414. 'customer': False, 'cooperator': True,
  415. 'street': self.address, 'zip': self.zip_code,
  416. 'city': self.city, 'email': self.company_email,
  417. 'out_inv_comm_type': 'bba',
  418. 'customer': self.share_product_id.customer,
  419. 'country_id': self.country_id.id,
  420. 'lang': self.lang,
  421. 'data_policy_approved': self.data_policy_approved,
  422. 'internal_rules_approved': self.internal_rules_approved
  423. }
  424. return partner_vals
  425. def get_partner_vals(self):
  426. partner_vals = {'name': self.name, 'firstname': self.firstname,
  427. 'lastname': self.lastname, 'street': self.address,
  428. 'zip': self.zip_code, 'email': self.email,
  429. 'gender': self.gender, 'cooperator': True,
  430. 'city': self.city, 'phone': self.phone,
  431. 'country_id': self.country_id.id, 'lang': self.lang,
  432. 'birthdate_date': self.birthdate,
  433. 'customer': self.share_product_id.customer,
  434. 'data_policy_approved': self.data_policy_approved,
  435. 'internal_rules_approved': self.internal_rules_approved
  436. }
  437. return partner_vals
  438. def get_representative_vals(self):
  439. contact_vals = {
  440. 'name': self.name,
  441. 'firstname': self.firstname,
  442. 'lastname': self.lastname, 'customer': False,
  443. 'is_company': False, 'cooperator': True,
  444. 'street': self.address, 'gender': self.gender,
  445. 'zip': self.zip_code, 'city': self.city,
  446. 'phone': self.phone, 'email': self.email,
  447. 'country_id': self.country_id.id,
  448. 'out_inv_comm_type': 'bba',
  449. 'out_inv_comm_algorithm': 'random',
  450. 'lang': self.lang,
  451. 'birthdate_date': self.birthdate,
  452. 'parent_id': self.partner.id,
  453. 'representative': True,
  454. 'function': self.contact_person_function,
  455. 'type': 'representative',
  456. 'data_policy_approved': self.data_policy_approved,
  457. 'internal_rules_approved': self.internal_rules_approved
  458. }
  459. return contact_vals
  460. def create_coop_partner(self):
  461. partner_obj = self.env['res.partner']
  462. if self.is_company:
  463. partner_vals = self.get_partner_company_vals()
  464. else:
  465. partner_vals = self.get_partner_vals()
  466. partner = partner_obj.create(partner_vals)
  467. if self.iban:
  468. self.env['res.partner.bank'].create({
  469. 'partner_id': partner.id,
  470. 'acc_number': self.iban
  471. })
  472. return partner
  473. def set_membership(self):
  474. # To be overridden
  475. return True
  476. @api.one
  477. def validate_subscription_request(self):
  478. partner_obj = self.env['res.partner']
  479. if self.ordered_parts <= 0:
  480. raise UserError(_('Number of share must be greater than 0.'))
  481. if self.partner_id:
  482. if not self.partner_id.cooperator:
  483. self.partner_id.cooperator = True
  484. partner = self.partner_id
  485. else:
  486. partner = None
  487. domain = []
  488. if self.already_cooperator:
  489. raise UserError(_('The checkbox already cooperator is'
  490. ' checked please select a cooperator.'))
  491. elif self.is_company and self.company_register_number:
  492. domain = [('company_register_number', '=', self.company_register_number)] #noqa
  493. elif not self.is_company and self.email:
  494. domain = [('email', '=', self.email)]
  495. if domain:
  496. partner = partner_obj.search(domain)
  497. if not partner:
  498. partner = self.create_coop_partner()
  499. else:
  500. partner = partner[0]
  501. if self.is_company and not partner.has_representative():
  502. contact = False
  503. if self.email:
  504. domain = [('email', '=', self.email)]
  505. contact = partner_obj.search(domain)
  506. if contact:
  507. contact.type = 'representative'
  508. if not contact:
  509. contact_vals = self.get_representative_vals()
  510. partner_obj.create(contact_vals)
  511. else:
  512. if len(contact) > 1:
  513. raise UserError(_('There is two different persons with the'
  514. ' same national register number. Please'
  515. ' proceed to a merge before to continue')
  516. )
  517. if contact.parent_id and contact.parent_id.id != partner.id:
  518. raise UserError(_('This contact person is already defined'
  519. ' for another company. Please select'
  520. ' another contact'))
  521. else:
  522. contact.write({'parent_id': partner.id,
  523. 'representative': True})
  524. invoice = self.create_invoice(partner)
  525. self.write({'partner_id': partner.id, 'state': 'done'})
  526. self.set_membership()
  527. return invoice
  528. @api.one
  529. def block_subscription_request(self):
  530. self.write({'state': 'block'})
  531. @api.one
  532. def unblock_subscription_request(self):
  533. self.write({'state': 'draft'})
  534. @api.one
  535. def cancel_subscription_request(self):
  536. self.write({'state': 'cancelled'})
  537. @api.one
  538. def put_on_waiting_list(self):
  539. self.write({'state': 'waiting'})
  540. class ShareLine(models.Model):
  541. _name = 'share.line'
  542. _description = "Share line"
  543. @api.multi
  544. def _compute_total_line(self):
  545. res = {}
  546. for line in self:
  547. line.total_amount_line = line.share_unit_price * line.share_number
  548. return res
  549. share_product_id = fields.Many2one('product.product',
  550. string='Share type',
  551. required=True,
  552. readonly=True)
  553. share_number = fields.Integer(string='Number of Share',
  554. required=True,
  555. readonly=True)
  556. share_short_name = fields.Char(related='share_product_id.short_name',
  557. string='Share type name',
  558. readonly=True)
  559. share_unit_price = fields.Float(string='Share price',
  560. readonly=True)
  561. effective_date = fields.Date(string='Effective Date',
  562. readonly=True)
  563. partner_id = fields.Many2one('res.partner',
  564. string='Cooperator',
  565. required=True,
  566. ondelete='cascade',
  567. readonly=True)
  568. total_amount_line = fields.Float(compute='_compute_total_line',
  569. string='Total amount line')
  570. class SubscriptionRegister(models.Model):
  571. _name = 'subscription.register'
  572. _description = "Subscription register"
  573. @api.multi
  574. def _compute_total_line(self):
  575. for line in self:
  576. line.total_amount_line = line.share_unit_price * line.quantity
  577. name = fields.Char(string='Number Operation',
  578. required=True,
  579. readonly=True)
  580. register_number_operation = fields.Integer(string='Register Number Operation',
  581. required=True,
  582. readonly=True)
  583. partner_id = fields.Many2one('res.partner',
  584. string='Cooperator',
  585. required=True,
  586. readonly=True)
  587. partner_id_to = fields.Many2one('res.partner',
  588. string='Transfered to',
  589. readonly=True)
  590. date = fields.Date(string='Subscription Date',
  591. required=True,
  592. readonly=True)
  593. quantity = fields.Integer(string='Number of share',
  594. readonly=True)
  595. share_unit_price = fields.Float(string='Share price',
  596. readonly=True)
  597. total_amount_line = fields.Float(compute='_compute_total_line',
  598. string='Total amount line')
  599. share_product_id = fields.Many2one('product.product',
  600. string='Share type',
  601. required=True,
  602. readonly=True,
  603. domain=[('is_share', '=', True)])
  604. share_short_name = fields.Char(related='share_product_id.short_name',
  605. string='Share type name',
  606. readonly=True)
  607. share_to_product_id = fields.Many2one('product.product',
  608. string='Share to type',
  609. readonly=True,
  610. domain=[('is_share', '=', True)])
  611. share_to_short_name = fields.Char(related='share_to_product_id.short_name',
  612. string='Share to type name',
  613. readonly=True)
  614. quantity_to = fields.Integer(string='Number of share to',
  615. readonly=True)
  616. share_to_unit_price = fields.Float(string='Share to price',
  617. readonly=True)
  618. type = fields.Selection([('subscription', 'Subscription'),
  619. ('transfer', 'Transfer'),
  620. ('sell_back', 'Sell Back'),
  621. ('convert', 'Conversion')],
  622. string='Operation Type', readonly=True)
  623. company_id = fields.Many2one('res.company', string='Company',
  624. required=True,
  625. change_default=True, readonly=True,
  626. default=lambda self: self.env['res.company']._company_default_get())
  627. user_id = fields.Many2one('res.users',
  628. string='Responsible',
  629. readonly=True,
  630. default=lambda self: self.env.user)
  631. _order = "register_number_operation asc"
  632. @api.model
  633. def read_group(self, domain, fields, groupby, offset=0, limit=None,
  634. orderby=False,
  635. lazy=True):
  636. if 'share_unit_price' in fields:
  637. fields.remove('share_unit_price')
  638. if 'register_number_operation' in fields:
  639. fields.remove('register_number_operation')
  640. res = super(SubscriptionRegister, self).read_group(domain, fields,
  641. groupby,
  642. offset=offset,
  643. limit=limit,
  644. orderby=orderby,
  645. lazy=lazy)
  646. if 'total_amount_line' in fields:
  647. for line in res:
  648. if '__domain' in line:
  649. lines = self.search(line['__domain'])
  650. inv_value = 0.0
  651. for line2 in lines:
  652. inv_value += line2.total_amount_line
  653. line['total_amount_line'] = inv_value
  654. return res