gooderp18绿色标准版
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

241 lines
8.0KB

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