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.

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