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.

401 lines
13 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. # Copyright (C) 2018 - TODAY, Pavlov Media
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import api, fields, models, _
  4. class Agreement(models.Model):
  5. _name = 'agreement'
  6. _inherit = ['mail.thread']
  7. def _default_stage_id(self):
  8. return self.env.ref('agreement.agreement_stage_new')
  9. # General
  10. name = fields.Char(
  11. string="Title",
  12. required=True
  13. )
  14. is_template = fields.Boolean(
  15. string="Is a Template?",
  16. default=False,
  17. copy=False,
  18. help="Make this agreement a template."
  19. )
  20. version = fields.Integer(
  21. string="Version",
  22. default=1,
  23. copy=False,
  24. help="The versions are used to keep track of document history and "
  25. "previous versions can be referenced."
  26. )
  27. revision = fields.Integer(
  28. string="Revision",
  29. default=0,
  30. copy=False,
  31. help="The revision will increase with every save event."
  32. )
  33. description = fields.Text(
  34. string="Description",
  35. track_visibility='onchange',
  36. help="Description of the agreement"
  37. )
  38. start_date = fields.Date(
  39. string="Start Date",
  40. track_visibility='onchange',
  41. help="When the agreement starts."
  42. )
  43. end_date = fields.Date(
  44. string="End Date",
  45. track_visibility='onchange',
  46. help="When the agreement ends."
  47. )
  48. color = fields.Integer()
  49. active = fields.Boolean(
  50. string="Active",
  51. default=True,
  52. help="If unchecked, it will allow you to hide the agreement without "
  53. "removing it."
  54. )
  55. company_signed_date = fields.Date(
  56. string="Signed on",
  57. track_visibility='onchange',
  58. help="Date the contract was signed by Company."
  59. )
  60. partner_signed_date = fields.Date(
  61. string="Signed on",
  62. track_visibility='onchange',
  63. help="Date the contract was signed by the Partner."
  64. )
  65. term = fields.Integer(
  66. string="Term (Months)",
  67. track_visibility='onchange',
  68. help="Number of months this agreement/contract is in effect with the "
  69. "partner."
  70. )
  71. expiration_notice = fields.Integer(
  72. string="Exp. Notice (Days)",
  73. track_visibility='onchange',
  74. help="Number of Days before expiration to be notified."
  75. )
  76. change_notice = fields.Integer(
  77. string="Change Notice (Days)",
  78. track_visibility='onchange',
  79. help="Number of Days to be notified before changes."
  80. )
  81. special_terms = fields.Text(
  82. string="Special Terms",
  83. track_visibility='onchange',
  84. help="Any terms that you have agreed to and want to track on the "
  85. "agreement/contract."
  86. )
  87. contract_value = fields.Monetary(
  88. compute='_compute_contract_value',
  89. string="Contract Value",
  90. help="Total value of the contract over ther entire term.",
  91. store=True
  92. )
  93. reference = fields.Char(
  94. string="Reference",
  95. required=True,
  96. default=lambda self: _('New'),
  97. track_visibility='onchange',
  98. help="ID used for internal contract tracking.")
  99. total_company_mrc = fields.Monetary(
  100. 'Company MRC',
  101. currency_field='currency_id',
  102. help="Total company monthly recurring costs."
  103. )
  104. total_customer_mrc = fields.Monetary(
  105. 'Customer MRC',
  106. currency_field='currency_id',
  107. help="Total custemer monthly recurring costs."
  108. )
  109. total_company_nrc = fields.Monetary(
  110. 'Company NRC',
  111. currency_field='currency_id',
  112. help="Total company non-recurring costs."
  113. )
  114. total_customer_nrc = fields.Monetary(
  115. 'Customer NRC',
  116. currency_field='currency_id',
  117. help="Total custemer non-monthly recurring costs."
  118. )
  119. increase_type_id = fields.Many2one(
  120. 'agreement.increasetype',
  121. string="Increase Type",
  122. track_visibility='onchange',
  123. help="The amount that certain rates may increase."
  124. )
  125. termination_requested = fields.Date(
  126. string="Termination Requested Date",
  127. track_visibility='onchange',
  128. help="Date that a request for termination was received."
  129. )
  130. termination_date = fields.Date(
  131. string="Termination Date",
  132. track_visibility='onchange',
  133. help="Date that the contract was terminated."
  134. )
  135. reviewed_date = fields.Date(
  136. string="Reviewed Date",
  137. track_visibility='onchange'
  138. )
  139. reviewed_user_id = fields.Many2one(
  140. 'res.users',
  141. string="Reviewed By",
  142. track_visibility='onchange'
  143. )
  144. approved_date = fields.Date(
  145. string="Approved Date",
  146. track_visibility='onchange'
  147. )
  148. approved_user_id = fields.Many2one(
  149. 'res.users',
  150. string="Approved By",
  151. track_visibility='onchange'
  152. )
  153. currency_id = fields.Many2one(
  154. 'res.currency',
  155. string='Currency'
  156. )
  157. partner_id = fields.Many2one(
  158. 'res.partner',
  159. string="Partmer",
  160. copy=True,
  161. help="The customer or vendor this agreement is related to."
  162. )
  163. company_partner_id = fields.Many2one(
  164. 'res.partner',
  165. string="Company",
  166. copy=True,
  167. default=lambda self: self.env.user.company_id.partner_id
  168. )
  169. partner_contact_id = fields.Many2one(
  170. 'res.partner',
  171. string="Partner Contact",
  172. copy=True,
  173. help="The primary partner contact (If Applicable)."
  174. )
  175. partner_contact_phone = fields.Char(
  176. related='partner_contact_id.phone',
  177. string="Phone"
  178. )
  179. partner_contact_email = fields.Char(
  180. related='partner_contact_id.email',
  181. string="Email"
  182. )
  183. company_contact_id = fields.Many2one(
  184. 'res.partner',
  185. string="Company Contact",
  186. copy=True,
  187. help="The primary contact in the company."
  188. )
  189. company_contact_phone = fields.Char(
  190. related='company_contact_id.phone',
  191. string="Phone"
  192. )
  193. company_contact_email = fields.Char(
  194. related='company_contact_id.email',
  195. string="Email"
  196. )
  197. agreement_type_id = fields.Many2one(
  198. 'agreement.type',
  199. string="Agreement Type",
  200. track_visibility='onchange',
  201. help="Select the type of agreement."
  202. )
  203. agreement_subtype_id = fields.Many2one(
  204. 'agreement.subtype',
  205. string="Agreement Sub-type",
  206. track_visibility='onchange',
  207. help="Select the sub-type of this agreement. Sub-Types are related to "
  208. "agreement types."
  209. )
  210. product_ids = fields.Many2many(
  211. 'product.template',
  212. string="Products & Services")
  213. sale_order_id = fields.Many2one(
  214. 'sale.order',
  215. string="Sales Order",
  216. track_visibility='onchange',
  217. copy=False,
  218. help="Select the Sales Order that this agreement is related to."
  219. )
  220. payment_term_id = fields.Many2one(
  221. 'account.payment.term',
  222. string="Payment Term",
  223. track_visibility='onchange',
  224. help="Terms of payments."
  225. )
  226. assigned_user_id = fields.Many2one(
  227. 'res.users',
  228. string="Assigned To",
  229. track_visibility='onchange',
  230. help="Select the user who manages this agreement."
  231. )
  232. company_signed_user_id = fields.Many2one(
  233. 'res.users',
  234. string="Signed By",
  235. track_visibility='onchange',
  236. help="The user at our company who authorized/signed the agreement or "
  237. "contract."
  238. )
  239. partner_signed_user_id = fields.Many2one(
  240. 'res.partner',
  241. string="Signed By",
  242. track_visibility='onchange',
  243. help="Contact on the account that signed the agreement/contract."
  244. )
  245. parent_agreement_id = fields.Many2one(
  246. 'agreement',
  247. string="Parent Agreement",
  248. help="Link this agreement to a parent agreement. For example if this "
  249. "agreement is an amendment to another agreement. This list will "
  250. "only show other agreements related to the same account."
  251. )
  252. renewal_type_id = fields.Many2one(
  253. 'agreement.renewaltype',
  254. string="Renewal Type",
  255. track_visibility='onchange',
  256. help="Describes what happens after the contract expires."
  257. )
  258. order_lines_services_ids = fields.One2many(
  259. related='sale_order_id.order_line',
  260. string="Service Order Lines",
  261. copy=False
  262. )
  263. sections_ids = fields.One2many(
  264. 'agreement.section',
  265. 'agreement_id',
  266. string="Sections",
  267. copy=True
  268. )
  269. clauses_ids = fields.One2many(
  270. 'agreement.clause',
  271. 'agreement_id',
  272. string="Clauses",
  273. copy=True
  274. )
  275. analytic_id = fields.Many2one('account.analytic.account',
  276. string='Analytic Account', index=True)
  277. analytic_line_ids = fields.One2many('account.analytic.line',
  278. 'agreement_id',
  279. string='Revenues and Costs',
  280. copy=False)
  281. previous_version_agreements_ids = fields.One2many(
  282. 'agreement',
  283. 'parent_agreement_id',
  284. string="Child Agreements",
  285. copy=False,
  286. domain=[('active', '=', False)]
  287. )
  288. child_agreements_ids = fields.One2many(
  289. 'agreement',
  290. 'parent_agreement_id',
  291. string="Child Agreements",
  292. copy=False,
  293. domain=[('active', '=', True)]
  294. )
  295. products_ids = fields.Many2many(
  296. 'product.template',
  297. string="Products",
  298. copy=False
  299. )
  300. state = fields.Selection([
  301. ('draft', 'Draft'),
  302. ('active', 'Active'),
  303. ('inactive', 'Inactive')],
  304. default='draft',
  305. track_visibility='always'
  306. )
  307. notification_address_id = fields.Many2one(
  308. 'res.partner',
  309. string="Notification Address",
  310. help="The address to send notificaitons to, if different from "
  311. "customer address.(Address Type = Other)"
  312. )
  313. signed_contract_filename = fields.Char(
  314. string="Filename"
  315. )
  316. signed_contract = fields.Binary(
  317. string="Signed Document",
  318. track_visibility='always'
  319. )
  320. # compute contract_value field
  321. @api.depends('total_customer_mrc', 'total_customer_nrc', 'term')
  322. def _compute_contract_value(self):
  323. for record in self:
  324. record.contract_value =\
  325. (record.total_customer_mrc * record.term) +\
  326. record.total_customer_nrc
  327. # compute total_company_mrc field
  328. @api.depends('order_lines_services_ids', 'sale_order_id')
  329. def _compute_company_mrc(self):
  330. order_lines = self.env['sale.order.line'].search(
  331. [('is_service', '=', True)])
  332. amount_total = sum(order_lines.mapped('purchase_price'))
  333. for record in self:
  334. record.total_company_mrc = amount_total
  335. # Used for Kanban grouped_by view
  336. @api.model
  337. def _read_group_stage_ids(self, stages, domain, order):
  338. stage_ids = self.env['agreement.stage'].search([])
  339. return stage_ids
  340. stage_id = fields.Many2one(
  341. 'agreement.stage',
  342. string="Stage",
  343. group_expand='_read_group_stage_ids',
  344. help="Select the current stage of the agreement.",
  345. track_visibility='onchange',
  346. index=True,
  347. default=lambda self: self._default_stage_id(),
  348. )
  349. # Create New Version Button
  350. @api.multi
  351. def create_new_version(self, vals):
  352. for rec in self:
  353. if not rec.state == 'draft':
  354. # Make sure status is draft
  355. rec.state = 'draft'
  356. default_vals = {'name': '{0} - OLD VERSION'.format(rec.name),
  357. 'active': False,
  358. 'parent_agreement_id': rec.id}
  359. # Make a current copy and mark it as old
  360. rec.copy(default=default_vals)
  361. # Increment the Version
  362. rec.version = rec.version + 1
  363. # Reset revision to 0 since it's a new version
  364. vals['revision'] = 0
  365. return super(Agreement, self).write(vals)
  366. def create_new_agreement(self):
  367. default_vals = {'name': 'NEW',
  368. 'active': True,
  369. 'version': 1,
  370. 'revision': 0,
  371. 'state': 'draft'}
  372. res = self.copy(default=default_vals)
  373. return {'res_model': 'agreement',
  374. 'type': 'ir.actions.act_window',
  375. 'view_mode': 'form',
  376. 'view_type': 'form',
  377. 'res_id': res.id}
  378. @api.model
  379. def create(self, vals):
  380. if vals.get('reference', _('New')) == _('New'):
  381. vals['reference'] = \
  382. self.env['ir.sequence'].next_by_code('agreement') or _('New')
  383. return super(Agreement, self).create(vals)
  384. # Increments the revision on each save action
  385. @api.multi
  386. def write(self, vals):
  387. vals['revision'] = self.revision + 1
  388. return super(Agreement, self).write(vals)