transformation_event.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. # -*- coding: utf-8 -*-
  2. # @authors: Alexander Ezquevo <alexander@acysos.com>
  3. # Copyright (C) 2015 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. from openerp.exceptions import Warning
  7. class TransformationEvent(models.Model):
  8. _name = 'farm.transformation.event'
  9. _inherit = {'farm.event': 'AbstractEvent_id'}
  10. _auto = True
  11. from_location = fields.Many2one(comodel_name='stock.location',
  12. string='Origin', required=True)
  13. to_animal_type = fields.Selection(selection=[
  14. ('male', 'Male'),
  15. ('female', 'Female'),
  16. ('individual', 'Individual'),
  17. ('group', 'Group'),
  18. ], string='Animal Type to Trasform', requiered=True)
  19. to_location = fields.Many2one(comodel_name='stock.location',
  20. string='Destination', required=True,
  21. domain=[('usage', '=', 'internal'),
  22. ('silo', '=', False), ])
  23. quantity = fields.Integer(string='Quantity', required=True,
  24. default=1)
  25. to_animal = fields.Many2one(comodel_name='farm.animal',
  26. string='Destination Animal',
  27. select=True)
  28. to_animal_group = fields.Many2one(comodel_name='farm.animal.group',
  29. string='Destination Group',
  30. select=True,
  31. help='Select a Destination Group if you'
  32. 'want to add the transformed animals to'
  33. 'this group. To create a new group leave'
  34. ' it empty.')
  35. move = fields.Many2one(comodel_name='stock.move',
  36. string='Stock Move', readonly=True)
  37. @api.one
  38. @api.onchange('animal', 'animal_group')
  39. def get_from_location(self):
  40. if self.animal_type == 'group':
  41. self.from_location = self.animal_group.location
  42. self.quantity = self.animal_group.quantity
  43. self.to_animal_group = self.animal_group
  44. else:
  45. self.from_location = self.animal.location
  46. @api.one
  47. def confirm(self):
  48. if not self.is_compatible_trasformation():
  49. raise Warning(
  50. _('Destination animal type no compatible'))
  51. elif not self.is_compatible_quant():
  52. return False
  53. elif not self.is_compatible_to_location():
  54. return False
  55. if self.animal_type == 'group' and self.to_animal_type == 'group':
  56. if self.animal_group != self.to_animal_group:
  57. self.group_to_group()
  58. else:
  59. self.move_group()
  60. elif self.to_animal_type == 'group':
  61. self.individual_to_group()
  62. else:
  63. self.group_to_indvidual()
  64. ani = False
  65. party = False
  66. if self.animal:
  67. ani = self.animal.id
  68. else:
  69. party = self.animal_group.id
  70. self.env['farm.move.event'].create({
  71. 'animal_type': self.animal_type,
  72. 'specie': self.specie.id,
  73. 'farm': self.farm.id,
  74. 'animal': ani,
  75. 'animal_group': party,
  76. 'from_location': self.from_location.id,
  77. 'timestamp': self.timestamp,
  78. 'to_location': self.to_location.id,
  79. 'quantity': self.quantity,
  80. 'unit_price': 1,
  81. 'move': self.move.id,
  82. })
  83. super(TransformationEvent, self).confirm()
  84. def is_compatible_trasformation(self):
  85. if self.animal_type == 'female' or self.animal_type == 'male':
  86. if self.to_animal_type == 'male' or \
  87. self.to_animal_type == 'female':
  88. return False
  89. elif self.animal_type == 'individual':
  90. if self.to_animal_type == 'individual':
  91. return False
  92. return True
  93. def is_compatible_quant(self):
  94. if self.to_animal_type == 'individual' or \
  95. self.animal_type == 'male' or \
  96. self.animal_type == 'female' or self.to_animal_type != 'group':
  97. if self.quantity != 1:
  98. raise Warning(
  99. _('Quantity no compatible'))
  100. elif self.animal_group.quantity < self.quantity:
  101. raise Warning(
  102. _('quantity is biger than group quantity'))
  103. elif self.quantity < 1:
  104. raise Warning(
  105. _('quantity is smaler than one'))
  106. return True
  107. def is_compatible_to_location(self):
  108. if self.animal_type == 'group' and self.to_animal_type == 'group':
  109. if self.to_animal_group != self.animal_group:
  110. if self.to_animal_group.location.id != \
  111. self.to_location.id:
  112. raise Warning(
  113. _('the destination is different from the location of'
  114. ' the destination group'))
  115. elif self.animal_type != 'group':
  116. if self.to_animal_group.location.id != \
  117. self.to_location.id:
  118. raise Warning(
  119. _('the destination is different from the location of'
  120. ' the destination group'))
  121. elif self.animal_group.location == self.to_location:
  122. raise Warning(
  123. _('the destination of animal is the same of the location'
  124. 'of the origin group'))
  125. return True
  126. @api.one
  127. def group_to_group(self):
  128. moves_obj = self.env['stock.move']
  129. quants_obj = self.env['stock.quant']
  130. production_lot_obj = self.env['stock.production.lot']
  131. animal_group_lot_obj = self.env['stock.lot_farm.animal.group']
  132. lots = []
  133. lot_ids = []
  134. old_lots = []
  135. for lot in self.animal_group.lot:
  136. lot_ids.append(lot.lot.id)
  137. old_lots.append(lot)
  138. if len(self.animal_group.lot) > 1:
  139. lot_id = self.animal_group.lot[2].lot
  140. else:
  141. lot_id = self.animal_group.lot[0].lot
  142. product_id = lot_id.product_id.id
  143. product_uom = \
  144. lot_id.product_id.product_tmpl_id.uom_id.id
  145. initial_location = self.animal_group.location.id
  146. for lot in self.to_animal_group.lot:
  147. lots.append(lot.id)
  148. for lot in old_lots:
  149. duplicate_lot = animal_group_lot_obj.create({
  150. 'animal_group': self.to_animal_group.id,
  151. 'lot': lot.lot.id})
  152. lots.append(duplicate_lot.id)
  153. self.to_animal_group.initial_quantity += self.quantity
  154. self.to_animal_group.quantity += self.quantity
  155. target_quants = quants_obj.search([
  156. ('lot_id', 'in', lot_ids),
  157. ('location_id', '=', initial_location),
  158. ])
  159. if len(self.to_animal_group.lot) < 3:
  160. new_lot = production_lot_obj.create({
  161. 'product_id': product_id,
  162. 'animal_type': 'group',
  163. })
  164. new_animal_group_lot = animal_group_lot_obj.create({
  165. 'lot': new_lot.id,
  166. 'animal_group': self.to_animal_group.id})
  167. lots.append(new_animal_group_lot.id)
  168. desty_quants = quants_obj.search([
  169. ('lot_id', '=', self.to_animal_group.lot[0].lot.id),
  170. ('location_id', '=', self.to_location.id),])
  171. for q in desty_quants:
  172. q.lot_id = new_lot
  173. else:
  174. new_lot = self.to_animal_group.lot[2].lot
  175. self.to_animal_group.lot = [(6, 0, lots)]
  176. new_move = moves_obj.create({
  177. 'name': 'regroup-' + new_lot.name,
  178. 'create_date': fields.Date.today(),
  179. 'date': self.timestamp,
  180. 'product_id': product_id,
  181. 'product_uom_qty': self.quantity,
  182. 'product_uom': product_uom,
  183. 'location_id': initial_location,
  184. 'location_dest_id': self.to_animal_group.location.id,
  185. 'origin': self.job_order.name
  186. })
  187. master_q = None
  188. for q in target_quants:
  189. if master_q is None:
  190. q.lot_id = new_lot
  191. master_q = q
  192. else:
  193. master_q.qty = master_q.qty + q.qty
  194. q.unlink()
  195. if master_q is not None:
  196. master_q.reservation_id = new_move.id
  197. if self.animal_group.quantity > self.quantity:
  198. self.animal_group.quantity -= self.quantity
  199. self.animal_group.initial_quantity -= self.quantity
  200. else:
  201. for line in self.animal_group.account.line_ids:
  202. line.account_id = self.to_animal_group.account
  203. line.name = line.name + '-Regroup-' + self.animal_group.number
  204. self.animal_group.active = False
  205. new_move.action_done()
  206. self.move = new_move
  207. def get_farm(self, location):
  208. while(location.location_id.id != 1):
  209. location = location.location_id
  210. return location
  211. @api.one
  212. def group_to_indvidual(self):
  213. moves_obj = self.env['stock.move']
  214. quants_obj = self.env['stock.quant']
  215. production_lot_obj = self.env['stock.production.lot']
  216. animal_obj = self.env['farm.animal']
  217. animal_lot_obj = self.env['stock.lot_farm.animal']
  218. self.animal_group.quantity -= 1
  219. if len(self.animal_group.lot) > 1:
  220. lot = self.animal_group.lot[2].lot
  221. else:
  222. lot = self.animal_group.lot.lot
  223. target_quant = quants_obj.search([
  224. ('lot_id', '=', lot.id),
  225. ('location_id', '=', self.animal_group.location.id),
  226. ])
  227. product_uom = \
  228. lot.product_id.product_tmpl_id.uom_id.id
  229. new_move = moves_obj.create({
  230. 'name':
  231. 'separation-' + self.to_animal_type + '-' +
  232. lot.name,
  233. 'create_date': fields.Date.today(),
  234. 'date': self.timestamp,
  235. 'product_id': lot.product_id.id,
  236. 'product_uom_qty': 1,
  237. 'product_uom': product_uom,
  238. 'location_id': self.animal_group.location.id,
  239. 'location_dest_id': self.to_location.id,
  240. 'origin': self.job_order.name
  241. })
  242. for q in target_quant:
  243. q.reservation_id = new_move.id
  244. new_move.action_done()
  245. animal = quants_obj.search([
  246. ('lot_id', '=', lot.id),
  247. ('product_id', '=', self.animal_group.specie.group_product.id),
  248. ('location_id', '=', self.to_location.id)])
  249. tag = False
  250. if self.to_animal_type == 'female':
  251. animal.product_id = self.animal_group.specie.female_product.id
  252. tag = self.env['farm.tags'].search([
  253. ('name', '=', (self.farm.name + '-future'))])
  254. if not tag:
  255. tag = self.env['farm.tags'].create({
  256. 'name': (self.farm.name + '-future')})
  257. elif self.to_animal_type == 'male':
  258. animal.product_id = self.animal_group.specie.male_product.id
  259. else:
  260. animal.product_id = self.animal_group.specie.individual_product.id
  261. new_lot = production_lot_obj.create({
  262. 'product_id': animal.product_id.id})
  263. animal.lot_id = new_lot
  264. self.move = new_move
  265. sex = {'male': 'male',
  266. 'female': 'female',
  267. 'individual': 'undetermined',
  268. }
  269. an_lot = animal_lot_obj.create({
  270. 'lot': new_lot.id})
  271. new_animal = animal_obj.create({
  272. 'type': self.to_animal_type,
  273. 'specie': self.animal_group.specie.id,
  274. 'breed': self.animal_group.breed.id,
  275. 'farm': self.get_farm(self.to_location).id,
  276. 'origin': 'purchased',
  277. 'birthdate': self.animal_group.arrival_date,
  278. 'initial_location': self.to_location.id,
  279. 'sex': sex[self.to_animal_type],
  280. 'lot': [(4, an_lot.id)],
  281. })
  282. if tag:
  283. new_animal.tags = [(6, 0, [tag.id, ])]
  284. new_animal.origin = 'raised'
  285. self.to_animal = new_animal
  286. @api.one
  287. def move_group(self):
  288. moves_obj = self.env['stock.move']
  289. quants_obj = self.env['stock.quant']
  290. if len(self.animal_group.lot) > 1:
  291. lot_id = self.animal_group.lot[2].lot.id
  292. else:
  293. lot_id = self.animal_group.lot[0].lot.id
  294. target_quant = quants_obj.search([
  295. ('lot_id', '=', lot_id),
  296. ('location_id', '=', self.animal_group.location.id),
  297. ])
  298. if len(self.to_animal_group.lot) > 1:
  299. dest_lot = self.to_animal_group.lot[2].lot
  300. else:
  301. dest_lot = self.to_animal_group.lot[0].lot
  302. warehose = self.to_location.get_farm_warehouse()
  303. location_dest = self.to_location.id
  304. picking_obj = self.env['stock.picking']
  305. picking_t = self.env['stock.picking.type'].search([
  306. ('warehouse_id', '=', warehose.id)])[1]
  307. new_pick = picking_obj.create({
  308. 'picking_type_id': picking_t.id,
  309. 'company_id': 1,
  310. 'partner_id': 1,
  311. 'move_type': 'one',
  312. 'date_done': fields.Date.today(),
  313. 'location_id': self.animal_group.location.id,
  314. 'location_dest_id': location_dest,
  315. })
  316. m_g_move = moves_obj.create({
  317. 'name': 'relocation-' + self.animal_group.number,
  318. 'date': self.timestamp,
  319. 'picking_id': new_pick.id,
  320. 'picking_type_id': picking_t.id,
  321. 'product_id': self.animal_group.lot[0].lot.product_id.id,
  322. 'product_uom_qty': self.quantity,
  323. 'product_uos_qty': self.quantity,
  324. 'product_uom':
  325. self.animal_group.lot[0].lot.product_id.product_tmpl_id.uom_id.id,
  326. 'product_uos':
  327. self.animal_group.lot[0].lot.product_id.product_tmpl_id.uom_id.id,
  328. 'location_id': self.animal_group.location.id,
  329. 'location_dest_id': location_dest,
  330. })
  331. for q in target_quant:
  332. q.lot_id = dest_lot
  333. q.reservation_id = m_g_move.id
  334. self.move = m_g_move
  335. self.animal_group.location = self.to_location
  336. new_farm = self.get_farm(self.to_location)
  337. self.animal_group.farm = new_farm
  338. analy_ac_obj = self.env['account.analytic.account']
  339. top_account = analy_ac_obj.search([
  340. ('name', '=', new_farm.name)])
  341. if not top_account:
  342. gen_account = analy_ac_obj.search([
  343. ('name', '=', 'General Account')])
  344. if not gen_account:
  345. gen_account = analy_ac_obj.create({'name': 'General Account'})
  346. top_account = analy_ac_obj.create({'name': new_farm.name,
  347. 'parent_id': gen_account.id})
  348. self.animal_group.account.parent_id = top_account
  349. transition_location = []
  350. for loc in self.specie.lost_found_location:
  351. transition_location.append(loc.id)
  352. if self.to_location.id not in transition_location:
  353. self.animal_group.state = 'fatten'
  354. tags_obj = self.env['farm.tags']
  355. for tag in self.animal_group.tags:
  356. tag.animal_group = [(3, self.animal_group.id)]
  357. new_tag = tags_obj.search([
  358. ('name', '=', self.animal_group.farm.name + '-' +
  359. self.to_location.name)])
  360. if len(new_tag) == 0:
  361. new_name = self.animal_group.farm.name + '-' \
  362. + self.to_location.name
  363. new_tag = tags_obj.create(
  364. {'name': new_name, })
  365. self.animal_group.tags = [(6, 0, [new_tag.id, ])]
  366. m_g_move.action_done()
  367. @api.one
  368. def individual_to_group(self):
  369. moves_obj = self.env['stock.move']
  370. quants_obj = self.env['stock.quant']
  371. production_lot_obj = self.env['stock.production.lot']
  372. animal_group_lot_obj = self.env['stock.lot_farm.animal.group']
  373. lots = []
  374. for lot in self.to_animal_group.lot:
  375. lots.append(lot.id)
  376. product_id = self.animal.lot.lot.product_id.id
  377. product_uom = \
  378. self.animal.lot.lot.product_id.product_tmpl_id.uom_id.id
  379. initial_location = self.animal.location.id
  380. lot_id = self.animal.lot.lot.id
  381. self.to_animal_group.initial_quantity += self.quantity
  382. self.to_animal_group.quantity += self.quantity
  383. target_quant = quants_obj.search([
  384. ('lot_id', '=', lot_id),
  385. ('location_id', '=', initial_location),
  386. ])
  387. if len(self.to_animal_group.lot) < 3:
  388. new_lot = production_lot_obj.create({
  389. 'product_id': product_id
  390. })
  391. else:
  392. new_lot = self.to_animal_group.lot[2]
  393. new_animal_group_lot = animal_group_lot_obj.create({
  394. 'lot': new_lot.id,
  395. 'animal_group': self.to_animal_group.id})
  396. lots.append(new_animal_group_lot.id)
  397. self.to_animal_group.lot = lots
  398. new_move = moves_obj.create({
  399. 'name': 'regroup-' + new_lot.name,
  400. 'create_date': fields.Date.today(),
  401. 'date': self.timestamp,
  402. 'product_id': product_id,
  403. 'product_uom_qty': self.quantity,
  404. 'product_uom': product_uom,
  405. 'location_id': initial_location,
  406. 'location_dest_id': self.to_animal_group.location.id,
  407. 'origin': self.job_order.name,
  408. })
  409. for q in target_quant:
  410. q.reservation_id = new_move.id
  411. new_move.action_done()
  412. old_quants = []
  413. for lot in self.to_animal_group.lot:
  414. old_quants.append(quants_obj.search([
  415. ('lot_id', '=', lot.lot.id),
  416. ('location_id', '=', self.to_animal_group.location.id)
  417. ]))
  418. for move in new_move:
  419. move.quant_ids.lot_id = new_lot
  420. for qs in old_quants:
  421. for q in qs:
  422. q.lot_id = new_lot
  423. self.animal.active = False
  424. animal = self.env['stock.quant'].search([
  425. ('lot_id', '=', new_lot.id),
  426. ('product_id', '=', product_id),
  427. ])
  428. animal.product_id = self.to_animal_group.lot[0].lot.product_id
  429. self.move = new_move