gooderp18绿色标准版
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

244 linhas
8.2KB

  1. from odoo import api, fields, models
  2. # 状态可选值
  3. LEAD_STATES = [
  4. ('todo', '新建'),
  5. ('doing', '正在进行'),
  6. ('done', '已完成'),
  7. ('cancel', '无效'),
  8. ]
  9. class Lead(models.Model):
  10. _name = 'lead'
  11. _description = '线索'
  12. user_id = fields.Many2one('res.users', '指派给', help='线索指派给业务员', default=lambda self: self.env.user)
  13. name = fields.Char('名称', required=True)
  14. note = fields.Text('描述')
  15. country = fields.Many2one('country', '国家/地区',
  16. ondelete='restrict')
  17. customer_name = fields.Char('客户公司名称')
  18. contact = fields.Char('联系人信息')
  19. state = fields.Selection(LEAD_STATES, '状态', default='todo')
  20. channel_id = fields.Many2one('core.value', '渠道',
  21. ondelete='restrict',
  22. domain=[('type', '=', 'channel')])
  23. source = fields.Char('来源')
  24. track_date = fields.Date('跟进日期')
  25. track_result = fields.Text('跟进结果')
  26. def new_opp(self):
  27. """创建商机"""
  28. return {
  29. 'name': "创建商机",
  30. 'res_model': 'opportunity',
  31. 'type': 'ir.actions.act_window',
  32. 'view_mode': 'form',
  33. 'context': {'default_name': self.name,
  34. 'default_lead_id': self.id,
  35. 'default_note': '%s %s %s' % (self.customer_name,
  36. self.contact,
  37. self.note)}
  38. }
  39. def set_cancel(self):
  40. """线索无效"""
  41. for lead in self:
  42. lead.write({'state': 'cancel'})
  43. return
  44. class Opportunity(models.Model):
  45. _name = 'opportunity'
  46. _inherits = {'task': 'task_id'}
  47. _inherit = ['mail.thread']
  48. _order = 'planned_revenue desc, priority desc, id'
  49. _description = '商机'
  50. @api.model
  51. def _select_objects(self):
  52. records = self.env['opportunity'].search([])
  53. models = self.env['ir.model'].sudo().search(
  54. [('model', 'in', [record.name for record in records])])
  55. return [(model.model, model.name) for model in models]
  56. @api.depends('line_ids.price', 'line_ids.quantity')
  57. def _compute_total_amount(self):
  58. """
  59. 计算报价总额
  60. :return:
  61. """
  62. for s in self:
  63. s.total_amount = sum(
  64. line.price * line.quantity for line in s.line_ids)
  65. # @api.model
  66. # def _read_group_status_ids(self):
  67. # """看板或列表视图上分组时显示所有阶段(即使该阶段没有记录)"""
  68. # status_ids = self.env['task.status'].search([('project_type_id', '=', False)])
  69. # return status_ids
  70. @api.model
  71. def _default_status(self):
  72. """创建商机时,阶段默认为todo状态的阶段,即 新建"""
  73. return self.task_id._default_status()
  74. task_id = fields.Many2one('task',
  75. '任务',
  76. ondelete='cascade',
  77. required=True)
  78. planned_revenue = fields.Float('预期收益', tracking=True)
  79. ref = fields.Reference(string='相关记录',
  80. selection='_select_objects')
  81. company_id = fields.Many2one(
  82. 'res.company',
  83. string='公司',
  84. change_default=True,
  85. default=lambda self: self.env.company)
  86. partner_id = fields.Many2one(
  87. 'partner',
  88. '客户',
  89. ondelete='restrict',
  90. help='待签约合同的客户',
  91. )
  92. date = fields.Date('预计采购时间', tracking=True)
  93. line_ids = fields.One2many(
  94. 'goods.quotation',
  95. 'opportunity_id',
  96. string='商品报价',
  97. copy=True,
  98. )
  99. total_amount = fields.Float(
  100. '报价总额',
  101. tracking=True,
  102. compute='_compute_total_amount',
  103. )
  104. success_reason_id = fields.Many2one(
  105. 'core.value',
  106. '成败原因',
  107. ondelete='restrict',
  108. domain=[('type', '=', 'success_reason')],
  109. context={'type': 'success_reason'},
  110. help='成败原因分析',
  111. )
  112. lead_id = fields.Many2one('lead', '线索')
  113. channel_id = fields.Many2one('core.value', related='lead_id.channel_id')
  114. source = fields.Char('来源', related='lead_id.source')
  115. status = fields.Many2one(
  116. 'task.status',
  117. string='状态',
  118. # group_expand='_read_group_status_ids',
  119. default=_default_status,
  120. tracking=True,
  121. ondelete='restrict',
  122. domain="[('project_type_id', '=', False)]",
  123. )
  124. def assign_to_me(self):
  125. """继承任务 指派给自己,将商机指派给自己,并修改状态"""
  126. for o in self:
  127. o.task_id.assign_to_me()
  128. def write(self, vals):
  129. if vals.get('status'):
  130. for s in self:
  131. s.lead_id.state = s.status.state
  132. return super().write(vals)
  133. @api.model_create_multi
  134. def create(self, vals_list):
  135. ret = super().create(vals_list)
  136. for s in ret:
  137. s.lead_id.state = 'doing'
  138. return ret
  139. def action_create_sell_order(self):
  140. line_ids = []
  141. for line in self.line_ids:
  142. newline = {'goods_id': line.goods_id.id, 'quantity': line.quantity, 'price_taxed': line.price}
  143. line_ids.append((0, 0, newline))
  144. date = fields.Date.context_today(self)
  145. res = self.env['sell.order'].create({
  146. 'opportunity_id': self.id,
  147. 'partner_id': self.partner_id.id,
  148. 'date': date,
  149. 'delivery_date': date,
  150. 'warehouse_id': self.env['warehouse'].search([('type', '=', 'stock')], order='id', limit=1).id,
  151. 'type': 'sell',
  152. 'line_ids': line_ids
  153. })
  154. self.status = self.env['task.status'].search([('state', '=', 'done')])
  155. action = {
  156. "type": "ir.actions.act_window",
  157. "view_mode": "form",
  158. "res_model": "sell.order",
  159. "res_id": res.id
  160. }
  161. return action
  162. class SellOrder(models.Model):
  163. _inherit = 'sell.order'
  164. opportunity_id = fields.Many2one('opportunity',
  165. ondelete='restrict',
  166. string='商机',
  167. domain="[('partner_id', '=', partner_id)]")
  168. class GoodsQuotation(models.Model):
  169. _name = 'goods.quotation'
  170. _description = '商品报价'
  171. opportunity_id = fields.Many2one('opportunity',
  172. '商机',
  173. index=True,
  174. required=True,
  175. ondelete='cascade',
  176. help='关联的商机')
  177. goods_id = fields.Many2one('goods',
  178. '商品',
  179. ondelete='restrict',
  180. help='商品')
  181. quantity = fields.Float('数量',
  182. default=1,
  183. digits='Quantity',
  184. help='数量')
  185. price = fields.Float('单价',
  186. required=True,
  187. digits='价格',
  188. help='商品报价')
  189. note = fields.Char('描述',
  190. help='商品描述')
  191. class Timeline(models.Model):
  192. _inherit = 'timeline'
  193. @api.model_create_multi
  194. def create(self, vals_list):
  195. """创建工作记录时,更新对应task的status等字段"""
  196. res = super(Timeline, self).create(vals_list)
  197. for vals in vals_list:
  198. set_status = vals.get('set_status')
  199. task_id = vals.get('task_id')
  200. next_action = vals.get('next_action')
  201. next_datetime = vals.get('next_datetime')
  202. user_id = vals.get('user_id')
  203. task = self.with_user(2).env['opportunity'].search([('task_id', '=', task_id)])
  204. if set_status:
  205. task.write({'status': set_status})
  206. if next_action:
  207. task.write({'next_action': next_action})
  208. if next_datetime:
  209. task.write({'next_datetime': next_datetime})
  210. if user_id:
  211. task.write({'user_id': user_id})
  212. return res
上海开阖软件有限公司 沪ICP备12045867号-1