中国本土应用
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.

174 lines
6.0KB

  1. import calendar
  2. from datetime import datetime
  3. from odoo import api, fields, models
  4. from odoo.exceptions import UserError, ValidationError
  5. MONTH_SELECTION = [
  6. ('1', '01'),
  7. ('2', '02'),
  8. ('3', '03'),
  9. ('4', '04'),
  10. ('5', '05'),
  11. ('6', '06'),
  12. ('7', '07'),
  13. ('8', '08'),
  14. ('9', '09'),
  15. ('10', '10'),
  16. ('11', '11'),
  17. ('12', '12')]
  18. # 字段只读状态
  19. READONLY_STATES = {
  20. 'done': [('readonly', True)],
  21. 'cancel': [('readonly', True)],
  22. }
  23. class FinancePeriod(models.Model):
  24. '''会计期间'''
  25. _name = 'finance.period'
  26. _order = 'name desc'
  27. _description = '会计期间'
  28. name = fields.Char(
  29. '会计期间',
  30. compute='_compute_name', readonly=True, store=True)
  31. is_closed = fields.Boolean('已结账', help='这个字段用于标识期间是否已结账,已结账的期间不能生成会计凭证。')
  32. year = fields.Char('会计年度', required=True, help='会计期间对应的年份')
  33. month = fields.Selection(
  34. MONTH_SELECTION, string='会计月份', required=True, help='会计期间对应的月份')
  35. company_id = fields.Many2one(
  36. 'res.company',
  37. string='公司',
  38. change_default=True,
  39. default=lambda self: self.env.company)
  40. @api.depends('year', 'month')
  41. def _compute_name(self):
  42. """
  43. 根据填写的月份年份 设定期间的name值
  44. :return: None
  45. """
  46. for p in self:
  47. if p.year and p.month:
  48. p.name = '%s%s' % (p.year, str(p.month).zfill(2))
  49. def period_compare(self, period_id_one, period_id_two):
  50. """
  51. 比较期间的大小
  52. :param period_id_one: 要比较的期间 1
  53. :param period_id_two:要比较的期间 2
  54. :return: 1 0 -1 分别代表 期间1 大于 等于 小于 期间2
  55. """
  56. period_one_str = "%s-%s" % (period_id_one.year,
  57. str(period_id_one.month).zfill(2))
  58. period_two_str = "%s-%s" % (period_id_two.year,
  59. str(period_id_two.month).zfill(2))
  60. if period_one_str > period_two_str:
  61. return 1
  62. elif period_one_str < period_two_str:
  63. return -1
  64. else:
  65. return 0
  66. @api.model
  67. def init_period(self):
  68. ''' 根据系统启用日期(安装core模块的日期)创建 '''
  69. current_date = self.env.ref('base.main_company').start_date
  70. period_id = self.search([
  71. ('year', '=', current_date.year),
  72. ('month', '=', current_date.month)
  73. ])
  74. if not period_id:
  75. return self.create({'year': current_date.year,
  76. 'month': str(current_date.month)})
  77. @api.model
  78. def get_init_period(self):
  79. '''系统启用的期间'''
  80. start_date = self.env.ref('base.main_company').start_date
  81. period_id = self.search([
  82. ('year', '=', start_date.year),
  83. ('month', '=', start_date.month)
  84. ])
  85. return period_id
  86. def get_date_now_period_id(self):
  87. """
  88. 默认是当前会计期间
  89. :return: 当前会计期间的对象 如果不存在则返回 False
  90. """
  91. datetime_str = datetime.now().strftime("%Y-%m-%d")
  92. datetime_str_list = datetime_str.split('-')
  93. period_row = self.search(
  94. [('year', '=', datetime_str_list[0]), ('month', '=', str(int(datetime_str_list[1])))])
  95. return period_row and period_row[0]
  96. def get_period_month_date_range(self, period_id):
  97. """
  98. 取得 period_id 期间的第一天 和最后一天
  99. :param period_id: 要取得一个月 最后一天和第一天的期间
  100. :return: 返回一个月的第一天和最后一天 ('2016-01-01','2016-01-31')
  101. """
  102. month_day_range = calendar.monthrange(
  103. int(period_id.year), int(period_id.month))
  104. return ("%s-%s-01" % (period_id.year, str(period_id.month).zfill(2)), "%s-%s-%s" % (period_id.year, str(period_id.month).zfill(2), str(month_day_range[1])))
  105. def get_year_fist_period_id(self):
  106. """
  107. 获取本年创建过的第一个会计期间
  108. :return: 当前会计期间的对象 如果不存在则返回 False
  109. """
  110. datetime_str = datetime.now().strftime("%Y-%m-%d")
  111. datetime_str_list = datetime_str.split('-')
  112. period_row = self.search(
  113. [('year', '=', datetime_str_list[0])])
  114. period_list = sorted(map(int, [period.month for period in period_row]))
  115. if not period_row[0]:
  116. raise UserError('日期%s所在会计期间不存在!' % datetime_str)
  117. fist_period = self.search(
  118. [('year', '=', datetime_str_list[0]), ('month', '=', period_list[0])], order='name')
  119. return fist_period
  120. def get_period(self, date):
  121. """
  122. 根据参数date 得出对应的期间
  123. :param date: 需要取得期间的时间
  124. :return: 对应的期间
  125. """
  126. if date:
  127. period_id = self.search([
  128. ('year', '=', date.year),
  129. ('month', '=', date.month)
  130. ])
  131. if period_id:
  132. if period_id.is_closed and self._context.get('module_name', False) != 'checkout_wizard':
  133. raise UserError('会计期间%s已关闭' % period_id.name)
  134. else:
  135. # 会计期间不存在,创建会计期间
  136. period_id = self.create({'year': date.year, 'month': str(date.month)})
  137. return period_id
  138. def search_period(self, date):
  139. """
  140. 根据参数date 得出对应的期间
  141. :param date: 需要取得期间的时间
  142. :return: 对应的期间
  143. """
  144. if date:
  145. period_id = self.search([
  146. ('year', '=', date.year),
  147. ('month', '=', date.month)
  148. ])
  149. return period_id
  150. _sql_constraints = [
  151. ('period_uniq', 'unique (year,month)', '会计期间不能重复'),
  152. ]
上海开阖软件有限公司 沪ICP备12045867号-1