def _populate_factories(self): purchase_order_ids = self.env.registry.populated_models[ 'purchase.order'] product_ids = self.env.registry.populated_models['product.product'] def get_product_uom(values, counter, random): product = self.env['product.product'].browse(values['product_id']) return product.uom_id.id def get_date_planned(values, counter, random): po = self.env['purchase.order'].browse(values['order_id']) return po.date_planned return [ ('order_id', populate.iterate(purchase_order_ids)), ('name', populate.constant("PO-line-{counter}")), ('product_id', populate.randomize(product_ids)), ('product_uom', populate.compute(get_product_uom)), ('taxes_id', populate.constant(False) ), # to avoid slow _prepare_add_missing_fields ('date_planned', populate.compute(get_date_planned)), ('product_qty', populate.randint(1, 10)), ('price_unit', populate.randint(10, 100)), ]
def _populate_factories(self): random = populate.Random('product_with_supplierinfo') company_ids = self.env.registry.populated_models[ 'res.company'][:COMPANY_NB_WITH_STOCK] + [False] partner_ids = self.env.registry.populated_models['res.partner'] product_templates_ids = self.env['product.product'].browse( self.env.registry.populated_models['product.product'] ).product_tmpl_id.ids product_templates_ids += self.env.registry.populated_models[ 'product.template'] product_templates_ids = random.sample( product_templates_ids, int(len(product_templates_ids) * 0.95)) def get_company_id(values, counter, random): partner = self.env['res.partner'].browse(values['name']) if partner.company_id: return partner.company_id.id return random.choice(company_ids) def get_delay(values, counter, random): # 5 % with huge delay (between 5 month and 6 month), otherwise between 1 and 10 days if random.random() > 0.95: return random.randint(150, 210) return random.randint(1, 10) return [ ('name', populate.randomize(partner_ids)), ('company_id', populate.compute(get_company_id)), ('product_tmpl_id', populate.iterate(product_templates_ids)), ('product_name', populate.constant("SI-{counter}")), ('sequence', populate.randint(1, 10)), ('min_qty', populate.randint(0, 10)), ('price', populate.randint(10, 100)), ('delay', populate.compute(get_delay)), ]
def _populate_factories(self): company_ids = self.env.registry.populated_models[ 'res.company'][:COMPANY_NB_WITH_STOCK] resource_calendar_no_company = self.env.ref( 'resource.resource_calendar_std').copy({'company_id': False}) def get_resource_calendar_id(values, counter, random): if not values['company_id']: return resource_calendar_no_company.id return self.env['res.company'].browse( values['company_id']).resource_calendar_id.id return [ ('name', populate.constant("Workcenter - {counter}")), ('company_id', populate.iterate(company_ids + [False])), ('resource_calendar_id', populate.compute(get_resource_calendar_id)), ('active', populate.iterate([True, False], [0.9, 0.1])), ('code', populate.constant("W/{counter}")), ('capacity', populate.iterate([0.5, 1.0, 2.0, 5.0], [0.2, 0.4, 0.2, 0.2])), ('sequence', populate.randint(1, 1000)), ('color', populate.randint(1, 12)), ('costs_hour', populate.randint(5, 25)), ('time_start', populate.iterate([0.0, 2.0, 10.0], [0.6, 0.2, 0.2])), ('time_stop', populate.iterate([0.0, 2.0, 10.0], [0.6, 0.2, 0.2])), ('oee_target', populate.randint(80, 99)), ]
def _populate_factories(self): # TODO: tree of product by company to be more closer to the reality boms = self.env['mrp.bom'].search( [('id', 'in', self.env.registry.populated_models['mrp.bom'])], order='sequence, product_id, id') product_manu_ids = OrderedSet() for bom in boms: if bom.product_id: product_manu_ids.add(bom.product_id.id) else: for product_id in bom.product_tmpl_id.product_variant_ids: product_manu_ids.add(product_id.id) product_manu_ids = list(product_manu_ids) product_manu = self.env['product.product'].browse(product_manu_ids) # product_no_manu is products which don't have any bom (leaves in the BoM trees) product_no_manu = self.env['product.product'].browse( self.env.registry.populated_models['product.product'] ) - product_manu product_no_manu_ids = product_no_manu.ids def get_product_id(values, counter, random): bom = self.env['mrp.bom'].browse(values['bom_id']) last_product_bom = bom.product_id if bom.product_id else bom.product_tmpl_id.product_variant_ids[ -1] # TODO: index in list is in O(n) can be avoid by a cache dict (if performance issue) index_prod = product_manu_ids.index(last_product_bom.id) # Always choose a product futher in the recordset `product_manu` to avoid any loops # Or used a product in the `product_no_manu` sparsity = 0.4 # Increase the sparsity will decrease the density of the BoM trees => smaller Tree len_remaining_manu = len(product_manu_ids) - index_prod - 1 len_no_manu = len(product_no_manu_ids) threshold = len_remaining_manu / (len_remaining_manu + sparsity * len_no_manu) if random.random() <= threshold: # TODO: avoid copy the list (if performance issue) return random.choice(product_manu_ids[index_prod + 1:]) else: return random.choice(product_no_manu_ids) def get_product_uom_id(values, counter, random): return self.env['product.product'].browse( values['product_id']).uom_id.id return [ ('bom_id', populate.iterate(boms.ids)), ('sequence', populate.randint(1, 1000)), ('product_id', populate.compute(get_product_id)), ('product_uom_id', populate.compute(get_product_uom_id)), ('product_qty', populate.randint(1, 10)), ]
def _populate_factories(self): order_ids = self.env.registry.populated_models["sale.order"] product_ids = self.env.registry.populated_models["product.product"] # If we want more advanced products with multiple variants # add a populate dependency on product template and the following lines product_ids += self.env["product.product"].search([ ('product_tmpl_id', 'in', self.env.registry.populated_models["product.template"]) ]).ids self.env['product.product'].browse(product_ids).read( ['uom_id']) # prefetch all uom_id def get_product_uom(values, counter, random): return self.env['product.product'].browse( values['product_id']).uom_id.id # TODO sections & notes (display_type & name) return [ ("order_id", populate.randomize(order_ids)), ("product_id", populate.randomize(product_ids)), ("product_uom", populate.compute(get_product_uom)), ("product_uom_qty", populate.randint(1, 200)), ]
def _populate_factories(self): # remaining: paperformat_id, parent_id, partner_id, favicon, font, report_header, external_report_layout_id, report_footer ref = self.env.ref def get_name(values=None, counter=0, **kwargs): return 'company_%s_%s' % (counter, self.env['res.currency'].browse( values['currency_id']).name) return [ ('name', populate.constant('company_{counter}')), ('sequence', populate.randint(0, 100)), ('company_registry', populate.iterate([False, 'company_registry_{counter}'])), ('base_onboarding_company_state', populate.iterate([False] + [ e[0] for e in type(self).base_onboarding_company_state.selection ])), ('primary_color', populate.iterate([False, '', '#ff7755'])), ('secondary_color', populate.iterate([False, '', '#ffff55'], seed='primary_color')), ('currency_id', populate.iterate([ ref('base.EUR').id, ref('base.USD').id, ref('base.CHF').id, ref('base.CHF').id ])), # add more? ('name', populate.compute(get_name)), ]
def _populate_factories(self): # Take a subset (50%) of bom to have some of then without any operation random = populate.Random('byproduct_subset_bom') boms_ids = self.env.registry.populated_models['mrp.bom'] boms_ids = random.sample(boms_ids, int(len(boms_ids) * 0.5)) boms = self.env['mrp.bom'].search( [('id', 'in', self.env.registry.populated_models['mrp.bom'])], order='sequence, product_id, id') product_manu_ids = OrderedSet() for bom in boms: if bom.product_id: product_manu_ids.add(bom.product_id.id) else: for product_id in bom.product_tmpl_id.product_variant_ids: product_manu_ids.add(product_id.id) product_manu = self.env['product.product'].browse(product_manu_ids) # product_no_manu is products which don't have any bom (leaves in the BoM trees) product_no_manu = self.env['product.product'].browse( self.env.registry.populated_models['product.product'] ) - product_manu product_no_manu_ids = product_no_manu.ids def get_product_uom_id(values, counter, random): return self.env['product.product'].browse( values['product_id']).uom_id.id return [ ('bom_id', populate.iterate(boms_ids)), ('product_id', populate.randomize(product_no_manu_ids)), ('product_uom_id', populate.compute(get_product_uom_id)), ('product_qty', populate.randint(1, 10)), ]
def _populate_factories(self): product_ids = self.env['product.product'].browse( self.env.registry.populated_models['product.product']).filtered( lambda p: p.type in ('product', 'consu')).ids random_products = populate.Random("move_product_sample") product_ids = random_products.sample(product_ids, int(len(product_ids) * 0.8)) def get_product_uom(values, counter, random): return self.env['product.product'].browse( values['product_id']).uom_id.id def _attach_to_record(iterator, field_name, model_name): random = populate.Random('_attach_to_record') fields, weights = self._populate_attach_record_weight() fields_generator = self._populate_attach_record_generator() for values in iterator: field = random.choices(fields, weights)[0] values[field] = next(fields_generator[field]) yield values def _compute_picking_values(iterator, field_name, model_name): random = populate.Random('_compute_picking_values') for values in iterator: if values.get('picking_id'): picking = self.env['stock.picking'].browse( values['picking_id']) values['picking_id'] = picking.id values['location_id'] = picking.location_id.id values['location_dest_id'] = picking.location_dest_id.id values['name'] = picking.name values['date'] = picking.scheduled_date values['company_id'] = picking.company_id.id if picking.picking_type_id.code == 'incoming': values['price_unit'] = random.randint(1, 100) yield values return [ ('product_id', populate.randomize(product_ids)), ('product_uom', populate.compute(get_product_uom)), ('product_uom_qty', populate.randint(1, 10)), ('sequence', populate.randint(1, 1000)), ('_attach_to_record', _attach_to_record), ('_compute_picking_values', _compute_picking_values), ]
def _populate_factories(self): # Take a subset (70%) of bom to have some of then without any operation random = populate.Random('operation_subset_bom') boms_ids = self.env.registry.populated_models['mrp.bom'] boms_ids = random.sample(boms_ids, int(len(boms_ids) * 0.7)) # Valid workcenters by company_id (the workcenter without company can be used by any operation) workcenters_by_company = defaultdict(OrderedSet) for workcenter in self.env['mrp.workcenter'].browse( self.env.registry.populated_models['mrp.workcenter']): workcenters_by_company[workcenter.company_id.id].add(workcenter.id) workcenters_by_company = { company_id: self.env['mrp.workcenter'].browse(workcenters) for company_id, workcenters in workcenters_by_company.items() } workcenters_by_company = { company_id: workcenters | workcenters_by_company.get(False, self.env['mrp.workcenter']) for company_id, workcenters in workcenters_by_company.items() } def get_company_id(values, counter, random): bom = self.env['mrp.bom'].browse(values['bom_id']) return bom.company_id.id def get_workcenter_id(values, counter, random): return random.choice( workcenters_by_company[values['company_id']]).id return [ ('bom_id', populate.iterate(boms_ids)), ('company_id', populate.compute(get_company_id)), ('workcenter_id', populate.compute(get_workcenter_id)), ('name', populate.constant("OP-{counter}")), ('sequence', populate.randint(1, 1000)), ('time_mode', populate.iterate(['auto', 'manual'])), ('time_mode_batch', populate.randint(1, 100)), ('time_cycle_manual', populate.randomize([1.0, 15.0, 60.0, 1440.0])), ]
def _populate_factories(self): company_ids = self.env.registry.populated_models[ 'res.company'][:COMPANY_NB_WITH_STOCK] product_tmpl_ids = self.env['product.product'].search([ ('id', 'in', self.env.registry.populated_models['product.product']), ('type', 'in', ('product', 'consu')) ]).product_tmpl_id.ids # Use only a 80 % subset of the products - the 20 % remaining will leaves of the bom tree random = populate.Random('subset_product_bom') product_tmpl_ids = random.sample(product_tmpl_ids, int(len(product_tmpl_ids) * 0.8)) def get_product_id(values=None, random=None, **kwargs): if random.random( ) > 0.5: # 50 % change to target specific product.product return False return random.choice(self.env['product.template'].browse( values['product_tmpl_id']).product_variant_ids.ids) return [ ( 'company_id', populate.randomize( [False] + company_ids, [0.9] + [0.1 / (len(company_ids) or 1.0)] * ( len(company_ids) ) # TODO: Inverse the weight, but need to make the bom tree by company (in bom line populate) )), ('product_tmpl_id', populate.randomize(product_tmpl_ids)), ('product_id', populate.compute(get_product_id)), ('product_qty', populate.randint(1, 5)), ('sequence', populate.randint(1, 1000)), ('code', populate.constant("R{counter}")), ('ready_to_produce', populate.randomize(['all_available', 'asap'])), ]
def _populate_factories(self): # TODO topping_ids_{1,2,3}, topping_label_{1,3}, topping_quantity_{1,3} user_ids = self.env.registry.populated_models['res.users'] product_ids = self.env.registry.populated_models['lunch.product'] company_ids = self.env.registry.populated_models['res.company'] return [ ('active', populate.cartesian([True, False])), ('state', populate.cartesian(['new', 'confirmed', 'ordered', 'cancelled'])), ('product_id', populate.randomize(product_ids)), ('user_id', populate.randomize(user_ids)), ('note', populate.constant('lunch_note_{counter}')), ('company_id', populate.randomize(company_ids)), ('quantity', populate.randint(0, 10)), ]
def _populate_factories(self): product_ids = self.env['product.product'].search([ ('id', 'in', self.env.registry.populated_models['product.product']), ('type', '=', 'product'), ('tracking', '=', 'none') ]).ids locations = self.env['stock.location'].search([ ('id', 'in', self.env.registry.populated_models['stock.location']), ('usage', '=', 'internal'), ]) return [ ('location_id', populate.randomize(locations.ids)), ('product_id', populate.randomize(product_ids)), ('inventory_quantity', populate.randint(0, 100)), ]
def _populate_factories(self): company_ids = self.env.registry.populated_models[ 'res.company'][:COMPANY_NB_WITH_STOCK] product_ids = self.env['product.product'].browse( self.env.registry.populated_models['product.product']).filtered( lambda p: p.type == 'product').ids product_categ_ids = self.env.registry.populated_models[ 'product.category'] storage_categ_ids = self.env.registry.populated_models[ 'stock.storage.category'] location_ids = self.env['stock.location'].browse( self.env.registry.populated_models['stock.location']).filtered( lambda loc: loc.usage == 'internal') def get_product_id(values, counter, random): if random.random() > 0.5: return random.choice(product_ids) return False def get_category_id(values, counter, random): if not values['product_id']: return random.choice(product_categ_ids) return False def get_location_in_id(values, counter, random): locations = location_ids.filtered( lambda loc: loc.company_id.id == values['company_id']) return random.choice(locations.ids) def get_location_out_id(values, counter, random): child_locs = self.env['stock.location'].search([ ('id', 'child_of', values['location_in_id']), ('usage', '=', 'internal') ]) + self.env['stock.location'].browse(values['location_in_id']) return random.choice(child_locs.ids) return [ ('company_id', populate.randomize(company_ids)), ('product_id', populate.compute(get_product_id)), ('category_id', populate.compute(get_category_id)), ('location_in_id', populate.compute(get_location_in_id)), ('location_out_id', populate.compute(get_location_out_id)), ('sequence', populate.randint(1, 1000)), ('storage_category_id', populate.randomize(storage_categ_ids)), ]
def _populate_factories(self): # cross dependant field in a sub generator, cartesian product of two fields dependant_factories = [ ('dependant_field_1', populate.cartesian(['d1_1', 'd1_2'])), ('dependant_field_2', populate.cartesian(['d2_1', 'd2_2', 'd2_3_{counter}'])), ] def generate_dependant(iterator, *args): dependants_generator = populate.chain_factories( dependant_factories, self._name) for values in dependants_generator: dependant_values = next(iterator) yield { **values, **dependant_values, '__complete': values['__complete'] and dependant_values['__complete'] } def get_name(values=None, counter=0, **kwargs): active = 'active' if values['active'] else 'inactive' cat = 'filling' if values['__complete'] else 'corner' return '%s_%s_%s' % (active, cat, counter) category_ids = self.env.registry.populated_models[ 'test.populate.category'] return [('active', populate.cartesian([True, False], [3, 1])), ('state', populate.cartesian([False] + self.env['test.populate']. _fields['state'].get_values(self.env))), ('some_ref', populate.iterate([False, 1, 2, 3, 4])), ('_dependant', generate_dependant), ('name', populate.compute(get_name)), ('category_id', populate.randomize([False] + category_ids)), ('sequence', populate.randint(1, 10))]
def _populate_factories(self): return super()._populate_factories() + [ ('po_lead', populate.randint(0, 2)) ]
def _populate_factories(self): now = datetime.now() company_ids = self.env.registry.populated_models[ 'res.company'][:COMPANY_NB_WITH_STOCK] products = self.env['product.product'].browse( self.env.registry.populated_models['product.product']) product_ids = products.filtered(lambda product: product.type in ('product', 'consu')).ids boms = self.env['mrp.bom'].browse( self.env.registry.populated_models['mrp.bom']) boms_by_company = defaultdict(OrderedSet) for bom in boms: boms_by_company[bom.company_id.id].add(bom.id) boms_by_company = { company_id: self.env['mrp.bom'].browse(boms) for company_id, boms in boms_by_company.items() } boms_by_company = { company_id: boms | boms_by_company.get(False, self.env['mrp.bom']) for company_id, boms in boms_by_company.items() } def get_bom_id(values, counter, random): if random.random() > 0.7: # 30 % of prototyping return False return random.choice(boms_by_company[values['company_id']]).id def get_consumption(values, counter, random): if not values['bom_id']: return 'flexible' return self.env['mrp.bom'].browse(values['bom_id']).consumption def get_product_id(values, counter, random): if not values['bom_id']: return random.choice(product_ids) bom = self.env['mrp.bom'].browse(values['bom_id']) return bom.product_id.id or random.choice( bom.product_tmpl_id.product_variant_ids.ids) def get_product_uom_id(values, counter, random): product = self.env['product.product'].browse(values['product_id']) return product.uom_id.id # Fetch all stock picking type and group then by company_id manu_picking_types = self.env['stock.picking.type'].search([ ('code', '=', 'mrp_operation') ]) manu_picking_types_by_company_id = defaultdict(OrderedSet) for picking_type in manu_picking_types: manu_picking_types_by_company_id[picking_type.company_id.id].add( picking_type.id) manu_picking_types_by_company_id = { company_id: list(picking_ids) for company_id, picking_ids in manu_picking_types_by_company_id.items() } def get_picking_type_id(values, counter, random): return random.choice( manu_picking_types_by_company_id[values['company_id']]) def get_location_src_id(values, counter, random): # TODO : add some randomness picking_type = self.env['stock.picking.type'].browse( values['picking_type_id']) return picking_type.default_location_src_id.id def get_location_dest_id(values, counter, random): # TODO : add some randomness picking_type = self.env['stock.picking.type'].browse( values['picking_type_id']) return picking_type.default_location_dest_id.id def get_date_planned_start(values, counter, random): # 95.45 % of picking scheduled between (-10, 30) days and follow a gauss distribution (only +-15% picking is late) delta = random.gauss(10, 10) return now + timedelta(days=delta) return [ ('company_id', populate.iterate(company_ids)), ('bom_id', populate.compute(get_bom_id)), ('consumption', populate.compute(get_consumption)), ('product_id', populate.compute(get_product_id)), ('product_uom_id', populate.compute(get_product_uom_id)), ('product_qty', populate.randint(1, 10)), ('picking_type_id', populate.compute(get_picking_type_id)), ('date_planned_start', populate.compute(get_date_planned_start)), ('location_src_id', populate.compute(get_location_src_id)), ('location_dest_id', populate.compute(get_location_dest_id)), ('priority', populate.iterate(['0', '1'], [0.95, 0.05])), ]
def _populate_factories(self): return super()._populate_factories() + [ ('produce_delay', populate.randint(1, 4)), ]
def _populate_factories(self): return super()._populate_factories() + [ ('manufacturing_lead', populate.randint(0, 2)), ]
def _populate_factories(self): pricelist_ids = self.env.registry.populated_models["product.pricelist"] product_ids = self.env.registry.populated_models["product.product"] p_tmpl_ids = self.env.registry.populated_models["product.template"] categ_ids = self.env.registry.populated_models["product.category"] def get_target_info(iterator, field_name, model_name): random = populate.Random("pricelist_target") for values in iterator: # If product population is updated to consider multi company # the company of product would have to be considered # for product_id & product_tmpl_id applied_on = values["applied_on"] if applied_on == "0_product_variant": values["product_id"] = random.choice(product_ids) elif applied_on == "1_product": values["product_tmpl_id"] = random.choice(p_tmpl_ids) elif applied_on == "2_product_category": values["categ_id"] = random.choice(categ_ids) yield values def get_prices(iterator, field_name, model_name): random = populate.Random("pricelist_prices") for values in iterator: # Fixed price, percentage, formula compute_price = values["compute_price"] if compute_price == "fixed": # base = "list_price" = default # fixed_price values["fixed_price"] = random.randint(1, 1000) elif compute_price == "percentage": # base = "list_price" = default # percent_price values["percent_price"] = random.randint(1, 100) else: # formula # pricelist base not considered atm. values["base"] = random.choice( ["list_price", "standard_price"]) values["price_discount"] = random.randint(0, 100) # price_min_margin, price_max_margin # price_round ??? price_discount, price_surcharge yield values now = date.today() def get_date_start(values, counter, random): if random.random( ) > 0.5: # 50 % of chance to have validation dates return now + timedelta(days=random.randint(-20, 20)) else: False def get_date_end(values, counter, random): if values['date_start']: # 50 % of chance to have validation dates return values['date_start'] + timedelta( days=random.randint(5, 100)) else: False return [ ("pricelist_id", populate.randomize(pricelist_ids)), ("applied_on", populate.randomize( [ "3_global", "2_product_category", "1_product", "0_product_variant" ], [5, 3, 2, 1], )), ("compute_price", populate.randomize( ["fixed", "percentage", "formula"], [5, 3, 1], )), ("_price", get_prices), ("_target", get_target_info), ("min_quantity", populate.randint(0, 50)), ("date_start", populate.compute(get_date_start)), ("date_end", populate.compute(get_date_end)), ]