| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 | # -*- coding: utf-8 -*-# @authors: Alexander Ezquevo <alexander@acysos.com># Copyright (C) 2015  Acysos S.L.# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).from openerp import models, fields, api, _from openerp.exceptions import Warningimport mathclass SemenExtractionEvent(models.Model):    _name = 'farm.semen_extraction.event'    _inherit = {'farm.event': 'AbstractEvent_id'}    _auto = True    semen_product = fields.Many2one(comodel_name='product.product',                                    string="Semen's Product")    untreated_semen_qty = fields.Float(string='Semen Extracted Qty',                                       required=True, digits=(16, 3))    formula_result = fields.Float(string='Formula Result', required=True)    solvent_calculated_qty = fields.Float(string='Calc. semen solvent Qty',                                          compute='get_solvent_qty')    semen_calculated_qty = fields.Float(string='Calc. Semen Produced Qty',                                        compute='get_semen_calculated_qty')    semen_qty = fields.Float(string='Semen Producec Quantity', digits=(16, 3))    semen_lot = fields.Many2one(comodel_name='stock.production.lot',                                string='Semen lot')    semen_move = fields.Many2one(comodel_name='stock.move', string='Move')    dose_location = fields.Many2one(comodel_name='stock.location',                                    string='Doses Location',                                    domain=[('usage', '=', 'internal')],                                    required=True)    dose_bom = fields.Many2one(comodel_name='mrp.bom',                               string='Dose Container',                               )    dose_calculated_units = fields.Float(        string='Calculated Doses',        help='Calculates the number of doses based on Container (BoM) and '        'Semen Produced Qty. The quantity is expressed in the UoM of the '        'Container.\n'        'You have to save the event to see this calculated value.',        compute='on_change_with_dose_calculated_units')    doses = fields.One2many(comodel_name='farm.semen_extraction.dose',                            inverse_name='event', string='Doses')    doses_semen_qty = fields.Float(string='Dose Semen Qty',                                   compute='on_change_with_doses_semen_qty')    semen_remaining_qty = fields.Float(        string='Remaining Semen',        compute='on_change_with_semen_remaining_qty')    @api.onchange('specie')    def onchange_specie(self):        return {'domain': {                'semen_product': [('id', '=', self.specie.semen_product.id)]}}    @api.one    def get_solvent_qty(self):        self.solvent_calculated_qty = \            self.semen_calculated_qty - self.untreated_semen_qty    @api.one    def get_semen_calculated_qty(self):        self.semen_calculated_qty = \            self.untreated_semen_qty * self.formula_result    @api.one    def on_change_with_dose_calculated_units(self):        if not self.dose_bom or not self.semen_qty:            self.dose_calculated_units = 0.0        else:            consumed_semen_qty = 0.0            for line in self.dose_bom.bom_line_ids:                if line.product_id == self.specie.semen_product:                    consumed_semen_qty = line.product_qty            if consumed_semen_qty == 0:                self.dose_calculated_units = 0.0            else:                self.dose_calculated_units = \                    float(self.semen_qty)/consumed_semen_qty    @api.one    def on_change_with_semen_remaining_qty(self):        semen_remaining_qty = self.semen_qty or 0        if self.semen_qty is None or not self.doses:            self.semen_remaining_qty = semen_remaining_qty        else:            for dose in self.doses:                semen_remaining_qty -= dose.semen_qty or 0.0            self.semen_remaining_qty = semen_remaining_qty    @api.one    def on_change_with_doses_semen_qty(self):        if self.semen_qty is None or not self.doses:            self.doses_semen_qty = 0.0        else:            doses_qty = 0.0            for dose in self.doses:                doses_qty += dose.semen_qty or 0.0            self.doses_semen_qty = doses_qty    def is_valid(self):        for extraction_event in self:            extraction_event.check_doses_semen_quantity()            extraction_event.check_deliveries_dose_quantity()    def check_doses_semen_quantity(self):        if self.semen_remaining_qty < 0.0:            raise Warning(                _('More semen in doses than produced'))    @api.one    def calculate_doses(self):        Dose_obj = self.env['farm.semen_extraction.dose']        for extraction_event in self:            if extraction_event.doses:                raise Warning(                    _('dose already defined'))            if not extraction_event.dose_bom:                continue            n_doses = math.floor(extraction_event.dose_calculated_units)            Dose_obj.create({                'event': extraction_event.id,                'sequence': 1,                'bom': extraction_event.dose_bom.id,                'quantity': n_doses})    @api.one    def confirm(self):        self.check_doses_semen_quantity()        for extraction_event in self:            if not extraction_event.doses:                raise Warning(                    _('no doses'))            self.get_semen_move()            for dose in extraction_event.doses:                dose.get_production()                dose.state = 'validated'        super(SemenExtractionEvent, extraction_event).confirm()    @api.one    def get_semen_move(self):        move_obj = self.env['stock.move']        lot_obj = self.env['stock.production.lot']        new_lot = lot_obj.create({            'product_id': self.specie.semen_product.id})        production_location = self.env['stock.location'].search(            [('usage', '=', 'production')])        new_move = move_obj.create({            'name': 'extrac' + new_lot.name,            'product_id': self.specie.semen_product.id,            'product_uom_qty': self.semen_qty,            'location_id': production_location.id,            'location_dest_id': self.dose_location.id,            'date': self.timestamp,            'company_id': self.farm.company_id.id,            'origin': 'extraction' + self.lot.name,            'product_uom':                self.specie.semen_product.product_tmpl_id.uom_id.id,            })        new_move.action_done()        for q in new_move.quant_ids:            q.lot_id = new_lot.id        self.semen_move = new_move        self.semen_lot = new_lotclass SemenExtractionDose(models.Model):    _name = 'farm.semen_extraction.dose'    _order = 'sequence ASC'    event = fields.Many2one(comodel_name='farm.semen_extraction.event',                            string='Event')    specie = fields.Many2one(comodel_name='farm.specie', string='Specie',                             compute='get_specie')    state = fields.Selection(string='state',                             selection=[                                    ('draft', 'Draft'),                                    ('validated', 'Validated')],                             default='draft')    sequence = fields.Integer(string='Line Num', required=True)    bom = fields.Many2one(comodel_name='mrp.bom', string='Container',                          required=True,                          domain=[('semen_dose', '=', True), ])    quantity = fields.Integer(string='Quantity', required=True)    semen_qty = fields.Float(string='Semen Qty', compute='get_qty')    dose_product = fields.Many2one(comodel_name='product.product',                                   string="Dose Product")    production = fields.Many2one(comodel_name='mrp.production',                                 string='production')    lot = fields.Many2one(comodel_name='stock.production.lot',                          string='Lot')    @api.one    def get_qty(self):        if not self.event or not self.bom or not self.quantity:            self.semen_qty = False        else:            semen_product = self.event.specie.semen_product            semen_qty = 0.0            for line in self.bom.bom_line_ids:                if line.product_id == semen_product:                    semen_qty = line.product_qty*self.quantity                    break            self.semen_qty = semen_qty    @api.one    def get_specie(self):        self.specie = self.event.specie    @api.one    def get_production(self):        production_location = self.env['stock.location'].search(            [('usage', '=', 'production')])        production_obj = self.env['mrp.production']        products_obj = self.env['product.product']        produce_line_obj = self.env['mrp.product.produce.line']        wiz_product_produce_obj = self.env['mrp.product.produce']        manu_product = products_obj.search(            [('product_tmpl_id', '=', self.bom.product_tmpl_id.id)])        new_production = production_obj.create({            'name': self.event,            'date_planned': self.event.timestamp,            'company_id': self.event.farm.company_id.id,            'product_id': manu_product.id,            'bom_id': self.bom.id,            'product_uom': self.bom.product_tmpl_id.uom_id.id,            'location_src_id': self.event.dose_location.id,            'location_dest_id': self.event.dose_location.id,            'product_qty': self.quantity,            'origin': self.event.job_order.name            })        new_production.action_confirm()        new_production.action_ready()        '''        for line in new_production.move_lines:            line.location_id = production_location        '''        lots_obj = self.env['stock.production.lot']        new_lot = lots_obj.create({            'product_id': manu_product.id, })        new_wiz_production = wiz_product_produce_obj.create({            'product_id': manu_product.id,            'product_qty': self.quantity,            'mode': 'consume_produce',            'lot_id': new_lot.id,            })        for line in new_production.move_lines:            produce_line_obj.create({                'product_id': line.product_id.id,                'product_qty': line.product_uom_qty,                'lot_id': self.event.semen_lot.id,                'produce_id': new_wiz_production.id,                })        new_production.action_produce(self.quantity,            'consume_produce', new_wiz_production)        new_production.action_production_end()        self.production = new_production        self.lot = new_lot
 |