GoodERP
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

171 行
8.1KB

  1. from odoo import models, fields, api
  2. from datetime import datetime
  3. import pytz
  4. from lxml import etree
  5. class NonActiveReport(models.TransientModel):
  6. _name = 'non.active.report'
  7. _description = '库龄报表'
  8. warehouse_id = fields.Many2one('warehouse', string='仓库')
  9. goods_id = fields.Many2one('goods', string='商品')
  10. attribute_id = fields.Many2one('attribute', string='属性')
  11. first_stage_day_qty = fields.Float(string='第一阶段数量')
  12. second_stage_day_qty = fields.Float(string='第二阶段数量')
  13. third_stage_day_qty = fields.Float(string='第三阶段数量')
  14. four_stage_day_qty = fields.Float(string='第四阶段数量')
  15. subtotal = fields.Float('合计')
  16. latest_move_date = fields.Datetime('最后发货日期')
  17. latest_move_qty = fields.Float('最后发货数量')
  18. @api.model
  19. def get_view(self, view_id=None, view_type='form', **options):
  20. """
  21. 继承系统自带的 视图构造方法 fields_view_get 实现动态的修改 呆滞报表的表头 string动态
  22. :param view_id:
  23. :param toolbar:
  24. :param submenu:
  25. :return:
  26. """
  27. res = super().get_view(view_id, view_type, **options)
  28. if self._context.get('first_stage_day'):
  29. now_date = datetime.strftime(
  30. datetime.now(pytz.timezone("UTC")), '%Y-%m-%d')
  31. doc = etree.XML(res['arch'])
  32. for node in doc.xpath("//field[@name='first_stage_day_qty']"):
  33. node.set('string', u"0~%s天" %
  34. (self._context.get('first_stage_day')))
  35. for node in doc.xpath("//field[@name='second_stage_day_qty']"):
  36. node.set('string',
  37. u"%s天~%s天" % (self._context.get('first_stage_day'), self._context.get('second_stage_day')))
  38. for node in doc.xpath("//field[@name='third_stage_day_qty']"):
  39. node.set('string',
  40. u"%s天~%s天" % (self._context.get('second_stage_day'), self._context.get('third_stage_day')))
  41. for node in doc.xpath("//field[@name='four_stage_day_qty']"):
  42. node.set('string', u"大于%s天" %
  43. (self._context.get('third_stage_day')))
  44. res['arch'] = etree.tostring(doc)
  45. return res
  46. class NonActiveReportWizard(models.TransientModel):
  47. _name = 'non.active.report.wizard'
  48. _description = '库龄报表向导'
  49. warehouse_id = fields.Many2one('warehouse', string='仓库')
  50. first_stage_day = fields.Integer(string='第一阶段天数', required=True)
  51. second_stage_day = fields.Integer(string='第二阶段天数', required=True)
  52. third_stage_day = fields.Integer(string='第三阶段天数', required=True)
  53. company_id = fields.Many2one(
  54. 'res.company',
  55. string='公司',
  56. change_default=True,
  57. default=lambda self: self.env.company)
  58. def get_warehouse_goods_stage_data(self, warehouse_id, first_stage_day, second_stage_day, third_stage_day):
  59. """
  60. 用sql 找到 系统 在所输入的时间阶段的对应的商品的 数量
  61. :param warehouse_id: 仓库id
  62. :param first_stage_day: 第一阶段天数
  63. :param second_stage_day:第一阶段天数
  64. :param third_stage_day: 第三阶段天数
  65. :return: 返回list dict
  66. """
  67. if warehouse_id:
  68. wahouse_id_sql = "AND wh_dest.id =%s" % (warehouse_id.id)
  69. else:
  70. wahouse_id_sql = "AND 1=1"
  71. now_date = datetime.strftime(
  72. datetime.now(pytz.timezone("UTC")), '%Y-%m-%d')
  73. vals = {'now_date': now_date, 'first_stage_day': first_stage_day, 'wahouse_id_sql': wahouse_id_sql,
  74. 'second_stage_day': second_stage_day, 'third_stage_day': third_stage_day}
  75. self.env.cr.execute('''
  76. select
  77. stage_goods_date.warehouse_dest_id as warehouse_id,
  78. stage_goods_date.goods_id as goods_id,
  79. stage_goods_date.attribute_id as attribute_id,
  80. NULL as latest_move_date,
  81. NULL as latest_move_qty,
  82. COALESCE(sum(stage_goods_date.first_stage),0) as first_stage_day_qty,
  83. COALESCE(sum(stage_goods_date.second_stage),0) as second_stage_day_qty,
  84. COALESCE(sum(stage_goods_date.third_stage),0) as third_stage_day_qty,
  85. COALESCE(sum(stage_goods_date.four_stage),0) as four_stage_day_qty,
  86. sum(stage_goods_date.subtotal) as subtotal
  87. from (select
  88. CASE
  89. when ('%(now_date)s' -line.date<=%(first_stage_day)d) then
  90. sum(line.qty_remaining)
  91. end as first_stage,
  92. CASE
  93. when ('%(now_date)s'-line.date>%(first_stage_day)d and '%(now_date)s' -line.date<=%(second_stage_day)d) then
  94. sum(line.qty_remaining)
  95. end as second_stage,
  96. CASE
  97. when ('%(now_date)s' -line.date>%(second_stage_day)d AND '%(now_date)s'-line.date<=%(third_stage_day)d) then
  98. sum(line.qty_remaining)
  99. end as third_stage,
  100. CASE
  101. when ('%(now_date)s'-line.date > %(third_stage_day)d) then
  102. sum(line.qty_remaining)
  103. end as four_stage,
  104. line.goods_id as goods_id,
  105. line.attribute_id as attribute_id,
  106. line.warehouse_dest_id as warehouse_dest_id,
  107. sum(line.qty_remaining) as subtotal
  108. FROM wh_move_line line
  109. LEFT JOIN warehouse wh_dest ON line.warehouse_dest_id = wh_dest.id
  110. LEFT JOIN warehouse wh ON line.warehouse_id = wh.id
  111. where line.state = 'done'
  112. %(wahouse_id_sql)s
  113. AND wh_dest.type='stock'
  114. GROUP BY line.warehouse_dest_id,line.goods_id,line.attribute_id,line.date) as stage_goods_date
  115. GROUP BY stage_goods_date.warehouse_dest_id,stage_goods_date.goods_id,stage_goods_date.attribute_id
  116. ''' % vals)
  117. return self.env.cr.dictfetchall()
  118. def open_non_active_report(self):
  119. """
  120. :return:
  121. 返回生成好的 库龄报表 记录的list视图返回,让用户可以直接看到结果
  122. """
  123. data_vals_list = self.get_warehouse_goods_stage_data(self.warehouse_id, self.first_stage_day,
  124. self.second_stage_day, self.third_stage_day)
  125. non_active_id_list = []
  126. for vals in data_vals_list:
  127. if vals.get('subtotal', 0) != 0:
  128. # 更新最后发货日期和最后发货数量
  129. latest_move_line = self.env['wh.move.line'].search([
  130. ('state', '=', 'done'),
  131. ('goods_id', '=', vals.get('goods_id')),
  132. ('attribute_id', '=', vals.get('attribute_id')),
  133. ('warehouse_id.type', '=', 'stock'),
  134. ('warehouse_dest_id.type', '=', 'customer')], order='write_date DESC', limit=1)
  135. if latest_move_line:
  136. vals['latest_move_date'] = latest_move_line.write_date
  137. vals['latest_move_qty'] = latest_move_line.goods_qty
  138. active_row = self.env['non.active.report'].create(vals)
  139. non_active_id_list.append(active_row.id)
  140. view = self.env.ref('warehouse.non_active_report_list')
  141. return {
  142. 'name': '库龄报表',
  143. 'view_mode': 'list',
  144. 'views': [(view.id, 'list')],
  145. 'res_model': 'non.active.report',
  146. 'type': 'ir.actions.act_window',
  147. 'target': 'main',
  148. 'domain': [('id', 'in', non_active_id_list)],
  149. 'limit': 65535,
  150. 'context': {'first_stage_day': self.first_stage_day,
  151. 'second_stage_day': self.second_stage_day, 'third_stage_day': self.third_stage_day}
  152. }
上海开阖软件有限公司 沪ICP备12045867号-1