def test_in_refund_line_onchange_sequence_number_1(self): self.assertRecordValues( self.invoice, [{ 'invoice_sequence_number_next': '0001', 'invoice_sequence_number_next_prefix': 'RBILL/2019/', }]) move_form = Form(self.invoice) move_form.invoice_sequence_number_next = '0042' move_form.save() self.assertRecordValues( self.invoice, [{ 'invoice_sequence_number_next': '0042', 'invoice_sequence_number_next_prefix': 'RBILL/2019/', }]) self.invoice.post() self.assertRecordValues(self.invoice, [{'name': 'RBILL/2019/0042'}]) values = { 'invoice_date': self.invoice.invoice_date, } invoice_copy = self.invoice.copy(default=values) invoice_copy.post() self.assertRecordValues(invoice_copy, [{'name': 'RBILL/2019/0043'}])
def test_multiple_shipments_invoices(self): """ Tests the case into which we receive part of the goods first, then 2 invoices at different rates, and finally the remaining quantities """ test_product = self.test_product_delivery date_po_and_delivery0 = '2017-01-01' purchase_order = self._create_purchase(test_product, date_po_and_delivery0, quantity=5.0) self._process_pickings(purchase_order.picking_ids, quantity=2.0, date=date_po_and_delivery0) picking = self.env['stock.picking'].search( [('purchase_id', '=', purchase_order.id)], order="id asc", limit=1) invoice = self._create_invoice_for_po(purchase_order, '2017-01-15') move_form = Form(invoice) with move_form.invoice_line_ids.edit(0) as line_form: line_form.quantity = 3.0 invoice = move_form.save() self.env['res.currency.rate'].create({ 'currency_id': self.currency_one.id, 'company_id': self.company.id, 'rate': 7.76435463, 'name': '2017-02-01', }) invoice.post() self.check_reconciliation(invoice, picking, full_reconcile=False) invoice2 = self._create_invoice_for_po(purchase_order, '2017-02-15') move_form = Form(invoice2) with move_form.invoice_line_ids.edit(0) as line_form: line_form.quantity = 2.0 invoice2 = move_form.save() self.env['res.currency.rate'].create({ 'currency_id': self.currency_one.id, 'company_id': self.company.id, 'rate': 13.834739702, 'name': '2017-03-01', }) invoice2.post() self.check_reconciliation(invoice2, picking, full_reconcile=False) self.env['res.currency.rate'].create({ 'currency_id': self.currency_one.id, 'company_id': self.company.id, 'rate': 12.195747002, 'name': '2017-04-01', }) # We don't need to make the date of processing explicit since the very last rate # will be taken self._process_pickings( purchase_order.picking_ids.filtered(lambda x: x.state != 'done'), quantity=3.0) picking = self.env['stock.picking'].search( [('purchase_id', '=', purchase_order.id)], order='id desc', limit=1) self.check_reconciliation(invoice2, picking)
def test_o2m_attrs(self): Model = self.env['test_testing_utilities.parent'].with_context( default_subs=[{ 'value': 5, }, { 'value': 7, }]) f = Form(Model, view='test_testing_utilities.o2m_modifier') f.save()
def test_required_bool(self): f = Form(self.env['test_testing_utilities.req_bool']) f.f_bool = False r = f.save() self.assertEqual(r.f_bool, 0) f2 = Form(self.env['test_testing_utilities.req_bool']) r2 = f2.save() self.assertEqual(r2.f_bool, 0)
def test_required(self): f = Form(self.env['test_testing_utilities.a']) # f1 no default & no value => should fail with self.assertRaisesRegexp(AssertionError, 'f1 is a required field'): f.save() # set f1 and unset f2 => should work f.f1 = '1' f.f2 = False r = f.save() self.assertEqual((r.f1, r.f2, r.f3, r.f4), ('1', 0, 0, 0))
def test_generate_with_putaway(self): """ Checks the `location_dest_id` of generated move lines is correclty set in fonction of defined putaway rules. """ nbre_of_lines = 4 shelf_location = self.env['stock.location'].create({ 'name': 'shelf1', 'usage': 'internal', 'location_id': self.location_dest.id, }) # Checks a first time without putaway... move = self.get_new_move(nbre_of_lines) form_wizard = Form(self.env['stock.assign.serial'].with_context( default_move_id=move.id, )) form_wizard.next_serial_count = nbre_of_lines form_wizard.next_serial_number = '001' wiz = form_wizard.save() wiz.generate_serial_numbers() for move_line in move.move_line_nosuggest_ids: self.assertEqual(move_line.qty_done, 1) # The location dest must be the default one. self.assertEqual(move_line.location_dest_id.id, self.location_dest.id) # We need to activate multi-locations to use putaway rules. grp_multi_loc = self.env.ref('stock.group_stock_multi_locations') self.env.user.write({'groups_id': [(4, grp_multi_loc.id)]}) # Creates a putaway rule putaway_product = self.env['stock.putaway.rule'].create({ 'product_id': self.product_serial.id, 'location_in_id': self.location_dest.id, 'location_out_id': shelf_location.id, }) # Checks now with putaway... move = self.get_new_move(nbre_of_lines) form_wizard = Form(self.env['stock.assign.serial'].with_context( default_move_id=move.id, )) form_wizard.next_serial_count = nbre_of_lines form_wizard.next_serial_number = '001' wiz = form_wizard.save() wiz.generate_serial_numbers() for move_line in move.move_line_nosuggest_ids: self.assertEqual(move_line.qty_done, 1) # The location dest must be now the one from the putaway. self.assertEqual(move_line.location_dest_id.id, shelf_location.id)
def setUpClass(cls): super(TestMrpSubcontractingCommon, cls).setUpClass() # 1: Create a subcontracting partner main_partner = cls.env['res.partner'].create({'name': 'main_partner'}) cls.subcontractor_partner1 = cls.env['res.partner'].create({ 'name': 'subcontractor_partner', 'parent_id': main_partner.id, 'company_id': cls.env.ref('base.main_company').id, }) # 2. Create a BOM of subcontracting type cls.comp1 = cls.env['product.product'].create({ 'name': 'Component1', 'type': 'product', 'categ_id': cls.env.ref('product.product_category_all').id, }) cls.comp2 = cls.env['product.product'].create({ 'name': 'Component2', 'type': 'product', 'categ_id': cls.env.ref('product.product_category_all').id, }) cls.finished = cls.env['product.product'].create({ 'name': 'finished', 'type': 'product', 'categ_id': cls.env.ref('product.product_category_all').id, }) bom_form = Form(cls.env['mrp.bom']) bom_form.type = 'subcontract' bom_form.product_tmpl_id = cls.finished.product_tmpl_id bom_form.subcontractor_ids.add(cls.subcontractor_partner1) with bom_form.bom_line_ids.new() as bom_line: bom_line.product_id = cls.comp1 bom_line.product_qty = 1 with bom_form.bom_line_ids.new() as bom_line: bom_line.product_id = cls.comp2 bom_line.product_qty = 1 cls.bom = bom_form.save() # Create a BoM for cls.comp2 cls.comp2comp = cls.env['product.product'].create({ 'name': 'component for Component2', 'type': 'product', 'categ_id': cls.env.ref('product.product_category_all').id, }) bom_form = Form(cls.env['mrp.bom']) bom_form.product_tmpl_id = cls.comp2.product_tmpl_id with bom_form.bom_line_ids.new() as bom_line: bom_line.product_id = cls.comp2comp bom_line.product_qty = 1 cls.comp2_bom = bom_form.save() cls.warehouse = cls.env['stock.warehouse'].search([], limit=1)
def test_generate_04_generate_in_multiple_time(self): """ Generates a Serial Number for each move lines (except the last one) but with multiple assignments, and checks the generated Serial Numbers are what we expect. """ nbre_of_lines = 10 move = self.get_new_move(nbre_of_lines) form_wizard = Form(self.env['stock.assign.serial'].with_context( default_move_id=move.id, )) # First assignment form_wizard.next_serial_count = 3 form_wizard.next_serial_number = '001' wiz = form_wizard.save() wiz.generate_serial_numbers() # Second assignment form_wizard.next_serial_count = 2 form_wizard.next_serial_number = 'bilou-64' wiz = form_wizard.save() wiz.generate_serial_numbers() # Third assignment form_wizard.next_serial_count = 4 form_wizard.next_serial_number = 'ro-1337-bot' wiz = form_wizard.save() wiz.generate_serial_numbers() # Checks all move lines have the right SN generated_numbers = [ # Correspond to the first assignment '001', '002', '003', # Correspond to the second assignment 'bilou-64', 'bilou-65', # Correspond to the third assignment 'ro-1337-bot', 'ro-1338-bot', 'ro-1339-bot', 'ro-1340-bot', ] self.assertEqual(len(move.move_line_ids), nbre_of_lines + len(generated_numbers)) self.assertEqual(len(move.move_line_nosuggest_ids), len(generated_numbers)) for move_line in move.move_line_nosuggest_ids: self.assertEqual(move_line.qty_done, 1) self.assertEqual(move_line.lot_name, generated_numbers.pop(0)) for move_line in (move.move_line_ids - move.move_line_nosuggest_ids): self.assertEqual(move_line.qty_done, 0) self.assertEqual(move_line.lot_name, False)
def test_in_refund_line_onchange_product_1(self): move_form = Form(self.invoice) with move_form.invoice_line_ids.edit(0) as line_form: line_form.product_id = self.product_b move_form.save() self.assertInvoiceValues( self.invoice, [ { **self.product_line_vals_1, 'name': self.product_b.name, 'product_id': self.product_b.id, 'product_uom_id': self.product_b.uom_id.id, 'account_id': self.product_b.property_account_expense_id.id, 'price_unit': 160.0, 'price_subtotal': 160.0, 'price_total': 208.0, 'tax_ids': self.product_b.supplier_taxes_id.ids, 'credit': 160.0, }, self.product_line_vals_2, { **self.tax_line_vals_1, 'price_unit': 48.0, 'price_subtotal': 48.0, 'price_total': 48.0, 'credit': 48.0, }, { **self.tax_line_vals_2, 'price_unit': 48.0, 'price_subtotal': 48.0, 'price_total': 48.0, 'credit': 48.0, }, { **self.term_line_vals_1, 'price_unit': -416.0, 'price_subtotal': -416.0, 'price_total': -416.0, 'debit': 416.0, }, ], { **self.move_vals, 'amount_untaxed': 320.0, 'amount_tax': 96.0, 'amount_total': 416.0, })
def _create_basic_config(self): new_config = Form(self.env['pos.config']) new_config.name = 'PoS Shop Test' new_config.module_account = True new_config.invoice_journal_id = self.invoice_journal new_config.journal_id = self.pos_sale_journal new_config.available_pricelist_ids.clear() new_config.available_pricelist_ids.add(self.currency_pricelist) new_config.pricelist_id = self.currency_pricelist config = new_config.save() cash_journal = config.payment_method_ids.filtered( lambda pm: pm.is_cash_count)[:1].cash_journal_id cash_split_pm = self.env['pos.payment.method'].create({ 'name': 'Split (Cash) PM', 'receivable_account_id': self.pos_receivable_account.id, 'split_transactions': True, 'is_cash_count': True, 'cash_journal_id': cash_journal.id, }) config.write({'payment_method_ids': [(4, cash_split_pm.id, 0)]}) return config
def test_generate_01_sn(self): """ Creates a move with 5 move lines, then asks for generates 5 Serial Numbers. Checks move has 5 new move lines with each a SN, and the 5 original move lines are still unchanged. """ nbre_of_lines = 5 move = self.get_new_move(nbre_of_lines) form_wizard = Form(self.env['stock.assign.serial'].with_context( default_move_id=move.id, default_next_serial_number='001', default_next_serial_count=nbre_of_lines, )) wiz = form_wizard.save() self.assertEqual(len(move.move_line_ids), nbre_of_lines) wiz.generate_serial_numbers() # Checks new move lines have the right SN generated_numbers = ['001', '002', '003', '004', '005'] self.assertEqual(len(move.move_line_ids), nbre_of_lines + len(generated_numbers)) for move_line in move.move_line_nosuggest_ids: # For a product tracked by SN, the `qty_done` is set on 1 when # `lot_name` is set. self.assertEqual(move_line.qty_done, 1) self.assertEqual(move_line.lot_name, generated_numbers.pop(0)) # Checks pre-generated move lines didn't change for move_line in (move.move_line_ids - move.move_line_nosuggest_ids): self.assertEqual(move_line.qty_done, 0) self.assertEqual(move_line.lot_name, False)
def test_generate_03_raise_exception(self): """ Tries to generate some SN but with invalid initial number. """ move = self.get_new_move(3) form_wizard = Form(self.env['stock.assign.serial'].with_context( default_move_id=move.id, default_next_serial_number='code-xxx', )) wiz = form_wizard.save() with self.assertRaises(UserError): wiz.generate_serial_numbers() form_wizard.next_serial_count = 0 # Must raise an exception because `next_serial_count` must be greater than 0. with self.assertRaises(ValidationError): form_wizard.save()
def test_putaway_1(self): """As a user of Company A, create a putaway rule with locations of Company A and set the company to Company B before saving. Check it is not possible. """ stock_location_a_1 = self.env['stock.location'].with_user( self.user_a).create({ 'location_id': self.stock_location_a.id, 'usage': 'internal', 'name': 'A_1', }) putaway_form = Form(self.env['stock.putaway.rule']) putaway_form.location_in_id = self.stock_location_a putaway_form.location_out_id = stock_location_a_1 putaway_form.company_id = self.company_b with self.assertRaises(UserError): putaway_form.save()
def test_m2m_readonly(self): Sub = self.env['test_testing_utilities.sub3'] a = Sub.create({'name': 'a'}) b = Sub.create({'name': 'b'}) r = self.env['test_testing_utilities.g'].create( {'m2m': [(6, 0, a.ids)]}) f = Form(r) with self.assertRaises(AssertionError): f.m2m.add(b) with self.assertRaises(AssertionError): f.m2m.remove(id=a.id) f.save() self.assertEqual(r.m2m, a)
def test_set(self): """ Checks that we get/set recordsets for m2o & that set correctly triggers onchange """ r1 = self.env['test_testing_utilities.m2o'].create({'name': "A"}) r2 = self.env['test_testing_utilities.m2o'].create({'name': "B"}) f = Form(self.env['test_testing_utilities.c']) # check that basic manipulations work f.f2 = r1 self.assertEqual(f.f2, r1) self.assertEqual(f.name, 'A') f.f2 = r2 self.assertEqual(f.name, 'B') # can't set an int to an m2o field with self.assertRaises(AssertionError): f.f2 = r1.id self.assertEqual(f.f2, r2) self.assertEqual(f.name, 'B') # can't set a record of the wrong model temp = self.env['test_testing_utilities.readonly'].create({}) with self.assertRaises(AssertionError): f.f2 = temp self.assertEqual(f.f2, r2) self.assertEqual(f.name, 'B') r = f.save() self.assertEqual(r.f2, r2)
def test_o2m_editable_list(self): """ Tests the o2m proxy when the list view is editable rather than delegating to a separate form view """ f = Form(self.env['test_testing_utilities.parent'], view='test_testing_utilities.o2m_parent_ed') custom_tree = self.env.ref( 'test_testing_utilities.editable_external').id subs_field = f._view['fields']['subs'] tree_view = subs_field['views']['tree'] self.assertEqual(tree_view['type'], 'tree') self.assertEqual( tree_view['view_id'], custom_tree, 'check that the tree view is the one referenced by tree_view_ref') self.assertIs(subs_field['views']['edition'], tree_view, "check that the edition view is the tree view") self.assertEqual(subs_field['views']['edition']['view_id'], custom_tree) with f.subs.new() as s: s.value = 1 with f.subs.new() as s: s.value = 3 with f.subs.new() as s: s.value = 7 r = f.save() self.assertEqual(r.v, 12) self.assertEqual([get(s) for s in r.subs], [('1', 1, 1), ('3', 3, 3), ('7', 7, 7)])
def test_in_refund_onchange_past_invoice_1(self): copy_invoice = self.invoice.copy() move_form = Form(self.invoice) move_form.invoice_line_ids.remove(0) move_form.invoice_line_ids.remove(0) move_form.invoice_vendor_bill_id = copy_invoice move_form.save() self.assertInvoiceValues(self.invoice, [ self.product_line_vals_1, self.product_line_vals_2, self.tax_line_vals_1, self.tax_line_vals_2, self.term_line_vals_1, ], self.move_vals)
def test_default_and_onchange(self): """ Checks defaults & onchanges impacting m2o fields """ Sub = self.env['test_testing_utilities.m2o'] a = Sub.create({'name': "A"}) b = Sub.create({'name': "B"}) f = Form(self.env['test_testing_utilities.d']) self.assertFalse(f.f, "The default value gets overridden by the onchange") f.f2 = "B" self.assertEqual( f.f, b, "The new m2o value should match the second field by name") f.save()
def test_basic_alterations(self): """ Tests that the o2m proxy allows adding, removing and editing o2m records """ f = Form(self.env['test_testing_utilities.parent'], view='test_testing_utilities.o2m_parent') f.subs.new().save() f.subs.new().save() f.subs.new().save() f.subs.remove(index=0) r = f.save() self.assertEqual([get(s) for s in r.subs], [("2", 2, 2), ("2", 2, 2)]) self.assertEqual(r.v, 5) with Form(r, view='test_testing_utilities.o2m_parent') as f: with f.subs.new() as sub: sub.value = 5 f.subs.new().save() with f.subs.edit(index=2) as sub: self.assertEqual(sub.v, 5) f.subs.remove(index=0) self.assertEqual([get(s) for s in r.subs], [("2", 2, 2), ("5", 5, 5), ("2", 2, 2)]) self.assertEqual(r.v, 10) with Form(r, view='test_testing_utilities.o2m_parent') as f, \ f.subs.edit(index=0) as sub,\ self.assertRaises(AssertionError): sub.name = "whop whop"
def test_defaults(self): """ Checks that we can load a default form view and perform trivial default_get & onchanges & computations """ f = Form(self.env['test_testing_utilities.a']) self.assertEqual(f.id, False, "check that our record is not in db (yet)") self.assertEqual(f.f2, 42) self.assertEqual(f.f3, 21) self.assertEqual(f.f4, 42) f.f1 = '4' self.assertEqual(f.f2, 42) self.assertEqual(f.f3, 21) self.assertEqual(f.f4, 10) f.f2 = 8 self.assertEqual(f.f3, 4) self.assertEqual(f.f4, 2) r = f.save() self.assertEqual( (r.f1, r.f2, r.f3, r.f4), ('4', 8, 4, 2), )
def create_payment(self, invoices): payment_register = Form(self.env['account.payment'].with_context(active_model='account.move', active_ids=invoices.ids)) payment_register.payment_date = time.strftime('%Y') + '-07-15' payment_register.journal_id = self.bank_journal payment_register.payment_method_id = self.payment_method_check payment = payment_register.save() payment.post() return payment
def test_allocation_request(self): """ Create an allocation request """ # employee should be set to current user allocation_form = Form(self.env['hr.leave.allocation'].with_user( self.user_employee)) allocation_form.holiday_status_id = self.holidays_type_1 allocation_form.name = 'New Allocation Request' allocation = allocation_form.save()
def _create_invoice_for_po(self, purchase_order, date): move_form = Form( self.env['account.move'].with_context(default_type='in_invoice')) move_form.invoice_date = date move_form.partner_id = self.test_partner move_form.currency_id = self.currency_two move_form.purchase_id = purchase_order return move_form.save()
def test_orderpoint_1(self): """As a user of company A, create an orderpoint for company B. Check itsn't possible to use a warehouse of companny A""" product = self.env['product.product'].create({ 'type': 'product', 'name': 'shared product', }) orderpoint = Form(self.env['stock.warehouse.orderpoint'].with_user( self.user_a)) orderpoint.company_id = self.company_b orderpoint.warehouse_id = self.warehouse_b orderpoint.location_id = self.stock_location_a orderpoint.product_id = product with self.assertRaises(UserError): orderpoint.save() orderpoint.location_id = self.stock_location_b orderpoint = orderpoint.save() self.assertEqual(orderpoint.company_id, self.company_b)
def _create_product(self, name, uom_id, routes=()): p = Form(self.env['product.product']) p.name = name p.type = 'product' p.uom_id = uom_id p.uom_po_id = uom_id p.route_ids.clear() for r in routes: p.route_ids.add(r) return p.save()
def test_partial_payment(self): """ Create test to pay invoices (cust. inv + vendor bill) with partial payment """ # Test Customer Invoice inv_1 = self.create_invoice(amount=600) payment_register = Form(self.env['account.payment'].with_context( active_model='account.move', active_ids=inv_1.ids)) payment_register.payment_date = time.strftime('%Y') + '-07-15' payment_register.journal_id = self.bank_journal_euro payment_register.payment_method_id = self.payment_method_manual_in # Perform the partial payment by setting the amount at 550 instead of 600 payment_register.amount = 550 payment = payment_register.save() self.assertEqual(len(payment), 1) self.assertEqual(payment.invoice_ids[0].id, inv_1.id) self.assertAlmostEquals(payment.amount, 550) self.assertEqual(payment.payment_type, 'inbound') self.assertEqual(payment.partner_id, self.partner_agrolait) self.assertEqual(payment.partner_type, 'customer') # Test Vendor Bill inv_2 = self.create_invoice(amount=500, type='in_invoice', partner=self.partner_china_exp.id) payment_register = Form(self.env['account.payment'].with_context( active_model='account.move', active_ids=inv_2.ids)) payment_register.payment_date = time.strftime('%Y') + '-07-15' payment_register.journal_id = self.bank_journal_euro payment_register.payment_method_id = self.payment_method_manual_in # Perform the partial payment by setting the amount at 300 instead of 500 payment_register.amount = 300 payment = payment_register.save() self.assertEqual(len(payment), 1) self.assertEqual(payment.invoice_ids[0].id, inv_2.id) self.assertAlmostEquals(payment.amount, 300) self.assertEqual(payment.payment_type, 'outbound') self.assertEqual(payment.partner_id, self.partner_china_exp) self.assertEqual(payment.partner_type, 'supplier')
def test_o2m_readonly_subfield(self): """ Tests that readonly is applied to the field of the o2m = not sent as part of the create / write values """ f = Form(self.env['o2m_readonly_subfield_parent']) with f.line_ids.new() as new_line: new_line.name = "ok" self.assertEqual(new_line.f, 2) r = f.save() self.assertEqual((r.line_ids.name, r.line_ids.f), ('ok', 2))
def test_picking_1(self): """As a user of Company A, create a picking and use a picking type of Company B, check the create picking belongs to Company B. """ picking_type_company_b = self.env['stock.picking.type'].search( [('company_id', '=', self.company_b.id)], limit=1) picking_form = Form(self.env['stock.picking'].with_user(self.user_a)) picking_form.picking_type_id = picking_type_company_b picking = picking_form.save() self.assertEqual(picking.company_id, self.company_b)
def test_attr(self): f = Form(self.env['test_testing_utilities.e'], view='test_testing_utilities.attrs_using_m2m') with self.assertRaises(AssertionError): f.count = 5 f.m2m.add(self.env['test_testing_utilities.sub2'].create( {'name': 'ok'})) f.count = 5 r = f.save() self.assertEqual(r.m2m.mapped('name'), ['ok', '1', '2', '3', '4'])
def test_product_1(self): """ As an user of Company A, checks we can or cannot create new product depending of its `company_id`.""" # Creates a new product with no company_id and set a responsible. # The product must be created as there is no company on the product. product_form = Form(self.env['product.template'].with_user( self.user_a)) product_form.name = 'Paramite Pie' product_form.responsible_id = self.user_b product = product_form.save() self.assertEqual(product.company_id.id, False) self.assertEqual(product.responsible_id.id, self.user_b.id) # Creates a new product belong to Company A and set a responsible belong # to Company B. The product mustn't be created as the product and the # user don't belong of the same company. self.user_b.company_ids = [(6, 0, [self.company_b.id])] product_form = Form(self.env['product.template'].with_user( self.user_a)) product_form.name = 'Meech Munchy' product_form.company_id = self.company_a product_form.responsible_id = self.user_b with self.assertRaises(UserError): # Raises an UserError for company incompatibility. product = product_form.save() # Creates a new product belong to Company A and set a responsible belong # to Company A & B (default B). The product must be created as the user # belongs to product's company. self.user_b.company_ids = [(6, 0, [self.company_a.id, self.company_b.id])] product_form = Form(self.env['product.template'].with_user( self.user_a)) product_form.name = 'Scrab Cake' product_form.company_id = self.company_a product_form.responsible_id = self.user_b product = product_form.save() self.assertEqual(product.company_id.id, self.company_a.id) self.assertEqual(product.responsible_id.id, self.user_b.id)