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.

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