GoodERP
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

175 líneas
8.3KB

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