中国本土应用
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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