GoodERP
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

354 rindas
17KB

  1. from odoo import models, fields, api
  2. from datetime import datetime, timedelta
  3. class ReportStockReceiptDelivery(models.Model):
  4. _name = 'report.stock.receipt.delivery'
  5. _description = '商品收发汇总表'
  6. _inherit = 'report.base'
  7. goods_class = fields.Char('商品类别')
  8. code = fields.Char('商品编号')
  9. goods = fields.Char('商品名称')
  10. uom = fields.Char('单位')
  11. attribute = fields.Char('属性')
  12. id_lists = fields.Text('库存调拨id列表')
  13. warehouse = fields.Char('仓库')
  14. origin = fields.Char('业务类型')
  15. goods_qty_begin = fields.Float(
  16. '期初数量', digits='Quantity')
  17. cost_begin = fields.Float(
  18. '期初成本', digits='Amount')
  19. goods_qty_end = fields.Float(
  20. '期末数量', digits='Quantity')
  21. cost_end = fields.Float(
  22. '期末成本', digits='Amount')
  23. goods_qty_out = fields.Float(
  24. '出库数量', digits='Quantity')
  25. cost_out = fields.Float(
  26. '出库成本', digits='Amount')
  27. goods_qty_in = fields.Float(
  28. '入库数量', digits='Quantity')
  29. cost_in = fields.Float(
  30. '入库成本', digits='Amount')
  31. # 入库数据
  32. goods_buy_receipt = fields.Float(
  33. '采购入库', digits='Quantity')
  34. cost_buy_receipt = fields.Float(
  35. '采购成本', digits='Amount')
  36. goods_in_others = fields.Float(
  37. '其他入库', digits='Quantity')
  38. cost_in_others = fields.Float(
  39. '其他成本', digits='Amount')
  40. goods_in_inventory = fields.Float(
  41. '盘盈入库', digits='Quantity')
  42. cost_in_inventory = fields.Float(
  43. '盘盈成本', digits='Amount')
  44. goods_delivery_return = fields.Float(
  45. '销售退货', digits='Quantity')
  46. cost_delivery_return = fields.Float(
  47. '退货成本', digits='Amount')
  48. goods_assembly_in = fields.Float(
  49. '组装入库', digits='Quantity')
  50. cost_assembly_in = fields.Float(
  51. '组装入库成本', digits='Amount')
  52. goods_internal_in = fields.Float(
  53. '调拨入库', digits='Quantity')
  54. cost_internal_in = fields.Float(
  55. '调拨入库成本', digits='Amount')
  56. # 出库数据
  57. goods_delivery_sell = fields.Float(
  58. '销售出库', digits='Quantity')
  59. cost_delivery_sell = fields.Float(
  60. '出库成本', digits='Amount')
  61. goods_out_others = fields.Float(
  62. '其他出库', digits='Quantity')
  63. cost_out_others = fields.Float(
  64. '其他成本', digits='Amount')
  65. goods_out_inventory = fields.Float(
  66. '盘亏出库', digits='Quantity')
  67. cost_out_inventory = fields.Float(
  68. '盘亏成本', digits='Amount')
  69. goods_receipt_return = fields.Float(
  70. '采购退货', digits='Quantity')
  71. cost_receipt_return = fields.Float(
  72. '退货成本', digits='Amount')
  73. goods_assembly_out = fields.Float(
  74. '组装出库', digits='Quantity')
  75. cost_assembly_out = fields.Float(
  76. '组装出库成本', digits='Amount')
  77. goods_internal_out = fields.Float(
  78. '调拨出库', digits='Quantity')
  79. cost_internal_out = fields.Float(
  80. '调拨出库成本', digits='Amount')
  81. def select_sql_inherit(self, sql_type='out', sql_origin=''):
  82. return '''
  83. SELECT min(line.id) as id,
  84. goods.name as goods,
  85. gc.name as goods_class,
  86. goods.code as code,
  87. att.name as attribute,
  88. array_agg(line.id) as id_lists,
  89. uom.name as uom,
  90. wh.name as warehouse,
  91. case
  92. when wm.origin = 'buy.receipt.buy' then '采购入库'
  93. when wm.origin = 'wh.in.others' then '其他入库'
  94. when wm.origin = 'wh.in.inventory' then '盘盈'
  95. when wm.origin = 'sell.delivery.return' then '销售退货'
  96. when wm.origin = 'sell.delivery.sell' then '销售出库'
  97. when wm.origin = 'wh.out.others' then '其他出库'
  98. when wm.origin = 'wh.out.inventory' then '盘亏'
  99. when wm.origin = 'buy.receipt.return' then '采购退货'
  100. when wm.origin = 'wh.internal' then '%s'
  101. when wm.origin = 'wh.assembly' and line.type = 'out' then '组装单子件'
  102. when wm.origin = 'wh.assembly' and line.type = 'in' then '组装单组合件'
  103. when wm.origin = 'outsource' and line.type = 'out' then '委外单子件'
  104. when wm.origin = 'outsource' and line.type = 'in' then '委外单组合件'
  105. end as origin,
  106. att.name as attribute,
  107. array_agg(line.id order by line.id) as id_lists,
  108. wh.name as warehouse,
  109. sum(case when
  110. line.date < '{date_start}' THEN line.goods_qty ELSE 0 END)
  111. as goods_qty_begin,
  112. sum(case when
  113. line.date < '{date_start}' THEN line.cost ELSE 0 END)
  114. as cost_begin,
  115. sum(case when
  116. line.date <= '{date_end}' THEN line.goods_qty ELSE 0 END)
  117. as goods_qty_end,
  118. sum(case when
  119. line.date <= '{date_end}' THEN line.cost ELSE 0 END)
  120. as cost_end,
  121. sum(case when
  122. line.date <= '{date_end}' AND line.date >= '{date_start}'
  123. THEN
  124. line.goods_qty ELSE 0 END)
  125. as goods_qty,
  126. sum(case when
  127. line.date <= '{date_end}' AND line.date >= '{date_start}'
  128. THEN
  129. line.cost ELSE 0 END)
  130. as cost
  131. ''' % ('调拨出库' if sql_origin == 'internal_in' else '调拨入库')
  132. def from_sql_inherit(self, sql_type='out', sql_origin=''):
  133. return '''
  134. FROM wh_move_line line
  135. inner join wh_move wm on wm.id = line.move_id
  136. inner join goods goods ON line.goods_id = goods.id
  137. left join goods_class gc on gc.id = goods.goods_class_id
  138. LEFT JOIN attribute att ON line.attribute_id = att.id
  139. LEFT JOIN uom uom ON line.uom_id = uom.id
  140. LEFT JOIN warehouse wh ON line.%s = wh.id
  141. ''' % ((sql_type == 'out' or (sql_type == 'internal' and sql_origin == 'internal_in')) and 'warehouse_id'
  142. or 'warehouse_dest_id')
  143. def where_sql_inherit(self, sql_type='out', sql_origin=''):
  144. extra = ''
  145. if self.env.context.get('warehouse_id'):
  146. extra += 'AND wh.id = {warehouse_id}'
  147. if self.env.context.get('goods_id'):
  148. extra += 'AND goods.id = {goods_id}'
  149. return '''
  150. WHERE line.state = 'done'
  151. AND wh.type = 'stock'
  152. AND wh.active = true
  153. AND line.date <= '{date_end}'
  154. %s
  155. ''' % extra
  156. def group_sql_inherit(self, sql_type='out', sql_origin=''):
  157. return '''
  158. GROUP BY gc.name, goods.id, wm.origin, line.type, goods.code,
  159. att.name, uom.name, wh.name, line.warehouse_id, line.type
  160. '''
  161. def order_sql_inherit(self, sql_type='out', sql_origin=''):
  162. return '''
  163. ORDER BY goods.id, wh.name
  164. '''
  165. def get_context_inherit(self, sql_type='out', context=None):
  166. return {
  167. 'date_start': context.get('date_start') or '',
  168. 'date_end': context.get('date_end'),
  169. 'warehouse_id': context.get('warehouse_id') and context.get('warehouse_id')[0] or '',
  170. 'goods_id': context.get('goods_id') and context.get('goods_id')[0] or '',
  171. }
  172. def get_record_key(self, record, sql_type='out'):
  173. return (
  174. record.get('goods'),
  175. record.get('uom'),
  176. record.get('warehouse'),
  177. record.get('attribute'),
  178. record.get('code'),
  179. record.get('goods_class')
  180. )
  181. def unzip_record_key(self, key):
  182. return {
  183. 'goods': key[0],
  184. 'uom': key[1],
  185. 'warehouse': key[2],
  186. 'attribute': key[3],
  187. 'code': key[4],
  188. 'goods_class': key[5]
  189. }
  190. def get_default_value_by_record(self, record, sql_type='out', sql_origin=''):
  191. return {
  192. 'id': record.get('id'),
  193. }
  194. def update_record_value(self, value, record, sql_type='out', sql_origin=''):
  195. tag = sql_type == 'out' and -1 or 1
  196. value.update({
  197. # 调拨入库
  198. 'goods_internal_in': value.get('goods_internal_in', 0) + (
  199. sql_type == 'internal' and sql_origin == '调拨入库' and record.get('goods_qty', 0) or 0),
  200. 'cost_internal_in': value.get('cost_internal_in', 0) + (
  201. sql_type == 'internal' and sql_origin == '调拨入库' and record.get('cost', 0) or 0),
  202. # 调拨出库
  203. 'goods_internal_out': value.get('goods_internal_out', 0) + (
  204. sql_type == 'internal' and sql_origin == '调拨出库' and record.get('goods_qty', 0) or 0),
  205. 'cost_internal_out': value.get('cost_internal_out', 0) + (
  206. sql_type == 'internal' and sql_origin == '调拨出库' and record.get('cost', 0) or 0),
  207. # =============================期初数量=============================
  208. 'goods_qty_begin': value.get('goods_qty_begin', 0) + (
  209. sql_type != 'internal' and tag * record.get('goods_qty_begin', 0)),
  210. 'cost_begin': value.get('cost_begin', 0) + (
  211. sql_type != 'internal' and tag * record.get('cost_begin', 0)),
  212. 'goods_qty_end': value.get('goods_qty_end', 0) + (
  213. sql_type != 'internal' and tag * record.get('goods_qty_end', 0)),
  214. 'cost_end': value.get('cost_end', 0) + (
  215. sql_type != 'internal' and tag * record.get('cost_end', 0)),
  216. # =============================一批入库数据=============================
  217. # 采购入库
  218. 'goods_buy_receipt': value.get('goods_buy_receipt', 0) +
  219. (sql_type == 'in' and sql_origin == '采购入库' and record.get('goods_qty', 0) or 0),
  220. 'cost_buy_receipt': value.get('cost_buy_receipt', 0) +
  221. (sql_type == 'in' and sql_origin == '采购入库' and record.get('cost', 0) or 0),
  222. # 其他入库
  223. 'goods_in_others': value.get('goods_in_others', 0) +
  224. (sql_type == 'in' and sql_origin == '其他入库' and record.get('goods_qty', 0) or 0),
  225. 'cost_in_others': value.get('cost_in_others', 0) +
  226. (sql_type == 'in' and sql_origin == '其他入库' and record.get('cost', 0) or 0),
  227. # 盘盈入库
  228. 'goods_in_inventory': value.get('goods_in_inventory', 0) +
  229. (sql_type == 'in' and sql_origin == '盘盈' and record.get('goods_qty', 0) or 0),
  230. 'cost_in_inventory': value.get('cost_in_inventory', 0) +
  231. (sql_type == 'in' and sql_origin == '盘盈' and record.get('cost', 0) or 0),
  232. # 销售退货
  233. 'goods_delivery_return': value.get('goods_delivery_return', 0) +
  234. (sql_type == 'in' and sql_origin == '销售退货' and record.get('goods_qty', 0) or 0),
  235. 'cost_delivery_return': value.get('cost_delivery_return', 0) +
  236. (sql_type == 'in' and sql_origin == '销售退货' and record.get('cost', 0) or 0),
  237. # 组装单组合件(组装入库)
  238. 'goods_assembly_in': value.get('goods_assembly_in', 0) +
  239. (sql_type == 'in' and sql_origin == '组装单组合件' and record.get('goods_qty',
  240. 0) or 0),
  241. 'cost_assembly_in': value.get('cost_assembly_in', 0) +
  242. (sql_type == 'in' and sql_origin == '组装单组合件' and record.get('cost', 0) or 0),
  243. # =============================一批出库数据=============================
  244. # 销售出库
  245. 'goods_delivery_sell': value.get('goods_delivery_sell', 0) +
  246. (sql_type == 'out' and sql_origin == '销售出库' and record.get('goods_qty', 0) or 0),
  247. 'cost_delivery_sell': value.get('cost_delivery_sell', 0) +
  248. (sql_type == 'out' and sql_origin == '销售出库' and record.get('cost', 0) or 0),
  249. # 其他出库
  250. 'goods_out_others': value.get('goods_out_others', 0) +
  251. (sql_type == 'out' and sql_origin == '其他出库' and record.get('goods_qty', 0) or 0),
  252. 'cost_out_others': value.get('cost_out_others', 0) +
  253. (sql_type == 'out' and sql_origin == '其他出库' and record.get('cost', 0) or 0),
  254. # 盘亏出库
  255. 'goods_out_inventory': value.get('goods_out_inventory', 0) +
  256. (sql_type == 'out' and sql_origin == '盘亏' and record.get('goods_qty', 0) or 0),
  257. 'cost_out_inventory': value.get('cost_out_inventory', 0) +
  258. (sql_type == 'out' and sql_origin == '盘亏' and record.get('cost', 0) or 0),
  259. # 采购退货
  260. 'goods_receipt_return': value.get('goods_receipt_return', 0) +
  261. (sql_type == 'out' and sql_origin == '采购退货' and record.get('goods_qty',
  262. 0) or 0),
  263. 'cost_receipt_return': value.get('cost_receipt_return', 0) +
  264. (sql_type == 'out' and sql_origin == '采购退货' and record.get('cost', 0) or 0),
  265. # 组装单子件(组装出库)
  266. 'goods_assembly_out': value.get('goods_assembly_out', 0) +
  267. (sql_type == 'out' and sql_origin == '组装单子件' and record.get('goods_qty',
  268. 0) or 0),
  269. 'cost_assembly_out': value.get('cost_assembly_out', 0) +
  270. (sql_type == 'out' and sql_origin == '组装单子件' and record.get('cost', 0) or 0),
  271. # =============================期末数量=============================
  272. 'goods_qty_in': value.get('goods_qty_in', 0) + (sql_type == 'in' and record.get('goods_qty', 0) or 0),
  273. 'cost_in': value.get('cost_in', 0) + (sql_type == 'in' and record.get('cost', 0) or 0),
  274. 'goods_qty_out': value.get('goods_qty_out', 0) + (sql_type == 'out' and record.get('goods_qty', 0) or 0),
  275. 'cost_out': value.get('cost_out', 0) + (sql_type == 'out' and record.get('cost', 0) or 0),
  276. 'id_lists': value.get('id_lists', []) + record.get('id_lists', []),
  277. })
  278. def compute_history_stock_by_collect(self, res, records, sql_type='out', sql_origin=''):
  279. for record in records:
  280. record_key = self.get_record_key(record, sql_type=sql_type)
  281. if not res.get(record_key):
  282. res[record_key] = self.get_default_value_by_record(
  283. record, sql_type=sql_type, sql_origin=record['origin'])
  284. self.update_record_value(
  285. res[record_key], record, sql_type=sql_type, sql_origin=record['origin'])
  286. def collect_data_by_sql(self, sql_type='out', sql_origin=''):
  287. out_collection = self.execute_sql_inherit(sql_type='out', sql_origin='')
  288. in_collection = self.execute_sql_inherit(sql_type='in', sql_origin='')
  289. internal_in_collection = self.execute_sql_inherit(sql_type='internal', sql_origin='internal_in')
  290. internal_out_collection = self.execute_sql_inherit(sql_type='internal', sql_origin='internal_out')
  291. res = {}
  292. self.compute_history_stock_by_collect(res, out_collection, sql_type='out')
  293. self.compute_history_stock_by_collect(res, in_collection, sql_type='in')
  294. self.compute_history_stock_by_collect(res, internal_out_collection, sql_type='internal')
  295. self.compute_history_stock_by_collect(res, internal_in_collection, sql_type='internal')
  296. result = []
  297. for key, value in res.items():
  298. value.update(self.unzip_record_key(key))
  299. result.append(value)
  300. return result
  301. def find_source_move_line(self):
  302. # 查看库存调拨明细
  303. move_line_ids = []
  304. # 获得'report.stock.receipt.delivery'记录集
  305. move_line_lists = self.get_data_from_cache(sql_type='out')
  306. date_start = self.env.context.get('date_start')
  307. date_end = self.env.context.get('date_end')
  308. for line in move_line_lists:
  309. if line.get('id') == self.id:
  310. domain_dict = [('date', '>=', date_start),
  311. ('date', '<=', date_end),
  312. ('id', 'in', line.get('id_lists'))
  313. ]
  314. move_line_ids = [line.id for line in self.env['wh.move.line'].search(domain_dict)]
  315. view = self.env.ref('warehouse.wh_move_line_list')
  316. return {
  317. 'name': ('库存调拨' + str(date_start) +
  318. '~' + str(date_end) +
  319. '~' + line['goods']),
  320. 'view_mode': 'list',
  321. 'views': [(view.id, 'list')],
  322. 'res_model': 'wh.move.line',
  323. 'type': 'ir.actions.act_window',
  324. 'domain': [('id', 'in', move_line_ids)]
  325. }
上海开阖软件有限公司 沪ICP备12045867号-1