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.

283 lines
14 KiB

  1. # -*- coding: utf-8 -*-
  2. from datetime import datetime
  3. from openerp import api, fields, models, _
  4. from openerp.exceptions import ValidationError
  5. class operation_request(models.Model):
  6. _name = 'operation.request'
  7. def get_date_now(self):
  8. return datetime.strftime(datetime.now(), '%Y-%m-%d')
  9. @api.multi
  10. @api.depends('share_product_id', 'share_product_id.list_price', 'quantity')
  11. def _compute_subscription_amount(self):
  12. for operation_request in self:
  13. operation_request.subscription_amount = operation_request.share_product_id.list_price * operation_request.quantity
  14. request_date = fields.Date(string='Request date',
  15. default=lambda self: self.get_date_now())
  16. partner_id = fields.Many2one('res.partner',
  17. string='Cooperator',
  18. domain=[('member', '=', True)],
  19. required=True)
  20. partner_id_to = fields.Many2one('res.partner',
  21. string='Transfered to',
  22. domain=[('cooperator', '=', True)])
  23. operation_type = fields.Selection([('subscription', 'Subscription'),
  24. ('transfer', 'Transfer'),
  25. ('sell_back', 'Sell Back'),
  26. ('convert', 'Conversion')],
  27. string='Operation Type',
  28. required=True)
  29. share_product_id = fields.Many2one('product.product',
  30. string='Share type',
  31. domain=[('is_share', '=', True)],
  32. required=True)
  33. share_to_product_id = fields.Many2one('product.product',
  34. string='Convert to this share type',
  35. domain=[('is_share', '=', True)])
  36. share_short_name = fields.Char(related='share_product_id.short_name',
  37. string='Share type name')
  38. share_to_short_name = fields.Char(related='share_to_product_id.short_name',
  39. string='Share to type name')
  40. share_unit_price = fields.Float(related='share_product_id.list_price',
  41. string='Share price')
  42. share_to_unit_price = fields.Float(related='share_to_product_id.list_price',
  43. string='Share to price')
  44. subscription_amount = fields.Float(compute='_compute_subscription_amount',
  45. string='Operation amount')
  46. quantity = fields.Integer(string='Number of share',
  47. required=True)
  48. state = fields.Selection([('draft', 'Draft'),
  49. ('waiting', 'Waiting'),
  50. ('approved', 'Approved'),
  51. ('done', 'Done'),
  52. ('cancelled', 'Cancelled'),
  53. ('refused', 'Refused')],
  54. string='State',
  55. required=True,
  56. default='draft')
  57. user_id = fields.Many2one('res.users',
  58. string='Responsible',
  59. readonly=True,
  60. default=lambda self: self.env.user)
  61. subscription_request = fields.One2many('subscription.request',
  62. 'operation_request_id',
  63. string="Share Receiver Info",
  64. help="In case on a transfer of"
  65. " share. If the share receiver"
  66. " isn't a effective member then a"
  67. " subscription form should"
  68. " be filled.")
  69. receiver_not_member = fields.Boolean(string='Receiver is not a member')
  70. company_id = fields.Many2one('res.company',
  71. string='Company',
  72. required=True,
  73. change_default=True,
  74. readonly=True,
  75. default=lambda self: self.env['res.company']._company_default_get())
  76. invoice = fields.Many2one('account.invoice',
  77. string="Invoice")
  78. @api.multi
  79. def approve_operation(self):
  80. for rec in self:
  81. rec.write({'state': 'approved'})
  82. @api.multi
  83. def refuse_operation(self):
  84. for rec in self:
  85. rec.write({'state': 'refused'})
  86. @api.multi
  87. def submit_operation(self):
  88. for rec in self:
  89. rec.validate()
  90. rec.write({'state': 'waiting'})
  91. @api.multi
  92. def cancel_operation(self):
  93. for rec in self:
  94. rec.write({'state': 'cancelled'})
  95. @api.multi
  96. def reset_to_draft(self):
  97. for rec in self:
  98. rec.write({'state': 'draft'})
  99. def get_total_share_dic(self, partner):
  100. total_share_dic = {}
  101. share_products = self.env['product.template'].search([('is_share', '=', True)])
  102. for share_product in share_products:
  103. total_share_dic[share_product.id] = 0
  104. for line in partner.share_ids:
  105. total_share_dic[line.share_product_id.id] += line.share_number
  106. return total_share_dic
  107. # This function doesn't handle the case of a cooperator can own
  108. # different kinds of share type
  109. def hand_share_over(self, partner, share_product_id, quantity):
  110. if not partner.member:
  111. raise ValidationError(_("This operation can't be executed if the cooperator is not an effective member"))
  112. share_ind = len(partner.share_ids)
  113. i = 1
  114. while quantity > 0:
  115. line = self.partner_id.share_ids[share_ind-i]
  116. if line.share_product_id.id == share_product_id.id:
  117. if quantity > line.share_number:
  118. quantity -= line.share_number
  119. line.unlink()
  120. else:
  121. share_left = line.share_number - quantity
  122. quantity = 0
  123. line.write({'share_number': share_left})
  124. i += 1
  125. # if the cooperator sold all his shares he's no more
  126. # an effective member
  127. remaning_share_dict = 0
  128. for share_quant in self.get_total_share_dic(partner).values():
  129. remaning_share_dict += share_quant
  130. if remaning_share_dict == 0:
  131. self.partner_id.write({'member': False, 'old_member': True})
  132. def has_share_type(self):
  133. for line in self.partner_id.share_ids:
  134. if line.share_product_id.id == self.share_product_id.id:
  135. return True
  136. return False
  137. def validate(self):
  138. if not self.has_share_type() and \
  139. self.operation_type in ['sell_back', 'transfer']:
  140. raise ValidationError(_("The cooperator doesn't own this share"
  141. " type. Please choose the appropriate"
  142. " share type."))
  143. if self.operation_type in ['sell_back', 'convert', 'transfer']:
  144. total_share_dic = self.get_total_share_dic(self.partner_id)
  145. if self.quantity > total_share_dic[self.share_product_id.id]:
  146. raise ValidationError(_("The cooperator can't hand over more"
  147. " shares that he/she owns."))
  148. if self.operation_type == 'convert' and \
  149. self.company_id.unmix_share_type:
  150. if self.share_product_id.code == self.share_to_product_id.code:
  151. raise ValidationError(_("You can't convert the share to"
  152. " the same share type."))
  153. if self.subscription_amount != self.partner_id.total_value:
  154. raise ValidationError(_("You must convert all the shares"
  155. " to the selected type."))
  156. elif self.operation_type == 'transfer':
  157. if not self.receiver_not_member and self.company_id.unmix_share_type \
  158. and (self.partner_id_to.cooperator_type
  159. and self.partner_id.cooperator_type != self.partner_id_to.cooperator_type):
  160. raise ValidationError(_("This share type could not be"
  161. " transfered to " +
  162. self.partner_id_to.name))
  163. @api.multi
  164. def execute_operation(self):
  165. self.ensure_one()
  166. effective_date = self.get_date_now()
  167. sub_request = self.env['subscription.request']
  168. for rec in self:
  169. rec.validate()
  170. if rec.state != 'approved':
  171. raise ValidationError(_("This operation must be approved"
  172. " before to be executed"))
  173. values = {
  174. 'partner_id': rec.partner_id.id, 'quantity': rec.quantity,
  175. 'share_product_id': rec.share_product_id.id, 'type': rec.operation_type,
  176. 'share_unit_price': rec.share_unit_price, 'date': effective_date,
  177. }
  178. if rec.operation_type == 'sell_back':
  179. self.hand_share_over(rec.partner_id, rec.share_product_id,
  180. rec.quantity)
  181. elif rec.operation_type == 'convert':
  182. amount_to_convert = rec.share_unit_price * rec.quantity
  183. convert_quant = int(amount_to_convert / rec.share_to_product_id.list_price)
  184. remainder = amount_to_convert % rec.share_to_product_id.list_price
  185. if rec.company_id.unmix_share_type:
  186. if convert_quant > 0 and remainder == 0:
  187. share_ids = rec.partner_id.share_ids
  188. line = share_ids[0]
  189. if len(share_ids) > 1:
  190. share_ids[1:len(share_ids)].unlink()
  191. line.write({
  192. 'share_number': convert_quant,
  193. 'share_product_id': rec.share_to_product_id.id,
  194. 'share_unit_price': rec.share_to_unit_price,
  195. 'share_short_name': rec.share_to_short_name
  196. })
  197. values['share_to_product_id'] = rec.share_to_product_id.id
  198. values['quantity_to'] = convert_quant
  199. else:
  200. raise ValidationError(_("Converting just part of the"
  201. " shares is not yet implemented"))
  202. elif rec.operation_type == 'transfer':
  203. if rec.receiver_not_member:
  204. partner = rec.subscription_request.create_coop_partner()
  205. # get cooperator number
  206. sequence_id = self.env.ref('easy_my_coop.sequence_subscription', False)
  207. sub_reg_num = sequence_id.next_by_id()
  208. partner_vals = sub_request.get_eater_vals(partner, rec.share_product_id)
  209. partner_vals['member'] = True
  210. partner_vals['cooperator_register_number'] = int(sub_reg_num)
  211. partner.write(partner_vals)
  212. rec.partner_id_to = partner
  213. else:
  214. if not rec.partner_id_to.member:
  215. partner_vals = sub_request.get_eater_vals(
  216. rec.partner_id_to,
  217. rec.share_product_id)
  218. partner_vals['member'] = True
  219. partner_vals['old_member'] = False
  220. rec.partner_id_to.write(partner_vals)
  221. # remove the parts to the giver
  222. self.hand_share_over(rec.partner_id,
  223. rec.share_product_id,
  224. rec.quantity)
  225. # give the share to the receiver
  226. self.env['share.line'].create({
  227. 'share_number': rec.quantity,
  228. 'partner_id': rec.partner_id_to.id,
  229. 'share_product_id': rec.share_product_id.id,
  230. 'share_unit_price': rec.share_unit_price,
  231. 'effective_date': effective_date})
  232. values['partner_id_to'] = rec.partner_id_to.id
  233. else:
  234. raise ValidationError(_("This operation is not yet"
  235. " implemented."))
  236. sequence_operation = self.env.ref('easy_my_coop.sequence_register_operation', False)
  237. sub_reg_operation = sequence_operation.next_by_id()
  238. values['name'] = sub_reg_operation
  239. values['register_number_operation'] = int(sub_reg_operation)
  240. rec.write({'state': 'done'})
  241. # send mail to the receiver
  242. if rec.operation_type == 'transfer':
  243. certificat_email_template = self.env.ref('easy_my_coop.email_template_share_transfer', False)
  244. certificat_email_template.send_mail(rec.partner_id_to.id, False)
  245. self.env['subscription.register'].create(values)
  246. certificat_email_template = self.env.ref('easy_my_coop.email_template_share_update', False)
  247. certificat_email_template.send_mail(rec.partner_id.id, False)