consume_stock.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. # -*- coding: utf-8 -*-
  2. # @authors: Alexander Ezquevo <alexander@acysos.com>
  3. # Copyright (C) 2016 Acysos S.L.
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. from openerp import models, fields, api
  6. class ConsumeStock(models.Model):
  7. _name = 'farm.consume.stock'
  8. state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')],
  9. default='draft')
  10. type = fields.Selection([('farm', 'Farm'), ('yard', 'Yard')],
  11. string='Distribution Type')
  12. origin = fields.Many2one(string='Origin',
  13. comodel_name='stock.location')
  14. to_location = fields.Many2one(string='Destinity',
  15. comodel_name='stock.location')
  16. product_id = fields.Many2one(string='Product',
  17. comodel_name='product.product')
  18. lot_id = fields.Many2one(string='Lot', comodel_name='stock.production.lot')
  19. quantity = fields.Float(string='Quantity')
  20. date = fields.Date(string='Date', defaut=fields.Date.today())
  21. @api.multi
  22. @api.onchange('type')
  23. def onchange_type(self):
  24. for res in self:
  25. if res.type and res.type == 'farm':
  26. return {'domain': {'to_location': [('usage', '=', 'view')]}}
  27. else:
  28. return {'domain': {'to_location': [('usage', '!=', 'view')]}}
  29. @api.multi
  30. @api.onchange('origin')
  31. def onchange_location(self):
  32. for res in self:
  33. ids = []
  34. quants = self.env['stock.quant'].search([
  35. ('location_id', '=', res.origin.id),
  36. ('qty', '>', 0)
  37. ])
  38. for q in quants:
  39. ids.append(q.product_id.id)
  40. return {'domain': {'product_id': [('id', 'in', ids)]}}
  41. @api.multi
  42. @api.onchange('product_id')
  43. def onchange_product(self):
  44. for res in self:
  45. ids = []
  46. quants = self.env['stock.quant'].search([
  47. ('location_id', '=', res.origin.id),
  48. ('product_id', '=', res.product_id.id)])
  49. for q in quants:
  50. ids.append(q.lot_id.id)
  51. return {'domain': {
  52. 'lot_id': [('id', 'in', ids)]}}
  53. @api.multi
  54. @api.onchange('lot_id')
  55. def on_change_lot(self):
  56. for res in self:
  57. quants = self.env['stock.quant'].search([
  58. ('location_id', '=', res.origin.id),
  59. ('product_id', '=', res.product_id.id),
  60. ('lot_id', '=', res.lot_id.id)])
  61. total = 0
  62. for q in quants:
  63. total = total + q.qty
  64. res.quantity = total
  65. @api.multi
  66. def get_cost(self, lot, qty, product_id):
  67. cost = 0
  68. if lot and lot.unit_cost and lot.unit_cost > 0:
  69. cost = lot.unit_cost * qty
  70. else:
  71. if lot:
  72. quants_obj = self.env['stock.quant']
  73. quants = quants_obj.search([
  74. ('lot_id', '=', lot.id)])
  75. ids = []
  76. for q in quants:
  77. ids.append(q.id)
  78. moves = self.env['stock.move'].with_context({}).search([
  79. ('quant_ids', 'in', ids),
  80. ('picking_id', '!=', False)])
  81. amount = 0.0
  82. raw_qty = 0
  83. for mov in moves:
  84. if mov.price_unit > 0:
  85. amount += mov.price_unit * mov.product_qty
  86. raw_qty = raw_qty + mov.product_qty
  87. if raw_qty > 0:
  88. unit_price = amount/raw_qty
  89. cost += qty * unit_price
  90. if cost == 0:
  91. cost = lot.product_id.product_tmpl_id.list_price * qty
  92. else:
  93. cost = product_id.product_tmpl_id.list_price * qty
  94. return cost
  95. @api.multi
  96. def confirm(self):
  97. moves_obj = self.env['stock.move']
  98. quants_obj = self.env['stock.quant']
  99. scrap = self.env['stock.location'].search(
  100. [('scrap_location', '=', True)])[0]
  101. for res in self:
  102. species = self.env['farm.specie'].search(
  103. [(True, '=', True)])
  104. remov_locs = []
  105. for specie in species:
  106. remov_locs.append(specie.removed_location.id)
  107. if res.type == 'farm':
  108. condition = ('farm', '=', res.to_location.id)
  109. else:
  110. condition = ('location', '=', res.to_location.id)
  111. afected_ani = self.env['farm.animal'].search([
  112. condition, ('location', 'not in', remov_locs)])
  113. afected_gro = self.env['farm.animal.group'].search([
  114. condition, ('state', '!=', 'sold'),
  115. ('location', 'not in', remov_locs)])
  116. afected_animals = [afected_gro, afected_ani]
  117. num_ani = len(afected_ani)
  118. for party in afected_gro:
  119. num_ani = num_ani + party.quantity
  120. cost = self.get_cost(res.lot_id, res.quantity, res.product_id)
  121. if num_ani > 0:
  122. cost_p_an = cost/num_ani
  123. for gro in afected_gro:
  124. self.set_party_cost(gro, res.date, cost_p_an)
  125. for an in afected_ani:
  126. self.set_animal_cost(an, res.date, cost_p_an)
  127. else:
  128. if res. type == 'farm':
  129. farm = res.to_location
  130. else:
  131. farm = self.get_farm(res.to_location)
  132. analitic_remain_ob = self.env['purchase.analitic.remain']
  133. analitic_remain = analitic_remain_ob.search([
  134. ('farm', '=', farm.id)])
  135. if len(analitic_remain) == 0:
  136. analitic_remain_ob.create({
  137. 'farm': farm.id,
  138. 'quantity': cost})
  139. else:
  140. analitic_remain.quantity = analitic_remain.quantity\
  141. + cost
  142. consumed_quants = []
  143. if res.lot_id:
  144. consumed_quants = quants_obj.search([
  145. ('lot_id', '=', res.lot_id.id),
  146. ('location_id', '=', res.origin.id)])
  147. new_move = moves_obj.create({
  148. 'name': 'consume',
  149. 'create_date': fields.Date.today(),
  150. 'date': res.date,
  151. 'product_id': res.product_id.id,
  152. 'product_uom_qty': res.quantity,
  153. 'product_uom': res.product_id.product_tmpl_id.uom_id.id,
  154. 'location_id': res.origin.id,
  155. 'location_dest_id': scrap.id,
  156. 'company_id': res.origin.company_id.id,
  157. })
  158. for q in consumed_quants:
  159. q.reservation_id = new_move.id
  160. new_move.action_done()
  161. res.state = 'confirmed'
  162. def get_farm(self, location):
  163. while(location.location_id.id != 1):
  164. location = location.location_id
  165. return location
  166. @api.multi
  167. def set_party_cost(self, party, date, cost_per_animal_day):
  168. company = self.env['res.company'].with_context({}).search([
  169. ('id', '=', 1)])
  170. journal = self.env['account.analytic.journal'].with_context(
  171. {}).search([('code', '=', 'PUR')])
  172. analytic_line_obj = self.env['account.analytic.line']
  173. analytic_line_obj.create({
  174. 'name': 'consum',
  175. 'date': date,
  176. 'amount': -(cost_per_animal_day * party.quantity),
  177. 'unit_amount': party.quantity,
  178. 'account_id': party.account.id,
  179. 'general_account_id': company.feed_account.id,
  180. 'journal_id': journal.id,
  181. })
  182. @api.multi
  183. def set_animal_cost(self, animal, date, cost_per_animal_day):
  184. company = self.env['res.company'].with_context({}).search([
  185. ('id', '=', animal.farm.company_id.id)])
  186. journal = self.env['account.analytic.journal'].with_context(
  187. {}).search([('code', '=', 'PUR')])
  188. analytic_line_obj = self.env['account.analytic.line']
  189. analytic_line_obj.create({
  190. 'name': 'consum',
  191. 'date': date,
  192. 'amount': -cost_per_animal_day,
  193. 'unit_amount': 1,
  194. 'account_id': animal.account.id,
  195. 'general_account_id': company.feed_account.id,
  196. 'journal_id': journal.id,
  197. })